合同小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
8.2 KiB

1 week ago
  1. // @ts-nocheck
  2. import { UploadFile, ChooseFileOptions, Oversize } from './type'
  3. // import { chooseFile, ChooseFileOption, ChooseFileSuccessCallbackResult } from '@/uni_modules/lime-choose-file'
  4. /**
  5. * ios上不支持返回上传文件的fileType
  6. * @param mediaType
  7. * @param tempFilePath
  8. * @returns string
  9. * @link https://developers.weixin.qq.com/community/develop/doc/00042820b28ee8fb41fc4d0c254c00
  10. */
  11. export function getFileType(tempFilePath : string, fileType ?: string) : string {
  12. if (fileType != null) return fileType.replace(/\/.+/,''); // 如果有返回fileType就直接用
  13. // 否则根据文件后缀进行判读
  14. const videoType = ['avi', 'wmv', 'mkv', 'mp4', 'mov', 'rm', '3gp', 'flv', 'mpg', 'rmvb'];
  15. const temp = tempFilePath.split('.');
  16. const postfix = temp[temp.length - 1];
  17. if (videoType.includes(postfix.toLocaleLowerCase())) {
  18. return 'video';
  19. }
  20. return 'image';
  21. }
  22. // 选中文件之后,计算一个随机的短文件名
  23. // export function getRandFileName(filePath: string):string {
  24. // const extIndex = filePath.lastIndexOf('.');
  25. // const extName = extIndex === -1 ? '' : filePath.substr(extIndex);
  26. // return parseInt(`${Date.now()}${Math.floor(Math.random() * 900 + 100)}`, 10).toString(36) + extName;
  27. // }
  28. export function getFileName(filePath: string): string {
  29. return filePath.substring(filePath.lastIndexOf('/') + 1)
  30. }
  31. export const isOverSize = (size:number, sizeLimit:number|null):boolean => {
  32. if (sizeLimit == null) return false;
  33. const base = 1000;
  34. // const unitMap = {
  35. // B: 1,
  36. // KB: base,
  37. // MB: base * base,
  38. // GB: base * base * base,
  39. // };
  40. const computedSize = sizeLimit * base
  41. // const computedSize = typeof sizeLimit == 'number' ? sizeLimit * base : sizeLimit?.size * unitMap[sizeLimit?.unit ?? 'KB']; // 单位 KB
  42. return size > computedSize;
  43. };
  44. export function chooseImage(opts : ChooseFileOptions) {
  45. // #ifdef MP-WEIXIN
  46. uni.chooseMedia({
  47. ...opts,
  48. mediaType: ['image'],
  49. })
  50. // #endif
  51. // #ifndef MP-WEIXIN
  52. uni.chooseImage({
  53. count: opts.count,
  54. sizeType: opts.sizeType,
  55. sourceType: opts.sourceType,
  56. extension: opts.extension,
  57. success(res){
  58. opts.success?.(res)
  59. },
  60. fail(err) {
  61. opts.fail?.(err)
  62. }
  63. })
  64. // #endif
  65. }
  66. export function chooseVideo(opts : ChooseFileOptions) {
  67. // #ifdef MP-WEIXIN
  68. uni.chooseMedia({
  69. ...opts,
  70. mediaType: ['video'],
  71. maxDuration: opts.maxDuration ?? 10,
  72. })
  73. // #endif
  74. // #ifndef MP-WEIXIN
  75. uni.chooseVideo({
  76. sourceType: opts.sourceType,
  77. // #ifndef APP-ANDROID || APP-IOS
  78. // compressed: opts.compressed ?? true,
  79. maxDuration: opts.maxDuration ?? 10,
  80. camera: opts.camera ?? 'back',
  81. // extension: opts.extension,
  82. // #endif
  83. success(res){
  84. opts.success?.(res)
  85. },
  86. fail(err) {
  87. opts.fail?.(err)
  88. }
  89. })
  90. // #endif
  91. }
  92. export function chooseAll(opts : ChooseFileOptions) {
  93. // #ifdef MP-WEIXIN
  94. uni.chooseMessageFile({
  95. ...opts,
  96. type: 'all',
  97. })
  98. // #endif
  99. // #ifndef MP-WEIXIN || APP-IOS || APP-ANDROID
  100. uni.chooseFile({
  101. count: opts.count,
  102. type: 'all',
  103. success(res) {
  104. opts.success?.(res)
  105. },
  106. fail(err) {
  107. opts.fail?.(err)
  108. }
  109. } as ChooseFileOption)
  110. // #endif
  111. // #ifdef APP-ANDROID
  112. // uni.chooseFile({
  113. // count: opts.count,
  114. // type: 'all',
  115. // success(res) {
  116. // opts.success?.(res)
  117. // },
  118. // fail(err) {
  119. // opts.fail?.(err)
  120. // }
  121. // })
  122. // #endif
  123. // #ifdef uniVersion >= 4.51
  124. // #ifdef APP-IOS || APP-ANDROID
  125. uni.chooseMedia({
  126. count: opts.count,
  127. mediaType: [opts.mediaType],
  128. sourceType: opts.sourceType,
  129. maxDuration: opts.maxDuration ?? 10,
  130. camera: opts.camera ?? 'back',
  131. success(res) {
  132. opts.success?.(res)
  133. },
  134. fail(err) {
  135. opts.fail?.(err)
  136. }
  137. })
  138. // opts.fail?.('当前环境不支持')
  139. // chooseFile({
  140. // count: opts.count,
  141. // type: 'all',
  142. // success(res) {
  143. // opts.success?.(res)
  144. // },
  145. // fail(err) {
  146. // opts.fail?.(err)
  147. // }
  148. // } as ChooseFileOption)
  149. // #endif
  150. // #endif
  151. }
  152. function normalizeChooseFiles(
  153. type: string,
  154. tempFiles: UTSJSONObject[], //ChooseImageTempFile
  155. tempFilePaths:string[],
  156. sizeLimit:number|null,
  157. oversize: Oversize | null
  158. ):UploadFile[]{
  159. const files : UploadFile[] = [];
  160. tempFiles.forEach((temp, index) =>{
  161. const tempFilePath = (temp['tempFilePath'] as string | null) ?? tempFilePaths[index]
  162. const name = (temp['name'] as string | null) ?? getFileName(tempFilePath);
  163. const size = (temp['size'] as number | null) ?? 0;
  164. const width = (temp['width'] as number | null);
  165. const height = (temp['height'] as number | null)
  166. const duration = (temp['duration'] as number | null);
  167. const path = (temp['path'] as string | null) ?? tempFilePath;
  168. const thumb = (temp['thumbTempFilePath'] as string | null);
  169. const _type = (type == 'all' ? getFileType(tempFilePath, temp['type'] as string | null) : type) as "video" | "image";
  170. if (isOverSize(size, sizeLimit)) {
  171. oversize?.(temp)
  172. return
  173. };
  174. files.push({
  175. name,
  176. type: _type,
  177. url: path,
  178. path,
  179. size,
  180. width,
  181. height,
  182. duration,
  183. thumb,
  184. percent: 0,
  185. // status: 'done'
  186. } as UploadFile)
  187. })
  188. return files
  189. }
  190. export function chooseFiles(opts: ChooseFileOptions):Promise<UploadFile[]> {
  191. return new Promise((resolve, reject)=>{
  192. if(opts.mediaType == 'image') {
  193. chooseImage({
  194. count: opts.count,
  195. mediaType: opts.mediaType,
  196. sizeType: opts.sizeType,
  197. sourceType: opts.sourceType,
  198. success(result: any){
  199. const res = result as ChooseImageSuccess
  200. // #ifndef APP-ANDROID || APP-IOS
  201. const tempFiles = res.tempFiles as UTSJSONObject[]
  202. const tempFilePaths = (res.tempFilePaths ?? []) as string[]
  203. // #endif
  204. // #ifdef APP-ANDROID || APP-IOS
  205. const tempFilePaths = res.tempFilePaths
  206. const tempFiles = res.tempFiles.map((item):UTSJSONObject => {
  207. return {
  208. name: item.name,
  209. path: item.path,
  210. size: item.size,
  211. type: item.type
  212. }
  213. })
  214. // #endif
  215. const files = normalizeChooseFiles('image', tempFiles, tempFilePaths, opts.sizeLimit, opts.oversize)
  216. resolve(files)
  217. }
  218. } as ChooseFileOptions)
  219. } else if(opts.mediaType == 'video') {
  220. chooseVideo({
  221. count: opts.count,
  222. mediaType: opts.mediaType,
  223. sourceType: opts.sourceType,
  224. sizeType: opts.sizeType,
  225. maxDuration: opts.maxDuration,
  226. success(result) {
  227. const res = result as ChooseVideoSuccess
  228. // #ifndef APP-ANDROID || APP-IOS
  229. const tempFilePaths = res.tempFilePaths ?? [res.tempFilePath] as string[]
  230. const tempFiles = res.tempFiles ?? [res.tempFile] as UTSJSONObject[]
  231. // #endif
  232. // #ifdef APP-ANDROID || APP-IOS
  233. const tempFilePaths = [res.tempFilePath] as string[]
  234. const {tempFilePath, duration, size, height, width} = res
  235. const tempFiles = [{path: tempFilePath, duration, duration, size, height, width}] as UTSJSONObject[]
  236. // #endif
  237. const files = normalizeChooseFiles('video', tempFiles, tempFilePaths, opts.sizeLimit, opts.oversize)
  238. resolve(files)
  239. }
  240. } as ChooseFileOptions)
  241. } else {
  242. chooseAll({
  243. count: opts.count,
  244. mediaType: opts.mediaType,
  245. sourceType: opts.sourceType,
  246. sizeType: opts.sizeType,
  247. success(result: any){
  248. // #ifndef APP-ANDROID || APP-IOS
  249. const res = result as ChooseFileSuccessCallbackResult
  250. const tempFilePaths = res.tempFiles
  251. const tempFiles = res.tempFiles
  252. const files = normalizeChooseFiles('all', tempFiles, tempFilePaths, opts.sizeLimit, opts.oversize)
  253. resolve(files)
  254. // #endif
  255. // #ifdef uniVersion < 4.51
  256. reject('当前环境不支持')
  257. // const tempFilePaths = res.tempFiles.map((it):string => it.path)
  258. // const tempFiles = res.tempFiles.map((it):UTSJSONObject => ({name: it.name, path: it.path, size: it.size, type: it.type}));
  259. // #endif
  260. // #ifdef uniVersion >= 4.51
  261. // #ifdef APP-ANDROID || APP-IOS
  262. const res = result as ChooseMediaSuccess // ChooseFileSuccess
  263. const tempFilePaths = res.tempFiles.map((it):string => it.tempFilePath)
  264. const tempFiles = res.tempFiles.map((it):UTSJSONObject => ({path: it.tempFilePath, size: it.size}));
  265. const files = normalizeChooseFiles('all', tempFiles, tempFilePaths, opts.sizeLimit, opts.oversize)
  266. resolve(files)
  267. // #endif
  268. // #endif
  269. }
  270. } as ChooseFileOptions)
  271. }
  272. })
  273. }