Commit 6d5dafbd7b5d256743b615ede074380361c11d8a

Authored by xp.Huang
2 parents f785827d 8919a212

Merge branch 'ww' into 'main'

fix: BUG in teambition

See merge request huang/yun-teng-iot-front!381
@@ -6,8 +6,10 @@ import type { @@ -6,8 +6,10 @@ import type {
6 ConfigurationCenterItemsModal, 6 ConfigurationCenterItemsModal,
7 } from './model/configurationCenterModal'; 7 } from './model/configurationCenterModal';
8 import { getPageData } from '../../base'; 8 import { getPageData } from '../../base';
  9 +import { FileUploadResponse } from '../../oem/model';
9 enum API { 10 enum API {
10 basicUrl = '/configuration/center', 11 basicUrl = '/configuration/center',
  12 + UPLOAD = '/oss/upload',
11 } 13 }
12 14
13 export const getPage = (params: queryPageParams) => { 15 export const getPage = (params: queryPageParams) => {
@@ -43,3 +45,7 @@ export const saveOrUpdateConfigurationCenter = ( @@ -43,3 +45,7 @@ export const saveOrUpdateConfigurationCenter = (
43 ) => { 45 ) => {
44 return isUpdate ? updateConfigurationCenter(params) : saveConfigurationCenter(params); 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 +};
@@ -186,7 +186,7 @@ export const getGATEWAYdevice = async (params: { organization: string }) => { @@ -186,7 +186,7 @@ export const getGATEWAYdevice = async (params: { organization: string }) => {
186 params, 186 params,
187 }); 187 });
188 return Promise.resolve<{ label: string; value: string }[]>( 188 return Promise.resolve<{ label: string; value: string }[]>(
189 - res.map((item) => ({ label: item.name, value: item.id })) 189 + res.map((item) => ({ label: item.name, value: item.tbDeviceId }))
190 ); 190 );
191 }; 191 };
192 192
  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,10 +4,10 @@
