From b28a46edcb7b906b4c5e00b4e0c6296e49096df8 Mon Sep 17 00:00:00 2001 From: Electrolux <59329360+electroluxcode@users.noreply.github.com> Date: Sun, 31 Mar 2024 07:02:02 +0800 Subject: [PATCH] feat(feature):upload->preview & upload->resultfield (#3707) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(components->upload->resultField): upload和imageupload组件中添加resultField与demo * feat(components->upload->preview): upload组件中添加自定义预览组件的方法与demo --- src/components/Upload/src/BasicUpload.vue | 2 + .../Upload/src/components/FileList.vue | 5 +- .../Upload/src/components/ImageUpload.vue | 14 +- .../Upload/src/components/UploadModal.vue | 11 +- .../src/components/UploadPreviewModal.vue | 33 ++- src/components/Upload/src/props.ts | 23 ++- src/components/Upload/src/types/typing.ts | 2 +- src/views/demo/comp/upload/index.vue | 195 ++++++++++++++++-- 8 files changed, 259 insertions(+), 26 deletions(-) diff --git a/src/components/Upload/src/BasicUpload.vue b/src/components/Upload/src/BasicUpload.vue index 25978cb1f..9c5ee4b50 100644 --- a/src/components/Upload/src/BasicUpload.vue +++ b/src/components/Upload/src/BasicUpload.vue @@ -34,6 +34,8 @@ @register="registerPreviewModal" @list-change="handlePreviewChange" @delete="handlePreviewDelete" + v-bind:preview-columns="props.previewColumns" + v-bind:before-preview-data="props.beforePreviewData" /> diff --git a/src/components/Upload/src/components/FileList.vue b/src/components/Upload/src/components/FileList.vue index 4c545bfd0..ae0f51aee 100644 --- a/src/components/Upload/src/components/FileList.vue +++ b/src/components/Upload/src/components/FileList.vue @@ -4,6 +4,7 @@ import { useSortable } from '@/hooks/web/useSortable'; import { useModalContext } from '@/components/Modal/src/hooks/useModalContext'; import { defineComponent, CSSProperties, watch, nextTick, ref, onMounted } from 'vue'; + import { FileBasicColumn } from '../types/typing'; export default defineComponent({ name: 'FileList', @@ -51,7 +52,9 @@ return () => { const { columns, actionColumn, dataSource } = props; - const columnList = [...columns, actionColumn]; + let columnList: FileBasicColumn[]; + columnList = (actionColumn ? [...columns, actionColumn] : [...columns]) as FileBasicColumn[]; + return ( // x scrollbar
diff --git a/src/components/Upload/src/components/ImageUpload.vue b/src/components/Upload/src/components/ImageUpload.vue index ccbbefdcf..cc1d83de3 100644 --- a/src/components/Upload/src/components/ImageUpload.vue +++ b/src/components/Upload/src/components/ImageUpload.vue @@ -37,12 +37,12 @@ import { uploadContainerProps } from '../props'; import { isImgTypeByName } from '../helper'; import { UploadResultStatus } from '@/components/Upload/src/types/typing'; - + import { get,omit } from 'lodash-es'; defineOptions({ name: 'ImageUpload' }); const emit = defineEmits(['change', 'update:value', 'delete']); const props = defineProps({ - ...uploadContainerProps, + ...omit(uploadContainerProps,["previewColumns","beforePreviewData"]), }); const { t } = useI18n(); const { createMessage } = useMessage(); @@ -170,7 +170,12 @@ name: props.name, filename: props.filename, }); - info.onSuccess!(res.data); + if(props.resultField){ + info.onSuccess!(res); + }else{ + // 不传入 resultField 的情况 + info.onSuccess!(res.data); + } const value = getValue(); isInnerOperate.value = true; emit('update:value', value); @@ -185,6 +190,9 @@ const list = (fileList.value || []) .filter((item) => item?.status === UploadResultStatus.DONE) .map((item: any) => { + if(props.resultField){ + return get(item?.response, props.resultField) + } return item?.url || item?.response?.url; }); return props.multiple ? list : list.length > 0 ? list[0] : ''; diff --git a/src/components/Upload/src/components/UploadModal.vue b/src/components/Upload/src/components/UploadModal.vue index c4da7208c..b7b89f761 100644 --- a/src/components/Upload/src/components/UploadModal.vue +++ b/src/components/Upload/src/components/UploadModal.vue @@ -66,6 +66,7 @@ import { warn } from '@/utils/log'; import FileList from './FileList.vue'; import { useI18n } from '@/hooks/web/useI18n'; + import { get } from 'lodash-es'; const props = defineProps({ ...basicProps, @@ -190,6 +191,14 @@ const { data } = ret; item.status = UploadResultStatus.SUCCESS; item.response = data; + if(props.resultField){ + // 适配预览组件而进行封装 + item.response = { + code:0, + message:"upload Success!", + url:get(ret, props.resultField) + } + } return { success: true, error: null, @@ -241,7 +250,7 @@ return createMessage.warning(t('component.upload.saveWarn')); } const fileList: string[] = []; - + for (const item of fileListRef.value) { const { status, response } = item; if (status === UploadResultStatus.SUCCESS && response) { diff --git a/src/components/Upload/src/components/UploadPreviewModal.vue b/src/components/Upload/src/components/UploadPreviewModal.vue index cec69fb02..5162fb4dd 100644 --- a/src/components/Upload/src/components/UploadPreviewModal.vue +++ b/src/components/Upload/src/components/UploadPreviewModal.vue @@ -15,30 +15,55 @@ import FileList from './FileList.vue'; import { BasicModal, useModalInner } from '@/components/Modal'; import { previewProps } from '../props'; - import { PreviewFileItem } from '../types/typing'; + import { FileBasicColumn, PreviewFileItem } from '../types/typing'; import { downloadByUrl } from '@/utils/file/download'; import { createPreviewColumns, createPreviewActionColumn } from './data'; import { useI18n } from '@/hooks/web/useI18n'; import { isArray } from '@/utils/is'; + import { BasicColumn } from '@/components/Table'; const props = defineProps(previewProps); const emit = defineEmits(['list-change', 'register', 'delete']); - const columns = createPreviewColumns() as any[]; - const actionColumn = createPreviewActionColumn({ handleRemove, handleDownload }) as any; + let columns : BasicColumn[] | FileBasicColumn[] = createPreviewColumns(); + let actionColumn :any; const [register] = useModalInner(); const { t } = useI18n(); - const fileListRef = ref([]); + const fileListRef = ref>([]); + watch( + () => props.previewColumns, + () => { + if (props.previewColumns.length) { + columns = props.previewColumns; + actionColumn = null + }else{ + columns=createPreviewColumns(); + actionColumn = createPreviewActionColumn({ handleRemove, handleDownload }) + }; + + }, + { immediate: true }, + ); + watch( () => props.value, (value) => { if (!isArray(value)) value = []; + if(props.beforePreviewData){ + value = props.beforePreviewData(value) as any + fileListRef.value = value + return + } fileListRef.value = value .filter((item) => !!item) .map((item) => { + if(typeof item!="string"){ + console.error("return value should be string") + return + } return { url: item, type: item.split('.').pop() || '', diff --git a/src/components/Upload/src/props.ts b/src/components/Upload/src/props.ts index eb477eee3..57350cf64 100644 --- a/src/components/Upload/src/props.ts +++ b/src/components/Upload/src/props.ts @@ -4,6 +4,8 @@ import { FileBasicColumn } from './types/typing'; import type { Options } from 'sortablejs'; import { Merge } from '@/utils/types'; +import { propTypes } from '@/utils/propTypes'; +import { BasicColumn } from '@/components/Table'; type SortableOptions = Merge< Omit, @@ -13,6 +15,19 @@ type SortableOptions = Merge< } >; +export const previewType = { + previewColumns:{ + type: Array as (PropType), + default: [], + required: false, + }, + beforePreviewData:{ + type: Function as PropType<(arg:string[])=>Recordable>, + default: null, + required: false, + }, +} + type ListType = 'text' | 'picture' | 'picture-card'; export const basicProps = { @@ -69,11 +84,13 @@ export const basicProps = { type: Object as PropType, default: () => ({}), }, + // support xxx.xxx.xx + resultField: propTypes.string.def(''), }; export const uploadContainerProps = { value: { - type: Array as PropType, + type: Array as (PropType), default: () => [], }, ...basicProps, @@ -85,6 +102,7 @@ export const uploadContainerProps = { type: Boolean as PropType, default: false, }, + ...previewType }; export const previewProps = { @@ -92,11 +110,12 @@ export const previewProps = { type: Array as PropType, default: () => [], }, + ...previewType }; export const fileListProps = { columns: { - type: Array as PropType, + type: Array as (PropType ), default: null, }, actionColumn: { diff --git a/src/components/Upload/src/types/typing.ts b/src/components/Upload/src/types/typing.ts index b87cdd68e..ad70489d7 100644 --- a/src/components/Upload/src/types/typing.ts +++ b/src/components/Upload/src/types/typing.ts @@ -16,7 +16,7 @@ export interface FileItem { percent: number; file: File; status?: UploadResultStatus; - response?: UploadApiResult; + response?: UploadApiResult | Recordable; uuid: string; } diff --git a/src/views/demo/comp/upload/index.vue b/src/views/demo/comp/upload/index.vue index cca0ef72a..3b498f063 100644 --- a/src/views/demo/comp/upload/index.vue +++ b/src/views/demo/comp/upload/index.vue @@ -12,7 +12,14 @@ - + + + + + + + +