reactor:【INFRA】文件上传 api,增加 directory 参数,去除 path 参数,并支持按照日期分目录、文件名不再使用 sha256 而是时间戳

This commit is contained in:
YunaiV 2025-05-02 19:58:59 +08:00
parent 8c4e1b7c72
commit f5b48f8e8c
5 changed files with 29 additions and 23 deletions

View File

@ -8,6 +8,8 @@ export interface FilePresignedUrlRespVO {
uploadUrl: string uploadUrl: string
// 文件 URL // 文件 URL
url: string url: string
// 文件路径
path: string
} }
// 查询文件列表 // 查询文件列表
@ -21,10 +23,10 @@ export const deleteFile = (id: number) => {
} }
// 获取文件预签名地址 // 获取文件预签名地址
export const getFilePresignedUrl = (path: string) => { export const getFilePresignedUrl = (name: string, directory?: string) => {
return request.get<FilePresignedUrlRespVO>({ return request.get<FilePresignedUrlRespVO>({
url: '/infra/file/presigned-url', url: '/infra/file/presigned-url',
params: { path } params: { name, directory }
}) })
} }

View File

@ -86,7 +86,8 @@ const props = defineProps({
autoUpload: propTypes.bool.def(true), // autoUpload: propTypes.bool.def(true), //
drag: propTypes.bool.def(false), // drag: propTypes.bool.def(false), //
isShowTip: propTypes.bool.def(true), // isShowTip: propTypes.bool.def(true), //
disabled: propTypes.bool.def(false) // ==> false disabled: propTypes.bool.def(false), // ==> false
directory: propTypes.string.def(undefined) // ==> undefined
}) })
// ========== ========== // ========== ==========
@ -95,7 +96,7 @@ const uploadList = ref<UploadUserFile[]>([])
const fileList = ref<UploadUserFile[]>([]) const fileList = ref<UploadUserFile[]>([])
const uploadNumber = ref<number>(0) const uploadNumber = ref<number>(0)
const { uploadUrl, httpRequest } = useUpload() const { uploadUrl, httpRequest } = useUpload(props.directory)
// //
const beforeUpload: UploadProps['beforeUpload'] = (file: UploadRawFile) => { const beforeUpload: UploadProps['beforeUpload'] = (file: UploadRawFile) => {

View File

@ -79,7 +79,8 @@ const props = defineProps({
width: propTypes.string.def('150px'), // ==> 150px width: propTypes.string.def('150px'), // ==> 150px
borderradius: propTypes.string.def('8px'), // ==> 8px borderradius: propTypes.string.def('8px'), // ==> 8px
showDelete: propTypes.bool.def(true), // showDelete: propTypes.bool.def(true), //
showBtnText: propTypes.bool.def(true) // showBtnText: propTypes.bool.def(true), //
directory: propTypes.string.def(undefined) // ==> undefined
}) })
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
@ -99,7 +100,7 @@ const deleteImg = () => {
emit('update:modelValue', '') emit('update:modelValue', '')
} }
const { uploadUrl, httpRequest } = useUpload() const { uploadUrl, httpRequest } = useUpload(props.directory)
const editImg = () => { const editImg = () => {
const dom = document.querySelector(`#${uuid.value} .el-upload__input`) const dom = document.querySelector(`#${uuid.value} .el-upload__input`)

View File

@ -81,10 +81,11 @@ const props = defineProps({
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // ==> ["image/jpeg", "image/png", "image/gif"] fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // ==> ["image/jpeg", "image/png", "image/gif"]
height: propTypes.string.def('150px'), // ==> 150px height: propTypes.string.def('150px'), // ==> 150px
width: propTypes.string.def('150px'), // ==> 150px width: propTypes.string.def('150px'), // ==> 150px
borderradius: propTypes.string.def('8px') // ==> 8px borderradius: propTypes.string.def('8px'), // ==> 8px
directory: propTypes.string.def(undefined) // ==> undefined
}) })
const { uploadUrl, httpRequest } = useUpload() const { uploadUrl, httpRequest } = useUpload(props.directory)
const fileList = ref<UploadUserFile[]>([]) const fileList = ref<UploadUserFile[]>([])
const uploadNumber = ref<number>(0) const uploadNumber = ref<number>(0)

