Commit 35b677d25ee225a7dbc7459a899eb843465e66d6

Authored by xp.Huang
2 parents e569fd79 f23f07bc

Merge branch 'f-dev' into 'main'

fix:修复Teambition上的问题  wip:报表功能开发中

See merge request huang/yun-teng-iot-front!268
1 1 import { BasicPageParams } from '/@/api/model/baseModel';
2   -export type CameraQueryParam = BasicPageParams & CameraParam;
  2 +export type ReportQueryParam = BasicPageParams & CameraParam;
3 3
4 4 export type CameraParam = {
5 5 status: true;
... ... @@ -9,76 +9,38 @@ export type CameraParam = {
9 9 orderType: string;
10 10 };
11 11
12   -export interface CameraModel {
13   - accessMode: number;
14   - avatar?: string;
15   - brand: string;
16   - createTime?: '2022-04-19T11:33:13.113Z';
17   - creator?: string;
18   - defaultConfig?: string;
19   - description?: string;
20   - deviceInfo?: string;
21   - deviceType?: string;
22   - enabled?: true;
23   - icon?: string;
24   - id?: string;
25   - name: string;
26   - organizationId: string;
27   - organizationName?: string;
28   - roleIds?: ['string'];
29   - sn: string;
30   - status?: false;
31   - tenantExpireTime?: '2022-04-19T11:33:13.113Z';
32   - tenantId?: string;
33   - tenantProfileId?: string;
34   - tenantStatus?: 'DISABLED';
35   - updateTime?: '2022-04-19T11:33:13.113Z';
36   - updater?: string;
37   - videoUrl: string;
38   -}
39   -
40   -export interface StreamingManageRecord {
41   - id: string;
42   - creator: string;
  12 +export interface ReportModel {
  13 + attributeNature: number;
  14 + attributes: [string];
43 15 createTime: string;
  16 + creator: string;
  17 + dataCompare: number;
  18 + defaultConfig: string;
  19 + description: string;
  20 + devices: [string];
  21 + enabled: true;
  22 + endTs: number;
  23 + executeContent: string;
  24 + executeWay: number;
  25 + icon: string;
  26 + id: string;
44 27 name: string;
45   - enabled: boolean;
46   - tenantId: string;
47   - sn: string;
48 28 organizationId: string;
49   - organizationName: string;
50   - status: boolean;
51   - accessMode: number;
52   - playProtocol: number;
53   -}
54   -
55   -export interface StreamingMediaModel {
56   - id: string;
57   - creator: string;
58   - createTime: string;
59   - enabled: boolean;
  29 + queryCondition: {
  30 + agg: string;
  31 + interval: number;
  32 + limit: number;
  33 + orderBy: string;
  34 + useStrictDataTypes: false;
  35 + };
  36 + remark: string;
  37 + roleIds: [string];
  38 + startTs: number;
  39 + status: number;
  40 + tenantExpireTime: string;
60 41 tenantId: string;
61   - type: number;
62   - host: string;
63   - appKey: string;
64   - appSecret: string;
65   - ssl: number;
66   -}
67   -
68   -export interface StreamingQueryParam {
69   - host?: string;
70   -}
71   -
72   -export interface StreamingSubmitParam {
73   - type: number;
74   - ssl: number;
75   - host: string;
76   - appKey: string;
77   - appSecret: string;
78   - id?: string;
79   -}
80   -
81   -export interface StreamingMediaDeleteParam {
82   - tenantId?: string;
83   - ids: string[];
  42 + tenantProfileId: string;
  43 + tenantStatus: string;
  44 + updateTime: string;
  45 + updater: string;
84 46 }
... ...
1 1 import { defHttp } from '/@/utils/http/axios';
2   -import {
3   - CameraModel,
4   - CameraQueryParam,
5   - StreamingMediaDeleteParam,
6   - StreamingQueryParam,
7   - StreamingSubmitParam,
8   -} from './model/reportModel';
9   -
10   -enum CameraManagerApi {
11   - CAMERA_POST_URL = '/video',
12   - CAMERA_GET_URL = '/video',
13   - CAMERA_DELETE_URL = '/video',
14   - CAMERA_GET_DETAIL_URL = '/video',
15   - STREAMING_GET_URL = '/video/platform',
16   - STREAMING_POST_URL = '/video/platform',
17   - STREAMING_DELETE_URL = '/video/platform',
18   - STREAMING_PLAY_GET_URL = '/video/url',
  2 +import { ReportModel, ReportQueryParam } from './model/reportModel';
  3 +
  4 +enum ReportManagerApi {
  5 + GET_REPORT_API = '/report_form/config',
  6 + POST_REPORT_API = '/report_form/config',
  7 + DELETE_REPORT_API = '/report_form/config',
  8 + // PUT_REPORT_API = '/report_form',
  9 + // PUTID_REPORT_API = '/report_form',
19 10 }
20 11
21   -export const cameraPage = (params: CameraQueryParam) => {
22   - return defHttp.get<CameraQueryParam>({
23   - url: CameraManagerApi.CAMERA_GET_URL,
  12 +//分页
  13 +export const reportPage = (params: ReportQueryParam) => {
  14 + return defHttp.get<ReportQueryParam>({
  15 + url: ReportManagerApi.GET_REPORT_API,
24 16 params,
25 17 });
26 18 };
27 19
28   -/**
29   - * 删除视频
30   - * @param ids 删除的ids
31   - */
32   -export const deleteCameraManage = (ids: string[]) => {
  20 +//删除
  21 +export const deleteReportManage = (ids: string[]) => {
33 22 return defHttp.delete({
34   - url: CameraManagerApi.CAMERA_DELETE_URL,
  23 + url: ReportManagerApi.DELETE_REPORT_API,
35 24 data: {
36 25 ids: ids,
37 26 },
38 27 });
39 28 };
40 29
41   -// 创建或编辑视频
42   -export const createOrEditCameraManage = (data) => {
43   - return defHttp.post<CameraModel>({
44   - url: CameraManagerApi.CAMERA_POST_URL,
  30 +// 创建或编辑
  31 +export const createOrEditReportManage = (data) => {
  32 + return defHttp.post<ReportModel>({
  33 + url: ReportManagerApi.POST_REPORT_API,
45 34 data,
46 35 });
47 36 };
48 37
49   -// 查询视频详情
50   -export const getCameraManageDetail = (id: string) => {
51   - return defHttp.get({
52   - url: CameraManagerApi.CAMERA_GET_DETAIL_URL + `/${id}`,
53   - });
54   -};
55   -
56   -/**
57   - * @description 获取流媒体列表
58   - * @param params
59   - * @returns
60   - */
61   -export const getStreamingMediaList = (params: StreamingQueryParam) => {
62   - return defHttp.get({
63   - url: CameraManagerApi.STREAMING_GET_URL,
64   - params,
65   - });
66   -};
67   -
68   -/**
69   - * @description 更新/新增流媒体记录
70   - * @param params
71   - * @returns
72   - */
73   -export const createOrUpdateStreamingMediaRecord = (params: StreamingSubmitParam) => {
74   - return defHttp.post({
75   - url: CameraManagerApi.STREAMING_POST_URL,
76   - params,
77   - });
78   -};
79   -
80   -/**
81   - * @description 删除流媒体记录
82   - * @param params
83   - * @returns
84   - */
85   -export const deleteStreamingMediaRecord = (params: StreamingMediaDeleteParam) => {
86   - return defHttp.delete({
87   - url: CameraManagerApi.STREAMING_POST_URL,
88   - params,
89   - });
90   -};
  38 +// // 修改状态
  39 +// export const putReportConfigManage = (data) => {
  40 +// return defHttp.post<ReportModel>({
  41 +// url: ReportManagerApi.PUT_REPORT_API,
  42 +// data,
  43 +// });
  44 +// };
91 45
92   -/**
93   - * @description 获取流媒体播放地址
94   - * @param entityId
95   - * @returns
96   - */
97   -export const getStreamingPlayUrl = (entityId: string) => {
98   - return defHttp.get({
99   - url: `${CameraManagerApi.STREAMING_PLAY_GET_URL}/${entityId}`,
100   - });
101   -};
  46 +// // 修改状态
  47 +// export const putReportByidAndStatusManage = (data) => {
  48 +// return defHttp.post<ReportModel>({
  49 +// url: ReportManagerApi.PUTID_REPORT_API,
  50 +// data,
  51 +// });
  52 +// };
... ...
... ... @@ -60,7 +60,7 @@
60 60 });
61 61 const emit = defineEmits(['expand']);
62 62
63   - const show = ref(false);
  63 + const show = ref(true);
64 64
65 65 const { prefixCls } = useDesign('collapse-container');
66 66
... ...
... ... @@ -61,7 +61,7 @@ export const formSchema: FormSchema[] = [
61 61 colProps: { span: 24 },
62 62 required: true,
63 63 component: 'RadioGroup',
64   - defaultValue:'NOTICE',
  64 + defaultValue: 'NOTICE',
65 65 componentProps: {
66 66 options: [
67 67 {
... ... @@ -96,6 +96,7 @@ export const formSchema: FormSchema[] = [
96 96 colProps: { span: 24 },
97 97 label: '通知内容',
98 98 required: true,
  99 + defaultValue: '',
99 100 render: ({ model, field }) => {
100 101 return h(Tinymce, {
101 102 value: model[field],
... ...
... ... @@ -7,7 +7,12 @@
7 7 width="30%"
8 8 @ok="handleSubmit"
9 9 >
10   - <BasicForm @register="registerForm" />
  10 + <BasicForm @register="registerForm">
  11 + <template #deviceAttr="{ model, field }">
  12 + <deviceAttrColumn :orgId="model['organizationId']" :value="model['devices']" />
  13 + <p style="display: none">{{ field }}</p>
  14 + </template>
  15 + </BasicForm>
11 16 </BasicDrawer>
12 17 </template>
13 18 <script lang="ts" setup>
... ... @@ -15,8 +20,9 @@
15 20 import { BasicForm, useForm } from '/@/components/Form';
16 21 import { formSchema } from './config.data';
17 22 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
18   - // import { createOrEditCameraManage } from '/@/api/camera/cameraManager';
  23 + import { createOrEditReportManage } from '/@/api/report/reportManager';
19 24 import { useMessage } from '/@/hooks/web/useMessage';
  25 + import deviceAttrColumn from './cpns/MappingsForm.vue';
20 26
21 27 const emit = defineEmits(['success', 'register']);
22 28 const isUpdate = ref(true);
... ... @@ -51,7 +57,7 @@
51 57 if (!values) return;
52 58 let saveMessage = '添加成功';
53 59 let updateMessage = '修改成功';
54   - // await createOrEditCameraManage(values);
  60 + await createOrEditReportManage(values);
55 61 closeDrawer();
56 62 emit('success');
57 63 createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);
... ...
... ... @@ -4,75 +4,63 @@ import moment from 'moment';
4 4 import { getOrganizationList } from '/@/api/system/system';
5 5 import { copyTransFun } from '/@/utils/fnUtils';
6 6 import { screenLinkPageByDeptIdGetDevice } from '/@/api/ruleengine/ruleengineApi';
7   -import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
8 7 import { findDictItemByCode } from '/@/api/system/dict';
9   -
10   -export enum TypeEnum {
11   - IS_TIMING = 'TIMING',
12   - IS_WEEK = 'week',
13   - IS_MONTH = 'month',
14   -}
15   -export const isTiming = (type: string) => {
16   - return type === TypeEnum.IS_TIMING;
17   -};
18   -export const isWeek = (type: string) => {
19   - return type === TypeEnum.IS_WEEK;
20   -};
21   -
22   -export const isMonth = (type: string) => {
23   - return type === TypeEnum.IS_MONTH;
24   -};
25   -
26   -export enum AggregateDataEnum {
27   - MIN = 'MIN',
28   - MAX = 'MAX',
29   - AVG = 'AVG',
30   - SUM = 'SUM',
31   - COUNT = 'COUNT',
32   - NONE = 'NONE',
33   -}
  8 +import {
  9 + optionsConfig,
  10 + isTiming,
  11 + isWeek,
  12 + isMonth,
  13 + isEmpty,
  14 + isDefultWeek,
  15 + isMin,
  16 + isMax,
  17 + isAvg,
  18 + isSum,
  19 + isCountAll,
  20 + AggregateDataEnum,
  21 +} from './timeConfig';
34 22
35 23 // 表格配置
36 24 export const columns: BasicColumn[] = [
37 25 {
38 26 title: '配置名称',
39   - dataIndex: '1',
  27 + dataIndex: 'name',
40 28 width: 80,
41 29 },
42 30 {
43 31 title: '所属组织',
44   - dataIndex: '2',
  32 + dataIndex: 'organizationId',
45 33 width: 120,
46 34 },
47 35 {
48 36 title: '数据类型',
49   - dataIndex: '3',
  37 + dataIndex: 'dataCompare',
50 38 width: 120,
51 39 },
52 40 {
53 41 title: '配置状态',
54   - dataIndex: '4',
  42 + dataIndex: 'status',
55 43 width: 120,
56 44 },
57 45 {
58 46 title: '执行方式',
59   - dataIndex: '5',
  47 + dataIndex: 'executeWay',
60 48 width: 160,
61 49 },
62 50 {
63 51 title: '执行设备',
64   - dataIndex: '6',
  52 + dataIndex: 'devices',
65 53 width: 160,
66 54 slots: { customRender: 'doDeviceSlot' },
67 55 },
68 56 {
69 57 title: '创建人',
70   - dataIndex: '7',
  58 + dataIndex: 'creator',
71 59 width: 180,
72 60 },
73 61 {
74 62 title: '创建日期',
75   - dataIndex: '8',
  63 + dataIndex: 'createTime',
76 64 width: 180,
77 65 },
78 66 ];
... ... @@ -84,7 +72,7 @@ export const viewDeviceColumn: BasicColumn[] = [
84 72 },
85 73 {
86 74 title: '属性',
87   - dataIndex: 'attr',
  75 + dataIndex: 'attributes',
88 76 width: 120,
89 77 },
90 78 ];
... ... @@ -92,7 +80,7 @@ export const viewDeviceColumn: BasicColumn[] = [
92 80 // 查询配置
93 81 export const searchFormSchema: FormSchema[] = [
94 82 {
95   - field: '1',
  83 + field: 'name',
96 84 label: '配置名称',
97 85 component: 'Input',
98 86 colProps: { span: 6 },
... ... @@ -102,7 +90,7 @@ export const searchFormSchema: FormSchema[] = [
102 90 },
103 91 },
104 92 {
105   - field: '2',
  93 + field: 'status',
106 94 label: '配置状态',
107 95 component: 'Select',
108 96 colProps: { span: 6 },
... ... @@ -121,7 +109,7 @@ export const searchFormSchema: FormSchema[] = [
121 109 },
122 110 },
123 111 {
124   - field: '3',
  112 + field: 'createTime',
125 113 label: '创建时间',
126 114 component: 'RangePicker',
127 115 componentProps: {
... ... @@ -136,7 +124,7 @@ export const searchFormSchema: FormSchema[] = [
136 124 // 新增编辑配置
137 125 export const formSchema: QFormSchema[] = [
138 126 {
139   - field: '1',
  127 + field: 'name',
140 128 label: '报表名称',
141 129 colProps: { span: 24 },
142 130 required: true,
... ... @@ -168,26 +156,9 @@ export const formSchema: QFormSchema[] = [
168 156 };
169 157 });
170 158 updateSchema({
171   - field: 'entityId',
  159 + field: 'devices',
172 160 componentProps: {
173 161 options,
174   - async onChange(e1) {
175   - if (e1) {
176   - const res = await getAttribute(e, e1.join(','));
177   - const attr = res.map((item) => {
178   - return {
179   - label: item,
180   - value: item,
181   - };
182   - });
183   - updateSchema({
184   - field: 'attr',
185   - componentProps: {
186   - options: attr,
187   - },
188   - });
189   - }
190   - },
191 162 },
192 163 });
193 164 }
... ... @@ -203,7 +174,7 @@ export const formSchema: QFormSchema[] = [
203 174 },
204 175 },
205 176 {
206   - field: '3',
  177 + field: 'remark',
207 178 label: '描述',
208 179 colProps: { span: 24 },
209 180 component: 'InputTextArea',
... ... @@ -213,23 +184,23 @@ export const formSchema: QFormSchema[] = [
213 184 },
214 185 },
215 186 {
216   - field: 'actionS',
  187 + field: 'executeWay',
217 188 component: 'RadioGroup',
218 189 label: '执行方式',
219 190 colProps: {
220 191 span: 24,
221 192 },
222   - defaultValue: '1',
  193 + defaultValue: 1,
223 194 componentProps: {
224 195 placeholder: '请选择执行方式',
225 196 options: [
226 197 {
227 198 label: '立即执行',
228   - value: '1',
  199 + value: 1,
229 200 },
230 201 {
231 202 label: '定时执行',
232   - value: 'TIMING',
  203 + value: 0,
233 204 },
234 205 ],
235 206 },
... ... @@ -249,7 +220,7 @@ export const formSchema: QFormSchema[] = [
249 220 { label: '每月', value: 'month' },
250 221 ],
251 222 },
252   - ifShow: ({ values }) => isTiming(values.actionS),
  223 + ifShow: ({ values }) => isTiming(values.executeWay),
253 224 },
254 225 {
255 226 field: '51111',
... ... @@ -303,10 +274,10 @@ export const formSchema: QFormSchema[] = [
303 274 labelField: 'itemText',
304 275 valueField: 'itemValue',
305 276 },
306   - ifShow: ({ values }) => isTiming(values.actionS),
  277 + ifShow: ({ values }) => isTiming(values.executeWay),
307 278 },
308 279 {
309   - field: 'entityId',
  280 + field: 'devices',
310 281 label: '设备',
311 282 required: true,
312 283 helpMessage: ['报表配置只对拥有数值型属性的设备才能配置'],
... ... @@ -318,30 +289,61 @@ export const formSchema: QFormSchema[] = [
318 289 colProps: { span: 24 },
319 290 },
320 291 {
321   - field: '7',
  292 + field: 'attributeNature',
322 293 component: 'RadioGroup',
323 294 label: '属性性质',
324 295 required: true,
325 296 colProps: {
326 297 span: 24,
327 298 },
328   - defaultValue: '1',
329   - componentProps: {
330   - placeholder: '请选择属性性质',
331   - options: [
  299 + defaultValue: 0,
  300 + componentProps: ({ formActionType }) => {
  301 + const { updateSchema } = formActionType;
  302 + const options = [
332 303 {
333 304 label: '共有',
334   - value: '1',
  305 + value: 0,
335 306 },
336 307 {
337 308 label: '全部',
338   - value: '2',
  309 + value: 1,
339 310 },
340   - ],
  311 + ];
  312 + return {
  313 + options,
  314 + async onChange(e) {
  315 + if (e) {
  316 + let dataCompareOpions: any = [];
  317 + if (e.target.value == 1) {
  318 + dataCompareOpions = [{ label: '历史数据', value: 0 }];
  319 + updateSchema({
  320 + field: 'dataCompare',
  321 + componentProps: {
  322 + options: dataCompareOpions,
  323 + },
  324 + });
  325 + } else {
  326 + dataCompareOpions = [
  327 + { label: '历史数据', value: 0 },
  328 + { label: '同比', value: 1 },
  329 + { label: '环比', value: 2 },
  330 + ];
  331 + updateSchema({
  332 + field: 'dataCompare',
  333 + componentProps: {
  334 + options: dataCompareOpions,
  335 + },
  336 + });
  337 + }
  338 + }
  339 + },
  340 + maxLength: 250,
  341 + placeholder: '请选择属性性质',
  342 + };
341 343 },
342 344 },
343 345 {
344   - field: 'attr',
  346 + field: 'devices1',
345 347 label: '设备属性',
346 348 required: true,
347 349 component: 'Select',
... ... @@ -349,24 +351,25 @@ export const formSchema: QFormSchema[] = [
349 351 placeholder: '请选择设备属性',
350 352 },
351 353 colProps: { span: 24 },
  354 + slot:'deviceAttr'
352 355 },
353 356 {
354   - field: '9',
  357 + field: 'dataCompare',
355 358 label: '数据类型',
356 359 required: true,
357 360 component: 'Select',
358 361 componentProps: {
359 362 placeholder: '请选择数据类型',
360 363 options: [
361   - { label: '历史数据', value: '1' },
362   - { label: '同比', value: '2' },
363   - { label: '环比', value: '3' },
  364 + { label: '历史数据', value: 0 },
  365 + { label: '同比', value: 1 },
  366 + { label: '环比', value: 2 },
364 367 ],
365 368 },
366 369 colProps: { span: 24 },
367 370 },
368 371 {
369   - field: '10',
  372 + field: 'agg',
370 373 label: '聚合条件',
371 374 required: true,
372 375 component: 'Select',
... ... @@ -389,56 +392,229 @@ export const formSchema: QFormSchema[] = [
389 392 label: '最小值',
390 393 value: AggregateDataEnum.MIN,
391 394 },
  395 + {
  396 + label: '计数',
  397 + value: AggregateDataEnum.COUNT,
  398 + },
  399 + {
  400 + label: '空',
  401 + value: AggregateDataEnum.NONE,
  402 + },
392 403 ],
393 404 },
394 405 colProps: { span: 24 },
395 406 },
396 407 {
397   - field: '91112',
  408 + field: 'limit',
  409 + component: 'InputNumber',
  410 + label: '最大值',
  411 + required: true,
  412 + defaultValue: 200,
  413 + colProps: { span: 22 },
  414 + componentProps: {
  415 + min: 7,
  416 + max: 50000,
  417 + },
  418 + ifShow: ({ values }) => isEmpty(values.agg),
  419 + },
  420 + {
  421 + field: 'defaultWeek',
  422 + component: 'ApiRadioGroup',
398 423 label: '查询周期',
399 424 required: true,
400   - component: 'Select',
  425 + colProps: {
  426 + span: 24,
  427 + },
  428 + defaultValue: '2',
401 429 componentProps: {
402 430 placeholder: '请选择查询周期',
403 431 options: [
404   - { label: '1秒', value: '1000' },
405   - { label: '5秒', value: '5000' },
406   - { label: '10秒', value: '10000' },
407   - { label: '15秒', value: '15000' },
408   - { label: '30秒', value: '30000' },
409   - { label: '1分', value: '60000' },
410   - { label: '2分', value: '120000' },
411   - { label: '5分', value: '300000' },
412   - { label: '10分', value: '600000' },
413   - { label: '15分', value: '900000' },
414   - { label: '30分', value: '1800000' },
415   - { label: '1小时', value: '3600000' },
416   - { label: '2小时', value: '7200000' },
417   - { label: '5小时', value: '18000000' },
418   - { label: '10小时', value: '36000000' },
419   - { label: '12小时', value: '43200000' },
420   - { label: '1天', value: '86400000' },
421   - { label: '7天', value: '604800000' },
422   - { label: '30天', value: '2592000000' },
  432 + {
  433 + label: '自定义周期',
  434 + value: 'defaultIsWeek',
  435 + },
  436 + {
  437 + label: '固定周期',
  438 + value: '2',
  439 + },
423 440 ],
424 441 },
  442 + },
  443 + {
  444 + field: 'interval',
  445 + label: '时间段',
  446 + required: true,
  447 + component: 'RangePicker',
  448 + componentProps: {
  449 + showTime: {
  450 + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  451 + },
  452 + placeholder: '请选择时间段',
  453 + },
  454 + colProps: { span: 24 },
  455 + ifShow: ({ values }) => isDefultWeek(values.defaultWeek),
  456 + },
  457 + {
  458 + field: '91112',
  459 + label: '时间周期',
  460 + required: true,
  461 + component: 'ApiSelect',
  462 + defaultValue: '1000',
  463 + componentProps: ({ formActionType }) => {
  464 + const { updateSchema } = formActionType;
  465 + return {
  466 + api: async () => {
  467 + const data: any = await findDictItemByCode({ dictCode: 'query_week' });
  468 + const option = data.map((item) => {
  469 + return {
  470 + label: item.itemText,
  471 + value: item.itemValue,
  472 + };
  473 + });
  474 + return option;
  475 + },
  476 + async onChange(e) {
  477 + if (Number(e) <= 30000) {
  478 + //30秒以内 -> 1秒
  479 + updateSchema({
  480 + field: '102121',
  481 + componentProps: {
  482 + options: optionsConfig.slice(0, 1),
  483 + },
  484 + });
  485 + } else if (Number(e) == 60000) {
  486 + //1分钟以内 -> 1秒 5秒
  487 + updateSchema({
  488 + field: '102121',
  489 + componentProps: {
  490 + options: optionsConfig.slice(0, 2),
  491 + },
  492 + });
  493 + } else if (Number(e) == 120000) {
  494 + //2分钟以内 -> 1秒 5秒 10 15
  495 + updateSchema({
  496 + field: '102121',
  497 + componentProps: {
  498 + options: optionsConfig.slice(0, 4),
  499 + },
  500 + });
  501 + } else if (Number(e) == 300000) {
  502 + //5分钟以内 -> 1秒 5秒 10 15 30
  503 + updateSchema({
  504 + field: '102121',
  505 + componentProps: {
  506 + options: optionsConfig.slice(0, 5),
  507 + },
  508 + });
  509 + } else if (Number(e) == 600000) {
  510 + //10分钟以内 -> 5秒 10 15 30 1分钟
  511 + updateSchema({
  512 + field: '102121',
  513 + componentProps: {
  514 + options: optionsConfig.slice(1, 2).concat(optionsConfig.slice(2, 6)),
  515 + },
  516 + });
  517 + } else if (Number(e) == 900000 || Number(e) == 1800000) {
  518 + //15 30 分钟以内 -> 5秒 10 15 30 1分钟 2分钟
  519 + updateSchema({
  520 + field: '102121',
  521 + componentProps: {
  522 + options: optionsConfig.slice(1, 2).concat(optionsConfig.slice(2, 7)),
  523 + },
  524 + });
  525 + } else if (Number(e) == 3600000) {
  526 + //1小时以内 -> 10秒 15 30 1分钟 2分钟 5分钟
  527 + updateSchema({
  528 + field: '102121',
  529 + componentProps: {
  530 + options: optionsConfig.slice(2, 8),
  531 + },
  532 + });
  533 + } else if (Number(e) == 7200000) {
  534 + //2小时以内 -> 15秒 30 1分钟 2分钟 5分钟 10 15
  535 + updateSchema({
  536 + field: '102121',
  537 + componentProps: {
  538 + options: optionsConfig.slice(3, 10),
  539 + },
  540 + });
  541 + } else if (Number(e) == 18000000) {
  542 + //5小时以内 -> 1分钟 2分钟 5分钟 10 15 30
  543 + updateSchema({
  544 + field: '102121',
  545 + componentProps: {
  546 + options: optionsConfig.slice(5, 11),
  547 + },
  548 + });
  549 + } else if (Number(e) == 36000000 || Number(e) == 43200000) {
  550 + //10 12小时以内 -> 2分钟 5分钟 10 15 30 1小时
  551 + updateSchema({
  552 + field: '102121',
  553 + componentProps: {
  554 + options: optionsConfig.slice(6, 12),
  555 + },
  556 + });
  557 + } else if (Number(e) == 86400000) {
  558 + //1天以内 -> 5分钟 10 15 30 1小时 2
  559 + updateSchema({
  560 + field: '102121',
  561 + componentProps: {
  562 + options: optionsConfig.slice(7, 13),
  563 + },
  564 + });
  565 + } else if (Number(e) == 604800000) {
  566 + //7天以内 -> 30分钟 1小时 2 5 10 12 1天
  567 + updateSchema({
  568 + field: '102121',
  569 + componentProps: {
  570 + options: optionsConfig.slice(10, 17),
  571 + },
  572 + });
  573 + } else if (Number(e) == 2592000000) {
  574 + //30天以内 -> 2小时 5 10 12 1天
  575 + updateSchema({
  576 + field: '102121',
  577 + componentProps: {
  578 + options: optionsConfig.slice(12, 17),
  579 + },
  580 + });
  581 + }
  582 + },
  583 + maxLength: 250,
  584 + placeholder: '请选择查询周期',
  585 + };
  586 + },
425 587 colProps: { span: 24 },
  588 + ifShow: ({ values }) =>
  589 + (!isEmpty(values.agg) && !isDefultWeek(values.defaultWeek)) ||
  590 + isMin(values.agg) ||
  591 + isMax(values.agg) ||
  592 + isAvg(values.agg) ||
  593 + isSum(values.agg) ||
  594 + isCountAll(values.agg),
426 595 },
427 596 {
428 597 field: '102121',
429 598 label: '间隔时间',
430 599 required: true,
431 600 component: 'Select',
  601 + colProps: { span: 24 },
  602 + defaultValue: '1000',
432 603 componentProps: {
433 604 placeholder: '请选择间隔时间',
434 605 options: [
435   - { label: '2小时', value: '7200000' },
436   - { label: '5小时', value: '18000000' },
437   - { label: '10小时', value: '36000000' },
438   - { label: '12小时', value: '43200000' },
439   - { label: '1天', value: '86400000' },
  606 + {
  607 + label: '1秒',
  608 + value: '1000',
  609 + },
440 610 ],
441 611 },
442   - colProps: { span: 24 },
  612 + ifShow: ({ values }) =>
  613 + (!isEmpty(values.agg) && !isDefultWeek(values.defaultWeek)) ||
  614 + isMin(values.agg) ||
  615 + isMax(values.agg) ||
  616 + isAvg(values.agg) ||
  617 + isSum(values.agg) ||
  618 + isCountAll(values.agg),
443 619 },
444 620 ];
... ...
  1 +<template>
  2 + <div
  3 + v-for="(param, index) in dynamicInput.params"
  4 + :key="index"
  5 + style="display: flex; margin-top: 0.25vh"
  6 + >
  7 + <a-input
  8 + :disabled="true"
  9 + placeholder="设备"
  10 + v-model:value="param.key"
  11 + style="width: 38%; margin-bottom: 5px; margin-left: 1vh"
  12 + @change="emitChange"
  13 + />
  14 + <Select
  15 + placeholder="请选择设备属性"
  16 + v-model:value="param.dataType"
  17 + style="width: 160px; margin-left: 1.8vw"
  18 + :options="selectOptions"
  19 + @change="emitChange"
  20 + />
  21 + <MinusCircleOutlined
  22 + v-if="dynamicInput.params.length > min"
  23 + class="dynamic-delete-button"
  24 + @click="remove(param)"
  25 + style="width: 50px; display: none"
  26 + />
  27 + </div>
  28 + <div style="display: none">
  29 + <a-button type="text" style="width: 28%; margin-top: 0.25vh" @click="add">
  30 + <PlusCircleOutlined />
  31 + Add mapping
  32 + </a-button>
  33 + </div>
  34 +</template>
  35 +<script lang="ts">
  36 + import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons-vue';
  37 + import { defineComponent, reactive, UnwrapRef, watchEffect, ref } from 'vue';
  38 + import { propTypes } from '/@/utils/propTypes';
  39 + import { SelectTypes } from 'ant-design-vue/es/select';
  40 + import { Select } from 'ant-design-vue';
  41 + import { screenLinkPageByDeptIdGetDevice } from '/@/api/ruleengine/ruleengineApi';
  42 + import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
  43 +
  44 + interface Params {
  45 + [x: string]: string;
  46 + dataType: string;
  47 + key: string;
  48 + }
  49 +
  50 + export default defineComponent({
  51 + name: 'JAddInput',
  52 + components: {
  53 + MinusCircleOutlined,
  54 + PlusCircleOutlined,
  55 + Select,
  56 + },
  57 + //--------------不继承Antd Design Vue Input的所有属性 否则控制台报大片警告--------------
  58 + inheritAttrs: false,
  59 + props: {
  60 + value: propTypes.array.def([]),
  61 + //自定义删除按钮多少才会显示
  62 + min: propTypes.integer.def(0),
  63 + orgId: propTypes.string.def(''),
  64 + },
  65 + emits: ['change', 'update:value', 'dynamicReduceHeight', 'dynamicAddHeight'],
  66 + setup(props, { emit }) {
  67 + const selectOptions = ref<SelectTypes['options']>([]);
  68 +
  69 + //input动态数据
  70 + const dynamicInput: UnwrapRef<{ params: Params[] }> = reactive({ params: [] });
  71 + //删除Input
  72 + const remove = (item: Params) => {
  73 + let index = dynamicInput.params.indexOf(item);
  74 + if (index !== -1) {
  75 + dynamicInput.params.splice(index, 1);
  76 + }
  77 + emitChange();
  78 + emit('dynamicReduceHeight');
  79 + };
  80 +
  81 + //新增Input
  82 + const add = () => {
  83 + dynamicInput.params.push({
  84 + dataType: 'STRING',
  85 + key: '',
  86 + });
  87 + emitChange();
  88 + emit('dynamicAddHeight');
  89 + };
  90 +
  91 + //监听传入数据value
  92 + watchEffect(() => {
  93 + initVal();
  94 + });
  95 +
  96 + /**
  97 + * 初始化数值
  98 + */
  99 + async function initVal() {
  100 + dynamicInput.params = [];
  101 + if (props.value) {
  102 + if (props.orgId) {
  103 + const res = await getAttribute(props.orgId, props.value.join(','));
  104 + selectOptions.value = res.map((o) => {
  105 + return {
  106 + label: o,
  107 + value: o,
  108 + };
  109 + });
  110 + const { items } = await screenLinkPageByDeptIdGetDevice({
  111 + organizationId: props.orgId,
  112 + });
  113 + const options = items.map((item) => {
  114 + return {
  115 + label: item.name,
  116 + value: item.tbDeviceId,
  117 + };
  118 + });
  119 + const temp: any = [];
  120 + options.forEach((f) => {
  121 + props.value.forEach((f1) => {
  122 + if (f1 == f.value) {
  123 + temp.push({
  124 + label: f.label,
  125 + value: f.value,
  126 + });
  127 + }
  128 + });
  129 + });
  130 + let jsonObj = temp;
  131 + jsonObj.forEach((item: Params) => {
  132 + dynamicInput.params.push({
  133 + dataType: item.dataType,
  134 + key: item.label,
  135 + value: item.value,
  136 + });
  137 + });
  138 + }
  139 + }
  140 + }
  141 + /**
  142 + * 数值改变
  143 + */
  144 + function emitChange() {
  145 + let obj: any = [];
  146 + if (dynamicInput.params.length > 0) {
  147 + dynamicInput.params.forEach((item: Params) => {
  148 + obj.push({
  149 + attr: item.dataType,
  150 + tbDeviceId: item.value,
  151 + });
  152 + });
  153 + }
  154 + console.log('数值改变', obj);
  155 + emit('change', obj);
  156 + emit('update:value', obj);
  157 + }
  158 +
  159 + return {
  160 + dynamicInput,
  161 + emitChange,
  162 + remove,
  163 + add,
  164 + selectOptions,
  165 + };
  166 + },
  167 + });
  168 +</script>
  169 +<style scoped>
  170 + .dynamic-delete-button {
  171 + cursor: pointer;
  172 + position: relative;
  173 + top: 4px;
  174 + font-size: 24px;
  175 + color: #999;
  176 + transition: all 0.3s;
  177 + }
  178 +
  179 + .dynamic-delete-button:hover {
  180 + color: #777;
  181 + }
  182 +
  183 + .dynamic-delete-button[disabled] {
  184 + cursor: not-allowed;
  185 + opacity: 0.5;
  186 + }
  187 +</style>
... ...
... ... @@ -58,7 +58,7 @@
58 58 import { useDrawer } from '/@/components/Drawer';
59 59 import ReportConfigDrawer from './ReportConfigDrawer.vue';
60 60 import DevicePreviewModal from './DevicePreviewModal.vue';
61   - import { cameraPage, deleteCameraManage } from '/@/api/camera/cameraManager';
  61 + import { reportPage, deleteReportManage } from '/@/api/report/reportManager';
62 62 import { searchFormSchema, columns } from './config.data';
63 63 import { Authority } from '/@/components/Authority';
64 64 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
... ... @@ -70,7 +70,7 @@
70 70
71 71 const [registerTable, { reload, setProps }] = useTable({
72 72 title: '报表列表',
73   - api: cameraPage,
  73 + api: reportPage,
74 74 columns,
75 75 showIndexColumn: false,
76 76 clickToRowSelect: false,
... ... @@ -100,7 +100,7 @@
100 100 };
101 101
102 102 const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete(
103   - deleteCameraManage,
  103 + deleteReportManage,
104 104 handleSuccess,
105 105 setProps
106 106 );
... ...
  1 +interface IOptionConfig {
  2 + label: string;
  3 + value: string;
  4 +}
  5 +
  6 +export const optionsConfig: IOptionConfig[] = [
  7 + {
  8 + label: '1秒',
  9 + value: '1000',
  10 + },
  11 + {
  12 + label: '5秒',
  13 + value: '5000',
  14 + },
  15 + {
  16 + label: '10秒',
  17 + value: '10000',
  18 + },
  19 + {
  20 + label: '15秒',
  21 + value: '15000',
  22 + },
  23 + {
  24 + label: '30秒',
  25 + value: '30000',
  26 + },
  27 + {
  28 + label: '1分钟',
  29 + value: '60000',
  30 + },
  31 + {
  32 + label: '2分钟',
  33 + value: '120000',
  34 + },
  35 + {
  36 + label: '5分钟',
  37 + value: '300000',
  38 + },
  39 + {
  40 + label: '10分钟',
  41 + value: '600000',
  42 + },
  43 + {
  44 + label: '15分钟',
  45 + value: '900000',
  46 + },
  47 + {
  48 + label: '30分钟',
  49 + value: '1800000',
  50 + },
  51 + {
  52 + label: '1小时',
  53 + value: '3600000',
  54 + },
  55 + {
  56 + label: '2小时',
  57 + value: '7200000',
  58 + },
  59 + {
  60 + label: '5小时',
  61 + value: '18000000',
  62 + },
  63 + {
  64 + label: '10小时',
  65 + value: '36000000',
  66 + },
  67 + {
  68 + label: '12小时',
  69 + value: '43200000',
  70 + },
  71 + {
  72 + label: '1天',
  73 + value: '86400000',
  74 + },
  75 +];
  76 +
  77 +export enum TypeEnum {
  78 + IS_TIMING = 0,
  79 + IS_WEEK = 'week',
  80 + IS_MONTH = 'month',
  81 + IS_EMPTY = 'NONE',
  82 + IS_DEFAULT_WEEK = 'defaultIsWeek',
  83 + IS_MIN = 'MIN',
  84 + IS_MAX = 'MAX',
  85 + IS_AVG = 'AVG',
  86 + IS_SUM = 'SUM',
  87 + COUNT = 'COUNT',
  88 +}
  89 +
  90 +export enum AggregateDataEnum {
  91 + MIN = 'MIN',
  92 + MAX = 'MAX',
  93 + AVG = 'AVG',
  94 + SUM = 'SUM',
  95 + COUNT = 'COUNT',
  96 + NONE = 'NONE',
  97 +}
  98 +
  99 +export const isTiming = (type: string) => {
  100 + return type === TypeEnum.IS_TIMING;
  101 +};
  102 +
  103 +export const isWeek = (type: string) => {
  104 + return type === TypeEnum.IS_WEEK;
  105 +};
  106 +
  107 +export const isMonth = (type: string) => {
  108 + return type === TypeEnum.IS_MONTH;
  109 +};
  110 +
  111 +export const isEmpty = (type: string) => {
  112 + return type === TypeEnum.IS_EMPTY;
  113 +};
  114 +
  115 +export const isDefultWeek = (type: string) => {
  116 + return type === TypeEnum.IS_DEFAULT_WEEK;
  117 +};
  118 +
  119 +export const isMin = (type: string) => {
  120 + return type === TypeEnum.IS_MIN;
  121 +};
  122 +
  123 +export const isMax = (type: string) => {
  124 + return type === TypeEnum.IS_MAX;
  125 +};
  126 +
  127 +export const isAvg = (type: string) => {
  128 + return type === TypeEnum.IS_AVG;
  129 +};
  130 +export const isSum = (type: string) => {
  131 + return type === TypeEnum.IS_SUM;
  132 +};
  133 +
  134 +export const isCountAll = (type: string) => {
  135 + return type === TypeEnum.COUNT;
  136 +};
... ...
... ... @@ -272,11 +272,15 @@
272 272 if (isApiHeaders && Object.values(isApiHeaders).includes('')) {
273 273 return createMessage.error('请填写属性');
274 274 }
275   - await postAddConvertApi(allPostForm);
276   - createMessage.success('数据流转新增成功');
277   - emit('success');
278   - defineClearFunc();
279   - closeModal();
  275 + const res = await postAddConvertApi(allPostForm);
  276 + if (res) {
  277 + closeModal();
  278 + createMessage.success('数据流转新增成功');
  279 + setTimeout(() => {
  280 + emit('success');
  281 + }, 500);
  282 + defineClearFunc();
  283 + }
280 284 } else {
281 285 await addOrEditFunc();
282 286 if (!isEdit.value) {
... ...
... ... @@ -15,7 +15,8 @@
15 15 <img v-if="logoPic" :src="logoPic" />
16 16 <div v-else>
17 17 <div style="margin-top: 1.875rem">
18   - <PlusOutlined style="font-size: 2.5rem" />
  18 + <LoadingOutlined v-if="loading" />
  19 + <PlusOutlined v-else style="font-size: 2.5rem" />
19 20 </div>
20 21 <div
21 22 class="ant-upload-text flex"
... ... @@ -38,7 +39,8 @@
38 39 <img v-if="bgPic" :src="bgPic" alt="avatar" />
39 40 <div v-else>
40 41 <div style="margin-top: 1.875rem">
41   - <PlusOutlined style="font-size: 2.5rem" />
  42 + <LoadingOutlined v-if="loading1" />
  43 + <PlusOutlined v-else style="font-size: 2.5rem" />
42 44 </div>
43 45 <div
44 46 class="ant-upload-text flex"
... ... @@ -93,7 +95,7 @@
93 95 import { BasicForm, useForm } from '/@/components/Form/index';
94 96 import { Loading } from '/@/components/Loading/index';
95 97 import { Card, Upload, Input, Modal } from 'ant-design-vue';
96   - import { PlusOutlined } from '@ant-design/icons-vue';
  98 + import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
97 99 import { schemas } from '../config/AppDraw.config';
98 100 import { FileItem, FileInfo } from '../types/index';
99 101 import { logoUpload, bgUpload } from '/@/api/oem/index';
... ... @@ -111,8 +113,11 @@
111 113 Input,
112 114 Modal,
113 115 Authority,
  116 + LoadingOutlined,
114 117 },
115 118 setup() {
  119 + const loading = ref(false);
  120 + const loading1 = ref(false);
116 121 const compState = ref({
117 122 absolute: false,
118 123 loading: false,
... ... @@ -153,11 +158,14 @@
153 158 const logoPic = ref();
154 159 async function customUploadLogoPic({ file }) {
155 160 if (beforeUploadLogoPic(file)) {
  161 + logoPic.value = '';
  162 + loading.value = true;
156 163 const formData = new FormData();
157 164 formData.append('file', file);
158 165 const response = await logoUpload(formData);
159 166 if (response.fileStaticUri) {
160 167 logoPic.value = response.fileStaticUri;
  168 + loading.value = false;
161 169 }
162 170 }
163 171 }
... ... @@ -177,11 +185,14 @@
177 185 const bgPic = ref();
178 186 async function customUploadBgPic({ file }) {
179 187 if (beforeUploadBgPic(file)) {
  188 + bgPic.value = '';
  189 + loading1.value = true;
180 190 const formData = new FormData();
181 191 formData.append('file', file);
182 192 const response = await bgUpload(formData);
183 193 if (response.fileStaticUri) {
184 194 bgPic.value = response.fileStaticUri;
  195 + loading1.value = false;
185 196 }
186 197 }
187 198 }
... ... @@ -202,7 +213,6 @@
202 213 if (beforeUploadHomeSwiper(file)) {
203 214 const formData = new FormData();
204 215 formData.append('file', file);
205   -
206 216 const response = await bgUpload(formData);
207 217 if (response.fileStaticUri) {
208 218 fileList.value.push({
... ... @@ -294,6 +304,8 @@
294 304 bgPic,
295 305 previewVisible,
296 306 previewImage,
  307 + loading,
  308 + loading1,
297 309 };
298 310 },
299 311 });
... ...
... ... @@ -14,7 +14,8 @@
14 14 <img v-if="logoPic" :src="logoPic" />
15 15 <div v-else>
16 16 <div style="margin-top: 1.875rem">
17   - <PlusOutlined style="font-size: 2.5rem" />
  17 + <LoadingOutlined v-if="loading" />
  18 + <PlusOutlined v-else style="font-size: 2.5rem" />
18 19 </div>
19 20 <div
20 21 class="ant-upload-text flex"
... ... @@ -40,7 +41,8 @@
40 41 </div>
41 42 <div v-else>
42 43 <div style="margin-top: 20px">
43   - <PlusOutlined style="font-size: 30px" />
  44 + <LoadingOutlined v-if="loading1" />
  45 + <PlusOutlined v-else style="font-size: 30px" />
44 46 </div>
45 47 <div
46 48 class="ant-upload-text flex"
... ... @@ -63,7 +65,8 @@
63 65 <img v-if="bgPic" :src="bgPic" alt="avatar" />
64 66 <div v-else>
65 67 <div style="margin-top: 1.875rem">
66   - <PlusOutlined style="font-size: 2.5rem" />
  68 + <LoadingOutlined v-if="loading2" />
  69 + <PlusOutlined v-else style="font-size: 2.5rem" />
67 70 </div>
68 71 <div
69 72 class="ant-upload-text flex"
... ... @@ -98,7 +101,7 @@
98 101 import { useMessage } from '/@/hooks/web/useMessage';
99 102 import type { FileItem } from '/@/components/Upload/src/typing';
100 103 import { logoUpload, iconUpload, bgUpload, getPlatForm, updatePlatForm } from '/@/api/oem/index';
101   - import { PlusOutlined } from '@ant-design/icons-vue';
  104 + import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
102 105 import { useUserStore } from '/@/store/modules/user';
103 106 import { createLocalStorage } from '/@/utils/cache/index';
104 107 import { Authority } from '/@/components/Authority';
... ... @@ -112,8 +115,12 @@
112 115 Input,
113 116 PlusOutlined,
114 117 Authority,
  118 + LoadingOutlined,
115 119 },
116 120 setup() {
  121 + const loading = ref(false);
  122 + const loading1 = ref(false);
  123 + const loading2= ref(false);
117 124 const compState = ref({
118 125 absolute: false,
119 126 loading: false,
... ... @@ -138,11 +145,14 @@
138 145 // logo图片上传
139 146 async function customUploadLogoPic({ file }) {
140 147 if (beforeUploadLogoPic(file)) {
  148 + logoPic.value = '';
  149 + loading.value = true;
141 150 const formData = new FormData();
142 151 formData.append('file', file);
143 152 const response = await logoUpload(formData);
144 153 if (response.fileStaticUri) {
145 154 logoPic.value = response.fileStaticUri;
  155 + loading.value = false;
146 156 }
147 157 }
148 158 }
... ... @@ -160,11 +170,14 @@
160 170 // Icon上传
161 171 async function customUploadIconPic({ file }) {
162 172 if (beforeUploadIconPic(file)) {
  173 + iconPic.value = '';
  174 + loading1.value = true;
163 175 const formData = new FormData();
164 176 formData.append('file', file);
165 177 const response = await iconUpload(formData);
166 178 if (response.fileStaticUri) {
167 179 iconPic.value = response.fileStaticUri;
  180 + loading1.value = false;
168 181 }
169 182 }
170 183 }
... ... @@ -182,11 +195,14 @@
182 195 // 登录页背景上传
183 196 async function customUploadBgPic({ file }) {
184 197 if (beforeUploadBgPic(file)) {
  198 + bgPic.value = '';
  199 + loading2.value = true;
185 200 const formData = new FormData();
186 201 formData.append('file', file);
187 202 const response = await bgUpload(formData);
188 203 if (response.fileStaticUri) {
189 204 bgPic.value = response.fileStaticUri;
  205 + loading2.value = false;
190 206 }
191 207 }
192 208 }
... ... @@ -250,6 +266,9 @@
250 266 beforeUploadBgPic,
251 267 compState,
252 268 handleUpdateInfo,
  269 + loading,
  270 + loading1,
  271 + loading2,
253 272 };
254 273 },
255 274 });
... ...
... ... @@ -14,7 +14,8 @@
14 14 <img v-if="qrcodePic" :src="qrcodePic" alt="avatar" />
15 15 <div v-else>
16 16 <div style="margin-top: 1.875rem">
17   - <PlusOutlined style="font-size: 2.5rem" />
  17 + <LoadingOutlined v-if="loading" />
  18 + <PlusOutlined v-else style="font-size: 2.5rem" />
18 19 </div>
19 20 <div
20 21 class="ant-upload-text flex"
... ... @@ -47,7 +48,7 @@
47 48 import { useMessage } from '/@/hooks/web/useMessage';
48 49 import { useUserStore } from '/@/store/modules/user';
49 50 import { createLocalStorage } from '/@/utils/cache';
50   - import { PlusOutlined } from '@ant-design/icons-vue';
  51 + import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
51 52 import { qrcodeUpload } from '/@/api/oem/index';
52 53 import type { FileItem } from '/@/components/Upload/src/typing';
53 54 import type { CityItem, Code } from '../types';
... ... @@ -61,8 +62,10 @@
61 62 Upload,
62 63 PlusOutlined,
63 64 Authority,
  65 + LoadingOutlined,
64 66 },
65 67 setup() {
  68 + const loading = ref(false);
66 69 const compState = ref({
67 70 absolute: false,
68 71 loading: false,
... ... @@ -98,11 +101,14 @@
98 101 const customUploadqrcodePic = async ({ file }) => {
99 102 clearValidate('qrcode');
100 103 if (beforeUploadqrcodePic(file)) {
  104 + qrcodePic.value = '';
  105 + loading.value = true;
101 106 const formData = new FormData();
102 107 formData.append('file', file);
103 108 const response = await qrcodeUpload(formData);
104 109 if (response.fileStaticUri) {
105 110 qrcodePic.value = response.fileStaticUri;
  111 + loading.value = false;
106 112 }
107 113 }
108 114 };
... ... @@ -132,8 +138,10 @@
132 138 delete newFieldValue.nameCoun;
133 139 delete newFieldValue.nameTown;
134 140
  141 + console.log(newFieldValue.qrCode);
  142 + console.log(newFieldValue.codeTown);
135 143 // 表单校验
136   - const values = await validate([
  144 + let validateArray = [
137 145 'name',
138 146 'abbreviation',
139 147 'officialWebsite',
... ... @@ -144,9 +152,26 @@
144 152 'contacts',
145 153 'tel',
146 154 'id',
147   - newFieldValue.qrCode == undefined ? 'prov' : '',
148   - newFieldValue.codeTown == undefined ? 'qrcode' : '',
149   - ]);
  155 + ];
  156 + if (newFieldValue.qrCode == undefined) {
  157 + validateArray.push('qrcode');
  158 + } else {
  159 + const findExistIndex = validateArray.findIndex((o) => o == 'qrcode');
  160 + if (findExistIndex !== -1) {
  161 + validateArray.splice(findExistIndex, 1);
  162 + }
  163 + }
  164 + if (newFieldValue.codeTown == undefined) {
  165 + validateArray.push('prov');
  166 + console.log(validateArray);
  167 + } else {
  168 + const findExistIndex1 = validateArray.findIndex((o) => o == 'prov');
  169 + if (findExistIndex1 !== -1) {
  170 + validateArray.splice(findExistIndex1, 1);
  171 + }
  172 + clearValidate('prov');
  173 + }
  174 + const values = await validate(validateArray);
150 175 if (!values) return;
151 176 compState.value.loading = true;
152 177 await updateEnterPriseDetail(newFieldValue);
... ... @@ -332,6 +357,7 @@
332 357 customUploadqrcodePic,
333 358 beforeUploadqrcodePic,
334 359 registerCustomForm,
  360 + loading,
335 361 };
336 362 },
337 363 });
... ...
1 1 <template>
2   - <BasicDrawer v-bind="$attrs" @register="registerDrawer" title="登登出日志详情" width="40%">
  2 + <BasicDrawer v-bind="$attrs" @register="registerDrawer" title="登登出日志详情" width="40%">
3 3 <BasicForm @register="registerForm" />
4 4 </BasicDrawer>
5 5 </template>
... ...