upload.uts 6.2 KB

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