Commit 21b223f679f9c6cfb9ffe9dcfc3c40b1cec96c23

Authored by fengtao
2 parents 7e974951 d994b48d

Merge branch 'main' into ft_local_dev

@@ -14,9 +14,9 @@ VITE_PUBLIC_PATH = / @@ -14,9 +14,9 @@ VITE_PUBLIC_PATH = /
14 # VITE_PROXY = [["/api","http://101.133.234.90:8080/api"]] 14 # VITE_PROXY = [["/api","http://101.133.234.90:8080/api"]]
15 # 线上测试环境 15 # 线上测试环境
16 # VITE_PROXY = [["/api","http://localhost:8080/api"],["/thingskit-drawio","http://localhost:3000/"]] 16 # VITE_PROXY = [["/api","http://localhost:8080/api"],["/thingskit-drawio","http://localhost:3000/"]]
17 -VITE_PROXY = [["/api","http://222.180.200.114:48080/api"],["/thingskit-drawio","http://localhost:3000/"]] 17 +# VITE_PROXY = [["/api","http://222.180.200.114:48080/api"],["/thingskit-drawio","http://localhost:3000/"]]
18 # VITE_PROXY = [["/api","http://121.37.251.8:8080/api"],["/thingskit-drawio","http://localhost:3000/"]] 18 # VITE_PROXY = [["/api","http://121.37.251.8:8080/api"],["/thingskit-drawio","http://localhost:3000/"]]
19 -# VITE_PROXY = [["/api","http://192.168.10.136:8080/api"],["/thingskit-drawio","http://192.168.10.136:8080/api"]] 19 +VITE_PROXY = [["/api","http://192.168.10.103:8080/api"],["/thingskit-drawio","http://192.168.10.136:8080/api"]]
20 20
21 # 实时数据的ws地址 21 # 实时数据的ws地址
22 # VITE_WEB_SOCKET = ws://localhost:8080/api/ws/plugins/telemetry?token= 22 # VITE_WEB_SOCKET = ws://localhost:8080/api/ws/plugins/telemetry?token=
1 import { BasicPageParams } from '../model/baseModel'; 1 import { BasicPageParams } from '../model/baseModel';
2 import { GetModelTslParams, ModelOfMatterParams } from './model/modelOfMatterModel'; 2 import { GetModelTslParams, ModelOfMatterParams } from './model/modelOfMatterModel';
3 import { defHttp } from '/@/utils/http/axios'; 3 import { defHttp } from '/@/utils/http/axios';
  4 +import { FunctionType } from '/@/views/device/profiles/step/cpns/physical/cpns/config';
