mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-23 23:39:47 +08:00
fix(components): 修复上传组件回显问题,修改accept参数逻辑
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,34 +14,55 @@ 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) {
|
||||
const { error, data } = await fetchGetOssListByIds(ossIds);
|
||||
if (error) return;
|
||||
fileList.value = data.map(item => ({
|
||||
id: String(item.ossId),
|
||||
url: item.url,
|
||||
name: item.originalName,
|
||||
status: 'finished'
|
||||
}));
|
||||
}
|
||||
});
|
||||
async function handleFetchOssList(ossIds: string[]) {
|
||||
startLoading();
|
||||
const { error, data } = await fetchGetOssListByIds(ossIds);
|
||||
if (error) return;
|
||||
fileList.value = data.map(item => ({
|
||||
id: String(item.ossId),
|
||||
url: item.url,
|
||||
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
4
src/enum/business.ts
Normal 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'
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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="请输入备注" />
|
||||
|
@ -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[]>([]);
|
||||
|
||||
|
Reference in New Issue
Block a user