Commit 96568ed89c925d8a6613f143ebd9cefd7ec9e2f2

Authored by ww
1 parent 90cd407d

perf: DEFECT-809 configuration center add thumbnail

... ... @@ -6,8 +6,10 @@ import type {
6 6 ConfigurationCenterItemsModal,
7 7 } from './model/configurationCenterModal';
8 8 import { getPageData } from '../../base';
  9 +import { FileUploadResponse } from '../../oem/model';
9 10 enum API {
10 11 basicUrl = '/configuration/center',
  12 + UPLOAD = '/oss/upload',
11 13 }
12 14
13 15 export const getPage = (params: queryPageParams) => {
... ... @@ -43,3 +45,7 @@ export const saveOrUpdateConfigurationCenter = (
43 45 ) => {
44 46 return isUpdate ? updateConfigurationCenter(params) : saveConfigurationCenter(params);
45 47 };
  48 +
  49 +export const uploadThumbnail = (file: FormData) => {
  50 + return defHttp.post<FileUploadResponse>({ url: API.UPLOAD, params: file });
  51 +};
... ...
  1 +<svg t="1667959039355" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2798" width="32" height="32"><path d="M860.068571 666.422857L726.857143 731.245714c-8.685714 4.205714-18.742857 4.205714-27.428572 0l-133.211428-64.822857A31.296 31.296 0 0 1 548.571429 638.262857V477.165714c0-11.977143 6.857143-22.948571 17.645714-28.16l133.211428-64.822857c8.685714-4.205714 18.742857-4.205714 27.428572 0l133.211428 64.822857c10.788571 5.211429 17.645714 16.182857 17.645715 28.16v161.097143c0 11.977143-6.857143 22.948571-17.645715 28.16z" fill="#B4D7FE" p-id="2799"></path><path d="M713.142857 701.988571V543.542857l-139.337143-68.571428M852.48 474.971429L713.142857 543.542857" fill="#B4D7FE" p-id="2800"></path><path d="M950.857143 146.285714H73.142857c-10.057143 0-18.285714 8.228571-18.285714 18.285715v621.714285c0 10.057143 8.228571 18.285714 18.285714 18.285715h205.714286v54.857142c0 10.057143 8.228571 18.285714 18.285714 18.285715h429.714286c10.057143 0 18.285714-8.228571 18.285714-18.285715v-54.857142H950.857143c10.057143 0 18.285714-8.228571 18.285714-18.285715V164.571429c0-10.057143-8.228571-18.285714-18.285714-18.285715zM708.571429 841.142857h-393.142858v-36.571428h393.142858v36.571428z m224-73.142857H91.428571V182.857143h841.142858v585.142857z" fill="#248BFF" p-id="2801"></path><path d="M182.857143 274.285714h201.142857v36.571429H182.857143z" fill="#B4D7FE" p-id="2802"></path><path d="M411.428571 237.714286H155.428571c-5.028571 0-9.142857 4.114286-9.142857 9.142857v457.142857c0 5.028571 4.114286 9.142857 9.142857 9.142857h256c5.028571 0 9.142857-4.114286 9.142858-9.142857V246.857143c0-5.028571-4.114286-9.142857-9.142858-9.142857z m-228.571428 36.571428h201.142857v36.571429H182.857143v-36.571429z m0 402.285715V347.428571h201.142857v329.142858H182.857143zM867.474286 452.571429l-146.285715-71.222858c-2.56-1.188571-5.302857-1.828571-8.045714-1.828571s-5.485714 0.64-8.045714 1.828571l-146.285714 71.222858c-6.217143 3.108571-10.24 9.417143-10.24 16.457142v177.371429c0 7.04 4.022857 13.348571 10.24 16.457143l146.285714 71.222857c2.56 1.188571 5.302857 1.828571 8.045714 1.828571s5.485714-0.64 8.045714-1.828571l146.285715-71.222857c6.308571-3.017143 10.24-9.417143 10.24-16.457143V469.028571c0-7.04-4.022857-13.348571-10.24-16.457142zM713.142857 418.102857l107.245714 52.205714-107.428571 52.937143c-0.64-0.365714-1.28-0.822857-1.92-1.097143l-105.142857-51.748571L713.142857 418.102857z m-128 82.834286l109.714286 54.034286v133.394285l-109.714286-53.394285V500.937143z m146.285714 187.428571V554.971429l109.714286-54.034286v134.034286l-109.714286 53.394285z" fill="#248BFF" p-id="2803"></path><path d="M347.428571 411.428571H219.428571c-10.057143 0-18.285714-8.228571-18.285714-18.285714s8.228571-18.285714 18.285714-18.285714h128c10.057143 0 18.285714 8.228571 18.285715 18.285714s-8.228571 18.285714-18.285715 18.285714zM859.428571 292.571429H484.571429c-10.057143 0-18.285714-8.228571-18.285715-18.285715s8.228571-18.285714 18.285715-18.285714h374.857142c10.057143 0 18.285714 8.228571 18.285715 18.285714s-8.228571 18.285714-18.285715 18.285715zM667.428571 356.571429H484.571429c-10.057143 0-18.285714-8.228571-18.285715-18.285715s8.228571-18.285714 18.285715-18.285714h182.857142c10.057143 0 18.285714 8.228571 18.285715 18.285714s-8.228571 18.285714-18.285715 18.285715zM548.571429 420.571429h-64c-10.057143 0-18.285714-8.228571-18.285715-18.285715s8.228571-18.285714 18.285715-18.285714h64c10.057143 0 18.285714 8.228571 18.285714 18.285714s-8.228571 18.285714-18.285714 18.285715zM237.714286 475.428571h-18.285715c-10.057143 0-18.285714-8.228571-18.285714-18.285714s8.228571-18.285714 18.285714-18.285714h18.285715c10.057143 0 18.285714 8.228571 18.285714 18.285714s-8.228571 18.285714-18.285714 18.285714z" fill="#248BFF" p-id="2804"></path><path d="M301.714286 539.428571h-82.285715c-10.057143 0-18.285714-8.228571-18.285714-18.285714s8.228571-18.285714 18.285714-18.285714h82.285715c10.057143 0 18.285714 8.228571 18.285714 18.285714s-8.228571 18.285714-18.285714 18.285714z" fill="#248BFF" p-id="2805"></path><path d="M274.285714 603.428571h-54.857143c-10.057143 0-18.285714-8.228571-18.285714-18.285714s8.228571-18.285714 18.285714-18.285714h54.857143c10.057143 0 18.285714 8.228571 18.285715 18.285714s-8.228571 18.285714-18.285715 18.285714z" fill="#248BFF" p-id="2806"></path></svg>
... ...
... ... @@ -4,10 +4,10 @@
4 4 };
5 5 </script>
6 6 <script lang="ts" setup>
7   - import { Upload, Spin } from 'ant-design-vue';
  7 + import { Upload, Spin, Tooltip } from 'ant-design-vue';
