您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

99 行
3.3 KiB

  1. import md5 from '~/utils/md5'
  2. /**
  3. * 老照片修复 / 上色(混元生图 3.0)
  4. *
  5. * create 走 multipart 直传原图(和证件照一样,避免先传 CDN 再由后端回源下载一次),
  6. * 其余查询类接口用 useApi() 的普通 POST 即可。
  7. */
  8. export function useOldPhoto() {
  9. const tokenCookie = useCookie('token', { path: '/' })
  10. const macCookie = useCookie('mac', { maxAge: 365 * 24 * 3600, path: '/' })
  11. const openIdCookie = useCookie('open_id', { path: '/' })
  12. const sourceCookie = useCookie('source', { path: '/' })
  13. const tokenState = useState('auth_token', () => tokenCookie.value || '')
  14. const openIdState = useState('auth_open_id', () => openIdCookie.value || '')
  15. if (import.meta.client && !macCookie.value) {
  16. macCookie.value = createUuid()
  17. }
  18. function createUuid() {
  19. if (globalThis.crypto?.randomUUID) return globalThis.crypto.randomUUID()
  20. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (char) => {
  21. const random = Math.floor(Math.random() * 16)
  22. const value = char === 'x' ? random : (random & 0x3) | 0x8
  23. return value.toString(16)
  24. })
  25. }
  26. function getNonce() {
  27. const timeStr = Date.now().toString()
  28. return { timeStr, nonce: md5(timeStr).substring(4, 14) }
  29. }
  30. /**
  31. * 提交修复任务
  32. * @param {File} file 原图
  33. * @param {{ mode: string, extra_prompt?: string, request_id?: string }} settings
  34. */
  35. async function create(file, settings = {}) {
  36. if (!file) throw new Error('请选择一张照片')
  37. const token = tokenState.value || tokenCookie.value || ''
  38. const { timeStr, nonce } = getNonce()
  39. const formData = new FormData()
  40. // ThinkJS 2 会先读公共参数,普通字段必须排在文件字段之前
  41. formData.append('token', token)
  42. formData.append('uid', openIdState.value || openIdCookie.value || '')
  43. formData.append('mac', macCookie.value || 'pc-old-photo')
  44. formData.append('base_timestamp', String(Math.floor(Date.now() / 1000)))
  45. formData.append('client', '1')
  46. formData.append('source', sourceCookie.value || '')
  47. formData.append('client_ios', '0')
  48. formData.append('version', '1.0.0')
  49. formData.append('version_code', '1')
  50. formData.append('request_id', settings.request_id || createUuid())
  51. formData.append('mode', settings.mode || 'colorize')
  52. if (settings.extra_prompt) formData.append('extra_prompt', settings.extra_prompt)
  53. formData.append('file', file)
  54. let result
  55. try {
  56. result = await $fetch('/api/oldphoto/create', {
  57. method: 'POST',
  58. headers: { token, timestr: timeStr, nonce },
  59. body: formData,
  60. })
  61. } catch (error) {
  62. const data = error?.data
  63. if (data && typeof data === 'object' && data.msg) {
  64. const normalized = new Error(data.msg)
  65. normalized.code = data.code || 1000
  66. normalized.data = data.data || {}
  67. throw normalized
  68. }
  69. throw error
  70. }
  71. if (result.code === 1009) {
  72. const { logout, showLogin } = useUser()
  73. logout()
  74. showLogin.value = true
  75. }
  76. if (result.code !== 0) {
  77. const error = new Error(result.msg || '提交失败,请稍后重试')
  78. error.code = result.code || 1000
  79. error.data = result.data || {}
  80. throw error
  81. }
  82. return result
  83. }
  84. return {
  85. create,
  86. createRequestId: createUuid,
  87. }
  88. }