Merge remote-tracking branch 'origin/master'
build / task (16.x, npm, macOS-latest) (push) Canceled after 0s
build / task (16.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, npm, windows-latest) (push) Canceled after 0s
build / task (16.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (16.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (16.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (16.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, yarn, windows-latest) (push) Canceled after 0s
build / task (18.x, npm, macOS-latest) (push) Canceled after 0s
build / task (18.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, npm, windows-latest) (push) Canceled after 0s
build / task (18.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (18.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (18.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (18.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, yarn, windows-latest) (push) Canceled after 0s
build / task (20.x, npm, macOS-latest) (push) Canceled after 0s
build / task (20.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, npm, windows-latest) (push) Canceled after 0s
build / task (20.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (20.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (20.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (20.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, yarn, windows-latest) (push) Canceled after 0s
build / task (16.x, npm, macOS-latest) (push) Canceled after 0s
build / task (16.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, npm, windows-latest) (push) Canceled after 0s
build / task (16.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (16.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (16.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (16.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, yarn, windows-latest) (push) Canceled after 0s
build / task (18.x, npm, macOS-latest) (push) Canceled after 0s
build / task (18.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, npm, windows-latest) (push) Canceled after 0s
build / task (18.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (18.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (18.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (18.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, yarn, windows-latest) (push) Canceled after 0s
build / task (20.x, npm, macOS-latest) (push) Canceled after 0s
build / task (20.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, npm, windows-latest) (push) Canceled after 0s
build / task (20.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (20.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (20.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (20.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, yarn, windows-latest) (push) Canceled after 0s
This commit is contained in:
commit
23dd3532bc
5 files changed
+109
-53
No files matched your search
@@ -21,3 +21,9 @@ VITE_IMAGE_BASE_PATH = https://www.pjzhhq.cn/api
|
||||
|
||||
# 代码生成服务地址
|
||||
VITE_GEN_PROXY_PATH = http://123.156.230.15:5003
|
||||
|
||||
|
||||
VITE_FILE_ACCESS_APP_ID="admin"
|
||||
VITE_FILE_ACCESS_KEY_ID="v1"
|
||||
VITE_FILE_ACCESS_KEY="5UhL2DT+y//+0qCF4Abm9h6MPbEOvJfGuLf2eZ28QSw="
|
||||
VITE_FILE_ACCESS_ALLOWED_ORIGINS="https://www.pjzhhq.cn,https://stgl.pj.gov.cn"
|
||||
@@ -66,7 +66,7 @@ interface UploadFileProps {
|
||||
drag?: boolean // 是否支持拖拽上传 ==> 非必传(默认为 true)
|
||||
disabled?: boolean // 是否禁用上传组件 ==> 非必传(默认为 false)
|
||||
fileSize?: number // 图片大小限制 ==> 非必传(默认为 5M)
|
||||
fileType?: File.ImageMimeType[] // 图片类型限制 ==> 非必传(默认为 ["image/jpeg", "image/png", "image/gif"])
|
||||
fileType?: string[] // 图片类型限制 ==> 非必传(默认 JPEG、PNG、GIF、WebP)
|
||||
height?: string // 组件高度 ==> 非必传(默认为 150px)
|
||||
width?: string // 组件宽度 ==> 非必传(默认为 150px)
|
||||
borderRadius?: string // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
@@ -82,7 +82,7 @@ const props = withDefaults(defineProps<UploadFileProps>(), {
|
||||
drag: true,
|
||||
disabled: false,
|
||||
fileSize: 5,
|
||||
fileType: () => ["image/jpeg", "image/png", "image/gif"],
|
||||
fileType: () => ["image/jpeg", "image/png", "image/gif", "image/webp"],
|
||||
height: "150px",
|
||||
width: "150px",
|
||||
borderRadius: "8px",
|
||||
@@ -116,21 +116,17 @@ const handleHttpUpload = async (options: UploadRequestOptions) => {
|
||||
let formData = new FormData()
|
||||
formData.append("file", options.file)
|
||||
formData.append("dir", props.dir)
|
||||
try {
|
||||
const { data } = await request({
|
||||
url: props.uploadFileUrl,
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
emit("update:imageUrl", data.url)
|
||||
// 调用 el-form 内部的校验方法(可自动校验)
|
||||
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string])
|
||||
} catch (error) {
|
||||
options.onError(error as any)
|
||||
}
|
||||
const { data } = await request({
|
||||
url: props.uploadFileUrl,
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
emit("update:imageUrl", data.url)
|
||||
// 调用 el-form 内部的校验方法(可自动校验)
|
||||
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string])
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,10 +182,10 @@ const uploadSuccess = () => {
|
||||
/**
|
||||
* @description 图片上传错误
|
||||
* */
|
||||
const uploadError = () => {
|
||||
const uploadError = (error: any) => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "图片上传失败,请您重新上传!",
|
||||
message: error?.msg || error?.message || "图片上传失败,请您重新上传!",
|
||||
type: "error",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ interface UploadFileProps {
|
||||
}
|
||||
const props = withDefaults(defineProps<UploadFileProps>(), {
|
||||
disabled: false,
|
||||
fileType: () => ["image/jpeg", "image/png", "image/gif"],
|
||||
fileType: () => ["image/jpeg", "image/png", "image/gif", "image/webp"],
|
||||
fileSize: 5,
|
||||
height: "150px",
|
||||
width: "150px",
|
||||
@@ -66,20 +66,16 @@ const formContext = inject(formContextKey, void 0)
|
||||
const handleHttpUpload = async (options: UploadRequestOptions) => {
|
||||
let formData = new FormData()
|
||||
formData.append("file", options.file)
|
||||
try {
|
||||
const res = await request({
|
||||
url: "/admin/sys-file/upload",
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
if (res.code == 0) {
|
||||
return res
|
||||
}
|
||||
} catch (error) {
|
||||
options.onError(error as any)
|
||||
const res = await request({
|
||||
url: "/admin/sys-file/upload",
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
if (res.code == 0) {
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,10 +147,10 @@ const handleRemove = (uploadFile: any, uploadFiles: any[]) => {
|
||||
/**
|
||||
* @description 图片上传错误
|
||||
* */
|
||||
const uploadError = () => {
|
||||
const uploadError = (error: any) => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "图片上传失败,请您重新上传!",
|
||||
message: error?.msg || error?.message || "图片上传失败,请您重新上传!",
|
||||
type: "error",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ interface UploadFileProps {
|
||||
}
|
||||
const props = withDefaults(defineProps<UploadFileProps>(), {
|
||||
disabled: false,
|
||||
fileType: () => ["image/jpeg", "image/png", "image/gif"],
|
||||
fileType: () => ["image/jpeg", "image/png", "image/gif", "image/webp"],
|
||||
fileSize: 5,
|
||||
height: "150px",
|
||||
width: "150px",
|
||||
@@ -51,20 +51,16 @@ const formContext = inject(formContextKey, void 0)
|
||||
const handleHttpUpload = async (options: UploadRequestOptions) => {
|
||||
let formData = new FormData()
|
||||
formData.append("file", options.file)
|
||||
try {
|
||||
const res = await request({
|
||||
url: "/admin/sys-file/qn/upload",
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
if (res.code == 0) {
|
||||
return res
|
||||
}
|
||||
} catch (error) {
|
||||
options.onError(error as any)
|
||||
const res = await request({
|
||||
url: "/admin/sys-file/qn/upload",
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
if (res.code == 0) {
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,10 +133,10 @@ const handleRemove = (uploadFile: any, uploadFiles: any[]) => {
|
||||
/**
|
||||
* @description 图片上传错误
|
||||
* */
|
||||
const uploadError = () => {
|
||||
const uploadError = (error: any) => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "图片上传失败,请您重新上传!",
|
||||
message: error?.msg || error?.message || "图片上传失败,请您重新上传!",
|
||||
type: "error",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
const { test } = require('node:test')
|
||||
const assert = require('node:assert/strict')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const vue = require('vue')
|
||||
const { parse, compileScript } = require('@vue/compiler-sfc')
|
||||
const { compile, root } = require('./helpers/file-access-runtime.cjs')
|
||||
|
||||
function setup(name, request) {
|
||||
const notifications = [], events = [], model = vue.ref('')
|
||||
const descriptor = parse(fs.readFileSync(path.join(root, 'src/components/Upload', name), 'utf8')).descriptor
|
||||
const loaded = { exports: {} }
|
||||
const mockVue = { ...vue, inject() {}, onMounted() {}, onBeforeUnmount() {}, useModel: () => model }
|
||||
const mocks = {
|
||||
vue: mockVue,
|
||||
'element-plus': { ElNotification: value => notifications.push(value), formContextKey: Symbol(), formItemContextKey: Symbol() },
|
||||
'@element-plus/icons-vue': {},
|
||||
'/@/utils/request': { default: request },
|
||||
'/@/utils/other': { generateUUID: () => 'upload-test' },
|
||||
'/@/utils/file-access': { fileUrl: value => value, originalFileUrl: value => value, resolveFileUrl: value => value },
|
||||
'/@/utils/file-access-dom': { bindFileAccessDom() {} },
|
||||
}
|
||||
const globals = { inject: mockVue.inject, computed: vue.computed, onMounted() {}, onBeforeUnmount() {} }
|
||||
const source = compileScript(descriptor, { id: name }).content.replace(/import\.meta\.env/g, '({})')
|
||||
new Function('module', 'exports', 'require', ...Object.keys(globals), compile(source))(
|
||||
loaded, loaded.exports, key => key in mocks ? mocks[key] : require(key), ...Object.values(globals))
|
||||
const props = {}
|
||||
for (const [name, settings] of Object.entries(loaded.exports.default.props)) {
|
||||
if ('default' in settings) props[name] = typeof settings.default === 'function' ? settings.default() : settings.default
|
||||
}
|
||||
const state = loaded.exports.default.setup(props, { expose() {}, emit: (...args) => events.push(args) })
|
||||
return { state, props, notifications, events, model }
|
||||
}
|
||||
|
||||
for (const name of ['Image.vue', 'Images.vue', 'qnImages.vue']) {
|
||||
test(name + ': WebP is allowed by default and backend errors never trigger a success notification', async () => {
|
||||
const failure = { msg: '图片实际格式未在白名单中' }
|
||||
const { state, props, notifications, events } = setup(name, async () => { throw failure })
|
||||
const file = new File(['public test fixture'], 'logo.webp', { type: 'image/webp' })
|
||||
assert.ok(props.fileType.includes('image/webp'))
|
||||
assert.equal(state.beforeUpload(file), true)
|
||||
assert.equal(notifications.length, 0)
|
||||
let callbackCount = 0
|
||||
await state.handleHttpUpload({ file, onError() { callbackCount++ } })
|
||||
.then(state.uploadSuccess, state.uploadError)
|
||||
assert.equal(callbackCount, 0, 'Element Plus handles the rejected Promise once')
|
||||
assert.deepEqual(notifications.map(value => [value.type, value.message]), [['error', failure.msg]])
|
||||
assert.equal(events.length, 0)
|
||||
props.fileType = ['image/png']
|
||||
assert.equal(state.beforeUpload(file), false, 'explicit business type restrictions are respected')
|
||||
})
|
||||
}
|
||||
|
||||
test('single-image uploads preserve the canonical raw WebP URL returned by the server', async () => {
|
||||
const raw = '/admin/sys-file/oss/file?fileName=logo.webp'
|
||||
const { state, events } = setup('Image.vue', async options => {
|
||||
assert.equal(options.data.get('file').name, 'logo.png')
|
||||
return { code: 0, data: { url: raw } }
|
||||
})
|
||||
await state.handleHttpUpload({ file: new File(['test'], 'logo.png', { type: 'image/png' }) })
|
||||
assert.deepEqual(events, [['update:imageUrl', raw]])
|
||||
})
|
||||
Reference in new issue
Block a user