upload.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. import { UPLOAD_URL } from '@/settings/siteSetting.js';
  2. import { useUserStore } from '@/store/user.js';
  3. const userStore = useUserStore();
  4. /**
  5. * type // image / video / file
  6. * opts {
  7. dir 上传路径
  8. filePath 文件资源
  9. count // 默认 1
  10. }
  11. **/
  12. let APIURLSET = uni.getStorageSync('APIURL')
  13. let APIURL = UPLOAD_URL
  14. if (APIURLSET) APIURL = `${String(APIURLSET).replace(/\/$/, '')}/file/upload`;
  15. export function chooseAndUploadFile(type, opts, dir = '') {
  16. if (type === 'image') {
  17. chooseImage({
  18. dir,
  19. ...opts
  20. });
  21. } else if (type === 'video') {
  22. chooseVideo({
  23. dir,
  24. ...opts
  25. });
  26. } else if (type === 'audio' || type === 'voice') {
  27. chooseAudio({
  28. dir,
  29. ...opts
  30. });
  31. } else {
  32. chooseFile({
  33. dir,
  34. ...opts
  35. });
  36. }
  37. }
  38. // 选择图片
  39. function chooseImage(opts = {}) {
  40. const { count = 1, sizeType = ['original'], sourceType = ['album', 'camera'], extension = ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'], callBack } = opts;
  41. uni.chooseImage({
  42. count,
  43. sizeType,
  44. extension,
  45. sourceType,
  46. success: async (res) => {
  47. console.log('chooseImage res res', res);
  48. const tempFiles = res.tempFiles;
  49. const file = await batchUploadFile({
  50. files: tempFiles,
  51. ...opts
  52. });
  53. console.log('file', file);
  54. callBack && callBack(file);
  55. },
  56. fail: (err) => {
  57. console.log('chooseImage-fail', err);
  58. }
  59. });
  60. }
  61. // 选择文件
  62. function chooseFile(opts = {}) {
  63. const { count = 1 } = opts;
  64. wx.chooseMessageFile({
  65. type: 'file',
  66. count,
  67. success: async (res) => {
  68. const { tempFiles } = res;
  69. const file = await batchUploadFile({
  70. files: tempFiles,
  71. ...opts
  72. });
  73. console.log('file', file);
  74. },
  75. fail(error) {
  76. console.log('fail', error);
  77. }
  78. });
  79. }
  80. // 选择视频
  81. function chooseVideo(opts = {}) {
  82. const { sourceType, callBack, dir, compressed = false, isVideo = false } = opts;
  83. // console.log('compressed', compressed);
  84. uni.chooseVideo({
  85. sourceType,
  86. compressed,
  87. success: async (res) => {
  88. const { size, tempFilePath } = res;
  89. let videoMaxSize = 300;
  90. if (userStore.getDefaultConfig) videoMaxSize = userStore.getDefaultConfig.videoMaxSize;
  91. // console.log('232333', videoMaxSize, size, userStore.getDefaultConfig);
  92. if (size > 1024 * 1024 * videoMaxSize) {
  93. uni.showModal({
  94. title: `视频需要${videoMaxSize}M以内`,
  95. success: (res) => {}
  96. });
  97. return;
  98. }
  99. const url = await uploadFile({
  100. dir,
  101. filePath: tempFilePath,
  102. isVideo,
  103. size: size ? (size / 1024 / 1024).toFixed(2) : 0
  104. });
  105. uni.setStorageSync('videoUrlUp', tempFilePath);
  106. callBack && callBack(url);
  107. // uni.compressVideo({
  108. // src: res.tempFilePath,
  109. // quality: 'high',
  110. // success: async (ress) => {
  111. // // 压缩成功
  112. // console.log('压缩成功', ress);
  113. // const { size, tempFilePath } = ress;
  114. // const url = await uploadFile({
  115. // dir,
  116. // filePath: tempFilePath
  117. // });
  118. // callBack && callBack(url);
  119. // },
  120. // fail: async (err) => {
  121. // // 压缩失败
  122. // console.log('压缩失败', err);
  123. // const { size, tempFilePath } = res;
  124. // const url = await uploadFile({
  125. // dir,
  126. // filePath: tempFilePath
  127. // });
  128. // callBack && callBack(url);
  129. // }
  130. // });
  131. // console.log('chooseVideo res res', res);
  132. },
  133. fail: (err) => {
  134. console.log('chooseVideo-fail', err);
  135. }
  136. });
  137. }
  138. // 选择音频
  139. function chooseAudio(opts = {}) {
  140. const { dir, callBack } = opts;
  141. wx.chooseMessageFile({
  142. count: 1,
  143. type: 'file',
  144. extension: ['mp3', 'wav', 'aac', 'ogg', 'wma', 'alac', 'amr', 'm4a'],
  145. success: async (res) => {
  146. console.log('chooseAudio res res', res.tempFiles[0].path);
  147. if (
  148. res.tempFiles[0].path.indexOf('.mp3') == -1 &&
  149. res.tempFiles[0].path.indexOf('.m4a') == -1 &&
  150. res.tempFiles[0].path.indexOf('.wav') == -1 &&
  151. res.tempFiles[0].path.indexOf('.MP3') == -1 &&
  152. res.tempFiles[0].path.indexOf('.M4A') == -1 &&
  153. res.tempFiles[0].path.indexOf('.WAV') == -1 &&
  154. res.tempFiles[0].path.indexOf('.aac') == -1 &&
  155. res.tempFiles[0].path.indexOf('.AAC') == -1 &&
  156. res.tempFiles[0].path.indexOf('.ogg') == -1 &&
  157. res.tempFiles[0].path.indexOf('.OGG') == -1 &&
  158. res.tempFiles[0].path.indexOf('.wma') == -1 &&
  159. res.tempFiles[0].path.indexOf('.WMA') == -1 &&
  160. res.tempFiles[0].path.indexOf('.alac') == -1 &&
  161. res.tempFiles[0].path.indexOf('.ALAC') == -1 &&
  162. res.tempFiles[0].path.indexOf('.amr') == -1 &&
  163. res.tempFiles[0].path.indexOf('.AMR') == -1
  164. ) {
  165. uni.showToast({
  166. title: '音频格式只能是mp3/m4a/wav',
  167. icon: 'none'
  168. });
  169. return;
  170. }
  171. const { tempFiles } = res;
  172. // if (tempFiles[0].size / 1024 / 1024 > 35) {
  173. // uni.showToast({ icon: 'none', mask: true, title: '音频需要35M以内' });
  174. // return;
  175. // }
  176. const url = await uploadFile({
  177. dir,
  178. filePath: tempFiles[0].path,
  179. size: tempFiles[0].size ? (tempFiles[0].size / 1024 / 1024).toFixed(2) : 0
  180. });
  181. callBack && callBack(url);
  182. },
  183. fail: (err) => {
  184. console.log('chooseAudio-fail', err);
  185. }
  186. });
  187. }
  188. // 上传之前
  189. function beforeUnload(files) {
  190. return new Promise(async (resolve, reject) => {
  191. const filesSize = files.map((x) => x.size / 1024 / 1024);
  192. const isExceed = filesSize.some((x) => x > 8);
  193. if (isExceed && files.length === 1) {
  194. uni.showToast({ icon: 'none', mask: true, title: '文件需要8M以内' });
  195. } else if (isExceed && files.length > 1) {
  196. files = files.filter((x) => x.size / 1024 / 1024 < 8);
  197. uni.showModal({
  198. title: '提示',
  199. content: '部分文件超过8M 已过滤,是否继续上传',
  200. confirmText: '继续上传',
  201. success: (res) => {
  202. if (res.confirm) {
  203. resolve(files);
  204. }
  205. }
  206. });
  207. } else {
  208. resolve(files);
  209. }
  210. });
  211. }
  212. // 批量上传
  213. export const batchUploadFile = async (opts = {}) => {
  214. const { dir = '', files } = opts;
  215. const fileFilter = await beforeUnload(files);
  216. let index = 0,
  217. filesLength = fileFilter.length,
  218. urls = [],
  219. errorArr = [];
  220. return new Promise(async (resolve, reject) => {
  221. let header = {
  222. 'Content-Type': 'application/json;charset=UTF-8',
  223. userId: userStore.getSiteId,
  224. Authorization: userStore.getToken
  225. };
  226. uni.showLoading({ mask: true, title: '上传中' });
  227. let str = dir ? '?typeId=' + dir : '';
  228. const startUpload = () => {
  229. return new Promise((resolve, reject) => {
  230. let start = () => {
  231. uni.uploadFile({
  232. url: APIURL + str,
  233. name: 'file',
  234. header,
  235. timeout: 1000 * 60 * 5,
  236. filePath: fileFilter[index].path,
  237. success: (res) => {
  238. console.log('uploadFile res', res);
  239. if (res.statusCode === 200) {
  240. const { data } = res;
  241. const jsonData = JSON.parse(data);
  242. console.log('jsonData', jsonData);
  243. if (jsonData.code == -3){
  244. uni.hideLoading()
  245. uni.showModal({
  246. title: '请先登录',
  247. success: (res) => {
  248. if (res.confirm) {
  249. uni.redirectTo({
  250. url: '/pages/index/index'
  251. });
  252. }
  253. },
  254. });
  255. return
  256. }
  257. if (jsonData.count === 0) {
  258. const { relativePath } = jsonData.data;
  259. urls.push(relativePath);
  260. index++;
  261. if (index >= filesLength) {
  262. resolve(true);
  263. } else {
  264. setTimeout(() => {
  265. start();
  266. }, 200);
  267. }
  268. } else {
  269. index++;
  270. }
  271. } else {
  272. index++;
  273. setTimeout(() => {
  274. uni.showModal({
  275. title: '上传失败',
  276. success: (res) => {}
  277. });
  278. }, 500);
  279. }
  280. }
  281. });
  282. };
  283. start();
  284. });
  285. };
  286. const flag = await startUpload();
  287. if (flag) {
  288. uni.hideLoading();
  289. // setTimeout(() => {
  290. // uni.showModal({
  291. // title: '上传失败',
  292. // success: (res) => {}
  293. // });
  294. // }, 500);
  295. resolve(urls);
  296. } else {
  297. reject(null);
  298. }
  299. });
  300. };
  301. // 上传
  302. export const uploadFile = (params = {}) => {
  303. const { dir = '', filePath, isVideo, size = '' } = params;
  304. let header = {
  305. 'Content-Type': 'application/json;charset=UTF-8',
  306. userId: userStore.getSiteId,
  307. Authorization: userStore.getToken
  308. };
  309. let sizeMsg = size ? `当前文件大小${size}M` : '';
  310. return new Promise((resolve, reject) => {
  311. if (!isVideo) uni.showLoading({ mask: true, title: '上传中' });
  312. let str = dir ? '?typeId=' + dir : '';
  313. let uploadTask = uni.uploadFile({
  314. url: APIURL + str,
  315. name: 'file',
  316. filePath,
  317. header,
  318. timeout: 1000 * 60 * 10,
  319. success: (res) => {
  320. if (res.statusCode === 200) {
  321. const { data } = res;
  322. const jsonData = JSON.parse(data);
  323. console.log('uploadFile.jsonData', jsonData);
  324. if (jsonData.code == 1) {
  325. const { relativePath } = jsonData.data;
  326. resolve(relativePath);
  327. } else {
  328. uni.showModal({
  329. title: jsonData.msg,
  330. success: (res) => {}
  331. });
  332. reject(new Error(jsonData.msg || '上传失败'));
  333. }
  334. } else {
  335. setTimeout(() => {
  336. uni.showModal({
  337. title: `接口错误!请重新上传!${sizeMsg}`,
  338. success: (res) => {}
  339. });
  340. }, 500);
  341. reject(new Error('接口错误'));
  342. }
  343. },
  344. fail: (err) => {
  345. setTimeout(() => {
  346. uni.showModal({
  347. title: `上传超时 ${sizeMsg}`,
  348. success: (res) => {}
  349. });
  350. }, 500);
  351. reject(err || new Error('上传失败'));
  352. },
  353. complete: () => {
  354. uni.hideLoading();
  355. }
  356. });
  357. uploadTask.onProgressUpdate((res) => {
  358. let progressText = '上传进度:' + res.progress + '%';
  359. if (res.progress === 100) {
  360. progressText = '上传完成';
  361. setTimeout(() => {
  362. progressText = '';
  363. }, 1500);
  364. }
  365. if (isVideo) {
  366. userStore.setUploadProgress(progressText);
  367. } else {
  368. uni.showLoading({ mask: true, title: progressText });
  369. }
  370. });
  371. });
  372. };