Commit b042fdeb59f1bf37d90b970654831f9eae5460bf

Authored by sqy
1 parent 656b64d2

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

Too many changes to show.

To preserve performance only 24 of 53 files are displayed.

1 import { generate } from '@ant-design/colors'; 1 import { generate } from '@ant-design/colors';
2 2
3 -export const primaryColor = '#0960bd'; 3 +export const primaryColor = '#377DFF';
4 4
5 export const darkMode = 'light'; 5 export const darkMode = 'light';
6 6
@@ -10,21 +10,21 @@ export default { @@ -10,21 +10,21 @@ export default {
10 status: 'status', 10 status: 'status',
11 }, 11 },
12 notice: { 12 notice: {
13 - webSiteNotice: 'web site notice', 13 + webSiteNotice: 'platform notice',
14 noticeManagement: 'notice management', 14 noticeManagement: 'notice management',
15 myNotice: 'my notice', 15 myNotice: 'my notice',
16 }, 16 },
17 17
18 device: { 18 device: {
19 deviceManagement: 'device management', 19 deviceManagement: 'device management',
20 - device: 'device', 20 + device: 'device management',
21 deviceProfile: 'device profile', 21 deviceProfile: 'device profile',
22 }, 22 },
23 tenant: { 23 tenant: {
24 tenant: 'tenant', 24 tenant: 'tenant',
25 tenantManagement: 'tenant management', 25 tenantManagement: 'tenant management',
26 tenantSetting: 'tenant config', 26 tenantSetting: 'tenant config',
27 - tenantOEM: 'OEM customization', 27 + tenantOEM: 'platform customization',
28 tenantRule: 'tenant rule', 28 tenantRule: 'tenant rule',
29 }, 29 },
30 30
@@ -49,23 +49,9 @@ export default { @@ -49,23 +49,9 @@ export default {
49 alarmManagement: 'alarm management', 49 alarmManagement: 'alarm management',
50 geographicPosition: 'geographic position', 50 geographicPosition: 'geographic position',
51 alarmContact: 'alarm contact', 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 system: { 55 system: {
70 system: 'system', 56 system: 'system',
71 accountManagement: 'account management', 57 accountManagement: 'account management',
@@ -10,13 +10,13 @@ export default { @@ -10,13 +10,13 @@ export default {
10 status: '状态', 10 status: '状态',
11 }, 11 },
12 notice: { 12 notice: {
13 - webSiteNotice: '站内通知', 13 + webSiteNotice: '平台通知',
14 noticeManagement: '通知管理', 14 noticeManagement: '通知管理',
15 myNotice: '我的通知', 15 myNotice: '我的通知',
16 }, 16 },
17 device: { 17 device: {
18 deviceManagement: '设备管理', 18 deviceManagement: '设备管理',
19 - device: '设备', 19 + device: '设备管理',
20 deviceProfile: '设备配置', 20 deviceProfile: '设备配置',
21 }, 21 },
22 22
@@ -24,7 +24,7 @@ export default { @@ -24,7 +24,7 @@ export default {
24 tenant: '租户', 24 tenant: '租户',
25 tenantManagement: '租户管理', 25 tenantManagement: '租户管理',
26 tenantSetting: '租户配置', 26 tenantSetting: '租户配置',
27 - tenantOEM: 'OEM定制', 27 + tenantOEM: '平台定制',
28 tenantRule: '租户角色', 28 tenantRule: '租户角色',
29 }, 29 },
30 organization: { 30 organization: {
@@ -34,20 +34,7 @@ export default { @@ -34,20 +34,7 @@ export default {
34 toolEditOrganization: '编辑组织', 34 toolEditOrganization: '编辑组织',
35 parentOrganization: '上级组织', 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 RuleEngine: { 38 RuleEngine: {
52 ruleEngine: '规则引擎', 39 ruleEngine: '规则引擎',
53 sceneLinkage: '场景联动', 40 sceneLinkage: '场景联动',
@@ -62,7 +49,7 @@ export default { @@ -62,7 +49,7 @@ export default {
62 alarmManagement: '告警管理', 49 alarmManagement: '告警管理',
63 geographicPosition: '地理位置', 50 geographicPosition: '地理位置',
64 alarmContact: '告警联系人', 51 alarmContact: '告警联系人',
65 - alarmCenter: '告警中心', 52 + alarmCenter: '告警记录',
66 }, 53 },
67 system: { 54 system: {
68 system: '系统管理', 55 system: '系统管理',
@@ -78,7 +78,7 @@ const setting: ProjectConfig = { @@ -78,7 +78,7 @@ const setting: ProjectConfig = {
78 // Menu configuration 78 // Menu configuration
79 menuSetting: { 79 menuSetting: {
80 // sidebar menu bg color 80 // sidebar menu bg color
81 - bgColor: SIDE_BAR_BG_COLOR_LIST[0], 81 + bgColor: SIDE_BAR_BG_COLOR_LIST[3],
82 // Whether to fix the left menu 82 // Whether to fix the left menu
83 fixed: true, 83 fixed: true,
84 // Menu collapse 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>