Commit 2159c2e46ad62a42be17b3820b8a1a7f2f3d4f3b

Authored by xp.Huang
2 parents cc379604 7241f8e0

Merge branch 'dev-fix-ww' into 'main_dev'

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

See merge request yunteng/thingskit-front!589
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 27 LIMIT = 'limit',
28 28 AGG = 'agg',
29 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 43 export const organizationId = ref('');
32 44
33 45 // 表格配置
... ... @@ -47,7 +59,9 @@ export const columns: BasicColumn[] = [
47 59 dataIndex: 'dataType',
48 60 width: 120,
49 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 332 colProps: { span: 24 },
319 333 },
320 334 {
321   - field: 'dataType',
  335 + field: SchemaFiled.DATA_TYPE,
322 336 label: '数据类型',
323 337 required: true,
324 338 component: 'Select',
325 339 componentProps: ({ formActionType }) => {
326 340 const { updateSchema, setFieldsValue } = formActionType;
327 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 345 return {
332 346 options,
... ... @@ -405,7 +419,6 @@ export const formSchema: QFormSchema[] = [
405 419 { label: '自定义周期', value: QueryWay.TIME_PERIOD },
406 420 ],
407 421 onChange(value) {
408   - console.log(value);
409 422 value === QueryWay.LATEST
410 423 ? setFieldsValue({
411 424 [SchemaFiled.DATE_RANGE]: [],
... ... @@ -425,11 +438,6 @@ export const formSchema: QFormSchema[] = [
425 438 ifShow({ values }) {
426 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 441 componentProps({ formActionType }) {
434 442 const { setFieldsValue } = formActionType;
435 443 let dates: Moment[] = [];
... ... @@ -514,7 +522,10 @@ export const formSchema: QFormSchema[] = [
514 522 component: 'Select',
515 523 required: true,
516 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 530 componentProps({ formModel, formActionType }) {
520 531 const options =
... ...