imageUpload.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /**
  2. * 图片上传和下载工具类
  3. */
  4. export default {
  5. /**
  6. * 获取文件列表
  7. * @param {String} type - 类型
  8. * @param {String} orderFileType - 订单文件类型 (1:聊天记录, 2:实物图, 3:细节图)
  9. * @param {String} receiptId - 收单ID
  10. * @param {String} itemBrand - 物品品牌
  11. * @param {String} clueId - 线索ID
  12. */
  13. async getFileList(type, orderFileType, receiptId, itemBrand, clueId) {
  14. try {
  15. const params = {
  16. clueId,
  17. sourceId: receiptId,
  18. type,
  19. orderFileType,
  20. isDuplicate: '1',
  21. pageNum: 1,
  22. pageSize: 1000
  23. }
  24. const response = await uni.$u.api.selectClueFileByDto(params)
  25. const rows = response.rows || []
  26. // 如果品牌包含逗号,说明是多个品牌,需要过滤
  27. // if (itemBrand && itemBrand.indexOf(',') !== -1) {
  28. return rows.filter(item => item.sourceId === receiptId)
  29. // }
  30. // return rows
  31. } catch (error) {
  32. console.error('获取文件列表失败:', error)
  33. uni.$u.toast('获取文件列表失败')
  34. return []
  35. }
  36. },
  37. /**
  38. * 选择图片
  39. * @param {Number} count - 最多选择数量
  40. * @returns {Promise<Array>} 图片路径数组
  41. */
  42. chooseImage(count = 9) {
  43. return new Promise((resolve, reject) => {
  44. uni.chooseImage({
  45. count,
  46. sizeType: ['compressed'],
  47. sourceType: ['album', 'camera'],
  48. success: (res) => {
  49. resolve(res.tempFilePaths)
  50. },
  51. fail: (err) => {
  52. console.error('选择图片失败:', err)
  53. reject(err)
  54. }
  55. })
  56. })
  57. },
  58. /**
  59. * 上传文件
  60. * @param {String} filePath - 文件路径
  61. * @returns {Promise<Object>} 上传结果
  62. */
  63. async uploadFile(filePath) {
  64. try {
  65. uni.showLoading({
  66. title: '上传中...',
  67. mask: true
  68. })
  69. const { data } = await uni.$u.api.uploadFile(filePath)
  70. return {
  71. fileSize: data.fileSize,
  72. fileSuffix: data.fileSuffix,
  73. fileName: data.name,
  74. fileUrl: data.url
  75. }
  76. } catch (error) {
  77. console.error('文件上传失败:', error)
  78. uni.$u.toast('上传失败,请重试')
  79. throw error
  80. } finally {
  81. uni.hideLoading()
  82. }
  83. },
  84. /**
  85. * 批量上传文件
  86. * @param {Array<String>} filePaths - 文件路径数组
  87. * @returns {Promise<Array>} 上传结果数组
  88. */
  89. async uploadFiles(filePaths) {
  90. try {
  91. const uploadPromises = filePaths.map(filePath => this.uploadFile(filePath))
  92. return await Promise.all(uploadPromises)
  93. } catch (error) {
  94. console.error('批量上传失败:', error)
  95. throw error
  96. }
  97. },
  98. /**
  99. * 绑定订单文件
  100. * @param {String} clueId - 线索ID
  101. * @param {String} receiptId - 收单ID
  102. * @param {String} orderFileType - 订单文件类型
  103. * @param {Array} fileList - 文件列表
  104. */
  105. async bindOrderFile(clueId, receiptId, orderFileType, fileList) {
  106. try {
  107. const list = fileList.map(file => ({
  108. fileSize: file.fileSize,
  109. fileSuffix: file.fileSuffix,
  110. fileName: file.fileName,
  111. fileUrl: file.fileUrl,
  112. orderFileType
  113. }))
  114. await uni.$u.api.saveClueFile({
  115. clueId,
  116. list,
  117. sourceId: receiptId,
  118. type: '2',
  119. orderFileType
  120. })
  121. uni.$u.toast('上传成功')
  122. } catch (error) {
  123. console.error('绑定订单文件失败:', error)
  124. uni.$u.toast('上传失败')
  125. throw error
  126. }
  127. },
  128. /**
  129. * 删除文件
  130. * @param {String|Array} fileIds - 文件ID或ID数组
  131. */
  132. async deleteFile(fileIds) {
  133. try {
  134. const ids = Array.isArray(fileIds) ? fileIds : [fileIds]
  135. await uni.$u.api.deleteClueFile(ids)
  136. uni.showToast({
  137. title: '删除成功',
  138. icon: 'success',
  139. duration: 2000
  140. })
  141. } catch (error) {
  142. console.error('删除文件失败:', error)
  143. uni.showToast({
  144. title: '删除失败',
  145. icon: 'error',
  146. duration: 2000
  147. })
  148. throw error
  149. }
  150. },
  151. /**
  152. * 保存图片到本地相册
  153. * @param {String} url - 图片URL
  154. * @returns {Promise}
  155. */
  156. saveImageToLocal(url) {
  157. return new Promise((resolve, reject) => {
  158. this._doSaveImage(url, resolve, reject)
  159. })
  160. },
  161. /**
  162. * 执行保存图片操作
  163. * @private
  164. */
  165. _doSaveImage(url, resolve, reject) {
  166. uni.downloadFile({
  167. url,
  168. success: (res) => {
  169. if (res.statusCode === 200 && res.tempFilePath) {
  170. uni.saveImageToPhotosAlbum({
  171. filePath: res.tempFilePath,
  172. success: () => {
  173. resolve()
  174. },
  175. fail: (err) => {
  176. console.error('保存到相册失败:', err)
  177. // 错误代码 12 通常表示权限问题
  178. const isPermissionError = err.code === 12 ||
  179. err.errCode === 12 ||
  180. err.errMsg.includes('auth denied') ||
  181. err.errMsg.includes('permission') ||
  182. err.errMsg.includes('UNKOWN ERROR')
  183. if (isPermissionError) {
  184. uni.showModal({
  185. title: '权限不足',
  186. content: '需要访问相册权限来保存图片,是否前往设置开启权限?',
  187. confirmText: '去设置',
  188. cancelText: '取消',
  189. success: (modalRes) => {
  190. if (modalRes.confirm) {
  191. uni.openSetting({
  192. success: (settingRes) => {
  193. // 检查是否开启了相册权限
  194. const hasPermission = settingRes.authSetting &&
  195. settingRes.authSetting['scope.writePhotosAlbum']
  196. if (hasPermission) {
  197. uni.showToast({
  198. title: '权限已开启,请重试保存',
  199. icon: 'none',
  200. duration: 2000
  201. })
  202. } else {
  203. uni.showToast({
  204. title: '请在设置中开启相册权限',
  205. icon: 'none',
  206. duration: 2000
  207. })
  208. }
  209. },
  210. fail: () => {
  211. uni.showToast({
  212. title: '无法打开设置',
  213. icon: 'none'
  214. })
  215. }
  216. })
  217. }
  218. }
  219. })
  220. } else {
  221. uni.showToast({
  222. title: '保存失败,请稍后重试',
  223. icon: 'none'
  224. })
  225. }
  226. reject(err)
  227. }
  228. })
  229. } else {
  230. const errorMsg = `下载失败,状态码: ${res.statusCode}`
  231. console.error(errorMsg)
  232. uni.showToast({
  233. title: '下载图片失败',
  234. icon: 'none'
  235. })
  236. reject(new Error(errorMsg))
  237. }
  238. },
  239. fail: (err) => {
  240. console.error('下载图片失败:', err)
  241. uni.showToast({
  242. title: '下载图片失败,请检查网络',
  243. icon: 'none'
  244. })
  245. reject(err)
  246. }
  247. })
  248. },
  249. /**
  250. * 批量保存图片到本地
  251. * @param {Array<String>} urls - 图片URL数组
  252. */
  253. async saveImagesToLocal(urls) {
  254. try {
  255. uni.showLoading({
  256. title: '正在保存图片...',
  257. mask: true
  258. })
  259. const savedImages = []
  260. const failedImages = []
  261. for (let i = 0; i < urls.length; i++) {
  262. const url = urls[i]
  263. try {
  264. await this.saveImageToLocal(url)
  265. savedImages.push(url)
  266. } catch (error) {
  267. console.error(`保存图片失败: ${url}`, error)
  268. failedImages.push(url)
  269. }
  270. uni.showLoading({
  271. title: `正在保存图片... (${i + 1}/${urls.length})`,
  272. mask: true
  273. })
  274. }
  275. uni.hideLoading()
  276. let message = `成功保存 ${savedImages.length} 张图片`
  277. if (failedImages.length > 0) {
  278. message += `,${failedImages.length} 张保存失败`
  279. }
  280. uni.showToast({
  281. title: message,
  282. icon: 'none',
  283. duration: 3000
  284. })
  285. } catch (error) {
  286. uni.hideLoading()
  287. console.error('保存图片过程中发生错误:', error)
  288. uni.showToast({
  289. title: '保存图片失败',
  290. icon: 'error'
  291. })
  292. }
  293. },
  294. /**
  295. * 复制图片链接
  296. * @param {Array<String>} urls - 图片URL数组
  297. */
  298. copyImageUrls(urls) {
  299. uni.setClipboardData({
  300. data: JSON.stringify(urls),
  301. success: () => {
  302. uni.showToast({
  303. title: '图片链接已复制',
  304. icon: 'none'
  305. })
  306. }
  307. })
  308. }
  309. }