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 @@
-
+
+
+
+
+
+
+
+