mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
fix(components): 修复上传组件回显问题,修改accept参数逻辑
This commit is contained in:
@ -1,9 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAttrs } from 'vue';
|
import { computed, useAttrs } from 'vue';
|
||||||
import type { UploadFileInfo, UploadProps } from 'naive-ui';
|
import type { UploadFileInfo, UploadProps } from 'naive-ui';
|
||||||
import { fetchBatchDeleteOss } from '@/service/api/system/oss';
|
import { fetchBatchDeleteOss } from '@/service/api/system/oss';
|
||||||
import { getToken } from '@/store/modules/auth/shared';
|
import { getToken } from '@/store/modules/auth/shared';
|
||||||
import { getServiceBaseURL } from '@/utils/service';
|
import { getServiceBaseURL } from '@/utils/service';
|
||||||
|
import { AcceptType } from '@/enum/business';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'FileUpload'
|
name: 'FileUpload'
|
||||||
@ -26,11 +27,18 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
defaultUpload: true,
|
defaultUpload: true,
|
||||||
showTip: true,
|
showTip: true,
|
||||||
max: 5,
|
max: 5,
|
||||||
accept: '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.pdf',
|
accept: undefined,
|
||||||
fileSize: 5,
|
fileSize: 5,
|
||||||
uploadType: 'file'
|
uploadType: 'file'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const accept = computed(() => {
|
||||||
|
if (props.accept) {
|
||||||
|
return props.accept;
|
||||||
|
}
|
||||||
|
return props.uploadType === 'file' ? AcceptType.File : AcceptType.Image;
|
||||||
|
});
|
||||||
|
|
||||||
const attrs: UploadProps = useAttrs();
|
const attrs: UploadProps = useAttrs();
|
||||||
|
|
||||||
let fileNum = 0;
|
let fileNum = 0;
|
||||||
@ -51,12 +59,12 @@ function beforeUpload(options: { file: UploadFileInfo; fileList: UploadFileInfo[
|
|||||||
const { file } = options;
|
const { file } = options;
|
||||||
|
|
||||||
// 校检文件类型
|
// 校检文件类型
|
||||||
if (props.accept) {
|
if (accept.value) {
|
||||||
const fileName = file.name.split('.');
|
const fileName = file.name.split('.');
|
||||||
const fileExt = `.${fileName[fileName.length - 1]}`;
|
const fileExt = `.${fileName[fileName.length - 1]}`;
|
||||||
const isTypeOk = props.accept.split(',')?.includes(fileExt);
|
const isTypeOk = accept.value.split(',')?.includes(fileExt);
|
||||||
if (!isTypeOk) {
|
if (!isTypeOk) {
|
||||||
window.$message?.error(`文件格式不正确, 请上传 ${props.accept} 格式文件!`);
|
window.$message?.error(`文件格式不正确, 请上传 ${accept.value} 格式文件!`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref, useAttrs, watch } from 'vue';
|
import { ref, useAttrs, watch } from 'vue';
|
||||||
import type { UploadFileInfo } from 'naive-ui';
|
import type { UploadFileInfo } from 'naive-ui';
|
||||||
|
import { useLoading } from '@sa/hooks';
|
||||||
import { fetchGetOssListByIds } from '@/service/api/system/oss';
|
import { fetchGetOssListByIds } from '@/service/api/system/oss';
|
||||||
import { isNotNull } from '@/utils/common';
|
import { isNotNull } from '@/utils/common';
|
||||||
import FileUpload from '@/components/custom/file-upload.vue';
|
import FileUpload from '@/components/custom/file-upload.vue';
|
||||||
@ -13,12 +14,12 @@ const attrs = useAttrs();
|
|||||||
|
|
||||||
const value = defineModel<string>('value', { default: '' });
|
const value = defineModel<string>('value', { default: '' });
|
||||||
|
|
||||||
|
const { loading, startLoading, endLoading } = useLoading();
|
||||||
|
|
||||||
const fileList = ref<UploadFileInfo[]>([]);
|
const fileList = ref<UploadFileInfo[]>([]);
|
||||||
|
|
||||||
onMounted(async () => {
|
async function handleFetchOssList(ossIds: string[]) {
|
||||||
fileList.value = [];
|
startLoading();
|
||||||
const ossIds = value.value.split(',')?.filter(item => isNotNull(item));
|
|
||||||
if (ossIds.length > 0) {
|
|
||||||
const { error, data } = await fetchGetOssListByIds(ossIds);
|
const { error, data } = await fetchGetOssListByIds(ossIds);
|
||||||
if (error) return;
|
if (error) return;
|
||||||
fileList.value = data.map(item => ({
|
fileList.value = data.map(item => ({
|
||||||
@ -27,20 +28,41 @@ onMounted(async () => {
|
|||||||
name: item.originalName,
|
name: item.originalName,
|
||||||
status: 'finished'
|
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(
|
watch(
|
||||||
fileList,
|
fileList,
|
||||||
val => {
|
val => {
|
||||||
value.value = val.map(item => item.id).join(',');
|
value.value = val
|
||||||
|
.filter(item => item.status === 'finished')
|
||||||
|
.map(item => item.id)
|
||||||
|
.join(',');
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<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';
|
import { $t } from '@/locales';
|
||||||
/**
|
/**
|
||||||
* Transform record to option
|
* Transform record to option
|
||||||
@ -87,8 +88,7 @@ export function isNull(value: any) {
|
|||||||
|
|
||||||
/** 判断是否为图片类型 */
|
/** 判断是否为图片类型 */
|
||||||
export function isImage(suffix: string) {
|
export function isImage(suffix: string) {
|
||||||
const imgSuffixList = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
|
return AcceptType.Image.split(',').includes(suffix.toLowerCase());
|
||||||
return imgSuffixList.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> = {
|
const rules: Record<RuleKey, App.Global.FormRule> = {
|
||||||
id: createRequiredRule('主键不能为空'),
|
id: createRequiredRule('主键不能为空'),
|
||||||
deptId: createRequiredRule('部门不能为空'),
|
deptId: createRequiredRule('部门不能为空'),
|
||||||
userId: createRequiredRule('用户不能为空'),
|
userId: createRequiredRule('用户不能为空'),
|
||||||
|
orderNum: createRequiredRule('排序号不能为空'),
|
||||||
testKey: createRequiredRule('key 键不能为空'),
|
testKey: createRequiredRule('key 键不能为空'),
|
||||||
value: createRequiredRule('值不能为空')
|
value: createRequiredRule('值不能为空')
|
||||||
};
|
};
|
||||||
@ -124,7 +125,7 @@ watch(visible, () => {
|
|||||||
<NInput v-model:value="model.testKey" placeholder="请输入 key 键" />
|
<NInput v-model:value="model.testKey" placeholder="请输入 key 键" />
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem label="值" path="value">
|
<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>
|
||||||
<NFormItem label="备注" path="remark">
|
<NFormItem label="备注" path="remark">
|
||||||
<NInput v-model:value="model.remark" type="textarea" placeholder="请输入备注" />
|
<NInput v-model:value="model.remark" type="textarea" placeholder="请输入备注" />
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import type { UploadFileInfo } from 'naive-ui';
|
import type { UploadFileInfo } from 'naive-ui';
|
||||||
import FileUpload from '@/components/custom/file-upload.vue';
|
import FileUpload from '@/components/custom/file-upload.vue';
|
||||||
|
import { AcceptType } from '@/enum/business';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'OssUploadModal'
|
name: 'OssUploadModal'
|
||||||
@ -23,9 +24,7 @@ const visible = defineModel<boolean>('visible', {
|
|||||||
default: false
|
default: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const accept = computed(() => {
|
const accept = computed(() => (props.uploadType === 'file' ? AcceptType.File : AcceptType.Image));
|
||||||
return props.uploadType === 'file' ? '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.pdf' : '.jpg,.jpeg,.png,.gif,.bmp,.webp';
|
|
||||||
});
|
|
||||||
|
|
||||||
const fileList = ref<UploadFileInfo[]>([]);
|
const fileList = ref<UploadFileInfo[]>([]);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user