Showing
16 changed files
with
547 additions
and
107 deletions
@@ -62,7 +62,7 @@ export const step1Schemas: FormSchema[] = [ | @@ -62,7 +62,7 @@ export const step1Schemas: FormSchema[] = [ | ||
62 | componentProps: { | 62 | componentProps: { |
63 | api: findDictItemByCode, | 63 | api: findDictItemByCode, |
64 | params: { | 64 | params: { |
65 | - dictCode: 'DEVICE_BRAND_GATEWAY', | 65 | + dictCode: 'device_brand_gateway', |
66 | }, | 66 | }, |
67 | labelField: 'itemText', | 67 | labelField: 'itemText', |
68 | valueField: 'itemValue', | 68 | valueField: 'itemValue', |
@@ -8,23 +8,50 @@ | @@ -8,23 +8,50 @@ | ||
8 | @ok="handleSubmit" | 8 | @ok="handleSubmit" |
9 | @cancel="handleCancel" | 9 | @cancel="handleCancel" |
10 | > | 10 | > |
11 | - <Tabs | ||
12 | - type="card" | ||
13 | - :animated="true" | ||
14 | - v-model:activeKey="activeKey" | ||
15 | - :size="size" | ||
16 | - @change="handleChange" | ||
17 | - > | ||
18 | - <TabPane forceRender key="1" tab="设备配置"> | ||
19 | - <DeviceConfigurationStep v-show="activeKey === '1'" ref="DevConStRef" /> | ||
20 | - </TabPane> | ||
21 | - <TabPane forceRender key="2" tab="传输配置"> | ||
22 | - <TransportConfigurationStep v-show="activeKey === '2'" ref="TransConStRef" /> | ||
23 | - </TabPane> | ||
24 | - <TabPane forceRender key="3" v-show="activeKey === '3'" tab="物模型管理"> | ||
25 | - <PhysicalModelManagementStep v-show="activeKey === '3'" ref="PhysicalModManRef" /> | ||
26 | - </TabPane> | ||
27 | - </Tabs> | 11 | + <div v-if="!isViewDetail" class="step-form-form"> |
12 | + <a-steps :current="current"> | ||
13 | + <a-step v-for="item in steps" :key="item.title" :title="item.title" /> | ||
14 | + </a-steps> | ||
15 | + </div> | ||
16 | + <div v-if="!isViewDetail" class="mt-5"> | ||
17 | + <DeviceConfigurationStep | ||
18 | + v-show="current === 0" | ||
19 | + ref="DevConStRef" | ||
20 | + @next="handleStepNext(true, null)" | ||
21 | + /> | ||
22 | + <TransportConfigurationStep | ||
23 | + v-show="current === 1" | ||
24 | + ref="TransConStRef" | ||
25 | + @prev="handleStepPrev" | ||
26 | + /> | ||
27 | + </div> | ||
28 | + <div v-if="isViewDetail"> | ||
29 | + <Tabs | ||
30 | + type="card" | ||
31 | + :animated="true" | ||
32 | + v-model:activeKey="activeKey" | ||
33 | + :size="size" | ||
34 | + @change="handleChange" | ||
35 | + > | ||
36 | + <TabPane forceRender key="1" tab="设备配置"> | ||
37 | + <DeviceConfigurationStep | ||
38 | + :ifShowBtn="isViewDetail ? false : true" | ||
39 | + v-show="activeKey === '1'" | ||
40 | + ref="DevConStRef" | ||
41 | + /> | ||
42 | + </TabPane> | ||
43 | + <TabPane forceRender key="2" tab="传输配置"> | ||
44 | + <TransportConfigurationStep | ||
45 | + :ifShowBtn="isViewDetail ? false : true" | ||
46 | + v-show="activeKey === '2'" | ||
47 | + ref="TransConStRef" | ||
48 | + /> | ||
49 | + </TabPane> | ||
50 | + <TabPane forceRender key="3" v-show="activeKey === '3'" tab="物模型管理"> | ||
51 | + <PhysicalModelManagementStep v-show="activeKey === '3'" ref="PhysicalModManRef" /> | ||
52 | + </TabPane> | ||
53 | + </Tabs> | ||
54 | + </div> | ||
28 | </BasicModal> | 55 | </BasicModal> |
29 | </div> | 56 | </div> |
30 | </template> | 57 | </template> |
@@ -33,6 +60,7 @@ | @@ -33,6 +60,7 @@ | ||
33 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 60 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
34 | import { deviceConfigAddOrEdit, deviceConfigGetDetail } from '/@/api/device/deviceConfigApi'; | 61 | import { deviceConfigAddOrEdit, deviceConfigGetDetail } from '/@/api/device/deviceConfigApi'; |
35 | import { useMessage } from '/@/hooks/web/useMessage'; | 62 | import { useMessage } from '/@/hooks/web/useMessage'; |
63 | + import { steps } from './device.profile.data'; | ||
36 | import { isEmpty } from '/@/utils/is'; | 64 | import { isEmpty } from '/@/utils/is'; |
37 | import { Tabs, TabPane } from 'ant-design-vue'; | 65 | import { Tabs, TabPane } from 'ant-design-vue'; |
38 | import DeviceConfigurationStep from './step/DeviceConfigurationStep.vue'; | 66 | import DeviceConfigurationStep from './step/DeviceConfigurationStep.vue'; |
@@ -47,6 +75,7 @@ | @@ -47,6 +75,7 @@ | ||
47 | const { createMessage } = useMessage(); | 75 | const { createMessage } = useMessage(); |
48 | const isViewDetail = ref(false); | 76 | const isViewDetail = ref(false); |
49 | const isUpdate = ref(false); | 77 | const isUpdate = ref(false); |
78 | + const current = ref(0); | ||
50 | const DevConStRef = ref<InstanceType<typeof DeviceConfigurationStep>>(); | 79 | const DevConStRef = ref<InstanceType<typeof DeviceConfigurationStep>>(); |
51 | const TransConStRef = ref<InstanceType<typeof TransportConfigurationStep>>(); | 80 | const TransConStRef = ref<InstanceType<typeof TransportConfigurationStep>>(); |
52 | const PhysicalModManRef = ref<InstanceType<typeof PhysicalModelManagementStep>>(); | 81 | const PhysicalModManRef = ref<InstanceType<typeof PhysicalModelManagementStep>>(); |
@@ -59,6 +88,7 @@ | @@ -59,6 +88,7 @@ | ||
59 | const transportTypeStr = ref(''); | 88 | const transportTypeStr = ref(''); |
60 | const [register, { closeModal, setModalProps }] = useModalInner(async (data) => { | 89 | const [register, { closeModal, setModalProps }] = useModalInner(async (data) => { |
61 | setModalProps({ confirmLoading: false }); | 90 | setModalProps({ confirmLoading: false }); |
91 | + current.value = 0; | ||
62 | isUpdate.value = data.isUpdate; | 92 | isUpdate.value = data.isUpdate; |
63 | isViewDetail.value = data.isView; | 93 | isViewDetail.value = data.isView; |
64 | const res = data.record !== undefined ? await deviceConfigGetDetail(data.record.id) : {}; | 94 | const res = data.record !== undefined ? await deviceConfigGetDetail(data.record.id) : {}; |
@@ -73,7 +103,7 @@ | @@ -73,7 +103,7 @@ | ||
73 | handleStepNext(false, res); | 103 | handleStepNext(false, res); |
74 | } | 104 | } |
75 | } else { | 105 | } else { |
76 | - setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看设备配置' }); | 106 | + setModalProps({ showOkBtn: false, showCancelBtn: false, title: '设备配置详情' }); |
77 | await setDeviceConfEditFormData(res); | 107 | await setDeviceConfEditFormData(res); |
78 | await setTransConfEditFormData(res); | 108 | await setTransConfEditFormData(res); |
79 | handleStepNext(false, res); | 109 | handleStepNext(false, res); |
@@ -86,10 +116,14 @@ | @@ -86,10 +116,14 @@ | ||
86 | }; | 116 | }; |
87 | const handleStepNext = (e, data) => { | 117 | const handleStepNext = (e, data) => { |
88 | if (e) { | 118 | if (e) { |
119 | + current.value++; | ||
89 | } else { | 120 | } else { |
90 | setTransConfEditFormData(data); | 121 | setTransConfEditFormData(data); |
91 | } | 122 | } |
92 | }; | 123 | }; |
124 | + const handleStepPrev = () => { | ||
125 | + current.value--; | ||
126 | + }; | ||
93 | 127 | ||
94 | const setDeviceConfEditFormData = async (res) => { | 128 | const setDeviceConfEditFormData = async (res) => { |
95 | await DevConStRef.value?.setFormData(res); | 129 | await DevConStRef.value?.setFormData(res); |
@@ -8,6 +8,17 @@ import { h } from 'vue'; | @@ -8,6 +8,17 @@ import { h } from 'vue'; | ||
8 | 8 | ||
9 | import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi'; | 9 | import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi'; |
10 | 10 | ||
11 | +export const steps = [ | ||
12 | + { | ||
13 | + title: '设备配置', | ||
14 | + content: 'First-content', | ||
15 | + }, | ||
16 | + { | ||
17 | + title: '传输配置', | ||
18 | + content: 'Second-content', | ||
19 | + }, | ||
20 | +]; | ||
21 | + | ||
11 | export const physicalColumn: BasicColumn[] = [ | 22 | export const physicalColumn: BasicColumn[] = [ |
12 | { | 23 | { |
13 | title: '功能名称', | 24 | title: '功能名称', |
@@ -61,6 +72,24 @@ export const step1Schemas: FormSchema[] = [ | @@ -61,6 +72,24 @@ export const step1Schemas: FormSchema[] = [ | ||
61 | slot: 'imageSelect', | 72 | slot: 'imageSelect', |
62 | }, | 73 | }, |
63 | { | 74 | { |
75 | + field: 'brand', | ||
76 | + component: 'ApiRadioGroup', | ||
77 | + label: '设备类型', | ||
78 | + required: true, | ||
79 | + colProps: { | ||
80 | + span: 14, | ||
81 | + }, | ||
82 | + defaultValue: 'GATEWAY', | ||
83 | + componentProps: { | ||
84 | + api: findDictItemByCode, | ||
85 | + params: { | ||
86 | + dictCode: 'device_type', | ||
87 | + }, | ||
88 | + labelField: 'itemText', | ||
89 | + valueField: 'itemValue', | ||
90 | + }, | ||
91 | + }, | ||
92 | + { | ||
64 | field: 'name', | 93 | field: 'name', |
65 | label: '配置名称', | 94 | label: '配置名称', |
66 | required: true, | 95 | required: true, |
@@ -37,9 +37,13 @@ | @@ -37,9 +37,13 @@ | ||
37 | import { useMessage } from '/@/hooks/web/useMessage'; | 37 | import { useMessage } from '/@/hooks/web/useMessage'; |
38 | import type { FileItem } from '/@/components/Upload/src/typing'; | 38 | import type { FileItem } from '/@/components/Upload/src/typing'; |
39 | 39 | ||
40 | + const emits = defineEmits(['next']); | ||
40 | const loading = ref(false); | 41 | const loading = ref(false); |
41 | const { createMessage } = useMessage(); | 42 | const { createMessage } = useMessage(); |
42 | const deviceConfigPic = ref(''); | 43 | const deviceConfigPic = ref(''); |
44 | + const props = defineProps({ | ||
45 | + ifShowBtn: { type: Boolean, default: true }, | ||
46 | + }); | ||
43 | 47 | ||
44 | const [register, { validate, setFieldsValue, resetFields, updateSchema }] = useForm({ | 48 | const [register, { validate, setFieldsValue, resetFields, updateSchema }] = useForm({ |
45 | labelWidth: 100, | 49 | labelWidth: 100, |
@@ -48,8 +52,11 @@ | @@ -48,8 +52,11 @@ | ||
48 | span: 14, | 52 | span: 14, |
49 | }, | 53 | }, |
50 | showResetButton: false, | 54 | showResetButton: false, |
51 | - submitOnReset: false, | ||
52 | - showActionButtonGroup: false, | 55 | + showActionButtonGroup: props.ifShowBtn ? true : false, |
56 | + submitButtonOptions: { | ||
57 | + text: '下一步', | ||
58 | + }, | ||
59 | + submitFunc: customSubmitFunc, | ||
53 | }); | 60 | }); |
54 | const editOrAddNameStatus = (nameStatus) => | 61 | const editOrAddNameStatus = (nameStatus) => |
55 | updateSchema({ | 62 | updateSchema({ |
@@ -83,6 +90,11 @@ | @@ -83,6 +90,11 @@ | ||
83 | } | 90 | } |
84 | return isJpgOrPng && isLt2M; | 91 | return isJpgOrPng && isLt2M; |
85 | }; | 92 | }; |
93 | + async function customSubmitFunc() { | ||
94 | + const values = await validate(); | ||
95 | + if (!values) return; | ||
96 | + emits('next', true, null); | ||
97 | + } | ||
86 | //回显数据 | 98 | //回显数据 |
87 | const setFormData = (v) => { | 99 | const setFormData = (v) => { |
88 | setFieldsValue(v); | 100 | setFieldsValue(v); |
1 | <template> | 1 | <template> |
2 | - <div> | 2 | + <div class="p-style"> |
3 | <BasicTable | 3 | <BasicTable |
4 | :rowSelection="{ type: 'checkbox' }" | 4 | :rowSelection="{ type: 'checkbox' }" |
5 | :clickToRowSelect="false" | 5 | :clickToRowSelect="false" |
6 | @register="registerTable" | 6 | @register="registerTable" |
7 | > | 7 | > |
8 | <template #toolbar> | 8 | <template #toolbar> |
9 | - <div style="display: flex; justify-content: space-between; width: 773px"> | ||
10 | - <div> | ||
11 | - <Authority value=""> | ||
12 | - <div style="display: flex"> | ||
13 | - <a-button | ||
14 | - style="margin-left: -20px" | ||
15 | - type="primary" | ||
16 | - @click="handleCreateOrEdit(null)" | ||
17 | - > | ||
18 | - 新增物模型 | ||
19 | - </a-button> | ||
20 | - <a-button class="ml-2" type="primary" @click="handleOpenTsl"> 物模型TSL </a-button> | ||
21 | - </div> | ||
22 | - </Authority> | 9 | + <div class="p-column"> |
10 | + <div class="p-content"> | ||
11 | + <a-alert | ||
12 | + style="width: 420px" | ||
13 | + message="当前展示的是已发布到线上的功能定义,如需修改,请点击" | ||
14 | + type="info" | ||
15 | + show-icon | ||
16 | + /> | ||
17 | + <span | ||
18 | + @click="handleEditPhysicalModel" | ||
19 | + class="ml-2" | ||
20 | + style="color: #409eff; cursor: pointer" | ||
21 | + type="primary" | ||
22 | + size="small" | ||
23 | + >“编辑物模型”</span | ||
24 | + > | ||
23 | </div> | 25 | </div> |
24 | - <div> | ||
25 | - <Authority value=""> | ||
26 | - <div style="display: flex"> | ||
27 | - <a-button type="primary"> 发布上线 </a-button> | ||
28 | - <a-button class="ml-2" type="text"> 返回 </a-button> | ||
29 | - <Popconfirm | ||
30 | - title="您确定要批量删除数据" | ||
31 | - ok-text="确定" | ||
32 | - cancel-text="取消" | ||
33 | - @confirm="handleDeleteOrBatchDelete(null)" | ||
34 | - > | 26 | + <div style="height: 20px"></div> |
27 | + <div class="p-bottom"> | ||
28 | + <div> | ||
29 | + <Authority value=""> | ||
30 | + <div style="display: flex"> | ||
35 | <a-button | 31 | <a-button |
36 | - style="display: none" | 32 | + v-if="isShowBtn" |
33 | + style="margin-left: -20px" | ||
37 | type="primary" | 34 | type="primary" |
38 | - color="error" | ||
39 | - :disabled="hasBatchDelete" | 35 | + @click="handleCreateOrEdit(null)" |
40 | > | 36 | > |
41 | - 批量删除 | 37 | + 新增物模型 |
42 | </a-button> | 38 | </a-button> |
43 | - </Popconfirm> | ||
44 | - </div> | ||
45 | - </Authority> | 39 | + <a-button |
40 | + :style="[isShowBtn ? { left: 0 + 'px' } : { left: -29 + 'px' }]" | ||
41 | + class="ml-2" | ||
42 | + type="primary" | ||
43 | + @click="handleOpenTsl" | ||
44 | + > | ||
45 | + 物模型TSL | ||
46 | + </a-button> | ||
47 | + </div> | ||
48 | + </Authority> | ||
49 | + </div> | ||
50 | + <div> | ||
51 | + <Authority value=""> | ||
52 | + <div style="display: flex"> | ||
53 | + <Popconfirm | ||
54 | + title="是否需要发布上线?" | ||
55 | + ok-text="确定" | ||
56 | + cancel-text="取消" | ||
57 | + @confirm="handleEmit" | ||
58 | + > | ||
59 | + <a-button v-if="isShowBtn" type="primary"> 发布上线 </a-button> | ||
60 | + </Popconfirm> | ||
61 | + <a-button | ||
62 | + style="background: #d7d7d7" | ||
63 | + v-if="isShowBtn" | ||
64 | + class="ml-2" | ||
65 | + type="text" | ||
66 | + @click="handleReturn" | ||
67 | + > | ||
68 | + 返回 | ||
69 | + </a-button> | ||
70 | + <Popconfirm | ||
71 | + title="您确定要批量删除数据" | ||
72 | + ok-text="确定" | ||
73 | + cancel-text="取消" | ||
74 | + @confirm="handleDeleteOrBatchDelete(null)" | ||
75 | + > | ||
76 | + <a-button | ||
77 | + style="display: none" | ||
78 | + type="primary" | ||
79 | + color="error" | ||
80 | + :disabled="hasBatchDelete" | ||
81 | + > | ||
82 | + 批量删除 | ||
83 | + </a-button> | ||
84 | + </Popconfirm> | ||
85 | + </div> | ||
86 | + </Authority> | ||
87 | + </div> | ||
46 | </div> | 88 | </div> |
47 | </div> | 89 | </div> |
48 | </template> | 90 | </template> |
@@ -53,18 +95,21 @@ | @@ -53,18 +95,21 @@ | ||
53 | label: '查看', | 95 | label: '查看', |
54 | icon: 'ant-design:eye-outlined', | 96 | icon: 'ant-design:eye-outlined', |
55 | onClick: handleViewDetail.bind(null, record), | 97 | onClick: handleViewDetail.bind(null, record), |
98 | + ifShow: isShowBtn ? false : true, | ||
56 | }, | 99 | }, |
57 | { | 100 | { |
58 | label: '编辑', | 101 | label: '编辑', |
59 | icon: 'clarity:note-edit-line', | 102 | icon: 'clarity:note-edit-line', |
60 | auth: '', | 103 | auth: '', |
61 | onClick: handleCreateOrEdit.bind(null, record), | 104 | onClick: handleCreateOrEdit.bind(null, record), |
105 | + ifShow: !isShowBtn ? false : true, | ||
62 | }, | 106 | }, |
63 | { | 107 | { |
64 | label: '删除', | 108 | label: '删除', |
65 | icon: 'ant-design:delete-outlined', | 109 | icon: 'ant-design:delete-outlined', |
66 | auth: '', | 110 | auth: '', |
67 | color: 'error', | 111 | color: 'error', |
112 | + ifShow: !isShowBtn ? false : true, | ||
68 | popConfirm: { | 113 | popConfirm: { |
69 | title: '是否确认删除', | 114 | title: '是否确认删除', |
70 | confirm: handleDeleteOrBatchDelete.bind(null, record), | 115 | confirm: handleDeleteOrBatchDelete.bind(null, record), |
@@ -79,6 +124,7 @@ | @@ -79,6 +124,7 @@ | ||
79 | </div> | 124 | </div> |
80 | </template> | 125 | </template> |
81 | <script lang="ts" setup> | 126 | <script lang="ts" setup> |
127 | + import { ref } from 'vue'; | ||
82 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 128 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
83 | import { useModal } from '/@/components/Modal'; | 129 | import { useModal } from '/@/components/Modal'; |
84 | import { physicalColumn } from '../device.profile.data'; | 130 | import { physicalColumn } from '../device.profile.data'; |
@@ -89,8 +135,11 @@ | @@ -89,8 +135,11 @@ | ||
89 | import PhysicalModelModal from './cpns/physical/PhysicalModelModal.vue'; | 135 | import PhysicalModelModal from './cpns/physical/PhysicalModelModal.vue'; |
90 | import PhysicalModelTsl from './cpns/physical/PhysicalModelTsl.vue'; | 136 | import PhysicalModelTsl from './cpns/physical/PhysicalModelTsl.vue'; |
91 | import { Popconfirm } from 'ant-design-vue'; | 137 | import { Popconfirm } from 'ant-design-vue'; |
138 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
92 | 139 | ||
93 | defineEmits(['register']); | 140 | defineEmits(['register']); |
141 | + const { createMessage } = useMessage(); | ||
142 | + const isShowBtn = ref(false); | ||
94 | const [registerModal, { openModal }] = useModal(); | 143 | const [registerModal, { openModal }] = useModal(); |
95 | const [registerModalTsl, { openModal: openModalTsl }] = useModal(); | 144 | const [registerModalTsl, { openModal: openModalTsl }] = useModal(); |
96 | 145 | ||
@@ -158,10 +207,27 @@ | @@ -158,10 +207,27 @@ | ||
158 | isUpdate: true, | 207 | isUpdate: true, |
159 | }); | 208 | }); |
160 | }; | 209 | }; |
210 | + const handleEditPhysicalModel = () => (isShowBtn.value = true); | ||
211 | + | ||
212 | + const handleReturn = () => (isShowBtn.value = false); | ||
213 | + const handleEmit = () => { | ||
214 | + createMessage.success('发布成功'); | ||
215 | + }; | ||
216 | + | ||
161 | defineExpose({}); | 217 | defineExpose({}); |
162 | </script> | 218 | </script> |
163 | <style lang="less" scoped> | 219 | <style lang="less" scoped> |
220 | + @import url('./common/PhysicalModelManagementStep.less'); | ||
221 | + | ||
164 | :deep(.ant-table-body) { | 222 | :deep(.ant-table-body) { |
165 | height: auto !important; | 223 | height: auto !important; |
166 | } | 224 | } |
225 | + | ||
226 | + :deep(.ant-divider) { | ||
227 | + margin-top: 58px; | ||
228 | + } | ||
229 | + | ||
230 | + :deep(.table-settings) { | ||
231 | + margin-top: 58px; | ||
232 | + } | ||
167 | </style> | 233 | </style> |
@@ -13,6 +13,8 @@ | @@ -13,6 +13,8 @@ | ||
13 | ? { minHeight: 55 + 'vh' } | 13 | ? { minHeight: 55 + 'vh' } |
14 | : isMqttType == 'SNMP' | 14 | : isMqttType == 'SNMP' |
15 | ? { minHeight: 60 + 'vh' } | 15 | ? { minHeight: 60 + 'vh' } |
16 | + : isMqttType == 'TCP' | ||
17 | + ? { minHeight: 15 + 'vh' } | ||
16 | : { minHeight: 25 + 'vh' }, | 18 | : { minHeight: 25 + 'vh' }, |
17 | ]" | 19 | ]" |
18 | > | 20 | > |
@@ -29,6 +31,16 @@ | @@ -29,6 +31,16 @@ | ||
29 | <div style="margin-top: 5vh" v-else-if="isMqttType == 'SNMP'"> | 31 | <div style="margin-top: 5vh" v-else-if="isMqttType == 'SNMP'"> |
30 | <SnmpCpns ref="snmpRef" /> | 32 | <SnmpCpns ref="snmpRef" /> |
31 | </div> | 33 | </div> |
34 | + <div style="margin-top: 5vh; margin-left: -102px" v-else-if="isMqttType == 'TCP'"> | ||
35 | + <TcpCpns ref="tcpRef" /> | ||
36 | + </div> | ||
37 | + <div v-if="ifShowBtn" class="btn-style"> | ||
38 | + <div style="display: flex; width: 4vw; height: 4vh; margin-top: 1.65vh; margin-left: 44px"> | ||
39 | + <Button type="default" style="border-radius: 2px" class="mt-5" @click="customResetFunc" | ||
40 | + >上一步</Button | ||
41 | + > | ||
42 | + </div> | ||
43 | + </div> | ||
32 | </div> | 44 | </div> |
33 | </div> | 45 | </div> |
34 | </template> | 46 | </template> |
@@ -36,15 +48,22 @@ | @@ -36,15 +48,22 @@ | ||
36 | import { reactive, ref, onUnmounted, nextTick } from 'vue'; | 48 | import { reactive, ref, onUnmounted, nextTick } from 'vue'; |
37 | import { BasicForm, useForm } from '/@/components/Form'; | 49 | import { BasicForm, useForm } from '/@/components/Form'; |
38 | import { step2Schemas } from '../device.profile.data'; | 50 | import { step2Schemas } from '../device.profile.data'; |
51 | + import { Button } from '/@/components/Button'; | ||
39 | import MqttCpns from './cpns/mqtt/Mqtt.vue'; | 52 | import MqttCpns from './cpns/mqtt/Mqtt.vue'; |
40 | import CoapCpns from './cpns/coap/Coap.vue'; | 53 | import CoapCpns from './cpns/coap/Coap.vue'; |
41 | import Lwm2mCpns from './cpns/lwm2m/index.vue'; | 54 | import Lwm2mCpns from './cpns/lwm2m/index.vue'; |
42 | import SnmpCpns from './cpns/snmp/index.vue'; | 55 | import SnmpCpns from './cpns/snmp/index.vue'; |
56 | + import TcpCpns from './cpns/tcp/index.vue'; | ||
43 | 57 | ||
58 | + const emits = defineEmits(['prev']); | ||
59 | + const props = defineProps({ | ||
60 | + ifShowBtn: { type: Boolean, default: true }, | ||
61 | + }); | ||
44 | const mqttRef = ref<InstanceType<typeof MqttCpns>>(); | 62 | const mqttRef = ref<InstanceType<typeof MqttCpns>>(); |
45 | const coapRef = ref<InstanceType<typeof CoapCpns>>(); | 63 | const coapRef = ref<InstanceType<typeof CoapCpns>>(); |
46 | const lwm2mRef = ref<InstanceType<typeof Lwm2mCpns>>(); | 64 | const lwm2mRef = ref<InstanceType<typeof Lwm2mCpns>>(); |
47 | const snmpRef = ref<InstanceType<typeof SnmpCpns>>(); | 65 | const snmpRef = ref<InstanceType<typeof SnmpCpns>>(); |
66 | + const tcpRef = ref<InstanceType<typeof TcpCpns>>(); | ||
48 | const isMqttType = ref('DEFAULT'); | 67 | const isMqttType = ref('DEFAULT'); |
49 | let step2Data = reactive({ | 68 | let step2Data = reactive({ |
50 | transportConfiguration: {}, | 69 | transportConfiguration: {}, |
@@ -57,7 +76,7 @@ | @@ -57,7 +76,7 @@ | ||
57 | }, | 76 | }, |
58 | showResetButton: false, | 77 | showResetButton: false, |
59 | submitOnReset: false, | 78 | submitOnReset: false, |
60 | - showActionButtonGroup: false, | 79 | + showActionButtonGroup: props.ifShowBtn ? true : false, |
61 | }); | 80 | }); |
62 | const setFormData = (v) => { | 81 | const setFormData = (v) => { |
63 | setFieldsValue({ | 82 | setFieldsValue({ |
@@ -68,6 +87,7 @@ | @@ -68,6 +87,7 @@ | ||
68 | coapRef.value?.setFormData(v?.profileData?.transportConfiguration); | 87 | coapRef.value?.setFormData(v?.profileData?.transportConfiguration); |
69 | lwm2mRef.value?.setFormData(v?.profileData?.transportConfiguration); | 88 | lwm2mRef.value?.setFormData(v?.profileData?.transportConfiguration); |
70 | snmpRef.value?.setFormData(v?.profileData?.transportConfiguration); | 89 | snmpRef.value?.setFormData(v?.profileData?.transportConfiguration); |
90 | + tcpRef.value?.setFormData(v?.profileData?.transportConfiguration); | ||
71 | }; | 91 | }; |
72 | 92 | ||
73 | const resetFormData = () => { | 93 | const resetFormData = () => { |
@@ -78,8 +98,12 @@ | @@ -78,8 +98,12 @@ | ||
78 | coapRef.value?.resetFormData(); | 98 | coapRef.value?.resetFormData(); |
79 | lwm2mRef.value?.resetFormData(); | 99 | lwm2mRef.value?.resetFormData(); |
80 | snmpRef.value?.resetFormData(); | 100 | snmpRef.value?.resetFormData(); |
101 | + tcpRef.value?.resetFormData(); | ||
81 | }); | 102 | }); |
82 | }; | 103 | }; |
104 | + async function customResetFunc() { | ||
105 | + emits('prev'); | ||
106 | + } | ||
83 | nextTick(() => { | 107 | nextTick(() => { |
84 | updateSchema({ | 108 | updateSchema({ |
85 | field: 'transportType', | 109 | field: 'transportType', |
@@ -91,6 +115,7 @@ | @@ -91,6 +115,7 @@ | ||
91 | { label: 'CoAP', value: 'COAP' }, | 115 | { label: 'CoAP', value: 'COAP' }, |
92 | { label: 'LWM2M', value: 'LWM2M' }, | 116 | { label: 'LWM2M', value: 'LWM2M' }, |
93 | { label: 'SNMP', value: 'SNMP' }, | 117 | { label: 'SNMP', value: 'SNMP' }, |
118 | + { label: 'TCP', value: 'TCP' }, | ||
94 | ], | 119 | ], |
95 | onChange(e) { | 120 | onChange(e) { |
96 | isMqttType.value = e; | 121 | isMqttType.value = e; |
@@ -109,11 +134,13 @@ | @@ -109,11 +134,13 @@ | ||
109 | const getCoapVal = await coapRef.value?.getFormData(); | 134 | const getCoapVal = await coapRef.value?.getFormData(); |
110 | const getLwm2mVal = await lwm2mRef.value?.getFormData(); | 135 | const getLwm2mVal = await lwm2mRef.value?.getFormData(); |
111 | const getSnmpVal = await snmpRef.value?.getFormData(); | 136 | const getSnmpVal = await snmpRef.value?.getFormData(); |
137 | + const getTcpVal = await tcpRef.value?.getFormData(); | ||
112 | step2Data.transportConfiguration = { | 138 | step2Data.transportConfiguration = { |
113 | ...getMqttVal, | 139 | ...getMqttVal, |
114 | ...getCoapVal, | 140 | ...getCoapVal, |
115 | ...getLwm2mVal, | 141 | ...getLwm2mVal, |
116 | ...getSnmpVal, | 142 | ...getSnmpVal, |
143 | + ...getTcpVal, | ||
117 | ...val, | 144 | ...val, |
118 | }; | 145 | }; |
119 | return step2Data; | 146 | return step2Data; |
1 | +.p-style { | ||
2 | + .p-column { | ||
3 | + display: flex; | ||
4 | + flex-direction: column; | ||
5 | + | ||
6 | + .p-content { | ||
7 | + display: flex; | ||
8 | + align-items: center; | ||
9 | + margin-left: -20px; | ||
10 | + } | ||
11 | + | ||
12 | + .p-bottom { | ||
13 | + display: flex; | ||
14 | + justify-content: space-between; | ||
15 | + width: 773px; | ||
16 | + margin-top: 0; | ||
17 | + } | ||
18 | + } | ||
19 | +} |
@@ -8,32 +8,46 @@ | @@ -8,32 +8,46 @@ | ||
8 | @ok="handleSubmit" | 8 | @ok="handleSubmit" |
9 | @cancel="handleCancel" | 9 | @cancel="handleCancel" |
10 | > | 10 | > |
11 | - <Tabs v-model:activeKey="activeKey" :size="size"> | ||
12 | - <TabPane key="1" tab="属性"> | ||
13 | - <Attr v-show="activeKey === '1'" ref="AttrRef" /> | ||
14 | - </TabPane> | ||
15 | - <TabPane disabled key="2" tab="服务"> | ||
16 | - <Service v-show="activeKey === '2'" ref="ServiceRef" /> | ||
17 | - </TabPane> | ||
18 | - <TabPane disabled key="3" v-show="activeKey === '3'" tab="事件"> | ||
19 | - <Events v-show="activeKey === '3'" ref="EventsRef" /> | ||
20 | - </TabPane> | ||
21 | - </Tabs> | 11 | + <div v-if="isViewDetail"> |
12 | + <Attribute v-show="activeKey === '1'" ref="AttrRef" /> | ||
13 | + </div> | ||
14 | + <div v-if="!isViewDetail"> | ||
15 | + <div> | ||
16 | + <Typography> | ||
17 | + <TypographyParagraph> | ||
18 | + <blockquote style="background: #f2f2f2">{{ blockContent }}</blockquote> | ||
19 | + </TypographyParagraph> | ||
20 | + </Typography> | ||
21 | + </div> | ||
22 | + <Tabs type="card" v-model:activeKey="activeKey" :size="size"> | ||
23 | + <TabPane key="1" tab="属性"> | ||
24 | + <Attribute v-show="activeKey === '1'" ref="AttrRef" /> | ||
25 | + </TabPane> | ||
26 | + <TabPane disabled key="2" tab="服务"> | ||
27 | + <Service v-show="activeKey === '2'" ref="ServiceRef" /> | ||
28 | + </TabPane> | ||
29 | + <TabPane disabled key="3" v-show="activeKey === '3'" tab="事件"> | ||
30 | + <Events v-show="activeKey === '3'" ref="EventsRef" /> | ||
31 | + </TabPane> | ||
32 | + </Tabs> | ||
33 | + </div> | ||
22 | </BasicModal> | 34 | </BasicModal> |
23 | </div> | 35 | </div> |
24 | </template> | 36 | </template> |
25 | <script lang="ts" setup> | 37 | <script lang="ts" setup> |
26 | import { ref, unref } from 'vue'; | 38 | import { ref, unref } from 'vue'; |
27 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 39 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
28 | - import { Tabs, TabPane } from 'ant-design-vue'; | ||
29 | - import Attr from './cpns/Attr.vue'; | 40 | + import { Tabs, TabPane, Typography, TypographyParagraph } from 'ant-design-vue'; |
41 | + import Attribute from './cpns/Attribute.vue'; | ||
30 | import Service from './cpns/Service.vue'; | 42 | import Service from './cpns/Service.vue'; |
31 | import Events from './cpns/Events.vue'; | 43 | import Events from './cpns/Events.vue'; |
32 | 44 | ||
33 | defineEmits(['register']); | 45 | defineEmits(['register']); |
46 | + const blockContent = `属性一般是设备的运行状态,如当前温度等;服务是设备可被调用的方法,支持定义参数,如执行某项任务;事件则是设备上报的 | ||
47 | +通知,如告警,需要被及时处理。`; | ||
34 | const activeKey = ref('1'); | 48 | const activeKey = ref('1'); |
35 | const size = ref('small'); | 49 | const size = ref('small'); |
36 | - const AttrRef = ref<InstanceType<typeof Attr>>(); | 50 | + const AttrRef = ref<InstanceType<typeof Attribute>>(); |
37 | const ServiceRef = ref<InstanceType<typeof Service>>(); | 51 | const ServiceRef = ref<InstanceType<typeof Service>>(); |
38 | const EventsRef = ref<InstanceType<typeof Events>>(); | 52 | const EventsRef = ref<InstanceType<typeof Events>>(); |
39 | const isUpdate = ref(false); | 53 | const isUpdate = ref(false); |
src/views/device/profiles/step/cpns/physical/cpns/Attribute.vue
renamed from
src/views/device/profiles/step/cpns/physical/cpns/Attr.vue
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | - <div style="display: flex; justify-content: space-between"> | 3 | + <div> |
4 | + <Typography> | ||
5 | + <TypographyParagraph> | ||
6 | + <blockquote style="background: #f2f2f2">{{ blockContent }}</blockquote> | ||
7 | + </TypographyParagraph> | ||
8 | + </Typography> | ||
9 | + </div> | ||
10 | + <div style="display: flex; justify-content: space-between; align-items: center"> | ||
4 | <div>模型内容</div> | 11 | <div>模型内容</div> |
5 | <div> | 12 | <div> |
6 | <Button @click="handlePremitter"> | 13 | <Button @click="handlePremitter"> |
@@ -29,10 +36,13 @@ | @@ -29,10 +36,13 @@ | ||
29 | import { useMessage } from '/@/hooks/web/useMessage'; | 36 | import { useMessage } from '/@/hooks/web/useMessage'; |
30 | import jsoneditor from 'jsoneditor'; | 37 | import jsoneditor from 'jsoneditor'; |
31 | import 'jsoneditor/dist/jsoneditor.min.css'; | 38 | import 'jsoneditor/dist/jsoneditor.min.css'; |
32 | - import { Button } from 'ant-design-vue'; | 39 | + import { Button, Typography, TypographyParagraph } from 'ant-design-vue'; |
33 | import { defaultTslContent } from './config'; | 40 | import { defaultTslContent } from './config'; |
34 | 41 | ||
35 | const { createMessage } = useMessage(); | 42 | const { createMessage } = useMessage(); |
43 | + const blockContent = `物模型是对设备在云端的功能描述,包括设备的属性、服务和事件。物联网平台通过定义一种物的描述语言来描述物模型,称之为 TSL(即 Thing | ||
44 | +Specification Language),采用 JSON 格式,您可以根据 TSL 组装上报设备的数据。您可以导出完整物模型,用于云端应用开发;您也可以只导出 | ||
45 | +精简物模型,配合设备端 SDK 实现设备开发。`; | ||
36 | const jsonValue = ref(defaultTslContent); | 46 | const jsonValue = ref(defaultTslContent); |
37 | const jsonInstance = ref(); | 47 | const jsonInstance = ref(); |
38 | const jsoneditorRef = ref(); | 48 | const jsoneditorRef = ref(); |
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="!isUpdate ? false : true" ref="converScriptRef" /> | ||
14 | + </BasicModal> | ||
15 | + </div> | ||
16 | +</template> | ||
17 | +<script setup lang="ts"> | ||
18 | + import { ref, computed, unref } from 'vue'; | ||
19 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
20 | + import ConverScript from '/@/views/scriptmanage/converscript/ConverScript.vue'; | ||
21 | + | ||
22 | + const converScriptRef = ref<InstanceType<typeof ConverScript>>(); | ||
23 | + const getTitle = computed(() => (isUpdate.value ? '测试脚本' : '新建脚本')); | ||
24 | + const isUpdate = ref(false); | ||
25 | + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | ||
26 | + setModalProps({ loading: true }); | ||
27 | + handleCancel(false); | ||
28 | + isUpdate.value = data.isUpdate; | ||
29 | + converScriptRef.value?.initEditor(data.record?.configuration?.jsScript); | ||
30 | + setModalProps({ loading: false }); | ||
31 | + const title = !unref(isUpdate) ? '测试脚本' : '新建脚本'; | ||
32 | + const okText = !unref(isUpdate) ? '测试' : '确定'; | ||
33 | + setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText }); | ||
34 | + // converScriptRef.value?.setFormData(); | ||
35 | + }); | ||
36 | + const handleSubmit = async () => { | ||
37 | + const val = await converScriptRef.value?.getFormData(); | ||
38 | + console.log(val); | ||
39 | + handleCancel(true); | ||
40 | + }; | ||
41 | + const handleCancel = (flag) => { | ||
42 | + if (flag) { | ||
43 | + closeModal(); | ||
44 | + } | ||
45 | + converScriptRef.value?.resetFormData(); | ||
46 | + }; | ||
47 | +</script> | ||
48 | +<style lang="less" scoped> | ||
49 | + @import url('/@/views/scriptmanage/converscript/ConverScriptModal.less'); | ||
50 | +</style> |
1 | +import { FormSchema } from '/@/components/Form'; | ||
2 | + | ||
3 | +export const tcpSchemas: FormSchema[] = [ | ||
4 | + { | ||
5 | + field: 'script', | ||
6 | + label: '转换脚本', | ||
7 | + component: 'Input', | ||
8 | + slot: 'script', | ||
9 | + colProps: { span: 24 }, | ||
10 | + }, | ||
11 | +]; | ||
12 | + | ||
13 | +// 新增编辑配置 | ||
14 | +export const formSchema: FormSchema[] = [ | ||
15 | + { | ||
16 | + field: 'name', | ||
17 | + label: '输入参数', | ||
18 | + colProps: { span: 24 }, | ||
19 | + required: true, | ||
20 | + component: 'Input', | ||
21 | + componentProps: { | ||
22 | + maxLength: 255, | ||
23 | + placeholder: '请输入输入参数', | ||
24 | + }, | ||
25 | + }, | ||
26 | + { | ||
27 | + field: 'scriptContent', | ||
28 | + label: '脚本内容', | ||
29 | + required: true, | ||
30 | + component: 'Input', | ||
31 | + slot: 'scriptContent', | ||
32 | + colProps: { span: 24 }, | ||
33 | + }, | ||
34 | + { | ||
35 | + field: 'remark', | ||
36 | + label: '输出参数', | ||
37 | + colProps: { span: 24 }, | ||
38 | + component: 'InputTextArea', | ||
39 | + componentProps: { | ||
40 | + rows: 6, | ||
41 | + maxLength: 255, | ||
42 | + placeholder: '请输入输出参数', | ||
43 | + }, | ||
44 | + }, | ||
45 | +]; |
1 | +<template> | ||
2 | + <div> | ||
3 | + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register"> | ||
4 | + <template #script> | ||
5 | + <div style="display: flex; align-items: center"> | ||
6 | + <div> | ||
7 | + <Select | ||
8 | + placeholder="请选择转换脚本" | ||
9 | + v-model:value="selectScript.script" | ||
10 | + style="width: 305px" | ||
11 | + :options="selectOptions" | ||
12 | + allowClear | ||
13 | + /> | ||
14 | + </div> | ||
15 | + <div> | ||
16 | + <span | ||
17 | + @click="handleCreateOrEdit('add')" | ||
18 | + class="ml-2" | ||
19 | + style="color: #409eff; cursor: pointer" | ||
20 | + type="primary" | ||
21 | + size="small" | ||
22 | + >新建转换脚本</span | ||
23 | + > | ||
24 | + </div> | ||
25 | + </div> | ||
26 | + <a-button @click="handleCreateOrEdit('test')" class="mt-4" type="primary" | ||
27 | + >测试脚本</a-button | ||
28 | + > | ||
29 | + </template> | ||
30 | + </BasicForm> | ||
31 | + <ConverScriptModal @register="registerModal" /> | ||
32 | + </div> | ||
33 | +</template> | ||
34 | +<script lang="ts" setup> | ||
35 | + import { ref, Ref, reactive, onMounted } from 'vue'; | ||
36 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
37 | + import { tcpSchemas } from './config'; | ||
38 | + import { SelectTypes } from 'ant-design-vue/es/select'; | ||
39 | + import { Select } from 'ant-design-vue'; | ||
40 | + import { useModal } from '/@/components/Modal'; | ||
41 | + import ConverScriptModal from './ConverScriptModal.vue'; | ||
42 | + | ||
43 | + const selectScript = reactive({ | ||
44 | + script: null, | ||
45 | + }); | ||
46 | + const selectOptions: Ref<SelectTypes['options']> = ref([ | ||
47 | + { | ||
48 | + label: '电表转换脚本', | ||
49 | + value: 1, | ||
50 | + }, | ||
51 | + { | ||
52 | + label: '水表转换脚本', | ||
53 | + value: 2, | ||
54 | + }, | ||
55 | + ]); | ||
56 | + onMounted(() => {}); | ||
57 | + | ||
58 | + const [register] = useForm({ | ||
59 | + labelWidth: 180, | ||
60 | + schemas: tcpSchemas, | ||
61 | + actionColOptions: { | ||
62 | + span: 14, | ||
63 | + }, | ||
64 | + }); | ||
65 | + const [registerModal, { openModal }] = useModal(); | ||
66 | + | ||
67 | + // 新增或编辑 | ||
68 | + const handleCreateOrEdit = (c) => { | ||
69 | + if (c === 'add') { | ||
70 | + openModal(true, { | ||
71 | + isUpdate: true, | ||
72 | + }); | ||
73 | + } else { | ||
74 | + openModal(true, { | ||
75 | + isUpdate: false, | ||
76 | + }); | ||
77 | + } | ||
78 | + }; | ||
79 | + | ||
80 | + const getFormData = () => { | ||
81 | + return selectScript; | ||
82 | + }; | ||
83 | + const resetFormData = () => { | ||
84 | + selectScript.script = null; | ||
85 | + }; | ||
86 | + const setFormData = (v) => { | ||
87 | + selectScript.script = v; | ||
88 | + }; | ||
89 | + defineExpose({ | ||
90 | + getFormData, | ||
91 | + resetFormData, | ||
92 | + setFormData, | ||
93 | + }); | ||
94 | +</script> | ||
95 | +<style lang="less" scoped></style> |
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | - <BasicForm @register="registerForm"> | ||
4 | - <template #scriptContent> | 3 | + <a-form |
4 | + ref="formRef" | ||
5 | + :model="scriptForm" | ||
6 | + name="basic" | ||
7 | + :label-col="{ span: 3 }" | ||
8 | + :wrapper-col="{ span: 17 }" | ||
9 | + autocomplete="off" | ||
10 | + > | ||
11 | + <a-form-item | ||
12 | + :label="ifAdd ? '名称' : '输入参数'" | ||
13 | + :name="ifAdd ? 'scriptName' : 'inputParams'" | ||
14 | + :rules="[{ required: true, message: ifAdd ? '请输入脚本名称' : '请输入参数' }]" | ||
15 | + > | ||
16 | + <a-input v-if="ifAdd" v-model:value="scriptForm.scriptName" placeholder="请输入脚本名称" /> | ||
17 | + <a-input v-else v-model:value="scriptForm.inputParams" placeholder="请输入参数" /> | ||
18 | + </a-form-item> | ||
19 | + <a-form-item | ||
20 | + label="脚本内容" | ||
21 | + name="scriptContent" | ||
22 | + :rules="[{ required: true, message: '请输入脚本内容' }]" | ||
23 | + > | ||
5 | <Card title="脚本内容" :bodyStyle="{ padding: 0, height: '280px' }"> | 24 | <Card title="脚本内容" :bodyStyle="{ padding: 0, height: '280px' }"> |
25 | + <template #extra> | ||
26 | + <a-button @click="handleFormat" size="small">格式化</a-button> | ||
27 | + </template> | ||
6 | <div ref="aceRef" class="overflow-hidden"></div> | 28 | <div ref="aceRef" class="overflow-hidden"></div> |
7 | </Card> | 29 | </Card> |
8 | <Button @click="handleCopy" class="mt-4"> | 30 | <Button @click="handleCopy" class="mt-4"> |
@@ -11,14 +33,29 @@ | @@ -11,14 +33,29 @@ | ||
11 | </template> | 33 | </template> |
12 | copy | 34 | copy |
13 | </Button> | 35 | </Button> |
14 | - </template> | ||
15 | - </BasicForm> | 36 | + </a-form-item> |
37 | + <a-form-item | ||
38 | + :label="ifAdd ? '备注' : '输出参数'" | ||
39 | + :name="ifAdd ? 'scriptRemark' : 'outputParams'" | ||
40 | + > | ||
41 | + <a-textarea | ||
42 | + :rows="5" | ||
43 | + v-if="ifAdd" | ||
44 | + v-model:value="scriptForm.scriptRemark" | ||
45 | + placeholder="请输入备注" | ||
46 | + /> | ||
47 | + <a-textarea | ||
48 | + :rows="5" | ||
49 | + v-else | ||
50 | + v-model:value="scriptForm.outputParams" | ||
51 | + placeholder="请输入输出参数" | ||
52 | + /> | ||
53 | + </a-form-item> | ||
54 | + </a-form> | ||
16 | </div> | 55 | </div> |
17 | </template> | 56 | </template> |
18 | <script setup lang="ts"> | 57 | <script setup lang="ts"> |
19 | - import { ref, unref } from 'vue'; | ||
20 | - import { formSchema } from './config.data'; | ||
21 | - import { BasicForm, useForm } from '/@/components/Form'; | 58 | + import { ref, unref, reactive } from 'vue'; |
22 | import ace from 'ace-builds'; | 59 | import ace from 'ace-builds'; |
23 | import { Card, Button } from 'ant-design-vue'; | 60 | import { Card, Button } from 'ant-design-vue'; |
24 | import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 | 61 | import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 |
@@ -29,15 +66,20 @@ | @@ -29,15 +66,20 @@ | ||
29 | import { useMessage } from '/@/hooks/web/useMessage'; | 66 | import { useMessage } from '/@/hooks/web/useMessage'; |
30 | 67 | ||
31 | defineEmits(['register']); | 68 | defineEmits(['register']); |
69 | + defineProps({ | ||
70 | + ifAdd: { type: Boolean, default: true }, | ||
71 | + }); | ||
72 | + const scriptForm = reactive({ | ||
73 | + scriptName: '', | ||
74 | + scriptRemark: '', | ||
75 | + scriptContent: '', | ||
76 | + inputParams: '', | ||
77 | + outputParams: '', | ||
78 | + }); | ||
32 | const { createMessage } = useMessage(); | 79 | const { createMessage } = useMessage(); |
33 | const { clipboardRef, copiedRef } = useCopyToClipboard(); | 80 | const { clipboardRef, copiedRef } = useCopyToClipboard(); |
34 | const aceEditor = ref(); | 81 | const aceEditor = ref(); |
35 | const aceRef = ref(); | 82 | const aceRef = ref(); |
36 | - const [registerForm, { validate, resetFields }] = useForm({ | ||
37 | - labelWidth: 120, | ||
38 | - schemas: formSchema, | ||
39 | - showActionButtonGroup: false, | ||
40 | - }); | ||
41 | // 初始化编辑器 | 83 | // 初始化编辑器 |
42 | const initEditor = (jsScript?: string) => { | 84 | const initEditor = (jsScript?: string) => { |
43 | aceEditor.value = ace.edit(aceRef.value, { | 85 | aceEditor.value = ace.edit(aceRef.value, { |
@@ -64,6 +106,7 @@ | @@ -64,6 +106,7 @@ | ||
64 | }` | 106 | }` |
65 | ); | 107 | ); |
66 | beautify(aceEditor.value.session); | 108 | beautify(aceEditor.value.session); |
109 | + scriptForm.scriptContent = aceEditor.value.getValue(); | ||
67 | }; | 110 | }; |
68 | const handleCopy = () => { | 111 | const handleCopy = () => { |
69 | const valueRef = aceEditor.value.getValue(); | 112 | const valueRef = aceEditor.value.getValue(); |
@@ -77,19 +120,29 @@ | @@ -77,19 +120,29 @@ | ||
77 | createMessage.success('复制成功!'); | 120 | createMessage.success('复制成功!'); |
78 | } | 121 | } |
79 | }; | 122 | }; |
123 | + const formRef = ref(); | ||
80 | const getFormData = async () => { | 124 | const getFormData = async () => { |
81 | - const value = await validate(); | 125 | + const value = await formRef.value.validateFields(); |
82 | if (!value) return; | 126 | if (!value) return; |
83 | return value; | 127 | return value; |
84 | }; | 128 | }; |
129 | + const setFormData = (v) => { | ||
130 | + for (let i in scriptForm) { | ||
131 | + Reflect.set(scriptForm, i, v[i]); | ||
132 | + } | ||
133 | + }; | ||
85 | const resetFormData = () => { | 134 | const resetFormData = () => { |
86 | - resetFields(); | 135 | + for (let i in scriptForm) { |
136 | + Reflect.set(scriptForm, i, ''); | ||
137 | + } | ||
87 | }; | 138 | }; |
139 | + const handleFormat = () => beautify(aceEditor.value.session); | ||
88 | 140 | ||
89 | defineExpose({ | 141 | defineExpose({ |
90 | initEditor, | 142 | initEditor, |
91 | getFormData, | 143 | getFormData, |
92 | resetFormData, | 144 | resetFormData, |
145 | + setFormData, | ||
93 | }); | 146 | }); |
94 | </script> | 147 | </script> |
95 | <style lang="less" scoped> | 148 | <style lang="less" scoped> |
@@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
10 | @cancel="handleCancel" | 10 | @cancel="handleCancel" |
11 | @ok="handleSubmit" | 11 | @ok="handleSubmit" |
12 | > | 12 | > |
13 | - <ConverScript ref="converScriptRef" /> | 13 | + <ConverScript :ifAdd="true" ref="converScriptRef" /> |
14 | </BasicModal> | 14 | </BasicModal> |
15 | </div> | 15 | </div> |
16 | </template> | 16 | </template> |
1 | -/* | ||
2 | - * @Author: fengtao 1400859700@qq.com | ||
3 | - * @Date: 2022-10-12 09:29:11 | ||
4 | - * @LastEditors: fengtao 1400859700@qq.com | ||
5 | - * @LastEditTime: 2022-10-13 17:28:24 | ||
6 | - * @FilePath: \yun-teng-iot-front\src\views\scriptmanage\converscript\config.data.ts | ||
7 | - * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE | ||
8 | - */ | ||
9 | import { BasicColumn, FormSchema } from '/@/components/Table'; | 1 | import { BasicColumn, FormSchema } from '/@/components/Table'; |
10 | import moment from 'moment'; | 2 | import moment from 'moment'; |
11 | import { h } from 'vue'; | 3 | import { h } from 'vue'; |
@@ -76,14 +68,11 @@ export const searchFormSchema: FormSchema[] = [ | @@ -76,14 +68,11 @@ export const searchFormSchema: FormSchema[] = [ | ||
76 | export const formSchema: FormSchema[] = [ | 68 | export const formSchema: FormSchema[] = [ |
77 | { | 69 | { |
78 | field: 'name', | 70 | field: 'name', |
79 | - label: '名称', | ||
80 | - colProps: { span: 24 }, | 71 | + label: '', |
81 | required: true, | 72 | required: true, |
82 | component: 'Input', | 73 | component: 'Input', |
83 | - componentProps: { | ||
84 | - maxLength: 255, | ||
85 | - placeholder: '请输入脚本名称', | ||
86 | - }, | 74 | + slot: 'scriptName', |
75 | + colProps: { span: 24 }, | ||
87 | }, | 76 | }, |
88 | { | 77 | { |
89 | field: 'scriptContent', | 78 | field: 'scriptContent', |
@@ -95,13 +84,10 @@ export const formSchema: FormSchema[] = [ | @@ -95,13 +84,10 @@ export const formSchema: FormSchema[] = [ | ||
95 | }, | 84 | }, |
96 | { | 85 | { |
97 | field: 'remark', | 86 | field: 'remark', |
98 | - label: '备注', | 87 | + label: '', |
88 | + required: true, | ||
89 | + component: 'Input', | ||
90 | + slot: 'scriptRemark', | ||
99 | colProps: { span: 24 }, | 91 | colProps: { span: 24 }, |
100 | - component: 'InputTextArea', | ||
101 | - componentProps: { | ||
102 | - rows: 6, | ||
103 | - maxLength: 255, | ||
104 | - placeholder: '请输入备注', | ||
105 | - }, | ||
106 | }, | 92 | }, |
107 | ]; | 93 | ]; |