index.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { config } from "@/config";
  2. import { request } from "../service";
  3. import { basename, extname, filename, parse, parseObject, pathJoin, uuid } from "../utils";
  4. import { useStore } from "../store";
  5. // 上传进度回调结果类型
  6. export type OnProgressUpdateResult = {
  7. progress: number;
  8. totalBytesSent: number;
  9. totalBytesExpectedToSend: number;
  10. };
  11. // 上传任务类型定义
  12. export type UploadTask = {
  13. abort(): void;
  14. };
  15. // 上传选项类型定义
  16. export type UploadOptions = {
  17. onProgressUpdate?: (result: OnProgressUpdateResult) => void; // 上传进度回调
  18. onTask?: (task: UploadTask) => void; // 上传任务回调
  19. };
  20. // 上传模式类型
  21. export type UploadMode = {
  22. mode: "local" | "cloud"; // 上传模式:本地或云端
  23. type: string; // 云服务类型
  24. };
  25. // 上传请求的参数类型
  26. export type UploadRequestOptions = {
  27. url: string;
  28. preview?: string;
  29. data: any;
  30. };
  31. // 云上传返回数据类型
  32. export type CloudUploadResponse = {
  33. uploadUrl?: string;
  34. url?: string;
  35. host?: string;
  36. credentials?: any;
  37. OSSAccessKeyId?: string;
  38. policy?: string;
  39. signature?: string;
  40. publicDomain?: string;
  41. token?: string;
  42. fields?: any;
  43. };
  44. // 本地上传返回数据类型
  45. export type LocalUploadResponse = {
  46. code: number;
  47. message?: string;
  48. data: string;
  49. };
  50. /**
  51. * 路径上传
  52. * @param path 文件路径
  53. */
  54. export async function upload(path: string) {
  55. return uploadFile({
  56. path,
  57. size: 0,
  58. name: "",
  59. type: "image/png"
  60. });
  61. }
  62. /**
  63. * 文件上传
  64. * @param file 文件信息 ChooseImageTempFile
  65. * @param options 上传选项
  66. */
  67. export async function uploadFile(
  68. file: ChooseImageTempFile,
  69. options: UploadOptions | null = null
  70. ): Promise<string> {
  71. const { user } = useStore();
  72. // 获取文件路径
  73. const filePath = file.path;
  74. // 获取文件名
  75. let fileName = file.name;
  76. // 如果文件名不存在,则使用文件路径的文件名
  77. if (fileName == "" || fileName == null) {
  78. fileName = basename(filePath);
  79. }
  80. // 获取文件扩展名
  81. let ext = extname(fileName);
  82. if (ext == "") {
  83. ext = "png";
  84. }
  85. // 生成唯一key: 原文件名_uuid.扩展名
  86. let key = `${filename(fileName)}_${uuid()}.${ext}`;
  87. // 支持多种上传方式
  88. return new Promise((resolve, reject) => {
  89. /**
  90. * 实际上传文件的函数
  91. * @param param0 上传参数
  92. */
  93. function next({ url, preview, data }: UploadRequestOptions) {
  94. // 发起上传请求
  95. const task = uni.uploadFile({
  96. url,
  97. filePath,
  98. name: "file",
  99. header: {
  100. // 本地上传带token
  101. Authorization: user.token
  102. },
  103. formData: {
  104. ...(data as UTSJSONObject),
  105. key
  106. },
  107. success(res) {
  108. // 本地上传返回处理
  109. const { code, data, message } = parseObject<LocalUploadResponse>(res.data)!;
  110. resolve(data);
  111. },
  112. fail(err) {
  113. console.error(err);
  114. reject(err);
  115. }
  116. });
  117. // 上传任务回调
  118. if (options?.onTask != null) {
  119. options.onTask!({
  120. abort: () => {
  121. task.abort();
  122. }
  123. } as UploadTask);
  124. }
  125. // 上传进度回调
  126. if (options?.onProgressUpdate != null) {
  127. task.onProgressUpdate((result) => {
  128. const { progress, totalBytesSent, totalBytesExpectedToSend } = result;
  129. options.onProgressUpdate!({
  130. progress,
  131. totalBytesSent,
  132. totalBytesExpectedToSend
  133. });
  134. });
  135. }
  136. }
  137. // 本地上传
  138. next({
  139. url: config.baseUrl + "/upms/files/upload",
  140. data: {}
  141. });
  142. });
  143. }