upload.uts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * 文件上传封装
  3. */
  4. import { getAccessToken, clearAll } from './storage'
  5. import type { ApiResponse } from '../types/user'
  6. import type { UploadResponse, UploadFileInfo } from '../types/workbench'
  7. import { getBaseUrl } from './request'
  8. /**
  9. * 处理 401 未授权错误
  10. */
  11. const handle401Error = (): void => {
  12. // 清除所有本地存储
  13. clearAll()
  14. // 提示用户
  15. uni.showToast({
  16. title: '登录已过期,请重新登录',
  17. icon: 'none',
  18. duration: 2000
  19. })
  20. // 延迟跳转到登录页
  21. setTimeout(() => {
  22. uni.reLaunch({
  23. url: '/pages/login/index'
  24. })
  25. }, 1500)
  26. }
  27. /**
  28. * 获取文件预览地址
  29. */
  30. export const getFileViewUrl = (fileId: string): string => {
  31. return getBaseUrl()+`${fileId}`
  32. }
  33. /**
  34. * 上传文件(多文件上传接口)
  35. * @param filePath 文件路径
  36. * @param businessType 业务类型模块
  37. */
  38. export const uploadFile = (filePath: string, businessType: string): Promise<UploadResponse> => {
  39. return new Promise((resolve, reject) => {
  40. const token = getAccessToken()
  41. uni.uploadFile({
  42. url: getBaseUrl() + `/common/upload`,
  43. filePath: filePath,
  44. name: 'file',
  45. header: {
  46. 'Authorization': 'Bearer ' + token ?? ''
  47. },
  48. success: (res) => {
  49. // 提取属性(any 类型不能直接访问属性)
  50. const statusCode = res.statusCode as number
  51. const resData = res.data as string
  52. console.log('上传响应:', res)
  53. // 处理 401 未授权
  54. if (statusCode == 401) {
  55. try {
  56. const errorResult = JSON.parse(resData) as UTSJSONObject
  57. const message = errorResult['message'] as string | null
  58. const error = errorResult['error'] as string | null
  59. // 显示错误信息
  60. const errorMsg = message ?? error ?? '登录已过期'
  61. // 处理 401 错误
  62. handle401Error()
  63. reject(new Error(errorMsg))
  64. } catch (e: any) {
  65. handle401Error()
  66. reject(new Error('登录已过期'))
  67. }
  68. return
  69. }
  70. // 处理成功响应
  71. if (statusCode == 200) {
  72. try {
  73. const result = JSON.parse(resData) as UTSJSONObject
  74. // 获取第一个文件信息
  75. const fileInfo = result as UTSJSONObject
  76. let code = fileInfo["code"] as number | null;
  77. let msg = fileInfo["msg"] as string | null;
  78. if (code == 200) {
  79. const fileName = fileInfo['fileName'] as string
  80. // 构建完整的 URL
  81. const url = getFileViewUrl(fileName)
  82. // 返回 UploadResponse
  83. const uploadResult: UploadResponse = {
  84. url: url,
  85. fileId: fileName,
  86. fileName: fileName,
  87. filePath: filePath,
  88. fileSize: 0,
  89. fileExt: '',
  90. businessType: businessType
  91. }
  92. resolve(uploadResult)
  93. }else{
  94. const errorMsg = msg != null ? msg : "请求失败";
  95. console.error('响应数据解析失败:', errorMsg)
  96. reject(new Error(errorMsg))
  97. }
  98. } catch (e: any) {
  99. console.error('响应数据解析失败:', e)
  100. reject(new Error('响应数据解析失败'))
  101. }
  102. } else {
  103. // 其他错误状态码
  104. try {
  105. const errorResult = JSON.parse(resData) as UTSJSONObject
  106. const message = errorResult['message'] as string | null
  107. const error = errorResult['error'] as string | null
  108. const errorMsg = message ?? error ?? `上传失败:${statusCode}`
  109. reject(new Error(errorMsg))
  110. } catch (e: any) {
  111. reject(new Error(`上传失败:${statusCode}`))
  112. }
  113. }
  114. },
  115. fail: (err: any) => {
  116. reject(new Error('上传失败,请检查网络连接'))
  117. }
  118. })
  119. })
  120. }
  121. /**
  122. * 上传图片
  123. * @param filePath 文件路径
  124. * @param businessType 业务类型模块,默认为 'image'
  125. */
  126. export const uploadImage = (filePath: string, businessType: string | null): Promise<UploadResponse> => {
  127. const type = businessType ?? 'image'
  128. return uploadFile(filePath, type)
  129. }
  130. /**
  131. * 上传视频
  132. * @param filePath 文件路径
  133. * @param businessType 业务类型模块,默认为 'video'
  134. */
  135. export const uploadVideo = (filePath: string, businessType: string | null): Promise<UploadResponse> => {
  136. const type = businessType ?? 'video'
  137. return uploadFile(filePath, type)
  138. }