Commit 7688959653aab9820613769926435ce87993bacd

Authored by xp.Huang
1 parent cea7fdf2

Merge branch 'ft' into 'main_dev'

fix: 修复Teambition上的问题

See merge request yunteng/thingskit-front!534

(cherry picked from commit 518484644c1ee2565e68856a0d7087323c033096)

8c3fb46a fix:DEFECT-1119...
a8dbbbd9 fix:DEFECT-1114 组态名称限制长度
b4c765f4 fix:DEFECT-1080 暗黑模式看板返回看不见
6011295a fix:DEFECT-1131 测试未输入ID时,提示错误,应提示未输入参数
7a7258d6 fix:DEFECT-1131 测试未输入ID时,提示错误,应提示未输入参数
1a7113e4 fix: 修复大屏公共接口管理操作权限问题
eaf22bd7 fix: DEFECT-1138 websocket接口还未选择产品,数据就测试出结果了
8637830f fix: DEFECT-1138 websocket接口还未选择产品,数据就测试出结果了
b3c40c28 fix: 修复报表配置corn表达式问题
1   -export enum VideoPlayerType {
2   - m3u8 = 'application/x-mpegURL',
3   - mp4 = 'video/mp4',
4   - webm = 'video/webm',
5   -}
6   -
7   -export const getVideoTypeByUrl = (url: string) => {
8   - const splitExtReg = /(?:.*)(?<=\.)/;
9   -
10   - const type = url.replace(splitExtReg, '');
11   -
12   - if (VideoPlayerType[type]) return VideoPlayerType[type];
13   -
14   - return VideoPlayerType.mp4;
15   -};
  1 +export enum VideoPlayerType {
  2 + m3u8 = 'application/x-mpegURL',
  3 + mp4 = 'video/mp4',
  4 + webm = 'video/webm',
  5 +}
  6 +
  7 +export const getVideoTypeByUrl = (url: string) => {
  8 + const splitExtReg = /(?:.*)(?<=\.)/;
  9 + const type = url.replace(splitExtReg, '');
  10 + /**
  11 + * https://vcsplay.scjtonline.cn:8200/live/HD_1569b634-4789-11eb-ab67-3cd2e55e0b20.m3u8?auth_key=1681179278-0-0-5c54a376f2ca32d05c4a152ee96336e9
  12 + * 如果是这种格式的m3u8,则截取的是这一部分.m3u8?auth_key=1681179278-0-0-5c54a376f2ca32d05c4a152ee96336e9
  13 + */
  14 + if (type.startsWith('m3u8')) return VideoPlayerType.m3u8;
  15 + if (type.startsWith('mp4')) return VideoPlayerType.mp4;
  16 + if (type.startsWith('webm')) return VideoPlayerType.webm;
  17 + return;
  18 +};