8 8 import { InboxOutlined } from '@ant-design/icons-vue';
9 9 import { useMessage } from '/@/hooks/web/useMessage';
10   - import { computed, ref, unref, useAttrs } from 'vue';
  10 + import { computed, ref, unref } from 'vue';
11 11 import { cloneDeep } from 'lodash-es';
12 12 import { isFunction, isNumber, isObject } from '/@/utils/is';
13 13 import { useDesign } from '/@/hooks/web/useDesign';
... ... @@ -23,8 +23,6 @@
23 23 const { prefixCls } = useDesign('api-upload');
24 24 const emit = defineEmits(['update:fileList', 'preview', 'download']);
25 25
26   - const attrs = useAttrs();
27   -
28 26 const { createMessage } = useMessage();
29 27
30 28 const loading = ref(false);
... ... @@ -70,6 +68,16 @@
70 68 return disabled ? disabled : unref(componentDisabled);
71 69 });
72 70
  71 + const isPictureCard = computed(() => {
  72 + const { listType } = props;
  73 + return listType === 'picture-card';
  74 + });
  75 +
  76 + const getMaxFileLimit = computed(() => {
  77 + const { maxFileLimit } = props;
  78 + return isPictureCard.value ? 1 : maxFileLimit;
  79 + });
  80 +
