bxUpload.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /**
  2. * 报销附件:拍照/相册 → /attachments/upload(multipart,已在加密排除路径)
  3. * 返回附件对象列表(含 id),提交后需 bindAttachments
  4. */
  5. import { API_BASE, TOKEN_KEY } from '@/config/api'
  6. function parseBody(raw) {
  7. try {
  8. return JSON.parse(typeof raw === 'string' ? raw : String(raw || ''))
  9. } catch {
  10. return {}
  11. }
  12. }
  13. function getToken() {
  14. const raw = uni.getStorageSync(TOKEN_KEY)
  15. return typeof raw === 'string' ? raw.trim() : raw ? String(raw).trim() : ''
  16. }
  17. /**
  18. * @param {{ bizType?: string, bizId?: string|number, maxCount?: number, currentCount?: number }} opts
  19. * @returns {Promise<Array<{ id: string, fileName?: string, localPath?: string }>>}
  20. */
  21. export async function chooseAndUploadBxAttachments(opts = {}) {
  22. const bizType = opts.bizType || 'reimburse_apply'
  23. const bizId = opts.bizId != null ? String(opts.bizId) : '0'
  24. const maxCount = opts.maxCount != null ? opts.maxCount : 6
  25. const currentCount = opts.currentCount || 0
  26. const remain = maxCount - currentCount
  27. if (remain <= 0) {
  28. uni.showToast({ title: `最多上传${maxCount}张`, icon: 'none' })
  29. return []
  30. }
  31. const choose = await new Promise((resolve) => {
  32. uni.chooseImage({
  33. count: remain,
  34. sizeType: ['compressed'],
  35. sourceType: ['album', 'camera'],
  36. success: (res) => resolve(res),
  37. fail: () => resolve(null)
  38. })
  39. })
  40. if (!choose?.tempFilePaths?.length) return []
  41. const token = getToken()
  42. const uploadUrl = `${API_BASE}/attachments/upload?biz_type=${encodeURIComponent(bizType)}&biz_id=${encodeURIComponent(bizId)}`
  43. const uploaded = []
  44. uni.showLoading({ title: '上传中...' })
  45. try {
  46. for (const filePath of choose.tempFilePaths) {
  47. const uploadRes = await new Promise((ok, fail) => {
  48. uni.uploadFile({
  49. url: uploadUrl,
  50. filePath,
  51. name: 'file',
  52. header: {
  53. Authorization: token ? `Bearer ${token}` : ''
  54. },
  55. success: ok,
  56. fail
  57. })
  58. })
  59. if (uploadRes.statusCode === 401) {
  60. uni.showToast({ title: '登录已失效', icon: 'none' })
  61. break
  62. }
  63. const body = parseBody(uploadRes.data)
  64. // bx: code===0
  65. if (body.code !== 0 || !body.data?.id) {
  66. uni.showToast({ title: body.msg || body.message || '上传失败', icon: 'none' })
  67. break
  68. }
  69. uploaded.push({
  70. id: String(body.data.id),
  71. fileName: body.data.fileName || body.data.file_name || '',
  72. localPath: filePath
  73. })
  74. }
  75. } catch (e) {
  76. uni.showToast({
  77. title: e instanceof Error ? e.message : '上传失败',
  78. icon: 'none'
  79. })
  80. } finally {
  81. uni.hideLoading()
  82. }
  83. return uploaded
  84. }