4 }; 4 };
5 </script> 5 </script>
6 <script lang="ts" setup> 6 <script lang="ts" setup>
7 - import { Upload, Spin } from 'ant-design-vue'; 7 + import { Upload, Spin, Tooltip } 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 { computed, ref, unref, useAttrs } from 'vue'; 10 + import { computed, ref, unref } from 'vue';
11 import { cloneDeep } from 'lodash-es'; 11 import { cloneDeep } from 'lodash-es';
12 import { isFunction, isNumber, isObject } from '/@/utils/is'; 12 import { isFunction, isNumber, isObject } from '/@/utils/is';
13 import { useDesign } from '/@/hooks/web/useDesign'; 13 import { useDesign } from '/@/hooks/web/useDesign';
@@ -23,8 +23,6 @@ @@ -23,8 +23,6 @@
23 const { prefixCls } = useDesign('api-upload'); 23 const { prefixCls } = useDesign('api-upload');
24 const emit = defineEmits(['update:fileList', 'preview', 'download']); 24 const emit = defineEmits(['update:fileList', 'preview', 'download']);
25 25
26 - const attrs = useAttrs();  
27 -  
28 const { createMessage } = useMessage(); 26 const { createMessage } = useMessage();
29 27
30 const loading = ref(false); 28 const loading = ref(false);
@@ -70,6 +68,16 @@ @@ -70,6 +68,16 @@
70 return disabled ? disabled : unref(componentDisabled); 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 const handleUpload = async (file: File | string | Blob | Promise<string | Blob | File>) => { 81 const handleUpload = async (file: File | string | Blob | Promise<string | Blob | File>) => {
74 try { 82 try {
75 setUploadStatus(true); 83 setUploadStatus(true);
@@ -78,10 +86,10 @@ @@ -78,10 +86,10 @@
78 if (api && isFunction(api)) { 86 if (api && isFunction(api)) {
79 const data = await api(file); 87 const data = await api(file);
80 if (isObject(data) && Reflect.has(data, 'uid') && Reflect.has(data, 'name')) { 88 if (isObject(data) && Reflect.has(data, 'uid') && Reflect.has(data, 'name')) {
81 - const { fileList, maxFileLimit } = props; 89 + const { fileList } = props;
82 let _fileList = cloneDeep(fileList); 90 let _fileList = cloneDeep(fileList);
83 91
84 - if (isNumber(maxFileLimit) && _fileList.length === maxFileLimit) { 92 + if (isNumber(unref(getMaxFileLimit)) && _fileList.length === unref(getMaxFileLimit)) {
85 _fileList.splice(0, 1); 93 _fileList.splice(0, 1);
86 } 94 }
87 95
@@ -106,49 +114,36 @@ @@ -106,49 +114,36 @@
106 emit('update:fileList', _fileList); 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 const handlePreview = (file: FileItem) => { 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 const handleDownload = (file: FileItem) => { 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 </script> 124 </script>
133 125
134 <template> 126 <template>
135 - <Upload.Dragger 127 + <Upload
136 class="block" 128 class="block"
137 :class="prefixCls" 129 :class="prefixCls"
138 :file-list="props.fileList" 130 :file-list="props.fileList"
  131 + :list-type="props.listType"
139 :disabled="getDisabled" 132 :disabled="getDisabled"
140 :before-upload="handleBeforeUpload" 133 :before-upload="handleBeforeUpload"
141 @preview="handlePreview" 134 @preview="handlePreview"
142 @download="handleDownload" 135 @download="handleDownload"
143 :remove="handleRemove" 136 :remove="handleRemove"
144 > 137 >
145 - <Spin :spinning="loading"> 138 + <Spin v-if="!fileList.length" :spinning="loading">
146 <div class="w-full h-full flex flex-col justify-center content-center"> 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 </div> 144 </div>
150 </Spin> 145 </Spin>
151 - </Upload.Dragger> 146 + </Upload>
152 </template> 147 </template>
153 148
154 <style lang="less"> 149 <style lang="less">
@@ -164,6 +159,12 @@ @@ -164,6 +159,12 @@
164 .ant-upload-list-item-name { 159 .ant-upload-list-item-name {
165 width: calc(100% - 22px); 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 </style> 170 </style>
@@ -245,69 +245,25 @@ @@ -245,69 +245,25 @@
245 </Space> 245 </Space>
246 </div> 246 </div>
247 </div> 247 </div>
248 - <List  
249 - :loading="loading"  
250 - :data-source="cameraList"  
251 - class="bg-light-50 flex-auto dark:bg-dark-900 split-mode-list"  
252 - :grid="gridLayout"  
253 - :style="{ '--height': `${100 / pagination.colNumber}%` }"  
254 - >  
255 - <template #renderItem="{ item }">  
256 - <List.Item>  
257 - <div class="box-border w-full h-full p-1px">  
258 - <div  
259 - v-if="item.placeholder"  
260 - class="bg-black w-full h-full overflow-hidden relative"  
261 - ></div>  
262 - <div  
263 - v-if="!item.placeholder"  
264 - class="bg-black w-full h-full overflow-hidden relative video-container"  
265 - >  
266 - <Spin v-show="!item.isTransform" :spinning="!item.isTransform">  
267 - <div class="bg-black text-light-50"> </div>  
268 - </Spin>  
269 - <VideoPlay  
270 - v-show="item.isTransform"  
271 - @loadstart="handleLoadStart(item)"  
272 - @loadeddata="handleLoadData(item)"  
273 - v-bind="options"  
274 - :src="item.videoUrl"  
275 - :title="item.name"  
276 - :type="item.type"  
277 - /> 248 + <section ref="videoContainer" class="flex-auto">
  249 + <List
  250 + :loading="loading"
  251 + :data-source="cameraList"
  252 + class="bg-light-50 w-full h-full dark:bg-dark-900 split-mode-list"
  253 + :grid="gridLayout"
  254 + :style="{ '--height': `${100 / pagination.colNumber}%` }"
  255 + >
  256 + <template #renderItem="{ item }">
  257 + <List.Item>
  258 + <div class="box-border w-full h-full p-1px">
278 <div 259 <div
279 - v-if="item.isTransform && isDef(item.canPlay) && !item.canPlay"  
280 - class="video-container-error-msk absolute top-0 left-0 text-lg w-full h-full text-light-50 flex justify-center items-center z-50 bg-black"  
281 - >  
282 - 视频加载出错了!  
283 - </div> 260 + v-if="item.placeholder"
  261 + class="bg-black w-full h-full overflow-hidden relative"
  262 + ></div>
284 <div 263 <div
285 - class="video-container-mask absolute top-0 left-0 z-50 text-lg w-full text-light-50 flex justify-center items-center"  
286 - style="height: 100%; background-color: rgba(0, 0, 0, 0.5)" 264 + v-if="!item.placeholder"
  265 + class="bg-black w-full h-full overflow-hidden relative video-container"
287 > 266 >
288 - <span>{{ item.name }}</span>  
289 - </div>  
290 - </div>  
291 - </div>  
292 - </List.Item>  
293 - </template>  
294 - </List>  
295 - <!-- <section ref="videoContainer" class="bg-light-50 flex-auto dark:bg-dark-900">  
296 - <Spin :spinning="loading" class="h-full">  
297 - <Empty  
298 - class="h-full flex flex-col justify-center items-center"  
299 - v-if="!cameraList.length"  
300 - />  
301 - <Row :gutter="8" class="h-full mx-0 content-start">  
302 - <Col  
303 - v-for="item in cameraList"  
304 - :key="item.id"  
305 - :style="{ height: `${100 / pagination.colNumber}%` }"  
306 - class="h-1/2 !px-0 !flex justify-center items-center"  
307 - :span="getColLayout"  
308 - >  
309 - <div class="box-border w-full h-full p-1px">  
310 - <div class="bg-black w-full h-full overflow-hidden relative video-container">  
311 <Spin v-show="!item.isTransform" :spinning="!item.isTransform"> 267 <Spin v-show="!item.isTransform" :spinning="!item.isTransform">
312 <div class="bg-black text-light-50"> </div> 268 <div class="bg-black text-light-50"> </div>
313 </Spin> 269 </Spin>
@@ -334,10 +290,10 @@ @@ -334,10 +290,10 @@
334 </div> 290 </div>
335 </div> 291 </div>
336 </div> 292 </div>
337 - </Col>  
338 - </Row>  
339 - </Spin>  
340 - </section> --> 293 + </List.Item>
  294 + </template>
  295 + </List>
  296 + </section>
341 </section> 297 </section>
342 </PageWrapper> 298 </PageWrapper>
343 <CameraDrawer @register="registerDrawer" @success="getCameraList" /> 299 <CameraDrawer @register="registerDrawer" @success="getCameraList" />
@@ -17,6 +17,8 @@ @@ -17,6 +17,8 @@
17 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; 17 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
18 import { useMessage } from '/@/hooks/web/useMessage'; 18 import { useMessage } from '/@/hooks/web/useMessage';
19 import { saveOrUpdateConfigurationCenter } from '/@/api/configuration/center/configurationCenter'; 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 export default defineComponent({ 23 export default defineComponent({
22 name: 'ConfigurationDrawer', 24 name: 'ConfigurationDrawer',
@@ -36,6 +38,11 @@ @@ -36,6 +38,11 @@
36 setDrawerProps({ confirmLoading: false }); 38 setDrawerProps({ confirmLoading: false });
37 isUpdate.value = !!data?.isUpdate; 39 isUpdate.value = !!data?.isUpdate;
38 if (unref(isUpdate)) { 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 if (data.record.organizationDTO) { 46 if (data.record.organizationDTO) {
40 await setFieldsValue(data.record); 47 await setFieldsValue(data.record);
41 } else { 48 } else {
@@ -51,9 +58,14 @@ @@ -51,9 +58,14 @@
51 try { 58 try {
52 const { createMessage } = useMessage(); 59 const { createMessage } = useMessage();
53 const values = await validate(); 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 setDrawerProps({ confirmLoading: true }); 65 setDrawerProps({ confirmLoading: true });
55 let saveMessage = '添加成功'; 66 let saveMessage = '添加成功';
56 let updateMessage = '修改成功'; 67 let updateMessage = '修改成功';
  68 + console.log(values);
57 await saveOrUpdateConfigurationCenter(values, unref(isUpdate)); 69 await saveOrUpdateConfigurationCenter(values, unref(isUpdate));
58 closeDrawer(); 70 closeDrawer();
59 emit('success'); 71 emit('success');
1 import { BasicColumn, FormSchema } from '/@/components/Table'; 1 import { BasicColumn, FormSchema } from '/@/components/Table';
2 import { getOrganizationList } from '/@/api/system/system'; 2 import { getOrganizationList } from '/@/api/system/system';
3 import { copyTransFun } from '/@/utils/fnUtils'; 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 export enum Platform { 7 export enum Platform {
5 PHONE = 'phone', 8 PHONE = 'phone',
6 PC = 'pc', 9 PC = 'pc',
@@ -64,6 +67,37 @@ export const searchFormSchema: FormSchema[] = [ @@ -64,6 +67,37 @@ export const searchFormSchema: FormSchema[] = [
64 67
65 export const formSchema: FormSchema[] = [ 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 field: 'name', 101 field: 'name',
68 label: '组态名称', 102 label: '组态名称',
69 required: true, 103 required: true,
@@ -25,6 +25,8 @@ @@ -25,6 +25,8 @@
25 import { useDrawer } from '/@/components/Drawer'; 25 import { useDrawer } from '/@/components/Drawer';
26 import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm'; 26 import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm';
27 import { getBoundingClientRect } from '/@/utils/domUtils'; 27 import { getBoundingClientRect } from '/@/utils/domUtils';
  28 + import configurationSrc from '/@/assets/icons/configuration.svg';
  29 + import { cloneDeep } from 'lodash';
28 30
29 const listColumn = ref(4); 31 const listColumn = ref(4);
30 32
@@ -98,7 +100,7 @@ @@ -98,7 +100,7 @@
98 if (record) { 100 if (record) {
99 openDrawer(true, { 101 openDrawer(true, {
100 isUpdate: true, 102 isUpdate: true,
101 - record, 103 + record: cloneDeep(record),
102 }); 104 });
103 } else { 105 } else {
104 openDrawer(true, { 106 openDrawer(true, {
@@ -204,8 +206,9 @@ @@ -204,8 +206,9 @@
204 <Card hoverable> 206 <Card hoverable>
205 <template #cover> 207 <template #cover>
206 <img 208 <img
  209 + class="w-36 h-36 flex justify-center items-center"
207 alt="example" 210 alt="example"
208 - src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png" 211 + :src="item.thumbnail || configurationSrc"
209 /> 212 />
210 </template> 213 </template>
211 <template class="ant-card-actions" #actions> 214 <template class="ant-card-actions" #actions>
@@ -242,8 +245,10 @@ @@ -242,8 +245,10 @@
242 </template> 245 </template>
243 <Card.Meta :title="item.name"> 246 <Card.Meta :title="item.name">
244 <template #description> 247 <template #description>
245 - <div class="truncate">{{ item.organizationDTO.name }}</div>  
246 - <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>
247 </template> 252 </template>
248 </Card.Meta> 253 </Card.Meta>
249 </Card> 254 </Card>
@@ -34,6 +34,12 @@ export const step1Schemas: FormSchema[] = [ @@ -34,6 +34,12 @@ export const step1Schemas: FormSchema[] = [
34 slot: 'snCode', 34 slot: 'snCode',
35 }, 35 },
36 { 36 {
  37 + field: 'transportType',
  38 + label: '类型',
  39 + component: 'Input',
  40 + show: false,
  41 + },
  42 + {
37 field: 'profileId', 43 field: 'profileId',
38 label: '所属产品', 44 label: '所属产品',
39 required: true, 45 required: true,
@@ -44,9 +50,9 @@ export const step1Schemas: FormSchema[] = [ @@ -44,9 +50,9 @@ export const step1Schemas: FormSchema[] = [
44 api: deviceProfile, 50 api: deviceProfile,
45 labelField: 'name', 51 labelField: 'name',
46 valueField: 'tbProfileId', 52 valueField: 'tbProfileId',
47 - onChange(_value: string, option: { deviceType: string }) {  
48 - const { deviceType } = option;  
49 - setFieldsValue({ deviceType: deviceType }); 53 + onChange(_value: string, option: { deviceType: string; transportType: string }) {
  54 + const { deviceType, transportType } = option;
  55 + setFieldsValue({ deviceType: deviceType, transportType });
50 }, 56 },
51 }; 57 };
52 }, 58 },
@@ -69,6 +75,17 @@ export const step1Schemas: FormSchema[] = [ @@ -69,6 +75,17 @@ export const step1Schemas: FormSchema[] = [
69 }, 75 },
70 }, 76 },
71 { 77 {
  78 + field: 'code',
  79 + label: '地址码',
  80 + component: 'Input',
  81 + ifShow: ({ model }) => {
  82 + return model['transportType'] === 'TCP';
  83 + },
  84 + dynamicRules: ({ model }) => {
  85 + return [{ required: model['transportType'] === 'TCP', message: '地址码为必填项' }];
  86 + },
  87 + },
  88 + {
72 field: 'brand', 89 field: 'brand',
73 component: 'ApiRadioGroup', 90 component: 'ApiRadioGroup',
74 label: '选择厂家', 91 label: '选择厂家',
@@ -110,72 +110,79 @@ @@ -110,72 +110,79 @@
110 // 提交 110 // 提交
111 const msg = computed(() => (unref(isUpdate) ? '更新设备成功' : '新增设备成功')); 111 const msg = computed(() => (unref(isUpdate) ? '更新设备成功' : '新增设备成功'));
112 async function handleOk() { 112 async function handleOk() {
113 - if (current.value === 0) {  
114 - // 验证  
115 - const valid = await unref(DeviceStep1Ref)?.parentValidate();  
116 - if (!valid) return;  
117 - stepState.value = unref(DeviceStep1Ref)?.parentGetFieldsValue();  
118 - } else {  
119 - // !!!此处需要删除地图的属性,否则会报堆栈溢出的错误 Uncaught RangeError: Maximum call stack size exceeded  
120 - Reflect.deleteProperty(stepState.value, 'map');  
121 - Reflect.deleteProperty(stepState.value, 'marker');  
122 - if (unref(DeviceStep2Ref)?.getFieldsValue().addAgree) {  
123 - const valid = await unref(DeviceStep2Ref)?.validate(); 113 + try {
  114 + if (current.value === 0) {
  115 + // 验证
  116 + const valid = await unref(DeviceStep1Ref)?.parentValidate();
124 if (!valid) return; 117 if (!valid) return;
125 - // 第二页验证通过情况  
126 - stepState.value = { 118 + stepState.value = unref(DeviceStep1Ref)?.parentGetFieldsValue();
  119 + } else {
  120 + // !!!此处需要删除地图的属性,否则会报堆栈溢出的错误 Uncaught RangeError: Maximum call stack size exceeded
  121 + Reflect.deleteProperty(stepState.value, 'map');
  122 + Reflect.deleteProperty(stepState.value, 'marker');
  123 + if (unref(DeviceStep2Ref)?.getFieldsValue().addAgree) {
  124 + const valid = await unref(DeviceStep2Ref)?.validate();
  125 + if (!valid) return;
  126 + // 第二页验证通过情况
  127 + stepState.value = {
  128 + ...unref(stepState),
  129 + ...unref(DeviceStep2Ref)?.getFieldsValue(),
  130 + };
  131 + }
  132 + }
  133 + // 验证成功 --调-- 新增或者编辑接口
  134 + // !!!此处需要删除地图的属性,否则会报堆栈溢出的错误 Uncaught RangeError: Maximum call stack size exceeded
  135 + Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'map');
  136 + Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'marker');
  137 + setModalProps({
  138 + confirmLoading: true,
  139 + });
  140 + if (unref(isUpdate)) {
  141 + const editData = {
127 ...unref(stepState), 142 ...unref(stepState),
128 - ...unref(DeviceStep2Ref)?.getFieldsValue(), 143 + deviceInfo: {
  144 + avatar: DeviceStep1Ref.value?.devicePic,
  145 + ...DeviceStep1Ref.value?.positionState,
  146 + },
129 }; 147 };
  148 + await createOrEditDevice(editData);
  149 + } else {
  150 + const createData = {
  151 + ...unref(stepState),
  152 + deviceInfo: {
  153 + avatar: DeviceStep1Ref.value?.devicePic,
  154 + ...DeviceStep1Ref.value?.positionState,
  155 + },
  156 + deviceToken:
  157 + unref(current) === 0 || !unref(stepState).addAgree
  158 + ? null
  159 + : {
  160 + credentialsType: unref(stepState).credentialType,
  161 + credentialsId: unref(stepState).credentialsId,
  162 + credentialsValue:
  163 + unref(stepState).credentialType === credentialTypeEnum.MQTT_BASIC
  164 + ? JSON.stringify({
  165 + userName: unref(stepState).username,
  166 + password: unref(stepState).password,
  167 + clientId: unref(stepState).clientId,
  168 + })
  169 + : unref(stepState).credentialType === credentialTypeEnum.X_509
  170 + ? unref(stepState).publicKey
  171 + : null,
  172 + },
  173 + };
  174 + await createOrEditDevice(createData);
130 } 175 }
  176 + createMessage.success(unref(msg));
  177 + handleCancel();
  178 + closeModal();
  179 + emit('reload');
  180 + } catch (error) {
  181 + } finally {
  182 + setModalProps({
  183 + confirmLoading: false,
  184 + });
131 } 185 }
132 - // 验证成功 --调-- 新增或者编辑接口  
133 - // !!!此处需要删除地图的属性,否则会报堆栈溢出的错误 Uncaught RangeError: Maximum call stack size exceeded  
134 - Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'map');  
135 - Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'marker');  
136 - setModalProps({  
137 - confirmLoading: true,  
138 - });  
139 - if (unref(isUpdate)) {  
140 - const editData = {  
141 - ...unref(stepState),  
142 - deviceInfo: {  
143 - avatar: DeviceStep1Ref.value?.devicePic,  
144 - ...DeviceStep1Ref.value?.positionState,  
145 - },  
146 - };  
147 - await createOrEditDevice(editData);  
148 - } else {  
149 - const createData = {  
150 - ...unref(stepState),  
151 - deviceInfo: {  
152 - avatar: DeviceStep1Ref.value?.devicePic,  
153 - ...DeviceStep1Ref.value?.positionState,  
154 - },  
155 - deviceToken:  
156 - unref(current) === 0 || !unref(stepState).addAgree  
157 - ? null  
158 - : {  
159 - credentialsType: unref(stepState).credentialType,  
160 - credentialsId: unref(stepState).credentialsId,  
161 - credentialsValue:  
162 - unref(stepState).credentialType === credentialTypeEnum.MQTT_BASIC  
163 - ? JSON.stringify({  
164 - userName: unref(stepState).username,  
165 - password: unref(stepState).password,  
166 - clientId: unref(stepState).clientId,  
167 - })  
168 - : unref(stepState).credentialType === credentialTypeEnum.X_509  
169 - ? unref(stepState).publicKey  
170 - : null,  
171 - },  
172 - };  
173 - await createOrEditDevice(createData);  
174 - }  
175 - createMessage.success(unref(msg));  
176 - handleCancel();  
177 - closeModal();  
178 - emit('reload');  
179 } 186 }
180 return { 187 return {
181 getTitle, 188 getTitle,
1 <template> 1 <template>
2 <div class="wrapper"> 2 <div class="wrapper">
3 <div ref="wrapRef" :style="{ height, width }"> </div> 3 <div ref="wrapRef" :style="{ height, width }"> </div>
4 - <div class="right-wrap">  
5 - <BasicTable style="cursor: pointer" @register="registerTable" @rowClick="deviceRowClick"> 4 + <div class="right-wrap !dark:bg-dark-900">
  5 + <BasicTable
  6 + style="cursor: pointer"
  7 + @register="registerTable"
  8 + @rowClick="deviceRowClick"
  9 + class="dark:bg-dark-900"
  10 + >
6 <template #deviceState="{ record }"> 11 <template #deviceState="{ record }">
7 <Tag 12 <Tag
8 :color=" 13 :color="
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 import ConverScriptModal from '/@/views/scriptmanage/converscript/ConverScriptModal.vue'; 42 import ConverScriptModal from '/@/views/scriptmanage/converscript/ConverScriptModal.vue';
43 43
44 const { createMessage } = useMessage(); 44 const { createMessage } = useMessage();
45 - const selectScript = reactive({ 45 + const selectScript = reactive<Record<'script', Nullable<string>>>({
46 script: null, 46 script: null,
47 }); 47 });
48 const selectOptions: Ref<SelectTypes['options']> = ref([]); 48 const selectOptions: Ref<SelectTypes['options']> = ref([]);
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 }; 55 };
56 }); 56 });
57 }); 57 });
58 - const handleSuccess = async () => { 58 + const handleSuccess = async (val: { id: string }) => {
59 const res = await getScriptManageMeList(); 59 const res = await getScriptManageMeList();
60 selectOptions.value = res.map((m) => { 60 selectOptions.value = res.map((m) => {
61 return { 61 return {
@@ -63,6 +63,7 @@ @@ -63,6 +63,7 @@
63 value: m.id, 63 value: m.id,
64 }; 64 };
65 }); 65 });
  66 + selectScript.script = val.id;
66 }; 67 };
67 68
68 const [register] = useForm({ 69 const [register] = useForm({
@@ -101,7 +101,7 @@ @@ -101,7 +101,7 @@
101 converScriptRef.value?.setScriptOutputData(res?.output); 101 converScriptRef.value?.setScriptOutputData(res?.output);
102 } 102 }
103 } 103 }
104 - emits('success'); 104 + emits('success', res);
105 } finally { 105 } finally {
106 setModalProps({ confirmLoading: false }); 106 setModalProps({ confirmLoading: false });
107 } 107 }