import md5 from '~/utils/md5' export function useIdPhoto() { const tokenCookie = useCookie('token', { path: '/' }) const macCookie = useCookie('mac', { maxAge: 365 * 24 * 3600, path: '/' }) const openIdCookie = useCookie('open_id', { path: '/' }) const sourceCookie = useCookie('source', { path: '/' }) const { getClientId, getClientIos } = useClientDevice() const tokenState = useState('auth_token', () => tokenCookie.value || '') const openIdState = useState('auth_open_id', () => openIdCookie.value || '') if (import.meta.client && !macCookie.value) { macCookie.value = createUuid() } function createUuid() { if (globalThis.crypto?.randomUUID) return globalThis.crypto.randomUUID() return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (char) => { const random = Math.floor(Math.random() * 16) const value = char === 'x' ? random : (random & 0x3) | 0x8 return value.toString(16) }) } function getNonce() { const timeStr = Date.now().toString() return { timeStr, nonce: md5(timeStr).substring(4, 14), } } async function create(file, settings) { if (!file) throw new Error('请选择一张照片') const token = tokenState.value || tokenCookie.value || '' const { timeStr, nonce } = getNonce() const formData = new FormData() // ThinkJS 2 会先读取公共参数,必须将普通字段放在文件字段之前。 formData.append('token', token) formData.append('uid', openIdState.value || openIdCookie.value || '') formData.append('mac', macCookie.value || 'pc-id-photo') formData.append('base_timestamp', String(Math.floor(Date.now() / 1000))) formData.append('client', String(getClientId())) formData.append('source', sourceCookie.value || '') formData.append('client_ios', String(getClientIos())) formData.append('version', '1.0.0') formData.append('version_code', '1') formData.append('request_id', settings.request_id || createUuid()) formData.append('spec_key', settings.spec_key) formData.append('background', settings.background) formData.append('beauty', settings.beauty) formData.append('scale', String(settings.scale)) formData.append('offset_x', String(settings.offset_x)) formData.append('offset_y', String(settings.offset_y)) formData.append('file', file) let result try { result = await $fetch('/api/idphoto/create', { method: 'POST', headers: { token, timestr: timeStr, nonce, }, body: formData, }) } catch (error) { const data = error?.data if (data && typeof data === 'object' && data.msg) { const normalized = new Error(data.msg) normalized.code = data.code || 1000 normalized.data = data.data || {} throw normalized } throw error } if (result.code === 1009) { const { logout, showLogin } = useUser() logout() showLogin.value = true } if (result.code !== 0) { const error = new Error(result.msg || '证件照制作失败') error.code = result.code || 1000 error.data = result.data || {} throw error } return result } return { create, createRequestId: createUuid, } }