Commit 7241f8e0ec7ab85d1a698e835e5f6de07bc5f4f8

Authored by ww
1 parent cc379604

perf: 优化报表导出,原始数据去除间隔时间选项

1 -<template>  
2 - <BasicDrawer  
3 - :maskClosable="true"  
4 - @close="handleClose"  
5 - destroyOnClose  
6 - v-bind="$attrs"  
7 - @register="registerDrawer"  
8 - showFooter  
9 - :title="getTitle"  
10 - width="30%"  
11 - @ok="handleSubmit"  
12 - >  
13 - <BasicForm @register="registerForm">  
14 - <template #devices="{ model, field }">  
15 - <p style="display: none">{{ field }}</p>  
16 - <p>{{ queryModeFunc(model['queryMode']) }}</p>  
17 - <p>{{ orgFunc(model['organizationId']) }}</p>  
18 - <p>{{ dataTypeFunc(model['dataType']) }}</p>  
19 - <Select  
20 - placeholder="请选择设备"  
21 - v-model:value="selectDevice"  
22 - style="width: 100%"  
23 - :options="selectOptions"  
24 - @change="handleDeviceChange"  
25 - @deselect="handleDeselect"  
26 - mode="multiple"  
27 - labelInValue  
28 - notFoundContent="请选择设备"  
29 - />  
30 - <div style="margin-top: 1.5vh"></div>  
31 - <template v-for="(item, index) in deviceList" :key="item.value">  
32 - <p style="display: none">{{ index }}</p>  
33 - <DeviceAttrCpns  
34 - :ref="bindDeviceRefObj.deviceAttrRef"  
35 - :value="item"  
36 - :orgId="organizationId || orgId"  
37 - />  
38 - </template>  
39 - </template>  
40 - </BasicForm>  
41 - </BasicDrawer>  
42 -</template>  
43 -<script lang="ts" setup>  
44 - import { ref, computed, unref, reactive, watch, Ref, nextTick } from 'vue';  
45 - import { BasicForm, useForm } from '/@/components/Form';  
46 - import { formSchema, organizationId } from './config.data';  
47 - import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';  
48 - import {  
49 - createOrEditReportManage,  
50 - putReportConfigManage,  
51 - reportEditDetailPage,  
52 - } from '/@/api/report/reportManager';  
53 - import { useMessage } from '/@/hooks/web/useMessage';  
54 - import moment from 'moment';  
55 - import { screenLinkPageByDeptIdGetDevice } from '/@/api/ruleengine/ruleengineApi';  
56 - import { Select } from 'ant-design-vue';  
57 - import DeviceAttrCpns from './cpns/DeviceAttrCpns.vue';  
58 - import { SchemaFiled } from './config.data';  
59 - import { QueryWay } from '../../device/localtion/cpns/TimePeriodForm/config';  
60 - import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config';  
61 -  
62 - type TDeviceList = {  
63 - key?: string;  
64 - value?: string;  
65 - label?: string;  
66 - attribute?: string;  
67 - device?: string;  
68 - name?: string;  
69 - attributes?: string | undefined;  
70 - deviceProfileId?: string;  
71 - id?: string;  
72 - };  
73 - type TSelectOption = {  
74 - value?: string;  
75 - label?: string;  
76 - deviceProfileId?: string;  
77 - id?: string;  
78 - };  
79 - const emit = defineEmits(['success', 'register']);  
80 - const bindDeviceRefObj = {  
81 - deviceAttrRef: ref([]),  
82 - };  
83 - const isUpdate = ref(true);  
84 - const editId = ref('');  
85 - const orgId = ref('');  
86 - const selectOptions: Ref<TSelectOption[]> = ref([]);  
87 - const selectDevice = ref([]);  
88 - const deviceList: Ref<TDeviceList[]> = ref([]);  
89 - const editDeviceList: Ref<TDeviceList[]> = ref([]);  
90 - let editResData: any = reactive({});  
91 - const editDeviceAttr: any = ref([]);  
92 - const orgFuncId = ref('');  
93 - const queryModeStr = ref('');  
94 - const dataTypeStr = ref(0);  
95 - const orgFunc = (e) => {  
96 - orgFuncId.value = e;  
97 - };  
98 - const queryModeFunc = (e) => {  
99 - queryModeStr.value = e;  
100 - };  
101 - const dataTypeFunc = (e) => {  
102 - dataTypeStr.value = e;  
103 - };  
104 - watch(  
105 - () => dataTypeStr.value,  
106 - (newValue) => {  
107 - if (newValue == 0) {  
108 - setFieldsValue({ limit: 100 });  
109 - } else {  
110 - }  
111 - }  
112 - );  
113 - watch(  
114 - () => queryModeStr.value,  
115 - (newValue: string) => {  
116 - if (newValue == 'latest') {  
117 - setFieldsValue({ startTs: 1000 });  
118 - setFieldsValue({ interval: 1000 });  
119 - } else {  
120 - }  
121 - }  
122 - );  
123 - watch(  
124 - () => orgFuncId.value,  
125 - async (newValue: string) => {  
126 - if (newValue) {  
127 - //获取设备  
128 - const { items } = await screenLinkPageByDeptIdGetDevice({  
129 - organizationId: newValue,  
130 - });  
131 - selectOptions.value = items.map((item) => {  
132 - if (item.deviceType !== 'GATEWAY')  
133 - return {  
134 - label: item.alias ? item.alias : item.name,  
135 - value: item.tbDeviceId,  
136 - id: item.id,  
137 - deviceProfileId: item.deviceProfileId,  
138 - };  
139 - });  
140 - }  
141 - }  
142 - );  
143 - //设备Select选中  
144 - const handleDeviceChange = (_, o) => {  
145 - if (unref(isUpdate)) {  
146 - //编辑  
147 - let temp: any = [];  
148 - editDeviceAttr.value.forEach((f) => {  
149 - temp = [f, ...o];  
150 - });  
151 - let deWeightThree = () => {  
152 - let map = new Map();  
153 - for (let item of deviceList.value) {  
154 - if (!map.has(item.value)) {  
155 - map.set(item.value, item);  
156 - }  
157 - }  
158 - return [...map.values()];  
159 - };  
160 - temp = deWeightThree();  
161 - deviceList.value = temp;  
162 - if (o.length !== 0) {  
163 - deviceList.value = o;  
164 - }  
165 - } else {  
166 - deviceList.value = o;  
167 - }  
168 - };  
169 - //设备取消删除  
170 - const handleDeselect = (e) => {  
171 - if (unref(isUpdate)) {  
172 - //编辑  
173 - let deWeightThree = () => {  
174 - let map = new Map();  
175 - for (let item of deviceList.value) {  
176 - if (!map.has(item.value)) {  
177 - map.set(item.value, item);  
178 - }  
179 - }  
180 - return [...map.values()];  
181 - };  
182 - deviceList.value = deWeightThree();  
183 - const findEditValue = deviceList.value.findIndex((f) => f.value == e.value);  
184 - if (findEditValue !== -1) deviceList.value.splice(findEditValue, 1);  
185 - } else {  
186 - const eDevice = e.key || e.value;  
187 - const findValue = deviceList.value.findIndex((f) => f.value == eDevice);  
188 - if (findValue !== -1) deviceList.value.splice(findValue, 1);  
189 - }  
190 - };  
191 - const [registerForm, { validate, setFieldsValue, resetFields, updateSchema, getFieldsValue }] =  
192 - useForm({  
193 - labelWidth: 120,  
194 - schemas: formSchema,  
195 - showActionButtonGroup: false,  
196 - fieldMapToTime: [[SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS]]],  
197 - });  
198 - const isViewDetail = ref(false);  
199 -  
200 - const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {  
201 - await nextTick();  
202 - await resetFields();  
203 - setDrawerProps({ confirmLoading: false });  
204 - isUpdate.value = !!data?.isUpdate;  
205 - isViewDetail.value = !!data?.isView;  
206 - if (unref(isViewDetail)) {  
207 - setDrawerProps({ showFooter: true });  
208 - if (unref(isUpdate)) {  
209 - setDrawerProps({ title: '编辑报表配置' });  
210 - } else {  
211 - setDrawerProps({ title: '新增报表配置' });  
212 - }  
213 - } else {  
214 - setDrawerProps({ showFooter: false });  
215 - setDrawerProps({ title: '查看报表配置' });  
216 - }  
217 - if (unref(isUpdate)) {  
218 - //编辑回显数据  
219 - editResData = await reportEditDetailPage(data.record.id);  
220 - //回显基础数据  
221 - editId.value = editResData.data.id;  
222 - const spanDisance = editResData.data.executeContent?.split(' ');  
223 - await setFieldsValue(editResData.data);  
224 - //回显嵌套数据  
225 - await setFieldsValue({  
226 - dateGroupGap:  
227 - editResData.data.queryCondition?.queryMode === 1  
228 - ? editResData.data.queryCondition?.interval  
229 - : null,  
230 - agg: editResData.data.queryCondition?.agg,  
231 - interval: editResData.data.queryCondition?.interval,  
232 - limit: editResData.data.queryCondition?.limit,  
233 - orderBy: editResData.data.queryCondition?.orderBy,  
234 - useStrictDataTypes: editResData.data.queryCondition?.useStrictDataTypes,  
235 - startTs: editResData.data.queryCondition?.startTs,  
236 - endTs: editResData.data.queryCondition?.endTs,  
237 - way: editResData.data?.way,  
238 - queryMode: editResData.data.queryCondition?.queryMode === 0 ? 'latest' : 'timePeriod',  
239 - cronTime:  
240 - editResData.data?.cycle?.cycleType === 2  
241 - ? spanDisance[2] < 10  
242 - ? editResData.data.executeContent.slice(0, 7) + '* * ?'  
243 - : editResData.data.executeContent.slice(0, 7) + ' ' + '* * ?'  
244 - : editResData.data?.cycle?.cycleType === 1  
245 - ? spanDisance[2] < 10  
246 - ? editResData.data.executeContent.slice(0, 5) + ' ' + ' * * ?'  
247 - : editResData.data.executeContent.slice(0, 6) + ' ' + ' * * ?'  
248 - : editResData.data.executeContent,  
249 - currentCycle: editResData.data?.cycle?.currentCycle,  
250 - cycleTime: editResData.data?.cycle?.cycleTime,  
251 - cycleType: editResData.data?.cycle?.cycleType,  
252 - });  
253 - const endTsTime = editResData.data.queryCondition?.endTs;  
254 - const startTsTime = editResData.data.queryCondition?.startTs;  
255 - const mathFloor = (endTsTime - startTsTime) / 10;  
256 - const multTen = Math.floor(mathFloor) * 10;  
257 - await setFieldsValue({  
258 - startTs: multTen,  
259 - });  
260 - if (editResData.data.queryCondition?.queryMode == 1) {  
261 - await setFieldsValue({  
262 - dataRange: [  
263 - editResData.data.queryCondition?.startTs,  
264 - editResData.data.queryCondition?.endTs,  
265 - ],  
266 - });  
267 - }  
268 - //回显聚合条件  
269 - const dataCompareOpions = [  
270 - { label: '最小值', value: AggregateDataEnum.MIN },  
271 - { label: '最大值', value: AggregateDataEnum.MAX },  
272 - { label: '平均值', value: AggregateDataEnum.AVG },  
273 - { label: '求和', value: AggregateDataEnum.SUM },  
274 - { label: '计数', value: AggregateDataEnum.COUNT },  
275 - { label: '空', value: AggregateDataEnum.NONE },  
276 - ];  
277 - const updateSchemaAgg = (options: {}) => {  
278 - updateSchema({  
279 - field: SchemaFiled.AGG,  
280 - componentProps: {  
281 - options,  
282 - },  
283 - });  
284 - };  
285 - if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 5));  
286 - else updateSchemaAgg(dataCompareOpions.slice(5, 6));  
287 - //回显执行方式和查询周期  
288 - const dataQueryOpions = [  
289 - { label: '固定周期', value: QueryWay.LATEST },  
290 - { label: '自定义周期', value: QueryWay.TIME_PERIOD },  
291 - ];  
292 - const updateSchemaQuery = (options: {}) => {  
293 - updateSchema({  
294 - field: SchemaFiled.WAY,  
295 - componentProps: {  
296 - options,  
297 - },  
298 - });  
299 - };  
300 - if (editResData.data.executeWay == 0) updateSchemaQuery(dataQueryOpions);  
301 - else updateSchemaQuery(dataQueryOpions.slice(0, 1));  
302 - //回显设备  
303 - orgId.value = editResData.data.organizationId;  
304 - const { items } = await screenLinkPageByDeptIdGetDevice({  
305 - organizationId: editResData.data.organizationId,  
306 - });  
307 - selectOptions.value = items.map((item) => {  
308 - if (item.deviceType !== 'GATEWAY')  
309 - return {  
310 - label: item.alias ? item.alias : item.name,  
311 - value: item.tbDeviceId,  
312 - id: item.id,  
313 - deviceProfileId: item.deviceProfileId,  
314 - };  
315 - });  
316 - const deviceIds = editResData.data.executeAttributes.map((m) => {  
317 - return {  
318 - label: m.name,  
319 - key: m.device,  
320 - };  
321 - });  
322 - selectDevice.value = deviceIds;  
323 - //回显设备属性  
324 - editDeviceAttr.value = editResData.data.executeAttributes?.map((item) => {  
325 - const T = selectOptions.value.find((o) => {  
326 - if (item.device === o.value) {  
327 - return {  
328 - id: o.id,  
329 - deviceProfileId: o.deviceProfileId,  
330 - };  
331 - }  
332 - });  
333 - return {  
334 - ...T,  
335 - label: item.alias ? item.alias : item.name,  
336 - value: item.device,  
337 - attributes: item.attributes,  
338 - };  
339 - });  
340 - deviceList.value = editDeviceAttr.value;  
341 - editDeviceList.value = editResData.data.executeAttributes;  
342 - } else {  
343 - setFieldsValue({  
344 - startTs: 1000,  
345 - interval: 1000,  
346 - });  
347 - editId.value = '';  
348 - orgId.value = '';  
349 - selectDevice.value = [];  
350 - selectOptions.value = [];  
351 - deviceList.value = [];  
352 - getAttrDevice.value = [];  
353 - editDeviceList.value = [];  
354 - editDeviceAttr.value = [];  
355 - updateSchema({  
356 - field: SchemaFiled.AGG,  
357 - componentProps: {  
358 - options: [],  
359 - },  
360 - });  
361 - //新增显示执行方式和查询周期  
362 - const dataQueryOpions = [  
363 - { label: '固定周期', value: QueryWay.LATEST },  
364 - { label: '自定义周期', value: QueryWay.TIME_PERIOD },  
365 - ];  
366 - const updateSchemaQuery = (options: {}) => {  
367 - updateSchema({  
368 - field: SchemaFiled.WAY,  
369 - componentProps: {  
370 - options,  
371 - },  
372 - });  
373 - };  
374 - if (getFieldsValue().executeWay == 0) updateSchemaQuery(dataQueryOpions);  
375 - }  
376 - });  
377 - const handleClose = () => {  
378 - deviceList.value = [];  
379 - editId.value = '';  
380 - orgId.value = '';  
381 - selectDevice.value = [];  
382 - selectOptions.value = [];  
383 - getAttrDevice.value = [];  
384 - editDeviceList.value = [];  
385 - editDeviceAttr.value = [];  
386 - };  
387 - const getAttrDevice: Ref<TDeviceList[]> = ref([]);  
388 - const getTitle = computed(() => (!unref(isUpdate) ? '新增报表配置' : '编辑报表配置'));  
389 - let postObj: any = reactive({});  
390 - let queryCondition: any = reactive({});  
391 - let executeContent: any = reactive({});  
392 - const startTs = ref(0);  
393 - const endTs = ref(0);  
394 -  
395 - const getFormValueFunc = () => {  
396 - const item: any = unref(bindDeviceRefObj.deviceAttrRef)?.map((item: any) => item.emitChange());  
397 - getAttrDevice.value = item;  
398 - };  
399 -  
400 - async function handleSubmit() {  
401 - setDrawerProps({ confirmLoading: true });  
402 - try {  
403 - const { createMessage } = useMessage();  
404 - const values = await validate();  
405 - if (!values) return;  
406 - getFormValueFunc();  
407 - let hasAttr = false;  
408 - if (!unref(isUpdate)) {  
409 - if (getAttrDevice.value.length === 0) {  
410 - return createMessage.error('请选择设备及其属性');  
411 - } else {  
412 - getAttrDevice.value.forEach((f: any) => {  
413 - if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;  
414 - });  
415 - }  
416 - } else {  
417 - if (getAttrDevice.value.length === 0) {  
418 - return createMessage.error('请选择设备及其属性');  
419 - } else {  
420 - getAttrDevice.value.forEach((f: any) => {  
421 - if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;  
422 - });  
423 - }  
424 - }  
425 - if (hasAttr) return createMessage.error('请选择设备属性');  
426 - if (values.executeWay == 0) {  
427 - executeContent = null;  
428 - } else {  
429 - //拼接corn  
430 - let joinCorn = '';  
431 - if (values.cycleType === 1) {  
432 - joinCorn = values.cronTime.slice(0, 6) + values.currentCycle.slice(5);  
433 - executeContent = joinCorn;  
434 - } else if (values.cycleType === 0) {  
435 - executeContent = values.cronTime;  
436 - } else if (values.cycleType === 2) {  
437 - joinCorn = values.cronTime.slice(0, 6) + values.cycleTime.slice(5);  
438 - executeContent = joinCorn;  
439 - }  
440 - }  
441 - if (values.queryMode === QueryWay.LATEST) {  
442 - startTs.value = moment().subtract(values.startTs, 'ms').valueOf();  
443 - endTs.value = Date.now();  
444 - } else {  
445 - const fT = JSON.parse(JSON.stringify(values.dataRange));  
446 - startTs.value = moment(fT[0]).valueOf();  
447 - endTs.value = moment(fT[1]).valueOf();  
448 - }  
449 - queryCondition = {  
450 - agg: values.agg,  
451 - interval: values?.queryMode === 'latest' ? values.interval : values.dateGroupGap,  
452 - limit: values.limit,  
453 - ...{  
454 - startTs: startTs.value,  
455 - },  
456 - ...{  
457 - endTs: endTs.value,  
458 - },  
459 - queryMode: values?.queryMode === 'latest' ? 0 : 1,  
460 - };  
461 - const cycle: any = {};  
462 - if (values.cycleType === 0) {  
463 - cycle.cycleType = values.cycleType;  
464 - cycle.cronTime = values.cronTime;  
465 - }  
466 - if (values.cycleType === 1) {  
467 - cycle.cycleType = values.cycleType;  
468 - cycle.currentCycle = values.currentCycle;  
469 - cycle.cronTime = values.cronTime;  
470 - }  
471 - if (values.cycleType === 2) {  
472 - cycle.cycleType = values.cycleType;  
473 - cycle.cycleTime = values.cycleTime;  
474 - cycle.cronTime = values.cronTime;  
475 - }  
476 - // const cycle = {  
477 - // currentCycle: values.currentCycle,  
478 - // cycleTime: values.cycleTime,  
479 - // cronTime: values.cronTime,  
480 - // cycleType: values.cycleType,  
481 - // };  
482 - delete values.devices;  
483 - delete values.agg;  
484 - delete values.interval;  
485 - delete values.timeZone;  
486 - delete values.cronTime;  
487 - delete values.currentCycle;  
488 - delete values.cycleTime;  
489 - delete values.limit1;  
490 - delete values.startTs;  
491 - delete values.queryMode;  
492 - delete values.cycleType;  
493 - postObj = {  
494 - ...values,  
495 - ...{  
496 - executeAttributes:  
497 - getAttrDevice.value.length == 0 ? editDeviceList.value : getAttrDevice.value,  
498 - },  
499 - ...{ queryCondition },  
500 - ...{ cycle },  
501 - ...{ executeContent },  
502 - ...{ id: editId.value !== '' ? editId.value : '' },  
503 - };  
504 - let saveMessage = '添加成功';  
505 - let updateMessage = '修改成功';  
506 - editId.value !== ''  
507 - ? await putReportConfigManage(postObj)  
508 - : await createOrEditReportManage(postObj);  
509 -  
510 - closeDrawer();  
511 - emit('success');  
512 - createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);  
513 - handleClose();  
514 - } finally {  
515 - setTimeout(() => {  
516 - setDrawerProps({ confirmLoading: false });  
517 - }, 300);  
518 - }  
519 - }  
520 -</script> 1 +<template>
  2 + <BasicDrawer
  3 + :maskClosable="true"
  4 + @close="handleClose"
  5 + destroyOnClose
  6 + v-bind="$attrs"
  7 + @register="registerDrawer"
  8 + showFooter
  9 + :title="getTitle"
  10 + width="30%"
  11 + @ok="handleSubmit"
  12 + >
  13 + <BasicForm @register="registerForm">
  14 + <template #devices="{ model, field }">
  15 + <p style="display: none">{{ field }}</p>
  16 + <p>{{ queryModeFunc(model['queryMode']) }}</p>
  17 + <p>{{ orgFunc(model['organizationId']) }}</p>
  18 + <p>{{ dataTypeFunc(model['dataType']) }}</p>
  19 + <Select
  20 + placeholder="请选择设备"
  21 + v-model:value="selectDevice"
  22 + style="width: 100%"
  23 + :options="selectOptions"
  24 + @change="handleDeviceChange"
  25 + @deselect="handleDeselect"
  26 + mode="multiple"
  27 + labelInValue
  28 + notFoundContent="请选择设备"
  29 + />
  30 + <div style="margin-top: 1.5vh"></div>
  31 + <template v-for="(item, index) in deviceList" :key="item.value">
  32 + <p style="display: none">{{ index }}</p>
  33 + <DeviceAttrCpns
  34 + :ref="bindDeviceRefObj.deviceAttrRef"
  35 + :value="item"
  36 + :orgId="organizationId || orgId"
  37 + />
  38 + </template>
  39 + </template>
  40 + </BasicForm>
  41 + </BasicDrawer>
  42 +</template>
  43 +<script lang="ts" setup>
  44 + import { ref, computed, unref, reactive, watch, Ref, nextTick } from 'vue';
  45 + import { BasicForm, useForm } from '/@/components/Form';
  46 + import { DataTypeEnum, formSchema, organizationId } from './config.data';
  47 + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  48 + import {
  49 + createOrEditReportManage,
  50 + putReportConfigManage,
  51 + reportEditDetailPage,
  52 + } from '/@/api/report/reportManager';
  53 + import { useMessage } from '/@/hooks/web/useMessage';
  54 + import moment from 'moment';
  55 + import { screenLinkPageByDeptIdGetDevice } from '/@/api/ruleengine/ruleengineApi';
  56 + import { Select } from 'ant-design-vue';
  57 + import DeviceAttrCpns from './cpns/DeviceAttrCpns.vue';
  58 + import { SchemaFiled } from './config.data';
  59 + import { QueryWay } from '../../device/localtion/cpns/TimePeriodForm/config';
  60 + import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config';
  61 +
  62 + type TDeviceList = {
  63 + key?: string;
  64 + value?: string;
  65 + label?: string;
  66 + attribute?: string;
  67 + device?: string;
  68 + name?: string;
  69 + attributes?: string | undefined;
  70 + deviceProfileId?: string;
  71 + id?: string;
  72 + };
  73 + type TSelectOption = {
  74 + value?: string;
  75 + label?: string;
  76 + deviceProfileId?: string;
  77 + id?: string;
  78 + };
  79 + const emit = defineEmits(['success', 'register']);
  80 + const bindDeviceRefObj = {
  81 + deviceAttrRef: ref([]),
  82 + };
  83 + const isUpdate = ref(true);
  84 + const editId = ref('');
  85 + const orgId = ref('');
  86 + const selectOptions: Ref<TSelectOption[]> = ref([]);
  87 + const selectDevice = ref([]);
  88 + const deviceList: Ref<TDeviceList[]> = ref([]);
  89 + const editDeviceList: Ref<TDeviceList[]> = ref([]);
  90 + let editResData: any = reactive({});
  91 + const editDeviceAttr: any = ref([]);
  92 + const orgFuncId = ref('');
  93 + const queryModeStr = ref('');
  94 + const dataTypeStr = ref(0);
  95 + const orgFunc = (e) => {
  96 + orgFuncId.value = e;
  97 + };
  98 + const queryModeFunc = (e) => {
  99 + queryModeStr.value = e;
  100 + };
  101 + const dataTypeFunc = (e) => {
  102 + dataTypeStr.value = e;
  103 + };
  104 + watch(
  105 + () => dataTypeStr.value,
  106 + (newValue) => {
  107 + if (newValue == 0) {
  108 + setFieldsValue({ limit: 100 });
  109 + } else {
  110 + }
  111 + }
  112 + );
  113 + watch(
  114 + () => queryModeStr.value,
  115 + (newValue: string) => {
  116 + if (newValue == 'latest') {
  117 + setFieldsValue({ startTs: 1000 });
  118 + setFieldsValue({ interval: 1000 });
  119 + } else {
  120 + }
  121 + }
  122 + );
  123 + watch(
  124 + () => orgFuncId.value,
  125 + async (newValue: string) => {
  126 + if (newValue) {
  127 + //获取设备
  128 + const { items } = await screenLinkPageByDeptIdGetDevice({
  129 + organizationId: newValue,
  130 + });
  131 + selectOptions.value = items.map((item) => {
  132 + if (item.deviceType !== 'GATEWAY')
  133 + return {
  134 + label: item.alias ? item.alias : item.name,
  135 + value: item.tbDeviceId,
  136 + id: item.id,
  137 + deviceProfileId: item.deviceProfileId,
  138 + };
  139 + });
  140 + }
  141 + }
  142 + );
  143 + //设备Select选中
  144 + const handleDeviceChange = (_, o) => {
  145 + if (unref(isUpdate)) {
  146 + //编辑
  147 + let temp: any = [];
  148 + editDeviceAttr.value.forEach((f) => {
  149 + temp = [f, ...o];
  150 + });
  151 + let deWeightThree = () => {
  152 + let map = new Map();
  153 + for (let item of deviceList.value) {
  154 + if (!map.has(item.value)) {
  155 + map.set(item.value, item);
  156 + }
  157 + }
  158 + return [...map.values()];
  159 + };
  160 + temp = deWeightThree();
  161 + deviceList.value = temp;
  162 + if (o.length !== 0) {
  163 + deviceList.value = o;
  164 + }
  165 + } else {
  166 + deviceList.value = o;
  167 + }
  168 + };
  169 + //设备取消删除
  170 + const handleDeselect = (e) => {
  171 + if (unref(isUpdate)) {
  172 + //编辑
  173 + let deWeightThree = () => {
  174 + let map = new Map();
  175 + for (let item of deviceList.value) {
  176 + if (!map.has(item.value)) {
  177 + map.set(item.value, item);
  178 + }
  179 + }
  180 + return [...map.values()];
  181 + };
  182 + deviceList.value = deWeightThree();
  183 + const findEditValue = deviceList.value.findIndex((f) => f.value == e.value);
  184 + if (findEditValue !== -1) deviceList.value.splice(findEditValue, 1);
  185 + } else {
  186 + const eDevice = e.key || e.value;
  187 + const findValue = deviceList.value.findIndex((f) => f.value == eDevice);
  188 + if (findValue !== -1) deviceList.value.splice(findValue, 1);
  189 + }
  190 + };
  191 + const [registerForm, { validate, setFieldsValue, resetFields, updateSchema, getFieldsValue }] =
  192 + useForm({
  193 + labelWidth: 120,
  194 + schemas: formSchema,
  195 + showActionButtonGroup: false,
  196 + fieldMapToTime: [[SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS]]],
  197 + });
  198 + const isViewDetail = ref(false);
  199 +
  200 + const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
  201 + await nextTick();
  202 + await resetFields();
  203 + setDrawerProps({ confirmLoading: false });
  204 + isUpdate.value = !!data?.isUpdate;
  205 + isViewDetail.value = !!data?.isView;
  206 + if (unref(isViewDetail)) {
  207 + setDrawerProps({ showFooter: true });
  208 + if (unref(isUpdate)) {
  209 + setDrawerProps({ title: '编辑报表配置' });
  210 + } else {
  211 + setDrawerProps({ title: '新增报表配置' });
  212 + }
  213 + } else {
  214 + setDrawerProps({ showFooter: false });
  215 + setDrawerProps({ title: '查看报表配置' });
  216 + }
  217 + if (unref(isUpdate)) {
  218 + //编辑回显数据
  219 + editResData = await reportEditDetailPage(data.record.id);
  220 + //回显基础数据
  221 + editId.value = editResData.data.id;
  222 + const spanDisance = editResData.data.executeContent?.split(' ');
  223 + await setFieldsValue(editResData.data);
  224 + //回显嵌套数据
  225 + await setFieldsValue({
  226 + dateGroupGap:
  227 + editResData.data.queryCondition?.queryMode === 1
  228 + ? editResData.data.queryCondition?.interval
  229 + : null,
  230 + agg: editResData.data.queryCondition?.agg,
  231 + interval: editResData.data.queryCondition?.interval,
  232 + limit: editResData.data.queryCondition?.limit,
  233 + orderBy: editResData.data.queryCondition?.orderBy,
  234 + useStrictDataTypes: editResData.data.queryCondition?.useStrictDataTypes,
  235 + startTs: editResData.data.queryCondition?.startTs,
  236 + endTs: editResData.data.queryCondition?.endTs,
  237 + way: editResData.data?.way,
  238 + queryMode: editResData.data.queryCondition?.queryMode === 0 ? 'latest' : 'timePeriod',
  239 + cronTime:
  240 + editResData.data?.cycle?.cycleType === 2
  241 + ? spanDisance[2] < 10
  242 + ? editResData.data.executeContent.slice(0, 7) + '* * ?'
  243 + : editResData.data.executeContent.slice(0, 7) + ' ' + '* * ?'
  244 + : editResData.data?.cycle?.cycleType === 1
  245 + ? spanDisance[2] < 10
  246 + ? editResData.data.executeContent.slice(0, 5) + ' ' + ' * * ?'
  247 + : editResData.data.executeContent.slice(0, 6) + ' ' + ' * * ?'
  248 + : editResData.data.executeContent,
  249 + currentCycle: editResData.data?.cycle?.currentCycle,
  250 + cycleTime: editResData.data?.cycle?.cycleTime,
  251 + cycleType: editResData.data?.cycle?.cycleType,
  252 + });
  253 + const endTsTime = editResData.data.queryCondition?.endTs;
  254 + const startTsTime = editResData.data.queryCondition?.startTs;
  255 + const mathFloor = (endTsTime - startTsTime) / 10;
  256 + const multTen = Math.floor(mathFloor) * 10;
  257 + await setFieldsValue({
  258 + startTs: multTen,
  259 + });
  260 + if (editResData.data.queryCondition?.queryMode == 1) {
  261 + await setFieldsValue({
  262 + dataRange: [
  263 + editResData.data.queryCondition?.startTs,
  264 + editResData.data.queryCondition?.endTs,
  265 + ],
  266 + });
  267 + }
  268 + //回显聚合条件
  269 + const dataCompareOpions = [
  270 + { label: '最小值', value: AggregateDataEnum.MIN },
  271 + { label: '最大值', value: AggregateDataEnum.MAX },
  272 + { label: '平均值', value: AggregateDataEnum.AVG },
  273 + { label: '求和', value: AggregateDataEnum.SUM },
  274 + { label: '计数', value: AggregateDataEnum.COUNT },
  275 + { label: '空', value: AggregateDataEnum.NONE },
  276 + ];
  277 + const updateSchemaAgg = (options: {}) => {
  278 + updateSchema({
  279 + field: SchemaFiled.AGG,
  280 + componentProps: {
  281 + options,
  282 + },
  283 + });
  284 + };
  285 + if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 5));
  286 + else updateSchemaAgg(dataCompareOpions.slice(5, 6));
  287 + //回显执行方式和查询周期
  288 + const dataQueryOpions = [
  289 + { label: '固定周期', value: QueryWay.LATEST },
  290 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  291 + ];
  292 + const updateSchemaQuery = (options: {}) => {
  293 + updateSchema({
  294 + field: SchemaFiled.WAY,
  295 + componentProps: {
  296 + options,
  297 + },
  298 + });
  299 + };
  300 + if (editResData.data.executeWay == 0) updateSchemaQuery(dataQueryOpions);
  301 + else updateSchemaQuery(dataQueryOpions.slice(0, 1));
  302 + //回显设备
  303 + orgId.value = editResData.data.organizationId;
  304 + const { items } = await screenLinkPageByDeptIdGetDevice({
  305 + organizationId: editResData.data.organizationId,
  306 + });
  307 + selectOptions.value = items.map((item) => {
  308 + if (item.deviceType !== 'GATEWAY')
  309 + return {
  310 + label: item.alias ? item.alias : item.name,
  311 + value: item.tbDeviceId,
  312 + id: item.id,
  313 + deviceProfileId: item.deviceProfileId,
  314 + };
  315 + });
  316 + const deviceIds = editResData.data.executeAttributes.map((m) => {
  317 + return {
  318 + label: m.name,
  319 + key: m.device,
  320 + };
  321 + });
  322 + selectDevice.value = deviceIds;
  323 + //回显设备属性
  324 + editDeviceAttr.value = editResData.data.executeAttributes?.map((item) => {
  325 + const T = selectOptions.value.find((o) => {
  326 + if (item.device === o.value) {
  327 + return {
  328 + id: o.id,
  329 + deviceProfileId: o.deviceProfileId,
  330 + };
  331 + }
  332 + });
  333 + return {
  334 + ...T,
  335 + label: item.alias ? item.alias : item.name,
  336 + value: item.device,
  337 + attributes: item.attributes,
  338 + };
  339 + });
  340 + deviceList.value = editDeviceAttr.value;
  341 + editDeviceList.value = editResData.data.executeAttributes;
  342 + } else {
  343 + setFieldsValue({
  344 + startTs: 1000,
  345 + interval: 1000,
  346 + });
  347 + editId.value = '';
  348 + orgId.value = '';
  349 + selectDevice.value = [];
  350 + selectOptions.value = [];
  351 + deviceList.value = [];
  352 + getAttrDevice.value = [];
  353 + editDeviceList.value = [];
  354 + editDeviceAttr.value = [];
  355 + updateSchema({
  356 + field: SchemaFiled.AGG,
  357 + componentProps: {
  358 + options: [],
  359 + },
  360 + });
  361 + //新增显示执行方式和查询周期
  362 + const dataQueryOpions = [
  363 + { label: '固定周期', value: QueryWay.LATEST },
  364 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  365 + ];
  366 + const updateSchemaQuery = (options: {}) => {
  367 + updateSchema({
  368 + field: SchemaFiled.WAY,
  369 + componentProps: {
  370 + options,
  371 + },
  372 + });
  373 + };
  374 + if (getFieldsValue().executeWay == 0) updateSchemaQuery(dataQueryOpions);
  375 + }
  376 + });
  377 + const handleClose = () => {
  378 + deviceList.value = [];
  379 + editId.value = '';
  380 + orgId.value = '';
  381 + selectDevice.value = [];
  382 + selectOptions.value = [];
  383 + getAttrDevice.value = [];
  384 + editDeviceList.value = [];
  385 + editDeviceAttr.value = [];
  386 + };
  387 + const getAttrDevice: Ref<TDeviceList[]> = ref([]);
  388 + const getTitle = computed(() => (!unref(isUpdate) ? '新增报表配置' : '编辑报表配置'));
  389 + let postObj: any = reactive({});
  390 + let queryCondition: any = reactive({});
  391 + let executeContent: any = reactive({});
  392 + const startTs = ref(0);
  393 + const endTs = ref(0);
  394 +
  395 + const getFormValueFunc = () => {
  396 + const item: any = unref(bindDeviceRefObj.deviceAttrRef)?.map((item: any) => item.emitChange());
  397 + getAttrDevice.value = item;
  398 + };
  399 +
  400 + async function handleSubmit() {
  401 + setDrawerProps({ confirmLoading: true });
  402 + try {
  403 + const { createMessage } = useMessage();
  404 + const values = await validate();
  405 + if (!values) return;
  406 + getFormValueFunc();
  407 + let hasAttr = false;
  408 + if (!unref(isUpdate)) {
  409 + if (getAttrDevice.value.length === 0) {
  410 + return createMessage.error('请选择设备及其属性');
  411 + } else {
  412 + getAttrDevice.value.forEach((f: any) => {
  413 + if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
  414 + });
  415 + }
  416 + } else {
  417 + if (getAttrDevice.value.length === 0) {
  418 + return createMessage.error('请选择设备及其属性');
  419 + } else {
  420 + getAttrDevice.value.forEach((f: any) => {
  421 + if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
  422 + });
  423 + }
  424 + }
  425 + if (hasAttr) return createMessage.error('请选择设备属性');
  426 + if (values.executeWay == 0) {
  427 + executeContent = null;
  428 + } else {
  429 + //拼接corn
  430 + let joinCorn = '';
  431 + if (values.cycleType === 1) {
  432 + joinCorn = values.cronTime.slice(0, 6) + values.currentCycle.slice(5);
  433 + executeContent = joinCorn;
  434 + } else if (values.cycleType === 0) {
  435 + executeContent = values.cronTime;
  436 + } else if (values.cycleType === 2) {
  437 + joinCorn = values.cronTime.slice(0, 6) + values.cycleTime.slice(5);
  438 + executeContent = joinCorn;
  439 + }
  440 + }
  441 + if (values.queryMode === QueryWay.LATEST) {
  442 + startTs.value = moment().subtract(values.startTs, 'ms').valueOf();
  443 + endTs.value = Date.now();
  444 + } else {
  445 + const fT = JSON.parse(JSON.stringify(values.dataRange));
  446 + startTs.value = moment(fT[0]).valueOf();
  447 + endTs.value = moment(fT[1]).valueOf();
  448 + }
  449 + queryCondition = {
  450 + agg: values.agg,
  451 + ...(values?.queryMode === QueryWay.LATEST && values?.dataType != DataTypeEnum.ORIGINAL
  452 + ? { interval: values?.queryMode === 'latest' ? values.interval : values.dateGroupGap }
  453 + : {}),
  454 + limit: values.limit,
  455 + ...{
  456 + startTs: startTs.value,
  457 + },
  458 + ...{
  459 + endTs: endTs.value,
  460 + },
  461 + queryMode: values?.queryMode === 'latest' ? 0 : 1,
  462 + };
  463 + const cycle: any = {};
  464 + if (values.cycleType === 0) {
  465 + cycle.cycleType = values.cycleType;
  466 + cycle.cronTime = values.cronTime;
  467 + }
  468 + if (values.cycleType === 1) {
  469 + cycle.cycleType = values.cycleType;
  470 + cycle.currentCycle = values.currentCycle;
  471 + cycle.cronTime = values.cronTime;
  472 + }
  473 + if (values.cycleType === 2) {
  474 + cycle.cycleType = values.cycleType;
  475 + cycle.cycleTime = values.cycleTime;
  476 + cycle.cronTime = values.cronTime;
  477 + }
  478 + // const cycle = {
  479 + // currentCycle: values.currentCycle,
  480 + // cycleTime: values.cycleTime,
  481 + // cronTime: values.cronTime,
  482 + // cycleType: values.cycleType,
  483 + // };
  484 + delete values.devices;
  485 + delete values.agg;
  486 + delete values.interval;
  487 + delete values.timeZone;
  488 + delete values.cronTime;
  489 + delete values.currentCycle;
  490 + delete values.cycleTime;
  491 + delete values.limit1;
  492 + delete values.startTs;
  493 + delete values.queryMode;
  494 + delete values.cycleType;
  495 + postObj = {
  496 + ...values,
  497 + ...{
  498 + executeAttributes:
  499 + getAttrDevice.value.length == 0 ? editDeviceList.value : getAttrDevice.value,
  500 + },
  501 + ...{ queryCondition },
  502 + ...{ cycle },
  503 + ...{ executeContent },
  504 + ...{ id: editId.value !== '' ? editId.value : '' },
  505 + };
  506 + let saveMessage = '添加成功';
  507 + let updateMessage = '修改成功';
  508 + editId.value !== ''
  509 + ? await putReportConfigManage(postObj)
  510 + : await createOrEditReportManage(postObj);
  511 +
  512 + closeDrawer();
  513 + emit('success');
  514 + createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);
  515 + handleClose();
  516 + } finally {
  517 + setTimeout(() => {
  518 + setDrawerProps({ confirmLoading: false });
  519 + }, 300);
  520 + }
  521 + }
  522 +</script>