... ...
... ... @@ -119,7 +119,7 @@ export const formSchema: FormSchema[] = [
119 119 component: 'Input',
120 120 componentProps: {
121 121 placeholder: '请输入组态名称',
122   - maxLength: 255,
  122 + maxLength: 36,
123 123 },
124 124 },
125 125 {
... ...
... ... @@ -125,8 +125,8 @@
125 125 const getTable = getTestTableKeyValue();
126 126 const hasRequired = getTable?.some((it) => it.required === true && !it.value);
127 127 if (hasRequired) {
128   - createMessage.error('选择项为必须的,参数不能为空');
129   - throw new Error('选择项为必须的,参数不能为空');
  128 + createMessage.error('参数不能为空');
  129 + throw new Error('参数不能为空');
130 130 }
131 131 getTable?.map((it) => (params[it.key!] = it.value!));
132 132 } else if (props.data?.type === 'json') {
... ...
... ... @@ -8,7 +8,7 @@
8 8 <a-col :span="2"> 测试结果 </a-col>
9 9 <a-col :span="22">
10 10 <a-textarea
11   - v-if="ifWebSocket === '2'"
  11 + v-if="isWebSocketType === '2'"
12 12 allow-clear
13 13 show-count
14 14 v-model:value="testResult"
... ... @@ -29,13 +29,12 @@
29 29 </div>
30 30 </template>
31 31 <script lang="ts" setup name="testRequest">
32   - import { nextTick, ref, reactive } from 'vue';
  32 + import { nextTick, ref, reactive, onUnmounted } from 'vue';
33 33 import { Button } from 'ant-design-vue';
34 34 import { otherHttp } from '/@/utils/http/axios';
35 35 import { useWebSocket } from '@vueuse/core';
36 36 import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
37 37 import { getAuthCache } from '/@/utils/auth';
38   - import { useMessage } from '/@/hooks/web/useMessage';
39 38 import { useUtils } from '../../../hooks/useUtils';
40 39
41 40 const emits = defineEmits(['emitExcute']);
... ... @@ -48,10 +47,6 @@
48 47
49 48 const showTestFlag = ref(false);
50 49
51   - const ifWebSocket = ref('');
52   -
53   - const { createMessage } = useMessage();
54   -
55 50 const token = getAuthCache(JWT_TOKEN_KEY);
56 51
57 52 const socketUrls = ref('');
... ... @@ -87,6 +82,8 @@
87 82
88 83 const httpResult = ref('');
89 84
  85 + const isWebSocketType = ref('');
  86 +
90 87 //执行测试接口
91 88 const handleExcute = () => {
92 89 emits('emitExcute');
... ... @@ -97,15 +94,14 @@
97 94 await nextTick();
98 95 //获取Params和Header和Body
99 96 const Objects = props.data;
100   - const isWebSocketType = Objects?.method;
  97 + isWebSocketType.value = Objects?.method;
101 98 const apiType = Objects?.apiType;
102 99 const url = Objects?.apiGetUrl;
103 100 const headers = Objects?.Header?.params;
104 101 const params = Objects?.Params?.params;
105 102 const body = Objects?.Body?.params;
106 103 const apiUrl = url?.restfulFormat(params);
107   - ifWebSocket.value = isWebSocketType;
108   - if (isWebSocketType === '2') {
  104 + if (isWebSocketType.value === '2') {
109 105 socketUrls.value = url;
110 106 socketMessage.server = `${socketUrls.value}?token=${token}`;
111 107 websocketRequest(params);
... ... @@ -117,13 +113,15 @@
117 113 };
118 114
119 115 //websocket请求
120   - const websocketRequest = (params) => {
  116 + const websocketRequest = (params, destroy = false) => {
121 117 //websocket请求
122   - Reflect.deleteProperty(params, 'deviceProfileId');
123   - Reflect.deleteProperty(params, 'organizationId');
124   - Reflect.set(params, 'cmdId', 1);
125   - Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
126   - Reflect.set(params, 'entityType', 'DEVICE');
  118 + if (Object.prototype.toString.call(params) === '[object Object]') {
  119 + Reflect.deleteProperty(params, 'deviceProfileId');
  120 + Reflect.deleteProperty(params, 'organizationId');
  121 + Reflect.set(params, 'cmdId', 1);
  122 + Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
  123 + Reflect.set(params, 'entityType', 'DEVICE');
  124 + }
127 125 socketMessage.sendValue.tsSubCmds.push(params);
128 126 const { send, close } = useWebSocket(socketMessage.server, {
129 127 onConnected() {
... ... @@ -138,12 +136,17 @@
138 136 console.log('断开连接了');
139 137 close();
140 138 },
141   - onError() {
142   - createMessage.error('webSocket连接超时,请联系管理员');
143   - },
  139 + onError() {},
144 140 });
  141 + if (destroy) close();
145 142 };
146 143
  144 + onUnmounted(() => {
  145 + if (isWebSocketType.value === '2') {
  146 + websocketRequest(null, true);
  147 + }
  148 + });
  149 +
147 150 //TODO: 待优化 项目自带第三方请求
148 151 const otherHttpRequest = async (
149 152 apiType,
... ... @@ -188,7 +191,7 @@
188 191 }
189 192 httpResult.value = '测试结果为:';
190 193 testResult.value = '测试结果为:';
191   - ifWebSocket.value = '0';
  194 + isWebSocketType.value = '0';
192 195 };
193 196
194 197 const showTest = () => (showTestFlag.value = true);
... ...
... ... @@ -64,8 +64,8 @@
64 64 const getTable = getTestTableKeyValue();
65 65 const hasRequired = getTable?.some((it) => it.required === true && !it.value);
66 66 if (hasRequired) {
67   - createMessage.error('选择项为必须的,参数不能为空');
68   - throw new Error('选择项为必须的,参数不能为空');
  67 + createMessage.error('参数不能为空');
  68 + throw new Error('参数不能为空');
69 69 }
70 70 const params: any = {};
71 71 getTable?.map((it: any) => (params[it.key!] = it.value!));
... ...
... ... @@ -105,8 +105,8 @@
105 105 const getTable = getTestTableKeyValue();
106 106 const hasRequired = getTable?.some((it) => it.required === true && !it.value);
107 107 if (hasRequired) {
108   - createMessage.error('选择项为必须的,参数不能为空');
109   - throw new Error('选择项为必须的,参数不能为空');
  108 + createMessage.error('参数不能为空');
  109 + throw new Error('参数不能为空');
110 110 }
111 111 const params: any = {};
112 112 getTable?.map((it) => (params[it.key!] = it.value!));
... ...
1 1 <template>
2 2 <div>
3 3 <BasicDrawer
  4 + destroyOnClose
4 5 showFooter
5 6 v-bind="$attrs"
6 7 @register="registerDrawer"
... ... @@ -46,7 +47,7 @@
46 47 import { useMessage } from '/@/hooks/web/useMessage';
47 48 import { useUtils } from './hooks/useUtils';
48 49
49   - const { resetReqHttpType, resetUpdateSchema } = useUtils();
  50 + const { resetReqHttpType } = useUtils();
50 51
51 52 const emits = defineEmits(['success', 'register']);
52 53
... ... @@ -69,10 +70,15 @@
69 70 const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
70 71 await resetFields();
71 72 await nextTick();
72   - updateSchema(resetUpdateSchema);
73 73 setFieldsValue(resetReqHttpType);
74 74 const title = `${!data.isUpdate ? '新增' : '修改'}公共接口`;
75 75 setDrawerProps({ title });
  76 + updateSchema({
  77 + field: 'requestHttpTypeAndUrl',
  78 + componentProps: {
  79 + type: '0',
  80 + },
  81 + });
76 82 isUpdate.value = data.isUpdate;
77 83 !isUpdate.value ? (putId.value = '') : (putId.value = data.record.id);
78 84 simpleRequestRef.value?.resetValue() && testSqlRef.value?.resetValue();
... ...
... ... @@ -39,7 +39,7 @@
39 39 icon: 'ant-design:node-expand-outlined',
40 40 onClick: handlePublish.bind(null, 'publish', record),
41 41 ifShow: () => {
42   - return record.state === 0;
  42 + return record.state === 0 && record.creator === userId;
43 43 },
44 44 },
45 45 {
... ... @@ -47,7 +47,7 @@
47 47 icon: 'ant-design:node-collapse-outlined',
48 48 onClick: handlePublish.bind(null, 'canelPublish', record),
49 49 ifShow: () => {
50   - return record.state === 1;
  50 + return record.state === 1 && record.creator === userId;
51 51 },
52 52 },
53 53 {
... ... @@ -55,7 +55,7 @@
55 55 icon: 'clarity:note-edit-line',
56 56 onClick: handleCreateOrEdit.bind(null, record),
57 57 ifShow: () => {
58   - return record.state === 0;
  58 + return record.state === 0 && record.creator === userId;
59 59 },
60 60 },
61 61 {
... ... @@ -63,7 +63,7 @@
63 63 icon: 'ant-design:delete-outlined',
64 64 color: 'error',
65 65 ifShow: () => {
66   - return record.state === 0;
  66 + return record.state === 0 && record.creator === userId;
67 67 },
68 68 popConfirm: {
69 69 title: '是否确认删除',
... ... @@ -93,6 +93,12 @@
93 93 import { Popconfirm, Modal } from 'ant-design-vue';
94 94 import { JsonPreview } from '/@/components/CodeEditor';
95 95 import { useMessage } from '/@/hooks/web/useMessage';
  96 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  97 + import { getAuthCache } from '/@/utils/auth';
  98 +
  99 + const userInfo = getAuthCache(USER_INFO_KEY) as any;
  100 +
  101 + const userId = ref(userInfo?.userId);
96 102
97 103 const [registerTable, { reload, clearSelectedRowKeys }] = useTable({
98 104 api: getDataViewInterfacePage,
... ...
1   -<template>
2   - <BasicDrawer
3   - :maskClosable="false"
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 } 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 resetFields();
202   - setDrawerProps({ confirmLoading: false });
203   - isUpdate.value = !!data?.isUpdate;
204   - isViewDetail.value = !!data?.isView;
205   - if (unref(isViewDetail)) {
206   - setDrawerProps({ showFooter: true });
207   - if (unref(isUpdate)) {
208   - setDrawerProps({ title: '编辑报表配置' });
209   - } else {
210   - setDrawerProps({ title: '新增报表配置' });
211   - }
212   - } else {
213   - setDrawerProps({ showFooter: false });
214   - setDrawerProps({ title: '查看报表配置' });
215   - }
216   - if (unref(isUpdate)) {
217   - //编辑回显数据
218   - editResData = await reportEditDetailPage(data.record.id);
219   - //回显基础数据
220   - editId.value = editResData.data.id;
221   - await setFieldsValue(editResData.data);
222   - //回显嵌套数据
223   - await setFieldsValue({
224   - agg: editResData.data.queryCondition?.agg,
225   - interval: editResData.data.queryCondition?.interval,
226   - limit: editResData.data.queryCondition?.limit,
227   - orderBy: editResData.data.queryCondition?.orderBy,
228   - useStrictDataTypes: editResData.data.queryCondition?.useStrictDataTypes,
229   - startTs: editResData.data.queryCondition?.startTs,
230   - endTs: editResData.data.queryCondition?.endTs,
231   - way: editResData.data?.way,
232   - queryMode: editResData.data.queryCondition?.queryMode === 0 ? 'latest' : 'timePeriod',
233   - cronTime: editResData.data?.executeContent,
234   - currentCycle: editResData.data?.cycle?.currentCycle,
235   - cycleTime: editResData.data?.cycle?.cycleTime,
236   - cycleType: editResData.data?.cycle?.cycleType,
237   - });
238   - const endTsTime = editResData.data.queryCondition?.endTs;
239   - const startTsTime = editResData.data.queryCondition?.startTs;
240   - const mathFloor = (endTsTime - startTsTime) / 10;
241   - const multTen = Math.floor(mathFloor) * 10;
242   - await setFieldsValue({
243   - startTs: multTen,
244   - });
245   - if (editResData.data.queryCondition?.queryMode == 1) {
246   - await setFieldsValue({
247   - dataRange: [
248   - editResData.data.queryCondition?.startTs,
249   - editResData.data.queryCondition?.endTs,
250   - ],
251   - });
252   - }
253   - //回显聚合条件
254   - const dataCompareOpions = [
255   - { label: '最小值', value: AggregateDataEnum.MIN },
256   - { label: '最大值', value: AggregateDataEnum.MAX },
257   - { label: '平均值', value: AggregateDataEnum.AVG },
258   - { label: '求和', value: AggregateDataEnum.SUM },
259   - { label: '空', value: AggregateDataEnum.NONE },
260   - ];
261   - const updateSchemaAgg = (options: {}) => {
262   - updateSchema({
263   - field: SchemaFiled.AGG,
264   - componentProps: {
265   - options,
266   - },
267   - });
268   - };
269   - if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 4));
270   - else updateSchemaAgg(dataCompareOpions.slice(4, 5));
271   - //回显执行方式和查询周期
272   - const dataQueryOpions = [
273   - { label: '固定周期', value: QueryWay.LATEST },
274   - { label: '自定义周期', value: QueryWay.TIME_PERIOD },
275   - ];
276   - const updateSchemaQuery = (options: {}) => {
277   - updateSchema({
278   - field: SchemaFiled.WAY,
279   - componentProps: {
280   - options,
281   - },
282   - });
283   - };
284   - if (editResData.data.executeWay == 0) updateSchemaQuery(dataQueryOpions);
285   - else updateSchemaQuery(dataQueryOpions.slice(0, 1));
286   - //回显设备
287   - orgId.value = editResData.data.organizationId;
288   - const { items } = await screenLinkPageByDeptIdGetDevice({
289   - organizationId: editResData.data.organizationId,
290   - });
291   - selectOptions.value = items.map((item) => {
292   - if (item.deviceType !== 'GATEWAY')
293   - return {
294   - label: item.alias ? item.alias : item.name,
295   - value: item.tbDeviceId,
296   - id: item.id,
297   - deviceProfileId: item.deviceProfileId,
298   - };
299   - });
300   - const deviceIds = editResData.data.executeAttributes.map((m) => {
301   - return {
302   - label: m.name,
303   - key: m.device,
304   - };
305   - });
306   - selectDevice.value = deviceIds;
307   - //回显设备属性
308   - editDeviceAttr.value = editResData.data.executeAttributes?.map((item) => {
309   - const T = selectOptions.value.find((o) => {
310   - if (item.device === o.value) {
311   - return {
312   - id: o.id,
313   - deviceProfileId: o.deviceProfileId,
314   - };
315   - }
316   - });
317   - return {
318   - ...T,
319   - label: item.alias ? item.alias : item.name,
320   - value: item.device,
321   - attributes: item.attributes,
322   - };
323   - });
324   - deviceList.value = editDeviceAttr.value;
325   - editDeviceList.value = editResData.data.executeAttributes;
326   - } else {
327   - setFieldsValue({
328   - startTs: 1000,
329   - interval: 1000,
330   - });
331   - editId.value = '';
332   - orgId.value = '';
333   - selectDevice.value = [];
334   - selectOptions.value = [];
335   - deviceList.value = [];
336   - getAttrDevice.value = [];
337   - editDeviceList.value = [];
338   - editDeviceAttr.value = [];
339   - updateSchema({
340   - field: SchemaFiled.AGG,
341   - componentProps: {
342   - options: [],
343   - },
344   - });
345   - //新增显示执行方式和查询周期
346   - const dataQueryOpions = [
347   - { label: '固定周期', value: QueryWay.LATEST },
348   - { label: '自定义周期', value: QueryWay.TIME_PERIOD },
349   - ];
350   - const updateSchemaQuery = (options: {}) => {
351   - updateSchema({
352   - field: SchemaFiled.WAY,
353   - componentProps: {
354   - options,
355   - },
356   - });
357   - };
358   - if (getFieldsValue().executeWay == 0) updateSchemaQuery(dataQueryOpions);
359   - }
360   - });
361   - const handleClose = () => {
362   - deviceList.value = [];
363   - editId.value = '';
364   - orgId.value = '';
365   - selectDevice.value = [];
366   - selectOptions.value = [];
367   - getAttrDevice.value = [];
368   - editDeviceList.value = [];
369   - editDeviceAttr.value = [];
370   - };
371   - const getAttrDevice: Ref<TDeviceList[]> = ref([]);
372   - const getTitle = computed(() => (!unref(isUpdate) ? '新增报表配置' : '编辑报表配置'));
373   - let postObj: any = reactive({});
374   - let queryCondition: any = reactive({});
375   - let executeContent: any = reactive({});
376   - const startTs = ref(0);
377   - const endTs = ref(0);
378   -
379   - const getFormValueFunc = () => {
380   - const item: any = unref(bindDeviceRefObj.deviceAttrRef)?.map((item: any) => item.emitChange());
381   - getAttrDevice.value = item;
382   - };
383   -
384   - async function handleSubmit() {
385   - setDrawerProps({ confirmLoading: true });
386   - try {
387   - const { createMessage } = useMessage();
388   - const values = await validate();
389   - if (!values) return;
390   - getFormValueFunc();
391   - let hasAttr = false;
392   - if (!unref(isUpdate)) {
393   - if (getAttrDevice.value.length === 0) {
394   - return createMessage.error('请选择设备及其属性');
395   - } else {
396   - getAttrDevice.value.forEach((f: any) => {
397   - if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
398   - });
399   - }
400   - } else {
401   - if (getAttrDevice.value.length === 0) {
402   - return createMessage.error('请选择设备及其属性');
403   - } else {
404   - getAttrDevice.value.forEach((f: any) => {
405   - if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
406   - });
407   - }
408   - }
409   - if (hasAttr) return createMessage.error('请选择设备属性');
410   - if (values.executeWay == 0) {
411   - executeContent = null;
412   - } else {
413   - executeContent = values.cronTime;
414   - }
415   - if (values.queryMode === QueryWay.LATEST) {
416   - startTs.value = moment().subtract(values.startTs, 'ms').valueOf();
417   - endTs.value = Date.now();
418   - } else {
419   - const fT = JSON.parse(JSON.stringify(values.dataRange));
420   - startTs.value = moment(fT[0]).valueOf();
421   - endTs.value = moment(fT[1]).valueOf();
422   - }
423   - queryCondition = {
424   - agg: values.agg,
425   - interval: values.interval,
426   - limit: values.limit,
427   - ...{
428   - startTs: startTs.value,
429   - },
430   - ...{
431   - endTs: endTs.value,
432   - },
433   - queryMode: values?.queryMode === 'latest' ? 0 : 1,
434   - };
435   - const cycle = {
436   - currentCycle: values.currentCycle,
437   - cycleTime: values.cycleTime,
438   - cycleType: values.cycleType,
439   - };
440   - delete values.devices;
441   - delete values.agg;
442   - delete values.interval;
443   - delete values.timeZone;
444   - delete values.cronTime;
445   - delete values.currentCycle;
446   - delete values.cycleTime;
447   - delete values.limit1;
448   - delete values.startTs;
449   - delete values.queryMode;
450   - delete values.cycleType;
451   - postObj = {
452   - ...values,
453   - ...{
454   - executeAttributes:
455   - getAttrDevice.value.length == 0 ? editDeviceList.value : getAttrDevice.value,
456   - },
457   - ...{ queryCondition },
458   - ...{ cycle },
459   - ...{ executeContent },
460   - ...{ id: editId.value !== '' ? editId.value : '' },
461   - };
462   - let saveMessage = '添加成功';
463   - let updateMessage = '修改成功';
464   - editId.value !== ''
465   - ? await putReportConfigManage(postObj)
466   - : await createOrEditReportManage(postObj);
467   -
468   - closeDrawer();
469   - emit('success');
470   - createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);
471   - handleClose();
472   - } finally {
473   - setTimeout(() => {
474   - setDrawerProps({ confirmLoading: false });
475   - }, 300);
476   - }
477   - }
478   -</script>
  1 +<template>
  2 + <BasicDrawer
  3 + :maskClosable="false"
  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 } 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 resetFields();
  202 + setDrawerProps({ confirmLoading: false });
  203 + isUpdate.value = !!data?.isUpdate;
  204 + isViewDetail.value = !!data?.isView;
  205 + if (unref(isViewDetail)) {
  206 + setDrawerProps({ showFooter: true });
  207 + if (unref(isUpdate)) {
  208 + setDrawerProps({ title: '编辑报表配置' });
  209 + } else {
  210 + setDrawerProps({ title: '新增报表配置' });
  211 + }
  212 + } else {
  213 + setDrawerProps({ showFooter: false });
  214 + setDrawerProps({ title: '查看报表配置' });
  215 + }
  216 + if (unref(isUpdate)) {
  217 + //编辑回显数据
  218 + editResData = await reportEditDetailPage(data.record.id);
  219 + //回显基础数据
  220 + editId.value = editResData.data.id;
  221 + const spanDisance = editResData.data.executeContent.split(' ');
  222 + await setFieldsValue(editResData.data);
  223 + //回显嵌套数据
  224 + await setFieldsValue({
  225 + agg: editResData.data.queryCondition?.agg,
  226 + interval: editResData.data.queryCondition?.interval,
  227 + limit: editResData.data.queryCondition?.limit,
  228 + orderBy: editResData.data.queryCondition?.orderBy,
  229 + useStrictDataTypes: editResData.data.queryCondition?.useStrictDataTypes,
  230 + startTs: editResData.data.queryCondition?.startTs,
  231 + endTs: editResData.data.queryCondition?.endTs,
  232 + way: editResData.data?.way,
  233 + queryMode: editResData.data.queryCondition?.queryMode === 0 ? 'latest' : 'timePeriod',
  234 + cronTime:
  235 + editResData.data?.cycle?.cycleType === 2
  236 + ? spanDisance[2] < 10
  237 + ? editResData.data.executeContent.slice(0, 7) + '* * ?'
  238 + : editResData.data.executeContent.slice(0, 7) + ' ' + '* * ?'
  239 + : editResData.data?.cycle?.cycleType === 1
  240 + ? spanDisance[2] < 10
  241 + ? editResData.data.executeContent.slice(0, 5) + ' ' + ' * * ?'
  242 + : editResData.data.executeContent.slice(0, 6) + ' ' + ' * * ?'
  243 + : editResData.data.executeContent,
  244 + currentCycle: editResData.data?.cycle?.currentCycle,
  245 + cycleTime: editResData.data?.cycle?.cycleTime,
  246 + cycleType: editResData.data?.cycle?.cycleType,
  247 + });
  248 + const endTsTime = editResData.data.queryCondition?.endTs;
  249 + const startTsTime = editResData.data.queryCondition?.startTs;
  250 + const mathFloor = (endTsTime - startTsTime) / 10;
  251 + const multTen = Math.floor(mathFloor) * 10;
  252 + await setFieldsValue({
  253 + startTs: multTen,
  254 + });
  255 + if (editResData.data.queryCondition?.queryMode == 1) {
  256 + await setFieldsValue({
  257 + dataRange: [
  258 + editResData.data.queryCondition?.startTs,
  259 + editResData.data.queryCondition?.endTs,
  260 + ],
  261 + });
  262 + }
  263 + //回显聚合条件
  264 + const dataCompareOpions = [
  265 + { label: '最小值', value: AggregateDataEnum.MIN },
  266 + { label: '最大值', value: AggregateDataEnum.MAX },
  267 + { label: '平均值', value: AggregateDataEnum.AVG },
  268 + { label: '求和', value: AggregateDataEnum.SUM },
  269 + { label: '空', value: AggregateDataEnum.NONE },
  270 + ];
  271 + const updateSchemaAgg = (options: {}) => {
  272 + updateSchema({
  273 + field: SchemaFiled.AGG,
  274 + componentProps: {
  275 + options,
  276 + },
  277 + });
  278 + };
  279 + if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 4));
  280 + else updateSchemaAgg(dataCompareOpions.slice(4, 5));
  281 + //回显执行方式和查询周期
  282 + const dataQueryOpions = [
  283 + { label: '固定周期', value: QueryWay.LATEST },
  284 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  285 + ];
  286 + const updateSchemaQuery = (options: {}) => {
  287 + updateSchema({
  288 + field: SchemaFiled.WAY,
  289 + componentProps: {
  290 + options,
  291 + },
  292 + });
  293 + };
  294 + if (editResData.data.executeWay == 0) updateSchemaQuery(dataQueryOpions);
  295 + else updateSchemaQuery(dataQueryOpions.slice(0, 1));
  296 + //回显设备
  297 + orgId.value = editResData.data.organizationId;
  298 + const { items } = await screenLinkPageByDeptIdGetDevice({
  299 + organizationId: editResData.data.organizationId,
  300 + });
  301 + selectOptions.value = items.map((item) => {
  302 + if (item.deviceType !== 'GATEWAY')
  303 + return {
  304 + label: item.alias ? item.alias : item.name,
  305 + value: item.tbDeviceId,
  306 + id: item.id,
  307 + deviceProfileId: item.deviceProfileId,
  308 + };
  309 + });
  310 + const deviceIds = editResData.data.executeAttributes.map((m) => {
  311 + return {
  312 + label: m.name,
  313 + key: m.device,
  314 + };
  315 + });
  316 + selectDevice.value = deviceIds;
  317 + //回显设备属性
  318 + editDeviceAttr.value = editResData.data.executeAttributes?.map((item) => {
  319 + const T = selectOptions.value.find((o) => {
  320 + if (item.device === o.value) {
  321 + return {
  322 + id: o.id,
  323 + deviceProfileId: o.deviceProfileId,
  324 + };
  325 + }
  326 + });
  327 + return {
  328 + ...T,
  329 + label: item.alias ? item.alias : item.name,
  330 + value: item.device,
  331 + attributes: item.attributes,
  332 + };
  333 + });
  334 + deviceList.value = editDeviceAttr.value;
  335 + editDeviceList.value = editResData.data.executeAttributes;
  336 + } else {
  337 + setFieldsValue({
  338 + startTs: 1000,
  339 + interval: 1000,
  340 + });
  341 + editId.value = '';
  342 + orgId.value = '';
  343 + selectDevice.value = [];
  344 + selectOptions.value = [];
  345 + deviceList.value = [];
  346 + getAttrDevice.value = [];
  347 + editDeviceList.value = [];
  348 + editDeviceAttr.value = [];
  349 + updateSchema({
  350 + field: SchemaFiled.AGG,
  351 + componentProps: {
  352 + options: [],
  353 + },
  354 + });
  355 + //新增显示执行方式和查询周期
  356 + const dataQueryOpions = [
  357 + { label: '固定周期', value: QueryWay.LATEST },
  358 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  359 + ];
  360 + const updateSchemaQuery = (options: {}) => {
  361 + updateSchema({
  362 + field: SchemaFiled.WAY,
  363 + componentProps: {
  364 + options,
  365 + },
  366 + });
  367 + };
  368 + if (getFieldsValue().executeWay == 0) updateSchemaQuery(dataQueryOpions);
  369 + }
  370 + });
  371 + const handleClose = () => {
  372 + deviceList.value = [];
  373 + editId.value = '';
  374 + orgId.value = '';
  375 + selectDevice.value = [];
  376 + selectOptions.value = [];
  377 + getAttrDevice.value = [];
  378 + editDeviceList.value = [];
  379 + editDeviceAttr.value = [];
  380 + };
  381 + const getAttrDevice: Ref<TDeviceList[]> = ref([]);
  382 + const getTitle = computed(() => (!unref(isUpdate) ? '新增报表配置' : '编辑报表配置'));
  383 + let postObj: any = reactive({});
  384 + let queryCondition: any = reactive({});
  385 + let executeContent: any = reactive({});
  386 + const startTs = ref(0);
  387 + const endTs = ref(0);
  388 +
  389 + const getFormValueFunc = () => {
  390 + const item: any = unref(bindDeviceRefObj.deviceAttrRef)?.map((item: any) => item.emitChange());
  391 + getAttrDevice.value = item;
  392 + };
  393 +
  394 + async function handleSubmit() {
  395 + setDrawerProps({ confirmLoading: true });
  396 + try {
  397 + const { createMessage } = useMessage();
  398 + const values = await validate();
  399 + if (!values) return;
  400 + getFormValueFunc();
  401 + let hasAttr = false;
  402 + if (!unref(isUpdate)) {
  403 + if (getAttrDevice.value.length === 0) {
  404 + return createMessage.error('请选择设备及其属性');
  405 + } else {
  406 + getAttrDevice.value.forEach((f: any) => {
  407 + if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
  408 + });
  409 + }
  410 + } else {
  411 + if (getAttrDevice.value.length === 0) {
  412 + return createMessage.error('请选择设备及其属性');
  413 + } else {
  414 + getAttrDevice.value.forEach((f: any) => {
  415 + if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
  416 + });
  417 + }
  418 + }
  419 + if (hasAttr) return createMessage.error('请选择设备属性');
  420 + if (values.executeWay == 0) {
  421 + executeContent = null;
  422 + } else {
  423 + //拼接corn
  424 + let joinCorn = '';
  425 + if (values.cycleType === 1) {
  426 + joinCorn = values.cronTime.slice(0, 6) + values.currentCycle.slice(5);
  427 + executeContent = joinCorn;
  428 + } else if (values.cycleType === 0) {
  429 + executeContent = values.cronTime;
  430 + } else if (values.cycleType === 2) {
  431 + joinCorn = values.cronTime.slice(0, 6) + values.cycleTime.slice(5);
  432 + executeContent = joinCorn;
  433 + }
  434 + }
  435 + if (values.queryMode === QueryWay.LATEST) {
  436 + startTs.value = moment().subtract(values.startTs, 'ms').valueOf();
  437 + endTs.value = Date.now();
  438 + } else {
  439 + const fT = JSON.parse(JSON.stringify(values.dataRange));
  440 + startTs.value = moment(fT[0]).valueOf();
  441 + endTs.value = moment(fT[1]).valueOf();
  442 + }
  443 + queryCondition = {
  444 + agg: values.agg,
  445 + interval: values.interval,
  446 + limit: values.limit,
  447 + ...{
  448 + startTs: startTs.value,
  449 + },
  450 + ...{
  451 + endTs: endTs.value,
  452 + },
  453 + queryMode: values?.queryMode === 'latest' ? 0 : 1,
  454 + };
  455 + const cycle: any = {};
  456 + if (values.cycleType === 0) {
  457 + cycle.cycleType = values.cycleType;
  458 + cycle.cronTime = values.cronTime;
  459 + }
  460 + if (values.cycleType === 1) {
  461 + cycle.cycleType = values.cycleType;
  462 + cycle.currentCycle = values.currentCycle;
  463 + cycle.cronTime = values.cronTime;
  464 + }
  465 + if (values.cycleType === 2) {
  466 + cycle.cycleType = values.cycleType;
  467 + cycle.cycleTime = values.cycleTime;
  468 + cycle.cronTime = values.cronTime;
  469 + }
  470 + // const cycle = {
  471 + // currentCycle: values.currentCycle,
  472 + // cycleTime: values.cycleTime,
  473 + // cronTime: values.cronTime,
  474 + // cycleType: values.cycleType,
  475 + // };
  476 + delete values.devices;
  477 + delete values.agg;
  478 + delete values.interval;
  479 + delete values.timeZone;
  480 + delete values.cronTime;
  481 + delete values.currentCycle;
  482 + delete values.cycleTime;
  483 + delete values.limit1;
  484 + delete values.startTs;
  485 + delete values.queryMode;
  486 + delete values.cycleType;
  487 + postObj = {
  488 + ...values,
  489 + ...{
  490 + executeAttributes:
  491 + getAttrDevice.value.length == 0 ? editDeviceList.value : getAttrDevice.value,
  492 + },
  493 + ...{ queryCondition },
  494 + ...{ cycle },
  495 + ...{ executeContent },
  496 + ...{ id: editId.value !== '' ? editId.value : '' },
  497 + };
  498 + let saveMessage = '添加成功';
  499 + let updateMessage = '修改成功';
  500 + editId.value !== ''
  501 + ? await putReportConfigManage(postObj)
  502 + : await createOrEditReportManage(postObj);
  503 +
  504 + closeDrawer();
  505 + emit('success');
  506 + createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);
  507 + handleClose();
  508 + } finally {
  509 + setTimeout(() => {
  510 + setDrawerProps({ confirmLoading: false });
  511 + }, 300);
  512 + }
  513 + }
  514 +</script>