73 81 const handleUpload = async (file: File | string | Blob | Promise<string | Blob | File>) => {
74 82 try {
75 83 setUploadStatus(true);
... ... @@ -78,10 +86,10 @@
78 86 if (api && isFunction(api)) {
79 87 const data = await api(file);
80 88 if (isObject(data) && Reflect.has(data, 'uid') && Reflect.has(data, 'name')) {
81   - const { fileList, maxFileLimit } = props;
  89 + const { fileList } = props;
82 90 let _fileList = cloneDeep(fileList);
83 91
84   - if (isNumber(maxFileLimit) && _fileList.length === maxFileLimit) {
  92 + if (isNumber(unref(getMaxFileLimit)) && _fileList.length === unref(getMaxFileLimit)) {
85 93 _fileList.splice(0, 1);
86 94 }
87 95
... ... @@ -106,49 +114,36 @@
106 114 emit('update:fileList', _fileList);
107 115 };
108 116
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   -
117 117 const handlePreview = (file: FileItem) => {
118   - if (Reflect.has(attrs, 'preview')) {
119   - emit('preview', file);
120   - return;
121   - }
122   - defaultPreview(file);
  118 + emit('preview', file);
123 119 };
124 120
125 121 const handleDownload = (file: FileItem) => {
126   - if (Reflect.has(attrs, 'download')) {
127   - emit('download', file);
128   - return;
129   - }
130   - defaultDownload(file);
  122 + emit('download', file);
131 123 };
132 124 </script>
133 125
134 126 <template>
135   - <Upload.Dragger
  127 + <Upload
136 128 class="block"
137 129 :class="prefixCls"
138 130 :file-list="props.fileList"
  131 + :list-type="props.listType"
139 132 :disabled="getDisabled"
140 133 :before-upload="handleBeforeUpload"
141 134 @preview="handlePreview"
142 135 @download="handleDownload"
143 136 :remove="handleRemove"
144 137 >
145   - <Spin :spinning="loading">
  138 + <Spin v-if="!fileList.length" :spinning="loading">
146 139 <div class="w-full h-full flex flex-col justify-center content-center">
147   - <InboxOutlined class="text-[3rem] !text-blue-500" />
148   - <div class="m-2 text-gray-400">点击上传或拖拽上传</div>
  140 + <Tooltip title="点击上传或拖拽上传">
  141 + <InboxOutlined class="text-[3rem] !text-blue-500" />
  142 + </Tooltip>
  143 + <div v-if="!isPictureCard" class="m-2 text-gray-400 text-sm">点击上传或拖拽上传</div>
149 144 </div>
150 145 </Spin>
151   - </Upload.Dragger>
  146 + </Upload>
152 147 </template>
153 148
154 149 <style lang="less">
... ... @@ -164,6 +159,12 @@
164 159 .ant-upload-list-item-name {
165 160 width: calc(100% - 22px);
166 161 }
  162 +
  163 + .ant-upload-select-text {
  164 + width: 100%;
  165 + text-align: center;
  166 + border: 1px dashed #d9d9d9;
  167 + }
167 168 }
168 169 }
169 170 </style>
... ...
... ... @@ -17,6 +17,8 @@
17 17 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
18 18 import { useMessage } from '/@/hooks/web/useMessage';
19 19 import { saveOrUpdateConfigurationCenter } from '/@/api/configuration/center/configurationCenter';
  20 + import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
  21 + import { buildUUID } from '/@/utils/uuid';
20 22
21 23 export default defineComponent({
22 24 name: 'ConfigurationDrawer',
... ... @@ -36,6 +38,11 @@
36 38 setDrawerProps({ confirmLoading: false });
37 39 isUpdate.value = !!data?.isUpdate;
38 40 if (unref(isUpdate)) {
  41 + if (data.record.thumbnail) {
  42 + data.record.thumbnail = [
  43 + { uid: buildUUID(), name: 'name', url: data.record.thumbnail } as FileItem,
  44 + ];
  45 + }
39 46 if (data.record.organizationDTO) {
40 47 await setFieldsValue(data.record);
41 48 } else {
... ... @@ -51,9 +58,14 @@
51 58 try {
52 59 const { createMessage } = useMessage();
53 60 const values = await validate();
  61 + if (Reflect.has(values, 'thumbnail')) {
  62 + const file = (values.thumbnail || []).at(0) || {};
  63 + values.thumbnail = file.url || null;
  64 + }
54 65 setDrawerProps({ confirmLoading: true });
55 66 let saveMessage = '添加成功';
56 67 let updateMessage = '修改成功';
  68 + console.log(values);
57 69 await saveOrUpdateConfigurationCenter(values, unref(isUpdate));
58 70 closeDrawer();
59 71 emit('success');
... ...
1 1 import { BasicColumn, FormSchema } from '/@/components/Table';
2 2 import { getOrganizationList } from '/@/api/system/system';
3 3 import { copyTransFun } from '/@/utils/fnUtils';
  4 +import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
  5 +import { createImgPreview } from '/@/components/Preview';
  6 +import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
4 7 export enum Platform {
5 8 PHONE = 'phone',
6 9 PC = 'pc',
... ... @@ -64,6 +67,37 @@ export const searchFormSchema: FormSchema[] = [
64 67
65 68 export const formSchema: FormSchema[] = [
66 69 {
  70 + field: 'thumbnail',
  71 + label: '缩略图',
  72 + component: 'ApiUpload',
  73 + changeEvent: 'update:fileList',
  74 + valueField: 'fileList',
  75 + componentProps: () => {
  76 + return {
  77 + listType: 'picture-card',
  78 + maxFileLimit: 1,
  79 + api: async (file: File) => {
  80 + try {
  81 + const formData = new FormData();
  82 + formData.set('file', file);
  83 + const { fileStaticUri, fileName } = await uploadThumbnail(formData);
  84 + return {
  85 + uid: fileStaticUri,
  86 + name: fileName,
  87 + url: fileStaticUri,
  88 + } as FileItem;
  89 + } catch (error) {
  90 + return {};
  91 + }
  92 + },
  93 + onPreview: (fileList: FileItem) => {
  94 + createImgPreview({ imageList: [fileList.url!] });
  95 + },
  96 + };
  97 + },
  98 + },
  99 +
  100 + {
67 101 field: 'name',
68 102 label: '组态名称',
69 103 required: true,
... ...
... ... @@ -26,6 +26,7 @@
26 26 import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm';
27 27 import { getBoundingClientRect } from '/@/utils/domUtils';
28 28 import configurationSrc from '/@/assets/icons/configuration.svg';
  29 + import { cloneDeep } from 'lodash';
29 30
30 31 const listColumn = ref(4);
31 32
... ... @@ -99,7 +100,7 @@
99 100 if (record) {
100 101 openDrawer(true, {
101 102 isUpdate: true,
102   - record,
  103 + record: cloneDeep(record),
103 104 });
104 105 } else {
105 106 openDrawer(true, {
... ... @@ -205,9 +206,9 @@
205 206 <Card hoverable>
206 207 <template #cover>
207 208 <img
208   - class="w-48 h-48 flex justify-center items-center"
  209 + class="w-36 h-36 flex justify-center items-center"
209 210 alt="example"
210   - :src="configurationSrc"
  211 + :src="item.thumbnail || configurationSrc"
211 212 />
212 213 </template>
213 214 <template class="ant-card-actions" #actions>
... ... @@ -244,8 +245,10 @@
244 245 </template>
245 246 <Card.Meta :title="item.name">
246 247 <template #description>
247   - <div class="truncate">{{ item.organizationDTO.name }}</div>
248   - <div class="truncate">{{ item.remark }} </div>
  248 + <div class="truncate h-11">
  249 + <div class="truncate">{{ item.organizationDTO.name }}</div>
  250 + <div class="truncate">{{ item.remark || '' }} </div>
  251 + </div>
249 252 </template>
250 253 </Card.Meta>
251 254 </Card>
... ...