fix: 修复 Vben5.0 form-create 多图上传校验拒绝 png/jpeg/gif,isImage 兼容 MIME 与扩展名两种 accept 写法

dev
YunaiV 2026-05-02 22:56:38 +08:00
parent 897220e19a
commit e385823d46
9 changed files with 120 additions and 152 deletions

View File

@ -6,18 +6,36 @@ export function useImagesUpload() {
return defineComponent({
name: 'ImagesUpload',
props: {
multiple: {
accept: {
type: Array,
default: () => ['image/jpeg', 'image/png', 'image/gif'],
},
disabled: {
type: Boolean,
default: true,
default: false,
},
maxNumber: {
type: Number,
default: 5,
},
maxSize: {
type: Number,
default: 5,
},
multiple: {
type: Boolean,
default: true,
},
},
setup(props) {
return () => (
<ImageUpload maxNumber={props.maxNumber} multiple={props.multiple} />
<ImageUpload
accept={props.accept as string[]}
disabled={props.disabled}
maxNumber={props.maxNumber}
maxSize={props.maxSize}
multiple={props.multiple}
/>
);
},
});

View File

@ -26,7 +26,7 @@ export function useUploadFileRule() {
makeRequiredRule(),
{
type: 'select',
field: 'fileType',
field: 'accept',
title: '文件类型',
value: ['doc', 'xls', 'ppt', 'txt', 'pdf'],
options: [
@ -40,12 +40,6 @@ export function useUploadFileRule() {
mode: 'multiple',
},
},
{
type: 'switch',
field: 'autoUpload',
title: '是否在选取文件后立即进行上传',
value: true,
},
{
type: 'switch',
field: 'drag',
@ -54,23 +48,23 @@ export function useUploadFileRule() {
},
{
type: 'switch',
field: 'isShowTip',
field: 'showDescription',
title: '是否显示提示',
value: true,
},
{
type: 'inputNumber',
field: 'fileSize',
field: 'maxSize',
title: '大小限制(MB)',
value: 5,
props: { min: 0 },
},
{
type: 'inputNumber',
field: 'limit',
field: 'maxNumber',
title: '数量限制',
value: 5,
props: { min: 0 },
props: { min: 1 },
},
{
type: 'switch',

View File

@ -24,15 +24,9 @@ export function useUploadImageRule() {
props(_: any, { t }: any) {
return localeProps(t, `${name}.props`, [
makeRequiredRule(),
{
type: 'switch',
field: 'drag',
title: '拖拽上传',
value: false,
},
{
type: 'select',
field: 'fileType',
field: 'accept',
title: '图片类型限制',
value: ['image/jpeg', 'image/png', 'image/gif'],
options: [
@ -52,40 +46,16 @@ export function useUploadImageRule() {
},
{
type: 'inputNumber',
field: 'fileSize',
field: 'maxSize',
title: '大小限制(MB)',
value: 5,
props: { min: 0 },
},
{
type: 'input',
field: 'height',
title: '组件高度',
value: '150px',
},
{
type: 'input',
field: 'width',
title: '组件宽度',
value: '150px',
},
{
type: 'input',
field: 'borderradius',
title: '组件边框圆角',
value: '8px',
},
{
type: 'switch',
field: 'disabled',
title: '是否显示删除按钮',
value: true,
},
{
type: 'switch',
field: 'showBtnText',
title: '是否显示按钮文字',
value: true,
title: '是否禁用',
value: false,
},
]);
},

View File

@ -24,15 +24,9 @@ export function useUploadImagesRule() {
props(_: any, { t }: any) {
return localeProps(t, `${name}.props`, [
makeRequiredRule(),
{
type: 'switch',
field: 'drag',
title: '拖拽上传',
value: false,
},
{
type: 'select',
field: 'fileType',
field: 'accept',
title: '图片类型限制',
value: ['image/jpeg', 'image/png', 'image/gif'],
options: [
@ -48,40 +42,27 @@ export function useUploadImagesRule() {
],
props: {
mode: 'multiple',
maxNumber: 5,
},
},
{
type: 'inputNumber',
field: 'fileSize',
field: 'maxSize',
title: '大小限制(MB)',
value: 5,
props: { min: 0 },
},
{
type: 'inputNumber',
field: 'limit',
field: 'maxNumber',
title: '数量限制',
value: 5,
props: { min: 0 },
props: { min: 1 },
},
{
type: 'input',
field: 'height',
title: '组件高度',
value: '150px',
},
{
type: 'input',
field: 'width',
title: '组件宽度',
value: '150px',
},
{
type: 'input',
field: 'borderradius',
title: '组件边框圆角',
value: '8px',
type: 'switch',
field: 'disabled',
title: '是否禁用',
value: false,
},
]);
},

View File

@ -6,18 +6,36 @@ export function useImagesUpload() {
return defineComponent({
name: 'ImagesUpload',
props: {
multiple: {
accept: {
type: Array,
default: () => ['image/jpeg', 'image/png', 'image/gif'],
},
disabled: {
type: Boolean,
default: true,
default: false,
},
maxNumber: {
type: Number,
default: 5,
},
maxSize: {
type: Number,
default: 5,
},
multiple: {
type: Boolean,
default: true,
},
},
setup(props) {
return () => (
<ImageUpload maxNumber={props.maxNumber} multiple={props.multiple} />
<ImageUpload
accept={props.accept as string[]}
disabled={props.disabled}
maxNumber={props.maxNumber}
maxSize={props.maxSize}
multiple={props.multiple}
/>
);
},
});

View File

@ -26,7 +26,7 @@ export function useUploadFileRule() {
makeRequiredRule(),
{
type: 'select',
field: 'fileType',
field: 'accept',
title: '文件类型',
value: ['doc', 'xls', 'ppt', 'txt', 'pdf'],
options: [
@ -40,12 +40,6 @@ export function useUploadFileRule() {
multiple: true,
},
},
{
type: 'switch',
field: 'autoUpload',
title: '是否在选取文件后立即进行上传',
value: true,
},
{
type: 'switch',
field: 'drag',
@ -54,23 +48,23 @@ export function useUploadFileRule() {
},
{
type: 'switch',
field: 'isShowTip',
field: 'showDescription',
title: '是否显示提示',
value: true,
},
{
type: 'inputNumber',
field: 'fileSize',
field: 'maxSize',
title: '大小限制(MB)',
value: 5,
props: { min: 0 },
},
{
type: 'inputNumber',
field: 'limit',
field: 'maxNumber',
title: '数量限制',
value: 5,
props: { min: 0 },
props: { min: 1 },
},
{
type: 'switch',

View File

@ -24,15 +24,9 @@ export function useUploadImageRule() {
props(_: any, { t }: any) {
return localeProps(t, `${name}.props`, [
makeRequiredRule(),
{
type: 'switch',
field: 'drag',
title: '拖拽上传',
value: false,
},
{
type: 'select',
field: 'fileType',
field: 'accept',
title: '图片类型限制',
value: ['image/jpeg', 'image/png', 'image/gif'],
options: [
@ -52,40 +46,16 @@ export function useUploadImageRule() {
},
{
type: 'inputNumber',
field: 'fileSize',
field: 'maxSize',
title: '大小限制(MB)',
value: 5,
props: { min: 0 },
},
{
type: 'input',
field: 'height',
title: '组件高度',
value: '150px',
},
{
type: 'input',
field: 'width',
title: '组件宽度',
value: '150px',
},
{
type: 'input',
field: 'borderradius',
title: '组件边框圆角',
value: '8px',
},
{
type: 'switch',
field: 'disabled',
title: '是否显示删除按钮',
value: true,
},
{
type: 'switch',
field: 'showBtnText',
title: '是否显示按钮文字',
value: true,
title: '是否禁用',
value: false,
},
]);
},

View File

@ -24,15 +24,9 @@ export function useUploadImagesRule() {
props(_: any, { t }: any) {
return localeProps(t, `${name}.props`, [
makeRequiredRule(),
{
type: 'switch',
field: 'drag',
title: '拖拽上传',
value: false,
},
{
type: 'select',
field: 'fileType',
field: 'accept',
title: '图片类型限制',
value: ['image/jpeg', 'image/png', 'image/gif'],
options: [
@ -48,40 +42,27 @@ export function useUploadImagesRule() {
],
props: {
multiple: true,
maxNumber: 5,
},
},
{
type: 'inputNumber',
field: 'fileSize',
field: 'maxSize',
title: '大小限制(MB)',
value: 5,
props: { min: 0 },
},
{
type: 'inputNumber',
field: 'limit',
field: 'maxNumber',
title: '数量限制',
value: 5,
props: { min: 0 },
props: { min: 1 },
},
{
type: 'input',
field: 'height',
title: '组件高度',
value: '150px',
},
{
type: 'input',
field: 'width',
title: '组件宽度',
value: '150px',
},
{
type: 'input',
field: 'borderradius',
title: '组件边框圆角',
value: '8px',
type: 'switch',
field: 'disabled',
title: '是否禁用',
value: false,
},
]);
},

View File

@ -103,11 +103,37 @@ export const defaultImageAccepts = [
'webp',
];
/**
* MIME
*/
const IMAGE_MIME_SUBTYPE_ALIASES: Record<string, string[]> = {
apng: ['apng', 'png'],
jpeg: ['jpeg', 'jpg'],
pjpeg: ['jpeg', 'jpg'],
'svg+xml': ['svg'],
tiff: ['tif', 'tiff'],
'x-icon': ['ico'],
};
/**
* MIME image/*
*/
function matchMimeSubtype(subtype: string, ext: string): boolean {
if (subtype === '*') {
return defaultImageAccepts.includes(ext);
}
const aliases = IMAGE_MIME_SUBTYPE_ALIASES[subtype];
if (aliases) {
return aliases.includes(ext);
}
return subtype === ext;
}
/**
*
*
* @param filename
* @param accepts
* @param accepts MIME image/png.ext .png png
* @returns
*/
export function isImage(
@ -118,7 +144,23 @@ export function isImage(
return false;
}
const ext = filename.split('.').pop()?.toLowerCase() || '';
return accepts.includes(ext);
if (!ext) {
return false;
}
return accepts.some((accept) => {
const lower = accept.toLowerCase();
// MIME 类型,例如 image/png image/* 仅放行已知图片扩展
if (lower.includes('/')) {
const subtype = lower.split('/').pop() || '';
return matchMimeSubtype(subtype, ext);
}
// 以点号开头的扩展名,例如 .png
if (lower.startsWith('.')) {
return lower.slice(1) === ext;
}
// 纯后缀
return lower === ext;
});
}
/**