View File

@ -1,5 +1,5 @@
import * as FileApi from '@/api/infra/file' import * as FileApi from '@/api/infra/file'
import CryptoJS from 'crypto-js' // import CryptoJS from 'crypto-js'
import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload' import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload'
import axios from 'axios' import axios from 'axios'
@ -10,7 +10,7 @@ export const getUploadUrl = (): string => {
return import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload' return import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload'
} }
export const useUpload = () => { export const useUpload = (directory?: string) => {
// 后端上传地址 // 后端上传地址
const uploadUrl = getUploadUrl() const uploadUrl = getUploadUrl()
// 是否使用前端直连上传 // 是否使用前端直连上传
@ -22,7 +22,7 @@ export const useUpload = () => {
// 1.1 生成文件名称 // 1.1 生成文件名称
const fileName = await generateFileName(options.file) const fileName = await generateFileName(options.file)
// 1.2 获取文件预签名地址 // 1.2 获取文件预签名地址
const presignedInfo = await FileApi.getFilePresignedUrl(fileName) const presignedInfo = await FileApi.getFilePresignedUrl(fileName, directory)
// 1.3 上传文件(不能使用 ElUpload 的 ajaxUpload 方法的原因:其使用的是 FormData 上传Minio 不支持) // 1.3 上传文件(不能使用 ElUpload 的 ajaxUpload 方法的原因:其使用的是 FormData 上传Minio 不支持)
return axios return axios
.put(presignedInfo.uploadUrl, options.file, { .put(presignedInfo.uploadUrl, options.file, {
@ -32,7 +32,7 @@ export const useUpload = () => {
}) })
.then(() => { .then(() => {
// 1.4. 记录文件信息到后端(异步) // 1.4. 记录文件信息到后端(异步)
createFile(presignedInfo, fileName, options.file) createFile(presignedInfo, options.file)
// 通知成功,数据格式保持与后端上传的返回结果一致 // 通知成功,数据格式保持与后端上传的返回结果一致
return { data: presignedInfo.url } return { data: presignedInfo.url }
}) })
@ -40,7 +40,7 @@ export const useUpload = () => {
// 模式二:后端上传 // 模式二:后端上传
// 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子 // 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
FileApi.updateFile({ file: options.file }) FileApi.updateFile({ file: options.file, directory })
.then((res) => { .then((res) => {
if (res.code === 0) { if (res.code === 0) {
resolve(res) resolve(res)
@ -67,11 +67,11 @@ export const useUpload = () => {
* @param name * @param name
* @param file * @param file
*/ */
function createFile(vo: FileApi.FilePresignedUrlRespVO, name: string, file: UploadRawFile) { function createFile(vo: FileApi.FilePresignedUrlRespVO, file: UploadRawFile) {
const fileVo = { const fileVo = {
configId: vo.configId, configId: vo.configId,
url: vo.url, url: vo.url,
path: name, path: vo.path,
name: file.name, name: file.name,
type: file.type, type: file.type,
size: file.size size: file.size
@ -85,14 +85,15 @@ function createFile(vo: FileApi.FilePresignedUrlRespVO, name: string, file: Uplo
* @param file * @param file
*/ */
async function generateFileName(file: UploadRawFile) { async function generateFileName(file: UploadRawFile) {
// 读取文件内容 // // 读取文件内容
const data = await file.arrayBuffer() // const data = await file.arrayBuffer()
const wordArray = CryptoJS.lib.WordArray.create(data) // const wordArray = CryptoJS.lib.WordArray.create(data)
// 计算SHA256 // // 计算SHA256
const sha256 = CryptoJS.SHA256(wordArray).toString() // const sha256 = CryptoJS.SHA256(wordArray).toString()
// 拼接后缀 // // 拼接后缀
const ext = file.name.substring(file.name.lastIndexOf('.')) // const ext = file.name.substring(file.name.lastIndexOf('.'))
return `${sha256}${ext}` // return `${sha256}${ext}`
return file.name
} }
/** /**