fix(components): 修复上传组件回显问题,修改accept参数逻辑

This commit is contained in:
AN
2025-06-11 11:09:34 +08:00
parent 03c8a7f5b7
commit e16a0fa6ed
6 changed files with 63 additions and 29 deletions

View File

@ -1,9 +1,10 @@
<script setup lang="ts">
import { useAttrs } from 'vue';
import { computed, useAttrs } from 'vue';
import type { UploadFileInfo, UploadProps } from 'naive-ui';
import { fetchBatchDeleteOss } from '@/service/api/system/oss';
import { getToken } from '@/store/modules/auth/shared';
import { getServiceBaseURL } from '@/utils/service';
import { AcceptType } from '@/enum/business';
defineOptions({
name: 'FileUpload'
@ -26,11 +27,18 @@ const props = withDefaults(defineProps<Props>(), {
defaultUpload: true,
showTip: true,
max: 5,
accept: '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.pdf',
accept: undefined,
fileSize: 5,
uploadType: 'file'
});
const accept = computed(() => {
if (props.accept) {
return props.accept;
}
return props.uploadType === 'file' ? AcceptType.File : AcceptType.Image;
});
const attrs: UploadProps = useAttrs();
let fileNum = 0;
@ -51,12 +59,12 @@ function beforeUpload(options: { file: UploadFileInfo; fileList: UploadFileInfo[
const { file } = options;
// 校检文件类型
if (props.accept) {
if (accept.value) {
const fileName = file.name.split('.');
const fileExt = `.${fileName[fileName.length - 1]}`;
const isTypeOk = props.accept.split(',')?.includes(fileExt);
const isTypeOk = accept.value.split(',')?.includes(fileExt);
if (!isTypeOk) {
window.$message?.error(`文件格式不正确, 请上传 ${props.accept} 格式文件!`);
window.$message?.error(`文件格式不正确, 请上传 ${accept.value} 格式文件!`);
return false;
}
}

View File

@ -1,6 +1,7 @@
<script setup lang="ts">
import { onMounted, ref, useAttrs, watch } from 'vue';
import { ref, useAttrs, watch } from 'vue';
import type { UploadFileInfo } from 'naive-ui';
import { useLoading } from '@sa/hooks';
import { fetchGetOssListByIds } from '@/service/api/system/oss';
import { isNotNull } from '@/utils/common';
import FileUpload from '@/components/custom/file-upload.vue';
@ -13,12 +14,12 @@ const attrs = useAttrs();
const value = defineModel<string>('value', { default: '' });
const { loading, startLoading, endLoading } = useLoading();
const fileList = ref<UploadFileInfo[]>([]);
onMounted(async () => {
fileList.value = [];
const ossIds = value.value.split(',')?.filter(item => isNotNull(item));
if (ossIds.length > 0) {
async function handleFetchOssList(ossIds: string[]) {
startLoading();
const { error, data } = await fetchGetOssListByIds(ossIds);
if (error) return;
fileList.value = data.map(item => ({
@ -27,20 +28,41 @@ onMounted(async () => {
name: item.originalName,
status: 'finished'
}));
endLoading();
}
});
watch(
value,
async val => {
const ossIds = val.split(',')?.filter(item => isNotNull(item));
const fileIds = new Set(fileList.value.filter(item => item.status === 'finished').map(item => item.id));
if (ossIds.every(item => fileIds.has(item))) {
return;
}
if (ossIds.length === 0) {
fileList.value = [];
return;
}
await handleFetchOssList(ossIds);
},
{ immediate: true }
);
watch(
fileList,
val => {
value.value = val.map(item => item.id).join(',');
value.value = val
.filter(item => item.status === 'finished')
.map(item => item.id)
.join(',');
},
{ deep: true }
);
</script>
<template>
<FileUpload v-bind="attrs" v-model:file-list="fileList" />
<NSpin v-if="loading" />
<FileUpload v-else v-bind="attrs" v-model:file-list="fileList" />
</template>
<style scoped></style>

4
src/enum/business.ts Normal file
View File

@ -0,0 +1,4 @@
export enum AcceptType {
Image = '.jpg,.jpeg,.png,.gif,.bmp,.webp',
File = '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.pdf,.zip,.rar,.7z'
}

View File

@ -1,3 +1,4 @@
import { AcceptType } from '@/enum/business';
import { $t } from '@/locales';
/**
* Transform record to option
@ -87,8 +88,7 @@ export function isNull(value: any) {
/** 判断是否为图片类型 */
export function isImage(suffix: string) {
const imgSuffixList = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
return imgSuffixList.includes(suffix.toLowerCase());
return AcceptType.Image.split(',').includes(suffix.toLowerCase());
}
/**

View File

@ -53,12 +53,13 @@ function createDefaultModel(): Model {
};
}
type RuleKey = Extract<keyof Model, 'id' | 'deptId' | 'userId' | 'testKey' | 'value'>;
type RuleKey = Extract<keyof Model, 'id' | 'deptId' | 'userId' | 'orderNum' | 'testKey' | 'value'>;
const rules: Record<RuleKey, App.Global.FormRule> = {
id: createRequiredRule('主键不能为空'),
deptId: createRequiredRule('部门不能为空'),
userId: createRequiredRule('用户不能为空'),
orderNum: createRequiredRule('排序号不能为空'),
testKey: createRequiredRule('key 键不能为空'),
value: createRequiredRule('值不能为空')
};
@ -124,7 +125,7 @@ watch(visible, () => {
<NInput v-model:value="model.testKey" placeholder="请输入 key 键" />
</NFormItem>
<NFormItem label="值" path="value">
<NInput v-model:value="model.value" placeholder="请输入值" />
<OssUpload v-model:value="model.value as string" upload-type="image" placeholder="请输入值" />
</NFormItem>
<NFormItem label="备注" path="remark">
<NInput v-model:value="model.remark" type="textarea" placeholder="请输入备注" />

View File

@ -2,6 +2,7 @@
import { computed, ref, watch } from 'vue';
import type { UploadFileInfo } from 'naive-ui';
import FileUpload from '@/components/custom/file-upload.vue';
import { AcceptType } from '@/enum/business';
defineOptions({
name: 'OssUploadModal'
@ -23,9 +24,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const accept = computed(() => {
return props.uploadType === 'file' ? '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.pdf' : '.jpg,.jpeg,.png,.gif,.bmp,.webp';
});
const accept = computed(() => (props.uploadType === 'file' ? AcceptType.File : AcceptType.Image));
const fileList = ref<UploadFileInfo[]>([]);