@@ -27,7 +27,19 @@ export enum SchemaFiled { @@ -27,7 +27,19 @@ export enum SchemaFiled {
27 LIMIT = 'limit', 27 LIMIT = 'limit',
28 AGG = 'agg', 28 AGG = 'agg',
29 ORDER_BY = 'orderBy', 29 ORDER_BY = 'orderBy',
  30 + DATA_TYPE = 'dataType',
30 } 31 }
  32 +
  33 +export enum DataTypeEnum {
  34 + ORIGINAL = 0,
  35 + AGG = 1,
  36 +}
  37 +
  38 +export enum DataTypeNameEnum {
  39 + ORIGINAL = '原始数据',
  40 + AGG = '聚合数据',
  41 +}
  42 +
31 export const organizationId = ref(''); 43 export const organizationId = ref('');
32 44
33 // 表格配置 45 // 表格配置
@@ -47,7 +59,9 @@ export const columns: BasicColumn[] = [ @@ -47,7 +59,9 @@ export const columns: BasicColumn[] = [
47 dataIndex: 'dataType', 59 dataIndex: 'dataType',
48 width: 120, 60 width: 120,
49 format: (_text: string, record: Recordable) => { 61 format: (_text: string, record: Recordable) => {
50 - return record.dataType === 0 ? '原始数据' : '聚合数据'; 62 + return record.dataType === DataTypeEnum.ORIGINAL
  63 + ? DataTypeNameEnum.ORIGINAL
  64 + : DataTypeNameEnum.AGG;
51 }, 65 },
52 }, 66 },
53 { 67 {
@@ -318,15 +332,15 @@ export const formSchema: QFormSchema[] = [ @@ -318,15 +332,15 @@ export const formSchema: QFormSchema[] = [
318 colProps: { span: 24 }, 332 colProps: { span: 24 },
319 }, 333 },
320 { 334 {
321 - field: 'dataType', 335 + field: SchemaFiled.DATA_TYPE,
322 label: '数据类型', 336 label: '数据类型',
323 required: true, 337 required: true,
324 component: 'Select', 338 component: 'Select',
325 componentProps: ({ formActionType }) => { 339 componentProps: ({ formActionType }) => {
326 const { updateSchema, setFieldsValue } = formActionType; 340 const { updateSchema, setFieldsValue } = formActionType;
327 const options = [ 341 const options = [
328 - { label: '原始数据', value: 0 },  
329 - { label: '聚合数据', value: 1 }, 342 + { label: DataTypeNameEnum.ORIGINAL, value: DataTypeEnum.ORIGINAL },
  343 + { label: DataTypeNameEnum.AGG, value: DataTypeEnum.AGG },
330 ]; 344 ];
331 return { 345 return {
332 options, 346 options,
@@ -405,7 +419,6 @@ export const formSchema: QFormSchema[] = [ @@ -405,7 +419,6 @@ export const formSchema: QFormSchema[] = [
405 { label: '自定义周期', value: QueryWay.TIME_PERIOD }, 419 { label: '自定义周期', value: QueryWay.TIME_PERIOD },
406 ], 420 ],
407 onChange(value) { 421 onChange(value) {
408 - console.log(value);  
409 value === QueryWay.LATEST 422 value === QueryWay.LATEST
410 ? setFieldsValue({ 423 ? setFieldsValue({
411 [SchemaFiled.DATE_RANGE]: [], 424 [SchemaFiled.DATE_RANGE]: [],
@@ -425,11 +438,6 @@ export const formSchema: QFormSchema[] = [ @@ -425,11 +438,6 @@ export const formSchema: QFormSchema[] = [
425 ifShow({ values }) { 438 ifShow({ values }) {
426 return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay); 439 return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay);
427 }, 440 },
428 - // componentProps: {  
429 - // showTime: {  
430 - // defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],  
431 - // },  
432 - // },  
433 componentProps({ formActionType }) { 441 componentProps({ formActionType }) {
434 const { setFieldsValue } = formActionType; 442 const { setFieldsValue } = formActionType;
435 let dates: Moment[] = []; 443 let dates: Moment[] = [];
@@ -514,7 +522,10 @@ export const formSchema: QFormSchema[] = [ @@ -514,7 +522,10 @@ export const formSchema: QFormSchema[] = [
514 component: 'Select', 522 component: 'Select',
515 required: true, 523 required: true,
516 ifShow({ values }) { 524 ifShow({ values }) {
517 - return values[SchemaFiled.WAY] == QueryWay.LATEST; 525 + return (
  526 + values[SchemaFiled.WAY] == QueryWay.LATEST &&
  527 + values[SchemaFiled.DATA_TYPE] !== DataTypeEnum.ORIGINAL
  528 + );
518 }, 529 },
519 componentProps({ formModel, formActionType }) { 530 componentProps({ formModel, formActionType }) {
520 const options = 531 const options =