... ...
1   -import { ref } from 'vue';
2   -import { BasicColumn, FormSchema } from '/@/components/Table';
3   -import type { FormSchema as QFormSchema } from '/@/components/Form/index';
4   -import moment from 'moment';
5   -import { getOrganizationList } from '/@/api/system/system';
6   -import { copyTransFun } from '/@/utils/fnUtils';
7   -import { findDictItemByCode } from '/@/api/system/dict';
8   -import { isTiming, isWeek, isMonth, isFixedTime } from './timeConfig';
9   -import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config';
10   -import {
11   - getPacketIntervalByRange,
12   - getPacketIntervalByValue,
13   - intervalOption,
14   -} from '../../device/localtion/cpns/TimePeriodForm/helper';
15   -
16   -export enum QueryWay {
17   - LATEST = 'latest',
18   - TIME_PERIOD = 'timePeriod',
19   -}
20   -export enum SchemaFiled {
21   - WAY = 'queryMode',
22   - TIME_PERIOD = 'timePeriod',
23   - KEYS = 'keys',
24   - DATE_RANGE = 'dataRange',
25   - START_TS = 'startTs',
26   - END_TS = 'endTs',
27   - INTERVAL = 'interval',
28   - LIMIT = 'limit',
29   - AGG = 'agg',
30   - ORDER_BY = 'orderBy',
31   -}
32   -export const organizationId = ref('');
33   -
34   -// 表格配置
35   -export const columns: BasicColumn[] = [
36   - {
37   - title: '配置名称',
38   - dataIndex: 'name',
39   - width: 120,
40   - },
41   - {
42   - title: '所属组织',
43   - dataIndex: 'organizationDTO.name',
44   - width: 120,
45   - },
46   - {
47   - title: '数据类型',
48   - dataIndex: 'dataType',
49   - width: 120,
50   - format: (_text: string, record: Recordable) => {
51   - return record.dataType === 0 ? '原始数据' : '聚合数据';
52   - },
53   - },
54   - {
55   - title: '配置状态',
56   - dataIndex: 'status',
57   - width: 120,
58   - slots: { customRender: 'configStatus' },
59   - },
60   - {
61   - title: '执行方式',
62   - dataIndex: 'executeWay',
63   - width: 160,
64   - format: (_text: string, record: Recordable) => {
65   - return record.executeWay === 0 ? '立即执行' : '定时执行';
66   - },
67   - },
68   - {
69   - title: '执行设备',
70   - dataIndex: 'devices',
71   - width: 160,
72   - slots: { customRender: 'doDeviceSlot' },
73   - },
74   - {
75   - title: '创建人',
76   - dataIndex: 'createUserName',
77   - width: 180,
78   - },
79   - {
80   - title: '创建时间',
81   - dataIndex: 'createTime',
82   - width: 180,
83   - },
84   -];
85   -export const viewDeviceColumn: BasicColumn[] = [
86   - {
87   - title: '设备',
88   - dataIndex: 'device',
89   - width: 80,
90   - },
91   - {
92   - title: '属性',
93   - dataIndex: 'attribute',
94   - width: 120,
95   - },
96   -];
97   -
98   -// 查询配置
99   -export const searchFormSchema: FormSchema[] = [
100   - {
101   - field: 'name',
102   - label: '配置名称',
103   - component: 'Input',
104   - colProps: { span: 6 },
105   - componentProps: {
106   - maxLength: 36,
107   - placeholder: '请输入配置名称',
108   - },
109   - },
110   - {
111   - field: 'status',
112   - label: '配置状态',
113   - component: 'Select',
114   - colProps: { span: 6 },
115   - componentProps: {
116   - options: [
117   - {
118   - label: '启用',
119   - value: 1,
120   - },
121   - {
122   - label: '禁用',
123   - value: 0,
124   - },
125   - ],
126   - placeholder: '请选择配置状态',
127   - },
128   - },
129   - {
130   - field: 'sendTime',
131   - label: '创建时间',
132   - component: 'RangePicker',
133   - componentProps: {
134   - showTime: {
135   - defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
136   - },
137   - },
138   - colProps: { span: 6 },
139   - },
140   -];
141   -
142   -// 新增编辑配置
143   -export const formSchema: QFormSchema[] = [
144   - {
145   - field: 'name',
146   - label: '报表名称',
147   - colProps: { span: 24 },
148   - required: true,
149   - component: 'Input',
150   - componentProps: {
151   - maxLength: 64,
152   - placeholder: '请输入报表名称',
153   - },
154   - },
155   - {
156   - field: 'organizationId',
157   - label: '所属组织',
158   - colProps: { span: 24 },
159   - component: 'ApiTreeSelect',
160   - required: true,
161   - componentProps: () => {
162   - return {
163   - maxLength: 250,
164   - placeholder: '请选择所属组织',
165   - api: async () => {
166   - const data = await getOrganizationList();
167   - copyTransFun(data as any as any[]);
168   - return data;
169   - },
170   - async onChange(e) {
171   - organizationId.value = e;
172   - },
173   - };
174   - },
175   - },
176   - {
177   - field: 'remark',
178   - label: '描述',
179   - colProps: { span: 24 },
180   - component: 'InputTextArea',
181   - componentProps: {
182   - maxLength: 255,
183   - placeholder: '请输入描述',
184   - },
185   - },
186   - {
187   - field: 'executeWay',
188   - component: 'RadioGroup',
189   - helpMessage: [
190   - `立即执行,在创建完报表配置后,启用配置即执行。
191   - 定时执行,用户定义执行时间,启用后,
192   - 在满足执行时间条件后,自动执行。`,
193   - ],
194   - label: '执行方式',
195   - colProps: {
196   - span: 24,
197   - },
198   - defaultValue: 0,
199   - componentProps: ({ formActionType }) => {
200   - const { updateSchema, setFieldsValue } = formActionType;
201   - const options = [
202   - {
203   - label: '立即执行',
204   - value: 0,
205   - },
206   - {
207   - label: '定时执行',
208   - value: 1,
209   - },
210   - ];
211   - return {
212   - options,
213   - placeholder: '请选择执行方式',
214   - onChange(e) {
215   - let dataCompareOpions: any = [];
216   - setFieldsValue({
217   - startTs: 1000,
218   - interval: 1000,
219   - });
220   - if (e.target.value == 0) {
221   - setFieldsValue({ queryMode: QueryWay.LATEST });
222   - dataCompareOpions = [
223   - { label: '固定周期', value: QueryWay.LATEST },
224   - { label: '自定义周期', value: QueryWay.TIME_PERIOD },
225   - ];
226   - updateSchema({
227   - field: SchemaFiled.WAY,
228   - componentProps: {
229   - options: dataCompareOpions,
230   - },
231   - });
232   - } else {
233   - setFieldsValue({ queryMode: QueryWay.LATEST });
234   - setFieldsValue({ startTs: 5000 });
235   - setFieldsValue({ interval: 1000 });
236   - dataCompareOpions = [{ label: '固定周期', value: QueryWay.LATEST }];
237   - updateSchema({
238   - defaultValue: QueryWay.LATEST,
239   - field: SchemaFiled.WAY,
240   - componentProps: {
241   - options: dataCompareOpions,
242   - },
243   - });
244   - }
245   - },
246   - maxLength: 250,
247   - };
248   - },
249   - },
250   - {
251   - field: 'cycleType',
252   - component: 'Select',
253   - label: '周期',
254   - required: true,
255   - colProps: { span: 24 },
256   - defaultValue: 0,
257   - componentProps: {
258   - placeholder: '请选择周期',
259   - options: [
260   - { label: '每日', value: 0 },
261   - { label: '每周', value: 1 },
262   - { label: '每月', value: 2 },
263   - ],
264   - },
265   - ifShow: ({ values }) => isTiming(values.executeWay),
266   - },
267   - {
268   - field: 'currentCycle',
269   - component: 'ApiSelect',
270   - label: '每周',
271   - required: true,
272   - colProps: { span: 24 },
273   - defaultValue: '0 0 0 ? * 1',
274   - componentProps: {
275   - placeholder: '请选择周期',
276   - api: findDictItemByCode,
277   - params: {
278   - dictCode: 'every_week',
279   - },
280   - labelField: 'itemText',
281   - valueField: 'itemValue',
282   - },
283   - ifShow: ({ values }) => isWeek(values.cycleType),
284   - },
285   - {
286   - field: 'cycleTime',
287   - component: 'ApiSelect',
288   - label: '每月',
289   - required: true,
290   - colProps: { span: 24 },
291   - defaultValue: '0 0 0 1 * ? *',
292   - componentProps: {
293   - placeholder: '请选择月份',
294   - api: findDictItemByCode,
295   - params: {
296   - dictCode: 'every_month',
297   - },
298   - labelField: 'itemText',
299   - valueField: 'itemValue',
300   - },
301   - ifShow: ({ values }) => isMonth(values.cycleType),
302   - },
303   - {
304   - field: 'cronTime',
305   - component: 'ApiSelect',
306   - label: '时间',
307   - required: true,
308   - colProps: { span: 24 },
309   - defaultValue: '0 0 0 * * ?',
310   - componentProps: {
311   - placeholder: '请选择时间',
312   - api: findDictItemByCode,
313   - params: {
314   - dictCode: 'every_day',
315   - },
316   - labelField: 'itemText',
317   - valueField: 'itemValue',
318   - },
319   - ifShow: ({ values }) => isTiming(values.executeWay),
320   - },
321   - {
322   - field: 'devices',
323   - label: '设备',
324   - component: 'Select',
325   - slot: 'devices',
326   - colProps: { span: 24 },
327   - },
328   - {
329   - field: 'dataType',
330   - label: '数据类型',
331   - required: true,
332   - component: 'Select',
333   - componentProps: ({ formActionType }) => {
334   - const { updateSchema, setFieldsValue } = formActionType;
335   - const options = [
336   - { label: '原始数据', value: 0 },
337   - { label: '聚合数据', value: 1 },
338   - ];
339   - return {
340   - options,
341   - onSelect(e) {
342   - let dataCompareOpions: any = [];
343   - if (e == 0) {
344   - setFieldsValue({ agg: 'NONE' });
345   - dataCompareOpions = [{ label: '空', value: AggregateDataEnum.NONE }];
346   - updateSchema({
347   - field: SchemaFiled.AGG,
348   - componentProps: {
349   - options: dataCompareOpions,
350   - },
351   - });
352   - } else {
353   - setFieldsValue({ agg: '' });
354   - dataCompareOpions = [
355   - { label: '最小值', value: AggregateDataEnum.MIN },
356   - { label: '最大值', value: AggregateDataEnum.MAX },
357   - { label: '平均值', value: AggregateDataEnum.AVG },
358   - { label: '求和', value: AggregateDataEnum.SUM },
359   - { label: '计数', value: AggregateDataEnum.COUNT },
360   - ];
361   - updateSchema({
362   - field: SchemaFiled.AGG,
363   - componentProps: {
364   - options: dataCompareOpions,
365   - },
366   - });
367   - }
368   - },
369   - maxLength: 250,
370   - placeholder: '请选择属性性质',
371   - };
372   - },
373   - colProps: { span: 24 },
374   - },
375   - {
376   - field: SchemaFiled.AGG,
377   - label: '聚合条件',
378   - component: 'Select',
379   - required: true,
380   - componentProps: {
381   - placeholder: '请选择聚合条件',
382   - getPopupContainer: () => document.body,
383   - },
384   - },
385   - {
386   - field: 'limit',
387   - required: true,
388   - label: '最大条数',
389   - component: 'InputNumber',
390   - defaultValue: 100,
391   - ifShow({ values }) {
392   - return values[SchemaFiled.AGG] === AggregateDataEnum.NONE;
393   - },
394   - colProps: { span: 12 },
395   - componentProps: {
396   - placeholder: '请输入最大条数',
397   - min: 7,
398   - max: 50000,
399   - },
400   - },
401   - {
402   - field: SchemaFiled.WAY,
403   - label: '查询周期',
404   - component: 'RadioGroup',
405   - defaultValue: QueryWay.LATEST,
406   - required: true,
407   - componentProps({ formActionType }) {
408   - const { setFieldsValue } = formActionType;
409   - return {
410   - placeholder: '请选择查询周期',
411   - options: [
412   - { label: '固定周期', value: QueryWay.LATEST },
413   - { label: '自定义周期', value: QueryWay.TIME_PERIOD },
414   - ],
415   - onChange(value) {
416   - console.log(value);
417   - value === QueryWay.LATEST
418   - ? setFieldsValue({
419   - [SchemaFiled.DATE_RANGE]: [],
420   - [SchemaFiled.START_TS]: null,
421   - [SchemaFiled.END_TS]: null,
422   - })
423   - : setFieldsValue({ [SchemaFiled.START_TS]: null });
424   - },
425   - };
426   - },
427   - },
428   - {
429   - field: SchemaFiled.DATE_RANGE,
430   - label: '时间段',
431   - component: 'RangePicker',
432   - required: true,
433   - ifShow({ values }) {
434   - return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay);
435   - },
436   - componentProps: {
437   - showTime: {
438   - defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
439   - },
440   - },
441   - colProps: {
442   - span: 10,
443   - },
444   - },
445   - {
446   - field: SchemaFiled.START_TS,
447   - label: '最近时间',
448   - component: 'Select',
449   - required: true,
450   - ifShow({ values }) {
451   - return values[SchemaFiled.WAY] == QueryWay.LATEST;
452   - },
453   - componentProps({ formActionType }) {
454   - const { setFieldsValue } = formActionType;
455   - return {
456   - defaultValue: 1000,
457   - placeholder: '请选择近期时间',
458   - options: intervalOption,
459   - onChange() {
460   - setFieldsValue({ [SchemaFiled.INTERVAL]: null });
461   - },
462   - };
463   - },
464   - },
465   - {
466   - field: SchemaFiled.INTERVAL,
467   - label: '间隔时间',
468   - component: 'Select',
469   - required: true,
470   - ifShow({ values }) {
471   - return values[SchemaFiled.WAY] == QueryWay.LATEST;
472   - },
473   - componentProps({ formModel, formActionType }) {
474   - const options =
475   - formModel[SchemaFiled.WAY] === QueryWay.LATEST
476   - ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS])
477   - : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]);
478   - if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) {
479   - formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null });
480   - }
481   - return {
482   - placeholder: '请选择间隔时间',
483   - options,
484   - };
485   - },
486   - },
487   -];
  1 +import { ref } from 'vue';
  2 +import { BasicColumn, FormSchema } from '/@/components/Table';
  3 +import type { FormSchema as QFormSchema } from '/@/components/Form/index';
  4 +import moment from 'moment';
  5 +import { getOrganizationList } from '/@/api/system/system';
  6 +import { copyTransFun } from '/@/utils/fnUtils';
  7 +import { findDictItemByCode } from '/@/api/system/dict';
  8 +import { isTiming, isWeek, isMonth, isFixedTime } from './timeConfig';
  9 +import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config';
  10 +import {
  11 + getPacketIntervalByRange,
  12 + getPacketIntervalByValue,
  13 + intervalOption,
  14 +} from '../../device/localtion/cpns/TimePeriodForm/helper';
  15 +
  16 +export enum QueryWay {
  17 + LATEST = 'latest',
  18 + TIME_PERIOD = 'timePeriod',
  19 +}
  20 +export enum SchemaFiled {
  21 + WAY = 'queryMode',
  22 + TIME_PERIOD = 'timePeriod',
  23 + KEYS = 'keys',
  24 + DATE_RANGE = 'dataRange',
  25 + START_TS = 'startTs',
  26 + END_TS = 'endTs',
  27 + INTERVAL = 'interval',
  28 + LIMIT = 'limit',
  29 + AGG = 'agg',
  30 + ORDER_BY = 'orderBy',
  31 +}
  32 +export const organizationId = ref('');
  33 +
  34 +// 表格配置
  35 +export const columns: BasicColumn[] = [
  36 + {
  37 + title: '配置名称',
  38 + dataIndex: 'name',
  39 + width: 120,
  40 + },
  41 + {
  42 + title: '所属组织',
  43 + dataIndex: 'organizationDTO.name',
  44 + width: 120,
  45 + },
  46 + {
  47 + title: '数据类型',
  48 + dataIndex: 'dataType',
  49 + width: 120,
  50 + format: (_text: string, record: Recordable) => {
  51 + return record.dataType === 0 ? '原始数据' : '聚合数据';
  52 + },
  53 + },
  54 + {
  55 + title: '配置状态',
  56 + dataIndex: 'status',
  57 + width: 120,
  58 + slots: { customRender: 'configStatus' },
  59 + },
  60 + {
  61 + title: '执行方式',
  62 + dataIndex: 'executeWay',
  63 + width: 160,
  64 + format: (_text: string, record: Recordable) => {
  65 + return record.executeWay === 0 ? '立即执行' : '定时执行';
  66 + },
  67 + },
  68 + {
  69 + title: '执行设备',
  70 + dataIndex: 'devices',
  71 + width: 160,
  72 + slots: { customRender: 'doDeviceSlot' },
  73 + },
  74 + {
  75 + title: '创建人',
  76 + dataIndex: 'createUserName',
  77 + width: 180,
  78 + },
  79 + {
  80 + title: '创建时间',
  81 + dataIndex: 'createTime',
  82 + width: 180,
  83 + },
  84 +];
  85 +export const viewDeviceColumn: BasicColumn[] = [
  86 + {
  87 + title: '设备',
  88 + dataIndex: 'device',
  89 + width: 80,
  90 + },
  91 + {
  92 + title: '属性',
  93 + dataIndex: 'attribute',
  94 + width: 120,
  95 + },
  96 +];
  97 +
  98 +// 查询配置
  99 +export const searchFormSchema: FormSchema[] = [
  100 + {
  101 + field: 'name',
  102 + label: '配置名称',
  103 + component: 'Input',
  104 + colProps: { span: 6 },
  105 + componentProps: {
  106 + maxLength: 36,
  107 + placeholder: '请输入配置名称',
  108 + },
  109 + },
  110 + {
  111 + field: 'status',
  112 + label: '配置状态',
  113 + component: 'Select',
  114 + colProps: { span: 6 },
  115 + componentProps: {
  116 + options: [
  117 + {
  118 + label: '启用',
  119 + value: 1,
  120 + },
  121 + {
  122 + label: '禁用',
  123 + value: 0,
  124 + },
  125 + ],
  126 + placeholder: '请选择配置状态',
  127 + },
  128 + },
  129 + {
  130 + field: 'sendTime',
  131 + label: '创建时间',
  132 + component: 'RangePicker',
  133 + componentProps: {
  134 + showTime: {
  135 + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  136 + },
  137 + },
  138 + colProps: { span: 6 },
  139 + },
  140 +];
  141 +
  142 +// 新增编辑配置
  143 +export const formSchema: QFormSchema[] = [
  144 + {
  145 + field: 'name',
  146 + label: '报表名称',
  147 + colProps: { span: 24 },
  148 + required: true,
  149 + component: 'Input',
  150 + componentProps: {
  151 + maxLength: 64,
  152 + placeholder: '请输入报表名称',
  153 + },
  154 + },
  155 + {
  156 + field: 'organizationId',
  157 + label: '所属组织',
  158 + colProps: { span: 24 },
  159 + component: 'ApiTreeSelect',
  160 + required: true,
  161 + componentProps: () => {
  162 + return {
  163 + maxLength: 250,
  164 + placeholder: '请选择所属组织',
  165 + api: async () => {
  166 + const data = await getOrganizationList();
  167 + copyTransFun(data as any as any[]);
  168 + return data;
  169 + },
  170 + async onChange(e) {
  171 + organizationId.value = e;
  172 + },
  173 + };
  174 + },
  175 + },
  176 + {
  177 + field: 'remark',
  178 + label: '描述',
  179 + colProps: { span: 24 },
  180 + component: 'InputTextArea',
  181 + componentProps: {
  182 + maxLength: 255,
  183 + placeholder: '请输入描述',
  184 + },
  185 + },
  186 + {
  187 + field: 'executeWay',
  188 + component: 'RadioGroup',
  189 + helpMessage: [
  190 + `立即执行,在创建完报表配置后,启用配置即执行。
  191 + 定时执行,用户定义执行时间,启用后,
  192 + 在满足执行时间条件后,自动执行。`,
  193 + ],
  194 + label: '执行方式',
  195 + colProps: {
  196 + span: 24,
  197 + },
  198 + defaultValue: 0,
  199 + componentProps: ({ formActionType }) => {
  200 + const { updateSchema, setFieldsValue } = formActionType;
  201 + const options = [
  202 + {
  203 + label: '立即执行',
  204 + value: 0,
  205 + },
  206 + {
  207 + label: '定时执行',
  208 + value: 1,
  209 + },
  210 + ];
  211 + return {
  212 + options,
  213 + placeholder: '请选择执行方式',
  214 + onChange(e) {
  215 + let dataCompareOpions: any = [];
  216 + setFieldsValue({
  217 + startTs: 1000,
  218 + interval: 1000,
  219 + });
  220 + if (e.target.value == 0) {
  221 + setFieldsValue({ queryMode: QueryWay.LATEST });
  222 + dataCompareOpions = [
  223 + { label: '固定周期', value: QueryWay.LATEST },
  224 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  225 + ];
  226 + updateSchema({
  227 + field: SchemaFiled.WAY,
  228 + componentProps: {
  229 + options: dataCompareOpions,
  230 + },
  231 + });
  232 + } else {
  233 + setFieldsValue({ queryMode: QueryWay.LATEST });
  234 + setFieldsValue({ startTs: 5000 });
  235 + setFieldsValue({ interval: 1000 });
  236 + dataCompareOpions = [{ label: '固定周期', value: QueryWay.LATEST }];
  237 + updateSchema({
  238 + defaultValue: QueryWay.LATEST,
  239 + field: SchemaFiled.WAY,
  240 + componentProps: {
  241 + options: dataCompareOpions,
  242 + },
  243 + });
  244 + }
  245 + },
  246 + maxLength: 250,
  247 + };
  248 + },
  249 + },
  250 + {
  251 + field: 'cycleType',
  252 + component: 'Select',
  253 + label: '周期',
  254 + required: true,
  255 + colProps: { span: 24 },
  256 + defaultValue: 0,
  257 + componentProps: {
  258 + placeholder: '请选择周期',
  259 + options: [
  260 + { label: '每日', value: 0 },
  261 + { label: '每周', value: 1 },
  262 + { label: '每月', value: 2 },
  263 + ],
  264 + },
  265 + ifShow: ({ values }) => isTiming(values.executeWay),
  266 + },
  267 + {
  268 + field: 'currentCycle',
  269 + component: 'ApiSelect',
  270 + label: '每周',
  271 + required: true,
  272 + colProps: { span: 24 },
  273 + defaultValue: '0 0 0 ? * MON',
  274 + componentProps: {
  275 + placeholder: '请选择周期',
  276 + api: findDictItemByCode,
  277 + params: {
  278 + dictCode: 'every_week',
  279 + },
  280 + labelField: 'itemText',
  281 + valueField: 'itemValue',
  282 + },
  283 + ifShow: ({ values }) => isWeek(values.cycleType),
  284 + },
  285 + {
  286 + field: 'cycleTime',
  287 + component: 'ApiSelect',
  288 + label: '每月',
  289 + required: true,
  290 + colProps: { span: 24 },
  291 + defaultValue: '0 0 0 1 * ? *',
  292 + componentProps: {
  293 + placeholder: '请选择月份',
  294 + api: findDictItemByCode,
  295 + params: {
  296 + dictCode: 'every_month',
  297 + },
  298 + labelField: 'itemText',
  299 + valueField: 'itemValue',
  300 + },
  301 + ifShow: ({ values }) => isMonth(values.cycleType),
  302 + },
  303 + {
  304 + field: 'cronTime',
  305 + component: 'ApiSelect',
  306 + label: '时间',
  307 + required: true,
  308 + colProps: { span: 24 },
  309 + defaultValue: '0 0 0 * * ?',
  310 + componentProps: {
  311 + placeholder: '请选择时间',
  312 + api: findDictItemByCode,
  313 + params: {
  314 + dictCode: 'every_day',
  315 + },
  316 + labelField: 'itemText',
  317 + valueField: 'itemValue',
  318 + },
  319 + ifShow: ({ values }) => isTiming(values.executeWay),
  320 + },
  321 + {
  322 + field: 'devices',
  323 + label: '设备',
  324 + component: 'Select',
  325 + slot: 'devices',
  326 + colProps: { span: 24 },
  327 + },
  328 + {
  329 + field: 'dataType',
  330 + label: '数据类型',
  331 + required: true,
  332 + component: 'Select',
  333 + componentProps: ({ formActionType }) => {
  334 + const { updateSchema, setFieldsValue } = formActionType;
  335 + const options = [
  336 + { label: '原始数据', value: 0 },
  337 + { label: '聚合数据', value: 1 },
  338 + ];
  339 + return {
  340 + options,
  341 + onSelect(e) {
  342 + let dataCompareOpions: any = [];
  343 + if (e == 0) {
  344 + setFieldsValue({ agg: 'NONE' });
  345 + dataCompareOpions = [{ label: '空', value: AggregateDataEnum.NONE }];
  346 + updateSchema({
  347 + field: SchemaFiled.AGG,
  348 + componentProps: {
  349 + options: dataCompareOpions,
  350 + },
  351 + });
  352 + } else {
  353 + setFieldsValue({ agg: '' });
  354 + dataCompareOpions = [
  355 + { label: '最小值', value: AggregateDataEnum.MIN },
  356 + { label: '最大值', value: AggregateDataEnum.MAX },
  357 + { label: '平均值', value: AggregateDataEnum.AVG },
  358 + { label: '求和', value: AggregateDataEnum.SUM },
  359 + { label: '计数', value: AggregateDataEnum.COUNT },
  360 + ];
  361 + updateSchema({
  362 + field: SchemaFiled.AGG,
  363 + componentProps: {
  364 + options: dataCompareOpions,
  365 + },
  366 + });
  367 + }
  368 + },
  369 + maxLength: 250,
  370 + placeholder: '请选择属性性质',
  371 + };
  372 + },
  373 + colProps: { span: 24 },
  374 + },
  375 + {
  376 + field: SchemaFiled.AGG,
  377 + label: '聚合条件',
  378 + component: 'Select',
  379 + required: true,
  380 + componentProps: {
  381 + placeholder: '请选择聚合条件',
  382 + getPopupContainer: () => document.body,
  383 + },
  384 + },
  385 + {
  386 + field: 'limit',
  387 + required: true,
  388 + label: '最大条数',
  389 + component: 'InputNumber',
  390 + defaultValue: 100,
  391 + ifShow({ values }) {
  392 + return values[SchemaFiled.AGG] === AggregateDataEnum.NONE;
  393 + },
  394 + colProps: { span: 12 },
  395 + componentProps: {
  396 + placeholder: '请输入最大条数',
  397 + min: 7,
  398 + max: 50000,
  399 + },
  400 + },
  401 + {
  402 + field: SchemaFiled.WAY,
  403 + label: '查询周期',
  404 + component: 'RadioGroup',
  405 + defaultValue: QueryWay.LATEST,
  406 + required: true,
  407 + componentProps({ formActionType }) {
  408 + const { setFieldsValue } = formActionType;
  409 + return {
  410 + placeholder: '请选择查询周期',
  411 + options: [
  412 + { label: '固定周期', value: QueryWay.LATEST },
  413 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  414 + ],
  415 + onChange(value) {
  416 + console.log(value);
  417 + value === QueryWay.LATEST
  418 + ? setFieldsValue({
  419 + [SchemaFiled.DATE_RANGE]: [],
  420 + [SchemaFiled.START_TS]: null,
  421 + [SchemaFiled.END_TS]: null,
  422 + })
  423 + : setFieldsValue({ [SchemaFiled.START_TS]: null });
  424 + },
  425 + };
  426 + },
  427 + },
  428 + {
  429 + field: SchemaFiled.DATE_RANGE,
  430 + label: '时间段',
  431 + component: 'RangePicker',
  432 + required: true,
  433 + ifShow({ values }) {
  434 + return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay);
  435 + },
  436 + componentProps: {
  437 + showTime: {
  438 + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  439 + },
  440 + },
  441 + colProps: {
  442 + span: 10,
  443 + },
  444 + },
  445 + {
  446 + field: SchemaFiled.START_TS,
  447 + label: '最近时间',
  448 + component: 'Select',
  449 + required: true,
  450 + ifShow({ values }) {
  451 + return values[SchemaFiled.WAY] == QueryWay.LATEST;
  452 + },
  453 + componentProps({ formActionType }) {
  454 + const { setFieldsValue } = formActionType;
  455 + return {
  456 + defaultValue: 1000,
  457 + placeholder: '请选择近期时间',
  458 + options: intervalOption,
  459 + onChange() {
  460 + setFieldsValue({ [SchemaFiled.INTERVAL]: null });
  461 + },
  462 + };
  463 + },
  464 + },
  465 + {
  466 + field: SchemaFiled.INTERVAL,
  467 + label: '间隔时间',
  468 + component: 'Select',
  469 + required: true,
  470 + ifShow({ values }) {
  471 + return values[SchemaFiled.WAY] == QueryWay.LATEST;
  472 + },
  473 + componentProps({ formModel, formActionType }) {
  474 + const options =
  475 + formModel[SchemaFiled.WAY] === QueryWay.LATEST
  476 + ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS])
  477 + : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]);
  478 + if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) {
  479 + formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null });
  480 + }
  481 + return {
  482 + placeholder: '请选择间隔时间',
  483 + options,
  484 + };
  485 + },
  486 + },
  487 +];
