Commit 1b99eb5ddb9bbfdb6b71010612664c3d328c133e

Authored by xp.Huang
2 parents 43ba5387 1c7d1fd7

Merge branch 'ww' into 'main'

fix: ApiUpload component happen error on build

See merge request huang/yun-teng-iot-front!363
@@ -10,7 +10,7 @@ export { default as ApiSelect } from './src/components/ApiSelect.vue'; @@ -10,7 +10,7 @@ export { default as ApiSelect } from './src/components/ApiSelect.vue';
10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; 10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
11 export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; 11 export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
12 export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'; 12 export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
13 -// export { default as ApiUpload } from './src/components/ApiUpload.vue'; 13 +export { default as ApiUpload } from './src/components/ApiUpload.vue';
14 14
15 //注册自定义组件 15 //注册自定义组件
16 export { 16 export {
@@ -33,6 +33,7 @@ import JAddInput from './externalCompns/components/JAddInput.vue'; @@ -33,6 +33,7 @@ import JAddInput from './externalCompns/components/JAddInput.vue';
33 import { JEasyCron } from './externalCompns/components/JEasyCron'; 33 import { JEasyCron } from './externalCompns/components/JEasyCron';
34 import ColorPicker from './components/ColorPicker.vue'; 34 import ColorPicker from './components/ColorPicker.vue';
35 import IconDrawer from './components/IconDrawer.vue'; 35 import IconDrawer from './components/IconDrawer.vue';
  36 +import ApiUpload from './components/ApiUpload.vue';
36 37
37 const componentMap = new Map<ComponentType, Component>(); 38 const componentMap = new Map<ComponentType, Component>();
38 39
@@ -73,6 +74,7 @@ componentMap.set('JAddInput', JAddInput); @@ -73,6 +74,7 @@ componentMap.set('JAddInput', JAddInput);
73 componentMap.set('JEasyCron', JEasyCron); 74 componentMap.set('JEasyCron', JEasyCron);
74 componentMap.set('ColorPicker', ColorPicker); 75 componentMap.set('ColorPicker', ColorPicker);
75 componentMap.set('IconDrawer', IconDrawer); 76 componentMap.set('IconDrawer', IconDrawer);
  77 +componentMap.set('ApiUpload', ApiUpload);
76 78
77 export function add(compName: ComponentType, component: Component) { 79 export function add(compName: ComponentType, component: Component) {
78 componentMap.set(compName, component); 80 componentMap.set(compName, component);
@@ -4,21 +4,26 @@ @@ -4,21 +4,26 @@
4 }; 4 };
5 </script> 5 </script>
6 <script lang="ts" setup> 6 <script lang="ts" setup>
7 - import { UploadDragger, Spin } from 'ant-design-vue'; 7 + import { Upload, Spin } from 'ant-design-vue';
8 import { InboxOutlined } from '@ant-design/icons-vue'; 8 import { InboxOutlined } from '@ant-design/icons-vue';
9 import { useMessage } from '/@/hooks/web/useMessage'; 9 import { useMessage } from '/@/hooks/web/useMessage';
10 - import { isBoolean, isFunction } from '/@/utils/is';  
11 - import { computed, ref, unref } from 'vue'; 10 + import { computed, ref, unref, useAttrs } from 'vue';
12 import { cloneDeep } from 'lodash-es'; 11 import { cloneDeep } from 'lodash-es';
13 - interface FileItem { 12 + import { isFunction, isNumber, isObject } from '/@/utils/is';
  13 + import { useDesign } from '/@/hooks/web/useDesign';
  14 +
  15 + export interface FileItem {
14 uid: string; 16 uid: string;
15 - name?: string; 17 + name: string;
16 status?: string; 18 status?: string;
17 response?: string; 19 response?: string;
18 url?: string; 20 url?: string;
19 } 21 }
20 22
21 - const emit = defineEmits(['update:fileList']); 23 + const { prefixCls } = useDesign('api-upload');
  24 + const emit = defineEmits(['update:fileList', 'preview', 'download']);
  25 +
  26 + const attrs = useAttrs();
22 27
23 const { createMessage } = useMessage(); 28 const { createMessage } = useMessage();
24 29
@@ -26,8 +31,9 @@ @@ -26,8 +31,9 @@
26 31
27 const componentDisabled = ref(false); 32 const componentDisabled = ref(false);
28 33
29 - const setLoading = (spin: boolean) => {  
30 - loading.value = spin; 34 + const setUploadStatus = (status: boolean) => {
  35 + loading.value = status;
  36 + componentDisabled.value = status;
31 }; 37 };
32 38
33 const props = withDefaults( 39 const props = withDefaults(
@@ -38,6 +44,7 @@ @@ -38,6 +44,7 @@
38 disabled?: boolean; 44 disabled?: boolean;
39 listType?: string; 45 listType?: string;
40 multiple?: boolean; 46 multiple?: boolean;
  47 + maxFileLimit?: number;
41 showUploadList?: boolean | { showPreviewIcon?: boolean; showRemoveIcon?: boolean }; 48 showUploadList?: boolean | { showPreviewIcon?: boolean; showRemoveIcon?: boolean };
42 transformFile?: (file: File) => string | Blob | Promise<string | Blob | File>; 49 transformFile?: (file: File) => string | Blob | Promise<string | Blob | File>;
43 api: (file: string | Blob | Promise<string | Blob | File>) => Promise<FileItem>; 50 api: (file: string | Blob | Promise<string | Blob | File>) => Promise<FileItem>;
@@ -60,28 +67,35 @@ @@ -60,28 +67,35 @@
60 67
61 const getDisabled = computed(() => { 68 const getDisabled = computed(() => {
62 const { disabled } = props; 69 const { disabled } = props;
63 - if (isBoolean(disabled)) {  
64 - return disabled ? componentDisabled.value : disabled;  
65 - }  
66 - return componentDisabled.value; 70 + return disabled ? disabled : unref(componentDisabled);
67 }); 71 });
68 72
69 const handleUpload = async (file: File | string | Blob | Promise<string | Blob | File>) => { 73 const handleUpload = async (file: File | string | Blob | Promise<string | Blob | File>) => {
70 try { 74 try {
71 - setLoading(true);  
72 - componentDisabled.value = true;  
73 - console.log({ componentDisabled: unref(componentDisabled), getDisabled: unref(getDisabled) }); 75 + setUploadStatus(true);
74 const { transformFile, api } = props; 76 const { transformFile, api } = props;
75 if (transformFile && isFunction(transformFile)) file = await transformFile(file as File); 77 if (transformFile && isFunction(transformFile)) file = await transformFile(file as File);
76 if (api && isFunction(api)) { 78 if (api && isFunction(api)) {
77 const data = await api(file); 79 const data = await api(file);
78 - emit('update:fileList', cloneDeep([...props.fileList, data])); 80 + if (isObject(data) && Reflect.has(data, 'uid') && Reflect.has(data, 'name')) {
  81 + const { fileList, maxFileLimit } = props;
  82 + let _fileList = cloneDeep(fileList);
  83 +
  84 + if (isNumber(maxFileLimit) && _fileList.length === maxFileLimit) {
  85 + _fileList.splice(0, 1);
  86 + }
  87 +
  88 + emit('update:fileList', cloneDeep([..._fileList, data]));
  89 + return;
  90 + }
  91 + window.console.error(
  92 + `The ApiUpload component's api properties need to return an object, that object requires a uid field and a name field`
  93 + );
79 } 94 }
80 } catch (error) { 95 } catch (error) {
81 window.console.error(error); 96 window.console.error(error);
82 } finally { 97 } finally {
83 - setLoading(false);  
84 - componentDisabled.value = false; 98 + setUploadStatus(false);
85 } 99 }
86 }; 100 };
87 101
@@ -92,17 +106,35 @@ @@ -92,17 +106,35 @@
92 emit('update:fileList', _fileList); 106 emit('update:fileList', _fileList);
93 }; 107 };
94 108
  109 + const defaultPreview = (file: FileItem) => {
  110 + console.log('default preview', file);
  111 + };
  112 +
  113 + const defaultDownload = (file: FileItem) => {
  114 + console.log('default download', file);
  115 + };
  116 +
95 const handlePreview = (file: FileItem) => { 117 const handlePreview = (file: FileItem) => {
96 - console.log('preview', file); 118 + if (Reflect.has(attrs, 'preview')) {
  119 + emit('preview', file);
  120 + return;
  121 + }
  122 + defaultPreview(file);
97 }; 123 };
98 124
99 const handleDownload = (file: FileItem) => { 125 const handleDownload = (file: FileItem) => {
100 - console.log('download', file); 126 + if (Reflect.has(attrs, 'download')) {
  127 + emit('download', file);
  128 + return;
  129 + }
  130 + defaultDownload(file);
101 }; 131 };
102 </script> 132 </script>
103 133
104 <template> 134 <template>
105 - <UploadDragger 135 + <Upload.Dragger
  136 + class="block"
  137 + :class="prefixCls"
106 :file-list="props.fileList" 138 :file-list="props.fileList"
107 :disabled="getDisabled" 139 :disabled="getDisabled"
108 :before-upload="handleBeforeUpload" 140 :before-upload="handleBeforeUpload"
@@ -111,11 +143,27 @@ @@ -111,11 +143,27 @@
111 :remove="handleRemove" 143 :remove="handleRemove"
112 > 144 >
113 <Spin :spinning="loading"> 145 <Spin :spinning="loading">
114 - {{ getDisabled }}  
115 <div class="w-full h-full flex flex-col justify-center content-center"> 146 <div class="w-full h-full flex flex-col justify-center content-center">
116 <InboxOutlined class="text-[3rem] !text-blue-500" /> 147 <InboxOutlined class="text-[3rem] !text-blue-500" />
117 <div class="m-2 text-gray-400">点击上传或拖拽上传</div> 148 <div class="m-2 text-gray-400">点击上传或拖拽上传</div>
118 </div> 149 </div>
119 </Spin> 150 </Spin>
120 - </UploadDragger> 151 + </Upload.Dragger>
121 </template> 152 </template>
  153 +
  154 +<style lang="less">
  155 + @basic-form: ~'@{namespace}-basic-form';
  156 + @prefix-cls: ~'@{namespace}-api-upload';
  157 +
  158 + .@{basic-form} {
  159 + // .ant-form-item-control-input-content > div > div {
  160 + // width: 100% !important;
  161 + // }
  162 +
  163 + .@{prefix-cls} {
  164 + .ant-upload-list-item-name {
  165 + width: calc(100% - 22px);
  166 + }
  167 + }
  168 + }
  169 +</style>
@@ -114,4 +114,5 @@ export type ComponentType = @@ -114,4 +114,5 @@ export type ComponentType =
114 | 'JAddInput' 114 | 'JAddInput'
115 | 'Rate' 115 | 'Rate'
116 | 'ColorPicker' 116 | 'ColorPicker'
117 - | 'IconDrawer'; 117 + | 'IconDrawer'
  118 + | 'ApiUpload';
1 import { BasicColumn, FormSchema } from '/@/components/Table'; 1 import { BasicColumn, FormSchema } from '/@/components/Table';
2 - 2 +import { PackageField } from './packageDetail.config';
3 export const columns: BasicColumn[] = [ 3 export const columns: BasicColumn[] = [
4 { 4 {
5 title: '创建时间', 5 title: '创建时间',
6 - dataIndex: 'createTime', 6 + dataIndex: PackageField.CREATE_TIME,
7 width: 120, 7 width: 120,
8 }, 8 },
9 { 9 {
10 title: '标题', 10 title: '标题',
11 - dataIndex: 'title', 11 + dataIndex: PackageField.TITLE,
12 width: 120, 12 width: 120,
13 }, 13 },
14 { 14 {
15 title: '版本', 15 title: '版本',
16 - dataIndex: 'version', 16 + dataIndex: PackageField.VERSION,
17 width: 120, 17 width: 120,
18 }, 18 },
19 { 19 {
20 title: '版本标签', 20 title: '版本标签',
21 - dataIndex: 'versionLabel', 21 + dataIndex: PackageField.VERSION_LABEL,
22 width: 120, 22 width: 120,
23 }, 23 },
24 { 24 {
25 title: '包类型', 25 title: '包类型',
26 - dataIndex: 'pkgType', 26 + dataIndex: PackageField.PACKAGE_TYPE,
27 width: 120, 27 width: 120,
28 }, 28 },
29 { 29 {
30 title: '直接URL', 30 title: '直接URL',
31 - dataIndex: 'url', 31 + dataIndex: PackageField.PACKAGE_EXTERNAL_URL,
32 width: 120, 32 width: 120,
33 }, 33 },
34 { 34 {
35 title: '文件大小', 35 title: '文件大小',
36 - dataIndex: 'fileSize', 36 + dataIndex: PackageField.FILE_SIZE,
37 width: 120, 37 width: 120,
38 }, 38 },
39 { 39 {
40 title: '校验和', 40 title: '校验和',
41 - dataIndex: 'vaildateTotal', 41 + dataIndex: PackageField.CHECK_SUM,
42 width: 120, 42 width: 120,
43 }, 43 },
44 ]; 44 ];
45 45
46 export const searchFormSchema: FormSchema[] = [ 46 export const searchFormSchema: FormSchema[] = [
47 { 47 {
48 - field: 'name', 48 + field: PackageField.TITLE,
49 label: '标题', 49 label: '标题',
50 component: 'Input', 50 component: 'Input',
51 colProps: { span: 8 }, 51 colProps: { span: 8 },
@@ -7,12 +7,15 @@ export enum PackageField { @@ -7,12 +7,15 @@ export enum PackageField {
7 DEVICE_CONFIGURATION = 'deviceConfiguration', 7 DEVICE_CONFIGURATION = 'deviceConfiguration',
8 PACKAGE_TYPE = 'packageType', 8 PACKAGE_TYPE = 'packageType',
9 PACKAGE_UPDATE_TYPE = 'PackageUpdateType', 9 PACKAGE_UPDATE_TYPE = 'PackageUpdateType',
10 - PACKAGE_BINARY_FILE = 'packageBinaryFile', 10 + PACKAGE_BINARY_FILE = 'fileList',
11 PACKAGE_EXTERNAL_URL = 'packageEexternalUrl', 11 PACKAGE_EXTERNAL_URL = 'packageEexternalUrl',
12 CHECK_SUM_WAY = 'checkSumWay', 12 CHECK_SUM_WAY = 'checkSumWay',
13 ALG = 'alg', 13 ALG = 'alg',
14 CHECK_SUM = 'checkSum', 14 CHECK_SUM = 'checkSum',
15 DESCRIPTION = 'description', 15 DESCRIPTION = 'description',
  16 +
  17 + CREATE_TIME = 'createTIme',
  18 + FILE_SIZE = 'fileSize',
16 } 19 }
17 20
18 export enum PackageUpdateType { 21 export enum PackageUpdateType {
@@ -119,10 +122,14 @@ export const formSchema: FormSchema[] = [ @@ -119,10 +122,14 @@ export const formSchema: FormSchema[] = [
119 ifShow: ({ model }) => { 122 ifShow: ({ model }) => {
120 return model[PackageField.PACKAGE_UPDATE_TYPE] === PackageUpdateType.BINARY_FILE; 123 return model[PackageField.PACKAGE_UPDATE_TYPE] === PackageUpdateType.BINARY_FILE;
121 }, 124 },
122 - component: 'Upload', 125 + component: 'ApiUpload',
  126 + valueField: PackageField.PACKAGE_BINARY_FILE,
  127 + changeEvent: `update:${PackageField.PACKAGE_BINARY_FILE}`,
123 componentProps: { 128 componentProps: {
124 - api: () => {  
125 - return {}; 129 + maxFileLimit: 1,
  130 + api: (_file: File) => {
  131 + console.log({ _file });
  132 + return { uid: _file.uid, name: _file.name };
126 }, 133 },
127 }, 134 },
128 }, 135 },
@@ -5,8 +5,6 @@ @@ -5,8 +5,6 @@
5 import { BasicTable, useTable } from '/@/components/Table'; 5 import { BasicTable, useTable } from '/@/components/Table';
6 import PackageDetailModal from './components/PackageDetailModal.vue'; 6 import PackageDetailModal from './components/PackageDetailModal.vue';
7 import { useModal } from '/@/components/Modal'; 7 import { useModal } from '/@/components/Modal';
8 - // import { ApiUpload } from '/@/components/Form';  
9 - // import { computed, ref, unref } from 'vue';  
10 8
11 const [register] = useTable({ 9 const [register] = useTable({
12 columns, 10 columns,
@@ -24,28 +22,10 @@ @@ -24,28 +22,10 @@
24 const handleCreatePackage = () => { 22 const handleCreatePackage = () => {
25 openModal(true); 23 openModal(true);
26 }; 24 };
27 -  
28 - // const fileList = ref([]);  
29 - // const handleUpload = async (file: File) => {  
30 - // console.log(file);  
31 - // return new Promise((resolve) => {  
32 - // setTimeout(() => {  
33 - // resolve({  
34 - // uid: file.uid,  
35 - // type: file.type,  
36 - // name: file.name,  
37 - // linkProps: { download: 'http://www.baidu.cn' },  
38 - // });  
39 - // }, 3000);  
40 - // });  
41 - // };  
42 </script> 25 </script>
43 26
44 <template> 27 <template>
45 <PageWrapper dense contentFullHeight contentClass="flex flex-col"> 28 <PageWrapper dense contentFullHeight contentClass="flex flex-col">
46 - <!-- <div class="w-40 h-40">  
47 - <ApiUpload v-model:file-list="fileList" :api="handleUpload" />  
48 - </div> -->  
49 <BasicTable @register="register"> 29 <BasicTable @register="register">
50 <template #toolbar> 30 <template #toolbar>
51 <Button @click="handleCreatePackage" type="primary">新增包</Button> 31 <Button @click="handleCreatePackage" type="primary">新增包</Button>