Commit be4155d1b60f8c27a60318a3d9f85b4caa73fdd7
Merge branch 'ft' into 'main_dev'
fix: 修改Teambition上的问题 See merge request yunteng/thingskit-front!542
Showing
23 changed files
with
786 additions
and
388 deletions
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | placeholder="请选择" |
19 | 19 | :options="selectOptions" |
20 | 20 | @change="handleChange" |
21 | + @dropdownVisibleChange="hanldeDropdownVisibleChange" | |
21 | 22 | allowClear |
22 | 23 | /> |
23 | 24 | </td> |
... | ... | @@ -111,16 +112,20 @@ |
111 | 112 | |
112 | 113 | // 减少 |
113 | 114 | const remove = (item, index: number) => { |
114 | - if (tableArray.content.length !== 1) { | |
115 | + if (tableArray.content.length > 1) { | |
115 | 116 | selectOptions.value.forEach((ele) => { |
116 | 117 | if (ele.value == item.key) { |
117 | 118 | ele.disabled = false; |
118 | 119 | } |
119 | 120 | }); |
120 | 121 | tableArray.content.splice(index, 1); |
122 | + } else { | |
123 | + resetValue(); | |
121 | 124 | } |
122 | 125 | }; |
123 | 126 | |
127 | + const hanldeDropdownVisibleChange = () => handleChange(); | |
128 | + | |
124 | 129 | //Select互斥 |
125 | 130 | const handleChange = () => { |
126 | 131 | selectOptions.value.forEach((ele) => { | ... | ... |
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | placeholder="请选择" |
19 | 19 | :options="selectOptions" |
20 | 20 | @change="handleChange" |
21 | + @dropdownVisibleChange="hanldeDropdownVisibleChange" | |
21 | 22 | allowClear |
22 | 23 | /> |
23 | 24 | </td> |
... | ... | @@ -111,13 +112,15 @@ |
111 | 112 | |
112 | 113 | // 减少 |
113 | 114 | const remove = (item, index: number) => { |
114 | - if (tableArray.content.length !== 1) { | |
115 | + if (tableArray.content.length > 1) { | |
115 | 116 | selectOptions.value.forEach((ele) => { |
116 | 117 | if (ele.value == item.key) { |
117 | 118 | ele.disabled = false; |
118 | 119 | } |
119 | 120 | }); |
120 | 121 | tableArray.content.splice(index, 1); |
122 | + } else { | |
123 | + resetValue(); | |
121 | 124 | } |
122 | 125 | }; |
123 | 126 | |
... | ... | @@ -139,6 +142,8 @@ |
139 | 142 | }); |
140 | 143 | }; |
141 | 144 | |
145 | + const hanldeDropdownVisibleChange = () => handleChange(); | |
146 | + | |
142 | 147 | //获取数据 |
143 | 148 | const getValue = () => { |
144 | 149 | const assemblyData = tableArray.content.map((it) => { | ... | ... |
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | <ParamsTable ref="paramsCellTableRef" :method="method" /> |
7 | 7 | <ParamsTest |
8 | 8 | @testParamsInterface="handleTestParamsInterface" |
9 | + @closeTest="onCloseTest" | |
9 | 10 | ref="testParamsRequestRef" |
10 | 11 | :data="dataMap.mapParamsObj" |
11 | 12 | /> |
... | ... | @@ -21,6 +22,7 @@ |
21 | 22 | <BodyTest |
22 | 23 | v-if="bodyType !== 'none'" |
23 | 24 | @testBodyInterface="handleTestBodyInterface" |
25 | + @closeTest="onCloseTest" | |
24 | 26 | ref="testBodyRequestRef" |
25 | 27 | :data="dataMap.mapBodyObj" |
26 | 28 | /> |
... | ... | @@ -29,6 +31,7 @@ |
29 | 31 | <HeaderTable ref="editHeaderCellTableRef" :method="method" /> |
30 | 32 | <HeaderTest |
31 | 33 | @testHeaderInterface="handleTestHeaderInterface" |
34 | + @closeTest="onCloseTest" | |
32 | 35 | ref="testHeaderRequestRef" |
33 | 36 | :data="dataMap.mapHeaderObj" |
34 | 37 | /> |
... | ... | @@ -107,6 +110,8 @@ |
107 | 110 | excuteTestRef.value?.resetValue(true); |
108 | 111 | }; |
109 | 112 | |
113 | + const onCloseTest = () => excuteTestRef.value?.resetValue(true); | |
114 | + | |
110 | 115 | //if-else-if-else分支优化 |
111 | 116 | const dataForTypeMap = [ |
112 | 117 | [(type) => type === 'Params', (data) => paramsCellTableRef.value?.setValue(data)], | ... | ... |
1 | 1 | <template> |
2 | 2 | <div> |
3 | 3 | <div class="mt-8"> |
4 | - <div> | |
5 | - <Button @click="handleTest" type="primary"> 测试接口 </Button> | |
4 | + <div class="flex"> | |
5 | + <Button @click="handleTest" type="primary"> 打开测试接口 </Button> | |
6 | + <Button class="ml-2" @click="onCloseTest" type="primary"> 关闭测试接口 </Button> | |
6 | 7 | </div> |
7 | 8 | <div v-if="showTestEditCell" class="mt-8"> |
8 | 9 | <a-row type="flex" justify="center"> |
... | ... | @@ -31,8 +32,9 @@ |
31 | 32 | import moment from 'moment'; |
32 | 33 | import { useUtils } from '../../../hooks/useUtils'; |
33 | 34 | import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue'; |
35 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
34 | 36 | |
35 | - const emits = defineEmits(['testBodyInterface']); | |
37 | + const emits = defineEmits(['testBodyInterface', 'closeTest']); | |
36 | 38 | |
37 | 39 | const props = defineProps({ |
38 | 40 | data: { |
... | ... | @@ -40,6 +42,8 @@ |
40 | 42 | }, |
41 | 43 | }); |
42 | 44 | |
45 | + const { createMessage } = useMessage(); | |
46 | + | |
43 | 47 | const showTestEditCell = ref(false); |
44 | 48 | |
45 | 49 | const excuteData = ref({}); |
... | ... | @@ -111,6 +115,7 @@ |
111 | 115 | return { |
112 | 116 | key, |
113 | 117 | value, |
118 | + required: it.required, | |
114 | 119 | }; |
115 | 120 | }); |
116 | 121 | }; |
... | ... | @@ -120,6 +125,11 @@ |
120 | 125 | let params: any = {}; |
121 | 126 | if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') { |
122 | 127 | const getTable = getTestTableKeyValue(); |
128 | + const hasRequired = getTable?.some((it) => it.required === true && !it.value); | |
129 | + if (hasRequired) { | |
130 | + createMessage.error('参数不能为空'); | |
131 | + throw new Error('参数不能为空'); | |
132 | + } | |
123 | 133 | getTable?.map((it) => (params[it.key!] = it.value!)); |
124 | 134 | } else if (props.data?.type === 'json') { |
125 | 135 | params = jsonEditorRef.value?.getJsonValue(); |
... | ... | @@ -141,6 +151,11 @@ |
141 | 151 | testResult.value = ''; |
142 | 152 | }; |
143 | 153 | |
154 | + const onCloseTest = () => { | |
155 | + showTestEditCell.value = false; | |
156 | + emits('closeTest'); | |
157 | + }; | |
158 | + | |
144 | 159 | defineExpose({ |
145 | 160 | setValue, |
146 | 161 | handleTest, | ... | ... |
... | ... | @@ -243,7 +243,9 @@ |
243 | 243 | if (f.key === 'organizationId') organizationId = f.value; |
244 | 244 | if (f.key === 'entityId') f.value = null; |
245 | 245 | }); |
246 | - getAttributeOptions({ deviceProfileId: e.value }); | |
246 | + if (e.value) { | |
247 | + getAttributeOptions({ deviceProfileId: e.value }); | |
248 | + } | |
247 | 249 | if (organizationId !== '') { |
248 | 250 | getEntityOptions(organizationId, e.value); |
249 | 251 | } | ... | ... |
... | ... | @@ -5,10 +5,10 @@ |
5 | 5 | </div> |
6 | 6 | <div class="mt-8"> |
7 | 7 | <a-row type="flex" justify="center"> |
8 | - <a-col :span="2"> 测试结果 </a-col> | |
9 | - <a-col :span="22"> | |
8 | + <a-col :span="24"> | |
10 | 9 | <a-textarea |
11 | - v-if="ifWebSocket === '2'" | |
10 | + disabled | |
11 | + v-if="isWebSocketType === '2'" | |
12 | 12 | allow-clear |
13 | 13 | show-count |
14 | 14 | v-model:value="testResult" |
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | :rows="8" |
17 | 17 | /> |
18 | 18 | <a-textarea |
19 | + disabled | |
19 | 20 | v-else |
20 | 21 | allow-clear |
21 | 22 | show-count |
... | ... | @@ -29,14 +30,13 @@ |
29 | 30 | </div> |
30 | 31 | </template> |
31 | 32 | <script lang="ts" setup name="testRequest"> |
32 | - import { nextTick, ref, reactive } from 'vue'; | |
33 | + import { nextTick, ref, reactive, onUnmounted } from 'vue'; | |
33 | 34 | import { Button } from 'ant-design-vue'; |
34 | 35 | import { otherHttp } from '/@/utils/http/axios'; |
35 | 36 | import { useWebSocket } from '@vueuse/core'; |
36 | 37 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; |
37 | 38 | import { getAuthCache } from '/@/utils/auth'; |
38 | - import { useMessage } from '/@/hooks/web/useMessage'; | |
39 | - // import { useGlobSetting } from '/@/hooks/setting'; | |
39 | + import { useUtils } from '../../../hooks/useUtils'; | |
40 | 40 | |
41 | 41 | const emits = defineEmits(['emitExcute']); |
42 | 42 | |
... | ... | @@ -48,16 +48,10 @@ |
48 | 48 | |
49 | 49 | const showTestFlag = ref(false); |
50 | 50 | |
51 | - const ifWebSocket = ref(''); | |
52 | - | |
53 | - const { createMessage } = useMessage(); | |
54 | - | |
55 | 51 | const token = getAuthCache(JWT_TOKEN_KEY); |
56 | 52 | |
57 | 53 | const socketUrls = ref(''); |
58 | 54 | |
59 | - // const { socketUrl } = useGlobSetting(); | |
60 | - | |
61 | 55 | const socketMessage: any = reactive({ |
62 | 56 | server: ``, |
63 | 57 | sendValue: { |
... | ... | @@ -89,6 +83,8 @@ |
89 | 83 | |
90 | 84 | const httpResult = ref(''); |
91 | 85 | |
86 | + const isWebSocketType = ref(''); | |
87 | + | |
92 | 88 | //执行测试接口 |
93 | 89 | const handleExcute = () => { |
94 | 90 | emits('emitExcute'); |
... | ... | @@ -99,18 +95,23 @@ |
99 | 95 | await nextTick(); |
100 | 96 | //获取Params和Header和Body |
101 | 97 | const Objects = props.data; |
102 | - const isWebSocketType = Objects?.method; | |
98 | + isWebSocketType.value = Objects?.method; | |
103 | 99 | const apiType = Objects?.apiType; |
104 | 100 | const url = Objects?.apiGetUrl; |
105 | 101 | const headers = Objects?.Header?.params; |
106 | 102 | const params = Objects?.Params?.params; |
107 | 103 | const body = Objects?.Body?.params; |
108 | 104 | const apiUrl = url?.restfulFormat(params); |
109 | - ifWebSocket.value = isWebSocketType; | |
110 | - if (isWebSocketType === '2') { | |
105 | + if (isWebSocketType.value === '2') { | |
111 | 106 | socketUrls.value = url; |
112 | 107 | socketMessage.server = `${socketUrls.value}?token=${token}`; |
113 | - websocketRequest(params); | |
108 | + const list = Object.values(params); | |
109 | + const isEmpty = list.some((it) => it === '' || null || undefined); | |
110 | + if (!isEmpty) { | |
111 | + websocketRequest(params); | |
112 | + } else { | |
113 | + resetValue(false); | |
114 | + } | |
114 | 115 | } else { |
115 | 116 | const resp = await otherHttpRequest(apiType, apiUrl?.split('{?')[0], headers, params, body); |
116 | 117 | if (!resp) return; |
... | ... | @@ -119,7 +120,7 @@ |
119 | 120 | }; |
120 | 121 | |
121 | 122 | //websocket请求 |
122 | - const websocketRequest = (params) => { | |
123 | + const websocketRequest = (params, destroy = false) => { | |
123 | 124 | //websocket请求 |
124 | 125 | Reflect.deleteProperty(params, 'deviceProfileId'); |
125 | 126 | Reflect.deleteProperty(params, 'organizationId'); |
... | ... | @@ -140,12 +141,17 @@ |
140 | 141 | console.log('断开连接了'); |
141 | 142 | close(); |
142 | 143 | }, |
143 | - onError() { | |
144 | - createMessage.error('webSocket连接超时,请联系管理员'); | |
145 | - }, | |
144 | + onError() {}, | |
146 | 145 | }); |
146 | + if (destroy) close(); | |
147 | 147 | }; |
148 | 148 | |
149 | + onUnmounted(() => { | |
150 | + if (isWebSocketType.value === '2') { | |
151 | + websocketRequest(null, true); | |
152 | + } | |
153 | + }); | |
154 | + | |
149 | 155 | //TODO: 待优化 项目自带第三方请求 |
150 | 156 | const otherHttpRequest = async ( |
151 | 157 | apiType, |
... | ... | @@ -165,8 +171,9 @@ |
165 | 171 | } |
166 | 172 | ); |
167 | 173 | case 'POST': |
174 | + const { convertObj } = useUtils(); | |
168 | 175 | return await otherHttp.post( |
169 | - { url: apiUrl, data: body, headers, params }, | |
176 | + { url: `${apiUrl}?${convertObj(params)}`, data: body, headers }, | |
170 | 177 | { |
171 | 178 | apiUrl: '', |
172 | 179 | joinPrefix, |
... | ... | @@ -189,7 +196,7 @@ |
189 | 196 | } |
190 | 197 | httpResult.value = '测试结果为:'; |
191 | 198 | testResult.value = '测试结果为:'; |
192 | - ifWebSocket.value = '0'; | |
199 | + isWebSocketType.value = '0'; | |
193 | 200 | }; |
194 | 201 | |
195 | 202 | const showTest = () => (showTestFlag.value = true); | ... | ... |
1 | 1 | <template> |
2 | 2 | <div> |
3 | 3 | <div class="mt-8"> |
4 | - <div> | |
5 | - <Button @click="handleTest" type="primary"> 测试接口 </Button> | |
4 | + <div class="flex"> | |
5 | + <Button @click="handleTest" type="primary"> 打开测试接口 </Button> | |
6 | + <Button class="ml-2" @click="onCloseTest" type="primary"> 关闭测试接口 </Button> | |
6 | 7 | </div> |
7 | 8 | <div v-if="showTestEditCell" class="mt-8"> |
8 | 9 | <a-row type="flex" justify="center"> |
... | ... | @@ -20,8 +21,9 @@ |
20 | 21 | import { ref, nextTick } from 'vue'; |
21 | 22 | import { Button } from 'ant-design-vue'; |
22 | 23 | import TestHeaderEditCellTable from './testEditHeaderCellTable.vue'; |
24 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
23 | 25 | |
24 | - const emits = defineEmits(['testHeaderInterface']); | |
26 | + const emits = defineEmits(['testHeaderInterface', 'closeTest']); | |
25 | 27 | |
26 | 28 | const props = defineProps({ |
27 | 29 | data: { |
... | ... | @@ -29,6 +31,8 @@ |
29 | 31 | }, |
30 | 32 | }); |
31 | 33 | |
34 | + const { createMessage } = useMessage(); | |
35 | + | |
32 | 36 | const showTestEditCell = ref(false); |
33 | 37 | |
34 | 38 | const excuteData = ref({}); |
... | ... | @@ -59,6 +63,11 @@ |
59 | 63 | //获取数据 |
60 | 64 | const getTestValue = () => { |
61 | 65 | const getTable = getTestTableKeyValue(); |
66 | + const hasRequired = getTable?.some((it) => it.required === true && !it.value); | |
67 | + if (hasRequired) { | |
68 | + createMessage.error('参数不能为空'); | |
69 | + throw new Error('参数不能为空'); | |
70 | + } | |
62 | 71 | const params: any = {}; |
63 | 72 | getTable?.map((it: any) => (params[it.key!] = it.value!)); |
64 | 73 | excuteData.value = { |
... | ... | @@ -73,6 +82,11 @@ |
73 | 82 | testResult.value = ''; |
74 | 83 | }; |
75 | 84 | |
85 | + const onCloseTest = () => { | |
86 | + showTestEditCell.value = false; | |
87 | + emits('closeTest'); | |
88 | + }; | |
89 | + | |
76 | 90 | defineExpose({ |
77 | 91 | setValue, |
78 | 92 | handleTest, | ... | ... |
1 | 1 | <template> |
2 | 2 | <div> |
3 | 3 | <div class="mt-8"> |
4 | - <div> | |
5 | - <Button @click="handleTest" type="primary"> 测试接口 </Button> | |
4 | + <div class="flex"> | |
5 | + <Button @click="handleTest" type="primary"> 打开测试接口 </Button> | |
6 | + <Button class="ml-2" @click="onCloseTest" type="primary"> 关闭测试接口 </Button> | |
6 | 7 | </div> |
7 | 8 | <div v-if="showTestEditCell" class="mt-8"> |
8 | 9 | <a-row type="flex" justify="center"> |
... | ... | @@ -22,8 +23,9 @@ |
22 | 23 | import TestParamsCellTable from './testEditParamsCellTable.vue'; |
23 | 24 | import moment from 'moment'; |
24 | 25 | import { useUtils } from '../../../hooks/useUtils'; |
26 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
25 | 27 | |
26 | - const emits = defineEmits(['testParamsInterface']); | |
28 | + const emits = defineEmits(['testParamsInterface', 'closeTest']); | |
27 | 29 | |
28 | 30 | const props = defineProps({ |
29 | 31 | data: { |
... | ... | @@ -31,6 +33,8 @@ |
31 | 33 | }, |
32 | 34 | }); |
33 | 35 | |
36 | + const { createMessage } = useMessage(); | |
37 | + | |
34 | 38 | const showTestEditCell = ref(false); |
35 | 39 | |
36 | 40 | const excuteData = ref({}); |
... | ... | @@ -92,6 +96,7 @@ |
92 | 96 | return { |
93 | 97 | key, |
94 | 98 | value, |
99 | + required: it.required, | |
95 | 100 | }; |
96 | 101 | }); |
97 | 102 | }; |
... | ... | @@ -99,6 +104,11 @@ |
99 | 104 | //获取数据 |
100 | 105 | const getTestValue = () => { |
101 | 106 | const getTable = getTestTableKeyValue(); |
107 | + const hasRequired = getTable?.some((it) => it.required === true && !it.value); | |
108 | + if (hasRequired) { | |
109 | + createMessage.error('参数不能为空'); | |
110 | + throw new Error('参数不能为空'); | |
111 | + } | |
102 | 112 | const params: any = {}; |
103 | 113 | getTable?.map((it) => (params[it.key!] = it.value!)); |
104 | 114 | if (params['keys']) { |
... | ... | @@ -116,6 +126,11 @@ |
116 | 126 | testResult.value = ''; |
117 | 127 | }; |
118 | 128 | |
129 | + const onCloseTest = () => { | |
130 | + showTestEditCell.value = false; | |
131 | + emits('closeTest'); | |
132 | + }; | |
133 | + | |
119 | 134 | defineExpose({ |
120 | 135 | setValue, |
121 | 136 | handleTest, | ... | ... |
... | ... | @@ -235,7 +235,9 @@ |
235 | 235 | if (f.key === 'organizationId') organizationId = f.value; |
236 | 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 | 241 | if (organizationId !== '') { |
240 | 242 | getEntityOptions(organizationId, e.value); |
241 | 243 | } | ... | ... |
... | ... | @@ -46,7 +46,7 @@ |
46 | 46 | import { useMessage } from '/@/hooks/web/useMessage'; |
47 | 47 | import { useUtils } from './hooks/useUtils'; |
48 | 48 | |
49 | - const { resetReqHttpType, resetUpdateSchema } = useUtils(); | |
49 | + const { resetReqHttpType } = useUtils(); | |
50 | 50 | |
51 | 51 | const emits = defineEmits(['success', 'register']); |
52 | 52 | |
... | ... | @@ -69,10 +69,15 @@ |
69 | 69 | const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { |
70 | 70 | await resetFields(); |
71 | 71 | await nextTick(); |
72 | - updateSchema(resetUpdateSchema); | |
73 | 72 | setFieldsValue(resetReqHttpType); |
74 | 73 | const title = `${!data.isUpdate ? '新增' : '修改'}公共接口`; |
75 | 74 | setDrawerProps({ title }); |
75 | + updateSchema({ | |
76 | + field: 'requestHttpTypeAndUrl', | |
77 | + componentProps: { | |
78 | + type: '0', | |
79 | + }, | |
80 | + }); | |
76 | 81 | isUpdate.value = data.isUpdate; |
77 | 82 | !isUpdate.value ? (putId.value = '') : (putId.value = data.record.id); |
78 | 83 | simpleRequestRef.value?.resetValue() && testSqlRef.value?.resetValue(); |
... | ... | @@ -104,6 +109,14 @@ |
104 | 109 | try { |
105 | 110 | const values = await validate(); |
106 | 111 | if (!values) return; |
112 | + const isRequestHttpTypeAndUrlEmpty = values?.requestHttpTypeAndUrl; | |
113 | + if ( | |
114 | + !Reflect.get(isRequestHttpTypeAndUrlEmpty, 'requestHttpType') || | |
115 | + !Reflect.get(isRequestHttpTypeAndUrlEmpty, 'requestUrl') | |
116 | + ) { | |
117 | + createMessage.error('请填写请求类型&地址'); | |
118 | + throw Error('请填写请求类型&地址'); | |
119 | + } | |
107 | 120 | const Objects = simpleRequestRef.value?.getValue(true); |
108 | 121 | const requestOriginUrl = |
109 | 122 | values['originUrlType'] === 'server_url' ? 'localhost' : values['requestOriginUrl']; | ... | ... |
... | ... | @@ -36,5 +36,20 @@ export const useUtils = () => { |
36 | 36 | type: '0', |
37 | 37 | }, |
38 | 38 | }; |
39 | - return { getMultipleKeys, pushObj, resetReqHttpType, resetUpdateSchema }; | |
39 | + //对象转get params参数 | |
40 | + const convertObj = (data: object) => { | |
41 | + const _result: any = []; | |
42 | + for (const key in data) { | |
43 | + const value = data[key]; | |
44 | + if (value.constructor == Array) { | |
45 | + value.forEach(function (_value) { | |
46 | + _result.push(key + '=' + _value); | |
47 | + }); | |
48 | + } else { | |
49 | + _result.push(key + '=' + value); | |
50 | + } | |
51 | + } | |
52 | + return _result.join('&'); | |
53 | + }; | |
54 | + return { getMultipleKeys, pushObj, resetReqHttpType, resetUpdateSchema, convertObj }; | |
40 | 55 | }; | ... | ... |
... | ... | @@ -39,7 +39,7 @@ |
39 | 39 | icon: 'ant-design:node-expand-outlined', |
40 | 40 | onClick: handlePublish.bind(null, 'publish', record), |
41 | 41 | ifShow: () => { |
42 | - return record.state === 0; | |
42 | + return record.state === 0 && record.creator === userId; | |
43 | 43 | }, |
44 | 44 | }, |
45 | 45 | { |
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 | icon: 'ant-design:node-collapse-outlined', |
48 | 48 | onClick: handlePublish.bind(null, 'canelPublish', record), |
49 | 49 | ifShow: () => { |
50 | - return record.state === 1; | |
50 | + return record.state === 1 && record.creator === userId; | |
51 | 51 | }, |
52 | 52 | }, |
53 | 53 | { |
... | ... | @@ -55,7 +55,7 @@ |
55 | 55 | icon: 'clarity:note-edit-line', |
56 | 56 | onClick: handleCreateOrEdit.bind(null, record), |
57 | 57 | ifShow: () => { |
58 | - return record.state === 0; | |
58 | + return record.state === 0 && record.creator === userId; | |
59 | 59 | }, |
60 | 60 | }, |
61 | 61 | { |
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | icon: 'ant-design:delete-outlined', |
64 | 64 | color: 'error', |
65 | 65 | ifShow: () => { |
66 | - return record.state === 0; | |
66 | + return record.state === 0 && record.creator === userId; | |
67 | 67 | }, |
68 | 68 | popConfirm: { |
69 | 69 | title: '是否确认删除', |
... | ... | @@ -93,6 +93,12 @@ |
93 | 93 | import { Popconfirm, Modal } from 'ant-design-vue'; |
94 | 94 | import { JsonPreview } from '/@/components/CodeEditor'; |
95 | 95 | import { useMessage } from '/@/hooks/web/useMessage'; |
96 | + import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | |
97 | + import { getAuthCache } from '/@/utils/auth'; | |
98 | + | |
99 | + const userInfo = getAuthCache(USER_INFO_KEY) as any; | |
100 | + | |
101 | + const userId = ref(userInfo?.userId); | |
96 | 102 | |
97 | 103 | const [registerTable, { reload, clearSelectedRowKeys }] = useTable({ |
98 | 104 | api: getDataViewInterfacePage, | ... | ... |
1 | 1 | <script lang="ts" setup> |
2 | 2 | import { Button, Tag } from 'ant-design-vue'; |
3 | - import { h, onMounted, ref, unref } from 'vue'; | |
3 | + import { h, onMounted, ref, unref, Ref } from 'vue'; | |
4 | 4 | import { DeviceRecord } from '/@/api/device/model/deviceModel'; |
5 | - import { ScriptRecord } from '/@/api/scriptmanage/model/scriptModel'; | |
5 | + // import { ScriptRecord } from '/@/api/scriptmanage/model/scriptModel'; | |
6 | 6 | import { getScriptManageMeList } from '/@/api/scriptmanage/scriptManager'; |
7 | 7 | import { Description, useDescription } from '/@/components/Description'; |
8 | 8 | import { useModal } from '/@/components/Modal'; |
9 | 9 | import CoverScriptModal from '/@/views/scriptmanage/converscript/ConverScriptModal.vue'; |
10 | + import { SelectTypes } from 'ant-design-vue/es/select'; | |
10 | 11 | |
11 | 12 | const props = defineProps<{ |
12 | 13 | record: DeviceRecord['profileData']['transportConfiguration']; |
13 | 14 | }>(); |
14 | 15 | |
15 | - const scriptInfo = ref<ScriptRecord>({} as unknown as ScriptRecord); | |
16 | + // const scriptInfo = ref<ScriptRecord>({} as unknown as ScriptRecord); | |
17 | + const authScriptIdStr = ref(''); | |
18 | + | |
19 | + const upScriptIdStr = ref(''); | |
20 | + | |
21 | + const selectUpOptions: Ref<SelectTypes['options']> = ref([]); | |
22 | + | |
23 | + const selectAuthOptions: Ref<SelectTypes['options']> = ref([]); | |
24 | + | |
25 | + onMounted(async () => { | |
26 | + selectUpOptions.value = await getAllScriptType('TRANSPORT_TCP_UP'); | |
27 | + selectAuthOptions.value = await getAllScriptType('TRANSPORT_TCP_AUTH'); | |
28 | + setDescProps({ | |
29 | + data: Object.assign(props.record), | |
30 | + }); | |
31 | + }); | |
32 | + | |
33 | + const getAllScriptType = async (type) => { | |
34 | + const rest = await getScriptManageMeList({ scriptType: type }); | |
35 | + return rest.map((m) => ({ label: m.name, value: m.id })); | |
36 | + }; | |
37 | + | |
38 | + const findScriptUpName = (scriptId) => { | |
39 | + upScriptIdStr.value = scriptId; | |
40 | + return selectUpOptions.value?.find((it) => it.value === scriptId)?.label; | |
41 | + }; | |
42 | + | |
43 | + const findScriptAuthName = (scriptId) => { | |
44 | + authScriptIdStr.value = scriptId; | |
45 | + return selectAuthOptions.value?.find((it) => it.value === scriptId)?.label; | |
46 | + }; | |
16 | 47 | |
17 | 48 | const [register, { setDescProps }] = useDescription({ |
18 | 49 | layout: 'vertical', |
... | ... | @@ -25,14 +56,27 @@ |
25 | 56 | span: 2, |
26 | 57 | }, |
27 | 58 | { |
28 | - field: 'scriptName', | |
29 | - label: '转换脚本', | |
59 | + field: 'authScriptId', | |
60 | + label: '鉴权脚本', | |
30 | 61 | render: (value: string) => { |
31 | 62 | return ( |
32 | 63 | value && |
33 | 64 | h('div', [ |
34 | - h(Tag, { color: 'blue' }, () => value), | |
35 | - h(Button, { type: 'link', onClick: handleTestScript }, () => '测试脚本'), | |
65 | + h(Tag, { color: 'blue' }, () => findScriptAuthName(value)), | |
66 | + h(Button, { type: 'link', onClick: handleTestAuthScript }, () => '测试脚本'), | |
67 | + ]) | |
68 | + ); | |
69 | + }, | |
70 | + }, | |
71 | + { | |
72 | + field: 'upScriptId', | |
73 | + label: '上行脚本', | |
74 | + render: (value: string) => { | |
75 | + return ( | |
76 | + value && | |
77 | + h('div', [ | |
78 | + h(Tag, { color: 'blue' }, () => findScriptUpName(value)), | |
79 | + h(Button, { type: 'link', onClick: handleTestUpScript }, () => '测试脚本'), | |
36 | 80 | ]) |
37 | 81 | ); |
38 | 82 | }, |
... | ... | @@ -42,29 +86,24 @@ |
42 | 86 | |
43 | 87 | const [registerModal, { openModal }] = useModal(); |
44 | 88 | |
45 | - const handleTestScript = () => { | |
89 | + const handleTestAuthScript = () => { | |
46 | 90 | openModal(true, { |
47 | 91 | isUpdate: false, |
48 | 92 | isTest: true, |
49 | - record: unref(scriptInfo).id, | |
93 | + record: unref(authScriptIdStr), | |
50 | 94 | isText: 'test', |
51 | 95 | isTitle: 'test', |
52 | 96 | }); |
53 | 97 | }; |
54 | 98 | |
55 | - onMounted(() => { | |
56 | - getTransforScriptInfo(); | |
57 | - }); | |
58 | - | |
59 | - const getTransforScriptInfo = async () => { | |
60 | - try { | |
61 | - const list = await getScriptManageMeList(); | |
62 | - const record = list.find((item) => item.id === props.record.scriptId); | |
63 | - scriptInfo.value = record!; | |
64 | - setDescProps({ | |
65 | - data: Object.assign(props.record, record, { scriptName: record?.name || '' }), | |
66 | - }); | |
67 | - } catch (error) {} | |
99 | + const handleTestUpScript = () => { | |
100 | + openModal(true, { | |
101 | + isUpdate: false, | |
102 | + isTest: true, | |
103 | + record: unref(upScriptIdStr), | |
104 | + isText: 'test', | |
105 | + isTitle: 'test', | |
106 | + }); | |
68 | 107 | }; |
69 | 108 | </script> |
70 | 109 | ... | ... |
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | </BasicDrawer> |
42 | 42 | </template> |
43 | 43 | <script lang="ts" setup> |
44 | - import { ref, computed, unref, reactive, watch, Ref } from 'vue'; | |
44 | + import { ref, computed, unref, reactive, watch, Ref, nextTick } from 'vue'; | |
45 | 45 | import { BasicForm, useForm } from '/@/components/Form'; |
46 | 46 | import { formSchema, organizationId } from './config.data'; |
47 | 47 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
... | ... | @@ -198,6 +198,7 @@ |
198 | 198 | const isViewDetail = ref(false); |
199 | 199 | |
200 | 200 | const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { |
201 | + await nextTick(); | |
201 | 202 | await resetFields(); |
202 | 203 | setDrawerProps({ confirmLoading: false }); |
203 | 204 | isUpdate.value = !!data?.isUpdate; |
... | ... | @@ -222,6 +223,10 @@ |
222 | 223 | await setFieldsValue(editResData.data); |
223 | 224 | //回显嵌套数据 |
224 | 225 | await setFieldsValue({ |
226 | + dateGroupGap: | |
227 | + editResData.data.queryCondition?.queryMode === 1 | |
228 | + ? editResData.data.queryCondition?.interval | |
229 | + : null, | |
225 | 230 | agg: editResData.data.queryCondition?.agg, |
226 | 231 | interval: editResData.data.queryCondition?.interval, |
227 | 232 | limit: editResData.data.queryCondition?.limit, |
... | ... | @@ -266,6 +271,7 @@ |
266 | 271 | { label: '最大值', value: AggregateDataEnum.MAX }, |
267 | 272 | { label: '平均值', value: AggregateDataEnum.AVG }, |
268 | 273 | { label: '求和', value: AggregateDataEnum.SUM }, |
274 | + { label: '计数', value: AggregateDataEnum.COUNT }, | |
269 | 275 | { label: '空', value: AggregateDataEnum.NONE }, |
270 | 276 | ]; |
271 | 277 | const updateSchemaAgg = (options: {}) => { |
... | ... | @@ -276,8 +282,8 @@ |
276 | 282 | }, |
277 | 283 | }); |
278 | 284 | }; |
279 | - if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 4)); | |
280 | - else updateSchemaAgg(dataCompareOpions.slice(4, 5)); | |
285 | + if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 5)); | |
286 | + else updateSchemaAgg(dataCompareOpions.slice(5, 6)); | |
281 | 287 | //回显执行方式和查询周期 |
282 | 288 | const dataQueryOpions = [ |
283 | 289 | { label: '固定周期', value: QueryWay.LATEST }, |
... | ... | @@ -442,7 +448,7 @@ |
442 | 448 | } |
443 | 449 | queryCondition = { |
444 | 450 | agg: values.agg, |
445 | - interval: values.interval, | |
451 | + interval: values?.queryMode === 'latest' ? values.interval : values.dateGroupGap, | |
446 | 452 | limit: values.limit, |
447 | 453 | ...{ |
448 | 454 | startTs: startTs.value, | ... | ... |
1 | 1 | import { ref } from 'vue'; |
2 | 2 | import { BasicColumn, FormSchema } from '/@/components/Table'; |
3 | 3 | import type { FormSchema as QFormSchema } from '/@/components/Form/index'; |
4 | -import moment from 'moment'; | |
5 | 4 | import { getOrganizationList } from '/@/api/system/system'; |
6 | 5 | import { copyTransFun } from '/@/utils/fnUtils'; |
7 | 6 | import { findDictItemByCode } from '/@/api/system/dict'; |
... | ... | @@ -12,6 +11,7 @@ import { |
12 | 11 | getPacketIntervalByValue, |
13 | 12 | intervalOption, |
14 | 13 | } from '../../device/localtion/cpns/TimePeriodForm/helper'; |
14 | +import moment, { Moment } from 'moment'; | |
15 | 15 | |
16 | 16 | export enum QueryWay { |
17 | 17 | LATEST = 'latest', |
... | ... | @@ -433,16 +433,70 @@ export const formSchema: QFormSchema[] = [ |
433 | 433 | ifShow({ values }) { |
434 | 434 | return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay); |
435 | 435 | }, |
436 | - componentProps: { | |
437 | - showTime: { | |
438 | - defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')], | |
439 | - }, | |
436 | + // componentProps: { | |
437 | + // showTime: { | |
438 | + // defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')], | |
439 | + // }, | |
440 | + // }, | |
441 | + componentProps({ formActionType }) { | |
442 | + const { setFieldsValue } = formActionType; | |
443 | + let dates: Moment[] = []; | |
444 | + return { | |
445 | + showTime: { | |
446 | + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')], | |
447 | + }, | |
448 | + onCalendarChange(value: Moment[]) { | |
449 | + dates = value; | |
450 | + }, | |
451 | + disabledDate(current: Moment) { | |
452 | + if (!dates || dates.length === 0 || !current) { | |
453 | + return false; | |
454 | + } | |
455 | + const diffDate = current.diff(dates[0], 'years', true); | |
456 | + return Math.abs(diffDate) > 1; | |
457 | + }, | |
458 | + onChange() { | |
459 | + dates = []; | |
460 | + setFieldsValue({ dateGroupGap: null }); | |
461 | + }, | |
462 | + getPopupContainer: () => document.body, | |
463 | + }; | |
440 | 464 | }, |
441 | 465 | colProps: { |
442 | 466 | span: 10, |
443 | 467 | }, |
444 | 468 | }, |
445 | 469 | { |
470 | + field: 'dateGroupGap', | |
471 | + label: '分组间隔', | |
472 | + component: 'Select', | |
473 | + dynamicRules: ({ model }) => { | |
474 | + return [ | |
475 | + { | |
476 | + required: model[SchemaFiled.AGG] !== AggregateDataEnum.NONE, | |
477 | + message: '分组间隔为必填项', | |
478 | + type: 'number', | |
479 | + }, | |
480 | + ]; | |
481 | + }, | |
482 | + ifShow({ values }) { | |
483 | + return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay); | |
484 | + }, | |
485 | + componentProps({ formModel, formActionType }) { | |
486 | + const options = | |
487 | + formModel[SchemaFiled.WAY] === QueryWay.LATEST | |
488 | + ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS]) | |
489 | + : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]); | |
490 | + if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) { | |
491 | + formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null }); | |
492 | + } | |
493 | + return { | |
494 | + options, | |
495 | + getPopupContainer: () => document.body, | |
496 | + }; | |
497 | + }, | |
498 | + }, | |
499 | + { | |
446 | 500 | field: SchemaFiled.START_TS, |
447 | 501 | label: '最近时间', |
448 | 502 | component: 'Select', | ... | ... |
... | ... | @@ -128,6 +128,7 @@ |
128 | 128 | import { findOperation } from './config/formatData'; |
129 | 129 | import { formatToDateTime } from '/@/utils/dateUtil'; |
130 | 130 | import ObjectModelValidateForm from '/@/components/Form/src/externalCompns/components/ObjectModelValidateForm/ObjectModelValidateForm.vue'; |
131 | + import { isEmpty } from '/@/utils/is'; | |
131 | 132 | import { add } from '/@/components/Form/src/componentMap'; |
132 | 133 | |
133 | 134 | add('ObjectModelValidateForm', ObjectModelValidateForm); |
... | ... | @@ -156,7 +157,7 @@ |
156 | 157 | const id = ref(undefined); |
157 | 158 | const tenantId = ref(undefined); |
158 | 159 | const isView = ref(true); |
159 | - const [registerForm, { resetFields, validate, setFieldsValue }] = useForm({ | |
160 | + const [registerForm, { resetFields, validate, setFieldsValue, getFieldsValue }] = useForm({ | |
160 | 161 | labelWidth: 120, |
161 | 162 | schemas: formSchema, |
162 | 163 | showActionButtonGroup: false, |
... | ... | @@ -617,12 +618,25 @@ |
617 | 618 | // item.updateFieldAlarmConfig(alarmConfigList); |
618 | 619 | // }); |
619 | 620 | // } |
621 | + | |
622 | + const isEmptyThrowError = (obj) => { | |
623 | + if (isEmpty(obj)) { | |
624 | + createMessage.error('请选择组织'); | |
625 | + throw Error('请选择组织'); | |
626 | + } | |
627 | + if (!Reflect.get(obj, 'organizationId')) { | |
628 | + createMessage.error('请选择组织'); | |
629 | + throw Error('请选择组织'); | |
630 | + } | |
631 | + }; | |
632 | + | |
620 | 633 | // 添加触发器 |
621 | 634 | const addTrigger = () => { |
622 | 635 | unref(triggerData).push(Date.now()); |
623 | 636 | nextTick(() => { |
624 | 637 | setFields(skipUnwrap.triggerItemRefs); |
625 | 638 | }); |
639 | + isEmptyThrowError(getFieldsValue()); | |
626 | 640 | }; |
627 | 641 | // 添加执行条件 |
628 | 642 | const addCondition = () => { |
... | ... | @@ -630,6 +644,7 @@ |
630 | 644 | nextTick(() => { |
631 | 645 | setFields(skipUnwrap.conditionItemRefs); |
632 | 646 | }); |
647 | + isEmptyThrowError(getFieldsValue()); | |
633 | 648 | }; |
634 | 649 | // 添加执行动作 |
635 | 650 | const addAction = () => { |
... | ... | @@ -637,6 +652,7 @@ |
637 | 652 | nextTick(() => { |
638 | 653 | setFields(skipUnwrap.actionItemRefs); |
639 | 654 | }); |
655 | + isEmptyThrowError(getFieldsValue()); | |
640 | 656 | }; |
641 | 657 | |
642 | 658 | /** | ... | ... |
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="scriptType" | |
33 | - :rules="[{ required: true, message: '请选择脚本类型' }]" | |
34 | - > | |
35 | - <a-space direction="vertical"> | |
36 | - <a-radio-group | |
37 | - @change="handleScriptType" | |
38 | - v-model:value="scriptForm.scriptType" | |
39 | - :options="scriptTypeOptions" | |
40 | - /> | |
41 | - </a-space> | |
42 | - </a-form-item> | |
43 | - <a-form-item | |
44 | - label="保存原始数据" | |
45 | - name="saveOriginalData" | |
46 | - :rules="[{ required: true, message: '请选择保存原始数据' }]" | |
47 | - > | |
48 | - <a-space direction="vertical"> | |
49 | - <a-radio-group v-model:value="scriptForm.saveOriginalData" :options="originalOptions" /> | |
50 | - </a-space> | |
51 | - </a-form-item> | |
52 | - <a-form-item label="脚本内容" :name="ifAdd ? 'convertJs' : 'script'"> | |
53 | - <Card title="脚本内容" :bodyStyle="{ padding: 0, height: '280px' }"> | |
54 | - <template #extra> | |
55 | - <a-button @click="handleFormat" size="small">格式化</a-button> | |
56 | - <Tooltip :title="defaultTitle" class="ml-2"> | |
57 | - <QuestionCircleOutlined style="font-size: 1rem" /> | |
58 | - </Tooltip> | |
59 | - </template> | |
60 | - <div ref="aceRef" class="overflow-hidden"></div> | |
61 | - </Card> | |
62 | - <Button @click="handleCopy" class="mt-4"> | |
63 | - <template #icon> | |
64 | - <CopyOutlined /> | |
65 | - </template> | |
66 | - copy | |
67 | - </Button> | |
68 | - </a-form-item> | |
69 | - <a-form-item | |
70 | - :label="ifAdd ? '备注' : '输出参数(output)'" | |
71 | - :name="ifAdd ? 'description' : 'output'" | |
72 | - > | |
73 | - <a-textarea | |
74 | - :rows="3" | |
75 | - v-if="ifAdd" | |
76 | - v-model:value="scriptForm.description" | |
77 | - placeholder="请输入备注" | |
78 | - :maxlength="255" | |
79 | - /> | |
80 | - <a-textarea | |
81 | - disabled | |
82 | - :rows="5" | |
83 | - v-else | |
84 | - v-model:value="scriptForm.output" | |
85 | - placeholder="输出参数为服务端返回的内容" | |
86 | - :maxlength="255" | |
87 | - /> | |
88 | - </a-form-item> | |
89 | - </a-form> | |
90 | - </div> | |
91 | -</template> | |
92 | -<script setup lang="ts"> | |
93 | - import { ref, unref, reactive, onMounted, toRefs, nextTick, computed } from 'vue'; | |
94 | - import ace from 'ace-builds'; | |
95 | - import { Card, Button, Tooltip } from 'ant-design-vue'; | |
96 | - import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 | |
97 | - import 'ace-builds/src-noconflict/theme-terminal'; // 默认设置的主题 | |
98 | - import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式 | |
99 | - import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js'; | |
100 | - import { CopyOutlined } from '@ant-design/icons-vue'; | |
101 | - import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; | |
102 | - import { useMessage } from '/@/hooks/web/useMessage'; | |
103 | - import { findDictItemByCode } from '/@/api/system/dict'; | |
104 | - import { QuestionCircleOutlined } from '@ant-design/icons-vue'; | |
105 | - import { defaultTitle, defaultScriptTypeContent } from './config.data'; | |
106 | - import { useAppStore } from '/@/store/modules/app'; | |
107 | - | |
108 | - defineEmits(['register']); | |
109 | - const props = defineProps({ | |
110 | - ifAdd: { type: Boolean, default: true }, | |
111 | - }); | |
112 | - | |
113 | - const scriptForm = reactive({ | |
114 | - name: '', | |
115 | - description: '', | |
116 | - convertJs: '', | |
117 | - script: '', | |
118 | - params: '', | |
119 | - output: '', | |
120 | - scriptType: 'TRANSPORT_TCP_UP', | |
121 | - saveOriginalData: 'true', | |
122 | - }); | |
123 | - | |
124 | - const reportTypeOptions = reactive({ | |
125 | - originalOptions: [], | |
126 | - scriptTypeOptions: [], | |
127 | - }); | |
128 | - | |
129 | - const { originalOptions, scriptTypeOptions } = toRefs(reportTypeOptions); | |
130 | - | |
131 | - const { createMessage } = useMessage(); | |
132 | - | |
133 | - const { clipboardRef, copiedRef } = useCopyToClipboard(); | |
134 | - | |
135 | - const aceEditor = ref(); | |
136 | - | |
137 | - const aceRef = ref(); | |
138 | - | |
139 | - const userStore = useAppStore(); | |
140 | - | |
141 | - const getAceClass = computed((): string => userStore.getDarkMode); | |
142 | - | |
143 | - const setDefaultRadio = (p2, p3) => { | |
144 | - scriptForm.saveOriginalData = p2; | |
145 | - scriptForm.scriptType = p3; | |
146 | - }; | |
147 | - | |
148 | - const getDictValue = async (dict_type) => { | |
149 | - const res = await findDictItemByCode({ | |
150 | - dictCode: dict_type, | |
151 | - }); | |
152 | - return res.map((m) => { | |
153 | - return { label: m.itemText, value: m.itemValue }; | |
154 | - }); | |
155 | - }; | |
156 | - | |
157 | - onMounted(async () => { | |
158 | - reportTypeOptions.originalOptions = (await getDictValue('original_data')) as never as any; | |
159 | - reportTypeOptions.scriptTypeOptions = (await getDictValue('script_type')) as never as any; | |
160 | - }); | |
161 | - | |
162 | - // 初始化编辑器 | |
163 | - const initEditor = () => { | |
164 | - aceEditor.value = ace.edit(aceRef.value, { | |
165 | - maxLines: 12, // 最大行数,超过会自动出现滚动条 | |
166 | - minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | |
167 | - fontSize: 14, // 编辑器内字体大小 | |
168 | - theme: 'ace/theme/chrome', // 默认设置的主题 | |
169 | - mode: 'ace/mode/javascript', // 默认设置的语言模式 | |
170 | - tabSize: 2, // 制表符设置为 4 个空格大小 | |
171 | - }); | |
172 | - | |
173 | - aceEditor.value.setOptions({ | |
174 | - enableBasicAutocompletion: true, | |
175 | - enableLiveAutocompletion: true, | |
176 | - theme: getAceClass.value === 'dark' ? 'ace/theme/terminal' : 'ace/theme/chrome', | |
177 | - }); | |
178 | - aceEditor.value.setValue(''); | |
179 | - beautify(aceEditor.value.session); | |
180 | - switchScriptTypeGetContent('TRANSPORT_TCP_UP'); | |
181 | - }; | |
182 | - | |
183 | - const handleScriptType = ({ target }) => { | |
184 | - const { value } = target; | |
185 | - switchScriptTypeGetContent(value); | |
186 | - }; | |
187 | - | |
188 | - const switchScriptTypeGetContent = (type) => { | |
189 | - aceEditor.value.setValue(defaultScriptTypeContent[type]); | |
190 | - }; | |
191 | - | |
192 | - const handleCopy = () => { | |
193 | - const valueRef = aceEditor.value.getValue(); | |
194 | - const value = unref(valueRef); | |
195 | - if (!value) { | |
196 | - createMessage.warning('请输入要拷贝的内容!'); | |
197 | - return; | |
198 | - } | |
199 | - clipboardRef.value = value; | |
200 | - if (unref(copiedRef)) { | |
201 | - createMessage.success('复制成功!'); | |
202 | - } | |
203 | - }; | |
204 | - | |
205 | - const formRef = ref(); | |
206 | - | |
207 | - const getFormData = async () => { | |
208 | - const value = await formRef.value.validateFields(); | |
209 | - if (props.ifAdd) { | |
210 | - scriptForm.convertJs = aceEditor.value.getValue(); | |
211 | - if (scriptForm.convertJs == '') { | |
212 | - createMessage.error('请编写脚本内容'); | |
213 | - throw '请编写脚本内容'; | |
214 | - } | |
215 | - } else { | |
216 | - scriptForm.script = aceEditor.value.getValue(); | |
217 | - if (scriptForm.script == '') { | |
218 | - createMessage.error('请编写脚本内容'); | |
219 | - throw '请编写脚本内容'; | |
220 | - } | |
221 | - } | |
222 | - if (!value) return; | |
223 | - if (scriptForm.params) { | |
224 | - const trimParams = scriptForm.params.replace(/\s*/g, ''); | |
225 | - Reflect.set(value, 'params', trimParams); | |
226 | - } | |
227 | - if (scriptForm.convertJs.length > 1000) { | |
228 | - createMessage.error('脚本内容长度不能大于1000'); | |
229 | - throw '脚本内容长度不能大于1000'; | |
230 | - } | |
231 | - return { | |
232 | - ...value, | |
233 | - ...{ convertJs: props.ifAdd ? scriptForm.convertJs : null }, | |
234 | - ...{ script: !props.ifAdd ? scriptForm.script : null }, | |
235 | - ...{ saveOriginalData: scriptForm.saveOriginalData === 'false' ? false : true }, | |
236 | - }; | |
237 | - }; | |
238 | - | |
239 | - const handleInputChange = (e) => { | |
240 | - const trimParams = e.target.value.replace(/\s*/g, ''); | |
241 | - Reflect.set(scriptForm, 'params', trimParams); | |
242 | - if (scriptForm.scriptType === 'TRANSPORT_TCP_DOWN') { | |
243 | - aceEditor.value.setValue(`out.datas = "${scriptForm.params}";out.deviceName = "sensor";`); | |
244 | - } | |
245 | - }; | |
246 | - | |
247 | - const setFormData = (v) => { | |
248 | - if (v) { | |
249 | - for (let i in scriptForm) { | |
250 | - Reflect.set(scriptForm, i, v[i]); | |
251 | - } | |
252 | - nextTick(() => { | |
253 | - setTimeout(() => { | |
254 | - scriptForm.saveOriginalData = v.saveOriginalData === false ? 'false' : 'true'; | |
255 | - }, 10); | |
256 | - }); | |
257 | - aceEditor.value.setValue(v.convertJs); | |
258 | - handleFormat(); | |
259 | - } | |
260 | - }; | |
261 | - | |
262 | - const setScriptContentData = (v) => { | |
263 | - aceEditor.value.setValue(v); | |
264 | - handleFormat(); | |
265 | - }; | |
266 | - | |
267 | - const resetFormData = () => { | |
268 | - for (let i in scriptForm) { | |
269 | - Reflect.set(scriptForm, i, ''); | |
270 | - } | |
271 | - }; | |
272 | - | |
273 | - const setScriptOutputData = (v) => { | |
274 | - scriptForm.output = v; | |
275 | - }; | |
276 | - | |
277 | - const handleFormat = () => { | |
278 | - beautify(aceEditor.value.session); | |
279 | - aceEditor.value.getSession().setUseWrapMode(true); | |
280 | - }; | |
281 | - | |
282 | - defineExpose({ | |
283 | - initEditor, | |
284 | - getFormData, | |
285 | - resetFormData, | |
286 | - setFormData, | |
287 | - setScriptContentData, | |
288 | - setScriptOutputData, | |
289 | - setDefaultRadio, | |
290 | - }); | |
291 | -</script> | |
292 | -<style lang="less" scoped> | |
293 | - @import url('./ConverScriptModal.less'); | |
294 | -</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-group compact> | |
17 | + <a-input | |
18 | + style="width: calc(100% - 200px)" | |
19 | + v-if="ifAdd" | |
20 | + :maxlength="36" | |
21 | + @change="handleInputChange" | |
22 | + v-model:value="scriptForm.name" | |
23 | + placeholder="请输入脚本名称" | |
24 | + /> | |
25 | + <a-input | |
26 | + @change="handleInputChange" | |
27 | + v-else | |
28 | + v-model:value="scriptForm.params" | |
29 | + placeholder="请输入参数" | |
30 | + /> | |
31 | + <a-button @click="onHandleClick(text)" v-show="ifAdd && !view" type="primary"> | |
32 | + 测试 | |
33 | + </a-button> | |
34 | + </a-input-group> | |
35 | + </a-form-item> | |
36 | + <a-form-item | |
37 | + label="脚本类型" | |
38 | + name="scriptType" | |
39 | + :rules="[{ required: true, message: '请选择脚本类型' }]" | |
40 | + > | |
41 | + <a-space direction="vertical"> | |
42 | + <a-radio-group | |
43 | + @change="handleScriptType" | |
44 | + v-model:value="scriptForm.scriptType" | |
45 | + :options="scriptTypeOptions" | |
46 | + /> | |
47 | + </a-space> | |
48 | + </a-form-item> | |
49 | + <a-form-item | |
50 | + label="保存原始数据" | |
51 | + name="saveOriginalData" | |
52 | + :rules="[{ required: true, message: '请选择保存原始数据' }]" | |
53 | + > | |
54 | + <a-space direction="vertical"> | |
55 | + <a-radio-group v-model:value="scriptForm.saveOriginalData" :options="originalOptions" /> | |
56 | + </a-space> | |
57 | + </a-form-item> | |
58 | + <a-form-item label="脚本内容" :name="ifAdd ? 'convertJs' : 'script'"> | |
59 | + <Card title="脚本内容" :bodyStyle="{ padding: 0, height: '280px' }"> | |
60 | + <template #extra> | |
61 | + <a-button @click="handleFormat" size="small">格式化</a-button> | |
62 | + <Tooltip v-if="!ifAdd" :title="defaultAuthTitle" class="ml-2"> | |
63 | + <QuestionCircleOutlined style="font-size: 1rem" /> | |
64 | + </Tooltip> | |
65 | + <Tooltip v-if="!ifAdd" :title="defaultUpTitle" class="ml-2"> | |
66 | + <QuestionCircleOutlined style="font-size: 1rem" /> | |
67 | + </Tooltip> | |
68 | + </template> | |
69 | + <div ref="aceRef" class="overflow-hidden"></div> | |
70 | + </Card> | |
71 | + <Button @click="handleCopy" class="mt-4"> | |
72 | + <template #icon> | |
73 | + <CopyOutlined /> | |
74 | + </template> | |
75 | + copy | |
76 | + </Button> | |
77 | + </a-form-item> | |
78 | + <a-form-item | |
79 | + :label="ifAdd ? '备注' : '输出参数(output)'" | |
80 | + :name="ifAdd ? 'description' : 'output'" | |
81 | + > | |
82 | + <a-textarea | |
83 | + :rows="3" | |
84 | + v-if="ifAdd" | |
85 | + v-model:value="scriptForm.description" | |
86 | + placeholder="请输入备注" | |
87 | + :maxlength="255" | |
88 | + /> | |
89 | + <a-textarea | |
90 | + :rows="5" | |
91 | + v-else | |
92 | + v-model:value="scriptForm.output" | |
93 | + placeholder="输出参数为服务端返回的内容" | |
94 | + :maxlength="255" | |
95 | + /> | |
96 | + </a-form-item> | |
97 | + </a-form> | |
98 | + <TestScriptModal @register="registerModal" @success="handleSuccess" /> | |
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 { defaultAuthTitle, defaultUpTitle, defaultScriptTypeContent } from './config.data'; | |
115 | + import { useAppStore } from '/@/store/modules/app'; | |
116 | + import TestScriptModal from './TestScriptModal.vue'; | |
117 | + import { useModal } from '/@/components/Modal'; | |
118 | + | |
119 | + defineEmits(['register']); | |
120 | + const props = defineProps({ | |
121 | + ifAdd: { type: Boolean, default: true }, | |
122 | + text: { type: String, default: '' }, | |
123 | + view: { type: Boolean, default: false }, | |
124 | + }); | |
125 | + | |
126 | + const scriptForm = reactive({ | |
127 | + name: '', | |
128 | + description: '', | |
129 | + convertJs: '', | |
130 | + script: '', | |
131 | + params: '', | |
132 | + output: '', | |
133 | + scriptType: 'TRANSPORT_TCP_UP', | |
134 | + saveOriginalData: 'true', | |
135 | + }); | |
136 | + | |
137 | + const reportTypeOptions = reactive({ | |
138 | + originalOptions: [], | |
139 | + scriptTypeOptions: [], | |
140 | + }); | |
141 | + | |
142 | + const { originalOptions, scriptTypeOptions } = toRefs(reportTypeOptions); | |
143 | + | |
144 | + const { createMessage } = useMessage(); | |
145 | + | |
146 | + const { clipboardRef, copiedRef } = useCopyToClipboard(); | |
147 | + | |
148 | + const aceEditor = ref(); | |
149 | + | |
150 | + const aceRef = ref(); | |
151 | + | |
152 | + const userStore = useAppStore(); | |
153 | + | |
154 | + const getAceClass = computed((): string => userStore.getDarkMode); | |
155 | + | |
156 | + const setDefaultRadio = (p2, p3) => { | |
157 | + scriptForm.saveOriginalData = p2; | |
158 | + scriptForm.scriptType = p3; | |
159 | + }; | |
160 | + | |
161 | + const getDictValue = async (dict_type) => { | |
162 | + const res = await findDictItemByCode({ | |
163 | + dictCode: dict_type, | |
164 | + }); | |
165 | + return res.map((m) => { | |
166 | + return { label: m.itemText, value: m.itemValue }; | |
167 | + }); | |
168 | + }; | |
169 | + | |
170 | + onMounted(async () => { | |
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 | + aceEditor.value.setValue(defaultScriptTypeContent[type]); | |
203 | + }; | |
204 | + | |
205 | + const handleCopy = () => { | |
206 | + const valueRef = aceEditor.value.getValue(); | |
207 | + const value = unref(valueRef); | |
208 | + if (!value) { | |
209 | + createMessage.warning('请输入要拷贝的内容!'); | |
210 | + return; | |
211 | + } | |
212 | + clipboardRef.value = value; | |
213 | + if (unref(copiedRef)) { | |
214 | + createMessage.success('复制成功!'); | |
215 | + } | |
216 | + }; | |
217 | + | |
218 | + const formRef = ref(); | |
219 | + | |
220 | + const getFormData = async () => { | |
221 | + const value = await formRef.value.validateFields(); | |
222 | + if (props.ifAdd) { | |
223 | + scriptForm.convertJs = aceEditor.value.getValue(); | |
224 | + if (scriptForm.convertJs == '') { | |
225 | + createMessage.error('请编写脚本内容'); | |
226 | + throw '请编写脚本内容'; | |
227 | + } | |
228 | + } else { | |
229 | + scriptForm.script = aceEditor.value.getValue(); | |
230 | + if (scriptForm.script == '') { | |
231 | + createMessage.error('请编写脚本内容'); | |
232 | + throw '请编写脚本内容'; | |
233 | + } | |
234 | + } | |
235 | + if (!value) return; | |
236 | + if (scriptForm.params) { | |
237 | + const trimParams = scriptForm.params.replace(/\s*/g, ''); | |
238 | + Reflect.set(value, 'params', trimParams); | |
239 | + } | |
240 | + if (scriptForm.convertJs.length > 1000) { | |
241 | + createMessage.error('脚本内容长度不能大于1000'); | |
242 | + throw '脚本内容长度不能大于1000'; | |
243 | + } | |
244 | + return { | |
245 | + ...value, | |
246 | + ...{ convertJs: props.ifAdd ? scriptForm.convertJs : null }, | |
247 | + ...{ script: !props.ifAdd ? scriptForm.script : null }, | |
248 | + ...{ saveOriginalData: scriptForm.saveOriginalData === 'false' ? false : true }, | |
249 | + }; | |
250 | + }; | |
251 | + | |
252 | + const handleInputChange = (e) => { | |
253 | + const trimParams = e.target.value.replace(/\s*/g, ''); | |
254 | + Reflect.set(scriptForm, 'params', trimParams); | |
255 | + if (scriptForm.scriptType === 'TRANSPORT_TCP_DOWN') { | |
256 | + aceEditor.value.setValue(`out.datas = "${scriptForm.params}";out.deviceName = "sensor";`); | |
257 | + } | |
258 | + }; | |
259 | + | |
260 | + const getRecordId = ref(''); | |
261 | + | |
262 | + const setFormData = (v) => { | |
263 | + if (v) { | |
264 | + getRecordId.value = v?.id; | |
265 | + for (let i in scriptForm) { | |
266 | + Reflect.set(scriptForm, i, v[i]); | |
267 | + } | |
268 | + nextTick(() => { | |
269 | + setTimeout(() => { | |
270 | + scriptForm.saveOriginalData = v.saveOriginalData === false ? 'false' : 'true'; | |
271 | + }, 10); | |
272 | + }); | |
273 | + aceEditor.value.setValue(v.convertJs); | |
274 | + handleFormat(); | |
275 | + } | |
276 | + }; | |
277 | + | |
278 | + const setScriptContentData = (v) => { | |
279 | + aceEditor.value.setValue(v); | |
280 | + handleFormat(); | |
281 | + }; | |
282 | + | |
283 | + const resetFormData = () => { | |
284 | + for (let i in scriptForm) { | |
285 | + Reflect.set(scriptForm, i, ''); | |
286 | + } | |
287 | + }; | |
288 | + | |
289 | + const setScriptOutputData = (v) => { | |
290 | + scriptForm.output = v; | |
291 | + }; | |
292 | + | |
293 | + const handleFormat = () => { | |
294 | + beautify(aceEditor.value.session); | |
295 | + aceEditor.value.getSession().setUseWrapMode(true); | |
296 | + }; | |
297 | + | |
298 | + const [registerModal, { openModal }] = useModal(); | |
299 | + | |
300 | + const onHandleClick = (o) => { | |
301 | + openModal(true, { | |
302 | + isAuth: '', | |
303 | + isUpdate: false, | |
304 | + record: o === 'add' ? null : getRecordId.value, | |
305 | + isTest: true, | |
306 | + isText: 'test', | |
307 | + isTitle: 'test', | |
308 | + }); | |
309 | + }; | |
310 | + | |
311 | + defineExpose({ | |
312 | + initEditor, | |
313 | + getFormData, | |
314 | + resetFormData, | |
315 | + setFormData, | |
316 | + setScriptContentData, | |
317 | + setScriptOutputData, | |
318 | + setDefaultRadio, | |
319 | + }); | |
320 | +</script> | |
321 | +<style lang="less" scoped> | |
322 | + @import url('./ConverScriptModal.less'); | |
323 | +</style> | ... | ... |
... | ... | @@ -10,7 +10,12 @@ |
10 | 10 | @cancel="handleCancel" |
11 | 11 | @ok="handleSubmit" |
12 | 12 | > |
13 | - <ConverScript :ifAdd="isTest ? false : true" ref="converScriptRef" /> | |
13 | + <ConverScript | |
14 | + :view="isViewDetail" | |
15 | + :text="isTitle" | |
16 | + :ifAdd="isTest ? false : true" | |
17 | + ref="converScriptRef" | |
18 | + /> | |
14 | 19 | </BasicModal> |
15 | 20 | </div> |
16 | 21 | </template> | ... | ... |
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 | |
14 | + :view="isViewDetail" | |
15 | + :text="isTitle" | |
16 | + :ifAdd="isTest ? false : true" | |
17 | + ref="converScriptRef" | |
18 | + /> | |
19 | + </BasicModal> | |
20 | + </div> | |
21 | +</template> | |
22 | +<script setup lang="ts"> | |
23 | + import { ref, computed, unref, reactive } from 'vue'; | |
24 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
25 | + import ConverScript from './ConverScript.vue'; | |
26 | + import { | |
27 | + createOrEditScriptManage, | |
28 | + getScriptManageDetail, | |
29 | + testScriptManage, | |
30 | + } from '/@/api/scriptmanage/scriptManager'; | |
31 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
32 | + | |
33 | + const emits = defineEmits(['success', 'register']); | |
34 | + const { createMessage } = useMessage(); | |
35 | + const converScriptRef = ref<InstanceType<typeof ConverScript>>(); | |
36 | + const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本')); | |
37 | + const isUpdate = ref(false); | |
38 | + const isViewDetail = ref(''); | |
39 | + const isTest = ref(false); | |
40 | + const isText = ref(''); | |
41 | + const isTitle = ref(''); | |
42 | + const editData = reactive({ | |
43 | + data: {}, | |
44 | + }); | |
45 | + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | |
46 | + setModalProps({ loading: true }); | |
47 | + handleCancel(false); | |
48 | + isUpdate.value = data.isUpdate; | |
49 | + isViewDetail.value = data.isView; | |
50 | + isTest.value = data.isTest; | |
51 | + isText.value = data.isText; | |
52 | + isTitle.value = data.isTitle; | |
53 | + editData.data = data.record; | |
54 | + setModalProps({ loading: false }); | |
55 | + converScriptRef.value?.initEditor(); | |
56 | + if (!unref(isViewDetail)) { | |
57 | + const title = | |
58 | + unref(isTitle) == 'edit' | |
59 | + ? '编辑转换脚本' | |
60 | + : unref(isTitle) == 'add' | |
61 | + ? '新增转换脚本' | |
62 | + : '测试转换脚本'; | |
63 | + const okText = isText.value == 'test' ? '测试' : '确定'; | |
64 | + if (unref(isTitle) == 'add') { | |
65 | + converScriptRef.value?.setDefaultRadio('true', 'TRANSPORT_TCP_UP'); | |
66 | + } | |
67 | + if (unref(isTitle) == 'edit') { | |
68 | + converScriptRef.value?.setFormData(data.record); | |
69 | + } | |
70 | + if (unref(isTitle) == 'test') { | |
71 | + if (data.record) { | |
72 | + const res = await getScriptManageDetail(data.record); | |
73 | + converScriptRef.value?.setFormData(res); | |
74 | + } else { | |
75 | + converScriptRef.value?.setDefaultRadio('true', 'TRANSPORT_TCP_UP'); | |
76 | + } | |
77 | + } | |
78 | + setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText }); | |
79 | + if (!unref(isUpdate)) { | |
80 | + } | |
81 | + } else { | |
82 | + setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看转换脚本' }); | |
83 | + const res = await getScriptManageDetail(data.record.id); | |
84 | + converScriptRef.value?.setFormData(res || {}); | |
85 | + } | |
86 | + }); | |
87 | + | |
88 | + const handleSubmit = async () => { | |
89 | + setModalProps({ confirmLoading: true }); | |
90 | + try { | |
91 | + const val = await converScriptRef.value?.getFormData(); | |
92 | + const tempObj = { | |
93 | + ...editData.data, | |
94 | + ...val, | |
95 | + }; | |
96 | + const res: any = | |
97 | + isText.value == 'test' | |
98 | + ? await testScriptManage(val) | |
99 | + : await createOrEditScriptManage(tempObj); | |
100 | + createMessage.success( | |
101 | + unref(isTitle) == 'edit' | |
102 | + ? '编辑转换脚本成功' | |
103 | + : unref(isTitle) == 'add' | |
104 | + ? '新增转换脚本成功' | |
105 | + : '测试转换脚本成功' | |
106 | + ); | |
107 | + if (unref(isTitle) == 'add' || unref(isTitle) == 'edit') { | |
108 | + setTimeout(() => { | |
109 | + closeModal(); | |
110 | + }, 10); | |
111 | + emits('success', { | |
112 | + res, | |
113 | + text: isText.value, | |
114 | + }); | |
115 | + } else { | |
116 | + if (res) { | |
117 | + converScriptRef.value?.setScriptOutputData(res?.output || res?.error); | |
118 | + } | |
119 | + } | |
120 | + } finally { | |
121 | + setModalProps({ confirmLoading: false }); | |
122 | + } | |
123 | + }; | |
124 | + const handleCancel = (flag) => { | |
125 | + if (flag) { | |
126 | + closeModal(); | |
127 | + } | |
128 | + converScriptRef.value?.resetFormData(); | |
129 | + }; | |
130 | +</script> | |
131 | +<style lang="less" scoped> | |
132 | + @import url('./ConverScriptModal.less'); | |
133 | +</style> | ... | ... |
... | ... | @@ -58,25 +58,30 @@ export const searchFormSchema: FormSchema[] = [ |
58 | 58 | }, |
59 | 59 | ]; |
60 | 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 | - ]), | |
61 | +export const defaultAuthTitle = h('div', { style: 'background:#404040' }, [ | |
62 | + h('h3', { style: 'color:white' }, '设备鉴权示例'), | |
63 | + h('h3', { style: 'color:white' }, '输入参数:为16进制字符串'), | |
64 | + h('h3', { style: 'color:white' }, '输出参数:{"password":"","success":""}'), | |
65 | + h('h3', { style: 'color:white' }, 'password为设备鉴权信息,success为鉴权成功后响应给设备的内容'), | |
66 | +]); | |
67 | + | |
68 | +export const defaultUpTitle = h('div', { style: 'background:#404040' }, [ | |
69 | + h('h3', { style: 'color:white' }, '上行数据解析示例'), | |
70 | + h('h3', { style: 'color:white' }, '输入参数:为字符串'), | |
71 | + h( | |
72 | + 'h3', | |
73 | + { style: 'color:white' }, | |
74 | + `输出参数:{"datas":{"source":""},"telemetry":true,"ackMsg":"","deviceName":"","ts":1681701034289}` | |
75 | + ), | |
76 | + h( | |
77 | + 'h3', | |
78 | + { style: 'color:white' }, | |
79 | + `datas:json对象,属性名为遥测指标或子设备名称 | |
80 | + telemetry: datas内容是否为遥测数据 | |
81 | + ackMsg: 响应给设备的确认消息 | |
82 | + deviceName: 设备名称 | |
83 | + ts: 数据采集时间` | |
84 | + ), | |
80 | 85 | ]); |
81 | 86 | |
82 | 87 | // TRANSPORT_TCP_DOWN: 'out.datas = "";out.deviceName = "sensor";', | ... | ... |
... | ... | @@ -273,6 +273,8 @@ |
273 | 273 | status: searchInfo.status, |
274 | 274 | page: pagination.current, |
275 | 275 | pageSize: pagination.pageSize, |
276 | + startTime: moment(searchInfo.sendTime.at(-2)).valueOf(), | |
277 | + endTime: moment(searchInfo.sendTime.at(-1)).valueOf(), | |
276 | 278 | }); |
277 | 279 | setTableData(res.items); |
278 | 280 | pagination.total = res.total; | ... | ... |