4 5
5 enum ModelOfMatter { 6 enum ModelOfMatter {
6 CREATE = '/things_model', 7 CREATE = '/things_model',
@@ -8,9 +9,16 @@ enum ModelOfMatter { @@ -8,9 +9,16 @@ enum ModelOfMatter {
8 DELETE = '/things_model', 9 DELETE = '/things_model',
9 TSL = '/things_model', 10 TSL = '/things_model',
10 LIST = '/things_model/page', 11 LIST = '/things_model/page',
  12 + RELEASE = '/things_model',
11 } 13 }
12 14
13 -export const getModelList = (params: BasicPageParams) => { 15 +export const getModelList = (
  16 + params: BasicPageParams & {
  17 + deviceProfileId: string;
  18 + functionTyp?: FunctionType;
  19 + nameOrIdentifier?: string;
  20 + }
  21 +) => {
14 return defHttp.get({ 22 return defHttp.get({
15 url: `${ModelOfMatter.LIST}`, 23 url: `${ModelOfMatter.LIST}`,
16 params, 24 params,
@@ -46,3 +54,9 @@ export const deleteModel = (params: string[]) => { @@ -46,3 +54,9 @@ export const deleteModel = (params: string[]) => {
46 }, 54 },
47 }); 55 });
48 }; 56 };
  57 +
  58 +export const releaseModel = (deviceProfileId: string) => {
  59 + return defHttp.put({
  60 + url: `${ModelOfMatter.RELEASE}/${deviceProfileId}`,
  61 + });
  62 +};
  1 +import { cloneDeep } from 'lodash-es';
1 import { DateTypeEnum } from './config'; 2 import { DateTypeEnum } from './config';
2 import { StructFormValue } from './type'; 3 import { StructFormValue } from './type';
3 import { DataType, ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel'; 4 import { DataType, ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel';
  5 +import { isArray } from '/@/utils/is';
4 6
5 export function transfromToStructJSON(value: StructFormValue): StructJSON { 7 export function transfromToStructJSON(value: StructFormValue): StructJSON {
6 const { 8 const {
@@ -16,9 +18,9 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { @@ -16,9 +18,9 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON {
16 identifier, 18 identifier,
17 remark, 19 remark,
18 specs, 20 specs,
19 - assessMode, 21 + accessMode,
20 } = value; 22 } = value;
21 - const basic = { functionName, identifier, remark, assessMode }; 23 + const basic = { functionName, identifier, remark, accessMode };
22 let dataType = {} as unknown as DataType; 24 let dataType = {} as unknown as DataType;
23 25
24 switch (type) { 26 switch (type) {
@@ -62,3 +64,27 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON { @@ -62,3 +64,27 @@ export function transfromToStructJSON(value: StructFormValue): StructJSON {
62 } 64 }
63 return { ...basic, dataType }; 65 return { ...basic, dataType };
64 } 66 }
  67 +
  68 +export const excludeIdInStructJSON = (struct: DataType) => {
  69 + const _value = cloneDeep(struct);
  70 + const { specs } = _value;
  71 + const list = [specs];
  72 +
  73 + while (list.length) {
  74 + for (const item of list) {
  75 + if (isArray(item)) {
  76 + (item as StructJSON[]).forEach((temp) => {
  77 + if (temp.dataType?.specs) {
  78 + list.push(temp.dataType.specs);
  79 + }
  80 + Reflect.deleteProperty(temp, 'id');
  81 + });
  82 + } else {
  83 + Reflect.deleteProperty(item as Recordable, 'id');
  84 + }
  85 + list.shift();
  86 + }
  87 + }
  88 +
  89 + return _value;
  90 +};
@@ -286,7 +286,7 @@ @@ -286,7 +286,7 @@
286 } 286 }
287 287
288 .split-screen-mode:deep(.ant-spin-container) { 288 .split-screen-mode:deep(.ant-spin-container) {
289 - height: 100%; 289 + height: 100% !important;
290 } 290 }
291 291
292 .video-container { 292 .video-container {
@@ -321,4 +321,8 @@ @@ -321,4 +321,8 @@
321 width: 100%; 321 width: 100%;
322 height: 100%; 322 height: 100%;
323 } 323 }
  324 +
  325 + .split-mode-lis:deep(.ant-spin-container:fullscreen) {
  326 + height: 100% !important;
  327 + }
324 </style> 328 </style>
@@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
27 import { getBoundingClientRect } from '/@/utils/domUtils'; 27 import { getBoundingClientRect } from '/@/utils/domUtils';
28 import configurationSrc from '/@/assets/icons/configuration.svg'; 28 import configurationSrc from '/@/assets/icons/configuration.svg';
29 import { cloneDeep } from 'lodash'; 29 import { cloneDeep } from 'lodash';
  30 + import { usePermission } from '/@/hooks/web/usePermission';
30 31
31 const listColumn = ref(4); 32 const listColumn = ref(4);
32 33
@@ -112,8 +113,9 @@ @@ -112,8 +113,9 @@
112 const { VITE_GLOB_CONFIGURATION } = import.meta.env; 113 const { VITE_GLOB_CONFIGURATION } = import.meta.env;
113 const isDev = isDevMode(); 114 const isDev = isDevMode();
114 115
  116 + const { hasPermission } = usePermission();
115 const handlePreview = (record: ConfigurationCenterItemsModal) => { 117 const handlePreview = (record: ConfigurationCenterItemsModal) => {
116 - console.log(record); 118 + if (!hasPermission('api:yt:configuration:center:get_configuration_info:get')) return;
117 window.open( 119 window.open(
118 `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${ 120 `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${
119 record!.id 121 record!.id
@@ -206,7 +208,12 @@ @@ -206,7 +208,12 @@
206 <Card hoverable> 208 <Card hoverable>
207 <template #cover> 209 <template #cover>
208 <div class="h-full w-full !flex justify-center items-center text-center"> 210 <div class="h-full w-full !flex justify-center items-center text-center">
209 - <img class="w-36 h-36" alt="example" :src="item.thumbnail || configurationSrc" /> 211 + <img
  212 + class="w-36 h-36"
  213 + alt="example"
  214 + :src="item.thumbnail || configurationSrc"
  215 + @click="handlePreview(item)"
  216 + />
210 </div> 217 </div>
211 </template> 218 </template>
212 <template class="ant-card-actions" #actions> 219 <template class="ant-card-actions" #actions>
@@ -215,18 +222,18 @@ @@ -215,18 +222,18 @@
215 <EyeOutlined key="setting" @click="handlePreview(item)" /> 222 <EyeOutlined key="setting" @click="handlePreview(item)" />
216 </Tooltip> 223 </Tooltip>
217 </Authority> 224 </Authority>
218 - <Authority value="api:yt:configuration:center:update">  
219 - <Tooltip title="编辑">  
220 - <EditOutlined key="edit" @click="handleCreateOrUpdate(item)" /> 225 + <Authority value="api:yt:configuration:center:get_configuration_info:get">
  226 + <Tooltip title="设计">
  227 + <EditOutlined key="edit" @click="handleDesign(item)" />
221 </Tooltip> 228 </Tooltip>
222 </Authority> 229 </Authority>
223 <Dropdown 230 <Dropdown
224 :dropMenuList="[ 231 :dropMenuList="[
225 { 232 {
226 text: '设计', 233 text: '设计',
227 - auth: 'api:yt:configuration:center:get_configuration_info:get', 234 + auth: 'api:yt:configuration:center:update',
228 icon: 'clarity:note-edit-line', 235 icon: 'clarity:note-edit-line',
229 - onClick: handleDesign.bind(null, item), 236 + onClick: handleCreateOrUpdate.bind(null, item),
230 }, 237 },
231 { 238 {
232 text: '删除', 239 text: '删除',
1 <template> 1 <template>
2 - <BasicDrawer v-bind="$attrs" title="产品详情" @register="register" width="60%">  
3 - <Tabs :animated="true" v-model:activeKey="activeKey" @change="handlePanelChange">  
4 - <TabPane key="product" tab="产品"> 2 + <BasicDrawer v-bind="$attrs" title="产品详情" @register="register" width="60%" destroy-on-close>
  3 + <Tabs v-model:activeKey="activeKey" @change="handlePanelChange">
  4 + <Tabs.TabPane key="product" tab="产品">
5 <div class="relative"> 5 <div class="relative">
6 <DeviceConfigurationStep :ifShowBtn="false" ref="DevConStRef" /> 6 <DeviceConfigurationStep :ifShowBtn="false" ref="DevConStRef" />
7 <div class="absolute w-full h-full top-0 cursor-not-allowed"></div> 7 <div class="absolute w-full h-full top-0 cursor-not-allowed"></div>
8 </div> 8 </div>
9 - </TabPane>  
10 - <TabPane key="transport" tab="传输配置"> 9 + </Tabs.TabPane>
  10 + <Tabs.TabPane key="transport" tab="传输配置">
11 <div class="relative"> 11 <div class="relative">
12 <TransportConfigurationStep :ifShowBtn="false" ref="TransConStRef" /> 12 <TransportConfigurationStep :ifShowBtn="false" ref="TransConStRef" />
13 <div class="absolute w-full h-full top-0 cursor-not-allowed"></div> 13 <div class="absolute w-full h-full top-0 cursor-not-allowed"></div>
14 </div> 14 </div>
15 - </TabPane>  
16 - <TabPane key="modelOfMatter" tab="物模型管理"> 15 + </Tabs.TabPane>
  16 + <Tabs.TabPane key="modelOfMatter" tab="物模型管理">
17 <PhysicalModelManagementStep :record="record" /> 17 <PhysicalModelManagementStep :record="record" />
18 - </TabPane> 18 + </Tabs.TabPane>
19 </Tabs> 19 </Tabs>
20 </BasicDrawer> 20 </BasicDrawer>
21 </template> 21 </template>
22 <script lang="ts" setup> 22 <script lang="ts" setup>
23 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; 23 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
24 - import { Tabs, TabPane } from 'ant-design-vue'; 24 + import { Tabs } from 'ant-design-vue';
25 import DeviceConfigurationStep from './step/DeviceConfigurationStep.vue'; 25 import DeviceConfigurationStep from './step/DeviceConfigurationStep.vue';
26 import TransportConfigurationStep from './step/TransportConfigurationStep.vue'; 26 import TransportConfigurationStep from './step/TransportConfigurationStep.vue';
27 import PhysicalModelManagementStep from './step/PhysicalModelManagementStep.vue'; 27 import PhysicalModelManagementStep from './step/PhysicalModelManagementStep.vue';
@@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@
50 50
51 const [register, {}] = useDrawerInner(async (data: { record: DeviceRecord }) => { 51 const [register, {}] = useDrawerInner(async (data: { record: DeviceRecord }) => {
52 activeKey.value = 'product'; 52 activeKey.value = 'product';
  53 + record.value = data.record;
53 record.value = await deviceConfigGetDetail(data.record.id); 54 record.value = await deviceConfigGetDetail(data.record.id);
54 setDeviceConfFormData(unref(record)); 55 setDeviceConfFormData(unref(record));
55 }); 56 });
@@ -6,6 +6,8 @@ import { numberRule } from '/@/utils/rules'; @@ -6,6 +6,8 @@ import { numberRule } from '/@/utils/rules';
6 6
7 import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi'; 7 import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi';
8 import { FormField, FunctionType } from './step/cpns/physical/cpns/config'; 8 import { FormField, FunctionType } from './step/cpns/physical/cpns/config';
  9 +import { h } from 'vue';
  10 +import { Tag } from 'ant-design-vue';
9 11
10 export const steps = [ 12 export const steps = [
11 { 13 {
@@ -21,7 +23,7 @@ export const steps = [ @@ -21,7 +23,7 @@ export const steps = [
21 export const formatFunctionType: Record<FunctionType, string> = { 23 export const formatFunctionType: Record<FunctionType, string> = {
22 [FunctionType.PROPERTIES]: '属性', 24 [FunctionType.PROPERTIES]: '属性',
23 [FunctionType.EVENTS]: '事件', 25 [FunctionType.EVENTS]: '事件',
24 - [FunctionType.SERVICE]: '事件', 26 + [FunctionType.SERVICE]: '服务',
25 }; 27 };
26 28
27 export const physicalColumn: BasicColumn[] = [ 29 export const physicalColumn: BasicColumn[] = [
@@ -52,12 +54,49 @@ export const physicalColumn: BasicColumn[] = [ @@ -52,12 +54,49 @@ export const physicalColumn: BasicColumn[] = [
52 }, 54 },
53 }, 55 },
54 { 56 {
  57 + title: '状态',
  58 + dataIndex: 'status',
  59 + width: 100,
  60 + customRender: (value: Record<'text', number>) => {
  61 + const { text } = value;
  62 + return h(
  63 + Tag,
  64 + {
  65 + color: text ? 'green' : 'red',
  66 + },
  67 + () => (text ? '已发布' : '待发布')
  68 + );
  69 + },
  70 + },
  71 + {
55 title: '创建时间', 72 title: '创建时间',
56 dataIndex: 'createTime', 73 dataIndex: 'createTime',
57 width: 150, 74 width: 150,
58 }, 75 },
59 ]; 76 ];
60 77
  78 +export const modelOfMatterForm: FormSchema[] = [
  79 + {
  80 + field: 'functionType',
  81 + label: '功能类型',
  82 + component: 'Select',
  83 + colProps: { span: 8 },
  84 + componentProps: {
  85 + options: [
  86 + { label: formatFunctionType[FunctionType.PROPERTIES], value: FunctionType.PROPERTIES },
  87 + { label: formatFunctionType[FunctionType.EVENTS], value: FunctionType.EVENTS },
  88 + { label: formatFunctionType[FunctionType.SERVICE], value: FunctionType.SERVICE },
  89 + ],
  90 + },
  91 + },
  92 + {
  93 + field: 'nameOrIdentifier',
  94 + label: '功能名称/标识符',
  95 + component: 'Input',
  96 + colProps: { span: 8 },
  97 + },
  98 +];
  99 +
61 export const step1Schemas: FormSchema[] = [ 100 export const step1Schemas: FormSchema[] = [
62 { 101 {
63 field: 'image', 102 field: 'image',
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 <div class="p-style"> 2 <div class="p-style">
3 <BasicTable 3 <BasicTable
4 :rowSelection="{ type: 'checkbox' }" 4 :rowSelection="{ type: 'checkbox' }"
  5 + class="bg-gray-100 dark:bg-dark-900"
5 :clickToRowSelect="false" 6 :clickToRowSelect="false"
6 @register="registerTable" 7 @register="registerTable"
7 > 8 >
@@ -31,6 +32,9 @@ @@ -31,6 +32,9 @@
31 新增物模型 32 新增物模型
32 </Button> 33 </Button>
33 <Button type="primary" @click="handleOpenTsl"> 物模型TSL </Button> 34 <Button type="primary" @click="handleOpenTsl"> 物模型TSL </Button>
  35 + <Button v-if="isShowBtn" type="primary" @click="handleImportModel"
  36 + >导入物模型</Button
  37 + >
34 </Authority> 38 </Authority>
35 </div> 39 </div>
36 <div class="flex gap-2"> 40 <div class="flex gap-2">
@@ -41,7 +45,9 @@ @@ -41,7 +45,9 @@
41 cancel-text="取消" 45 cancel-text="取消"
42 @confirm="handleEmit" 46 @confirm="handleEmit"
43 > 47 >
44 - <Button v-if="isShowBtn" type="primary"> 发布上线 </Button> 48 + <Button v-if="isShowBtn" type="primary" :loading="releaseLoading">
  49 + 发布上线
  50 + </Button>
45 </Popconfirm> 51 </Popconfirm>
46 <Button v-if="isShowBtn" class="!bg-gray-200" type="text" @click="handleReturn"> 52 <Button v-if="isShowBtn" class="!bg-gray-200" type="text" @click="handleReturn">
47 返回 53 返回
@@ -108,7 +114,7 @@ @@ -108,7 +114,7 @@
108 <script lang="ts" setup> 114 <script lang="ts" setup>
109 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 115 import { BasicTable, useTable, TableAction } from '/@/components/Table';
110 import { useModal } from '/@/components/Modal'; 116 import { useModal } from '/@/components/Modal';
111 - import { physicalColumn } from '../device.profile.data'; 117 + import { modelOfMatterForm, physicalColumn } from '../device.profile.data';
112 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 118 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
113 import { Authority } from '/@/components/Authority'; 119 import { Authority } from '/@/components/Authority';
114 import PhysicalModelModal from './cpns/physical/PhysicalModelModal.vue'; 120 import PhysicalModelModal from './cpns/physical/PhysicalModelModal.vue';
@@ -116,13 +122,13 @@ @@ -116,13 +122,13 @@
116 import { Popconfirm, Button, Alert } from 'ant-design-vue'; 122 import { Popconfirm, Button, Alert } from 'ant-design-vue';
117 import { useMessage } from '/@/hooks/web/useMessage'; 123 import { useMessage } from '/@/hooks/web/useMessage';
118 import { DeviceRecord } from '/@/api/device/model/deviceModel'; 124 import { DeviceRecord } from '/@/api/device/model/deviceModel';
119 - import { deleteModel, getModelList } from '/@/api/device/modelOfMatter'; 125 + import { deleteModel, getModelList, releaseModel } from '/@/api/device/modelOfMatter';
120 import { OpenModelOfMatterModelParams, OpenModelMode } from './cpns/physical/types'; 126 import { OpenModelOfMatterModelParams, OpenModelMode } from './cpns/physical/types';
121 import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; 127 import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
122 import { ref } from 'vue'; 128 import { ref } from 'vue';
123 defineEmits(['register']); 129 defineEmits(['register']);
124 130
125 - defineProps<{ 131 + const props = defineProps<{
126 record: DeviceRecord; 132 record: DeviceRecord;
127 }>(); 133 }>();
128 134
@@ -132,13 +138,19 @@ @@ -132,13 +138,19 @@
132 const [registerModalTsl, { openModal: openModalTsl }] = useModal(); 138 const [registerModalTsl, { openModal: openModalTsl }] = useModal();
133 139
134 const [registerTable, { reload, setProps }] = useTable({ 140 const [registerTable, { reload, setProps }] = useTable({
135 - api: getModelList, 141 + api: async (params: Record<'page' | 'pageSize', number>) => {
  142 + return await getModelList({ ...params, deviceProfileId: props.record.id });
  143 + },
136 columns: physicalColumn, 144 columns: physicalColumn,
137 showIndexColumn: false, 145 showIndexColumn: false,
138 clickToRowSelect: false, 146 clickToRowSelect: false,
139 - useSearchForm: false,  
140 showTableSetting: true, 147 showTableSetting: true,
141 bordered: true, 148 bordered: true,
  149 + useSearchForm: true,
  150 + formConfig: {
  151 + schemas: modelOfMatterForm,
  152 + labelWidth: 120,
  153 + },
142 actionColumn: { 154 actionColumn: {
143 width: 200, 155 width: 200,
144 title: '操作', 156 title: '操作',
@@ -200,11 +212,23 @@ @@ -200,11 +212,23 @@
200 const handleEditPhysicalModel = () => (isShowBtn.value = true); 212 const handleEditPhysicalModel = () => (isShowBtn.value = true);
201 213
202 const handleReturn = () => (isShowBtn.value = false); 214 const handleReturn = () => (isShowBtn.value = false);
203 - const handleEmit = () => {  
204 - isShowBtn.value = false;  
205 - createMessage.success('发布成功'); 215 +
  216 + const releaseLoading = ref(false);
  217 + const handleEmit = async () => {
  218 + try {
  219 + releaseLoading.value = true;
  220 + await releaseModel(props.record.id);
  221 + handleReturn();
  222 + createMessage.success('发布成功');
  223 + reload();
  224 + } catch (error) {
  225 + } finally {
  226 + releaseLoading.value = false;
  227 + }
206 }; 228 };
207 229
  230 + const handleImportModel = async () => {};
  231 +
208 defineExpose({}); 232 defineExpose({});
209 </script> 233 </script>
210 <style lang="less" scoped> 234 <style lang="less" scoped>
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 @ok="handleSubmit" 9 @ok="handleSubmit"
10 @cancel="handleCancel" 10 @cancel="handleCancel"
11 > 11 >
12 - <div> 12 + <div class="relative">
13 <div v-if="openModalMode === OpenModelMode.CREATE"> 13 <div v-if="openModalMode === OpenModelMode.CREATE">
14 <Typography> 14 <Typography>
15 <TypographyParagraph> 15 <TypographyParagraph>
@@ -24,26 +24,26 @@ @@ -24,26 +24,26 @@
24 :size="size" 24 :size="size"
25 > 25 >
26 <TabPane :key="FunctionType.PROPERTIES" tab="属性" /> 26 <TabPane :key="FunctionType.PROPERTIES" tab="属性" />
27 - <TabPane :key="FunctionType.SERVICE" tab="服务" />  
28 - <TabPane  
29 - :key="FunctionType.EVENTS"  
30 - tab="事件"  
31 - :disabled="$props.record.transportType === 'TCP'"  
32 - /> 27 + <TabPane :key="FunctionType.SERVICE" :disabled="isTCPGatewaySubDevice" tab="服务" />
  28 + <TabPane :key="FunctionType.EVENTS" tab="事件" :disabled="isTCPGatewaySubDevice" />
33 </Tabs> 29 </Tabs>
34 - <Attribute v-show="activeKey === FunctionType.PROPERTIES" ref="AttrRef" /> 30 + <Attribute v-if="activeKey === FunctionType.PROPERTIES" ref="AttrRef" />
35 <Service 31 <Service
36 - v-show="activeKey === FunctionType.SERVICE" 32 + v-if="activeKey === FunctionType.SERVICE"
37 :record="$props.record" 33 :record="$props.record"
38 ref="ServiceRef" 34 ref="ServiceRef"
39 /> 35 />
40 - <Events v-show="activeKey === FunctionType.EVENTS" ref="EventsRef" /> 36 + <Events v-if="activeKey === FunctionType.EVENTS" ref="EventsRef" />
  37 + <div
  38 + v-if="openModalMode === OpenModelMode.VIEW"
  39 + class="absolute w-full h-full top-0 cursor-not-allowed z-50"
  40 + ></div>
41 </div> 41 </div>
42 </BasicModal> 42 </BasicModal>
43 </div> 43 </div>
44 </template> 44 </template>
45 <script lang="ts" setup> 45 <script lang="ts" setup>
46 - import { ref, unref } from 'vue'; 46 + import { ref, unref, nextTick, computed } from 'vue';
47 import { BasicModal, useModalInner } from '/@/components/Modal'; 47 import { BasicModal, useModalInner } from '/@/components/Modal';
48 import { Tabs, TabPane, Typography, TypographyParagraph } from 'ant-design-vue'; 48 import { Tabs, TabPane, Typography, TypographyParagraph } from 'ant-design-vue';
49 import Attribute from './cpns/Attribute.vue'; 49 import Attribute from './cpns/Attribute.vue';
@@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
51 import Events from './cpns/Events.vue'; 51 import Events from './cpns/Events.vue';
52 import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; 52 import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
53 import { createModel, updateModel } from '/@/api/device/modelOfMatter'; 53 import { createModel, updateModel } from '/@/api/device/modelOfMatter';
54 - import { DeviceRecord } from '/@/api/device/model/deviceModel'; 54 + import { DeviceRecord, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
55 import { useMessage } from '/@/hooks/web/useMessage'; 55 import { useMessage } from '/@/hooks/web/useMessage';
56 import { OpenModelMode, OpenModelOfMatterModelParams } from './types/index'; 56 import { OpenModelMode, OpenModelOfMatterModelParams } from './types/index';
57 import { FunctionType } from './cpns/config'; 57 import { FunctionType } from './cpns/config';
@@ -62,6 +62,12 @@ @@ -62,6 +62,12 @@
62 record: DeviceRecord; 62 record: DeviceRecord;
63 }>(); 63 }>();
64 64
  65 + const isTCPGatewaySubDevice = computed(() => {
  66 + const { record } = props;
  67 + const { deviceType, transportType } = record;
  68 + return deviceType === DeviceTypeEnum.SENSOR && transportType === 'TCP';
  69 + });
  70 +
65 const blockContent = `属性一般是设备的运行状态,如当前温度等;服务是设备可被调用的方法,支持定义参数,如执行某项任务;事件则是设备上报的 71 const blockContent = `属性一般是设备的运行状态,如当前温度等;服务是设备可被调用的方法,支持定义参数,如执行某项任务;事件则是设备上报的
66 通知,如告警,需要被及时处理。`; 72 通知,如告警,需要被及时处理。`;
67 const activeKey = ref<FunctionType>(FunctionType.PROPERTIES); 73 const activeKey = ref<FunctionType>(FunctionType.PROPERTIES);
@@ -101,16 +107,13 @@ @@ -101,16 +107,13 @@
101 if (record) { 107 if (record) {
102 functionType.value = data.record.functionType; 108 functionType.value = data.record.functionType;
103 activeKey.value = data.record.functionType; 109 activeKey.value = data.record.functionType;
  110 + await nextTick();
104 setFormData(record.functionType, record as unknown as ModelOfMatterParams); 111 setFormData(record.functionType, record as unknown as ModelOfMatterParams);
105 } 112 }
106 if (unref(openModalMode) === OpenModelMode.VIEW) { 113 if (unref(openModalMode) === OpenModelMode.VIEW) {
107 setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看物模型' }); 114 setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看物模型' });
108 - // setFormData(functionType.value, record);  
109 } else { 115 } else {
110 const title = unref(openModalMode) === OpenModelMode.UPDATE ? '编辑物模型' : '新增物模型'; 116 const title = unref(openModalMode) === OpenModelMode.UPDATE ? '编辑物模型' : '新增物模型';
111 - if (OpenModelMode.UPDATE) {  
112 - // setFormData(functionType.value, record);  
113 - }  
114 setModalProps({ title, showOkBtn: true, showCancelBtn: true }); 117 setModalProps({ title, showOkBtn: true, showCancelBtn: true });
115 } 118 }
116 } 119 }
@@ -150,6 +153,7 @@ @@ -150,6 +153,7 @@
150 closeModal(); 153 closeModal();
151 emit('success'); 154 emit('success');
152 } catch (error) { 155 } catch (error) {
  156 + throw Error(error);
153 } finally { 157 } finally {
154 setModalProps({ loading: false, okButtonProps: { loading: false } }); 158 setModalProps({ loading: false, okButtonProps: { loading: false } });
155 } 159 }
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 width="55rem" 6 width="55rem"
7 @register="register" 7 @register="register"
8 @ok="handleSubmit" 8 @ok="handleSubmit"
  9 + okText="导出物模型"
9 @cancel="handleCancel" 10 @cancel="handleCancel"
10 > 11 >
11 <TslContent :record="$props.record" ref="TslConRef" /> 12 <TslContent :record="$props.record" ref="TslConRef" />
@@ -19,7 +20,7 @@ @@ -19,7 +20,7 @@
19 20
20 defineEmits(['register']); 21 defineEmits(['register']);
21 22
22 - defineProps<{ 23 + const props = defineProps<{
23 record: DeviceRecord; 24 record: DeviceRecord;
24 }>(); 25 }>();
25 26
@@ -42,7 +43,17 @@ @@ -42,7 +43,17 @@
42 const handleSubmit = () => { 43 const handleSubmit = () => {
43 const value = TslConRef.value?.getFormData(); 44 const value = TslConRef.value?.getFormData();
44 if (!value) return; 45 if (!value) return;
45 - console.log('搜集值', value); 46 +
  47 + const blob = new Blob([JSON.stringify(value, null, 2)], { type: 'text/json' });
  48 + const objectURL = URL.createObjectURL(blob);
  49 + const element = document.createElement('a');
  50 + element.href = objectURL;
  51 + element.download = `${props.record.name}-model.json`;
  52 + element.style.display = 'none';
  53 + document.body.appendChild(element);
  54 + element.click();
  55 + element.remove();
  56 + URL.revokeObjectURL(objectURL);
46 }; 57 };
47 </script> 58 </script>
48 59
@@ -6,7 +6,10 @@ @@ -6,7 +6,10 @@
6 import { DataType, ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; 6 import { DataType, ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
7 import { formSchemas } from '/@/components/Form/src/externalCompns/components/StructForm/config'; 7 import { formSchemas } from '/@/components/Form/src/externalCompns/components/StructForm/config';
8 import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type'; 8 import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type';
9 - import { transfromToStructJSON } from '/@/components/Form/src/externalCompns/components/StructForm/util'; 9 + import {
  10 + transfromToStructJSON,
  11 + excludeIdInStructJSON,
  12 + } from '/@/components/Form/src/externalCompns/components/StructForm/util';
10 import { FunctionType } from './config'; 13 import { FunctionType } from './config';
11 import { isArray } from 'lodash'; 14 import { isArray } from 'lodash';
12 15
@@ -26,6 +29,8 @@ @@ -26,6 +29,8 @@
26 if (!_values) return {}; 29 if (!_values) return {};
27 const { functionName, remark, identifier, accessMode } = _values; 30 const { functionName, remark, identifier, accessMode } = _values;
28 const structJSON = transfromToStructJSON(_values); 31 const structJSON = transfromToStructJSON(_values);
  32 + const dataType = excludeIdInStructJSON(structJSON.dataType!);
  33 +
29 const value = { 34 const value = {
30 functionName, 35 functionName,
31 functionType: FunctionType.PROPERTIES, 36 functionType: FunctionType.PROPERTIES,
@@ -33,7 +38,7 @@ @@ -33,7 +38,7 @@
33 identifier, 38 identifier,
34 accessMode, 39 accessMode,
35 functionJson: { 40 functionJson: {
36 - dataType: structJSON.dataType, 41 + dataType: dataType,
37 }, 42 },
38 } as ModelOfMatterParams; 43 } as ModelOfMatterParams;
39 return value; 44 return value;
@@ -4,8 +4,9 @@ @@ -4,8 +4,9 @@
4 <script lang="ts" setup> 4 <script lang="ts" setup>
5 import { BasicForm, useForm } from '/@/components/Form'; 5 import { BasicForm, useForm } from '/@/components/Form';
6 import { eventSchemas, FunctionType } from './config'; 6 import { eventSchemas, FunctionType } from './config';
7 - import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; 7 + import { ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel';
8 import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type'; 8 import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type';
  9 + import { excludeIdInStructJSON } from '/@/components/Form/src/externalCompns/components/StructForm/util';
9 10
10 const [register, { validate, resetFields, setFieldsValue }] = useForm({ 11 const [register, { validate, resetFields, setFieldsValue }] = useForm({
11 labelWidth: 100, 12 labelWidth: 100,
@@ -34,8 +35,13 @@ @@ -34,8 +35,13 @@
34 35
35 async function getFormData() { 36 async function getFormData() {
36 const _values = (await validate()) as StructFormValue; 37 const _values = (await validate()) as StructFormValue;
37 - const { functionName, remark, identifier, outputData, eventType } = _values; 38 + const { functionName, remark, identifier, outputData: _outputData, eventType } = _values;
38 if (!_values) return {} as unknown as ModelOfMatterParams; 39 if (!_values) return {} as unknown as ModelOfMatterParams;
  40 +
  41 + const outputData = (_outputData as unknown as StructJSON[]).map((item) =>
  42 + excludeIdInStructJSON(item.dataType!)
  43 + );
  44 +
39 const value = { 45 const value = {
40 functionName, 46 functionName,
41 identifier, 47 identifier,
@@ -6,8 +6,9 @@ @@ -6,8 +6,9 @@
6 import { serviceSchemas } from './config'; 6 import { serviceSchemas } from './config';
7 import { FunctionType } from './config'; 7 import { FunctionType } from './config';
8 import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type'; 8 import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type';
9 - import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; 9 + import { ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel';
10 import { DeviceRecord } from '/@/api/device/model/deviceModel'; 10 import { DeviceRecord } from '/@/api/device/model/deviceModel';
  11 + import { excludeIdInStructJSON } from '/@/components/Form/src/externalCompns/components/StructForm/util';
11 12
12 const props = defineProps<{ 13 const props = defineProps<{
13 record: DeviceRecord; 14 record: DeviceRecord;
@@ -27,7 +28,10 @@ @@ -27,7 +28,10 @@
27 //回显数据 28 //回显数据
28 const setFormData = (record: ModelOfMatterParams) => { 29 const setFormData = (record: ModelOfMatterParams) => {
29 const { functionJson = {}, functionName, identifier, remark, callType } = record; 30 const { functionJson = {}, functionName, identifier, remark, callType } = record;
30 - const { inputData, outputData, serviceCommand } = functionJson; 31 + const { inputData = [], outputData } = functionJson;
  32 + const { serviceCommand } =
  33 + (inputData.at(0) as unknown as { serviceCommand: string }) ||
  34 + ({} as { serviceCommand: string });
31 const value = { 35 const value = {
32 functionName, 36 functionName,
33 identifier, 37 identifier,
@@ -43,9 +47,24 @@ @@ -43,9 +47,24 @@
43 //获取数据 47 //获取数据
44 async function getFormData() { 48 async function getFormData() {
45 const _values = (await validate()) as StructFormValue; 49 const _values = (await validate()) as StructFormValue;
46 - const { functionName, remark, identifier, inputData, outputData, serviceCommand, callType } =  
47 - _values; 50 + const {
  51 + functionName,
  52 + remark,
  53 + identifier,
  54 + inputData: _inputData = [],
  55 + outputData: _outputData = [],
  56 + serviceCommand,
  57 + callType,
  58 + } = _values;
48 if (!_values) return {}; 59 if (!_values) return {};
  60 +
  61 + const outputData = (_outputData as unknown as StructJSON[]).map((item) =>
  62 + excludeIdInStructJSON(item.dataType!)
  63 + );
  64 + const inputData = (_inputData as unknown as StructJSON[]).map((item) =>
  65 + excludeIdInStructJSON(item.dataType!)
  66 + );
  67 +
49 const value = { 68 const value = {
50 functionName, 69 functionName,
51 identifier, 70 identifier,
@@ -55,7 +74,7 @@ @@ -55,7 +74,7 @@
55 functionJson: { 74 functionJson: {
56 inputData, 75 inputData,
57 outputData, 76 outputData,
58 - serviceCommand, 77 + ...(serviceCommand ? { inputData: [{ serviceCommand }] } : {}),
59 }, 78 },
60 } as ModelOfMatterParams; 79 } as ModelOfMatterParams;
61 80
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 </div> 30 </div>
31 <div> 31 <div>
32 <Spin :spinning="loading"> 32 <Spin :spinning="loading">
33 - <div id="jsoneditor" ref="jsoneditorRef"></div> 33 + <div id="jsoneditor" ref="jsoneditorEl"></div>
34 </Spin> 34 </Spin>
35 </div> 35 </div>
36 </div> 36 </div>
@@ -60,9 +60,12 @@ @@ -60,9 +60,12 @@
60 60
61 const jsonValue = ref(); 61 const jsonValue = ref();
62 62
63 - const jsonInstance = ref(); 63 + const jsonInstance = ref<{
  64 + set: (value?: Recordable) => void;
  65 + get: () => Recordable;
  66 + }>();
64 67
65 - const jsoneditorRef = ref<Recordable>(); 68 + const jsoneditorEl = ref<HTMLDivElement>();
66 69
67 const activeKey = ref(FunctionType.PROPERTIES); 70 const activeKey = ref(FunctionType.PROPERTIES);
68 71
@@ -73,7 +76,7 @@ @@ -73,7 +76,7 @@
73 mainMenuBar: false, 76 mainMenuBar: false,
74 statusBar: false, 77 statusBar: false,
75 }; 78 };
76 - let editor = new jsoneditor(jsoneditorRef.value, options); 79 + let editor = new jsoneditor(jsoneditorEl.value, options);
77 editor.set(jsonValue.value); 80 editor.set(jsonValue.value);
78 jsonInstance.value = editor; 81 jsonInstance.value = editor;
79 }); 82 });
@@ -83,7 +86,7 @@ @@ -83,7 +86,7 @@
83 86
84 const handleCopy = () => { 87 const handleCopy = () => {
85 try { 88 try {
86 - const valueRef = unref(jsonInstance).get(); 89 + const valueRef = unref(jsonInstance)?.get();
87 const value = JSON.stringify(unref(valueRef)); 90 const value = JSON.stringify(unref(valueRef));
88 if (!value) { 91 if (!value) {
89 createMessage.warning('请输入要拷贝的内容!'); 92 createMessage.warning('请输入要拷贝的内容!');
@@ -99,31 +102,36 @@ @@ -99,31 +102,36 @@
99 }; 102 };
100 103
101 const getFormData = () => { 104 const getFormData = () => {
102 - const value = unref(jsonInstance).get(); 105 + const value = unref(jsonInstance)?.get();
103 if (!value) return; 106 if (!value) return;
104 return value; 107 return value;
105 }; 108 };
106 109
107 const resetFormData = () => { 110 const resetFormData = () => {
108 - unref(jsonInstance).set(); 111 + unref(jsonInstance)?.set();
109 }; 112 };
110 113
111 const handlePremitter = () => { 114 const handlePremitter = () => {
112 - const value = unref(jsonInstance).get();  
113 - return unref(jsonInstance).set(value); 115 + const value = unref(jsonInstance)?.get();
  116 + return unref(jsonInstance)?.set(value);
114 }; 117 };
115 118
116 const handleSwitchTsl = async (functionType: FunctionType) => { 119 const handleSwitchTsl = async (functionType: FunctionType) => {
117 try { 120 try {
118 loading.value = true; 121 loading.value = true;
119 const record = await getModelTsl({ deviceProfileId: props.record.id, functionType }); 122 const record = await getModelTsl({ deviceProfileId: props.record.id, functionType });
120 - console.log(record); 123 + jsonInstance.value?.set(record);
121 } catch (error) { 124 } catch (error) {
122 } finally { 125 } finally {
123 loading.value = false; 126 loading.value = false;
124 } 127 }
125 }; 128 };
126 129
  130 + onMounted(() => {
  131 + activeKey.value = FunctionType.PROPERTIES;
  132 + handleSwitchTsl(FunctionType.PROPERTIES);
  133 + });
  134 +
127 defineExpose({ 135 defineExpose({
128 getFormData, 136 getFormData,
129 resetFormData, 137 resetFormData,
1 -<template>  
2 - <div>  
3 - <BasicForm @register="registerForm">  
4 - <template #structSlot>  
5 - <CommomParam  
6 - ref="CommomParamInParamRef"  
7 - :isExcludeStruct="true"  
8 - :isInputParam="true"  
9 - :inputParamData="inputParamData"  
10 - @emitAddInParam="handleAddInParam"  
11 - @emitEditInParam="handleEditInParam"  
12 - @emitDeletelnParam="handleDelInParam"  
13 - />  
14 - </template>  
15 - </BasicForm>  
16 - <AddParamsModal @register="registerModal" @data="getData" />  
17 - </div>  
18 -</template>  
19 -<script lang="ts" setup>  
20 - import { unref } from 'vue';  
21 - import { BasicForm, useForm } from '/@/components/Form';  
22 - import { addParamsSchemas } from '../config';  
23 - import { useModal } from '/@/components/Modal';  
24 - import useCommon from '../../hook/useCommon';  
25 - import AddParamsModal from './AddParamsModal.vue';  
26 - import CommomParam from './CommomParam.vue';  
27 - import useDefineVar from '../../hook/useDefineVar';  
28 -  
29 - defineEmits(['register']);  
30 -  
31 - const { inputParamData, CommomParamInParamRef } = useDefineVar();  
32 -  
33 - const { useChangeTypeGetTypeForm, useGetInOrOutData, useUpdateFormExcludeStruct } = useCommon();  
34 -  
35 - const [registerModal, { openModal }] = useModal();  
36 -  
37 - const [registerForm, { validate, resetFields, updateSchema }] = useForm({  
38 - labelWidth: 100,  
39 - schemas: addParamsSchemas,  
40 - actionColOptions: {  
41 - span: 14,  
42 - },  
43 - showResetButton: false,  
44 - submitOnReset: false,  
45 - showActionButtonGroup: false,  
46 - });  
47 -  
48 - const getData = (d, f) => useGetInOrOutData(d, f, unref(inputParamData), []);  
49 -  
50 - const handleAddInParam = (b, o) => openModal(b, o);  
51 -  
52 - const handleEditInParam = (b, o) => openModal(b, o);  
53 -  
54 - const handleDelInParam = (i) => unref(inputParamData).splice(i, 1);  
55 -  
56 - const updateFormExcludeStruct = (flag) => useUpdateFormExcludeStruct(flag, updateSchema);  
57 -  
58 - const getOutputStructList = () => CommomParamInParamRef.value?.getInputStructList();  
59 -  
60 - const getBoolOrStruct = (T, S, B) => {  
61 - if (T === 'STRUCT') {  
62 - return S;  
63 - } else if (T === 'INT' || T === 'DOUBLE' || T === 'TEXT') {  
64 - return null;  
65 - } else {  
66 - return B;  
67 - }  
68 - };  
69 -  
70 - const getIntOrText = (T, D) => {  
71 - if (T === 'STRUCT') {  
72 - return null;  
73 - } else if (T === 'INT' || T === 'DOUBLE' || T === 'TEXT') {  
74 - return D;  
75 - }  
76 - };  
77 -  
78 - const getFormData = async () => {  
79 - const values = await validate();  
80 - if (!values) return;  
81 - const outputParams = getOutputStructList();  
82 - outputParams?.forEach((f) => {  
83 - f.dataType = 'STRUCT';  
84 - f.childSpecsDTO = getIntOrText(f.childDataType, f.dataSpecs);  
85 - f.childEnumSpecsDTO = getBoolOrStruct(f.childDataType, null, f.dataSpecsList);  
86 - });  
87 - const dataSpecs = useChangeTypeGetTypeForm(values.dataType, values);  
88 - const dataSpecsList = useChangeTypeGetTypeForm(values.dataType, values);  
89 - const { boolClose, boolOpen, step, unit, valueRange, length, ...value } = values;  
90 - const none = [valueRange, step, unit, boolOpen, boolClose, length]; //没用,防止eslint报未使用变量  
91 - console.log(none);  
92 - return {  
93 - ...{ childName: value.name },  
94 - ...{ childDataType: value.dataType },  
95 - ...value,  
96 - ...{  
97 - dataSpecs: getIntOrText(values.dataType, dataSpecs),  
98 - },  
99 - ...{  
100 - dataSpecsList: getBoolOrStruct(values.dataType, outputParams, dataSpecsList),  
101 - },  
102 - };  
103 - };  
104 -  
105 - const setFormData = (v) => {  
106 - try {  
107 - setFieldsValue(v);  
108 - setFieldsValue({  
109 - ...v.dataSpecs,  
110 - valueRange: v.dataSpecs,  
111 - });  
112 - setFieldsValue({  
113 - boolClose: v.dataType == 'BOOL' ? v.dataSpecsList[0].name : '',  
114 - boolOpen: v.dataType == 'BOOL' ? v.dataSpecsList[1].name : '',  
115 - });  
116 - const { dataSpecsList, dataType, childDataType } = v;  
117 - if (childDataType == 'BOOL') {  
118 - setFieldsValue({  
119 - dataType: childDataType,  
120 - boolClose: dataSpecsList[0].name,  
121 - boolOpen: dataSpecsList[1].name,  
122 - });  
123 - }  
124 - if (dataType == 'BOOL' || dataType == 'STRUCT') {  
125 - inputParamData.value = [...new Array(dataSpecsList.length).keys()];  
126 - inputParamData.value = dataSpecsList;  
127 - }  
128 - } catch (e) {  
129 - console.log('AddParamForm error info', e);  
130 - }  
131 - };  
132 -  
133 - const resetFormData = () => {  
134 - resetFields();  
135 - inputParamData.value = [];  
136 - };  
137 -  
138 - defineExpose({  
139 - setFormData,  
140 - getFormData,  
141 - resetFormData,  
142 - updateFormExcludeStruct,  
143 - });  
144 -</script>  
145 -  
146 -<style lang="less" scope>  
147 - .add-style {  
148 - color: #0170cc;  
149 - cursor: pointer;  
150 - }  
151 -</style>  
1 -<template>  
2 - <div>  
3 - <BasicModal  
4 - :title="getTitle"  
5 - :maskClosable="false"  
6 - v-bind="$attrs"  
7 - width="45rem"  
8 - @register="register"  
9 - @ok="handleSubmit"  
10 - @cancel="handleCancel"  
11 - >  
12 - <AddParamForm ref="AddParamFormRef" />  
13 - </BasicModal>  
14 - </div>  
15 -</template>  
16 -<script lang="ts" setup>  
17 - import { ref, computed, reactive } from 'vue';  
18 - import { BasicModal, useModalInner } from '/@/components/Modal';  
19 - import AddParamForm from './AddParamForm.vue';  
20 - import useParitalValid from '../../hook/useParitalValid';  
21 -  
22 - const emits = defineEmits(['register', 'data']);  
23 -  
24 - const {} = useParitalValid();  
25 -  
26 - const setEditData: any = reactive({  
27 - getEditData: {},  
28 - });  
29 -  
30 - const AddParamFormRef = ref<InstanceType<typeof AddParamForm>>();  
31 -  
32 - const isUpdate = ref(false);  
33 -  
34 - const isFlag = ref('');  
35 -  
36 - const excludeStruct = ref(false);  
37 -  
38 - const getTitle = computed(() => (!isUpdate.value ? '编辑参数' : '新增参数'));  
39 -  
40 - const [register, { setModalProps }] = useModalInner(async (data) => {  
41 - setModalProps({ loading: true });  
42 -  
43 - isUpdate.value = data.isUpdate;  
44 - isFlag.value = data.flag;  
45 - excludeStruct.value = data.excludeStruct;  
46 - !isUpdate.value ? AddParamFormRef.value?.setFormData(data.record) : '';  
47 - setEditData.getEditData = data.record;  
48 - setModalProps({ loading: false });  
49 - if (excludeStruct.value) {  
50 - AddParamFormRef.value?.updateFormExcludeStruct(true);  
51 - } else {  
52 - AddParamFormRef.value?.updateFormExcludeStruct(false);  
53 - }  
54 - });  
55 -  
56 - const handleCancel = () => {  
57 - AddParamFormRef.value?.resetFormData();  
58 - };  
59 -  
60 - const handleSubmit = async () => {  
61 - const value = await AddParamFormRef.value?.getFormData();  
62 - if (!value) return;  
63 - emits('data', value);  
64 - handleCancel();  
65 - };  
66 -</script>  
67 -<style lang="less" scope></style>  
1 -<template>  
2 - <!-- 输入参数 -->  
3 - <div v-if="isInputParam">  
4 - <template v-for="(item, index) in inputParamData" :key="item.name">  
5 - <span style="display: none">{{ item }}</span>  
6 - <InputParamItem  
7 - :title="item.name"  
8 - :item="item"  
9 - class="mt-4"  
10 - :index="index"  
11 - :ref="dynamicBindRef.inputParamItemRef"  
12 - @delete="deleteInParItem"  
13 - @edit="editInParItem"  
14 - />  
15 - </template>  
16 - <div style="display: flex" :class="{ 'mt-2': inputParamData.length > 0 }">  
17 - <span class="add-style">+</span>  
18 - <span class="add-style" @click="handleAddInParam">增加参数</span>  
19 - </div>  
20 - </div>  
21 - <!-- 输出参数 -->  
22 - <div v-if="isOutputParam">  
23 - <template v-for="(item, index) in outputParamData" :key="item.name">  
24 - <span style="display: none">{{ item + index }}</span>  
25 - <InputParamItem  
26 - :title="item.name"  
27 - :item="item"  
28 - class="mt-4"  
29 - :index="index"  
30 - :ref="dynamicBindRef.outputParamItemRef"  
31 - @delete="deleteOutParItem"  
32 - @edit="editOutParItem"  
33 - />  
34 - </template>  
35 - <div style="display: flex" :class="{ 'mt-2': outputParamData.length > 0 }">  
36 - <span class="add-style">+</span>  
37 - <span class="add-style" @click="handleAddOutParam">增加参数</span>  
38 - </div>  
39 - </div>  
40 -</template>  
41 -<script lang="ts" setup>  
42 - import { ref, unref } from 'vue';  
43 - import InputParamItem from './InputParamItem.vue';  
44 -  
45 - const props = defineProps({  
46 - isExcludeStruct: { type: Boolean, default: true },  
47 - isInputParam: { type: Boolean, default: false },  
48 - isOutputParam: { type: Boolean, default: false },  
49 - inputParamData: {  
50 - type: Array as PropType<any[]>,  
51 - default: () => [],  
52 - },  
53 - outputParamData: {  
54 - type: Array as PropType<any[]>,  
55 - default: () => [],  
56 - },  
57 - });  
58 -  
59 - const emit = defineEmits([  
60 - 'emitAddInParam',  
61 - 'emitEditInParam',  
62 - 'emitDeletelnParam',  
63 - 'emitAddOutParam',  
64 - 'emitEditOutParam',  
65 - 'emitDeleteOutParam',  
66 - ]);  
67 -  
68 - const dynamicBindRef = {  
69 - inputParamItemRef: ref([]),  
70 - outputParamItemRef: ref([]),  
71 - };  
72 -  
73 - const commomAddParamObj = {  
74 - isUpdate: true,  
75 - excludeStruct: props.isExcludeStruct ? true : false,  
76 - };  
77 -  
78 - const commomEditParamObj = {  
79 - isUpdate: false,  
80 - excludeStruct: props.isExcludeStruct ? true : false,  
81 - };  
82 -  
83 - const handleAddInParam = () => {  
84 - emit('emitAddInParam', true, {  
85 - ...commomAddParamObj,  
86 - flag: 'input',  
87 - });  
88 - };  
89 -  
90 - const deleteInParItem = (index) => {  
91 - emit('emitDeletelnParam', index);  
92 - };  
93 -  
94 - const editInParItem = (item) => {  
95 - emit('emitEditInParam', true, {  
96 - ...commomEditParamObj,  
97 - record: item,  
98 - flag: 'input',  
99 - });  
100 - };  
101 -  
102 - const handleAddOutParam = () => {  
103 - emit('emitAddOutParam', true, {  
104 - ...commomAddParamObj,  
105 - flag: 'output',  
106 - });  
107 - };  
108 -  
109 - const deleteOutParItem = (index) => {  
110 - emit('emitDeleteOutParam', index);  
111 - };  
112 -  
113 - const editOutParItem = (item) => {  
114 - emit('emitEditOutParam', true, {  
115 - ...commomEditParamObj,  
116 - record: item,  
117 - flag: 'output',  
118 - });  
119 - };  
120 -  
121 - const getInputStructList = () =>  
122 - unref(dynamicBindRef.inputParamItemRef)?.map((item: any) => item.getFormData());  
123 -  
124 - const getOutputStructList = () =>  
125 - unref(dynamicBindRef.outputParamItemRef)?.map((item: any) => item.getFormData());  
126 -  
127 - defineExpose({  
128 - getInputStructList,  
129 - getOutputStructList,  
130 - });  
131 -</script>  
132 -<style lang="less" scoped>  
133 - .add-style {  
134 - color: #0170cc;  
135 - cursor: pointer;  
136 - }  
137 -</style>  
1 -<template>  
2 - <div>  
3 - <a-card :title="`参数名称:${item.id}`" style="width: 540px; margin-top: -5px">  
4 - <template #extra>  
5 - <div style="display: flex; align-items: center">  
6 - <span style="color: #0170cc; cursor: pointer" @click="handleEdit">编辑</span>  
7 - <a-divider type="vertical" style="height: 12px; background-color: #d8d8d8" />  
8 - <span style="color: #0170cc; cursor: pointer" class="ml-1" @click="handleDelete"  
9 - >删除</span  
10 - >  
11 - </div>  
12 - </template>  
13 - </a-card>  
14 - </div>  
15 -</template>  
16 -<script lang="ts" setup>  
17 - import { FunctionJson } from '/@/api/device/model/modelOfMatterModel';  
18 -  
19 - const emit = defineEmits(['delete', 'edit']);  
20 -  
21 - type ItemRecrod = FunctionJson & { id: string };  
22 -  
23 - const props = defineProps({  
24 - item: {  
25 - type: Object as PropType<ItemRecrod>,  
26 - required: true,  
27 - default: () => {},  
28 - },  
29 - });  
30 -  
31 - const handleDelete = () => {  
32 - emit('delete', props.item);  
33 - };  
34 -  
35 - const handleEdit = () => {  
36 - emit('edit', props.item);  
37 - };  
38 -  
39 - const getFormData = () => {  
40 - return props.item;  
41 - };  
42 -  
43 - defineExpose({  
44 - getFormData,  
45 - });  
46 -</script>  
47 -<style lang="less" scoped>  
48 - :deep(.ant-card-body) {  
49 - display: none !important;  
50 - }  
51 -</style>  
@@ -113,6 +113,15 @@ export const serviceSchemas = (tcpDeviceFlag: boolean): FormSchema[] => { @@ -113,6 +113,15 @@ export const serviceSchemas = (tcpDeviceFlag: boolean): FormSchema[] => {
113 }, 113 },
114 }, 114 },
115 { 115 {
  116 + field: FormField.SERVICE_COMMAND,
  117 + label: '输入参数',
  118 + component: 'Input',
  119 + ifShow: tcpDeviceFlag,
  120 + componentProps: {
  121 + placeholder: '请输入ASCII或HEX服务命令',
  122 + },
  123 + },
  124 + {
116 field: FormField.INPUT_PARAM, 125 field: FormField.INPUT_PARAM,
117 label: '输入参数', 126 label: '输入参数',
118 component: 'StructForm', 127 component: 'StructForm',
@@ -127,19 +136,9 @@ export const serviceSchemas = (tcpDeviceFlag: boolean): FormSchema[] => { @@ -127,19 +136,9 @@ export const serviceSchemas = (tcpDeviceFlag: boolean): FormSchema[] => {
127 component: 'StructForm', 136 component: 'StructForm',
128 valueField: 'value', 137 valueField: 'value',
129 changeEvent: 'update:value', 138 changeEvent: 'update:value',
130 - ifShow: !tcpDeviceFlag,  
131 colProps: { span: 24 }, 139 colProps: { span: 24 },
132 }, 140 },
133 { 141 {
134 - field: FormField.SERVICE_COMMAND,  
135 - label: '服务命令',  
136 - component: 'Input',  
137 - ifShow: tcpDeviceFlag,  
138 - componentProps: {  
139 - placeholder: '请输入服务命令',  
140 - },  
141 - },  
142 - {  
143 field: FormField.REFARK, 142 field: FormField.REFARK,
144 label: '备注', 143 label: '备注',
145 component: 'InputTextArea', 144 component: 'InputTextArea',
1 <template> 1 <template>
2 - <div :class="`${prefixCls}-bottom`"> 2 + <div :class="[`${prefixCls}-bottom`, '!dark:bg-dark-900']">
3 <Tabs> 3 <Tabs>
4 <template v-for="item in achieveList" :key="item.key"> 4 <template v-for="item in achieveList" :key="item.key">
5 <TabPane :tab="item.name"> 5 <TabPane :tab="item.name">
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 &-bottom { 37 &-bottom {
38 padding: 10px; 38 padding: 10px;
39 margin: 16px; 39 margin: 16px;
40 - background-color: @component-background; 40 + // background-color: @component-background;
41 border-radius: 3px; 41 border-radius: 3px;
42 } 42 }
43 } 43 }