... ...
... ... @@ -41,15 +41,21 @@
41 41 import HistoryTrendModal from './components/HistoryTrendModal.vue';
42 42 import trendIcon from '/@/assets/svg/trend.svg';
43 43 import backIcon from '/@/assets/images/back.png';
  44 + import backWhiteIcon from '/@/assets/images/backWhite.png';
44 45 import { useCalcGridLayout } from '../hook/useCalcGridLayout';
45 46 import { FrontComponent } from '../const/const';
46 47 import { useScript } from '/@/hooks/web/useScript';
47 48 import { BAI_DU_MAP_GL_LIB, BAI_DU_MAP_TRACK_ANIMATION } from '/@/utils/fnUtils';
  49 + import { useAppStore } from '/@/store/modules/app';
48 50
49 51 const props = defineProps<{
50 52 value: Recordable;
51 53 }>();
52 54
  55 + const userStore = useAppStore();
  56 +
  57 + const getAceClass = computed((): string => userStore.getDarkMode);
  58 +
53 59 const ROUTE = useRoute();
54 60
55 61 const ROUTER = useRouter();
... ... @@ -383,7 +389,7 @@
383 389 <template #title>
384 390 <div class="flex items-center">
385 391 <img
386   - :src="backIcon"
  392 + :src="getAceClass === 'dark' ? backWhiteIcon : backIcon"
387 393 v-if="!getIsSharePage"
388 394 class="mr-3 cursor-pointer"
389 395 @click="handleBack"
... ...