沙钢智慧能源系统前端代码
houzhongjian
2024-10-09 314507f8ddadd9c66e98d260c3b2a5dad1a04015
提交 | 用户 | 时间
314507 1 import * as FileApi from '@/api/infra/file'
H 2 import CryptoJS from 'crypto-js'
3 import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload'
4 import axios from 'axios'
5
6 export const useUpload = () => {
7   // 后端上传地址
8   const uploadUrl = import.meta.env.VITE_UPLOAD_URL
9   // 是否使用前端直连上传
10   const isClientUpload = UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE
11   // 重写ElUpload上传方法
12   const httpRequest = async (options: UploadRequestOptions) => {
13     // 模式一:前端上传
14     if (isClientUpload) {
15       // 1.1 生成文件名称
16       const fileName = await generateFileName(options.file)
17       // 1.2 获取文件预签名地址
18       const presignedInfo = await FileApi.getFilePresignedUrl(fileName)
19       // 1.3 上传文件(不能使用 ElUpload 的 ajaxUpload 方法的原因:其使用的是 FormData 上传,Minio 不支持)
20       return axios.put(presignedInfo.uploadUrl, options.file, {
21         headers: {
22           'Content-Type': options.file.type,
23         }
24       }).then(() => {
25         // 1.4. 记录文件信息到后端(异步)
26         createFile(presignedInfo, fileName, options.file)
27         // 通知成功,数据格式保持与后端上传的返回结果一致
28         return { data: presignedInfo.url }
29       })
30     } else {
31       // 模式二:后端上传
32       // 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子
33       return new Promise((resolve, reject) => {
34         FileApi.updateFile({ file: options.file })
35           .then((res) => {
36             if (res.code === 0) {
37               resolve(res)
38             } else {
39               reject(res)
40             }
41           })
42           .catch((res) => {
43             reject(res)
44           })
45       })
46     }
47   }
48
49   return {
50     uploadUrl,
51     httpRequest
52   }
53 }
54
55 /**
56  * 创建文件信息
57  * @param vo 文件预签名信息
58  * @param name 文件名称
59  * @param file 文件
60  */
61 function createFile(vo: FileApi.FilePresignedUrlRespVO, name: string, file: UploadRawFile) {
62   const fileVo = {
63     configId: vo.configId,
64     url: vo.url,
65     path: name,
66     name: file.name,
67     type: file.type,
68     size: file.size
69   }
70   FileApi.createFile(fileVo)
71   return fileVo
72 }
73
74 /**
75  * 生成文件名称(使用算法SHA256)
76  * @param file 要上传的文件
77  */
78 async function generateFileName(file: UploadRawFile) {
79   // 读取文件内容
80   const data = await file.arrayBuffer()
81   const wordArray = CryptoJS.lib.WordArray.create(data)
82   // 计算SHA256
83   const sha256 = CryptoJS.SHA256(wordArray).toString()
84   // 拼接后缀
85   const ext = file.name.substring(file.name.lastIndexOf('.'))
86   return `${sha256}${ext}`
87 }
88
89 /**
90  * 上传类型
91  */
92 enum UPLOAD_TYPE {
93   // 客户端直接上传(只支持S3服务)
94   CLIENT = 'client',
95   // 客户端发送到后端上传
96   SERVER = 'server'
97 }