fix:富文本多选图片上传失败的问题(同时对 token 过期更友好),对应 https://t.zsxq.com/pKpGk

pull/855/head
YunaiV 2026-01-18 15:09:55 +08:00
parent 08a4b1b289
commit 62404bef25
1 changed files with 35 additions and 102 deletions

View File

@ -6,8 +6,7 @@ import { propTypes } from '@/utils/propTypes'
import { isNumber } from '@/utils/is' import { isNumber } from '@/utils/is'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { useLocaleStore } from '@/store/modules/locale' import { useLocaleStore } from '@/store/modules/locale'
import { getRefreshToken, getTenantId } from '@/utils/auth' import { useUpload } from '@/components/UploadFile/src/useUpload'
import { getUploadUrl } from '@/components/UploadFile/src/useUpload'
import merge from 'lodash-es/merge' import merge from 'lodash-es/merge'
defineOptions({ name: 'Editor' }) defineOptions({ name: 'Editor' })
@ -34,6 +33,10 @@ const props = defineProps({
const emit = defineEmits(['change', 'update:modelValue']) const emit = defineEmits(['change', 'update:modelValue'])
// 使用项目的上传方法,实现逐个文件上传
const { httpRequest: imageHttpRequest } = useUpload(`${props.directory}-image`)
const { httpRequest: videoHttpRequest } = useUpload(`${props.directory}-video`)
// 编辑器实例,必须用 shallowRef // 编辑器实例,必须用 shallowRef
const editorRef = shallowRef<IDomEditor>() const editorRef = shallowRef<IDomEditor>()
@ -114,7 +117,6 @@ const editorConfig = computed((): IEditorConfig => {
}, },
MENU_CONF: { MENU_CONF: {
['uploadImage']: { ['uploadImage']: {
server: getUploadUrl(),
// 单个文件的最大体积限制,默认为 2M // 单个文件的最大体积限制,默认为 2M
maxFileSize: 10 * 1024 * 1024, maxFileSize: 10 * 1024 * 1024,
// 最多可上传几个文件,默认为 100 // 最多可上传几个文件,默认为 100
@ -122,60 +124,25 @@ const editorConfig = computed((): IEditorConfig => {
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 [] // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['image/*'], allowedFileTypes: ['image/*'],
// 自定义增加 http header // 使用 customUpload 实现逐个文件上传,复用项目的 httpRequest
headers: { async customUpload(file: File, insertFn: InsertFnType) {
Accept: '*', try {
Authorization: 'Bearer ' + getRefreshToken(), // 使用 getRefreshToken() 方法,而不使用 getAccessToken() 方法的原因:Editor 无法方便的刷新访问令牌 const res = await imageHttpRequest({
'tenant-id': getTenantId() file: file as any,
}, onProgress: () => {},
onSuccess: () => {},
// 超时时间,默认为 10 秒 onError: () => {}
timeout: 15 * 1000, // 15 秒 } as any)
// 兼容前端直连上传和后端上传两种模式的返回格式
// form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image const url = (res as any).data?.data || (res as any).data
fieldName: 'file', insertFn(url, 'image', url)
// 附加参数 } catch (error: any) {
meta: { ElMessage.error(error.msg || '图片上传失败')
directory: `${props.directory}-image` console.error('Upload error:', error)
},
metaWithUrl: false,
// uppy 配置项
uppyConfig: {
onBeforeFileAdded: (newFile: any) => {
newFile.id = `${newFile.id}-${Date.now()}`
return newFile
} }
},
// 上传之前触发
onBeforeUpload(file: File) {
// console.log(file)
return file
},
// 上传进度的回调函数
onProgress(progress: number) {
// progress 是 0-100 的数字
console.log('progress', progress)
},
onSuccess(file: File, res: any) {
console.log('onSuccess', file, res)
},
onFailed(file: File, res: any) {
alert(res.message)
console.log('onFailed', file, res)
},
onError(file: File, err: any, res: any) {
alert(err.message)
console.error('onError', file, err, res)
},
// 自定义插入图片
customInsert(res: any, insertFn: InsertFnType) {
insertFn(res.data, 'image', res.data)
} }
}, },
['uploadVideo']: { ['uploadVideo']: {
server: getUploadUrl(),
// 单个文件的最大体积限制,默认为 10M // 单个文件的最大体积限制,默认为 10M
maxFileSize: 1024 * 1024 * 1024, maxFileSize: 1024 * 1024 * 1024,
// 最多可上传几个文件,默认为 100 // 最多可上传几个文件,默认为 100
@ -183,56 +150,22 @@ const editorConfig = computed((): IEditorConfig => {
// 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 [] // 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['video/*'], allowedFileTypes: ['video/*'],
// 自定义增加 http header // 使用 customUpload 实现逐个文件上传,复用项目的 httpRequest
headers: { async customUpload(file: File, insertFn: InsertFnType) {
Accept: '*', try {
Authorization: 'Bearer ' + getRefreshToken(), // 使用 getRefreshToken() 方法,而不使用 getAccessToken() 方法的原因:Editor 无法方便的刷新访问令牌 const res = await videoHttpRequest({
'tenant-id': getTenantId() file: file as any,
}, onProgress: () => {},
onSuccess: () => {},
// 超时时间,默认为 30 秒 onError: () => {}
timeout: 15 * 1000, // 15 秒 } as any)
// 兼容前端直连上传和后端上传两种模式的返回格式
// form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image const url = (res as any).data?.data || (res as any).data
fieldName: 'file', insertFn(url, 'mp4', url)
// 附加参数 } catch (error: any) {
meta: { ElMessage.error(error.msg || '视频上传失败')
directory: `${props.directory}-video` console.error('Upload error:', error)
},
metaWithUrl: false,
// uppy 配置项
uppyConfig: {
onBeforeFileAdded: (newFile: any) => {
newFile.id = `${newFile.id}-${Date.now()}`
return newFile
} }
},
// 上传之前触发
onBeforeUpload(file: File) {
// console.log(file)
return file
},
// 上传进度的回调函数
onProgress(progress: number) {
// progress 是 0-100 的数字
console.log('progress', progress)
},
onSuccess(file: File, res: any) {
console.log('onSuccess', file, res)
},
onFailed(file: File, res: any) {
alert(res.message)
console.log('onFailed', file, res)
},
onError(file: File, err: any, res: any) {
alert(err.message)
console.error('onError', file, err, res)
},
// 自定义插入图片
customInsert(res: any, insertFn: InsertFnType) {
insertFn(res.data, 'mp4', res.data)
} }
} }
}, },