Commit b042fdeb59f1bf37d90b970654831f9eae5460bf

Authored by sqy
1 parent 656b64d2

'修改主题色,调整页面菜单文件名称'

Too many changes to show.

To preserve performance only 24 of 53 files are displayed.

1 1 import { generate } from '@ant-design/colors';
2 2
3   -export const primaryColor = '#0960bd';
  3 +export const primaryColor = '#377DFF';
4 4
5 5 export const darkMode = 'light';
6 6
... ...
... ... @@ -10,21 +10,21 @@ export default {
10 10 status: 'status',
11 11 },
12 12 notice: {
13   - webSiteNotice: 'web site notice',
  13 + webSiteNotice: 'platform notice',
14 14 noticeManagement: 'notice management',
15 15 myNotice: 'my notice',
16 16 },
17 17
18 18 device: {
19 19 deviceManagement: 'device management',
20   - device: 'device',
  20 + device: 'device management',
21 21 deviceProfile: 'device profile',
22 22 },
23 23 tenant: {
24 24 tenant: 'tenant',
25 25 tenantManagement: 'tenant management',
26 26 tenantSetting: 'tenant config',
27   - tenantOEM: 'OEM customization',
  27 + tenantOEM: 'platform customization',
28 28 tenantRule: 'tenant rule',
29 29 },
30 30
... ... @@ -49,23 +49,9 @@ export default {
49 49 alarmManagement: 'alarm management',
50 50 geographicPosition: 'geographic position',
51 51 alarmContact: 'alarm contact',
52   - alarmCenter: 'alarm center',
  52 + alarmCenter: 'alarm record',
53 53 },
54 54
55   - dept: {
56   - queryDeptName: 'dept name',
57   - queryDeptStatus: 'status',
58   - toolDeptList: 'dept list',
59   - toolCreateDept: 'create dept',
60   - toolEditDept: 'edit dept',
61   - tableTitleDeptSort: 'sort',
62   - tableTitleDeptCreateTime: 'create time',
63   - tableTitleDeptOperation: 'operation',
64   - drawerTitleDeptEnable: 'enable',
65   - drawerTitleDeptDisable: 'disable',
66   - drawerTitleDeptParentDept: 'parent dept',
67   - tableTitleMemo: 'memo',
68   - },
69 55 system: {
70 56 system: 'system',
71 57 accountManagement: 'account management',
... ...
... ... @@ -10,13 +10,13 @@ export default {
10 10 status: '状态',
11 11 },
12 12 notice: {
13   - webSiteNotice: '站内通知',
  13 + webSiteNotice: '平台通知',
14 14 noticeManagement: '通知管理',
15 15 myNotice: '我的通知',
16 16 },
17 17 device: {
18 18 deviceManagement: '设备管理',
19   - device: '设备',
  19 + device: '设备管理',
20 20 deviceProfile: '设备配置',
21 21 },
22 22
... ... @@ -24,7 +24,7 @@ export default {
24 24 tenant: '租户',
25 25 tenantManagement: '租户管理',
26 26 tenantSetting: '租户配置',
27   - tenantOEM: 'OEM定制',
  27 + tenantOEM: '平台定制',
28 28 tenantRule: '租户角色',
29 29 },
30 30 organization: {
... ... @@ -34,20 +34,7 @@ export default {
34 34 toolEditOrganization: '编辑组织',
35 35 parentOrganization: '上级组织',
36 36 },
37   - dept: {
38   - queryDeptName: '部门名称',
39   - queryDeptStatus: '状态',
40   - toolDeptList: '部门列表',
41   - toolCreateDept: '新增部门',
42   - toolEditDept: '编辑部门',
43   - tableTitleDeptSort: '排序',
44   - tableTitleDeptCreateTime: '创建时间',
45   - tableTitleDeptOperation: '操作',
46   - drawerTitleDeptEnable: '启用',
47   - drawerTitleDeptDisable: '停用',
48   - drawerTitleDeptParentDept: '上级部门',
49   - tableTitleMemo: '备注',
50   - },
  37 +
51 38 RuleEngine: {
52 39 ruleEngine: '规则引擎',
53 40 sceneLinkage: '场景联动',
... ... @@ -62,7 +49,7 @@ export default {
62 49 alarmManagement: '告警管理',
63 50 geographicPosition: '地理位置',
64 51 alarmContact: '告警联系人',
65   - alarmCenter: '告警中心',
  52 + alarmCenter: '告警记录',
66 53 },
67 54 system: {
68 55 system: '系统管理',
... ...
... ... @@ -78,7 +78,7 @@ const setting: ProjectConfig = {
78 78 // Menu configuration
79 79 menuSetting: {
80 80 // sidebar menu bg color
81   - bgColor: SIDE_BAR_BG_COLOR_LIST[0],
  81 + bgColor: SIDE_BAR_BG_COLOR_LIST[3],
82 82 // Whether to fix the left menu
83 83 fixed: true,
84 84 // Menu collapse
... ...
1   -import { alarmLevel, statusType } from '/@/views/device/manage/config/detail.config';
2   -import { FormSchema } from '/@/components/Form';
3   -import { BasicColumn } from '/@/components/Table';
4   -import moment from 'moment';
5   -export const alarmSearchSchemas: FormSchema[] = [
6   - {
7   - field: 'status',
8   - label: '告警状态',
9   - component: 'Select',
10   - colProps: { span: 6 },
11   - componentProps: {
12   - options: [
13   - {
14   - label: '清除未确认',
15   - value: 'CLEARED_UNACK',
16   - },
17   - {
18   - label: '激活未确认',
19   - value: 'ACTIVE_UNACK',
20   - },
21   - {
22   - label: '清除已确认',
23   - value: 'CLEARED_ACK',
24   - },
25   - {
26   - label: '激活已确认',
27   - value: 'ACTIVE_ACK',
28   - },
29   - ],
30   - },
31   - },
32   - {
33   - field: 'alarmType',
34   - label: '告警类型',
35   - component: 'Input',
36   - colProps: { span: 6 },
37   - componentProps: {
38   - maxLength: 255,
39   - placeholder: '请输入告警类型',
40   - },
41   - dynamicRules: () => {
42   - return [
43   - {
44   - required: false,
45   - validator: (_, value) => {
46   - if (String(value).length > 255) {
47   - return Promise.reject('字数不超过255个字');
48   - }
49   - return Promise.resolve();
50   - },
51   - },
52   - ];
53   - },
54   - },
55   - {
56   - field: 'endTime',
57   - label: '告警时间',
58   - component: 'DatePicker',
59   - componentProps: {
60   - valueFormat: 'x',
61   - showTime: { defaultValue: moment('23:59:59', 'HH:mm:ss') },
62   - },
63   - colProps: { span: 6 },
64   - },
65   -];
66   -export const alarmColumns: BasicColumn[] = [
67   - {
68   - title: '告警时间',
69   - dataIndex: 'createdTime',
70   - width: 120,
71   - },
72   - {
73   - title: '告警设备',
74   - dataIndex: 'deviceName',
75   - width: 100,
76   - },
77   - {
78   - title: '类型',
79   - dataIndex: 'type',
80   - width: 160,
81   - },
82   - {
83   - title: '告警级别',
84   - dataIndex: 'severity',
85   - width: 160,
86   - format: (text) => alarmLevel(text),
87   - },
88   - {
89   - title: '状态',
90   - dataIndex: 'status',
91   - format: (text) => statusType(text),
92   - width: 160,
93   - },
94   -];
95   -
96   -export const alarmSchemasForm: FormSchema[] = [
97   - {
98   - field: 'deviceName',
99   - label: '告警设备',
100   - component: 'Input',
101   - componentProps: {
102   - disabled: true,
103   - },
104   - },
105   -
106   - {
107   - field: 'startTs',
108   - label: '开始时间',
109   - component: 'Input',
110   - componentProps: {
111   - disabled: true,
112   - },
113   - },
114   - {
115   - field: 'endTs',
116   - label: '结束时间',
117   - component: 'Input',
118   - componentProps: {
119   - disabled: true,
120   - },
121   - },
122   - {
123   - field: 'ackTs',
124   - label: '处理时间',
125   - component: 'Input',
126   - componentProps: {
127   - disabled: true,
128   - },
129   - ifShow: ({ values }) => values.status === '激活已确认' || values.status === '清除已确认',
130   - },
131   - {
132   - field: 'clearTs',
133   - label: '清除时间',
134   - component: 'Input',
135   - componentProps: {
136   - disabled: true,
137   - },
138   - ifShow: ({ values }) => values.status === '清除已确认' || values.status === '清除未确认',
139   - },
140   - {
141   - field: 'type',
142   - label: '告警类型',
143   - component: 'Input',
144   - componentProps: {
145   - disabled: true,
146   - },
147   - },
148   - {
149   - field: 'severity',
150   - label: '严重程度',
151   - component: 'Input',
152   - componentProps: {
153   - disabled: true,
154   - },
155   - },
156   - {
157   - field: 'status',
158   - label: '状态',
159   - component: 'Input',
160   - componentProps: {
161   - disabled: true,
162   - },
163   - },
164   - {
165   - field: 'details',
166   - label: '详情',
167   - component: 'InputTextArea',
168   - },
169   -];
1   -<template>
2   - <BasicDrawer v-bind="$attrs" title="告警详情" @register="registerDrawer" width="30%">
3   - <BasicForm @register="registerForm" />
4   - <div class="flex justify-end">
5   - <a-button
6   - type="primary"
7   - class="mr-4"
8   - @click="handleAlarm"
9   - v-if="alarmStatus !== 'ACTIVE_ACK' && alarmStatus !== 'CLEARED_ACK'"
10   - >处理</a-button
11   - >
12   - <a-button
13   - danger
14   - type="primary"
15   - @click="clearAlarm"
16   - v-if="alarmStatus !== 'CLEARED_UNACK' && alarmStatus !== 'CLEARED_ACK'"
17   - >清除</a-button
18   - >
19   - </div>
20   - </BasicDrawer>
21   -</template>
22   -
23   -<script lang="ts">
24   - import { defineComponent, ref, unref } from 'vue';
25   - import { BasicForm, useForm } from '/@/components/Form';
26   - import { alarmSchemasForm } from '../config/detail.config';
27   - import { clearOrAckAlarm } from '/@/api/device/deviceManager';
28   - import { alarmLevel, statusType } from '/@/views/device/manage/config/detail.config';
29   - import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
30   - export default defineComponent({
31   - name: 'AlarmDetailDrawer',
32   - components: {
33   - BasicForm,
34   - BasicDrawer,
35   - },
36   - emits: ['success', 'register'],
37   - setup(_, { emit }) {
38   - const [registerForm, { setFieldsValue, resetFields }] = useForm({
39   - showActionButtonGroup: false,
40   - schemas: alarmSchemasForm,
41   - labelCol: {
42   - span: 5,
43   - },
44   - });
45   - const alarmId = ref('');
46   - const alarmStatus = ref('');
47   - const [registerDrawer, { closeDrawer }] = useDrawerInner(async (data) => {
48   - await resetFields();
49   - await setFieldsValue({
50   - ...data,
51   - severity: alarmLevel(data.severity),
52   - status: statusType(data.status),
53   - });
54   - alarmStatus.value = data.status;
55   - alarmId.value = data.id;
56   - });
57   - // 处理报警
58   - const handleAlarm = async () => {
59   - await clearOrAckAlarm(unref(alarmId), false);
60   - emit('success');
61   - closeDrawer();
62   - };
63   - // 清除报警
64   - const clearAlarm = async () => {
65   - await clearOrAckAlarm(unref(alarmId), true);
66   - emit('success');
67   - closeDrawer();
68   - };
69   - return {
70   - registerDrawer,
71   - registerForm,
72   - clearAlarm,
73   - handleAlarm,
74   - alarmStatus,
75   - };
76   - },
77   - });
78   -</script>
79   -
80   -<style lang="less" scoped></style>
1   -<template>
2   - <div>
3   - <BasicTable @register="registerTable">
4   - <template #action="{ record }">
5   - <TableAction
6   - :actions="[
7   - {
8   - label: '详情',
9   - icon: 'ant-design:eye-outlined',
10   - onClick: handleDetail.bind(null, record),
11   - },
12   - ]"
13   - />
14   - </template>
15   - </BasicTable>
16   - <AlarmDetailDrawer @register="registerDetailDrawer" @success="handleSuccess" />
17   - </div>
18   -</template>
19   -<script lang="ts">
20   - import { defineComponent } from 'vue';
21   - import { BasicTable, useTable, TableAction } from '/@/components/Table';
22   - import { alarmColumns, alarmSearchSchemas } from './config/detail.config';
23   - import { getDeviceAlarm } from '/@/api/device/deviceManager';
24   - import { useDrawer } from '/@/components/Drawer';
25   - import AlarmDetailDrawer from './cpns/AlarmDetailDrawer.vue';
26   -
27   - export default defineComponent({
28   - name: 'AlarmCenter',
29   - components: {
30   - BasicTable,
31   - TableAction,
32   - AlarmDetailDrawer,
33   - },
34   -
35   - setup() {
36   - const [registerTable, { reload }] = useTable({
37   - api: getDeviceAlarm,
38   - columns: alarmColumns,
39   - formConfig: {
40   - labelWidth: 120,
41   - schemas: alarmSearchSchemas,
42   - },
43   - useSearchForm: true,
44   - bordered: true,
45   - showIndexColumn: false,
46   - showTableSetting: true,
47   - actionColumn: {
48   - width: 200,
49   - title: '操作',
50   - slots: { customRender: 'action' },
51   - fixed: 'right',
52   - },
53   - beforeFetch: (data) => {
54   - Reflect.set(data, 'startTime', null);
55   - },
56   - });
57   - const [registerDetailDrawer, { openDrawer }] = useDrawer();
58   - const handleDetail = (record: Recordable) => {
59   - openDrawer(true, record);
60   - };
61   - const handleSuccess = () => {
62   - reload();
63   - };
64   - return {
65   - registerTable,
66   - registerDetailDrawer,
67   - handleDetail,
68   - handleSuccess,
69   - };
70   - },
71   - });
72   -</script>
1   -import type { BasicColumn } from '/@/components/Table';
2   -import type { FormSchema } from '/@/components/Table';
3   -import { getOrganizationList } from '/@/api/system/system';
4   -import { copyTransFun } from '/@/utils/fnUtils';
5   -import { getDeviceProfile } from '/@/api/alarm/position';
6   -
7   -export enum AggregateDataEnum {
8   - MIN = 'MIN',
9   - MAX = 'MAX',
10   - AVG = 'AVG',
11   - SUM = 'SUM',
12   - COUNT = 'COUNT',
13   - NONE = 'NONE',
14   -}
15   -export const formSchema: FormSchema[] = [
16   - {
17   - field: 'organizationId',
18   - label: '',
19   - component: 'ApiTreeSelect',
20   - componentProps: {
21   - placeholder: '请选择组织',
22   - api: async () => {
23   - const data = await getOrganizationList();
24   - copyTransFun(data as any as any[]);
25   - return data;
26   - },
27   - },
28   - },
29   - {
30   - field: 'profileId',
31   - label: '',
32   - component: 'ApiSelect',
33   - componentProps: {
34   - api: getDeviceProfile,
35   - placeholder: '请选择设备配置',
36   - labelField: 'name',
37   - valueField: 'id',
38   - },
39   - },
40   - {
41   - field: 'name',
42   - label: '',
43   - component: 'Input',
44   - componentProps: {
45   - maxLength: 255,
46   - placeholder: '请输入设备名称',
47   - },
48   - },
49   - {
50   - field: 'deviceState',
51   - label: '',
52   - component: 'RadioGroup',
53   - componentProps: {
54   - size: 'small',
55   - options: [
56   - { label: '全部', value: '' },
57   - { label: '待激活', value: 'INACTIVE' },
58   - { label: '在线', value: 'ONLINE' },
59   - { label: '离线', value: 'OFFLINE' },
60   - ],
61   - },
62   - },
63   - {
64   - field: 'alarmStatus',
65   - label: '是否告警',
66   - component: 'RadioGroup',
67   - labelWidth: '85px',
68   - componentProps: {
69   - size: 'small',
70   - options: [
71   - { label: '是', value: '1' },
72   - { label: '否', value: '0' },
73   - ],
74   - },
75   - },
76   -];
77   -
78   -export const columns: BasicColumn[] = [
79   - {
80   - title: '名称',
81   - dataIndex: 'name',
82   - width: 100,
83   - },
84   - {
85   - title: '位置',
86   - dataIndex: 'deviceInfo.address',
87   - width: 100,
88   - },
89   - {
90   - title: '状态',
91   - dataIndex: 'deviceState',
92   - width: 100,
93   - slots: { customRender: 'deviceState' },
94   - },
95   -];
96   -
97   -// 动态生成options
98   -function generateOptions(value: number) {
99   - if (value === 3600000) {
100   - return [
101   - {
102   - label: '10秒',
103   - value: 10000,
104   - },
105   - {
106   - label: '15秒',
107   - value: 15000,
108   - },
109   - {
110   - label: '30秒',
111   - value: 30000,
112   - },
113   - {
114   - label: '1分钟',
115   - value: 60000,
116   - },
117   - {
118   - label: '2分钟',
119   - value: 120000,
120   - },
121   - {
122   - label: '5分钟',
123   - value: 300000,
124   - },
125   - ];
126   - } else if (value === 7200000) {
127   - return [
128   - {
129   - label: '15秒',
130   - value: 15000,
131   - },
132   - {
133   - label: '30秒',
134   - value: 30000,
135   - },
136   - {
137   - label: '1分钟',
138   - value: 60000,
139   - },
140   - {
141   - label: '2分钟',
142   - value: 120000,
143   - },
144   - {
145   - label: '5分钟',
146   - value: 300000,
147   - },
148   - {
149   - label: '10分钟',
150   - value: 600000,
151   - },
152   - {
153   - label: '15分钟',
154   - value: 900000,
155   - },
156   - ];
157   - } else if (value === 18000000) {
158   - return [
159   - {
160   - label: '1分钟',
161   - value: 60000,
162   - },
163   - {
164   - label: '2分钟',
165   - value: 120000,
166   - },
167   - {
168   - label: '5分钟',
169   - value: 300000,
170   - },
171   - {
172   - label: '10分钟',
173   - value: 600000,
174   - },
175   - {
176   - label: '15分钟',
177   - value: 900000,
178   - },
179   - {
180   - label: '30分钟',
181   - value: 1800000,
182   - },
183   - ];
184   - } else if (value === 36000000) {
185   - return [
186   - {
187   - label: '2分钟',
188   - value: 120000,
189   - },
190   - {
191   - label: '5分钟',
192   - value: 300000,
193   - },
194   - {
195   - label: '10分钟',
196   - value: 600000,
197   - },
198   - {
199   - label: '15分钟',
200   - value: 900000,
201   - },
202   - {
203   - label: '30分钟',
204   - value: 1800000,
205   - },
206   - {
207   - label: '1小时',
208   - value: 3600000,
209   - },
210   - ];
211   - } else if (value === 43200000) {
212   - return [
213   - {
214   - label: '2分钟',
215   - value: 120000,
216   - },
217   - {
218   - label: '5分钟',
219   - value: 300000,
220   - },
221   - {
222   - label: '10分钟',
223   - value: 600000,
224   - },
225   - {
226   - label: '15分钟',
227   - value: 900000,
228   - },
229   - {
230   - label: '30分钟',
231   - value: 1800000,
232   - },
233   - {
234   - label: '1小时',
235   - value: 3600000,
236   - },
237   - ];
238   - } else if (value === 86400000) {
239   - return [
240   - {
241   - label: '5分钟',
242   - value: 300000,
243   - },
244   - {
245   - label: '10分钟',
246   - value: 600000,
247   - },
248   - {
249   - label: '15分钟',
250   - value: 900000,
251   - },
252   - {
253   - label: '30分钟',
254   - value: 1800000,
255   - },
256   - {
257   - label: '1小时',
258   - value: 3600000,
259   - },
260   - {
261   - label: '2小时',
262   - value: 7200000,
263   - },
264   - ];
265   - } else if (value === 604800000) {
266   - return [
267   - {
268   - label: '30分钟',
269   - value: 1800000,
270   - },
271   - {
272   - label: '1小时',
273   - value: 3600000,
274   - },
275   - {
276   - label: '2小时',
277   - value: 7200000,
278   - },
279   - {
280   - label: '5小时',
281   - value: 18000000,
282   - },
283   - {
284   - label: '10小时',
285   - value: 36000000,
286   - },
287   - {
288   - label: '12小时',
289   - value: 43200000,
290   - },
291   - {
292   - label: '1天',
293   - value: 86400000,
294   - },
295   - ];
296   - } else {
297   - return [
298   - {
299   - label: '2小时',
300   - value: 7200000,
301   - },
302   - {
303   - label: '5小时',
304   - value: 18000000,
305   - },
306   - {
307   - label: '10小时',
308   - value: 36000000,
309   - },
310   - {
311   - label: '12小时',
312   - value: 43200000,
313   - },
314   - {
315   - label: '1天',
316   - value: 86400000,
317   - },
318   - ];
319   - }
320   -}
321   -export const schemas: FormSchema[] = [
322   - {
323   - field: 'endTs',
324   - label: '最后数据',
325   - component: 'Select',
326   - required: true,
327   - componentProps({ formModel, formActionType }) {
328   - return {
329   - onChange(value) {
330   - const { updateSchema } = formActionType;
331   - console.log(value);
332   - formModel.interval = '';
333   - updateSchema({
334   - field: 'interval',
335   - componentProps: {
336   - placeholder: '请选择分组间隔',
337   - options: generateOptions(value),
338   - },
339   - });
340   - },
341   - getPopupContainer: () => document.body,
342   - options: [
343   - {
344   - label: '最近1小时',
345   - value: 3600000,
346   - },
347   - {
348   - label: '最近2小时',
349   - value: 7200000,
350   - },
351   - {
352   - label: '最近5小时',
353   - value: 18000000,
354   - },
355   - {
356   - label: '最近10小时',
357   - value: 36000000,
358   - },
359   - {
360   - label: '最近12小时',
361   - value: 43200000,
362   - },
363   - {
364   - label: '最近1天',
365   - value: 86400000,
366   - },
367   - {
368   - label: '最近7天',
369   - value: 604800000,
370   - },
371   - {
372   - label: '最近30天',
373   - value: 2592000000,
374   - },
375   - ],
376   - };
377   - },
378   - colProps: {
379   - span: 6,
380   - },
381   - },
382   - {
383   - field: 'interval',
384   - label: '分组间隔',
385   - component: 'Select',
386   - colProps: {
387   - span: 6,
388   - },
389   - componentProps: {
390   - placeholder: '请选择分组间隔',
391   - getPopupContainer: () => document.body,
392   - options: [
393   - {
394   - label: '5分钟',
395   - value: 300000,
396   - },
397   - {
398   - label: '10分钟',
399   - value: 600000,
400   - },
401   - {
402   - label: '15分钟',
403   - value: 900000,
404   - },
405   - {
406   - label: '30分钟',
407   - value: 1800000,
408   - },
409   - {
410   - label: '1小时',
411   - value: 3600000,
412   - },
413   - {
414   - label: '2小时',
415   - value: 7200000,
416   - },
417   - ],
418   - },
419   - },
420   - {
421   - field: 'agg',
422   - label: '数据聚合功能',
423   - component: 'Select',
424   - componentProps: {
425   - getPopupContainer: () => document.body,
426   - options: [
427   - {
428   - label: '最小值',
429   - value: AggregateDataEnum.MIN,
430   - },
431   - {
432   - label: '最大值',
433   - value: AggregateDataEnum.MAX,
434   - },
435   - {
436   - label: '平均值',
437   - value: AggregateDataEnum.AVG,
438   - },
439   - {
440   - label: '求和',
441   - value: AggregateDataEnum.SUM,
442   - },
443   - ],
444   - },
445   - colProps: {
446   - span: 6,
447   - },
448   - },
449   -];
1   -<template>
2   - <div class="wrapper">
3   - <div ref="wrapRef" :style="{ height, width }"> </div>
4   - <div class="right-wrap">
5   - <BasicTable @register="registerTable" @rowClick="deviceRowClick">
6   - <template #deviceState="{ record }">
7   - <Tag
8   - :color="
9   - record.deviceState == DeviceState.INACTIVE
10   - ? 'warning'
11   - : record.deviceState == DeviceState.ONLINE
12   - ? 'success'
13   - : 'error'
14   - "
15   - class="ml-2"
16   - >
17   - {{
18   - record.deviceState == DeviceState.INACTIVE
19   - ? '待激活'
20   - : record.deviceState == DeviceState.ONLINE
21   - ? '在线'
22   - : '离线'
23   - }}
24   - </Tag>
25   - </template>
26   - </BasicTable>
27   - </div>
28   - <BasicModal
29   - @register="registerModal"
30   - title="历史数据"
31   - width="70%"
32   - :minHeight="400"
33   - :footer="null"
34   - @cancel="cancelHistoryModal"
35   - :canFullscreen="false"
36   - >
37   - <BasicForm @register="registerForm" />
38   - <div v-show="isNull" ref="chartRef" :style="{ height: '600px', width }"></div>
39   - <Empty v-show="!isNull" />
40   - </BasicModal>
41   - <DeviceDetailDrawer @register="registerDetailDrawer" />
42   - </div>
43   -</template>
44   -<script lang="ts">
45   - import { defineComponent, ref, nextTick, unref, onMounted, Ref } from 'vue';
46   - import { useScript } from '/@/hooks/web/useScript';
47   - import { formSchema, columns } from './config.data';
48   - import { BasicTable, useTable } from '/@/components/Table';
49   - import { devicePage } from '/@/api/alarm/contact/alarmContact';
50   - import { Tag, Empty } from 'ant-design-vue';
51   - import { DeviceState } from '/@/api/device/model/deviceModel';
52   - import { BAI_DU_MAP_URL } from '/@/utils/fnUtils';
53   - import { useModal, BasicModal } from '/@/components/Modal';
54   - import { BasicForm, useForm } from '/@/components/Form';
55   - import { schemas } from './config.data';
56   - import { useECharts } from '/@/hooks/web/useECharts';
57   - import {
58   - getDeviceHistoryInfo,
59   - getDeviceDataKeys,
60   - getDeviceActiveTime,
61   - } from '/@/api/alarm/position';
62   - import { useDrawer } from '/@/components/Drawer';
63   - import DeviceDetailDrawer from '/@/views/device/manage/cpns/modal/DeviceDetailDrawer.vue';
64   - import moment from 'moment';
65   - // 导入一些静态图片,避免打包时不能正确解析
66   - import djx from '/@/assets/images/djx.png';
67   - import zx from '/@/assets/images/zx.png';
68   - import lx from '/@/assets/images/lx.png';
69   - import djh from '/@/assets/images/djh.png';
70   - import online from '/@/assets/images/online1.png';
71   - import lx1 from '/@/assets/images/lx1.png';
72   - export default defineComponent({
73   - name: 'BaiduMap',
74   - components: {
75   - BasicTable,
76   - Tag,
77   - Empty,
78   - BasicModal,
79   - BasicForm,
80   - DeviceDetailDrawer,
81   - },
82   - props: {
83   - width: {
84   - type: String,
85   - default: '100%',
86   - },
87   - height: {
88   - type: String,
89   - default: 'calc(100vh - 78px)',
90   - },
91   - },
92   - setup() {
93   - let entityId = '';
94   - let keys = [];
95   - let globalRecord: any = {};
96   - const wrapRef = ref<HTMLDivElement | null>(null);
97   - const chartRef = ref<HTMLDivElement | null>(null);
98   - const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
99   - const isNull = ref(true);
100   - const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
101   - const [registerDetailDrawer, { openDrawer }] = useDrawer();
102   - const [registerModal, { openModal }] = useModal();
103   - const [
104   - registerForm,
105   - { resetFields, getFieldsValue, setFieldsValue, validate, updateSchema },
106   - ] = useForm({
107   - labelWidth: 120,
108   - schemas,
109   - async submitFunc() {
110   - // 表单验证
111   - await validate();
112   - let { endTs, interval, agg } = getFieldsValue();
113   - if (!endTs || !keys.length) return;
114   - // 数据收集
115   - const dataArray: any[] = [];
116   - const startTs = Date.now() - endTs;
117   - endTs = Date.now();
118   - // 发送请求
119   - const res = await getDeviceHistoryInfo({
120   - entityId,
121   - keys: keys.join(),
122   - startTs,
123   - endTs,
124   - interval,
125   - agg,
126   - });
127   - // 判断数据对象是否为空
128   - if (!Object.keys(res).length) {
129   - isNull.value = false;
130   - return;
131   - } else {
132   - isNull.value = true;
133   - }
134   - // 处理数据
135   - for (const key in res) {
136   - for (const item1 of res[key]) {
137   - let { ts, value } = item1;
138   - const time = moment(ts).format('YYYY-MM-DD HH:mm:ss');
139   - value = Number(value).toFixed(2);
140   - dataArray.push([time, value, key]);
141   - }
142   - }
143   - const series: any = keys.map((item) => {
144   - return {
145   - name: item,
146   - type: 'line',
147   - stack: 'Total',
148   - data: dataArray.filter((item1) => item1[2] === item),
149   - };
150   - });
151   - // 设置数据
152   - setOptions({
153   - tooltip: {
154   - trigger: 'axis',
155   - },
156   - legend: {
157   - data: keys,
158   - },
159   - grid: {
160   - left: '3%',
161   - right: '4%',
162   - bottom: '3%',
163   - containLabel: true,
164   - },
165   - dataZoom: [
166   - {
167   - type: 'inside',
168   - start: 0,
169   - end: 50,
170   - },
171   - {
172   - start: 20,
173   - end: 40,
174   - },
175   - ],
176   - xAxis: {
177   - type: 'time',
178   - boundaryGap: false,
179   - },
180   - yAxis: {
181   - type: 'value',
182   - boundaryGap: [0, '100%'],
183   - },
184   - series,
185   - });
186   - },
187   - });
188   - const [registerTable] = useTable({
189   - api: devicePage,
190   - columns,
191   - formConfig: {
192   - schemas: formSchema,
193   - labelAlign: 'left',
194   - },
195   - showIndexColumn: false,
196   - useSearchForm: true,
197   - pagination: {
198   - showSizeChanger: false,
199   - },
200   - });
201   -
202   - async function initMap() {
203   - await toPromise();
204   - await nextTick();
205   - const wrapEl = unref(wrapRef);
206   - const BMap = (window as any).BMap;
207   - if (!wrapEl) return;
208   - const map = new BMap.Map(wrapEl);
209   - const point = new BMap.Point(104.04666605565338, 30.543516387560476);
210   - map.centerAndZoom(point, 15);
211   - map.enableScrollWheelZoom(true);
212   - }
213   - // 点击表格某一行触发
214   - const deviceRowClick = async (record) => {
215   - entityId = record.tbDeviceId;
216   - globalRecord = record;
217   - const BMap = (window as any).BMap;
218   - const wrapEl = unref(wrapRef);
219   - const map = new BMap.Map(wrapEl);
220   - if (record.deviceInfo.address) {
221   - keys = await getDeviceDataKeys(entityId);
222   - const { name, organizationDTO, deviceState, deviceProfile } = record;
223   - const { longitude, latitude, address } = record.deviceInfo;
224   - const point = new BMap.Point(longitude, latitude);
225   - let options = {
226   - width: 300, // 信息窗口宽度
227   - height: 230, // 信息窗口高度
228   - };
229   - map.centerAndZoom(point, 15);
230   - map.enableScrollWheelZoom(true);
231   - // 创建信息窗口对象
232   - const res = await getDeviceActiveTime(entityId);
233   -
234   - let { value: activeStatus, lastUpdateTs } = res[0];
235   - lastUpdateTs = moment(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss');
236   - let infoWindow = new BMap.InfoWindow(
237   - `
238   - <div style="display:flex;justify-content:space-between; margin:20px 0px;">
239   - <div style="font-size:16px;font-weight:bold">${name}</div>
240   - ${
241   - deviceState === 'INACTIVE'
242   - ? `<div style="display:flex;align-items:center"><img style="width:15px;height:15px" src="${djh}">待激活</div>`
243   - : deviceState === 'ONLINE'
244   - ? `<div style="display:flex;align-items:center"><img style="width:15px;height:15px" src="${online}">在线</div>`
245   - : `<div style="display:flex;align-items:center"><img style="width:15px;height:15px" src="${lx1}">离线</div>`
246   - }
247   - </div>
248   - <div>所属组织:${organizationDTO.name}</div>
249   - <div style="margin-top:6px;">接入协议:${deviceProfile.transportType}</div>
250   - <div style="margin-top:6px;">设备位置:${address}</div>
251   - <div style="margin-top:6px;">${activeStatus ? '在' : '离'}线时间:${lastUpdateTs}</div>
252   - <div style="display:flex;justify-content:end; margin-top:10px">
253   - <button onclick="openDeviceInfoDrawer()" style="margin-right:10px;color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">设备信息</button>
254   - <button onclick="openHistoryModal()" style="color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">历史数据</button>
255   - </div>
256   - `,
257   - options
258   - );
259   -
260   - map.openInfoWindow(infoWindow, map.getCenter());
261   - let preMarker = null;
262   -
263   - const rivet = deviceState === 'INACTIVE' ? djx : deviceState === 'ONLINE' ? zx : lx;
264   - let myIcon = new BMap.Icon(rivet, new BMap.Size(20, 30));
265   - let marker = new BMap.Marker(point, { icon: myIcon });
266   - if (marker) {
267   - map.removeOverlay(preMarker);
268   - }
269   - map.addOverlay(marker);
270   - } else {
271   - const point = new BMap.Point(106.63028229687498, 36.06735821600903);
272   - let options = {
273   - width: 100, // 信息窗口宽度
274   - height: 100, // 信息窗口高度
275   - title: '提示', // 信息窗口标题
276   - };
277   - map.centerAndZoom(point, 5);
278   - map.enableScrollWheelZoom(true);
279   - let infoWindow = new BMap.InfoWindow('该设备暂无地理位置', options); // 创建信息窗口对象
280   - map.openInfoWindow(infoWindow, map.getCenter());
281   - }
282   - };
283   -
284   - // 设备信息
285   - const openDeviceInfoDrawer = async () => {
286   - const { id, tbDeviceId } = globalRecord;
287   - openDrawer(true, {
288   - id,
289   - tbDeviceId,
290   - });
291   - };
292   - const openHistoryModal = async () => {
293   - openModal(true);
294   - // 收集参数
295   - const dataArray: any[] = [];
296   - const startTs = Date.now() - 86400000; //最近一天
297   - const endTs = Date.now();
298   - // 发送请求
299   - if (!keys.length) {
300   - isNull.value = false;
301   - return;
302   - } else {
303   - isNull.value = true;
304   - }
305   - const res = await getDeviceHistoryInfo({
306   - entityId,
307   - keys: keys.join(),
308   - startTs,
309   - endTs,
310   - interval: 7200000, //间隔两小时
311   - agg: 'AVG',
312   - });
313   - // 判断对象是否为空
314   - if (!Object.keys(res).length) {
315   - isNull.value = false;
316   - return;
317   - } else {
318   - isNull.value = true;
319   - }
320   - // 处理数据
321   - for (const key in res) {
322   - for (const item1 of res[key]) {
323   - let { ts, value } = item1;
324   - const time = moment(ts).format('YYYY-MM-DD HH:mm:ss');
325   - value = Number(value).toFixed(2);
326   - dataArray.push([time, value, key]);
327   - }
328   - }
329   - const series: any = keys.map((item) => {
330   - return {
331   - name: item,
332   - type: 'line',
333   - stack: 'Total',
334   - data: dataArray.filter((item1) => item1[2] === item),
335   - };
336   - });
337   - console.log(dataArray);
338   - // 设置数据;
339   - setOptions({
340   - tooltip: {
341   - trigger: 'axis',
342   - },
343   - legend: {
344   - data: keys,
345   - },
346   - grid: {
347   - left: '3%',
348   - right: '4%',
349   - bottom: '3%',
350   - containLabel: true,
351   - },
352   - dataZoom: [
353   - {
354   - type: 'inside',
355   - start: 0,
356   - end: 50,
357   - },
358   - {
359   - start: 0,
360   - end: 20,
361   - },
362   - ],
363   - xAxis: {
364   - type: 'time',
365   - boundaryGap: false,
366   - },
367   - yAxis: {
368   - type: 'value',
369   - boundaryGap: [0, '100%'],
370   - },
371   - series,
372   - });
373   - setFieldsValue({
374   - endTs: 86400000,
375   - interval: 7200000,
376   - agg: 'AVG',
377   - });
378   - };
379   - const cancelHistoryModal = () => {
380   - resetFields();
381   - updateSchema({
382   - field: 'interval',
383   - componentProps: {
384   - placeholder: '请选择分组间隔',
385   - options: [
386   - {
387   - label: '5分钟',
388   - value: 300000,
389   - },
390   - {
391   - label: '10分钟',
392   - value: 600000,
393   - },
394   - {
395   - label: '15分钟',
396   - value: 900000,
397   - },
398   - {
399   - label: '30分钟',
400   - value: 1800000,
401   - },
402   - {
403   - label: '1小时',
404   - value: 3600000,
405   - },
406   - {
407   - label: '2小时',
408   - value: 7200000,
409   - },
410   - ],
411   - },
412   - });
413   - setOptions({});
414   - };
415   - onMounted(() => {
416   - initMap();
417   - (window as any).openDeviceInfoDrawer = openDeviceInfoDrawer;
418   - (window as any).openHistoryModal = openHistoryModal;
419   - });
420   - return {
421   - wrapRef,
422   - registerTable,
423   - deviceRowClick,
424   - DeviceState,
425   - registerModal,
426   - registerForm,
427   - chartRef,
428   - isNull,
429   - cancelHistoryModal,
430   - registerDetailDrawer,
431   - };
432   - },
433   - });
434   -</script>
435   -<style scoped>
436   - .wrapper {
437   - position: relative;
438   - }
439   - .right-wrap {
440   - padding-top: 10px;
441   - width: 22%;
442   - height: 95%;
443   - position: absolute;
444   - right: 5%;
445   - top: 3%;
446   - background-color: #fff;
447   - }
448   -</style>
1   -<template>
2   - <BasicDrawer
3   - v-bind="$attrs"
4   - @register="registerDrawer"
5   - showFooter
6   - :title="getTitle"
7   - width="30%"
8   - @ok="handleSubmit"
9   - >
10   - <BasicForm @register="registerForm" />
11   - </BasicDrawer>
12   -</template>
13   -<script lang="ts">
14   - import { defineComponent, ref, computed, unref } from 'vue';
15   - import { BasicForm, useForm } from '/@/components/Form';
16   - import { formSchema } from './config.data';
17   - import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
18   - import { saveOrEditAlarmContact } from '/@/api/alarm/contact/alarmContact';
19   - import { useMessage } from '/@/hooks/web/useMessage';
20   -
21   - export default defineComponent({
22   - name: 'ContactDrawer',
23   - components: { BasicDrawer, BasicForm },
24   - emits: ['success', 'register'],
25   - setup(_, { emit }) {
26   - const isUpdate = ref(true);
27   -
28   - const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({
29   - labelWidth: 120,
30   - schemas: formSchema,
31   - showActionButtonGroup: false,
32   - });
33   -
34   - const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
35   - await resetFields();
36   - setDrawerProps({ confirmLoading: false });
37   - isUpdate.value = !!data?.isUpdate;
38   - if (unref(isUpdate)) {
39   - if (data.record.organizationDTO) {
40   - await setFieldsValue(data.record);
41   - } else {
42   - Reflect.deleteProperty(data.record, 'organizationId');
43   - await setFieldsValue(data.record);
44   - }
45   - }
46   - });
47   -
48   - const getTitle = computed(() => (!unref(isUpdate) ? '新增联系人配置' : '编辑联系人配置'));
49   -
50   - async function handleSubmit() {
51   - try {
52   - const { createMessage } = useMessage();
53   - const values = await validate();
54   - setDrawerProps({ confirmLoading: true });
55   - let saveMessage = '添加成功';
56   - let updateMessage = '修改成功';
57   - await saveOrEditAlarmContact(values, unref(isUpdate));
58   - closeDrawer();
59   - emit('success');
60   - createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);
61   - } finally {
62   - setDrawerProps({ confirmLoading: false });
63   - }
64   - }
65   -
66   - return {
67   - getTitle,
68   - registerDrawer,
69   - registerForm,
70   - handleSubmit,
71   - };
72   - },
73   - });
74   -</script>
1   -import { BasicColumn, FormSchema } from '/@/components/Table';
2   -import { getOrganizationList } from '/@/api/system/system';
3   -import { copyTransFun } from '/@/utils/fnUtils';
4   -import { emailRule, phoneRule } from '/@/utils/rules';
5   -
6   -// 表格列数据
7   -export const columns: BasicColumn[] = [
8   - {
9   - title: '姓名',
10   - dataIndex: 'username',
11   - width: 120,
12   - },
13   - {
14   - title: '所属组织',
15   - dataIndex: 'organizationDTO.name',
16   - width: 160,
17   - },
18   - {
19   - title: '手机',
20   - dataIndex: 'phone',
21   - width: 160,
22   - },
23   - {
24   - title: '邮箱',
25   - dataIndex: 'email',
26   - width: 160,
27   - },
28   - {
29   - title: '微信',
30   - dataIndex: 'wechat',
31   - width: 180,
32   - },
33   - {
34   - title: '备注',
35   - dataIndex: 'remark',
36   - width: 120,
37   - },
38   -
39   - {
40   - title: '添加时间',
41   - dataIndex: 'createTime',
42   - width: 180,
43   - },
44   - {
45   - title: '更新时间',
46   - dataIndex: 'updateTime',
47   - width: 180,
48   - },
49   -];
50   -
51   -// 查询字段
52   -export const searchFormSchema: FormSchema[] = [
53   - {
54   - field: 'username',
55   - label: '联系人姓名',
56   - component: 'Input',
57   - colProps: { span: 8 },
58   - componentProps: {
59   - maxLength: 36,
60   - placeholder: '请输入联系人姓名',
61   - },
62   - },
63   -];
64   -
65   -// 弹框配置项
66   -export const formSchema: FormSchema[] = [
67   - {
68   - field: 'username',
69   - label: '联系人姓名',
70   - required: true,
71   - component: 'Input',
72   - componentProps: {
73   - placeholder: '请输入联系人姓名',
74   - maxLength: 255,
75   - },
76   - },
77   - {
78   - field: 'organizationId',
79   - label: '所属组织',
80   - component: 'ApiTreeSelect',
81   - componentProps: {
82   - api: async () => {
83   - const data = await getOrganizationList();
84   - copyTransFun(data as any as any[]);
85   - return data;
86   - },
87   - },
88   - },
89   - {
90   - field: 'phone',
91   - label: '手机号码',
92   - component: 'Input',
93   - componentProps: {
94   - placeholder: '请输入手机号码',
95   - },
96   - rules: phoneRule,
97   - },
98   - {
99   - field: 'email',
100   - label: '电子邮箱',
101   - component: 'Input',
102   - componentProps: {
103   - placeholder: '请输入电子邮箱',
104   - },
105   - rules: emailRule,
106   - },
107   - {
108   - field: 'wechat',
109   - label: '微信',
110   - component: 'Input',
111   - componentProps: {
112   - placeholder: '请输入微信号',
113   - maxLength: 255,
114   - },
115   - },
116   - {
117   - field: 'remark',
118   - label: '备注',
119   - component: 'InputTextArea',
120   - componentProps: {
121   - placeholder: '请输入备注',
122   - maxLength: 255,
123   - },
124   - },
125   - {
126   - field: 'id',
127   - label: '',
128   - component: 'Input',
129   - show: false,
130   - componentProps: {
131   - maxLength: 36,
132   - placeholder: 'id',
133   - },
134   - },
135   -];
1   -<template>
2   - <div>
3   - <PageWrapper dense contentFullHeight contentClass="flex">
4   - <OrganizationIdTree
5   - class="w-1/4 xl:w-1/5"
6   - @select="handleSelect"
7   - ref="organizationIdTreeRef"
8   - />
9   - <BasicTable @register="registerTable" :searchInfo="searchInfo" class="w-3/4 xl:w-4/5">
10   - <template #toolbar>
11   - <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增告警联系人 </a-button>
12   - <a-button
13   - type="primary"
14   - color="error"
15   - @click="handleDeleteOrBatchDelete(null)"
16   - :disabled="hasBatchDelete"
17   - >
18   - 批量删除
19   - </a-button>
20   - </template>
21   - <template #action="{ record }">
22   - <TableAction
23   - :actions="[
24   - {
25   - label: '编辑',
26   - icon: 'clarity:note-edit-line',
27   - onClick: handleCreateOrEdit.bind(null, record),
28   - },
29   - {
30   - label: '删除',
31   - icon: 'ant-design:delete-outlined',
32   - color: 'error',
33   - popConfirm: {
34   - title: '是否确认删除',
35   - confirm: handleDeleteOrBatchDelete.bind(null, record),
36   - },
37   - },
38   - ]"
39   - />
40   - </template>
41   - </BasicTable>
42   - </PageWrapper>
43   - <ContactDrawer @register="registerDrawer" @success="handleSuccess" />
44   - </div>
45   -</template>
46   -
47   -<script lang="ts">
48   - import { defineComponent, reactive, ref, computed } from 'vue';
49   - import { BasicTable, useTable, TableAction } from '/@/components/Table';
50   - import { PageWrapper } from '/@/components/Page';
51   - import { useMessage } from '/@/hooks/web/useMessage';
52   - import { useDrawer } from '/@/components/Drawer';
53   - import ContactDrawer from './ContactDrawer.vue';
54   - import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
55   -
56   - import { getAlarmContact, deleteAlarmContact } from '/@/api/alarm/contact/alarmContact';
57   - import { searchFormSchema, columns } from './config.data';
58   - export default defineComponent({
59   - components: {
60   - PageWrapper,
61   - OrganizationIdTree,
62   - BasicTable,
63   - TableAction,
64   - ContactDrawer,
65   - },
66   - setup() {
67   - let selectedRowIds = ref<string[]>([]);
68   - const hasBatchDelete = computed(() => selectedRowIds.value.length <= 0);
69   - // 复选框事件
70   - const onSelectRowChange = (selectedRowKeys: string[]) => {
71   - selectedRowIds.value = selectedRowKeys;
72   - };
73   - const searchInfo = reactive<Recordable>({});
74   - const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
75   - // 表格hooks
76   - const [registerTable, { reload }] = useTable({
77   - api: getAlarmContact,
78   - columns,
79   - clickToRowSelect: false,
80   - formConfig: {
81   - labelWidth: 120,
82   - schemas: searchFormSchema,
83   - resetFunc: resetFn,
84   - },
85   - useSearchForm: true,
86   - showTableSetting: true,
87   - bordered: true,
88   - rowSelection: {
89   - onChange: onSelectRowChange,
90   - type: 'checkbox',
91   - },
92   - rowKey: 'id',
93   - actionColumn: {
94   - width: 200,
95   - title: '操作',
96   - dataIndex: 'action',
97   - slots: { customRender: 'action' },
98   - fixed: 'right',
99   - },
100   - });
101   - // 弹框
102   - const [registerDrawer, { openDrawer }] = useDrawer();
103   - const { createMessage } = useMessage();
104   -
105   - // 刷新
106   - const handleSuccess = () => {
107   - reload();
108   - };
109   - // 新增或编辑
110   - const handleCreateOrEdit = (record: Recordable | null) => {
111   - if (record) {
112   - openDrawer(true, {
113   - isUpdate: true,
114   - record,
115   - });
116   - } else {
117   - openDrawer(true, {
118   - isUpdate: false,
119   - });
120   - }
121   - };
122   - // 删除或批量删除
123   - const handleDeleteOrBatchDelete = async (record: Recordable | null) => {
124   - if (record) {
125   - try {
126   - await deleteAlarmContact([record.id]);
127   - createMessage.success('删除联系人成功');
128   - handleSuccess();
129   - } catch (e) {
130   - createMessage.error('删除失败');
131   - }
132   - } else {
133   - try {
134   - await deleteAlarmContact(selectedRowIds.value);
135   - createMessage.success('批量删除联系人成功');
136   - selectedRowIds.value = [];
137   - handleSuccess();
138   - } catch (e) {
139   - createMessage.info('删除失败');
140   - }
141   - }
142   - };
143   -
144   - // 树形选择器
145   - const handleSelect = (organizationId: string) => {
146   - searchInfo.organizationId = organizationId;
147   - handleSuccess();
148   - };
149   - return {
150   - searchInfo,
151   - hasBatchDelete,
152   - handleCreateOrEdit,
153   - handleDeleteOrBatchDelete,
154   - handleSelect,
155   - handleSuccess,
156   - registerTable,
157   - registerDrawer,
158   - organizationIdTreeRef,
159   - };
160   - },
161   - });
162   -</script>
1   -<template>
2   - <div>
3   - <BasicModal
4   - v-bind="$attrs"
5   - @register="registerDrawer"
6   - showFooter
7   - :title="getTitle"
8   - width="1000px"
9   - @ok="handleSubmit"
10   - @cancel="handleCancel"
11   - >
12   - <div class="step-form-form">
13   - <a-steps :current="current">
14   - <a-step title="选择转换方式" />
15   - <a-step title="完善配置参数" />
16   - </a-steps>
17   - </div>
18   - <div>
19   - <div v-show="current === 0">
20   - <TransferConfigMode ref="refTransferConfigMode" @next="handleNext"
21   - /></div>
22   - <div v-show="current === 1">
23   - <TransferConfigParams
24   - ref="refTransferConfigParams"
25   - :getModeSelect="getModeSelectVal"
26   - @prevSon="handlePrev"
27   - /></div>
28   - </div>
29   - </BasicModal>
30   - </div>
31   -</template>
32   -<script lang="ts">
33   - import { defineComponent, reactive, ref, computed, unref, getCurrentInstance } from 'vue';
34   - import { BasicModal, useModalInner } from '/@/components/Modal';
35   - import { Steps } from 'ant-design-vue';
36   - import TransferConfigMode from './cpns/transferConfigMode.vue';
37   - import TransferConfigParams from './cpns/transferConfigParams.vue';
38   - import { postAddConvertApi } from '/@/api/datamanager/dataManagerApi';
39   - import { useMessage } from '/@/hooks/web/useMessage';
40   -
41   - export default defineComponent({
42   - name: 'ConfigDrawer',
43   - components: {
44   - BasicModal,
45   - [Steps.name]: Steps,
46   - [Steps.Step.name]: Steps.Step,
47   - TransferConfigMode,
48   - TransferConfigParams,
49   - },
50   - emits: ['success', 'register'],
51   - setup(_, { emit }) {
52   - const { createMessage } = useMessage();
53   - const { proxy } = getCurrentInstance();
54   - const allPostForm = reactive({});
55   - const getNameObj = reactive({
56   - name: '',
57   - });
58   - const getTypeObj = reactive({
59   - type: '',
60   - remark: '',
61   - });
62   - const additionalInfoV = {
63   - additionalInfo: {
64   - description: '',
65   - },
66   - };
67   - const getSonFormValue = ref({});
68   - const getModeSonFormValue = ref({});
69   - const refTransferConfigParams = ref(null);
70   - const refTransferConfigMode = ref(null);
71   - const getModeSelectVal = ref({});
72   - const isUpdate = ref(true);
73   - const getTitle = computed(() => (!unref(isUpdate) ? '新增转换配置' : '编辑数据转换'));
74   - const current = ref(0);
75   - const editPostId = ref('');
76   - const editType = reactive({
77   - type: '',
78   - configuration: {},
79   - name: '',
80   - });
81   - const editNextType = reactive({
82   - type: '',
83   - configuration: {},
84   - name: '',
85   - remark: '',
86   - });
87   - const editTypeFunc = (d) => {
88   - editType.type = d.type;
89   - editType.configuration = d.configuration;
90   - editType.name = d.name;
91   - };
92   -
93   - const [registerDrawer, { closeModal }] = useModalInner(async (data) => {
94   - isUpdate.value = !!data?.isUpdate;
95   - current.value = 0;
96   - if (unref(isUpdate)) {
97   - editPostId.value = data.record.id;
98   - editNextType.type = data.record.type;
99   - editNextType.configuration = data.record;
100   - editNextType.name = data.record.name;
101   - editNextType.remark = data.record.remark;
102   - proxy.$refs.refTransferConfigMode.setStepOneFieldsValueFunc(editNextType);
103   - }
104   - });
105   - const handleCancel = () => {
106   - defineClearFunc();
107   - };
108   - const defineClearFunc = () => {
109   - try {
110   - proxy.$refs.refTransferConfigMode.customResetStepOneFunc();
111   - proxy.$refs.refTransferConfigParams?.clearSonValueDataFunc();
112   - } catch (e) {
113   - return e;
114   - }
115   - };
116   - const handleNext = (args) => {
117   - current.value++;
118   - getModeSelectVal.value = args;
119   - if (unref(isUpdate)) {
120   - try {
121   - if (editNextType.type == 'org.thingsboard.rule.engine.kafka.TbKafkaNode') {
122   - editTypeFunc(editNextType.configuration);
123   - } else if (editNextType.type == 'org.thingsboard.rule.engine.mqtt.TbMqttNode') {
124   - editTypeFunc(editNextType.configuration);
125   - } else if (editNextType.type == 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode') {
126   - editTypeFunc(editNextType.configuration);
127   - } else if (editNextType.type == 'org.thingsboard.rule.engine.rest.TbRestApiCallNode') {
128   - editTypeFunc(editNextType.configuration);
129   - }
130   - proxy.$refs.refTransferConfigParams.editSonValueDataFunc(editType);
131   - } catch (e) {
132   - return e;
133   - }
134   - }
135   - };
136   - const handlePrev = () => {
137   - current.value--;
138   - };
139   -
140   - const commonFunc = () => {
141   - try {
142   - additionalInfoV.additionalInfo.description =
143   - getSonFormValue.value.configuration.description;
144   - delete getSonFormValue.value.configuration.description;
145   - delete getSonFormValue.value.configuration.type;
146   - delete getSonFormValue.value?.configuration?.name;
147   - } catch (e) {
148   - return e;
149   - }
150   - };
151   - const addOrEditFunc = async () => {
152   - if (!unref(isUpdate)) {
153   - proxy.$refs.refTransferConfigParams.clearSonValueValidateFunc();
154   - }
155   - getModeSonFormValue.value = await proxy.$refs.refTransferConfigMode.getSonValueFunc();
156   - getSonFormValue.value = await proxy.$refs.refTransferConfigParams.getSonValueDataFunc();
157   - if (getModeSonFormValue.value?.type == 'org.thingsboard.rule.engine.kafka.TbKafkaNode') {
158   - getTypeObj.type = 'org.thingsboard.rule.engine.kafka.TbKafkaNode';
159   - getTypeObj.remark = getModeSonFormValue.value.remark;
160   - getNameObj.name = getSonFormValue.value?.configuration?.name;
161   - commonFunc();
162   - } else if (
163   - getModeSonFormValue.value?.type == 'org.thingsboard.rule.engine.mqtt.TbMqttNode'
164   - ) {
165   - getTypeObj.type = 'org.thingsboard.rule.engine.mqtt.TbMqttNode';
166   - getTypeObj.remark = getModeSonFormValue.value.remark;
167   - getNameObj.name = getSonFormValue.value?.configuration?.name;
168   - commonFunc();
169   - } else if (
170   - getModeSonFormValue.value?.type == 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode'
171   - ) {
172   - getTypeObj.type = 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode';
173   - getTypeObj.remark = getModeSonFormValue.value.remark;
174   - getNameObj.name = getSonFormValue.value?.configuration?.name;
175   - commonFunc();
176   - } else if (
177   - getModeSonFormValue.value?.type == 'org.thingsboard.rule.engine.rest.TbRestApiCallNode'
178   - ) {
179   - getTypeObj.type = 'org.thingsboard.rule.engine.rest.TbRestApiCallNode';
180   - getTypeObj.remark = getModeSonFormValue.value.remark;
181   - getNameObj.name = getSonFormValue.value?.configuration?.name;
182   - commonFunc();
183   - }
184   - const id: any = {
185   - id: unref(isUpdate) ? editPostId.value : '',
186   - };
187   - Object.assign(
188   - allPostForm,
189   - getTypeObj,
190   - getSonFormValue.value,
191   - getNameObj,
192   - id,
193   - additionalInfoV
194   - );
195   - if (!unref(isUpdate)) {
196   - delete allPostForm.id;
197   - }
198   - };
199   - const handleSubmit = async () => {
200   - if (!unref(isUpdate)) {
201   - await addOrEditFunc();
202   - await postAddConvertApi(allPostForm);
203   - createMessage.success('数据转换新增成功');
204   - emit('success');
205   - defineClearFunc();
206   - closeModal();
207   - } else {
208   - await addOrEditFunc();
209   - await postAddConvertApi(allPostForm);
210   - createMessage.success('数据转换编辑成功');
211   - emit('success');
212   - defineClearFunc();
213   - closeModal();
214   - }
215   - };
216   - return {
217   - handleCancel,
218   - registerDrawer,
219   - handleSubmit,
220   - getTitle,
221   - current,
222   - handleNext,
223   - handlePrev,
224   - getModeSelectVal,
225   - refTransferConfigParams,
226   - refTransferConfigMode,
227   - };
228   - },
229   - });
230   -</script>
1   -import { BasicColumn, FormSchema } from '/@/components/Table';
2   -import { h } from 'vue';
3   -import { Tag } from 'ant-design-vue';
4   -
5   -export const columns: BasicColumn[] = [
6   - {
7   - title: '数据转换名称',
8   - dataIndex: 'name',
9   - width: 200,
10   - },
11   - {
12   - title: '途径',
13   - dataIndex: 'type',
14   - width: 200,
15   - customRender: ({ record }) => {
16   - const status = record.type;
17   - const enable =
18   - status === 'org.thingsboard.rule.engine.kafka.TbKafkaNode'
19   - ? 'KafKa'
20   - : record.type === 'org.thingsboard.rule.engine.mqtt.TbMqttNode'
21   - ? 'MQTT'
22   - : record.type === 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode'
23   - ? 'RabbitMQ'
24   - : 'REST_API';
25   - const color =
26   - enable == 'KafKa'
27   - ? '#0099FF'
28   - : enable == 'MQTT'
29   - ? '#7C7CC9'
30   - : enable == 'RabbitMQ'
31   - ? '#E8A15E'
32   - : '#81B1AB';
33   - const text =
34   - enable == 'KafKa'
35   - ? 'KafKa'
36   - : enable == 'MQTT'
37   - ? 'MQTT'
38   - : enable == 'RabbitMQ'
39   - ? 'RabbitMQ'
40   - : 'REST_API';
41   - return h(Tag, { color: color }, () => text);
42   - },
43   -
44   - format: (_text: string, record: Recordable) => {
45   - return record.type === 'org.thingsboard.rule.engine.kafka.TbKafkaNode'
46   - ? 'KafKa'
47   - : record.type === 'org.thingsboard.rule.engine.mqtt.TbMqttNode'
48   - ? 'MQTT'
49   - : record.type === 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode'
50   - ? 'RabbitMQ'
51   - : 'REST_API';
52   - },
53   - },
54   - {
55   - title: '状态',
56   - dataIndex: 'status',
57   - width: 120,
58   - customRender: ({ record }) => {
59   - const status = record.status;
60   - const enable = ~~status === 1;
61   - const color = enable ? '#2aae67' : '#eb846f';
62   - const text = enable ? '启用' : '禁用';
63   - return h(Tag, { color: color }, () => text);
64   - },
65   - },
66   - {
67   - title: '描述',
68   - dataIndex: 'remark',
69   - width: 200,
70   - },
71   - {
72   - title: '创建时间',
73   - dataIndex: 'createTime',
74   - width: 180,
75   - },
76   -];
77   -
78   -export const searchFormSchema: FormSchema[] = [
79   - {
80   - field: 'name',
81   - label: '名称',
82   - component: 'Input',
83   - colProps: { span: 6 },
84   - componentProps: {
85   - maxLength: 36,
86   - placeholder: '请输入名称',
87   - },
88   - },
89   - {
90   - field: 'status',
91   - label: '状态',
92   - component: 'Select',
93   - componentProps: {
94   - placeholder: '请选择状态',
95   - options: [
96   - { label: '已启用', value: '1' },
97   - { label: '未启用', value: '0' },
98   - ],
99   - },
100   - colProps: { span: 6 },
101   - },
102   -];
1   -import { FormSchema } from '/@/components/Form';
2   -import { findDictItemByCode } from '/@/api/system/dict';
3   -import { isExistDataManagerNameApi } from '/@/api/datamanager/dataManagerApi';
4   -import { ref } from 'vue';
5   -import { useMessage } from '/@/hooks/web/useMessage';
6   -const { createMessage } = useMessage();
7   -
8   -const typeValue = ref('');
9   -
10   -export enum CredentialsEnum {
11   - IS_ANONYMOUS = 'anonymous',
12   - IS_BASIC = 'basic',
13   - IS_PEM = 'pem',
14   -}
15   -
16   -export const isBasic = (type: string) => {
17   - return type === CredentialsEnum.IS_BASIC;
18   -};
19   -export const isPem = (type: string) => {
20   - return type === CredentialsEnum.IS_PEM;
21   -};
22   -
23   -export const modeForm: FormSchema[] = [
24   - {
25   - field: 'type',
26   - label: '转换方式',
27   - component: 'ApiSelect',
28   - required: true,
29   - colProps: {
30   - span: 13,
31   - },
32   - componentProps({}) {
33   - return {
34   - api: findDictItemByCode,
35   - params: {
36   - dictCode: 'convert_data_to',
37   - },
38   - labelField: 'itemText',
39   - valueField: 'itemValue',
40   - onChange(value) {
41   - typeValue.value = value;
42   - },
43   - };
44   - },
45   - },
46   - {
47   - field: 'remark',
48   - label: '描述',
49   - colProps: { span: 13 },
50   - component: 'Input',
51   - componentProps: {
52   - maxLength: 255,
53   - placeholder: '请输入描述',
54   - },
55   - },
56   -];
57   -
58   -export const modeKafkaInseretKeyAndValueForm: FormSchema[] = [
59   - {
60   - field: 'key',
61   - label: 'Key',
62   - colProps: { span: 12 },
63   - required: true,
64   - component: 'Input',
65   - componentProps: {
66   - maxLength: 255,
67   - placeholder: '请输入Key',
68   - },
69   - },
70   - {
71   - field: 'value',
72   - label: 'Value',
73   - colProps: { span: 12 },
74   - required: true,
75   - component: 'Input',
76   - componentProps: {
77   - maxLength: 255,
78   - placeholder: '请输入Value',
79   - },
80   - },
81   -];
82   -
83   -export const modeApiInseretKeyAndValueForm: FormSchema[] = [
84   - {
85   - field: 'key',
86   - label: 'Header',
87   - colProps: { span: 12 },
88   - required: true,
89   - component: 'Input',
90   - componentProps: {
91   - maxLength: 255,
92   - placeholder: '请输入Header',
93   - },
94   - },
95   - {
96   - field: 'value',
97   - label: 'Value',
98   - colProps: { span: 12 },
99   - required: true,
100   - component: 'Input',
101   - componentProps: {
102   - maxLength: 255,
103   - placeholder: '请输入Value',
104   - },
105   - },
106   -];
107   -
108   -export const modeKafkaForm: FormSchema[] = [
109   - {
110   - field: 'name',
111   - label: '名称',
112   - colProps: { span: 12 },
113   - required: true,
114   - component: 'Input',
115   - componentProps: {
116   - maxLength: 255,
117   - placeholder: '请输入名称',
118   - },
119   - dynamicRules: ({ values }) => {
120   - return [
121   - {
122   - required: true,
123   - validator(_, value) {
124   - return new Promise((resolve, reject) => {
125   - if (value == '') {
126   - reject('请输入名称');
127   - } else {
128   - if (values.name != undefined) {
129   - isExistDataManagerNameApi({
130   - name: value,
131   - type:
132   - typeValue.value == ''
133   - ? 'org.thingsboard.rule.engine.kafka.TbKafkaNode'
134   - : typeValue.value,
135   - }).then((data) => {
136   - if (data == true) {
137   - createMessage.error('名称已存在');
138   - resolve();
139   - } else {
140   - resolve();
141   - }
142   - });
143   - } else {
144   - resolve();
145   - }
146   - }
147   - });
148   - },
149   - },
150   - ];
151   - },
152   - },
153   - {
154   - field: 'topicPattern',
155   - label: 'Topic',
156   - colProps: { span: 12 },
157   - required: true,
158   - component: 'Input',
159   - defaultValue: 'my-topic',
160   - componentProps: {
161   - maxLength: 255,
162   - placeholder: '请输入Topic pattern',
163   - },
164   - },
165   - {
166   - field: 'bootstrapServers',
167   - label: 'Bootstrap',
168   - colProps: { span: 12 },
169   - component: 'Input',
170   - defaultValue: 'localhost:9092',
171   - required: true,
172   - componentProps: {
173   - maxLength: 255,
174   - placeholder: 'localhost:9092',
175   - },
176   - },
177   - {
178   - field: 'retries',
179   - label: 'Retries',
180   - colProps: { span: 12 },
181   - component: 'InputNumber',
182   - defaultValue: 0,
183   - componentProps: {
184   - maxLength: 255,
185   - placeholder: '请输入Automatically retry times if fails',
186   - },
187   - },
188   - {
189   - field: 'batchSize',
190   - label: 'BatchSize',
191   - colProps: { span: 12 },
192   - component: 'InputNumber',
193   - defaultValue: 16384,
194   - componentProps: {
195   - maxLength: 255,
196   - placeholder: '请输入Produces batch size in bytes',
197   - },
198   - },
199   - {
200   - field: 'linger',
201   - label: 'Linger',
202   - colProps: { span: 12 },
203   - component: 'InputNumber',
204   - defaultValue: 0,
205   - componentProps: {
206   - maxLength: 255,
207   - placeholder: '请输入Time to buffer locally(ms)',
208   - },
209   - },
210   - {
211   - field: 'bufferMemory',
212   - label: 'BufferMemory',
213   - colProps: { span: 12 },
214   - component: 'InputNumber',
215   - defaultValue: 33554432,
216   - componentProps: {
217   - maxLength: 255,
218   - placeholder: '请输入Client buffer max size in bytes',
219   - },
220   - },
221   - {
222   - field: 'acks',
223   - component: 'Select',
224   - label: 'Acks',
225   - colProps: { span: 12 },
226   - defaultValue: '-1',
227   - componentProps: {
228   - placeholder: '请选择Number of acknowledgments',
229   - options: [
230   - { label: 'all', value: 'all' },
231   - { label: '-1', value: '-1' },
232   - { label: '0', value: '0' },
233   - { label: '1', value: '1' },
234   - ],
235   - },
236   - },
237   - {
238   - field: 'keySerializer',
239   - label: 'Key',
240   - colProps: { span: 12 },
241   - required: true,
242   - component: 'Input',
243   - defaultValue: 'org.apache.kafka.common.serialization.StringSerializer',
244   - componentProps: {
245   - maxLength: 255,
246   - placeholder: 'org.apache.kafka.common.serialization.StringSerializer',
247   - },
248   - },
249   - {
250   - field: 'valueSerializer',
251   - label: 'Value',
252   - colProps: { span: 12 },
253   - required: true,
254   - component: 'Input',
255   - defaultValue: 'org.apache.kafka.common.serialization.StringSerializer',
256   - componentProps: {
257   - maxLength: 255,
258   - placeholder: 'org.apache.kafka.common.serialization.StringSerializer',
259   - },
260   - },
261   - {
262   - field: '1',
263   - label: '',
264   - colProps: { span: 24 },
265   - slot: 'addValue',
266   - component: 'Input',
267   - },
268   - {
269   - field: 'addMetadataKeyValuesAsKafkaHeaders',
270   - label: '选择',
271   - colProps: { span: 12 },
272   - component: 'Checkbox',
273   - renderComponentContent: 'Add Message metadata key-value pairs to Kafka record headers',
274   - },
275   - {
276   - field: 'kafkaHeadersCharset',
277   - component: 'Select',
278   - label: 'Charset',
279   - required: true,
280   - colProps: { span: 12 },
281   - defaultValue: 'UTF-8',
282   - componentProps: {
283   - placeholder: '请选择Charset encoding',
284   - options: [
285   - { label: 'US-ASCII', value: 'US' },
286   - { label: 'ISO-8859-1', value: 'ISO-8859-1' },
287   - { label: 'UTF-8', value: 'UTF-8' },
288   - { label: 'UTF-16BE', value: 'UTF-16BE' },
289   - { label: 'UTF-16LE', value: 'UTF-16LE' },
290   - { label: 'UTF-16', value: 'UTF-16' },
291   - ],
292   - },
293   - ifShow: ({ values }) => {
294   - return !!values.addMetadataKeyValuesAsKafkaHeaders;
295   - },
296   - },
297   -
298   - {
299   - field: 'description',
300   - label: '说明',
301   - colProps: { span: 12 },
302   - component: 'Input',
303   - componentProps: {
304   - maxLength: 255,
305   - placeholder: '请输入说明',
306   - },
307   - },
308   -];
309   -
310   -export const modeMqttForm: FormSchema[] = [
311   - {
312   - field: 'name',
313   - label: '名称',
314   - colProps: { span: 12 },
315   - required: true,
316   - component: 'Input',
317   - componentProps: {
318   - maxLength: 255,
319   - placeholder: '请输入名称',
320   - },
321   - dynamicRules: ({ values }) => {
322   - return [
323   - {
324   - required: true,
325   - validator(_, value) {
326   - return new Promise((resolve, reject) => {
327   - if (value == '') {
328   - reject('请输入名称');
329   - } else {
330   - if (values.name != undefined) {
331   - isExistDataManagerNameApi({
332   - name: value,
333   - type:
334   - typeValue.value == ''
335   - ? 'org.thingsboard.rule.engine.mqtt.TbMqttNode'
336   - : typeValue.value,
337   - }).then((data) => {
338   - if (data == true) {
339   - createMessage.error('名称已存在');
340   - resolve();
341   - } else {
342   - resolve();
343   - }
344   - });
345   - } else {
346   - resolve();
347   - }
348   - }
349   - });
350   - },
351   - },
352   - ];
353   - },
354   - },
355   - {
356   - field: 'topicPattern',
357   - label: 'Topic',
358   - colProps: { span: 12 },
359   - required: true,
360   - component: 'Input',
361   - componentProps: {
362   - maxLength: 255,
363   - placeholder: '请输入Topic pattern',
364   - },
365   - },
366   - {
367   - field: 'host',
368   - label: 'Host',
369   - colProps: { span: 12 },
370   - component: 'Input',
371   - required: true,
372   - defaultValue: 'localhost',
373   - componentProps: {
374   - maxLength: 255,
375   - placeholder: '请输入Host',
376   - },
377   - },
378   - {
379   - field: 'port',
380   - label: 'Port',
381   - colProps: { span: 12 },
382   - component: 'InputNumber',
383   - defaultValue: 1883,
384   - required: true,
385   - componentProps: {
386   - maxLength: 255,
387   - placeholder: '请输入Port',
388   - },
389   - },
390   - {
391   - field: 'connectTimeoutSec',
392   - label: 'Connection',
393   - colProps: { span: 12 },
394   - component: 'InputNumber',
395   - defaultValue: 10,
396   - required: true,
397   - componentProps: {
398   - maxLength: 255,
399   - placeholder: '请输入Connection timeout (sec)',
400   - },
401   - },
402   - {
403   - field: 'clientId',
404   - label: 'Client ID',
405   - colProps: { span: 12 },
406   - component: 'Input',
407   - componentProps: {
408   - maxLength: 255,
409   - placeholder: '请输入Client ID',
410   - },
411   - },
412   - {
413   - field: 'cleanSession',
414   - label: 'Clean',
415   - colProps: { span: 12 },
416   - component: 'Checkbox',
417   - renderComponentContent: 'Clean session',
418   - },
419   - {
420   - field: 'ssl',
421   - label: 'Enable',
422   - colProps: { span: 12 },
423   - component: 'Checkbox',
424   - renderComponentContent: 'Enable SSL',
425   - },
426   - {
427   - field: 'type',
428   - component: 'Select',
429   - label: 'type',
430   - colProps: { span: 12 },
431   - componentProps: {
432   - placeholder: '请选择Credentials',
433   - options: [
434   - { label: 'Anonymous', value: 'anonymous' },
435   - { label: 'Basic', value: 'basic' },
436   - { label: 'PEM', value: 'pem' },
437   - ],
438   - },
439   - },
440   - {
441   - field: 'username',
442   - label: 'Username',
443   - colProps: { span: 12 },
444   - component: 'Input',
445   - required: true,
446   - componentProps: {
447   - maxLength: 255,
448   - placeholder: '请输入Username',
449   - },
450   - ifShow: ({ values }) => isBasic(Reflect.get(values, 'type')),
451   - },
452   - {
453   - field: 'password',
454   - label: 'Password',
455   - colProps: { span: 12 },
456   - component: 'Input',
457   - componentProps: {
458   - maxLength: 255,
459   - placeholder: '请输入Password',
460   - },
461   - ifShow: ({ values }) => isBasic(Reflect.get(values, 'type')),
462   - },
463   - {
464   - field: '4',
465   - label: '',
466   - colProps: { span: 24 },
467   - component: 'Input',
468   - slot: 'uploadAdd1',
469   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
470   - },
471   - {
472   - field: '5',
473   - label: '',
474   - colProps: { span: 24 },
475   - component: 'Input',
476   - slot: 'uploadAdd2',
477   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
478   - },
479   - {
480   - field: '6',
481   - label: '',
482   - colProps: { span: 24 },
483   - component: 'Input',
484   - slot: 'uploadAdd3',
485   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
486   - },
487   - {
488   - field: 'password',
489   - label: 'Password',
490   - colProps: { span: 12 },
491   - component: 'Input',
492   - componentProps: {
493   - maxLength: 255,
494   - placeholder: '请输入Password',
495   - },
496   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
497   - },
498   - {
499   - field: 'description',
500   - label: '说明',
501   - colProps: { span: 12 },
502   - component: 'Input',
503   - componentProps: {
504   - maxLength: 255,
505   - placeholder: '请输入说明',
506   - },
507   - },
508   -];
509   -
510   -export const modeRabbitMqForm: FormSchema[] = [
511   - {
512   - field: 'name',
513   - label: '名称',
514   - colProps: { span: 12 },
515   - required: true,
516   - component: 'Input',
517   - componentProps: {
518   - maxLength: 255,
519   - placeholder: '请输入名称',
520   - },
521   - dynamicRules: ({ values }) => {
522   - return [
523   - {
524   - required: true,
525   - validator(_, value) {
526   - return new Promise((resolve, reject) => {
527   - if (value == '') {
528   - reject('请输入名称');
529   - } else {
530   - if (values.name != undefined) {
531   - isExistDataManagerNameApi({
532   - name: value,
533   - type:
534   - typeValue.value == ''
535   - ? 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode'
536   - : typeValue.value,
537   - }).then((data) => {
538   - if (data == true) {
539   - createMessage.error('名称已存在');
540   - resolve();
541   - } else {
542   - resolve();
543   - }
544   - });
545   - } else {
546   - resolve();
547   - }
548   - }
549   - });
550   - },
551   - },
552   - ];
553   - },
554   - },
555   - {
556   - field: 'exchangeNamePattern',
557   - label: 'Exchange',
558   - colProps: { span: 12 },
559   - component: 'Input',
560   - componentProps: {
561   - maxLength: 255,
562   - placeholder: '请输入Exchange name pattern',
563   - },
564   - },
565   - {
566   - field: 'routingKeyPattern',
567   - label: 'Routing',
568   - colProps: { span: 12 },
569   - component: 'Input',
570   - componentProps: {
571   - maxLength: 255,
572   - placeholder: '请输入Routing key pattern',
573   - },
574   - },
575   - {
576   - field: 'messageProperties',
577   - component: 'Select',
578   - label: 'Message',
579   - colProps: { span: 12 },
580   - componentProps: {
581   - placeholder: '请选择Message properties',
582   - options: [
583   - { label: 'BASIC', value: 'BASIC' },
584   - { label: 'TEXT_PLAIN', value: 'TEXT_PLAIN' },
585   - { label: 'MINIMAL_BASIC', value: 'MINIMAL_BASIC' },
586   - { label: 'MINIMAL_PERSISTENT_BASIC', value: 'MINIMAL_PERSISTENT_BASIC' },
587   - { label: 'PERSISTENT_BASIC', value: 'PERSISTENT_BASIC' },
588   - { label: 'PERSISTENT_TEXT_PLAIN', value: 'PERSISTENT_TEXT_PLAIN' },
589   - ],
590   - },
591   - },
592   - {
593   - field: 'host',
594   - label: 'Host',
595   - colProps: { span: 12 },
596   - component: 'Input',
597   - required: true,
598   - defaultValue: 'localhost',
599   - componentProps: {
600   - maxLength: 255,
601   - placeholder: 'localhost',
602   - },
603   - },
604   - {
605   - field: 'port',
606   - label: 'Port',
607   - colProps: { span: 12 },
608   - component: 'InputNumber',
609   - defaultValue: 5672,
610   - required: true,
611   - componentProps: {
612   - maxLength: 255,
613   - placeholder: '请输入Port',
614   - },
615   - },
616   - {
617   - field: 'virtualHost',
618   - label: 'Virtual',
619   - colProps: { span: 12 },
620   - component: 'Input',
621   - defaultValue: '/',
622   - componentProps: {
623   - maxLength: 255,
624   - placeholder: '/',
625   - },
626   - },
627   - {
628   - field: 'username',
629   - label: 'Username',
630   - colProps: { span: 12 },
631   - component: 'Input',
632   - defaultValue: 'guest',
633   - componentProps: {
634   - maxLength: 255,
635   - placeholder: '请输入Username',
636   - },
637   - },
638   - {
639   - field: 'password',
640   - label: 'Password',
641   - colProps: { span: 12 },
642   - component: 'Input',
643   - defaultValue: 'guest',
644   - componentProps: {
645   - maxLength: 255,
646   - placeholder: '请输入Password',
647   - },
648   - },
649   - {
650   - field: 'automaticRecoveryEnabled',
651   - label: ' Automatic',
652   - colProps: { span: 12 },
653   - component: 'Checkbox',
654   - renderComponentContent: 'Automatic recovery',
655   - },
656   - {
657   - field: 'connectionTimeout',
658   - label: 'Connect',
659   - colProps: { span: 12 },
660   - component: 'InputNumber',
661   - defaultValue: 60000,
662   - componentProps: {
663   - maxLength: 255,
664   - placeholder: '请输入Connection timeout (ms)',
665   - },
666   - },
667   - {
668   - field: 'handshakeTimeout',
669   - label: 'Handshake',
670   - colProps: { span: 12 },
671   - component: 'InputNumber',
672   - defaultValue: 10000,
673   - componentProps: {
674   - maxLength: 255,
675   - placeholder: '请输入Handshake timeout (ms)',
676   - },
677   - },
678   - {
679   - field: '1',
680   - label: '',
681   - colProps: { span: 24 },
682   - component: 'Input',
683   - slot: 'addKeyAndValue',
684   - },
685   -
686   - {
687   - field: 'description',
688   - label: '说明',
689   - colProps: { span: 12 },
690   - component: 'Input',
691   - componentProps: {
692   - maxLength: 255,
693   - placeholder: '请输入说明',
694   - },
695   - },
696   -];
697   -
698   -export const modeApiForm: FormSchema[] = [
699   - {
700   - field: 'name',
701   - label: '名称',
702   - colProps: { span: 12 },
703   - required: true,
704   - component: 'Input',
705   - componentProps: {
706   - maxLength: 255,
707   - placeholder: '请输入名称',
708   - },
709   - dynamicRules: ({ values }) => {
710   - return [
711   - {
712   - required: true,
713   - validator(_, value) {
714   - return new Promise((resolve, reject) => {
715   - if (value == '') {
716   - reject('请输入名称');
717   - } else {
718   - if (values.name != undefined) {
719   - isExistDataManagerNameApi({
720   - name: value,
721   - type:
722   - typeValue.value == ''
723   - ? 'org.thingsboard.rule.engine.rest.TbRestApiCallNode'
724   - : typeValue.value,
725   - }).then((data) => {
726   - if (data == true) {
727   - createMessage.error('名称已存在');
728   - resolve();
729   - } else {
730   - resolve();
731   - }
732   - });
733   - } else {
734   - resolve();
735   - }
736   - }
737   - });
738   - },
739   - },
740   - ];
741   - },
742   - },
743   - {
744   - field: 'restEndpointUrlPattern',
745   - label: 'Endpoint',
746   - colProps: { span: 12 },
747   - required: true,
748   - defaultValue: 'http://localhost/api',
749   - component: 'Input',
750   - componentProps: {
751   - maxLength: 255,
752   - placeholder: '请输入Endpoint URL pattern',
753   - },
754   - },
755   - {
756   - field: 'requestMethod',
757   - component: 'Select',
758   - label: 'Request',
759   - colProps: { span: 12 },
760   - defaultValue: 'POST',
761   - componentProps: {
762   - placeholder: '请选择Request method',
763   - options: [
764   - { label: 'GET', value: 'GET' },
765   - { label: 'POST', value: 'POST' },
766   - { label: 'PUT', value: 'PUT' },
767   - { label: 'DELETE', value: 'DELETE' },
768   - ],
769   - },
770   - },
771   - {
772   - field: 'enableProxy',
773   - label: '选择',
774   - colProps: { span: 12 },
775   - component: 'Checkbox',
776   - renderComponentContent: 'Enable proxy',
777   - },
778   -
779   - {
780   - field: 'proxyHost',
781   - label: 'Host',
782   - colProps: { span: 12 },
783   - required: true,
784   - component: 'Input',
785   - componentProps: {
786   - maxLength: 255,
787   - placeholder: 'http或者https开头',
788   - },
789   - ifShow: ({ values }) => {
790   - return !!values.enableProxy;
791   - },
792   - },
793   - {
794   - field: 'proxyPort',
795   - label: 'Port',
796   - colProps: { span: 12 },
797   - required: true,
798   - component: 'InputNumber',
799   - defaultValue: 0,
800   - componentProps: {
801   - maxLength: 255,
802   - placeholder: 'http或者https开头',
803   - },
804   - ifShow: ({ values }) => {
805   - return !!values.enableProxy;
806   - },
807   - },
808   - {
809   - field: 'proxyUser',
810   - label: 'User',
811   - colProps: { span: 12 },
812   - required: true,
813   - component: 'Input',
814   - componentProps: {
815   - maxLength: 255,
816   - placeholder: '请输入Proxy user',
817   - },
818   - ifShow: ({ values }) => {
819   - return !!values.enableProxy;
820   - },
821   - },
822   - {
823   - field: 'proxyPassword',
824   - label: 'Password',
825   - colProps: { span: 12 },
826   - required: true,
827   - component: 'Input',
828   - componentProps: {
829   - maxLength: 255,
830   - placeholder: '请输入Proxy password',
831   - },
832   - ifShow: ({ values }) => {
833   - return !!values.enableProxy;
834   - },
835   - },
836   -
837   - {
838   - field: 'useSystemProxyProperties',
839   - label: '选择',
840   - colProps: { span: 12 },
841   - component: 'Checkbox',
842   - renderComponentContent: 'Use system proxy properties',
843   - },
844   - {
845   - field: 'maxParallelRequestsCount',
846   - label: 'Max',
847   - colProps: { span: 12 },
848   - required: true,
849   - component: 'InputNumber',
850   - defaultValue: 0,
851   - componentProps: {
852   - maxLength: 255,
853   - placeholder: '请输入Max number of paraller requests',
854   - },
855   - ifShow: ({ values }) => {
856   - return !!values.useSystemProxyProperties;
857   - },
858   - },
859   - {
860   - field: 'ignoreRequestBody',
861   - label: '选择',
862   - colProps: { span: 12 },
863   - component: 'Checkbox',
864   - renderComponentContent: 'Without request body',
865   - },
866   - {
867   - field: 'readTimeoutMs',
868   - label: 'Read',
869   - colProps: { span: 12 },
870   - required: true,
871   - component: 'InputNumber',
872   - defaultValue: 0,
873   - componentProps: {
874   - maxLength: 255,
875   - placeholder: '请输入Read timeout in times',
876   - },
877   - ifShow: ({ values }) => {
878   - return !values.useSystemProxyProperties;
879   - },
880   - },
881   - {
882   - field: 'maxParallelRequestsCount',
883   - label: 'Max',
884   - colProps: { span: 12 },
885   - required: true,
886   - component: 'InputNumber',
887   - defaultValue: 0,
888   - componentProps: {
889   - maxLength: 255,
890   - placeholder: '请输入Max number of paraller requests',
891   - },
892   - ifShow: ({ values }) => {
893   - return !values.useSystemProxyProperties;
894   - },
895   - },
896   - {
897   - field: 'Header',
898   - label: 'Header',
899   - colProps: { span: 12 },
900   - required: true,
901   - component: 'Input',
902   - defaultValue: 'Content-Type',
903   - componentProps: {
904   - maxLength: 255,
905   - placeholder: 'Content-Type',
906   - },
907   - },
908   - {
909   - field: 'Value',
910   - label: 'Value',
911   - colProps: { span: 12 },
912   - required: true,
913   - component: 'Input',
914   - defaultValue: 'application/json',
915   - componentProps: {
916   - maxLength: 255,
917   - placeholder: 'application/json',
918   - },
919   - },
920   - {
921   - field: '1',
922   - label: '',
923   - colProps: { span: 24 },
924   - component: 'Input',
925   - slot: 'addKeyAndValue',
926   - },
927   -
928   - {
929   - field: 'useRedisQueueForMsgPersistence',
930   - label: '选择',
931   - colProps: { span: 12 },
932   - component: 'Checkbox',
933   - renderComponentContent: 'Use redis queue for message persistence',
934   - },
935   - {
936   - field: 'trimQueue',
937   - label: '选择',
938   - colProps: { span: 12 },
939   - component: 'Checkbox',
940   - renderComponentContent: 'Trim redis queue',
941   - ifShow: ({ values }) => {
942   - return !!values.useRedisQueueForMsgPersistence;
943   - },
944   - },
945   - {
946   - field: 'maxQueueSize',
947   - label: 'Redis',
948   - colProps: { span: 12 },
949   - required: true,
950   - component: 'InputNumber',
951   - defaultValue: 0,
952   - componentProps: {
953   - maxLength: 255,
954   - placeholder: '请输入Redis queue max size',
955   - },
956   - ifShow: ({ values }) => {
957   - return !!values.useRedisQueueForMsgPersistence;
958   - },
959   - },
960   -
961   - {
962   - field: 'type',
963   - component: 'Select',
964   - label: 'type',
965   - colProps: { span: 12 },
966   - componentProps: {
967   - placeholder: '请选择Number of acknowledgments',
968   - options: [
969   - { label: 'Anonymous', value: 'anonymous' },
970   - { label: 'Basic', value: 'basic' },
971   - { label: 'PEM', value: 'pem' },
972   - ],
973   - },
974   - },
975   - {
976   - field: 'username',
977   - label: 'Username',
978   - colProps: { span: 12 },
979   - component: 'Input',
980   - required: true,
981   - componentProps: {
982   - maxLength: 255,
983   - placeholder: '请输入Username',
984   - },
985   - ifShow: ({ values }) => isBasic(Reflect.get(values, 'type')),
986   - },
987   - {
988   - field: 'password',
989   - label: 'Password',
990   - colProps: { span: 12 },
991   - component: 'Input',
992   - required: true,
993   - componentProps: {
994   - maxLength: 255,
995   - placeholder: '请输入Password',
996   - },
997   - ifShow: ({ values }) => isBasic(Reflect.get(values, 'type')),
998   - },
999   - {
1000   - field: '1',
1001   - label: '',
1002   - colProps: { span: 24 },
1003   - component: 'Input',
1004   - slot: 'uploadAdd1',
1005   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
1006   - },
1007   - {
1008   - field: '1',
1009   - label: '',
1010   - colProps: { span: 24 },
1011   - component: 'Input',
1012   - slot: 'uploadAdd2',
1013   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
1014   - },
1015   - {
1016   - field: '1',
1017   - label: '',
1018   - colProps: { span: 24 },
1019   - component: 'Input',
1020   - slot: 'uploadAdd3',
1021   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
1022   - },
1023   - {
1024   - field: 'password',
1025   - label: 'Password',
1026   - colProps: { span: 12 },
1027   - component: 'Input',
1028   - componentProps: {
1029   - maxLength: 255,
1030   - placeholder: '请输入Password',
1031   - },
1032   - ifShow: ({ values }) => isPem(Reflect.get(values, 'type')),
1033   - },
1034   -
1035   - {
1036   - field: 'description',
1037   - label: '说明',
1038   - colProps: { span: 12 },
1039   - component: 'Input',
1040   - componentProps: {
1041   - maxLength: 255,
1042   - placeholder: '请输入说明',
1043   - },
1044   - },
1045   -];
1   -<template>
2   - <div class="root">
3   - <div class="root-form">
4   - <BasicForm :showSubmitButton="false" @register="register">
5   - <template #addKeyAndValue="{ field }">
6   - <span style="display: none">{{ field }}</span>
7   - <div>
8   - <div>
9   - <template v-for="(item, index) in keyAndValueArr" :key="index">
10   - <span style="display: none">{{ item + index }}</span>
11   - <BasicForm
12   - :showResetButton="false"
13   - :showSubmitButton="false"
14   - @register="registerKeyAndValue"
15   - />
16   - </template>
17   - <div
18   - style="
19   - width: 7vw;
20   - height: 3.3vh;
21   - display: flex;
22   - flex-direction: row;
23   - justify-content: center;
24   - align-items: center;
25   - margin-left: 1.8vw;
26   - "
27   - >
28   - <div
29   - style="
30   - width: 2.9vw;
31   - height: 3.3vh;
32   - background-color: #0960bd;
33   - border-radius: 2px;
34   - cursor: pointer;
35   - text-align: center;
36   - line-height: 3.1vh;
37   - "
38   - >
39   - <span @click="addKeyAndValueFunc" style="color: white">添加</span>
40   - </div>
41   - <div
42   - style="
43   - width: 2.9vw;
44   - height: 3.3vh;
45   - margin-left: 1vw;
46   - background-color: #ed6f6f;
47   - border-radius: 2px;
48   - cursor: pointer;
49   - text-align: center;
50   - line-height: 3.1vh;
51   - "
52   - >
53   - <span @click="removeKeyAndValueFunc" style="color: white">删除</span>
54   - </div>
55   - </div>
56   - <div> </div>
57   - </div>
58   - </div>
59   - </template>
60   - <template #uploadAdd1="{ field }">
61   - <span style="display: none">{{ field }}</span>
62   - <a-upload-dragger
63   - v-model:fileList="fileList"
64   - name="file"
65   - :multiple="true"
66   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
67   - @change="handleChange"
68   - >
69   - <p class="ant-upload-drag-icon">
70   - <InboxOutlined />
71   - </p>
72   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
73   - <p class="ant-upload-hint">
74   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
75   - other band files
76   - </p>
77   - </a-upload-dragger>
78   - </template>
79   - <template #uploadAdd2="{ field }">
80   - <span style="display: none">{{ field }}</span>
81   - <a-upload-dragger
82   - v-model:fileList="fileList"
83   - name="file"
84   - :multiple="true"
85   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
86   - @change="handleChange"
87   - >
88   - <p class="ant-upload-drag-icon">
89   - <InboxOutlined />
90   - </p>
91   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
92   - <p class="ant-upload-hint">
93   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
94   - other band files
95   - </p>
96   - </a-upload-dragger>
97   - </template>
98   - <template #uploadAdd3="{ field }">
99   - <span style="display: none">{{ field }}</span>
100   - <a-upload-dragger
101   - v-model:fileList="fileList"
102   - name="file"
103   - :multiple="true"
104   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
105   - @change="handleChange"
106   - >
107   - <p class="ant-upload-drag-icon">
108   - <InboxOutlined />
109   - </p>
110   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
111   - <p class="ant-upload-hint">
112   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
113   - other band files
114   - </p>
115   - </a-upload-dragger>
116   - </template>
117   - </BasicForm>
118   - </div>
119   - </div>
120   -</template>
121   -<script lang="ts">
122   - import { defineComponent, ref, reactive } from 'vue';
123   - import { BasicForm, useForm } from '/@/components/Form';
124   - import { modeApiForm, modeApiInseretKeyAndValueForm } from '../config';
125   - import { InboxOutlined } from '@ant-design/icons-vue';
126   - import { Alert, Divider, Descriptions, Upload } from 'ant-design-vue';
127   - interface IKeyAndValue {
128   - key: string;
129   - value: string;
130   - }
131   - export default defineComponent({
132   - components: {
133   - BasicForm,
134   - [Alert.name]: Alert,
135   - [Divider.name]: Divider,
136   - [Descriptions.name]: Descriptions,
137   - [Descriptions.Item.name]: Descriptions.Item,
138   - InboxOutlined,
139   - [Upload.Dragger.name]: Upload.Dragger,
140   - },
141   - emits: ['next', 'prev', 'register'],
142   - setup(_, { emit }) {
143   - const fileList = ref<[]>([]);
144   - const keyAndValueArr = ref<[]>([]);
145   - const temp = ref({});
146   - let tempObj = ref({});
147   - const otherPropertiesValues = reactive({
148   - headers: {},
149   - });
150   - const credentialsV = reactive({
151   - credentials: {
152   - type: '',
153   - },
154   - });
155   - const keyAndValueArrTemp = ref<[]>([]);
156   - const keyAndValueObj = reactive<IKeyAndValue>({
157   - key: '',
158   - value: '',
159   - });
160   - const sonValues = reactive({
161   - configuration: {},
162   - });
163   - const [register, { validate, setFieldsValue, resetFields: defineClearFunc }] = useForm({
164   - labelWidth: 80,
165   - schemas: modeApiForm,
166   - actionColOptions: {
167   - span: 14,
168   - },
169   - resetButtonOptions: {
170   - text: '上一步',
171   - },
172   -
173   - resetFunc: customResetFunc,
174   - submitFunc: customSubmitFunc,
175   - });
176   -
177   - const [
178   - registerKeyAndValue,
179   - { validate: validateKeyAndValue, resetFields: defineClearKeyAndValueFunc },
180   - ] = useForm({
181   - labelWidth: 80,
182   - schemas: modeApiInseretKeyAndValueForm,
183   - actionColOptions: {
184   - span: 14,
185   - },
186   - });
187   - const setStepTwoFieldsValueFunc = (v, v1) => {
188   - setFieldsValue(v);
189   - setFieldsValue({
190   - name: v1,
191   - });
192   - };
193   - const customClearStepTwoValueFunc = async () => {
194   - defineClearFunc();
195   - defineClearKeyAndValueFunc();
196   - };
197   - async function customResetFunc() {
198   - emit('prev');
199   - }
200   - async function customSubmitFunc() {
201   - try {
202   - const values = await validate();
203   - emit('next', values);
204   - } catch (error) {
205   - } finally {
206   - }
207   - }
208   - const tempGetKeyAndVal = async () => {
209   - temp.value = await validateKeyAndValue();
210   - };
211   - // const defaultAddKeyAndValueFunc = () => {
212   - // if (keyAndValueArr.value.length == 0) {
213   - // keyAndValueArr.value.push(keyAndValueObj as never);
214   - // }
215   - // };
216   - // defaultAddKeyAndValueFunc();
217   -
218   - const getDefaultValue = async () => {
219   - await tempGetKeyAndVal();
220   - keyAndValueArrTemp.value.push(temp.value as never);
221   - };
222   -
223   - const addKeyAndValueFunc = async () => {
224   - keyAndValueArr.value.push(keyAndValueObj as never);
225   - await tempGetKeyAndVal();
226   - tempObj.value = temp.value;
227   - keyAndValueArrTemp.value.push(tempObj.value as never);
228   - };
229   - const removeKeyAndValueFunc = () => {
230   - keyAndValueArr.value.splice(0, 1);
231   - };
232   - const handleChange = () => {};
233   -
234   - const getSonValueFunc = async () => {
235   - sonValues.configuration = await validate();
236   - if (keyAndValueArrTemp.value.length != 0) {
237   - await getDefaultValue();
238   - }
239   - credentialsV.credentials.type = sonValues.configuration.type;
240   - const kong = {};
241   - let kongTemp = {};
242   - keyAndValueArrTemp.value.map((item) => {
243   - kong[item.key] = item.value;
244   - });
245   - kongTemp = JSON.parse(JSON.stringify(kong));
246   - otherPropertiesValues.headers = kongTemp;
247   - Object.assign(sonValues.configuration, otherPropertiesValues, credentialsV);
248   - return sonValues;
249   - };
250   - return {
251   - register,
252   - setStepTwoFieldsValueFunc,
253   - customClearStepTwoValueFunc,
254   - addKeyAndValueFunc,
255   - removeKeyAndValueFunc,
256   - getSonValueFunc,
257   - keyAndValueArr,
258   - registerKeyAndValue,
259   - fileList,
260   - handleChange,
261   - };
262   - },
263   - });
264   -</script>
265   -<style lang="less" scoped>
266   - .root {
267   - width: 47.55vw;
268   - border: 1px solid #bfbfbf;
269   - display: flex;
270   - margin-top: 1vh;
271   - margin-left: 1.5vw;
272   - border-radius: 8px;
273   -
274   - .root-form {
275   - width: 45vw;
276   - margin: 1vh 1vw;
277   - position: relative;
278   - :deep .ant-input-number {
279   - width: 18.35vw !important;
280   - }
281   - :deep .ant-btn {
282   - position: absolute;
283   - right: 1vw;
284   - background-color: #0960bd;
285   - border-radius: 2px;
286   - span {
287   - color: white;
288   - }
289   - }
290   - }
291   - }
292   -</style>
1   -<template>
2   - <div class="root">
3   - <div class="root-form">
4   - <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register">
5   - <template #addValue="{ field }">
6   - <span style="display: none">{{ field }}</span>
7   - <div>
8   - <div>
9   - <div v-if="keyAndValueArr.length > 0">
10   - <template v-for="(item, index) in keyAndValueArr" :key="index">
11   - <span style="display: none">{{ item + index }}</span>
12   - <BasicForm
13   - :showResetButton="false"
14   - :showSubmitButton="false"
15   - @register="registerKeyAndValue"
16   - />
17   - </template>
18   - </div>
19   - <div
20   - style="
21   - width: 7vw;
22   - height: 3.3vh;
23   - display: flex;
24   - flex-direction: row;
25   - justify-content: center;
26   - align-items: center;
27   - margin-left: 1.8vw;
28   - "
29   - >
30   - <div
31   - style="
32   - width: 2.9vw;
33   - height: 3.3vh;
34   - background-color: #0960bd;
35   - border-radius: 2px;
36   - cursor: pointer;
37   - text-align: center;
38   - line-height: 3.1vh;
39   - "
40   - >
41   - <span @click="addKeyAndValueFunc" style="color: white">添加</span>
42   - </div>
43   - <div
44   - style="
45   - width: 2.9vw;
46   - height: 3.3vh;
47   - margin-left: 1vw;
48   - background-color: #ed6f6f;
49   - border-radius: 2px;
50   - cursor: pointer;
51   - text-align: center;
52   - line-height: 3.1vh;
53   - "
54   - >
55   - <span @click="removeKeyAndValueFunc" style="color: white">删除</span>
56   - </div>
57   - </div>
58   - <div> </div>
59   - </div>
60   - </div>
61   - </template>
62   - </BasicForm>
63   - <div
64   - style="
65   - width: 3.3vw;
66   - height: 3.3vh;
67   - margin-left: 22vw;
68   - margin-top: 2vh;
69   - background-color: #0960bd;
70   - border-radius: 2px;
71   - cursor: pointer;
72   - text-align: center;
73   - line-height: 3.1vh;
74   - "
75   - >
76   - <span @click="customResetFunc" style="color: white">上一步</span>
77   - </div>
78   - </div>
79   - </div>
80   -</template>
81   -<script lang="ts">
82   - import { defineComponent, ref, reactive } from 'vue';
83   - import { BasicForm, useForm } from '/@/components/Form';
84   - import { modeKafkaForm, modeKafkaInseretKeyAndValueForm } from '../config';
85   - import { Alert, Divider, Descriptions } from 'ant-design-vue';
86   -
87   - interface IKeyAndValue {
88   - key: string;
89   - value: string;
90   - }
91   -
92   - export default defineComponent({
93   - components: {
94   - BasicForm,
95   - [Alert.name]: Alert,
96   - [Divider.name]: Divider,
97   - [Descriptions.name]: Descriptions,
98   - [Descriptions.Item.name]: Descriptions.Item,
99   - },
100   - emits: ['next', 'prev', 'register'],
101   - setup(_, { emit }) {
102   - const temp = ref({});
103   - let tempObj = ref({});
104   - const keyAndValueArr = ref<[]>([]);
105   - const keyAndValueArrTemp = ref<[]>([]);
106   - const vType = ref('');
107   - const keyAndValueObj = reactive<IKeyAndValue>({
108   - key: '',
109   - value: '',
110   - });
111   - const sonValues = reactive({
112   - configuration: {},
113   - });
114   - const otherPropertiesValues = reactive({
115   - otherProperties: {},
116   - });
117   -
118   - const [register, { validate, setFieldsValue, resetFields: defineClearFunc, clearValidate }] =
119   - useForm({
120   - labelWidth: 80,
121   - schemas: modeKafkaForm,
122   - actionColOptions: {
123   - span: 14,
124   - },
125   - resetButtonOptions: {
126   - text: '上一步',
127   - },
128   - resetFunc: customResetFunc,
129   - });
130   -
131   - const [
132   - registerKeyAndValue,
133   - { validate: validateKeyAndValue, resetFields: defineClearKeyAndValueFunc },
134   - ] = useForm({
135   - labelWidth: 80,
136   - schemas: modeKafkaInseretKeyAndValueForm,
137   - actionColOptions: {
138   - span: 14,
139   - },
140   - });
141   -
142   - const clearValidateFunc = async () => {
143   - await clearValidate(['name']);
144   - };
145   -
146   - const setStepTwoFieldsValueFunc = async (v, v1) => {
147   - setFieldsValue(v);
148   - vType.value = v1;
149   - setFieldsValue({
150   - name: v1,
151   - });
152   - };
153   -
154   - const customClearStepTwoValueFunc = async () => {
155   - defineClearFunc();
156   - defineClearKeyAndValueFunc();
157   - };
158   - async function customResetFunc() {
159   - emit('prev');
160   - }
161   -
162   - const tempGetKeyAndVal = async () => {
163   - temp.value = await validateKeyAndValue();
164   - };
165   - // const defaultAddKeyAndValueFunc = () => {
166   - // if (keyAndValueArr.value.length == 0) {
167   - // keyAndValueArr.value.push(keyAndValueObj as never);
168   - // }
169   - // };
170   - // defaultAddKeyAndValueFunc();
171   -
172   - const getDefaultValue = async () => {
173   - await tempGetKeyAndVal();
174   - keyAndValueArrTemp.value.push(temp.value as never);
175   - };
176   -
177   - const addKeyAndValueFunc = async () => {
178   - keyAndValueArr.value.push(keyAndValueObj as never);
179   - await tempGetKeyAndVal();
180   - tempObj.value = temp.value;
181   - keyAndValueArrTemp.value.push(tempObj.value as never);
182   - };
183   - const removeKeyAndValueFunc = () => {
184   - keyAndValueArr.value.splice(0, 1);
185   - };
186   -
187   - const getSonValueFunc = async () => {
188   - try {
189   - sonValues.configuration = await validate();
190   - if (keyAndValueArrTemp.value.length != 0) {
191   - await getDefaultValue();
192   - }
193   - const kong = {};
194   - let kongTemp = {};
195   - keyAndValueArrTemp.value.map((item) => {
196   - kong[item.key] = item.value;
197   - });
198   - kongTemp = JSON.parse(JSON.stringify(kong));
199   - otherPropertiesValues.otherProperties = kongTemp;
200   - Object.assign(sonValues.configuration, otherPropertiesValues);
201   - return sonValues;
202   - } catch (e) {
203   - return e;
204   - }
205   - };
206   - return {
207   - clearValidateFunc,
208   - getSonValueFunc,
209   - keyAndValueArr,
210   - register,
211   - setStepTwoFieldsValueFunc,
212   - customClearStepTwoValueFunc,
213   - addKeyAndValueFunc,
214   - registerKeyAndValue,
215   - removeKeyAndValueFunc,
216   - customResetFunc,
217   - };
218   - },
219   - });
220   -</script>
221   -<style lang="less" scoped>
222   - .root {
223   - width: 47.55vw;
224   - border: 1px solid #d9d9d9;
225   - display: flex;
226   - margin-top: 1vh;
227   - margin-left: 1.5vw;
228   - border-radius: 8px;
229   - .root-form {
230   - width: 45vw;
231   - margin: 1vh 1vw;
232   - position: relative;
233   - :deep .ant-input-number {
234   - width: 18.35vw !important;
235   - }
236   - }
237   - }
238   -</style>
1   -<template>
2   - <div class="root">
3   - <div class="root-form">
4   - <BasicForm :showSubmitButton="false" @register="register">
5   - <template #uploadAdd1="{ field }">
6   - <span style="display: none">{{ field }}</span>
7   - <a-upload-dragger
8   - v-model:fileList="fileList"
9   - name="file"
10   - :multiple="true"
11   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
12   - @change="handleChange"
13   - >
14   - <p class="ant-upload-drag-icon">
15   - <InboxOutlined />
16   - </p>
17   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
18   - <p class="ant-upload-hint">
19   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
20   - other band files
21   - </p>
22   - </a-upload-dragger>
23   - </template>
24   - <template #uploadAdd2="{ field }">
25   - <span style="display: none">{{ field }}</span>
26   - <a-upload-dragger
27   - v-model:fileList="fileList"
28   - name="file"
29   - :multiple="true"
30   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
31   - @change="handleChange"
32   - >
33   - <p class="ant-upload-drag-icon">
34   - <InboxOutlined />
35   - </p>
36   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
37   - <p class="ant-upload-hint">
38   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
39   - other band files
40   - </p>
41   - </a-upload-dragger>
42   - </template>
43   - <template #uploadAdd3="{ field }">
44   - <span style="display: none">{{ field }}</span>
45   - <a-upload-dragger
46   - v-model:fileList="fileList"
47   - name="file"
48   - :multiple="true"
49   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
50   - @change="handleChange"
51   - >
52   - <p class="ant-upload-drag-icon">
53   - <InboxOutlined />
54   - </p>
55   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
56   - <p class="ant-upload-hint">
57   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
58   - other band files
59   - </p>
60   - </a-upload-dragger>
61   - </template>
62   - </BasicForm>
63   - </div>
64   - </div>
65   -</template>
66   -<script lang="ts">
67   - import { defineComponent, ref, reactive } from 'vue';
68   - import { BasicForm, useForm } from '/@/components/Form';
69   - import { modeMqttForm } from '../config';
70   - import { InboxOutlined } from '@ant-design/icons-vue';
71   - import { Alert, Divider, Descriptions, Upload } from 'ant-design-vue';
72   -
73   - export default defineComponent({
74   - components: {
75   - BasicForm,
76   - [Alert.name]: Alert,
77   - [Divider.name]: Divider,
78   - [Descriptions.name]: Descriptions,
79   - [Descriptions.Item.name]: Descriptions.Item,
80   - InboxOutlined,
81   - [Upload.Dragger.name]: Upload.Dragger,
82   - },
83   - emits: ['next', 'prev', 'register'],
84   - setup(_, { emit }) {
85   - const fileList = ref<[]>([]);
86   - const credentialsV = reactive({
87   - credentials: {
88   - type: '',
89   - },
90   - });
91   - const sonValues = reactive({
92   - configuration: {},
93   - });
94   - const [register, { validate, setFieldsValue, resetFields: defineClearFunc }] = useForm({
95   - labelWidth: 80,
96   - schemas: modeMqttForm,
97   - actionColOptions: {
98   - span: 14,
99   - },
100   - resetButtonOptions: {
101   - text: '上一步',
102   - },
103   -
104   - resetFunc: customResetFunc,
105   - submitFunc: customSubmitFunc,
106   - });
107   - const setStepTwoFieldsValueFunc = (v, v1) => {
108   - setFieldsValue(v);
109   - setFieldsValue({
110   - name: v1,
111   - });
112   - };
113   - const customClearStepTwoValueFunc = async () => {
114   - defineClearFunc();
115   - };
116   - async function customResetFunc() {
117   - emit('prev');
118   - }
119   - async function customSubmitFunc() {
120   - try {
121   - const values = await validate();
122   - emit('next', values);
123   - } catch (error) {
124   - } finally {
125   - }
126   - }
127   - const handleChange = () => {};
128   - const getSonValueFunc = async () => {
129   - sonValues.configuration = await validate();
130   - credentialsV.credentials.type = sonValues.configuration.type;
131   - Object.assign(sonValues.configuration, credentialsV);
132   - return sonValues;
133   - };
134   - return {
135   - getSonValueFunc,
136   - register,
137   - setStepTwoFieldsValueFunc,
138   - customClearStepTwoValueFunc,
139   - fileList,
140   - handleChange,
141   - };
142   - },
143   - });
144   -</script>
145   -<style lang="less" scoped>
146   - .root {
147   - width: 47.55vw;
148   - min-height: 50vh;
149   - border: 1px solid #bfbfbf;
150   - display: flex;
151   - margin-top: 1vh;
152   - margin-left: 1.5vw;
153   - border-radius: 8px;
154   - .root-form {
155   - width: 45vw;
156   - margin: 1vh 1vw;
157   - position: relative;
158   - :deep .ant-input-number {
159   - width: 18.35vw !important;
160   - }
161   - :deep .ant-btn {
162   - position: absolute;
163   - right: 1vw;
164   - background-color: #0960bd;
165   - border-radius: 2px;
166   - span {
167   - color: white;
168   - }
169   - }
170   - }
171   - }
172   -</style>
1   -<template>
2   - <div class="root">
3   - <div class="root-form">
4   - <BasicForm :showSubmitButton="false" @register="register">
5   - <template #addKeyAndValue="{ field }">
6   - <span style="display: none">{{ field }}</span>
7   - <div>
8   - <div>
9   - <template v-for="(item, index) in keyAndValueArr" :key="index">
10   - <span style="display: none">{{ item + index }}</span>
11   - <BasicForm
12   - :showResetButton="false"
13   - :showSubmitButton="false"
14   - @register="registerKeyAndValue"
15   - />
16   - </template>
17   - <div
18   - style="
19   - width: 7vw;
20   - height: 3.3vh;
21   - display: flex;
22   - flex-direction: row;
23   - justify-content: center;
24   - align-items: center;
25   - margin-left: 1.8vw;
26   - "
27   - >
28   - <div
29   - style="
30   - width: 2.9vw;
31   - height: 3.3vh;
32   - background-color: #0960bd;
33   - border-radius: 1px;
34   - cursor: pointer;
35   - text-align: center;
36   - line-height: 3.1vh;
37   - "
38   - >
39   - <span @click="addKeyAndValueFunc" style="color: white">添加</span>
40   - </div>
41   - <div
42   - style="
43   - width: 2.9vw;
44   - height: 3.3vh;
45   - margin-left: 1vw;
46   - background-color: #ed6f6f;
47   - border-radius: 1px;
48   - cursor: pointer;
49   - text-align: center;
50   - line-height: 3.1vh;
51   - "
52   - >
53   - <span @click="removeKeyAndValueFunc" style="color: white">删除</span>
54   - </div>
55   - </div>
56   - <div> </div>
57   - </div>
58   - </div>
59   - </template>
60   - </BasicForm>
61   - </div>
62   - </div>
63   -</template>
64   -<script lang="ts">
65   - import { defineComponent, ref, reactive } from 'vue';
66   - import { BasicForm, useForm } from '/@/components/Form';
67   - import { modeRabbitMqForm, modeKafkaInseretKeyAndValueForm } from '../config';
68   - import { Alert, Divider, Descriptions } from 'ant-design-vue';
69   -
70   - interface IKeyAndValue {
71   - key: string;
72   - value: string;
73   - }
74   - export default defineComponent({
75   - components: {
76   - BasicForm,
77   - [Alert.name]: Alert,
78   - [Divider.name]: Divider,
79   - [Descriptions.name]: Descriptions,
80   - [Descriptions.Item.name]: Descriptions.Item,
81   - },
82   - emits: ['next', 'prev', 'register'],
83   - setup(_, { emit }) {
84   - const temp = ref({});
85   - let tempObj = ref({});
86   - const otherPropertiesValues = reactive({
87   - clientProperties: {},
88   - });
89   -
90   - const keyAndValueArrTemp = ref<[]>([]);
91   - const keyAndValueObj = reactive<IKeyAndValue>({
92   - key: '',
93   - value: '',
94   - });
95   - const keyAndValueArr = ref<[]>([]);
96   - const sonValues = reactive({
97   - configuration: {},
98   - });
99   -
100   - const [register, { validate, setFieldsValue, resetFields: defineClearFunc }] = useForm({
101   - labelWidth: 80,
102   - schemas: modeRabbitMqForm,
103   - actionColOptions: {
104   - span: 14,
105   - },
106   - resetButtonOptions: {
107   - text: '上一步',
108   - },
109   -
110   - resetFunc: customResetFunc,
111   - submitFunc: customSubmitFunc,
112   - });
113   -
114   - const [registerKeyAndValue, { validate: validateKeyAndValue }] = useForm({
115   - labelWidth: 80,
116   - schemas: modeKafkaInseretKeyAndValueForm,
117   - actionColOptions: {
118   - span: 14,
119   - },
120   - });
121   -
122   - const setStepTwoFieldsValueFunc = (v, v1) => {
123   - setFieldsValue(v);
124   - setFieldsValue({
125   - name: v1,
126   - });
127   - };
128   - const customClearStepTwoValueFunc = async () => {
129   - defineClearFunc();
130   - };
131   - async function customResetFunc() {
132   - emit('prev');
133   - }
134   - async function customSubmitFunc() {
135   - try {
136   - const values = await validate();
137   - emit('next', values);
138   - } catch (error) {
139   - } finally {
140   - }
141   - }
142   - const tempGetKeyAndVal = async () => {
143   - temp.value = await validateKeyAndValue();
144   - };
145   - // const defaultAddKeyAndValueFunc = () => {
146   - // if (keyAndValueArr.value.length == 0) {
147   - // keyAndValueArr.value.push(keyAndValueObj as never);
148   - // }
149   - // };
150   - // defaultAddKeyAndValueFunc();
151   -
152   - const getDefaultValue = async () => {
153   - await tempGetKeyAndVal();
154   - keyAndValueArrTemp.value.push(temp.value as never);
155   - };
156   -
157   - const addKeyAndValueFunc = async () => {
158   - keyAndValueArr.value.push(keyAndValueObj as never);
159   - await tempGetKeyAndVal();
160   - tempObj.value = temp.value;
161   - keyAndValueArrTemp.value.push(tempObj.value as never);
162   - };
163   - const removeKeyAndValueFunc = () => {
164   - keyAndValueArr.value.splice(0, 1);
165   - };
166   - const getSonValueFunc = async () => {
167   - sonValues.configuration = await validate();
168   - if (keyAndValueArrTemp.value.length != 0) {
169   - await getDefaultValue();
170   - }
171   - const kong = {};
172   - let kongTemp = {};
173   - keyAndValueArrTemp.value.map((item) => {
174   - kong[item.key] = item.value;
175   - });
176   - kongTemp = JSON.parse(JSON.stringify(kong));
177   - otherPropertiesValues.clientProperties = kongTemp;
178   - Object.assign(sonValues.configuration, otherPropertiesValues);
179   - return sonValues;
180   - };
181   -
182   - return {
183   - getSonValueFunc,
184   - register,
185   - setStepTwoFieldsValueFunc,
186   - customClearStepTwoValueFunc,
187   - keyAndValueArr,
188   - registerKeyAndValue,
189   - addKeyAndValueFunc,
190   - removeKeyAndValueFunc,
191   - };
192   - },
193   - });
194   -</script>
195   -<style lang="less" scoped>
196   - .root {
197   - width: 47.55vw;
198   - border: 1px solid #d9d9d9;
199   - display: flex;
200   - margin-top: 1vh;
201   - margin-left: 1.5vw;
202   - border-radius: 8px;
203   -
204   - .root-form {
205   - width: 44vw;
206   - margin: 1vh 1vw;
207   - position: relative;
208   - :deep .ant-input-number {
209   - width: 17.85vw !important;
210   - }
211   - :deep .ant-btn {
212   - position: absolute;
213   - right: 1vw;
214   - background-color: #0960bd;
215   - border-radius: 2px;
216   - span {
217   - color: white;
218   - }
219   - }
220   - }
221   - }
222   -</style>
1   -<template>
2   - <div class="root">
3   - <div class="root-form">
4   - <div>
5   - <BasicForm @register="register" />
6   - </div>
7   - </div>
8   - </div>
9   -</template>
10   -<script lang="ts">
11   - import { defineComponent, ref } from 'vue';
12   - import { BasicForm, useForm } from '/@/components/Form';
13   - import { modeForm } from './config';
14   - import { Select, Input, Divider } from 'ant-design-vue';
15   -
16   - export default defineComponent({
17   - components: {
18   - BasicForm,
19   - [Select.name]: Select,
20   - [Input.name]: Input,
21   - [Input.Group.name]: Input.Group,
22   - [Divider.name]: Divider,
23   - },
24   - emits: ['next', 'resetFunc', 'register'],
25   - setup(_, { emit }) {
26   - const sonValues = ref({});
27   - const [register, { validateFields, setFieldsValue, resetFields }] = useForm({
28   - labelWidth: 100,
29   - schemas: modeForm,
30   - actionColOptions: {
31   - span: 14,
32   - },
33   - showResetButton: false,
34   - submitButtonOptions: {
35   - text: '下一步',
36   - },
37   - submitFunc: customSubmitFunc,
38   - });
39   - //提交数据
40   - async function customSubmitFunc() {
41   - try {
42   - const values = await validateFields();
43   - emit('next', values);
44   - } catch (error) {}
45   - }
46   - //回显数据
47   - const setStepOneFieldsValueFunc = (v) => {
48   - setFieldsValue(v);
49   - };
50   -
51   - //清空数据
52   - const customResetStepOneFunc = () => {
53   - resetFields();
54   - };
55   - const getSonValueFunc = async () => {
56   - sonValues.value = await validateFields();
57   - return sonValues.value;
58   - };
59   - return {
60   - getSonValueFunc,
61   - register,
62   - setStepOneFieldsValueFunc,
63   - customResetStepOneFunc,
64   - };
65   - },
66   - });
67   -</script>
68   -<style lang="less" scoped>
69   - .root {
70   - width: 100vw;
71   - height: 30vh;
72   - .root-form {
73   - width: 40vw;
74   - position: relative;
75   - left: 14vw;
76   - top: 8vh;
77   - :deep .ant-btn {
78   - position: absolute;
79   - right: 8.6vw;
80   - top: 6vh;
81   - background-color: #0960bd;
82   - border-radius: 2px;
83   - span {
84   - color: white;
85   - }
86   - }
87   - }
88   - }
89   -</style>
1   -<template>
2   - <div class="step2">
3   - <div>
4   - <div v-show="isWhereComp == 'org.thingsboard.rule.engine.kafka.TbKafkaNode'">
5   - <TransferConfigKafka ref="refTransferConfigKafka" @prev="getSonPrev" />
6   - </div>
7   - <div v-show="isWhereComp == 'org.thingsboard.rule.engine.mqtt.TbMqttNode'">
8   - <TransferConfigMqtt ref="refTransferConfigMqtt" @prev="getSonPrev" />
9   - </div>
10   - <div v-show="isWhereComp == 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode'">
11   - <TransferConfigRabbitMq ref="refTransferConfigRabbitMq" @prev="getSonPrev" />
12   - </div>
13   - <div v-show="isWhereComp == 'org.thingsboard.rule.engine.rest.TbRestApiCallNode'">
14   - <TransferConfigApi ref="refTransferConfigApi" @prev="getSonPrev" />
15   - </div>
16   - </div>
17   - </div>
18   -</template>
19   -<script lang="ts">
20   - import { defineComponent, watch, ref, getCurrentInstance } from 'vue';
21   - import TransferConfigKafka from '../cpns/cpns/transferConfigKafka.vue';
22   - import TransferConfigMqtt from '../cpns/cpns/transferConfigMqtt.vue';
23   - import TransferConfigRabbitMq from '../cpns/cpns/transferConfigRabbitMq.vue';
24   - import TransferConfigApi from '../cpns/cpns/transferConfigApi.vue';
25   - import { Alert, Divider, Descriptions } from 'ant-design-vue';
26   -
27   - export default defineComponent({
28   - components: {
29   - [Alert.name]: Alert,
30   - [Divider.name]: Divider,
31   - [Descriptions.name]: Descriptions,
32   - [Descriptions.Item.name]: Descriptions.Item,
33   - TransferConfigKafka,
34   - TransferConfigMqtt,
35   - TransferConfigRabbitMq,
36   - TransferConfigApi,
37   - },
38   - // eslint-disable-next-line vue/require-prop-types
39   - props: ['getModeSelect', 'defineClearFuncProp'],
40   - emits: ['prevSon'],
41   - setup(props, { emit }) {
42   - const { proxy } = getCurrentInstance();
43   - const getTransferConfigKafkaValue = ref({});
44   - const refTransferConfigKafka = ref(null);
45   - const refTransferConfigMqtt = ref(null);
46   - const refTransferConfigRabbitMq = ref(null);
47   - const refTransferConfigApi = ref(null);
48   - const isWhereComp = ref('');
49   -
50   - const getSonPrev = () => {
51   - emit('prevSon');
52   - };
53   - watch(
54   - () => props.getModeSelect,
55   - (val) => {
56   - isWhereComp.value = val.type;
57   - }
58   - );
59   - const clearSonValueDataFunc = () => {
60   - try {
61   - proxy.$refs.refTransferConfigKafka?.customClearStepTwoValueFunc();
62   - proxy.$refs.refTransferConfigMqtt?.customClearStepTwoValueFunc();
63   - proxy.$refs.refTransferConfigRabbitMq?.customClearStepTwoValueFunc();
64   - proxy.$refs.refTransferConfigApi?.customClearStepTwoValueFunc();
65   - } catch (e) {
66   - return e;
67   - }
68   - };
69   - const clearSonValueValidateFunc = () => {
70   - try {
71   - proxy.$refs.refTransferConfigKafka?.clearValidateFunc();
72   - // proxy.$refs.refTransferConfigMqtt?.customClearStepTwoValueFunc();
73   - // proxy.$refs.refTransferConfigRabbitMq?.customClearStepTwoValueFunc();
74   - // proxy.$refs.refTransferConfigApi?.customClearStepTwoValueFunc();
75   - } catch (e) {
76   - return e;
77   - }
78   - };
79   - const getSonValueDataFunc = () => {
80   - if (isWhereComp.value == 'org.thingsboard.rule.engine.kafka.TbKafkaNode') {
81   - getTransferConfigKafkaValue.value = proxy.$refs.refTransferConfigKafka.getSonValueFunc();
82   - } else if (isWhereComp.value == 'org.thingsboard.rule.engine.mqtt.TbMqttNode') {
83   - getTransferConfigKafkaValue.value = proxy.$refs.refTransferConfigMqtt.getSonValueFunc();
84   - } else if (isWhereComp.value == 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode') {
85   - getTransferConfigKafkaValue.value =
86   - proxy.$refs.refTransferConfigRabbitMq.getSonValueFunc();
87   - } else if (isWhereComp.value == 'org.thingsboard.rule.engine.rest.TbRestApiCallNode') {
88   - getTransferConfigKafkaValue.value = proxy.$refs.refTransferConfigApi.getSonValueFunc();
89   - }
90   - return getTransferConfigKafkaValue.value;
91   - };
92   - const editSonValueDataFunc = (v) => {
93   - try {
94   - if (v.type == 'org.thingsboard.rule.engine.kafka.TbKafkaNode') {
95   - isWhereComp.value = v.type;
96   - proxy.$refs.refTransferConfigKafka.setStepTwoFieldsValueFunc(v.configuration, v.name);
97   - } else if (v.type == 'org.thingsboard.rule.engine.mqtt.TbMqttNode') {
98   - isWhereComp.value = v.type;
99   - proxy.$refs.refTransferConfigMqtt.setStepTwoFieldsValueFunc(v.configuration, v.name);
100   - } else if (v.type == 'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode') {
101   - isWhereComp.value = v.type;
102   - proxy.$refs.refTransferConfigRabbitMq.setStepTwoFieldsValueFunc(
103   - v.configuration,
104   - v.name
105   - );
106   - } else if (v.type == 'org.thingsboard.rule.engine.rest.TbRestApiCallNode') {
107   - isWhereComp.value = v.type;
108   - proxy.$refs.refTransferConfigApi.setStepTwoFieldsValueFunc(v.configuration, v.name);
109   - }
110   - } catch (e) {
111   - return e;
112   - }
113   - };
114   - return {
115   - clearSonValueValidateFunc,
116   - clearSonValueDataFunc,
117   - editSonValueDataFunc,
118   - refTransferConfigKafka,
119   - getSonValueDataFunc,
120   - getSonPrev,
121   - isWhereComp,
122   - refTransferConfigMqtt,
123   - refTransferConfigRabbitMq,
124   - refTransferConfigApi,
125   - };
126   - },
127   - });
128   -</script>
129   -<style lang="less" scoped></style>
1   -<template>
2   - <div>
3   - <BasicTable
4   - @selection-change="useSelectionChange"
5   - @register="registerTable"
6   - :loading="loading"
7   - :rowSelection="{ type: 'checkbox' }"
8   - >
9   - <template #toolbar>
10   - <a-button type="primary" @click="handleAdd"> 添加转换 </a-button>
11   - <a-button
12   - :disabled="disabledStatus1"
13   - @click="handleDelete"
14   - :type="disabledStatus1 ? 'default' : 'primary'"
15   - >
16   - <span :style="{ color: disabledStatus1 ? 'grey' : 'white' }">批量删除</span>
17   - </a-button>
18   - <a-button
19   - :disabled="disabledStatus2"
20   - @click="handleMutiuteDisable"
21   - :type="disabledStatus2 ? 'default' : 'primary'"
22   - >
23   - <span :style="{ color: disabledStatus2 ? 'grey' : 'white' }">批量禁用</span>
24   - </a-button>
25   - <a-button
26   - :disabled="disabledStatus3"
27   - @click="handleMutiuteEnable"
28   - :type="disabledStatus3 ? 'default' : 'primary'"
29   - >
30   - <span :style="{ color: disabledStatus3 ? 'grey' : 'white' }">批量启用</span>
31   - </a-button>
32   - </template>
33   - <template #action="{ record }">
34   - <TableAction
35   - :actions="[
36   - {
37   - label: '编辑',
38   - icon: 'clarity:note-edit-line',
39   - onClick: handleEdit.bind(null, record),
40   - ifShow: (_action) => {
41   - return record.status == 0;
42   - },
43   - },
44   -
45   - {
46   - label: '删除',
47   - icon: 'ant-design:delete-outlined',
48   - color: 'error',
49   - popConfirm: {
50   - title: '是否确认删除',
51   - confirm: handleSingleDelete.bind(null, record),
52   - },
53   - ifShow: (_action) => {
54   - return record.status == 0;
55   - },
56   - },
57   - {
58   - label: '启用',
59   - icon: 'ant-design:check-circle-outlined',
60   - color: 'success',
61   - popConfirm: {
62   - title: '是否启用?',
63   - confirm: handleEnableOrDisable.bind(null, record),
64   - },
65   - ifShow: (_action) => {
66   - return record.status == 0;
67   - },
68   - },
69   - {
70   - label: '禁用',
71   - icon: 'ant-design:close-circle-outlined',
72   - popConfirm: {
73   - title: '是否禁用?',
74   - confirm: handleDisable.bind(null, record),
75   - },
76   - ifShow: (_action) => {
77   - return record.status == 1;
78   - },
79   - },
80   - ]"
81   - />
82   - </template>
83   - </BasicTable>
84   - <div>
85   - <DataTransferDrawer @register="registerModal" @success="handleSuccess" />
86   - </div>
87   - </div>
88   -</template>
89   -<script lang="ts">
90   - import { defineComponent, reactive, ref } from 'vue';
91   - import { BasicTable, useTable, TableAction } from '/@/components/Table';
92   - import { columns, searchFormSchema } from './config';
93   - import { useModal } from '/@/components/Modal';
94   - import DataTransferDrawer from './addDataTransferDrawer.vue';
95   - import {
96   - getConvertApi,
97   - isEnableOrDisableApi,
98   - deleteConvertApi,
99   - } from '/@/api/datamanager/dataManagerApi';
100   - import { useMessage } from '/@/hooks/web/useMessage';
101   -
102   - export default defineComponent({
103   - name: 'Index',
104   - components: { BasicTable, TableAction, DataTransferDrawer },
105   - setup() {
106   - const enableObj = reactive({
107   - convertIds: [],
108   - status: 0,
109   - });
110   - const disabledStatus1 = ref(true);
111   - const disabledStatus2 = ref(true);
112   - const disabledStatus3 = ref(true);
113   - const loading = ref(true);
114   - const { createMessage } = useMessage();
115   - let selectedRowKeys: any = ref([]);
116   - let getSelectRowsArr: any = ref([]);
117   - let isJudgeSelectRowsArr: any = ref([]);
118   - const [registerModal, { openModal }] = useModal();
119   - const [
120   - registerTable,
121   - { reload, getSelectRowKeys, getSelectRows, setLoading, clearSelectedRowKeys },
122   - ] = useTable({
123   - title: '数据转换列表',
124   - clickToRowSelect: false,
125   - columns,
126   - api: getConvertApi,
127   - formConfig: {
128   - labelWidth: 120,
129   - schemas: searchFormSchema,
130   - },
131   - rowKey: 'id',
132   - useSearchForm: true,
133   - showTableSetting: true,
134   - bordered: true,
135   - showIndexColumn: false,
136   - actionColumn: {
137   - width: 180,
138   - title: '操作',
139   - dataIndex: 'action',
140   - slots: { customRender: 'action' },
141   - fixed: 'right',
142   - },
143   - });
144   -
145   - //新增
146   - const handleAdd = () => {
147   - setTimeout(() => {
148   - openModal(true, {
149   - isUpdate: false,
150   - });
151   - }, 10);
152   - };
153   -
154   - const handleSuccess = () => {
155   - reload();
156   - };
157   - const handleEdit = (record: Recordable) => {
158   - setTimeout(() => {
159   - openModal(true, {
160   - record,
161   - isUpdate: true,
162   - });
163   - }, 10);
164   - };
165   -
166   - const handleEnableOrDisable = async (record: Recordable) => {
167   - setLoading(true);
168   - enableObj.convertIds.length = 0;
169   - try {
170   - enableObj.status = record.status;
171   - enableObj.convertIds.push(record.id as never);
172   - if (enableObj.status == 0) {
173   - enableObj.status = 1;
174   - }
175   - const res = await isEnableOrDisableApi(enableObj as never);
176   - if (res !== '') {
177   - createMessage.success('转换配置启用成功');
178   - setLoading(false);
179   - reload();
180   - } else {
181   - createMessage.error('转换配置启用失败');
182   - }
183   - } catch (e) {
184   - return e;
185   - } finally {
186   - setLoading(false);
187   - }
188   - };
189   - const handleDisable = async (record: Recordable) => {
190   - setLoading(true);
191   - enableObj.convertIds.length = 0;
192   - try {
193   - enableObj.status = record.status;
194   - enableObj.convertIds.push(record.id as never);
195   - if (enableObj.status == 1) {
196   - enableObj.status = 0;
197   - }
198   - const res = await isEnableOrDisableApi(enableObj as never);
199   - if (res !== '') {
200   - createMessage.success('转换配置禁用成功');
201   - setLoading(false);
202   - reload();
203   - } else {
204   - createMessage.error('转换配置禁用失败');
205   - }
206   - } catch (e) {
207   - } finally {
208   - setLoading(false);
209   - }
210   - };
211   - const handleSingleDelete = async (record: Recordable) => {
212   - try {
213   - let ids = [record.id];
214   - await deleteConvertApi(ids);
215   - createMessage.success('删除成功');
216   - reload();
217   - } catch (e) {
218   - return e;
219   - }
220   - };
221   - const useSelectionChange = () => {
222   - selectedRowKeys.value = getSelectRowKeys();
223   - isJudgeSelectRowsArr.value = getSelectRows();
224   - const hasDisableStatus = isJudgeSelectRowsArr.value.map((m) => {
225   - return m.status;
226   - });
227   - if (hasDisableStatus.length == 0) {
228   - disabledStatus1.value = true;
229   - disabledStatus2.value = true;
230   - disabledStatus3.value = true;
231   - }
232   - hasDisableStatus.every((e) => {
233   - if (e == 1) {
234   - disabledStatus3.value = true;
235   - disabledStatus2.value = false;
236   - } else if (e == 0) {
237   - disabledStatus2.value = true;
238   - disabledStatus3.value = false;
239   - }
240   - });
241   - let i1 = hasDisableStatus.indexOf(0);
242   - let i2 = hasDisableStatus.indexOf(1);
243   - if (i1 !== -1 && i2 !== -1) {
244   - disabledStatus2.value = true;
245   - disabledStatus3.value = true;
246   - }
247   - if (isJudgeSelectRowsArr.value.length == 0) {
248   - disabledStatus1.value = true;
249   - } else {
250   - disabledStatus1.value = false;
251   - }
252   - };
253   -
254   - const handleDelete = async () => {
255   - try {
256   - setLoading(true);
257   - const data = await deleteConvertApi(selectedRowKeys.value);
258   - if (data == true) {
259   - createMessage.success('删除成功');
260   - setLoading(false);
261   - reload();
262   - } else {
263   - createMessage.error('删除失败');
264   - }
265   - } catch (e) {
266   - return e;
267   - } finally {
268   - setLoading(false);
269   - clearSelectedRowKeys();
270   - }
271   - };
272   - const handleMutiuteDisable = async () => {
273   - enableObj.convertIds.length = 0;
274   - try {
275   - setLoading(true);
276   - getSelectRowsArr.value = getSelectRows();
277   - getSelectRowsArr.value.forEach((f) => {
278   - if (f.id) {
279   - enableObj.status = 0;
280   - enableObj.convertIds.push(f.id as never);
281   - }
282   - });
283   - const res = await isEnableOrDisableApi(enableObj as never);
284   - if (res !== '') {
285   - createMessage.success('转换配置多项禁用成功');
286   - setLoading(false);
287   - reload();
288   - } else {
289   - createMessage.error('转换配置多项禁用失败');
290   - }
291   - } catch (e) {
292   - return e;
293   - } finally {
294   - setLoading(false);
295   - clearSelectedRowKeys();
296   - }
297   - };
298   -
299   - const handleMutiuteEnable = async () => {
300   - enableObj.convertIds.length = 0;
301   - try {
302   - setLoading(true);
303   - getSelectRowsArr.value = getSelectRows();
304   - getSelectRowsArr.value.forEach((f) => {
305   - if (f.id) {
306   - enableObj.status = 1;
307   - enableObj.convertIds.push(f.id as never);
308   - }
309   - });
310   - const res = await isEnableOrDisableApi(enableObj as never);
311   - if (res !== '') {
312   - createMessage.success('转换配置多项启用成功');
313   - setLoading(false);
314   - reload();
315   - } else {
316   - createMessage.error('转换配置多项启用失败');
317   - }
318   - } catch (e) {
319   - return e;
320   - } finally {
321   - setLoading(false);
322   - clearSelectedRowKeys();
323   - }
324   - };
325   -
326   - return {
327   - disabledStatus1,
328   - disabledStatus2,
329   - disabledStatus3,
330   - handleMutiuteEnable,
331   - loading,
332   - registerTable,
333   - handleAdd,
334   - handleDelete,
335   - registerModal,
336   - handleSuccess,
337   - handleEdit,
338   - handleEnableOrDisable,
339   - handleSingleDelete,
340   - useSelectionChange,
341   - handleMutiuteDisable,
342   - handleDisable,
343   - };
344   - },
345   - });
346   -</script>
347   -
348   -<style lang="less" scoped></style>
1   -import { BasicColumn, FormSchema } from '/@/components/Table';
2   -import { h } from 'vue';
3   -import { Tag, Switch } from 'ant-design-vue';
4   -import { useMessage } from '/@/hooks/web/useMessage';
5   -import { updateTransformScriptStatusApi } from '/@/api/device/TransformScriptApi';
6   -export const columns: BasicColumn[] = [
7   - {
8   - title: '名称',
9   - dataIndex: 'name',
10   - width: 100,
11   - },
12   - {
13   - title: '用途',
14   - dataIndex: 'type',
15   - width: 200,
16   - customRender: () => h(Tag, { color: 'blue' }, () => '消息格式化'),
17   - },
18   - {
19   - title: '状态',
20   - dataIndex: 'status',
21   - width: 120,
22   - customRender: ({ record }) => {
23   - if (!Reflect.has(record, 'pendingStatus')) {
24   - record.pendingStatus = false;
25   - }
26   - return h(Switch, {
27   - checked: record.status === 1,
28   - checkedChildren: '已启用',
29   - unCheckedChildren: '已禁用',
30   - loading: record.pendingStatus,
31   - onChange(checked: boolean) {
32   - record.pendingStatus = true;
33   - const newStatus = checked ? 1 : 0;
34   - const { createMessage } = useMessage();
35   - updateTransformScriptStatusApi(newStatus, record.id)
36   - .then(() => {
37   - record.status = newStatus;
38   - createMessage.success(`${record.status ? '启用' : '禁用'}成功`);
39   - })
40   - .finally(() => {
41   - record.pendingStatus = false;
42   - });
43   - },
44   - });
45   - },
46   - },
47   - {
48   - title: '创建时间',
49   - dataIndex: 'createTime',
50   - width: 180,
51   - },
52   -];
53   -
54   -export const searchFormSchema: FormSchema[] = [
55   - {
56   - field: 'name',
57   - label: '名称',
58   - component: 'Input',
59   - colProps: { span: 6 },
60   - componentProps: {
61   - maxLength: 36,
62   - placeholder: '请输入名称',
63   - },
64   - },
65   - {
66   - field: 'status',
67   - label: '状态',
68   - component: 'Select',
69   - componentProps: {
70   - placeholder: '请选择状态',
71   - options: [
72   - { label: '已启用', value: '1' },
73   - { label: '未启用', value: '0' },
74   - ],
75   - },
76   - colProps: { span: 6 },
77   - },
78   -];
79   -
80   -export const formSchema: FormSchema[] = [
81   - {
82   - field: 'name',
83   - label: '名称',
84   - required: true,
85   - component: 'Input',
86   - componentProps: {
87   - maxLength: 36,
88   - placeholder: '请输入名称',
89   - },
90   - },
91   - {
92   - field: 'remark',
93   - label: '说明',
94   - component: 'InputTextArea',
95   - componentProps: {
96   - maxLength: 255,
97   - autoSize: { minRows: 5, maxRows: 8 },
98   - placeholder: '请输入说明',
99   - },
100   - },
101   - {
102   - field: 'function',
103   - label: '',
104   - component: 'Input',
105   - slot: 'function',
106   - },
107   - {
108   - field: 'id',
109   - label: 'id',
110   - component: 'Input',
111   - ifShow: false,
112   - },
113   -];
1   -<template>
2   - <div>
3   - <BasicDrawer
4   - v-bind="$attrs"
5   - :title="getTitle"
6   - @register="register"
7   - width="500px"
8   - showFooter
9   - @ok="handleSubmit"
10   - >
11   - <BasicForm @register="registerForm">
12   - <template #function>
13   - <Card title="转换函数" :bodyStyle="{ padding: 0, height: '280px' }">
14   - <template #extra>
15   - <Tag color="blue">Transform Function</Tag>
16   - <a-button @click="handleFormat" size="small">格式化</a-button>
17   - </template>
18   - <div class="ml-8">function Transform(msg, metadata) {</div>
19   - <div ref="aceRef" class="overflow-hidden"></div>
20   - <div class="ml-7">}</div>
21   - </Card>
22   - <a-button type="primary" class="mt-4" @click="testTransformFunc">测试转换功能</a-button>
23   - </template>
24   - </BasicForm>
25   - </BasicDrawer>
26   - </div>
27   -</template>
28   -
29   -<script lang="ts" setup>
30   - import { ref, computed } from 'vue';
31   - import { useDrawerInner, BasicDrawer } from '/@/components/Drawer/index';
32   - import { useForm, BasicForm } from '/@/components/Form/index';
33   - import { formSchema } from '../config/config.data.ts';
34   - import { Card, Tag } from 'ant-design-vue';
35   - import { createOrEditTransformScriptApi } from '/@/api/device/TransformScriptApi';
36   - import { useMessage } from '/@/hooks/web/useMessage';
37   - import ace from 'ace-builds';
38   - import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题
39   - import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式
40   - import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js';
41   -
42   - const emit = defineEmits(['register', 'isStatus', 'success']);
43   - const isUpdate = ref(false);
44   - const aceEditor = ref();
45   - const aceRef = ref();
46   - const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本'));
47   - const [register, { closeDrawer }] = useDrawerInner((data) => {
48   - resetFields();
49   - isUpdate.value = data.isUpdate;
50   - initEditor(data.record?.configuration.jsScript);
51   - if (isUpdate.value) {
52   - setFieldsValue(data.record);
53   - }
54   - });
55   - const [registerForm, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
56   - showActionButtonGroup: false,
57   - colProps: { span: 24 },
58   - schemas: formSchema,
59   - });
60   -
61   - // 初始化编辑器
62   - const initEditor = (jsScript?: string) => {
63   - aceEditor.value = ace.edit(aceRef.value, {
64   - maxLines: 12, // 最大行数,超过会自动出现滚动条
65   - minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
66   - fontSize: 14, // 编辑器内字体大小
67   - theme: 'ace/theme/chrome', // 默认设置的主题
68   - mode: 'ace/mode/javascript', // 默认设置的语言模式
69   - tabSize: 2, // 制表符设置为 4 个空格大小
70   - });
71   -
72   - aceEditor.value.setOptions({
73   - enableBasicAutocompletion: true,
74   - enableLiveAutocompletion: true,
75   - });
76   - aceEditor.value.setValue(jsScript ?? 'return {msg: msg, metadata: metadata};');
77   - beautify(aceEditor.value.session);
78   - };
79   -
80   - const testTransformFunc = () => {
81   - closeDrawer();
82   - const jsCode = aceEditor.value.getValue();
83   - emit('isStatus', { status: 1, jsCode });
84   - };
85   - const handleSubmit = async () => {
86   - const fieldsValue = getFieldsValue();
87   - try {
88   - await createOrEditTransformScriptApi({
89   - configuration: {
90   - jsScript: aceEditor.value.getValue(),
91   - },
92   - type: 'org.thingsboard.rule.engine.transform.TbTransformMsgNode',
93   - ...fieldsValue,
94   - });
95   - closeDrawer();
96   - emit('success');
97   - const { createMessage } = useMessage();
98   - createMessage.success('保存成功');
99   - } catch (e) {
100   - const { createMessage } = useMessage();
101   - createMessage.success('保存失败');
102   - }
103   - };
104   - const handleFormat = () => {
105   - beautify(aceEditor.value.session);
106   - };
107   - defineExpose({ aceEditor });
108   -</script>