Commit cea7fdf23a38e81c2e96acf3f188d1d7f4e70e35
1 parent
7ddce7c2
Merge branch 'ft' into 'main_dev'
fix: 修复Teambition上的问题 See merge request yunteng/thingskit-front!533 (cherry picked from commit 6fee6dcc13983532958543c85383139aad19fdce) c62f9e54 pref:优化测试接口表格,只有一项时,清除对应项 85cc1230 fix:DEFECT-1122 分页接口测试错误提示,修复post传参问题 e2c049f2 fix:DEFECT-1112 提示输入参数值 表格选择是否必须为是,则对应测试接口参数若为空则增加提示 f8d25bcd fix:DEFECT-1112 提示输入参数值 表格选择是否必须为是,则对应测试接口参数若为空则增加提示 eaaa19ee pref:调整脚本管理 转换函数 dda4b267 fix:DEFECT-1078 修复暗黑模式场景联动白框问题 b8876e1a fix:DEFECT-1079 修复暗黑模式转换脚本白框问题
Showing
16 changed files
with
767 additions
and
622 deletions
1 | <template> | 1 | <template> |
2 | - <div :class="prefixCls"> | 2 | + <div |
3 | + :class="prefixCls" | ||
4 | + :style="{ backgroundColor: modeSwitch === 'dark' ? '#1f1f1f' : 'rgb(242, 242, 242)' }" | ||
5 | + > | ||
3 | <CollapseHeader | 6 | <CollapseHeader |
4 | v-bind="$props" | 7 | v-bind="$props" |
5 | :prefixCls="prefixCls" | 8 | :prefixCls="prefixCls" |
@@ -29,7 +32,7 @@ | @@ -29,7 +32,7 @@ | ||
29 | </template> | 32 | </template> |
30 | <script lang="ts" setup> | 33 | <script lang="ts" setup> |
31 | import type { PropType } from 'vue'; | 34 | import type { PropType } from 'vue'; |
32 | - import { ref } from 'vue'; | 35 | + import { ref, computed } from 'vue'; |
33 | // component | 36 | // component |
34 | import { Skeleton } from 'ant-design-vue'; | 37 | import { Skeleton } from 'ant-design-vue'; |
35 | import { CollapseTransition } from '/@/components/Transition'; | 38 | import { CollapseTransition } from '/@/components/Transition'; |
@@ -38,6 +41,7 @@ | @@ -38,6 +41,7 @@ | ||
38 | // hook | 41 | // hook |
39 | import { useTimeoutFn } from '/@/hooks/core/useTimeout'; | 42 | import { useTimeoutFn } from '/@/hooks/core/useTimeout'; |
40 | import { useDesign } from '/@/hooks/web/useDesign'; | 43 | import { useDesign } from '/@/hooks/web/useDesign'; |
44 | + import { useAppStore } from '/@/store/modules/app'; | ||
41 | 45 | ||
42 | const props = defineProps({ | 46 | const props = defineProps({ |
43 | isClose: { type: Boolean, default: true }, | 47 | isClose: { type: Boolean, default: true }, |
@@ -64,6 +68,11 @@ | @@ -64,6 +68,11 @@ | ||
64 | */ | 68 | */ |
65 | lazyTime: { type: Number, default: 0 }, | 69 | lazyTime: { type: Number, default: 0 }, |
66 | }); | 70 | }); |
71 | + | ||
72 | + const userStore = useAppStore(); | ||
73 | + | ||
74 | + const modeSwitch = computed((): string => userStore.getDarkMode); | ||
75 | + | ||
67 | const emit = defineEmits(['expand', 'change', 'hchange']); | 76 | const emit = defineEmits(['expand', 'change', 'hchange']); |
68 | 77 | ||
69 | const show = ref(true); | 78 | const show = ref(true); |
@@ -92,7 +101,7 @@ | @@ -92,7 +101,7 @@ | ||
92 | @prefix-cls: ~'@{namespace}-collapse-container'; | 101 | @prefix-cls: ~'@{namespace}-collapse-container'; |
93 | 102 | ||
94 | .@{prefix-cls} { | 103 | .@{prefix-cls} { |
95 | - background-color: @component-background; | 104 | + // background-color: @component-background; |
96 | border-radius: 2px; | 105 | border-radius: 2px; |
97 | transition: all 0.3s ease-in-out; | 106 | transition: all 0.3s ease-in-out; |
98 | 107 |
@@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
18 | placeholder="请选择" | 18 | placeholder="请选择" |
19 | :options="selectOptions" | 19 | :options="selectOptions" |
20 | @change="handleChange" | 20 | @change="handleChange" |
21 | + @dropdownVisibleChange="hanldeDropdownVisibleChange" | ||
21 | allowClear | 22 | allowClear |
22 | /> | 23 | /> |
23 | </td> | 24 | </td> |
@@ -111,16 +112,20 @@ | @@ -111,16 +112,20 @@ | ||
111 | 112 | ||
112 | // 减少 | 113 | // 减少 |
113 | const remove = (item, index: number) => { | 114 | const remove = (item, index: number) => { |
114 | - if (tableArray.content.length !== 1) { | 115 | + if (tableArray.content.length > 1) { |
115 | selectOptions.value.forEach((ele) => { | 116 | selectOptions.value.forEach((ele) => { |
116 | if (ele.value == item.key) { | 117 | if (ele.value == item.key) { |
117 | ele.disabled = false; | 118 | ele.disabled = false; |
118 | } | 119 | } |
119 | }); | 120 | }); |
120 | tableArray.content.splice(index, 1); | 121 | tableArray.content.splice(index, 1); |
122 | + } else { | ||
123 | + resetValue(); | ||
121 | } | 124 | } |
122 | }; | 125 | }; |
123 | 126 | ||
127 | + const hanldeDropdownVisibleChange = () => handleChange(); | ||
128 | + | ||
124 | //Select互斥 | 129 | //Select互斥 |
125 | const handleChange = () => { | 130 | const handleChange = () => { |
126 | selectOptions.value.forEach((ele) => { | 131 | selectOptions.value.forEach((ele) => { |
@@ -132,7 +137,7 @@ | @@ -132,7 +137,7 @@ | ||
132 | element.value = ''; | 137 | element.value = ''; |
133 | element.editDisabled = true; | 138 | element.editDisabled = true; |
134 | } | 139 | } |
135 | - if (element.key === ele.value && element.key !== 'scope' && element.key !== 'fixed_date') { | 140 | + if (element.key === ele.value && element.key !== 'scope') { |
136 | ele.disabled = true; | 141 | ele.disabled = true; |
137 | } | 142 | } |
138 | }); | 143 | }); |
@@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
18 | placeholder="请选择" | 18 | placeholder="请选择" |
19 | :options="selectOptions" | 19 | :options="selectOptions" |
20 | @change="handleChange" | 20 | @change="handleChange" |
21 | + @dropdownVisibleChange="hanldeDropdownVisibleChange" | ||
21 | allowClear | 22 | allowClear |
22 | /> | 23 | /> |
23 | </td> | 24 | </td> |
@@ -111,13 +112,15 @@ | @@ -111,13 +112,15 @@ | ||
111 | 112 | ||
112 | // 减少 | 113 | // 减少 |
113 | const remove = (item, index: number) => { | 114 | const remove = (item, index: number) => { |
114 | - if (tableArray.content.length !== 1) { | 115 | + if (tableArray.content.length > 1) { |
115 | selectOptions.value.forEach((ele) => { | 116 | selectOptions.value.forEach((ele) => { |
116 | if (ele.value == item.key) { | 117 | if (ele.value == item.key) { |
117 | ele.disabled = false; | 118 | ele.disabled = false; |
118 | } | 119 | } |
119 | }); | 120 | }); |
120 | tableArray.content.splice(index, 1); | 121 | tableArray.content.splice(index, 1); |
122 | + } else { | ||
123 | + resetValue(); | ||
121 | } | 124 | } |
122 | }; | 125 | }; |
123 | 126 | ||
@@ -132,13 +135,15 @@ | @@ -132,13 +135,15 @@ | ||
132 | element.value = ''; | 135 | element.value = ''; |
133 | element.editDisabled = true; | 136 | element.editDisabled = true; |
134 | } | 137 | } |
135 | - if (element.key === ele.value && element.key !== 'scope' && element.key !== 'fixed_date') { | 138 | + if (element.key === ele.value && element.key !== 'scope') { |
136 | ele.disabled = true; | 139 | ele.disabled = true; |
137 | } | 140 | } |
138 | }); | 141 | }); |
139 | }); | 142 | }); |
140 | }; | 143 | }; |
141 | 144 | ||
145 | + const hanldeDropdownVisibleChange = () => handleChange(); | ||
146 | + | ||
142 | //获取数据 | 147 | //获取数据 |
143 | const getValue = () => { | 148 | const getValue = () => { |
144 | const assemblyData = tableArray.content.map((it) => { | 149 | const assemblyData = tableArray.content.map((it) => { |
@@ -31,6 +31,7 @@ | @@ -31,6 +31,7 @@ | ||
31 | import moment from 'moment'; | 31 | import moment from 'moment'; |
32 | import { useUtils } from '../../../hooks/useUtils'; | 32 | import { useUtils } from '../../../hooks/useUtils'; |
33 | import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue'; | 33 | import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue'; |
34 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
34 | 35 | ||
35 | const emits = defineEmits(['testBodyInterface']); | 36 | const emits = defineEmits(['testBodyInterface']); |
36 | 37 | ||
@@ -40,6 +41,8 @@ | @@ -40,6 +41,8 @@ | ||
40 | }, | 41 | }, |
41 | }); | 42 | }); |
42 | 43 | ||
44 | + const { createMessage } = useMessage(); | ||
45 | + | ||
43 | const showTestEditCell = ref(false); | 46 | const showTestEditCell = ref(false); |
44 | 47 | ||
45 | const excuteData = ref({}); | 48 | const excuteData = ref({}); |
@@ -63,13 +66,12 @@ | @@ -63,13 +66,12 @@ | ||
63 | const getValue = async () => { | 66 | const getValue = async () => { |
64 | await nextTick(); | 67 | await nextTick(); |
65 | await nextTick(() => { | 68 | await nextTick(() => { |
66 | - console.log(props.data?.list); | ||
67 | if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') { | 69 | if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') { |
68 | const getSingleKey = props.data?.list; | 70 | const getSingleKey = props.data?.list; |
69 | - const getMuteKey = props.data?.list?.filter((it: any) => it.key.split(',').length > 1); | 71 | + const getMuteKey = props.data?.list?.filter((it: any) => it.key?.split(',').length > 1); |
70 | const getMuteKeys = getMultipleKeys(getMuteKey); | 72 | const getMuteKeys = getMultipleKeys(getMuteKey); |
71 | const mergeKeys = [...getSingleKey, ...getMuteKeys]?.filter( | 73 | const mergeKeys = [...getSingleKey, ...getMuteKeys]?.filter( |
72 | - (it: any) => it.key.split(',').length === 1 | 74 | + (it: any) => it.key?.split(',').length === 1 |
73 | ); | 75 | ); |
74 | testEditCellTableRef.value?.setTableArray(mergeKeys); | 76 | testEditCellTableRef.value?.setTableArray(mergeKeys); |
75 | } else if (props.data?.type === 'json') { | 77 | } else if (props.data?.type === 'json') { |
@@ -111,6 +113,7 @@ | @@ -111,6 +113,7 @@ | ||
111 | return { | 113 | return { |
112 | key, | 114 | key, |
113 | value, | 115 | value, |
116 | + required: it.required, | ||
114 | }; | 117 | }; |
115 | }); | 118 | }); |
116 | }; | 119 | }; |
@@ -120,6 +123,11 @@ | @@ -120,6 +123,11 @@ | ||
120 | let params: any = {}; | 123 | let params: any = {}; |
121 | if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') { | 124 | if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') { |
122 | const getTable = getTestTableKeyValue(); | 125 | const getTable = getTestTableKeyValue(); |
126 | + const hasRequired = getTable?.some((it) => it.required === true && !it.value); | ||
127 | + if (hasRequired) { | ||
128 | + createMessage.error('选择项为必须的,参数不能为空'); | ||
129 | + throw new Error('选择项为必须的,参数不能为空'); | ||
130 | + } | ||
123 | getTable?.map((it) => (params[it.key!] = it.value!)); | 131 | getTable?.map((it) => (params[it.key!] = it.value!)); |
124 | } else if (props.data?.type === 'json') { | 132 | } else if (props.data?.type === 'json') { |
125 | params = jsonEditorRef.value?.getJsonValue(); | 133 | params = jsonEditorRef.value?.getJsonValue(); |
@@ -228,6 +228,7 @@ | @@ -228,6 +228,7 @@ | ||
228 | }; | 228 | }; |
229 | 229 | ||
230 | const getAttributeOptions = async (params) => { | 230 | const getAttributeOptions = async (params) => { |
231 | + console.log(params); | ||
231 | const res = await getDeviceAttributes(params); | 232 | const res = await getDeviceAttributes(params); |
232 | if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0); | 233 | if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0); |
233 | attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier })); | 234 | attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier })); |
@@ -243,7 +244,9 @@ | @@ -243,7 +244,9 @@ | ||
243 | if (f.key === 'organizationId') organizationId = f.value; | 244 | if (f.key === 'organizationId') organizationId = f.value; |
244 | if (f.key === 'entityId') f.value = null; | 245 | if (f.key === 'entityId') f.value = null; |
245 | }); | 246 | }); |
246 | - getAttributeOptions({ deviceProfileId: e.value }); | 247 | + if (e.value) { |
248 | + getAttributeOptions({ deviceProfileId: e.value }); | ||
249 | + } | ||
247 | if (organizationId !== '') { | 250 | if (organizationId !== '') { |
248 | getEntityOptions(organizationId, e.value); | 251 | getEntityOptions(organizationId, e.value); |
249 | } | 252 | } |
@@ -261,6 +264,9 @@ | @@ -261,6 +264,9 @@ | ||
261 | </script> | 264 | </script> |
262 | 265 | ||
263 | <style scoped lang="less"> | 266 | <style scoped lang="less"> |
267 | + :deep(.ant-select-selector) { | ||
268 | + max-width: 16vw; | ||
269 | + } | ||
264 | @table-color: #e5e7eb; | 270 | @table-color: #e5e7eb; |
265 | 271 | ||
266 | .table-border-color { | 272 | .table-border-color { |
@@ -36,7 +36,7 @@ | @@ -36,7 +36,7 @@ | ||
36 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; | 36 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; |
37 | import { getAuthCache } from '/@/utils/auth'; | 37 | import { getAuthCache } from '/@/utils/auth'; |
38 | import { useMessage } from '/@/hooks/web/useMessage'; | 38 | import { useMessage } from '/@/hooks/web/useMessage'; |
39 | - // import { useGlobSetting } from '/@/hooks/setting'; | 39 | + import { useUtils } from '../../../hooks/useUtils'; |
40 | 40 | ||
41 | const emits = defineEmits(['emitExcute']); | 41 | const emits = defineEmits(['emitExcute']); |
42 | 42 | ||
@@ -56,8 +56,6 @@ | @@ -56,8 +56,6 @@ | ||
56 | 56 | ||
57 | const socketUrls = ref(''); | 57 | const socketUrls = ref(''); |
58 | 58 | ||
59 | - // const { socketUrl } = useGlobSetting(); | ||
60 | - | ||
61 | const socketMessage: any = reactive({ | 59 | const socketMessage: any = reactive({ |
62 | server: ``, | 60 | server: ``, |
63 | sendValue: { | 61 | sendValue: { |
@@ -152,7 +150,7 @@ | @@ -152,7 +150,7 @@ | ||
152 | apiUrl, | 150 | apiUrl, |
153 | headers = {}, | 151 | headers = {}, |
154 | params = {}, | 152 | params = {}, |
155 | - body, | 153 | + body = {}, |
156 | joinPrefix = false | 154 | joinPrefix = false |
157 | ) => { | 155 | ) => { |
158 | switch (apiType) { | 156 | switch (apiType) { |
@@ -165,8 +163,9 @@ | @@ -165,8 +163,9 @@ | ||
165 | } | 163 | } |
166 | ); | 164 | ); |
167 | case 'POST': | 165 | case 'POST': |
166 | + const { convertObj } = useUtils(); | ||
168 | return await otherHttp.post( | 167 | return await otherHttp.post( |
169 | - { url: apiUrl, data: body, headers, params }, | 168 | + { url: `${apiUrl}?${convertObj(params)}`, data: body, headers }, |
170 | { | 169 | { |
171 | apiUrl: '', | 170 | apiUrl: '', |
172 | joinPrefix, | 171 | joinPrefix, |
@@ -20,6 +20,7 @@ | @@ -20,6 +20,7 @@ | ||
20 | import { ref, nextTick } from 'vue'; | 20 | import { ref, nextTick } from 'vue'; |
21 | import { Button } from 'ant-design-vue'; | 21 | import { Button } from 'ant-design-vue'; |
22 | import TestHeaderEditCellTable from './testEditHeaderCellTable.vue'; | 22 | import TestHeaderEditCellTable from './testEditHeaderCellTable.vue'; |
23 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
23 | 24 | ||
24 | const emits = defineEmits(['testHeaderInterface']); | 25 | const emits = defineEmits(['testHeaderInterface']); |
25 | 26 | ||
@@ -29,6 +30,8 @@ | @@ -29,6 +30,8 @@ | ||
29 | }, | 30 | }, |
30 | }); | 31 | }); |
31 | 32 | ||
33 | + const { createMessage } = useMessage(); | ||
34 | + | ||
32 | const showTestEditCell = ref(false); | 35 | const showTestEditCell = ref(false); |
33 | 36 | ||
34 | const excuteData = ref({}); | 37 | const excuteData = ref({}); |
@@ -59,6 +62,11 @@ | @@ -59,6 +62,11 @@ | ||
59 | //获取数据 | 62 | //获取数据 |
60 | const getTestValue = () => { | 63 | const getTestValue = () => { |
61 | const getTable = getTestTableKeyValue(); | 64 | const getTable = getTestTableKeyValue(); |
65 | + const hasRequired = getTable?.some((it) => it.required === true && !it.value); | ||
66 | + if (hasRequired) { | ||
67 | + createMessage.error('选择项为必须的,参数不能为空'); | ||
68 | + throw new Error('选择项为必须的,参数不能为空'); | ||
69 | + } | ||
62 | const params: any = {}; | 70 | const params: any = {}; |
63 | getTable?.map((it: any) => (params[it.key!] = it.value!)); | 71 | getTable?.map((it: any) => (params[it.key!] = it.value!)); |
64 | excuteData.value = { | 72 | excuteData.value = { |
@@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
22 | import TestParamsCellTable from './testEditParamsCellTable.vue'; | 22 | import TestParamsCellTable from './testEditParamsCellTable.vue'; |
23 | import moment from 'moment'; | 23 | import moment from 'moment'; |
24 | import { useUtils } from '../../../hooks/useUtils'; | 24 | import { useUtils } from '../../../hooks/useUtils'; |
25 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
25 | 26 | ||
26 | const emits = defineEmits(['testParamsInterface']); | 27 | const emits = defineEmits(['testParamsInterface']); |
27 | 28 | ||
@@ -31,6 +32,8 @@ | @@ -31,6 +32,8 @@ | ||
31 | }, | 32 | }, |
32 | }); | 33 | }); |
33 | 34 | ||
35 | + const { createMessage } = useMessage(); | ||
36 | + | ||
34 | const showTestEditCell = ref(false); | 37 | const showTestEditCell = ref(false); |
35 | 38 | ||
36 | const excuteData = ref({}); | 39 | const excuteData = ref({}); |
@@ -92,6 +95,7 @@ | @@ -92,6 +95,7 @@ | ||
92 | return { | 95 | return { |
93 | key, | 96 | key, |
94 | value, | 97 | value, |
98 | + required: it.required, | ||
95 | }; | 99 | }; |
96 | }); | 100 | }); |
97 | }; | 101 | }; |
@@ -99,6 +103,11 @@ | @@ -99,6 +103,11 @@ | ||
99 | //获取数据 | 103 | //获取数据 |
100 | const getTestValue = () => { | 104 | const getTestValue = () => { |
101 | const getTable = getTestTableKeyValue(); | 105 | const getTable = getTestTableKeyValue(); |
106 | + const hasRequired = getTable?.some((it) => it.required === true && !it.value); | ||
107 | + if (hasRequired) { | ||
108 | + createMessage.error('选择项为必须的,参数不能为空'); | ||
109 | + throw new Error('选择项为必须的,参数不能为空'); | ||
110 | + } | ||
102 | const params: any = {}; | 111 | const params: any = {}; |
103 | getTable?.map((it) => (params[it.key!] = it.value!)); | 112 | getTable?.map((it) => (params[it.key!] = it.value!)); |
104 | if (params['keys']) { | 113 | if (params['keys']) { |
@@ -235,7 +235,9 @@ | @@ -235,7 +235,9 @@ | ||
235 | if (f.key === 'organizationId') organizationId = f.value; | 235 | if (f.key === 'organizationId') organizationId = f.value; |
236 | if (f.key === 'entityId') f.value = null; | 236 | if (f.key === 'entityId') f.value = null; |
237 | }); | 237 | }); |
238 | - getAttributeOptions({ deviceProfileId: e.value }); | 238 | + if (e.value) { |
239 | + getAttributeOptions({ deviceProfileId: e.value }); | ||
240 | + } | ||
239 | if (organizationId !== '') { | 241 | if (organizationId !== '') { |
240 | getEntityOptions(organizationId, e.value); | 242 | getEntityOptions(organizationId, e.value); |
241 | } | 243 | } |
@@ -5,9 +5,14 @@ export const useUtils = () => { | @@ -5,9 +5,14 @@ export const useUtils = () => { | ||
5 | list?.forEach((it) => { | 5 | list?.forEach((it) => { |
6 | const keys = it.key.split(','); | 6 | const keys = it.key.split(','); |
7 | const temp = keys.map((item) => { | 7 | const temp = keys.map((item) => { |
8 | - const obj: { key: string; value: string } = { key: '', value: '' }; | 8 | + const obj: { key: string; value: string; required: boolean } = { |
9 | + key: '', | ||
10 | + value: '', | ||
11 | + required: false, | ||
12 | + }; | ||
9 | obj.key = item; | 13 | obj.key = item; |
10 | obj.value = item === 'scope' ? it.value : ''; | 14 | obj.value = item === 'scope' ? it.value : ''; |
15 | + obj.required = it.required; | ||
11 | return obj; | 16 | return obj; |
12 | }); | 17 | }); |
13 | temps = temp; | 18 | temps = temp; |
@@ -36,5 +41,20 @@ export const useUtils = () => { | @@ -36,5 +41,20 @@ export const useUtils = () => { | ||
36 | type: '0', | 41 | type: '0', |
37 | }, | 42 | }, |
38 | }; | 43 | }; |
39 | - return { getMultipleKeys, pushObj, resetReqHttpType, resetUpdateSchema }; | 44 | + //对象转get params参数 |
45 | + const convertObj = (data: object) => { | ||
46 | + const _result: any = []; | ||
47 | + for (const key in data) { | ||
48 | + const value = data[key]; | ||
49 | + if (value.constructor == Array) { | ||
50 | + value.forEach(function (_value) { | ||
51 | + _result.push(key + '=' + _value); | ||
52 | + }); | ||
53 | + } else { | ||
54 | + _result.push(key + '=' + value); | ||
55 | + } | ||
56 | + } | ||
57 | + return _result.join('&'); | ||
58 | + }; | ||
59 | + return { getMultipleKeys, pushObj, resetReqHttpType, resetUpdateSchema, convertObj }; | ||
40 | }; | 60 | }; |
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | - <CollapseContainer style="background-color: #f2f2f2" :title="`${title} ${index + 1}`"> | 3 | + <CollapseContainer :title="`${title} ${index + 1}`"> |
4 | <template #action> | 4 | <template #action> |
5 | <div class="flex"> | 5 | <div class="flex"> |
6 | <div class="flex"> | 6 | <div class="flex"> |
1 | <template> | 1 | <template> |
2 | - <CollapseContainer style="background-color: #f2f2f2" :title="`执行动作 ${actionIndex + 1}`"> | 2 | + <CollapseContainer :title="`执行动作 ${actionIndex + 1}`"> |
3 | <template #action> | 3 | <template #action> |
4 | <Tooltip title="移除" v-if="actionData.length > 1"> | 4 | <Tooltip title="移除" v-if="actionData.length > 1"> |
5 | <Icon | 5 | <Icon |
1 | -<template> | ||
2 | - <div> | ||
3 | - <BasicDrawer | ||
4 | - v-bind="$attrs" | ||
5 | - :title="getTitle" | ||
6 | - @register="register" | ||
7 | - width="500px" | ||
8 | - @ok="handleSubmit" | ||
9 | - showFooter | ||
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, unref } 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'; | ||
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: any = ref(false); | ||
44 | - const isView = ref(true); | ||
45 | - const aceEditor = ref(); | ||
46 | - const aceRef = ref(); | ||
47 | - const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本')); | ||
48 | - const editId = ref(''); | ||
49 | - const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | ||
50 | - resetFields(); | ||
51 | - setDrawerProps({ confirmLoading: false }); | ||
52 | - isUpdate.value = data.isUpdate; | ||
53 | - initEditor(data.record?.configuration.jsScript); | ||
54 | - switch (isUpdate.value) { | ||
55 | - case 'view': | ||
56 | - isView.value = false; | ||
57 | - setDrawerProps({ | ||
58 | - showFooter: unref(isView), | ||
59 | - title: '查看转换脚本', | ||
60 | - loading: false, | ||
61 | - }); | ||
62 | - editId.value = data.record.id; | ||
63 | - setFieldsValue(data.record); | ||
64 | - break; | ||
65 | - case true: | ||
66 | - isView.value = true; | ||
67 | - setDrawerProps({ | ||
68 | - showFooter: unref(isView), | ||
69 | - title: '编辑转换脚本', | ||
70 | - loading: false, | ||
71 | - }); | ||
72 | - editId.value = data.record.id; | ||
73 | - setFieldsValue(data.record); | ||
74 | - break; | ||
75 | - case false: | ||
76 | - isView.value = true; | ||
77 | - setDrawerProps({ | ||
78 | - showFooter: unref(isView), | ||
79 | - title: '新增转换脚本', | ||
80 | - loading: false, | ||
81 | - }); | ||
82 | - break; | ||
83 | - } | ||
84 | - }); | ||
85 | - const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({ | ||
86 | - showActionButtonGroup: false, | ||
87 | - colProps: { span: 24 }, | ||
88 | - schemas: formSchema, | ||
89 | - }); | ||
90 | - | ||
91 | - // 初始化编辑器 | ||
92 | - const initEditor = (jsScript?: string) => { | ||
93 | - aceEditor.value = ace.edit(aceRef.value, { | ||
94 | - maxLines: 12, // 最大行数,超过会自动出现滚动条 | ||
95 | - minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | ||
96 | - fontSize: 14, // 编辑器内字体大小 | ||
97 | - theme: 'ace/theme/chrome', // 默认设置的主题 | ||
98 | - mode: 'ace/mode/javascript', // 默认设置的语言模式 | ||
99 | - tabSize: 2, // 制表符设置为 4 个空格大小 | ||
100 | - }); | ||
101 | - | ||
102 | - aceEditor.value.setOptions({ | ||
103 | - enableBasicAutocompletion: true, | ||
104 | - enableLiveAutocompletion: true, | ||
105 | - }); | ||
106 | - aceEditor.value.setValue(jsScript ?? 'return {msg: msg, metadata: metadata};'); | ||
107 | - beautify(aceEditor.value.session); | ||
108 | - }; | ||
109 | - | ||
110 | - const testTransformFunc = () => { | ||
111 | - closeDrawer(); | ||
112 | - const jsCode = aceEditor.value.getValue(); | ||
113 | - emit('isStatus', { status: 1, jsCode }); | ||
114 | - }; | ||
115 | - const handleSubmit = async () => { | ||
116 | - const editIdPost = isUpdate.value ? { id: editId.value } : {}; | ||
117 | - try { | ||
118 | - setDrawerProps({ confirmLoading: true }); | ||
119 | - const fieldsValue = await validate(); | ||
120 | - if (!fieldsValue) return; | ||
121 | - await createOrEditTransformScriptApi({ | ||
122 | - configuration: { | ||
123 | - jsScript: aceEditor.value.getValue(), | ||
124 | - }, | ||
125 | - type: 'org.thingsboard.rule.engine.transform.TbTransformMsgNode', | ||
126 | - ...fieldsValue, | ||
127 | - ...editIdPost, | ||
128 | - }); | ||
129 | - closeDrawer(); | ||
130 | - emit('success'); | ||
131 | - const { createMessage } = useMessage(); | ||
132 | - createMessage.success('保存成功'); | ||
133 | - } catch (e) { | ||
134 | - } finally { | ||
135 | - setTimeout(() => { | ||
136 | - setDrawerProps({ confirmLoading: false }); | ||
137 | - }, 300); | ||
138 | - } | ||
139 | - }; | ||
140 | - const handleFormat = () => { | ||
141 | - beautify(aceEditor.value.session); | ||
142 | - }; | ||
143 | - defineExpose({ aceEditor }); | ||
144 | -</script> | 1 | +<template> |
2 | + <div> | ||
3 | + <BasicDrawer | ||
4 | + v-bind="$attrs" | ||
5 | + :title="getTitle" | ||
6 | + @register="register" | ||
7 | + width="500px" | ||
8 | + @ok="handleSubmit" | ||
9 | + showFooter | ||
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, unref } 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'; | ||
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/theme-terminal'; // 默认设置的主题 | ||
40 | + import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式 | ||
41 | + import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js'; | ||
42 | + import { useAppStore } from '/@/store/modules/app'; | ||
43 | + | ||
44 | + const emit = defineEmits(['register', 'isStatus', 'success']); | ||
45 | + const userStore = useAppStore(); | ||
46 | + const getAceClass = computed((): string => userStore.getDarkMode); | ||
47 | + const isUpdate: any = ref(false); | ||
48 | + const isView = ref(true); | ||
49 | + const aceEditor = ref(); | ||
50 | + const aceRef = ref(); | ||
51 | + const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本')); | ||
52 | + const editId = ref(''); | ||
53 | + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { | ||
54 | + resetFields(); | ||
55 | + setDrawerProps({ confirmLoading: false }); | ||
56 | + isUpdate.value = data.isUpdate; | ||
57 | + initEditor(data.record?.configuration.jsScript); | ||
58 | + switch (isUpdate.value) { | ||
59 | + case 'view': | ||
60 | + isView.value = false; | ||
61 | + setDrawerProps({ | ||
62 | + showFooter: unref(isView), | ||
63 | + title: '查看转换脚本', | ||
64 | + loading: false, | ||
65 | + }); | ||
66 | + editId.value = data.record.id; | ||
67 | + setFieldsValue(data.record); | ||
68 | + break; | ||
69 | + case true: | ||
70 | + isView.value = true; | ||
71 | + setDrawerProps({ | ||
72 | + showFooter: unref(isView), | ||
73 | + title: '编辑转换脚本', | ||
74 | + loading: false, | ||
75 | + }); | ||
76 | + editId.value = data.record.id; | ||
77 | + setFieldsValue(data.record); | ||
78 | + break; | ||
79 | + case false: | ||
80 | + isView.value = true; | ||
81 | + setDrawerProps({ | ||
82 | + showFooter: unref(isView), | ||
83 | + title: '新增转换脚本', | ||
84 | + loading: false, | ||
85 | + }); | ||
86 | + break; | ||
87 | + } | ||
88 | + }); | ||
89 | + const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({ | ||
90 | + showActionButtonGroup: false, | ||
91 | + colProps: { span: 24 }, | ||
92 | + schemas: formSchema, | ||
93 | + }); | ||
94 | + | ||
95 | + // 初始化编辑器 | ||
96 | + const initEditor = (jsScript?: string) => { | ||
97 | + aceEditor.value = ace.edit(aceRef.value, { | ||
98 | + maxLines: 12, // 最大行数,超过会自动出现滚动条 | ||
99 | + minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | ||
100 | + fontSize: 14, // 编辑器内字体大小 | ||
101 | + theme: 'ace/theme/chrome', // 默认设置的主题 | ||
102 | + mode: 'ace/mode/javascript', // 默认设置的语言模式 | ||
103 | + tabSize: 2, // 制表符设置为 4 个空格大小 | ||
104 | + }); | ||
105 | + | ||
106 | + aceEditor.value.setOptions({ | ||
107 | + enableBasicAutocompletion: true, | ||
108 | + enableLiveAutocompletion: true, | ||
109 | + theme: getAceClass.value === 'dark' ? 'ace/theme/terminal' : 'ace/theme/chrome', | ||
110 | + }); | ||
111 | + aceEditor.value.setValue(jsScript ?? 'return {msg: msg, metadata: metadata};'); | ||
112 | + beautify(aceEditor.value.session); | ||
113 | + }; | ||
114 | + | ||
115 | + const testTransformFunc = () => { | ||
116 | + closeDrawer(); | ||
117 | + const jsCode = aceEditor.value.getValue(); | ||
118 | + emit('isStatus', { status: 1, jsCode }); | ||
119 | + }; | ||
120 | + const handleSubmit = async () => { | ||
121 | + const editIdPost = isUpdate.value ? { id: editId.value } : {}; | ||
122 | + try { | ||
123 | + setDrawerProps({ confirmLoading: true }); | ||
124 | + const fieldsValue = await validate(); | ||
125 | + if (!fieldsValue) return; | ||
126 | + await createOrEditTransformScriptApi({ | ||
127 | + configuration: { | ||
128 | + jsScript: aceEditor.value.getValue(), | ||
129 | + }, | ||
130 | + type: 'org.thingsboard.rule.engine.transform.TbTransformMsgNode', | ||
131 | + ...fieldsValue, | ||
132 | + ...editIdPost, | ||
133 | + }); | ||
134 | + closeDrawer(); | ||
135 | + emit('success'); | ||
136 | + const { createMessage } = useMessage(); | ||
137 | + createMessage.success('保存成功'); | ||
138 | + } catch (e) { | ||
139 | + } finally { | ||
140 | + setTimeout(() => { | ||
141 | + setDrawerProps({ confirmLoading: false }); | ||
142 | + }, 300); | ||
143 | + } | ||
144 | + }; | ||
145 | + const handleFormat = () => { | ||
146 | + beautify(aceEditor.value.session); | ||
147 | + }; | ||
148 | + defineExpose({ aceEditor }); | ||
149 | +</script> |
1 | -<template> | ||
2 | - <div> | ||
3 | - <a-form | ||
4 | - ref="formRef" | ||
5 | - :model="scriptForm" | ||
6 | - name="basic" | ||
7 | - :label-col="{ span: 4 }" | ||
8 | - :wrapper-col="{ span: 16 }" | ||
9 | - autocomplete="off" | ||
10 | - > | ||
11 | - <a-form-item | ||
12 | - :label="ifAdd ? '名称' : '输入参数(params)'" | ||
13 | - :name="ifAdd ? 'name' : 'params'" | ||
14 | - :rules="[{ required: true, message: ifAdd ? '请输入脚本名称' : '请输入参数' }]" | ||
15 | - > | ||
16 | - <a-input | ||
17 | - v-if="ifAdd" | ||
18 | - :maxlength="36" | ||
19 | - v-model:value="scriptForm.name" | ||
20 | - placeholder="请输入脚本名称" | ||
21 | - /> | ||
22 | - <a-input | ||
23 | - @change="handleInputChange" | ||
24 | - v-else | ||
25 | - v-model:value="scriptForm.params" | ||
26 | - placeholder="请输入参数" | ||
27 | - /> | ||
28 | - </a-form-item> | ||
29 | - <a-form-item | ||
30 | - label="上报数据类型" | ||
31 | - name="dataType" | ||
32 | - :rules="[{ required: true, message: '请选择上报数据类型' }]" | ||
33 | - > | ||
34 | - <a-space direction="vertical"> | ||
35 | - <a-radio-group v-model:value="scriptForm.dataType" :options="typeOptions" /> | ||
36 | - </a-space> | ||
37 | - </a-form-item> | ||
38 | - <a-form-item | ||
39 | - label="保存原始数据" | ||
40 | - name="saveOriginalData" | ||
41 | - :rules="[{ required: true, message: '请选择保存原始数据' }]" | ||
42 | - > | ||
43 | - <a-space direction="vertical"> | ||
44 | - <a-radio-group v-model:value="scriptForm.saveOriginalData" :options="originalOptions" /> | ||
45 | - </a-space> | ||
46 | - </a-form-item> | ||
47 | - <a-form-item label="脚本内容" :name="ifAdd ? 'convertJs' : 'script'"> | ||
48 | - <Card title="脚本内容" :bodyStyle="{ padding: 0, height: '280px' }"> | ||
49 | - <template #extra> | ||
50 | - <a-button @click="handleFormat" size="small">格式化</a-button> | ||
51 | - <Tooltip :title="defaultTitle" class="ml-2"> | ||
52 | - <QuestionCircleOutlined style="font-size: 1rem" /> | ||
53 | - </Tooltip> | ||
54 | - </template> | ||
55 | - <div ref="aceRef" class="overflow-hidden"></div> | ||
56 | - </Card> | ||
57 | - <Button @click="handleCopy" class="mt-4"> | ||
58 | - <template #icon> | ||
59 | - <CopyOutlined /> | ||
60 | - </template> | ||
61 | - copy | ||
62 | - </Button> | ||
63 | - </a-form-item> | ||
64 | - <a-form-item | ||
65 | - :label="ifAdd ? '备注' : '输出参数(output)'" | ||
66 | - :name="ifAdd ? 'description' : 'output'" | ||
67 | - > | ||
68 | - <a-textarea | ||
69 | - :rows="3" | ||
70 | - v-if="ifAdd" | ||
71 | - v-model:value="scriptForm.description" | ||
72 | - placeholder="请输入备注" | ||
73 | - :maxlength="255" | ||
74 | - /> | ||
75 | - <a-textarea | ||
76 | - :rows="3" | ||
77 | - v-else | ||
78 | - v-model:value="scriptForm.output" | ||
79 | - placeholder="输出参数为服务端返回的内容" | ||
80 | - :maxlength="255" | ||
81 | - /> | ||
82 | - </a-form-item> | ||
83 | - </a-form> | ||
84 | - </div> | ||
85 | -</template> | ||
86 | -<script setup lang="ts"> | ||
87 | - import { ref, unref, reactive, onMounted, toRefs, nextTick } from 'vue'; | ||
88 | - import ace from 'ace-builds'; | ||
89 | - import { Card, Button, Tooltip } from 'ant-design-vue'; | ||
90 | - import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 | ||
91 | - import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式 | ||
92 | - import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js'; | ||
93 | - import { CopyOutlined } from '@ant-design/icons-vue'; | ||
94 | - import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; | ||
95 | - import { useMessage } from '/@/hooks/web/useMessage'; | ||
96 | - import { findDictItemByCode } from '/@/api/system/dict'; | ||
97 | - import { QuestionCircleOutlined } from '@ant-design/icons-vue'; | ||
98 | - import { defaultTitle } from './config.data'; | ||
99 | - | ||
100 | - defineEmits(['register']); | ||
101 | - const props = defineProps({ | ||
102 | - ifAdd: { type: Boolean, default: true }, | ||
103 | - }); | ||
104 | - const scriptForm = reactive({ | ||
105 | - name: '', | ||
106 | - description: '', | ||
107 | - convertJs: '', | ||
108 | - script: '', | ||
109 | - params: '', | ||
110 | - output: '', | ||
111 | - dataType: 'HEX', | ||
112 | - saveOriginalData: 'true', | ||
113 | - }); | ||
114 | - const reportTypeOptions = reactive({ | ||
115 | - typeOptions: [], | ||
116 | - originalOptions: [], | ||
117 | - }); | ||
118 | - const { originalOptions, typeOptions } = toRefs(reportTypeOptions); | ||
119 | - const { createMessage } = useMessage(); | ||
120 | - const { clipboardRef, copiedRef } = useCopyToClipboard(); | ||
121 | - const aceEditor = ref(); | ||
122 | - const aceRef = ref(); | ||
123 | - const setDefaultRadio = (p1, p2) => { | ||
124 | - scriptForm.dataType = p1; | ||
125 | - scriptForm.saveOriginalData = p2; | ||
126 | - }; | ||
127 | - onMounted(async () => { | ||
128 | - const res: any = await findDictItemByCode({ | ||
129 | - dictCode: 'report_data_type', | ||
130 | - }); | ||
131 | - const resOriginal: any = await findDictItemByCode({ | ||
132 | - dictCode: 'original_data', | ||
133 | - }); | ||
134 | - reportTypeOptions.typeOptions = res.map((m) => { | ||
135 | - return { label: m.itemText, value: m.itemValue }; | ||
136 | - }); | ||
137 | - reportTypeOptions.originalOptions = resOriginal.map((m) => { | ||
138 | - return { label: m.itemText, value: m.itemValue }; | ||
139 | - }); | ||
140 | - }); | ||
141 | - // 初始化编辑器 | ||
142 | - const initEditor = () => { | ||
143 | - aceEditor.value = ace.edit(aceRef.value, { | ||
144 | - maxLines: 12, // 最大行数,超过会自动出现滚动条 | ||
145 | - minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | ||
146 | - fontSize: 14, // 编辑器内字体大小 | ||
147 | - theme: 'ace/theme/chrome', // 默认设置的主题 | ||
148 | - mode: 'ace/mode/javascript', // 默认设置的语言模式 | ||
149 | - tabSize: 2, // 制表符设置为 4 个空格大小 | ||
150 | - }); | ||
151 | - | ||
152 | - aceEditor.value.setOptions({ | ||
153 | - enableBasicAutocompletion: true, | ||
154 | - enableLiveAutocompletion: true, | ||
155 | - }); | ||
156 | - aceEditor.value.setValue(''); | ||
157 | - beautify(aceEditor.value.session); | ||
158 | - // scriptForm.convertJs = aceEditor.value.getValue(); | ||
159 | - }; | ||
160 | - const handleCopy = () => { | ||
161 | - const valueRef = aceEditor.value.getValue(); | ||
162 | - const value = unref(valueRef); | ||
163 | - if (!value) { | ||
164 | - createMessage.warning('请输入要拷贝的内容!'); | ||
165 | - return; | ||
166 | - } | ||
167 | - clipboardRef.value = value; | ||
168 | - if (unref(copiedRef)) { | ||
169 | - createMessage.success('复制成功!'); | ||
170 | - } | ||
171 | - }; | ||
172 | - const formRef = ref(); | ||
173 | - const getFormData = async () => { | ||
174 | - const value = await formRef.value.validateFields(); | ||
175 | - if (props.ifAdd) { | ||
176 | - scriptForm.convertJs = aceEditor.value.getValue(); | ||
177 | - if (scriptForm.convertJs == '') { | ||
178 | - createMessage.error('请编写脚本内容'); | ||
179 | - throw '请编写脚本内容'; | ||
180 | - } | ||
181 | - } else { | ||
182 | - scriptForm.script = aceEditor.value.getValue(); | ||
183 | - if (scriptForm.script == '') { | ||
184 | - createMessage.error('请编写脚本内容'); | ||
185 | - throw '请编写脚本内容'; | ||
186 | - } | ||
187 | - } | ||
188 | - if (!value) return; | ||
189 | - if (scriptForm.params) { | ||
190 | - const trimParams = scriptForm.params.replace(/\s*/g, ''); | ||
191 | - Reflect.set(value, 'params', trimParams); | ||
192 | - } | ||
193 | - if (scriptForm.convertJs.length > 1000) { | ||
194 | - createMessage.error('脚本内容长度不能大于1000'); | ||
195 | - throw '脚本内容长度不能大于1000'; | ||
196 | - } | ||
197 | - return { | ||
198 | - ...value, | ||
199 | - ...{ convertJs: props.ifAdd ? scriptForm.convertJs : null }, | ||
200 | - ...{ script: !props.ifAdd ? scriptForm.script : null }, | ||
201 | - ...{ saveOriginalData: scriptForm.saveOriginalData === 'false' ? false : true }, | ||
202 | - }; | ||
203 | - }; | ||
204 | - const handleInputChange = (e) => { | ||
205 | - const trimParams = e.target.value.replace(/\s*/g, ''); | ||
206 | - Reflect.set(scriptForm, 'params', trimParams); | ||
207 | - }; | ||
208 | - const setFormData = (v) => { | ||
209 | - if (v) { | ||
210 | - for (let i in scriptForm) { | ||
211 | - Reflect.set(scriptForm, i, v[i]); | ||
212 | - } | ||
213 | - nextTick(() => { | ||
214 | - setTimeout(() => { | ||
215 | - scriptForm.saveOriginalData = v.saveOriginalData === false ? 'false' : 'true'; | ||
216 | - scriptForm.dataType = v.dataType; | ||
217 | - }, 10); | ||
218 | - }); | ||
219 | - aceEditor.value.setValue(v.convertJs); | ||
220 | - handleFormat(); | ||
221 | - } | ||
222 | - }; | ||
223 | - const setScriptContentData = (v) => { | ||
224 | - aceEditor.value.setValue(v); | ||
225 | - handleFormat(); | ||
226 | - }; | ||
227 | - const resetFormData = () => { | ||
228 | - for (let i in scriptForm) { | ||
229 | - Reflect.set(scriptForm, i, ''); | ||
230 | - } | ||
231 | - }; | ||
232 | - const setScriptOutputData = (v) => { | ||
233 | - scriptForm.output = v; | ||
234 | - }; | ||
235 | - const handleFormat = () => beautify(aceEditor.value.session); | ||
236 | - | ||
237 | - defineExpose({ | ||
238 | - initEditor, | ||
239 | - getFormData, | ||
240 | - resetFormData, | ||
241 | - setFormData, | ||
242 | - setScriptContentData, | ||
243 | - setScriptOutputData, | ||
244 | - setDefaultRadio, | ||
245 | - }); | ||
246 | -</script> | ||
247 | -<style lang="less" scoped> | ||
248 | - @import url('./ConverScriptModal.less'); | ||
249 | -</style> | 1 | +<template> |
2 | + <div> | ||
3 | + <a-form | ||
4 | + ref="formRef" | ||
5 | + :model="scriptForm" | ||
6 | + name="basic" | ||
7 | + :label-col="{ span: 4 }" | ||
8 | + :wrapper-col="{ span: 16 }" | ||
9 | + autocomplete="off" | ||
10 | + > | ||
11 | + <a-form-item | ||
12 | + :label="ifAdd ? '名称' : '输入参数(params)'" | ||
13 | + :name="ifAdd ? 'name' : 'params'" | ||
14 | + :rules="[{ required: true, message: ifAdd ? '请输入脚本名称' : '请输入参数' }]" | ||
15 | + > | ||
16 | + <a-input | ||
17 | + v-if="ifAdd" | ||
18 | + :maxlength="36" | ||
19 | + @change="handleInputChange" | ||
20 | + v-model:value="scriptForm.name" | ||
21 | + placeholder="请输入脚本名称" | ||
22 | + /> | ||
23 | + <a-input | ||
24 | + @change="handleInputChange" | ||
25 | + v-else | ||
26 | + v-model:value="scriptForm.params" | ||
27 | + placeholder="请输入参数" | ||
28 | + /> | ||
29 | + </a-form-item> | ||
30 | + <a-form-item | ||
31 | + label="上报数据类型" | ||
32 | + name="dataType" | ||
33 | + :rules="[{ required: false, message: '请选择上报数据类型' }]" | ||
34 | + > | ||
35 | + <a-space direction="vertical"> | ||
36 | + <a-radio-group v-model:value="scriptForm.dataType" :options="typeOptions" /> | ||
37 | + </a-space> | ||
38 | + </a-form-item> | ||
39 | + <a-form-item | ||
40 | + label="脚本类型" | ||
41 | + name="scriptType" | ||
42 | + :rules="[{ required: true, message: '请选择脚本类型' }]" | ||
43 | + > | ||
44 | + <a-space direction="vertical"> | ||
45 | + <a-radio-group | ||
46 | + @change="handleScriptType" | ||
47 | + v-model:value="scriptForm.scriptType" | ||
48 | + :options="scriptTypeOptions" | ||
49 | + /> | ||
50 | + </a-space> | ||
51 | + </a-form-item> | ||
52 | + <a-form-item | ||
53 | + label="保存原始数据" | ||
54 | + name="saveOriginalData" | ||
55 | + :rules="[{ required: true, message: '请选择保存原始数据' }]" | ||
56 | + > | ||
57 | + <a-space direction="vertical"> | ||
58 | + <a-radio-group v-model:value="scriptForm.saveOriginalData" :options="originalOptions" /> | ||
59 | + </a-space> | ||
60 | + </a-form-item> | ||
61 | + <a-form-item label="脚本内容" :name="ifAdd ? 'convertJs' : 'script'"> | ||
62 | + <Card title="脚本内容" :bodyStyle="{ padding: 0, height: '280px' }"> | ||
63 | + <template #extra> | ||
64 | + <a-button @click="handleFormat" size="small">格式化</a-button> | ||
65 | + <Tooltip :title="defaultTitle" class="ml-2"> | ||
66 | + <QuestionCircleOutlined style="font-size: 1rem" /> | ||
67 | + </Tooltip> | ||
68 | + </template> | ||
69 | + {{ getAceClass }} | ||
70 | + <div ref="aceRef" class="overflow-hidden"></div> | ||
71 | + </Card> | ||
72 | + <Button @click="handleCopy" class="mt-4"> | ||
73 | + <template #icon> | ||
74 | + <CopyOutlined /> | ||
75 | + </template> | ||
76 | + copy | ||
77 | + </Button> | ||
78 | + </a-form-item> | ||
79 | + <a-form-item | ||
80 | + :label="ifAdd ? '备注' : '输出参数(output)'" | ||
81 | + :name="ifAdd ? 'description' : 'output'" | ||
82 | + > | ||
83 | + <a-textarea | ||
84 | + :rows="3" | ||
85 | + v-if="ifAdd" | ||
86 | + v-model:value="scriptForm.description" | ||
87 | + placeholder="请输入备注" | ||
88 | + :maxlength="255" | ||
89 | + /> | ||
90 | + <a-textarea | ||
91 | + :rows="3" | ||
92 | + v-else | ||
93 | + v-model:value="scriptForm.output" | ||
94 | + placeholder="输出参数为服务端返回的内容" | ||
95 | + :maxlength="255" | ||
96 | + /> | ||
97 | + </a-form-item> | ||
98 | + </a-form> | ||
99 | + </div> | ||
100 | +</template> | ||
101 | +<script setup lang="ts"> | ||
102 | + import { ref, unref, reactive, onMounted, toRefs, nextTick, computed } from 'vue'; | ||
103 | + import ace from 'ace-builds'; | ||
104 | + import { Card, Button, Tooltip } from 'ant-design-vue'; | ||
105 | + import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 | ||
106 | + import 'ace-builds/src-noconflict/theme-terminal'; // 默认设置的主题 | ||
107 | + import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式 | ||
108 | + import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js'; | ||
109 | + import { CopyOutlined } from '@ant-design/icons-vue'; | ||
110 | + import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; | ||
111 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
112 | + import { findDictItemByCode } from '/@/api/system/dict'; | ||
113 | + import { QuestionCircleOutlined } from '@ant-design/icons-vue'; | ||
114 | + import { defaultTitle, defaultScriptTypeContent } from './config.data'; | ||
115 | + import { useAppStore } from '/@/store/modules/app'; | ||
116 | + | ||
117 | + defineEmits(['register']); | ||
118 | + const props = defineProps({ | ||
119 | + ifAdd: { type: Boolean, default: true }, | ||
120 | + }); | ||
121 | + | ||
122 | + const scriptForm = reactive({ | ||
123 | + name: '', | ||
124 | + description: '', | ||
125 | + convertJs: '', | ||
126 | + script: '', | ||
127 | + params: '', | ||
128 | + output: '', | ||
129 | + dataType: 'HEX', | ||
130 | + scriptType: 'TRANSPORT_TCP_UP', | ||
131 | + saveOriginalData: 'true', | ||
132 | + }); | ||
133 | + | ||
134 | + const reportTypeOptions = reactive({ | ||
135 | + typeOptions: [], | ||
136 | + originalOptions: [], | ||
137 | + scriptTypeOptions: [], | ||
138 | + }); | ||
139 | + | ||
140 | + const { originalOptions, typeOptions, scriptTypeOptions } = toRefs(reportTypeOptions); | ||
141 | + | ||
142 | + const { createMessage } = useMessage(); | ||
143 | + | ||
144 | + const { clipboardRef, copiedRef } = useCopyToClipboard(); | ||
145 | + | ||
146 | + const aceEditor = ref(); | ||
147 | + | ||
148 | + const aceRef = ref(); | ||
149 | + | ||
150 | + const userStore = useAppStore(); | ||
151 | + | ||
152 | + const getAceClass = computed((): string => userStore.getDarkMode); | ||
153 | + | ||
154 | + const setDefaultRadio = (p1, p2, p3) => { | ||
155 | + scriptForm.dataType = p1; | ||
156 | + scriptForm.saveOriginalData = p2; | ||
157 | + scriptForm.scriptType = p3; | ||
158 | + }; | ||
159 | + | ||
160 | + const getDictValue = async (dict_type) => { | ||
161 | + const res = await findDictItemByCode({ | ||
162 | + dictCode: dict_type, | ||
163 | + }); | ||
164 | + return res.map((m) => { | ||
165 | + return { label: m.itemText, value: m.itemValue }; | ||
166 | + }); | ||
167 | + }; | ||
168 | + | ||
169 | + onMounted(async () => { | ||
170 | + reportTypeOptions.typeOptions = (await getDictValue('report_data_type')) as never as any; | ||
171 | + reportTypeOptions.originalOptions = (await getDictValue('original_data')) as never as any; | ||
172 | + reportTypeOptions.scriptTypeOptions = (await getDictValue('script_type')) as never as any; | ||
173 | + }); | ||
174 | + | ||
175 | + // 初始化编辑器 | ||
176 | + const initEditor = () => { | ||
177 | + aceEditor.value = ace.edit(aceRef.value, { | ||
178 | + maxLines: 12, // 最大行数,超过会自动出现滚动条 | ||
179 | + minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | ||
180 | + fontSize: 14, // 编辑器内字体大小 | ||
181 | + theme: 'ace/theme/chrome', // 默认设置的主题 | ||
182 | + mode: 'ace/mode/javascript', // 默认设置的语言模式 | ||
183 | + tabSize: 2, // 制表符设置为 4 个空格大小 | ||
184 | + }); | ||
185 | + | ||
186 | + aceEditor.value.setOptions({ | ||
187 | + enableBasicAutocompletion: true, | ||
188 | + enableLiveAutocompletion: true, | ||
189 | + theme: getAceClass.value === 'dark' ? 'ace/theme/terminal' : 'ace/theme/chrome', | ||
190 | + }); | ||
191 | + aceEditor.value.setValue(''); | ||
192 | + beautify(aceEditor.value.session); | ||
193 | + switchScriptTypeGetContent('TRANSPORT_TCP_UP'); | ||
194 | + }; | ||
195 | + | ||
196 | + const handleScriptType = ({ target }) => { | ||
197 | + const { value } = target; | ||
198 | + switchScriptTypeGetContent(value); | ||
199 | + }; | ||
200 | + | ||
201 | + const switchScriptTypeGetContent = (type) => { | ||
202 | + if (type === 'TRANSPORT_TCP_DOWN') | ||
203 | + Reflect.set( | ||
204 | + defaultScriptTypeContent, | ||
205 | + 'TRANSPORT_TCP_DOWN', | ||
206 | + `out.datas = "${scriptForm.params}";out.deviceName = "sensor";` | ||
207 | + ); | ||
208 | + aceEditor.value.setValue(defaultScriptTypeContent[type]); | ||
209 | + }; | ||
210 | + | ||
211 | + const handleCopy = () => { | ||
212 | + const valueRef = aceEditor.value.getValue(); | ||
213 | + const value = unref(valueRef); | ||
214 | + if (!value) { | ||
215 | + createMessage.warning('请输入要拷贝的内容!'); | ||
216 | + return; | ||
217 | + } | ||
218 | + clipboardRef.value = value; | ||
219 | + if (unref(copiedRef)) { | ||
220 | + createMessage.success('复制成功!'); | ||
221 | + } | ||
222 | + }; | ||
223 | + | ||
224 | + const formRef = ref(); | ||
225 | + | ||
226 | + const getFormData = async () => { | ||
227 | + const value = await formRef.value.validateFields(); | ||
228 | + if (props.ifAdd) { | ||
229 | + scriptForm.convertJs = aceEditor.value.getValue(); | ||
230 | + if (scriptForm.convertJs == '') { | ||
231 | + createMessage.error('请编写脚本内容'); | ||
232 | + throw '请编写脚本内容'; | ||
233 | + } | ||
234 | + } else { | ||
235 | + scriptForm.script = aceEditor.value.getValue(); | ||
236 | + if (scriptForm.script == '') { | ||
237 | + createMessage.error('请编写脚本内容'); | ||
238 | + throw '请编写脚本内容'; | ||
239 | + } | ||
240 | + } | ||
241 | + if (!value) return; | ||
242 | + if (scriptForm.params) { | ||
243 | + const trimParams = scriptForm.params.replace(/\s*/g, ''); | ||
244 | + Reflect.set(value, 'params', trimParams); | ||
245 | + } | ||
246 | + if (scriptForm.convertJs.length > 1000) { | ||
247 | + createMessage.error('脚本内容长度不能大于1000'); | ||
248 | + throw '脚本内容长度不能大于1000'; | ||
249 | + } | ||
250 | + return { | ||
251 | + ...value, | ||
252 | + ...{ convertJs: props.ifAdd ? scriptForm.convertJs : null }, | ||
253 | + ...{ script: !props.ifAdd ? scriptForm.script : null }, | ||
254 | + ...{ saveOriginalData: scriptForm.saveOriginalData === 'false' ? false : true }, | ||
255 | + }; | ||
256 | + }; | ||
257 | + | ||
258 | + const handleInputChange = (e) => { | ||
259 | + const trimParams = e.target.value.replace(/\s*/g, ''); | ||
260 | + Reflect.set(scriptForm, 'params', trimParams); | ||
261 | + if (scriptForm.scriptType === 'TRANSPORT_TCP_DOWN') { | ||
262 | + aceEditor.value.setValue(`out.datas = "${scriptForm.params}";out.deviceName = "sensor";`); | ||
263 | + } | ||
264 | + }; | ||
265 | + | ||
266 | + const setFormData = (v) => { | ||
267 | + if (v) { | ||
268 | + for (let i in scriptForm) { | ||
269 | + Reflect.set(scriptForm, i, v[i]); | ||
270 | + } | ||
271 | + nextTick(() => { | ||
272 | + setTimeout(() => { | ||
273 | + scriptForm.saveOriginalData = v.saveOriginalData === false ? 'false' : 'true'; | ||
274 | + scriptForm.dataType = v.dataType; | ||
275 | + }, 10); | ||
276 | + }); | ||
277 | + aceEditor.value.setValue(v.convertJs); | ||
278 | + handleFormat(); | ||
279 | + } | ||
280 | + }; | ||
281 | + | ||
282 | + const setScriptContentData = (v) => { | ||
283 | + aceEditor.value.setValue(v); | ||
284 | + handleFormat(); | ||
285 | + }; | ||
286 | + | ||
287 | + const resetFormData = () => { | ||
288 | + for (let i in scriptForm) { | ||
289 | + Reflect.set(scriptForm, i, ''); | ||
290 | + } | ||
291 | + }; | ||
292 | + | ||
293 | + const setScriptOutputData = (v) => { | ||
294 | + scriptForm.output = v; | ||
295 | + }; | ||
296 | + | ||
297 | + const handleFormat = () => beautify(aceEditor.value.session); | ||
298 | + | ||
299 | + defineExpose({ | ||
300 | + initEditor, | ||
301 | + getFormData, | ||
302 | + resetFormData, | ||
303 | + setFormData, | ||
304 | + setScriptContentData, | ||
305 | + setScriptOutputData, | ||
306 | + setDefaultRadio, | ||
307 | + }); | ||
308 | +</script> | ||
309 | +<style lang="less" scoped> | ||
310 | + @import url('./ConverScriptModal.less'); | ||
311 | +</style> |
1 | -<template> | ||
2 | - <div> | ||
3 | - <BasicModal | ||
4 | - destroyOnClose | ||
5 | - v-bind="$attrs" | ||
6 | - width="60rem" | ||
7 | - @register="register" | ||
8 | - :title="getTitle" | ||
9 | - :minHeight="500" | ||
10 | - @cancel="handleCancel" | ||
11 | - @ok="handleSubmit" | ||
12 | - > | ||
13 | - <ConverScript :ifAdd="isTest ? false : true" ref="converScriptRef" /> | ||
14 | - </BasicModal> | ||
15 | - </div> | ||
16 | -</template> | ||
17 | -<script setup lang="ts"> | ||
18 | - import { ref, computed, unref, reactive } from 'vue'; | ||
19 | - import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
20 | - import ConverScript from './ConverScript.vue'; | ||
21 | - import { | ||
22 | - createOrEditScriptManage, | ||
23 | - getScriptManageDetail, | ||
24 | - testScriptManage, | ||
25 | - } from '/@/api/scriptmanage/scriptManager'; | ||
26 | - import { useMessage } from '/@/hooks/web/useMessage'; | ||
27 | - | ||
28 | - const emits = defineEmits(['success', 'register']); | ||
29 | - const { createMessage } = useMessage(); | ||
30 | - const converScriptRef = ref<InstanceType<typeof ConverScript>>(); | ||
31 | - const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本')); | ||
32 | - const isUpdate = ref(false); | ||
33 | - const isViewDetail = ref(''); | ||
34 | - const isTest = ref(false); | ||
35 | - const isText = ref(''); | ||
36 | - const isTitle = ref(''); | ||
37 | - const editData = reactive({ | ||
38 | - data: {}, | ||
39 | - }); | ||
40 | - const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | ||
41 | - setModalProps({ loading: true }); | ||
42 | - handleCancel(false); | ||
43 | - isUpdate.value = data.isUpdate; | ||
44 | - isViewDetail.value = data.isView; | ||
45 | - isTest.value = data.isTest; | ||
46 | - isText.value = data.isText; | ||
47 | - isTitle.value = data.isTitle; | ||
48 | - editData.data = data.record; | ||
49 | - setModalProps({ loading: false }); | ||
50 | - converScriptRef.value?.initEditor(); | ||
51 | - if (!unref(isViewDetail)) { | ||
52 | - const title = | ||
53 | - unref(isTitle) == 'edit' | ||
54 | - ? '编辑转换脚本' | ||
55 | - : unref(isTitle) == 'add' | ||
56 | - ? '新增转换脚本' | ||
57 | - : '测试转换脚本'; | ||
58 | - const okText = isText.value == 'test' ? '测试' : '确定'; | ||
59 | - if (unref(isTitle) == 'add') { | ||
60 | - converScriptRef.value?.setDefaultRadio('HEX', 'true'); | ||
61 | - } | ||
62 | - if (unref(isTitle) == 'edit') { | ||
63 | - converScriptRef.value?.setFormData(data.record); | ||
64 | - } | ||
65 | - if (unref(isTitle) == 'test') { | ||
66 | - if (data.record) { | ||
67 | - const res = await getScriptManageDetail(data.record); | ||
68 | - converScriptRef.value?.setFormData(res); | ||
69 | - } else { | ||
70 | - converScriptRef.value?.setDefaultRadio('HEX', 'true'); | ||
71 | - } | ||
72 | - } | ||
73 | - setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText }); | ||
74 | - if (!unref(isUpdate)) { | ||
75 | - } | ||
76 | - } else { | ||
77 | - setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看转换脚本' }); | ||
78 | - const res = await getScriptManageDetail(data.record.id); | ||
79 | - converScriptRef.value?.setFormData(res || {}); | ||
80 | - } | ||
81 | - }); | ||
82 | - | ||
83 | - const handleSubmit = async () => { | ||
84 | - setModalProps({ confirmLoading: true }); | ||
85 | - try { | ||
86 | - const val = await converScriptRef.value?.getFormData(); | ||
87 | - const tempObj = { | ||
88 | - ...editData.data, | ||
89 | - ...val, | ||
90 | - }; | ||
91 | - const res: any = | ||
92 | - isText.value == 'test' | ||
93 | - ? await testScriptManage(val) | ||
94 | - : await createOrEditScriptManage(tempObj); | ||
95 | - createMessage.success( | ||
96 | - unref(isTitle) == 'edit' | ||
97 | - ? '编辑转换脚本成功' | ||
98 | - : unref(isTitle) == 'add' | ||
99 | - ? '新增转换脚本成功' | ||
100 | - : '测试转换脚本成功' | ||
101 | - ); | ||
102 | - if (unref(isTitle) == 'add' || unref(isTitle) == 'edit') { | ||
103 | - setTimeout(() => { | ||
104 | - closeModal(); | ||
105 | - }, 10); | ||
106 | - emits('success', { | ||
107 | - res, | ||
108 | - text: isText.value, | ||
109 | - }); | ||
110 | - } else { | ||
111 | - if (res) { | ||
112 | - converScriptRef.value?.setScriptOutputData(res?.output || res?.error); | ||
113 | - } | ||
114 | - } | ||
115 | - } finally { | ||
116 | - setModalProps({ confirmLoading: false }); | ||
117 | - } | ||
118 | - }; | ||
119 | - const handleCancel = (flag) => { | ||
120 | - if (flag) { | ||
121 | - closeModal(); | ||
122 | - } | ||
123 | - converScriptRef.value?.resetFormData(); | ||
124 | - }; | ||
125 | -</script> | ||
126 | -<style lang="less" scoped> | ||
127 | - @import url('./ConverScriptModal.less'); | ||
128 | -</style> | 1 | +<template> |
2 | + <div> | ||
3 | + <BasicModal | ||
4 | + destroyOnClose | ||
5 | + v-bind="$attrs" | ||
6 | + width="60rem" | ||
7 | + @register="register" | ||
8 | + :title="getTitle" | ||
9 | + :minHeight="500" | ||
10 | + @cancel="handleCancel" | ||
11 | + @ok="handleSubmit" | ||
12 | + > | ||
13 | + <ConverScript :ifAdd="isTest ? false : true" ref="converScriptRef" /> | ||
14 | + </BasicModal> | ||
15 | + </div> | ||
16 | +</template> | ||
17 | +<script setup lang="ts"> | ||
18 | + import { ref, computed, unref, reactive } from 'vue'; | ||
19 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
20 | + import ConverScript from './ConverScript.vue'; | ||
21 | + import { | ||
22 | + createOrEditScriptManage, | ||
23 | + getScriptManageDetail, | ||
24 | + testScriptManage, | ||
25 | + } from '/@/api/scriptmanage/scriptManager'; | ||
26 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
27 | + | ||
28 | + const emits = defineEmits(['success', 'register']); | ||
29 | + const { createMessage } = useMessage(); | ||
30 | + const converScriptRef = ref<InstanceType<typeof ConverScript>>(); | ||
31 | + const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本')); | ||
32 | + const isUpdate = ref(false); | ||
33 | + const isViewDetail = ref(''); | ||
34 | + const isTest = ref(false); | ||
35 | + const isText = ref(''); | ||
36 | + const isTitle = ref(''); | ||
37 | + const editData = reactive({ | ||
38 | + data: {}, | ||
39 | + }); | ||
40 | + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | ||
41 | + setModalProps({ loading: true }); | ||
42 | + handleCancel(false); | ||
43 | + isUpdate.value = data.isUpdate; | ||
44 | + isViewDetail.value = data.isView; | ||
45 | + isTest.value = data.isTest; | ||
46 | + isText.value = data.isText; | ||
47 | + isTitle.value = data.isTitle; | ||
48 | + editData.data = data.record; | ||
49 | + setModalProps({ loading: false }); | ||
50 | + converScriptRef.value?.initEditor(); | ||
51 | + if (!unref(isViewDetail)) { | ||
52 | + const title = | ||
53 | + unref(isTitle) == 'edit' | ||
54 | + ? '编辑转换脚本' | ||
55 | + : unref(isTitle) == 'add' | ||
56 | + ? '新增转换脚本' | ||
57 | + : '测试转换脚本'; | ||
58 | + const okText = isText.value == 'test' ? '测试' : '确定'; | ||
59 | + if (unref(isTitle) == 'add') { | ||
60 | + converScriptRef.value?.setDefaultRadio('HEX', 'true', 'TRANSPORT_TCP_UP'); | ||
61 | + } | ||
62 | + if (unref(isTitle) == 'edit') { | ||
63 | + converScriptRef.value?.setFormData(data.record); | ||
64 | + } | ||
65 | + if (unref(isTitle) == 'test') { | ||
66 | + if (data.record) { | ||
67 | + const res = await getScriptManageDetail(data.record); | ||
68 | + converScriptRef.value?.setFormData(res); | ||
69 | + } else { | ||
70 | + converScriptRef.value?.setDefaultRadio('HEX', 'true', 'TRANSPORT_TCP_UP'); | ||
71 | + } | ||
72 | + } | ||
73 | + setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText }); | ||
74 | + if (!unref(isUpdate)) { | ||
75 | + } | ||
76 | + } else { | ||
77 | + setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看转换脚本' }); | ||
78 | + const res = await getScriptManageDetail(data.record.id); | ||
79 | + converScriptRef.value?.setFormData(res || {}); | ||
80 | + } | ||
81 | + }); | ||
82 | + | ||
83 | + const handleSubmit = async () => { | ||
84 | + setModalProps({ confirmLoading: true }); | ||
85 | + try { | ||
86 | + const val = await converScriptRef.value?.getFormData(); | ||
87 | + const tempObj = { | ||
88 | + ...editData.data, | ||
89 | + ...val, | ||
90 | + }; | ||
91 | + const res: any = | ||
92 | + isText.value == 'test' | ||
93 | + ? await testScriptManage(val) | ||
94 | + : await createOrEditScriptManage(tempObj); | ||
95 | + createMessage.success( | ||
96 | + unref(isTitle) == 'edit' | ||
97 | + ? '编辑转换脚本成功' | ||
98 | + : unref(isTitle) == 'add' | ||
99 | + ? '新增转换脚本成功' | ||
100 | + : '测试转换脚本成功' | ||
101 | + ); | ||
102 | + if (unref(isTitle) == 'add' || unref(isTitle) == 'edit') { | ||
103 | + setTimeout(() => { | ||
104 | + closeModal(); | ||
105 | + }, 10); | ||
106 | + emits('success', { | ||
107 | + res, | ||
108 | + text: isText.value, | ||
109 | + }); | ||
110 | + } else { | ||
111 | + if (res) { | ||
112 | + converScriptRef.value?.setScriptOutputData(res?.output || res?.error); | ||
113 | + } | ||
114 | + } | ||
115 | + } finally { | ||
116 | + setModalProps({ confirmLoading: false }); | ||
117 | + } | ||
118 | + }; | ||
119 | + const handleCancel = (flag) => { | ||
120 | + if (flag) { | ||
121 | + closeModal(); | ||
122 | + } | ||
123 | + converScriptRef.value?.resetFormData(); | ||
124 | + }; | ||
125 | +</script> | ||
126 | +<style lang="less" scoped> | ||
127 | + @import url('./ConverScriptModal.less'); | ||
128 | +</style> |
1 | -import { BasicColumn, FormSchema } from '/@/components/Table'; | ||
2 | -import moment from 'moment'; | ||
3 | -import { h } from 'vue'; | ||
4 | - | ||
5 | -// 表格配置 | ||
6 | -export const columns: BasicColumn[] = [ | ||
7 | - { | ||
8 | - title: '脚本名称', | ||
9 | - dataIndex: 'name', | ||
10 | - width: 80, | ||
11 | - }, | ||
12 | - { | ||
13 | - title: '脚本状态', | ||
14 | - dataIndex: 'status', | ||
15 | - width: 120, | ||
16 | - slots: { customRender: 'status' }, | ||
17 | - }, | ||
18 | - { | ||
19 | - title: '脚本内容', | ||
20 | - dataIndex: 'convertJs', | ||
21 | - width: 120, | ||
22 | - slots: { customRender: 'convertJs' }, | ||
23 | - }, | ||
24 | - { | ||
25 | - title: '备注', | ||
26 | - dataIndex: 'description', | ||
27 | - width: 120, | ||
28 | - }, | ||
29 | - { | ||
30 | - title: '创建时间', | ||
31 | - dataIndex: 'createTime', | ||
32 | - width: 180, | ||
33 | - }, | ||
34 | -]; | ||
35 | - | ||
36 | -// 查询配置 | ||
37 | -export const searchFormSchema: FormSchema[] = [ | ||
38 | - { | ||
39 | - field: 'name', | ||
40 | - label: '脚本名称', | ||
41 | - component: 'Input', | ||
42 | - colProps: { span: 6 }, | ||
43 | - componentProps: { | ||
44 | - maxLength: 36, | ||
45 | - placeholder: '请输入配置名称', | ||
46 | - }, | ||
47 | - }, | ||
48 | - { | ||
49 | - field: 'sendTime', | ||
50 | - label: '创建时间', | ||
51 | - component: 'RangePicker', | ||
52 | - componentProps: { | ||
53 | - showTime: { | ||
54 | - defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')], | ||
55 | - }, | ||
56 | - }, | ||
57 | - colProps: { span: 6 }, | ||
58 | - }, | ||
59 | -]; | ||
60 | - | ||
61 | -export const defaultTitle = h('div', { style: 'background:#404040' }, [ | ||
62 | - h('h3', { style: 'color:white' }, '示例'), | ||
63 | - h('h3', { style: 'color:white' }, '输入参数:'), | ||
64 | - h('h3', { style: 'color:white' }, '0103040150008D3BBB'), | ||
65 | - h('h3', { style: 'color:white' }, [ | ||
66 | - h('h3', { style: 'color:white' }, '脚本内容:'), | ||
67 | - h( | ||
68 | - 'h3', | ||
69 | - { style: 'color:white' }, | ||
70 | - "out.humidity = (parseInt('0x'+params.substr(6, 4))*0.1).toFixed(2);" | ||
71 | - ), | ||
72 | - h( | ||
73 | - 'h3', | ||
74 | - { style: 'color:white' }, | ||
75 | - "out.temperature = (parseInt('0x'+params.substr(10, 4))*0.1).toFixed(2);" | ||
76 | - ), | ||
77 | - h('h3', { style: 'color:white' }, '输出参数:'), | ||
78 | - h('h3', { style: 'color:white' }, "{'humidity':'33.60','temperature':'14.10'}"), | ||
79 | - ]), | ||
80 | -]); | 1 | +import { BasicColumn, FormSchema } from '/@/components/Table'; |
2 | +import moment from 'moment'; | ||
3 | +import { h } from 'vue'; | ||
4 | + | ||
5 | +// 表格配置 | ||
6 | +export const columns: BasicColumn[] = [ | ||
7 | + { | ||
8 | + title: '脚本名称', | ||
9 | + dataIndex: 'name', | ||
10 | + width: 80, | ||
11 | + }, | ||
12 | + { | ||
13 | + title: '脚本状态', | ||
14 | + dataIndex: 'status', | ||
15 | + width: 120, | ||
16 | + slots: { customRender: 'status' }, | ||
17 | + }, | ||
18 | + { | ||
19 | + title: '脚本内容', | ||
20 | + dataIndex: 'convertJs', | ||
21 | + width: 120, | ||
22 | + slots: { customRender: 'convertJs' }, | ||
23 | + }, | ||
24 | + { | ||
25 | + title: '备注', | ||
26 | + dataIndex: 'description', | ||
27 | + width: 120, | ||
28 | + }, | ||
29 | + { | ||
30 | + title: '创建时间', | ||
31 | + dataIndex: 'createTime', | ||
32 | + width: 180, | ||
33 | + }, | ||
34 | +]; | ||
35 | + | ||
36 | +// 查询配置 | ||
37 | +export const searchFormSchema: FormSchema[] = [ | ||
38 | + { | ||
39 | + field: 'name', | ||
40 | + label: '脚本名称', | ||
41 | + component: 'Input', | ||
42 | + colProps: { span: 6 }, | ||
43 | + componentProps: { | ||
44 | + maxLength: 36, | ||
45 | + placeholder: '请输入配置名称', | ||
46 | + }, | ||
47 | + }, | ||
48 | + { | ||
49 | + field: 'sendTime', | ||
50 | + label: '创建时间', | ||
51 | + component: 'RangePicker', | ||
52 | + componentProps: { | ||
53 | + showTime: { | ||
54 | + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')], | ||
55 | + }, | ||
56 | + }, | ||
57 | + colProps: { span: 6 }, | ||
58 | + }, | ||
59 | +]; | ||
60 | + | ||
61 | +export const defaultTitle = h('div', { style: 'background:#404040' }, [ | ||
62 | + h('h3', { style: 'color:white' }, '示例'), | ||
63 | + h('h3', { style: 'color:white' }, '输入参数:'), | ||
64 | + h('h3', { style: 'color:white' }, '0103040150008D3BBB'), | ||
65 | + h('h3', { style: 'color:white' }, [ | ||
66 | + h('h3', { style: 'color:white' }, '脚本内容:'), | ||
67 | + h( | ||
68 | + 'h3', | ||
69 | + { style: 'color:white' }, | ||
70 | + "out.humidity = (parseInt('0x'+params.substr(6, 4))*0.1).toFixed(2);" | ||
71 | + ), | ||
72 | + h( | ||
73 | + 'h3', | ||
74 | + { style: 'color:white' }, | ||
75 | + "out.temperature = (parseInt('0x'+params.substr(10, 4))*0.1).toFixed(2);" | ||
76 | + ), | ||
77 | + h('h3', { style: 'color:white' }, '输出参数:'), | ||
78 | + h('h3', { style: 'color:white' }, "{'humidity':'33.60','temperature':'14.10'}"), | ||
79 | + ]), | ||
80 | +]); | ||
81 | + | ||
82 | +export const defaultScriptTypeContent = { | ||
83 | + TRANSPORT_TCP_UP: | ||
84 | + 'var attrData = {};var teleData = {};teleData.source= params;out.datas = teleData;out.telemetry =true;out.ackMsg = params;out.deviceName = "sensor";out.ts = Date.now();', | ||
85 | + TRANSPORT_TCP_DOWN: 'out.datas = "";out.deviceName = "sensor";', | ||
86 | + TRANSPORT_TCP_AUTH: 'out.password = params;out.success = params;', | ||
87 | +}; |