Commit 2d9be9884523c74fb577a0e6549dfd5336cf0b04

Authored by xp.Huang
2 parents 93399038 d2a6ff3f

Merge branch 'fix/DEFECT-1873' into 'main_dev'

fix: 修复设备详情命令下发枚举类型无法下发&&优化命令下发逻辑

See merge request yunteng/thingskit-front!1174
Showing 70 changed files with 444 additions and 1481 deletions
1 1 import { DeviceProfileModel } from '../../device/model/deviceModel';
2   -import { HistoryData } from './model';
  2 +import { DeviceAttributeItemType, HistoryData } from './model';
3 3 import { defHttp } from '/@/utils/http/axios';
4 4 import { isString } from '/@/utils/is';
5 5 import { OrderByEnum } from '/@/views/device/localtion/cpns/TimePeriodForm/config';
... ... @@ -38,7 +38,7 @@ export const getDeviceDataKeys = (id: string) => {
38 38 };
39 39 // 获取设备状态,在线 or 离线时间
40 40 export const getDeviceActiveTime = (entityId: string) => {
41   - return defHttp.get(
  41 + return defHttp.get<DeviceAttributeItemType[]>(
42 42 {
43 43 url: `/plugins/telemetry/DEVICE/${entityId}/values/attributes?keys=active`,
44 44 },
... ...
1 1 export interface HistoryData {
2 2 [key: string]: { ts: number; value: string }[];
3 3 }
  4 +
  5 +export interface DeviceAttributeItemType {
  6 + key: string;
  7 + value: boolean;
  8 + lastUpdateTs: number;
  9 +}
... ...
... ... @@ -13,7 +13,7 @@ import { ChildDeviceParams } from './model/deviceModel';
13 13 import { PaginationResult } from '/#/axios';
14 14 import { AlarmLogItem } from './model/deviceConfigModel';
15 15 import { omit } from 'lodash-es';
16   -import { CommandDeliveryWayEnum } from '/@/enums/toolEnum';
  16 +import { CommandDeliveryWayEnum } from '/@/enums/deviceEnum';
17 17 enum DeviceManagerApi {
18 18 /**
19 19 * 设备URL
... ...
1 1 import { BasicPageParams } from '/@/api/model/baseModel';
  2 +import { CommandTypeEnum, RPCCommandMethodEnum } from '/@/enums/deviceEnum';
2 3
3 4 export type TDeviceConfigPageQueryParam = BasicPageParams & TDeviceConfigParams;
4 5
... ... @@ -184,3 +185,10 @@ export interface Configuration {
184 185 export interface TransportConfiguration {
185 186 type: string;
186 187 }
  188 +
  189 +export interface RpcCommandType {
  190 + additionalInfo: { cmdType: CommandTypeEnum };
  191 + method: RPCCommandMethodEnum;
  192 + params: Recordable | string | number;
  193 + persistent: boolean;
  194 +}
... ...
... ... @@ -2,7 +2,7 @@ import { withInstall } from '/@/utils';
2 2 // @ts-ignore
3 3 import codeEditor from './src/CodeEditor.vue';
4 4 import jsonPreview from './src/json-preview/JsonPreview.vue';
5   -export { JSONEditor } from './src/JSONEditor';
  5 +export { JSONEditor, JSONEditorValidator, parseStringToJSON } from './src/JSONEditor';
6 6
7 7 export const CodeEditor = withInstall(codeEditor);
8 8 export const JsonPreview = withInstall(jsonPreview);
... ...
... ... @@ -12,17 +12,17 @@ export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
12 12 export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
13 13 export { default as ApiUpload } from './src/components/ApiUpload.vue';
14 14
15   -export { default as StructForm } from './src/externalCompns/components/StructForm/StructForm.vue';
  15 +export { default as StructForm } from './src/components/StructForm/StructForm.vue';
16 16 export { default as JavaScriptFunctionEditor } from './src/components/JavaScriptFunctionEditor.vue';
17 17
18   -export { ThingsModelForm } from './src/externalCompns/components/ThingsModelForm';
  18 +export { ThingsModelForm } from './src/components/ThingsModelForm';
19 19
20 20 //注册自定义组件
21 21 export {
22 22 JEasyCron,
23 23 JEasyCronInner,
24 24 JEasyCronModal,
25   -} from '/@/components/Form/src/externalCompns/components/JEasyCron';
  25 +} from '/@/components/Form/src/components/JEasyCron';
26 26 // Jeecg自定义校验
27   -export { JCronValidator } from '/@/components/Form/src/externalCompns/components/JEasyCron';
  27 +export { JCronValidator } from '/@/components/Form/src/components/JEasyCron';
28 28 // export { BasicForm };
... ...
... ... @@ -29,20 +29,20 @@ import { IconPicker } from '/@/components/Icon';
29 29 import { CountdownInput } from '/@/components/CountDown';
30 30 import ApiRadioGroup from './components/ApiRadioGroup.vue';
31 31 //自定义组件
32   -import JAddInput from './externalCompns/components/JAddInput.vue';
33   -import { JEasyCron } from './externalCompns/components/JEasyCron';
  32 +import JAddInput from './components/JAddInput.vue';
  33 +import { JEasyCron } from './components/JEasyCron';
34 34 import ColorPicker from './components/ColorPicker.vue';
35 35 import IconDrawer from './components/IconDrawer.vue';
36 36 import ApiUpload from './components/ApiUpload.vue';
37 37 import ApiSearchSelect from './components/ApiSearchSelect.vue';
38   -import CustomMinMaxInput from './externalCompns/components/CustomMinMaxInput.vue';
39   -import StructForm from './externalCompns/components/StructForm/StructForm.vue';
  38 +import CustomMinMaxInput from './components/CustomMinMaxInput.vue';
  39 +import StructForm from './components/StructForm/StructForm.vue';
40 40 import ApiSelectScrollLoad from './components/ApiSelectScrollLoad.vue';
41 41 import InputGroup from './components/InputGroup.vue';
42 42 import RegisterAddressInput from '/@/views/task/center/components/PollCommandInput/RegisterAddressInput.vue';
43   -import ExtendDesc from '/@/components/Form/src/externalCompns/components/ExtendDesc/index.vue';
44   -import DeviceProfileForm from '/@/components/Form/src/externalCompns/components/DeviceProfileForm/index.vue';
45   -import EnumList from './externalCompns/components/StructForm/EnumList.vue';
  43 +import ExtendDesc from '/@/components/Form/src/components/ExtendDesc/index.vue';
  44 +import DeviceProfileForm from '/@/components/Form/src/components/DeviceProfileForm/index.vue';
  45 +import EnumList from './components/StructForm/EnumList.vue';
46 46
47 47 const componentMap = new Map<ComponentType, Component>();
48 48
... ...
src/components/Form/src/components/CustomMinMaxInput.vue renamed from src/components/Form/src/externalCompns/components/CustomMinMaxInput.vue
src/components/Form/src/components/DeviceProfileForm/index.vue renamed from src/components/Form/src/externalCompns/components/DeviceProfileForm/index.vue
src/components/Form/src/components/ExtendDesc/config.ts renamed from src/components/Form/src/externalCompns/components/ExtendDesc/config.ts
src/components/Form/src/components/ExtendDesc/index.vue renamed from src/components/Form/src/externalCompns/components/ExtendDesc/index.vue
src/components/Form/src/components/JAddInput.vue renamed from src/components/Form/src/externalCompns/components/JAddInput.vue
src/components/Form/src/components/JEasyCron/EasyCronInner.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/EasyCronInner.vue
src/components/Form/src/components/JEasyCron/EasyCronInput.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/EasyCronInput.vue
src/components/Form/src/components/JEasyCron/EasyCronModal.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/EasyCronModal.vue
src/components/Form/src/components/JEasyCron/LICENSE renamed from src/components/Form/src/externalCompns/components/JEasyCron/LICENSE
src/components/Form/src/components/JEasyCron/easy.cron.data.ts renamed from src/components/Form/src/externalCompns/components/JEasyCron/easy.cron.data.ts
src/components/Form/src/components/JEasyCron/easy.cron.inner.less renamed from src/components/Form/src/externalCompns/components/JEasyCron/easy.cron.inner.less
src/components/Form/src/components/JEasyCron/easy.cron.input.less renamed from src/components/Form/src/externalCompns/components/JEasyCron/easy.cron.input.less
src/components/Form/src/components/JEasyCron/index.ts renamed from src/components/Form/src/externalCompns/components/JEasyCron/index.ts
src/components/Form/src/components/JEasyCron/tabs/DayUI.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/DayUI.vue
src/components/Form/src/components/JEasyCron/tabs/HourUI.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/HourUI.vue
src/components/Form/src/components/JEasyCron/tabs/MinuteUI.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/MinuteUI.vue
src/components/Form/src/components/JEasyCron/tabs/MonthUI.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/MonthUI.vue
src/components/Form/src/components/JEasyCron/tabs/SecondUI.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/SecondUI.vue
src/components/Form/src/components/JEasyCron/tabs/WeekUI.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/WeekUI.vue
src/components/Form/src/components/JEasyCron/tabs/YearUI.vue renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/YearUI.vue
src/components/Form/src/components/JEasyCron/tabs/useTabMixin.ts renamed from src/components/Form/src/externalCompns/components/JEasyCron/tabs/useTabMixin.ts
src/components/Form/src/components/JEasyCron/validator.ts renamed from src/components/Form/src/externalCompns/components/JEasyCron/validator.ts
src/components/Form/src/components/StructForm/EnumList.config.ts renamed from src/components/Form/src/externalCompns/components/StructForm/EnumList.config.ts
src/components/Form/src/components/StructForm/EnumList.vue renamed from src/components/Form/src/externalCompns/components/StructForm/EnumList.vue
src/components/Form/src/components/StructForm/StructForm.vue renamed from src/components/Form/src/externalCompns/components/StructForm/StructForm.vue
src/components/Form/src/components/StructForm/StructFormModel.vue renamed from src/components/Form/src/externalCompns/components/StructForm/StructFormModel.vue
src/components/Form/src/components/StructForm/config.ts renamed from src/components/Form/src/externalCompns/components/StructForm/config.ts
src/components/Form/src/components/StructForm/type.ts renamed from src/components/Form/src/externalCompns/components/StructForm/type.ts
src/components/Form/src/components/StructForm/util.ts renamed from src/components/Form/src/externalCompns/components/StructForm/util.ts
src/components/Form/src/components/ThingsModelForm/StructPreview.vue renamed from src/components/Form/src/externalCompns/components/ThingsModelForm/StructPreview.vue
src/components/Form/src/components/ThingsModelForm/config.ts renamed from src/components/Form/src/externalCompns/components/ThingsModelForm/config.ts
1   -import { FormSchema } from '../../../types/form';
  1 +import { FormSchema } from '/@/components/Form';
2 2 import { Specs, StructJSON } from '/@/api/device/model/modelOfMatterModel';
  3 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
3 4 import { DataTypeEnum } from '/@/enums/objectModelEnum';
4   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
  5 +import { validateTCPCustomCommand } from '.';
5 6
6 7 export const getFormSchemas = ({
7 8 structJSON: structJson,
... ... @@ -143,6 +144,7 @@ export const getFormSchemas = ({
143 144 component: 'Input',
144 145 required,
145 146 defaultValue: serviceCommand,
  147 + rules: [{ validator: validateTCPCustomCommand }],
146 148 componentProps: {
147 149 placeholder: `请输入服务命令`,
148 150 },
... ...
src/components/Form/src/components/ThingsModelForm/index.ts renamed from src/components/Form/src/externalCompns/components/ThingsModelForm/index.ts
src/components/Form/src/components/ThingsModelForm/index.vue renamed from src/components/Form/src/externalCompns/components/ThingsModelForm/index.vue
... ... @@ -5,7 +5,7 @@
5 5 import { ThingsModelForm } from '.';
6 6 import { DefineComponentsBasicExpose } from '/#/utils';
7 7 import { StructJSON } from '/@/api/device/model/modelOfMatterModel';
8   - import { useForm } from '../../../hooks/useForm';
  8 + import { useForm } from '../../hooks/useForm';
9 9 import { DataTypeEnum } from '/@/enums/objectModelEnum';
10 10 import { BasicForm } from '/@/components/Form';
11 11
... ...
1   -<script lang="ts" setup>
2   - import { Card } from 'ant-design-vue';
3   - import { computed, nextTick, onMounted, onUpdated, unref, watch } from 'vue';
4   - import { BasicCreateFormParams } from './type';
5   - import { DynamicProps } from '/#/utils';
6   - import { Specs, StructJSON } from '/@/api/device/model/modelOfMatterModel';
7   - import { BasicForm, FormProps, FormSchema, useForm } from '/@/components/Form';
8   - import { DataTypeEnum } from '/@/enums/objectModelEnum';
9   - import { ReadAndWriteEnum } from '/@/enums/toolEnum';
10   -
11   - const props = withDefaults(
12   - defineProps<{
13   - inputData?: StructJSON[];
14   - formProps?: FormProps;
15   - value?: Recordable;
16   - required?: boolean;
17   - }>(),
18   - {
19   - inputData: () => [] as StructJSON[],
20   - formProps: () => ({}),
21   - value: () => ({}),
22   - }
23   - );
24   -
25   - const emit = defineEmits(['update:value']);
26   -
27   - const getCurrentKeys = computed(() => {
28   - const { inputData } = props;
29   - return (inputData || []).map((item) => item.identifier);
30   - });
31   -
32   - const [register, { setProps, getFieldsValue, setFieldsValue }] = useForm({
33   - schemas: [],
34   - showActionButtonGroup: false,
35   - layout: 'inline',
36   - labelWidth: 80,
37   - wrapperCol: { span: 12 },
38   - ...(props.formProps || ({} as unknown as Partial<DynamicProps<FormProps>>)),
39   - });
40   -
41   - const syncValue = (key: string, value: any) => {
42   - let record = getFieldsValue();
43   - record = { ...record, [key]: value };
44   - const setValues = {};
45   - Object.keys(record).forEach((key) => {
46   - const hasKey = unref(getCurrentKeys).includes(key);
47   - if (hasKey) {
48   - setValues[key] = record[key];
49   - }
50   - });
51   - emit('update:value', setValues);
52   - };
53   -
54   - const createInputNumber = ({
55   - identifier,
56   - functionName,
57   - specs,
58   - }: BasicCreateFormParams): FormSchema => {
59   - const { valueRange } = specs! as Partial<Specs>;
60   - const { max = 2147483647, min = -2147483648 } = valueRange || {};
61   - return {
62   - field: identifier,
63   - label: functionName,
64   - component: 'InputNumber',
65   - rules: [
66   - {
67   - required: props.required,
68   - message: `${functionName}是必填项`,
69   - },
70   - {
71   - type: 'number',
72   - trigger: 'change',
73   - validator: (_rule, value) => {
74   - const reg = /^[0-9]*$/;
75   - if (!reg.test(value)) return Promise.reject(`${functionName}不是一个有效的数字`);
76   - if (value < min || value > max) {
77   - return Promise.reject(`${functionName}取值范围在${min}~${max}之间`);
78   - }
79   - return Promise.resolve(value);
80   - },
81   - },
82   - ],
83   - componentProps: {
84   - max,
85   - min,
86   - // step: step,
87   - // formatter: (value: string) => value,
88   - // parser: (string: string) => {
89   - // if (dataType === DataTypeEnum.NUMBER_INT) {
90   - // return Number(Number(string).toFixed());
91   - // }
92   - // return Number(string);
93   - // },
94   - onChange: (value: string) => {
95   - syncValue(identifier, value);
96   - },
97   - },
98   - } as FormSchema;
99   - };
100   -
101   - const createInput = ({ identifier, functionName, specs }: BasicCreateFormParams): FormSchema => {
102   - const { length = 10240 } = specs! as Partial<Specs>;
103   - return {
104   - field: identifier,
105   - label: functionName,
106   - component: 'Input',
107   - rules: [
108   - {
109   - required: props.required,
110   - message: `${functionName}是必填项`,
111   - },
112   - {
113   - type: 'string',
114   - trigger: 'change',
115   - validator: (_rule, value) => {
116   - if (value.length > length) {
117   - return Promise.reject(`${functionName}数据长度应该小于${length}`);
118   - }
119   - return Promise.resolve(value);
120   - },
121   - },
122   - ],
123   - componentProps: {
124   - maxLength: length,
125   - onChange: (value: InputEvent) => {
126   - syncValue(identifier, (value.target as HTMLInputElement).value);
127   - },
128   - },
129   - } as FormSchema;
130   - };
131   -
132   - const createSelect = ({ identifier, functionName, specs }: BasicCreateFormParams): FormSchema => {
133   - const { boolClose, boolOpen } = specs! as Partial<Specs>;
134   - return {
135   - field: identifier,
136   - label: functionName,
137   - component: 'Select',
138   - rules: [
139   - {
140   - required: props.required,
141   - message: `${functionName}是必填项`,
142   - type: 'number',
143   - },
144   - ],
145   - componentProps: {
146   - options: [
147   - { label: `${boolClose}-0`, value: 0 },
148   - { label: `${boolOpen}-1`, value: 1 },
149   - ],
150   - onChange: (value: string) => {
151   - syncValue(identifier, value);
152   - },
153   - },
154   - };
155   - };
156   -
157   - const createInputJson = ({ identifier, functionName }: BasicCreateFormParams): FormSchema => {
158   - return {
159   - field: identifier,
160   - label: functionName,
161   - component: 'InputTextArea',
162   - rules: [
163   - {
164   - required: props.required,
165   - message: `${functionName}是必填项`,
166   - },
167   - ],
168   - componentProps: {
169   - onChange: (value: InputEvent) => {
170   - syncValue(identifier, (value.target as HTMLInputElement).value);
171   - },
172   - },
173   - };
174   - };
175   -
176   - const transformToFormSchema = (inputData: StructJSON[]) => {
177   - const schemas: FormSchema[] = [];
178   - for (const item of inputData) {
179   - const { dataType, identifier, functionName, accessMode } = item;
180   - if (accessMode === ReadAndWriteEnum.READ) {
181   - continue;
182   - }
183   - const { type, specs } = dataType! || {};
184   -
185   - const params: BasicCreateFormParams = {
186   - identifier: identifier!,
187   - functionName: functionName!,
188   - dataType: dataType! as unknown as DataTypeEnum,
189   - specs: specs as Partial<Specs>,
190   - };
191   - if (type === DataTypeEnum.NUMBER_INT || type === DataTypeEnum.NUMBER_DOUBLE) {
192   - schemas.push(createInputNumber(params));
193   - }
194   -
195   - if (type === DataTypeEnum.BOOL) {
196   - schemas.push(createSelect(params));
197   - }
198   -
199   - if (type === DataTypeEnum.STRING) {
200   - schemas.push(createInput(params));
201   - }
202   -
203   - if (type === DataTypeEnum.STRUCT) {
204   - schemas.push(createInputJson(params));
205   - }
206   - }
207   -
208   - return schemas;
209   - };
210   -
211   - const generateSchemas = (value: StructJSON[]) => {
212   - if (value && value.length) {
213   - const schemas = transformToFormSchema(value);
214   - setProps({ schemas });
215   - }
216   - };
217   -
218   - onMounted(() => {
219   - generateSchemas(props.inputData);
220   - });
221   -
222   - onUpdated(async () => {
223   - if (props.inputData && props.inputData.length) {
224   - await nextTick();
225   - setFieldsValue(props.value || {});
226   - }
227   - });
228   -
229   - watch(
230   - () => props.inputData,
231   - (value) => {
232   - generateSchemas(value);
233   - }
234   - );
235   -
236   - watch(
237   - () => props.formProps,
238   - (value) => {
239   - setProps(value);
240   - }
241   - );
242   -</script>
243   -
244   -<template>
245   - <Card bordered class="!border-dashed !rounded-lg !border-2px">
246   - <!-- <Alert class="!mb-4 w-32" message="服务参数配置" type="info" /> -->
247   - <BasicForm class="object-model-validate-form" @register="register" />
248   - </Card>
249   -</template>
250   -
251   -<style lang="less">
252   - .object-model-validate-form {
253   - .ant-input-number {
254   - width: 100% !important;
255   - }
256   - }
257   -</style>
1   -import { Specs } from '/@/api/device/model/modelOfMatterModel';
2   -import { DataTypeEnum } from '/@/enums/objectModelEnum';
3   -
4   -export interface BasicCreateFormParams {
5   - identifier: string;
6   - functionName: string;
7   - dataType: DataTypeEnum;
8   - specs: Partial<Specs>;
9   -}
... ... @@ -122,7 +122,6 @@ export type ComponentType =
122 122 | 'ApiSelectScrollLoad'
123 123 | 'TransferModal'
124 124 | 'TransferTableModal'
125   - | 'ObjectModelValidateForm'
126 125 | 'ThingsModelForm'
127 126 | 'DevicePicker'
128 127 | 'ProductPicker'
... ...
  1 +export enum TransportTypeEnum {
  2 + DEFAULT = 'DEFAULT',
  3 + MQTT = 'MQTT',
  4 + COAP = 'COAP',
  5 + LWM2M = 'LWM2M',
  6 + SNMP = 'SNMP',
  7 + TCP = 'TCP',
  8 +}
  9 +
  10 +export enum ReadAndWriteEnum {
  11 + READ = 'r',
  12 + READ_AND_WRITE = 'rw',
  13 +}
  14 +
  15 +export enum ServiceCallTypeEnum {
  16 + ASYNC = 'ASYNC',
  17 + SYNC = 'SYNC',
  18 +}
  19 +
  20 +export enum ServiceCallTypeNameEnum {
  21 + ASYNC = '异步',
  22 + SYNC = '同步',
  23 +}
  24 +
  25 +export enum CommandDeliveryWayEnum {
  26 + ONE_WAY = 'oneway',
  27 + TWO_WAY = 'twoway',
  28 +}
  29 +
  30 +export enum CommandDeliveryWayNameEnum {
  31 + ONE_WAY = '单向',
  32 + TWO_WAY = '双向',
  33 +}
  34 +
  35 +export enum CommandTypeEnum {
  36 + CUSTOM = 0,
  37 + SERVICE = 1,
  38 + ATTRIBUTE = 2,
  39 + API = 'api',
  40 +}
  41 +
  42 +export enum CommandTypeNameEnum {
  43 + CUSTOM = '自定义',
  44 + SERVICE = '服务',
  45 + ATTRIBUTE = '属性',
  46 +}
  47 +
  48 +export enum RPCCommandMethodEnum {
  49 + THINGSKIT = 'methodThingskit',
  50 +}
... ...
... ... @@ -154,16 +154,3 @@ export enum ExecutionActionNameEnum {
154 154 DEVICE_OUT = '设备输出',
155 155 MSG_NOTIFY = '告警输出',
156 156 }
157   -
158   -export enum CommandTypeEnum {
159   - CUSTOM = 0,
160   - SERVICE = 1,
161   - ATTRIBUTE = 2,
162   - API = 'api',
163   -}
164   -
165   -export enum CommandTypeNameEnum {
166   - CUSTOM = '自定义',
167   - SERVICE = '服务',
168   - ATTRIBUTE = '属性',
169   -}
... ...
... ... @@ -29,23 +29,3 @@ export enum BooleanStringEnum {
29 29 TRUE = 'true',
30 30 FALSE = 'false',
31 31 }
32   -
33   -export enum ReadAndWriteEnum {
34   - READ = 'r',
35   - READ_AND_WRITE = 'rw',
36   -}
37   -
38   -export enum ServiceCallTypeEnum {
39   - ASYNC = 'ASYNC',
40   - SYNC = 'SYNC',
41   -}
42   -
43   -export enum ServiceCallTypeNameEnum {
44   - ASYNC = '异步',
45   - SYNC = '同步',
46   -}
47   -
48   -export enum CommandDeliveryWayEnum {
49   - ONE_WAY = 'oneway',
50   - TWO_WAY = 'twoway',
51   -}
... ...
1   -import { FormProps, FormSchema, useComponentRegister } from '/@/components/Form';
  1 +import { FormSchema, useComponentRegister } from '/@/components/Form';
2 2 import { findDictItemByCode } from '/@/api/system/dict';
3 3 import { getGatewayDevice, queryDeviceProfileBy } from '/@/api/device/deviceManager';
4   -import { TransportTypeEnum } from '../../profiles/components/TransportDescript/const';
5   -import { JSONEditorValidator } from '/@/components/CodeEditor/src/JSONEditor';
6 4 import { JSONEditor } from '/@/components/CodeEditor';
7 5 import { DeviceRecord, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
8   -import { getModelServices } from '/@/api/device/modelOfMatter';
9   -import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
10   -import { h, toRaw, unref } from 'vue';
11   -import ObjectModelValidateForm from '/@/components/Form/src/externalCompns/components/ObjectModelValidateForm/ObjectModelValidateForm.vue';
12   -import { CommandDeliveryWayEnum, ServiceCallTypeEnum } from '/@/enums/toolEnum';
  6 +import { h } from 'vue';
13 7 import { TaskTypeEnum } from '/@/views/task/center/config';
14 8 import { AddressTypeEnum } from '/@/views/task/center/components/PollCommandInput';
15 9 import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
... ... @@ -17,9 +11,9 @@ import { createImgPreview } from '/@/components/Preview';
17 11 import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
18 12 import LockControlGroup from '/@/components/Form/src/components/LockControlGroup.vue';
19 13 import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
  14 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
20 15
21 16 useComponentRegister('JSONEditor', JSONEditor);
22   -useComponentRegister('ObjectModelValidateForm', ObjectModelValidateForm);
23 17 useComponentRegister('LockControlGroup', LockControlGroup);
24 18 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
25 19
... ... @@ -910,214 +904,3 @@ export const TokenSchemas: FormSchema[] = [
910 904 },
911 905 },
912 906 ];
913   -
914   -export enum ValueType {
915   - JSON = 'json',
916   - STRING = 'string',
917   -}
918   -
919   -export enum CommandFieldsEnum {
920   - COMMAND_TYPE = 'commandType',
921   - VALUE_TYPE = 'valueType',
922   - COMMAND_TEXT = 'commandText',
923   - COMAND_VALUE = 'commandValue',
924   - SERVICE = 'service',
925   - SERVICE_TYPE = 'service_type',
926   - TCP_SERVICE = 'tcpService',
927   - MODEL_INPUT = 'modelInput',
928   - CUSTOM_TYPE = 'customType',
929   -}
930   -
931   -export enum CommandType {
932   - CUSTOM = 'custom',
933   - SERVICE = 'service',
934   -}
935   -
936   -export const CommandSchemas = (
937   - transportType: TransportTypeEnum,
938   - deviceProfileId: string
939   -): FormSchema[] => {
940   - return [
941   - {
942   - field: CommandFieldsEnum.COMMAND_TYPE,
943   - component: 'RadioGroup',
944   - label: '下发类型',
945   - defaultValue: CommandType.CUSTOM,
946   - componentProps: ({ formActionType }) => {
947   - const { setFieldsValue } = formActionType;
948   - return {
949   - options: [
950   - { label: '自定义', value: CommandType.CUSTOM },
951   - { label: '服务', value: CommandType.SERVICE },
952   - ],
953   - onChange() {
954   - setFieldsValue({
955   - [CommandFieldsEnum.SERVICE]: null,
956   - [CommandFieldsEnum.MODEL_INPUT]: null,
957   - [CommandFieldsEnum.COMAND_VALUE]: null,
958   - [CommandFieldsEnum.COMMAND_TEXT]: null,
959   - });
960   - },
961   - };
962   - },
963   - },
964   - {
965   - field: CommandFieldsEnum.CUSTOM_TYPE,
966   - component: 'RadioGroup',
967   - label: '单向/双向',
968   - defaultValue: CommandDeliveryWayEnum.ONE_WAY,
969   - ifShow: ({ model }) => model[CommandFieldsEnum.COMMAND_TYPE] === CommandType.CUSTOM,
970   - componentProps: {
971   - options: [
972   - {
973   - label: '单向',
974   - value: CommandDeliveryWayEnum.ONE_WAY,
975   - },
976   - {
977   - label: '双向',
978   - value: CommandDeliveryWayEnum.TWO_WAY,
979   - },
980   - ],
981   - },
982   - },
983   - {
984   - field: CommandFieldsEnum.VALUE_TYPE,
985   - label: '命令类型',
986   - component: 'RadioGroup',
987   - ifShow: ({ model }) => model[CommandFieldsEnum.COMMAND_TYPE] === CommandType.CUSTOM,
988   - defaultValue: transportType === TransportTypeEnum.TCP ? ValueType.STRING : ValueType.JSON,
989   - componentProps: () => {
990   - const options: Record<'label' | 'value', string>[] = [];
991   - if (transportType === TransportTypeEnum.TCP) {
992   - options.push({ label: '字符串', value: ValueType.STRING });
993   - } else {
994   - options.push({ label: 'JSON', value: ValueType.JSON });
995   - }
996   - return {
997   - options,
998   - };
999   - },
1000   - },
1001   - {
1002   - field: CommandFieldsEnum.COMMAND_TEXT,
1003   - label: '命令',
1004   - ifShow: ({ model }) =>
1005   - model[CommandFieldsEnum.VALUE_TYPE] === ValueType.STRING &&
1006   - model[CommandFieldsEnum.COMMAND_TYPE] === CommandType.CUSTOM,
1007   - component: 'InputTextArea',
1008   - componentProps: {
1009   - autoSize: {
1010   - minRows: 3,
1011   - },
1012   - placeholder: '请输入命令内容',
1013   - },
1014   - dynamicRules: () => {
1015   - return [
1016   - {
1017   - required: false,
1018   - validator: (_, value) => {
1019   - const zg = /^[0-9a-zA-Z]*$/;
1020   - if (!zg.test(value)) {
1021   - return Promise.reject('输入的内容只能是字母和数字的组合');
1022   - } else {
1023   - return Promise.resolve();
1024   - }
1025   - },
1026   - },
1027   - ];
1028   - },
1029   - },
1030   - {
1031   - field: CommandFieldsEnum.COMAND_VALUE,
1032   - label: '命令',
1033   - component: 'JSONEditor',
1034   - colProps: { span: 20 },
1035   - changeEvent: 'update:value',
1036   - valueField: 'value',
1037   - rules: [...JSONEditorValidator()],
1038   - ifShow: ({ model }) =>
1039   - model[CommandFieldsEnum.VALUE_TYPE] === ValueType.JSON &&
1040   - model[CommandFieldsEnum.COMMAND_TYPE] === CommandType.CUSTOM,
1041   -
1042   - componentProps: {
1043   - height: 250,
1044   - },
1045   - },
1046   - {
1047   - field: CommandFieldsEnum.SERVICE,
1048   - label: '服务',
1049   - component: 'ApiSelect',
1050   - ifShow: ({ model }) => model[CommandFieldsEnum.COMMAND_TYPE] !== CommandType.CUSTOM,
1051   - rules: [{ required: true, message: '请选择服务' }],
1052   - componentProps: ({ formActionType }) => {
1053   - const { setFieldsValue, updateSchema } = formActionType;
1054   - return {
1055   - api: async () => {
1056   - try {
1057   - const result = await getModelServices({ deviceProfileId });
1058   - return result || [];
1059   - } catch (error) {
1060   - return [];
1061   - }
1062   - },
1063   - valueField: 'identifier',
1064   - labelField: 'functionName',
1065   - getPopupContainer: () => document.body,
1066   - onChange(value: string, options: ModelOfMatterParams) {
1067   - if (!value) return;
1068   -
1069   - const setValues = {
1070   - [CommandFieldsEnum.CUSTOM_TYPE]:
1071   - options.callType === ServiceCallTypeEnum.ASYNC
1072   - ? CommandDeliveryWayEnum.ONE_WAY
1073   - : CommandDeliveryWayEnum.TWO_WAY,
1074   - [CommandFieldsEnum.MODEL_INPUT]: null,
1075   - };
1076   -
1077   - if (transportType !== TransportTypeEnum.TCP) {
1078   - updateSchema({
1079   - field: CommandFieldsEnum.MODEL_INPUT,
1080   - componentProps: {
1081   - inputData: toRaw(unref(options.functionJson.inputData)),
1082   - },
1083   - });
1084   - } else {
1085   - Object.assign(setValues, {
1086   - [CommandFieldsEnum.TCP_SERVICE]:
1087   - options.functionJson?.inputData?.[0]?.serviceCommand,
1088   - });
1089   - }
1090   -
1091   - setFieldsValue(setValues);
1092   - },
1093   - };
1094   - },
1095   - },
1096   - {
1097   - field: CommandFieldsEnum.TCP_SERVICE,
1098   - component: 'Input',
1099   - label: '命令',
1100   - dynamicDisabled: true,
1101   - ifShow: ({ model }) =>
1102   - model[CommandFieldsEnum.SERVICE] &&
1103   - transportType === TransportTypeEnum.TCP &&
1104   - model[CommandFieldsEnum.COMMAND_TYPE] !== CommandType.CUSTOM,
1105   - },
1106   - {
1107   - field: CommandFieldsEnum.MODEL_INPUT,
1108   - component: 'ObjectModelValidateForm',
1109   - label: '输入参数',
1110   - changeEvent: 'update:value',
1111   - valueField: 'value',
1112   - ifShow: ({ model }) =>
1113   - model[CommandFieldsEnum.SERVICE] &&
1114   - transportType !== TransportTypeEnum.TCP &&
1115   - model[CommandFieldsEnum.COMMAND_TYPE] !== CommandType.CUSTOM,
1116   - componentProps: {
1117   - formProps: {
1118   - wrapperCol: { span: 24 },
1119   - } as FormProps,
1120   - },
1121   - },
1122   - ];
1123   -};
... ...
... ... @@ -5,8 +5,8 @@ import { DeviceRecord, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
5 5 import { findDictItemByCode } from '/@/api/system/dict';
6 6 import { FormSchema, useComponentRegister } from '/@/components/Form';
7 7 import { BasicColumn } from '/@/components/Table';
  8 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
8 9 import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
9   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
10 10 import XLSX, { CellObject } from 'xlsx';
11 11
12 12 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
... ...
  1 +import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
  2 +import { getModelServices } from '/@/api/device/modelOfMatter';
  3 +import { FormProps, FormSchema, useComponentRegister } from '/@/components/Form';
  4 +import { validateTCPCustomCommand } from '/@/components/Form/src/components/ThingsModelForm';
  5 +import { JSONEditor, JSONEditorValidator } from '/@/components/CodeEditor';
  6 +import {
  7 + TransportTypeEnum,
  8 + CommandTypeNameEnum,
  9 + CommandTypeEnum,
  10 + ServiceCallTypeEnum,
  11 + CommandDeliveryWayEnum,
  12 + CommandDeliveryWayNameEnum,
  13 +} from '/@/enums/deviceEnum';
  14 +
  15 +export interface CommandDeliveryFormFieldType {
  16 + [CommandFieldsEnum.COMMAND_TYPE]: CommandTypeEnum;
  17 + [CommandFieldsEnum.TCP_COMMAND_VALUE]?: string;
  18 + [CommandFieldsEnum.COMAND_VALUE]?: string;
  19 + [CommandFieldsEnum.SERVICE]?: string;
  20 + [CommandFieldsEnum.MODEL_INPUT]?: ModelOfMatterParams;
  21 + [CommandFieldsEnum.CALL_TYPE]: CommandDeliveryWayEnum;
  22 +}
  23 +
  24 +export enum CommandFieldsEnum {
  25 + COMMAND_TYPE = 'commandType',
  26 + TCP_COMMAND_VALUE = 'tcpCommandValue',
  27 + COMAND_VALUE = 'commandValue',
  28 + SERVICE = 'service',
  29 + MODEL_INPUT = 'modelInput',
  30 + CALL_TYPE = 'callType',
  31 +
  32 + SERVICE_COMMAND = 'serviceCommand',
  33 +
  34 + SERVICE_OBJECT_MODEL = 'serviceObjectModel',
  35 +}
  36 +
  37 +useComponentRegister('JSONEditor', JSONEditor);
  38 +
  39 +export const CommandSchemas = (
  40 + transportType: TransportTypeEnum,
  41 + deviceProfileId: string
  42 +): FormSchema[] => {
  43 + return [
  44 + {
  45 + field: CommandFieldsEnum.COMMAND_TYPE,
  46 + component: 'RadioGroup',
  47 + label: '下发类型',
  48 + defaultValue: CommandTypeEnum.CUSTOM,
  49 + required: true,
  50 + componentProps: ({ formActionType }) => {
  51 + const { setFieldsValue } = formActionType;
  52 + return {
  53 + options: [
  54 + { label: CommandTypeNameEnum.CUSTOM, value: CommandTypeEnum.CUSTOM },
  55 + { label: CommandTypeNameEnum.SERVICE, value: CommandTypeEnum.SERVICE },
  56 + ],
  57 + onChange() {
  58 + setFieldsValue({
  59 + [CommandFieldsEnum.SERVICE]: null,
  60 + [CommandFieldsEnum.MODEL_INPUT]: null,
  61 + [CommandFieldsEnum.COMAND_VALUE]: null,
  62 + [CommandFieldsEnum.TCP_COMMAND_VALUE]: null,
  63 + });
  64 + },
  65 + };
  66 + },
  67 + },
  68 + {
  69 + field: CommandFieldsEnum.CALL_TYPE,
  70 + component: 'RadioGroup',
  71 + label: '单向/双向',
  72 + required: true,
  73 + defaultValue: CommandDeliveryWayEnum.ONE_WAY,
  74 + ifShow: ({ model }) => model[CommandFieldsEnum.COMMAND_TYPE] === CommandTypeEnum.CUSTOM,
  75 + componentProps: {
  76 + options: Object.keys(CommandDeliveryWayEnum).map((key) => ({
  77 + label: CommandDeliveryWayNameEnum[key],
  78 + value: CommandDeliveryWayEnum[key],
  79 + })),
  80 + },
  81 + },
  82 + {
  83 + field: CommandFieldsEnum.TCP_COMMAND_VALUE,
  84 + label: '命令',
  85 + required: true,
  86 + ifShow: ({ model }) =>
  87 + transportType === TransportTypeEnum.TCP &&
  88 + model[CommandFieldsEnum.COMMAND_TYPE] === CommandTypeEnum.CUSTOM,
  89 + component: 'Input',
  90 + rules: [{ validator: validateTCPCustomCommand }],
  91 + componentProps: {
  92 + placeholder: '请输入命令',
  93 + },
  94 + },
  95 + {
  96 + field: CommandFieldsEnum.COMAND_VALUE,
  97 + label: '命令',
  98 + component: 'JSONEditor',
  99 + colProps: { span: 20 },
  100 + changeEvent: 'update:value',
  101 + valueField: 'value',
  102 + required: true,
  103 + rules: JSONEditorValidator(),
  104 + ifShow: ({ model }) =>
  105 + transportType !== TransportTypeEnum.TCP &&
  106 + model[CommandFieldsEnum.COMMAND_TYPE] === CommandTypeEnum.CUSTOM,
  107 + componentProps: {
  108 + height: 250,
  109 + },
  110 + },
  111 + {
  112 + field: CommandFieldsEnum.SERVICE,
  113 + label: '服务',
  114 + component: 'ApiSelect',
  115 + required: true,
  116 + ifShow: ({ model }) => model[CommandFieldsEnum.COMMAND_TYPE] !== CommandTypeEnum.CUSTOM,
  117 + rules: [{ required: true, message: '请选择服务' }],
  118 + componentProps: ({ formActionType }) => {
  119 + const { setFieldsValue } = formActionType;
  120 + return {
  121 + api: getModelServices,
  122 + params: {
  123 + deviceProfileId,
  124 + },
  125 + valueField: 'identifier',
  126 + labelField: 'functionName',
  127 + getPopupContainer: () => document.body,
  128 + placeholder: '请选择服务',
  129 + onChange(
  130 + value: string,
  131 + options: ModelOfMatterParams & Record<'label' | 'value', string>
  132 + ) {
  133 + if (!value) return;
  134 + setFieldsValue({
  135 + [CommandFieldsEnum.CALL_TYPE]:
  136 + options.callType === ServiceCallTypeEnum.ASYNC
  137 + ? CommandDeliveryWayEnum.ONE_WAY
  138 + : CommandDeliveryWayEnum.TWO_WAY,
  139 + [CommandFieldsEnum.MODEL_INPUT]: null,
  140 + [CommandFieldsEnum.SERVICE_OBJECT_MODEL]: Object.assign(options, {
  141 + functionName: options.label,
  142 + identifier: options.value,
  143 + }),
  144 + });
  145 + },
  146 + };
  147 + },
  148 + },
  149 + {
  150 + field: CommandFieldsEnum.SERVICE_OBJECT_MODEL,
  151 + label: '服务物模型',
  152 + component: 'Input',
  153 + ifShow: false,
  154 + },
  155 + {
  156 + field: CommandFieldsEnum.MODEL_INPUT,
  157 + component: 'Input',
  158 + label: '输入参数',
  159 + changeEvent: 'update:value',
  160 + valueField: 'value',
  161 + ifShow: ({ model }) =>
  162 + model[CommandFieldsEnum.SERVICE] &&
  163 + model[CommandFieldsEnum.SERVICE_OBJECT_MODEL] &&
  164 + model[CommandFieldsEnum.COMMAND_TYPE] !== CommandTypeEnum.CUSTOM,
  165 + componentProps: {
  166 + formProps: {
  167 + wrapperCol: { span: 24 },
  168 + } as FormProps,
  169 + },
  170 + slot: 'serviceCommand',
  171 + },
  172 + ];
  173 +};
... ...
  1 +export { default as CommandDeliveryModal } from './index.vue';
... ...
  1 +<template>
  2 + <BasicModal
  3 + title="命令下发"
  4 + :width="650"
  5 + @register="registerModal"
  6 + @ok="handleOk"
  7 + @cancel="handleCancel"
  8 + >
  9 + <BasicForm @register="registerForm">
  10 + <template #serviceCommand="{ field, model }">
  11 + <ThingsModelForm
  12 + :disabled="deviceDetail?.transportType === TransportTypeEnum.TCP"
  13 + ref="thingsModelFormRef"
  14 + v-model:value="model[field]"
  15 + :key="model[CommandFieldsEnum.SERVICE_OBJECT_MODEL]?.identifier"
  16 + :inputData="model[CommandFieldsEnum.SERVICE_OBJECT_MODEL]?.functionJson?.inputData"
  17 + :transportType="deviceDetail?.transportType"
  18 + />
  19 + </template>
  20 + </BasicForm>
  21 + </BasicModal>
  22 +</template>
  23 +<script lang="ts" setup>
  24 + import { nextTick, ref, unref } from 'vue';
  25 + import { BasicForm, ThingsModelForm, useForm } from '/@/components/Form';
  26 + import { CommandDeliveryFormFieldType, CommandFieldsEnum, CommandSchemas } from './config';
  27 + import { useMessage } from '/@/hooks/web/useMessage';
  28 + import { DeviceRecord } from '/@/api/device/model/deviceModel';
  29 + import { CommandDeliveryWayEnum } from '/@/enums/deviceEnum';
  30 + import { CommandTypeEnum, RPCCommandMethodEnum, TransportTypeEnum } from '/@/enums/deviceEnum';
  31 + import { BasicModal, useModalInner } from '/@/components/Modal';
  32 + import { getDeviceActiveTime } from '/@/api/alarm/position';
  33 + import { RpcCommandType } from '/@/api/device/model/deviceConfigModel';
  34 + import { parseStringToJSON } from '/@/components/CodeEditor';
  35 + import { commandIssuanceApi } from '/@/api/device/deviceManager';
  36 +
  37 + defineEmits(['register']);
  38 +
  39 + const thingsModelFormRef = ref<InstanceType<typeof ThingsModelForm>>();
  40 + const deviceDetail = ref<DeviceRecord>();
  41 +
  42 + const [registerModal, { setModalProps }] = useModalInner(
  43 + (params: ModalParamsType<DeviceRecord>) => {
  44 + const { record } = params;
  45 + deviceDetail.value = record;
  46 + setProps({
  47 + schemas: CommandSchemas(record.transportType as TransportTypeEnum, record.deviceProfileId),
  48 + });
  49 + }
  50 + );
  51 +
  52 + const { createMessage } = useMessage();
  53 +
  54 + const [registerForm, { setProps, getFieldsValue, validate, resetFields, clearValidate }] =
  55 + useForm({
  56 + labelWidth: 120,
  57 + baseColProps: { span: 20 },
  58 + labelAlign: 'right',
  59 + showSubmitButton: false,
  60 + showResetButton: false,
  61 + });
  62 +
  63 + const handleCancel = async () => {
  64 + await resetFields();
  65 + await nextTick();
  66 + await clearValidate();
  67 + };
  68 +
  69 + const handleValidate = async () => {
  70 + await validate();
  71 + await unref(thingsModelFormRef)?.validate?.();
  72 + };
  73 +
  74 + const handleValidateDeviceActive = async (): Promise<boolean> => {
  75 + const result = await getDeviceActiveTime(unref(deviceDetail)!.tbDeviceId);
  76 + const [firstItem] = result;
  77 + return !!firstItem.value;
  78 + };
  79 +
  80 + const handleCommandParams = (
  81 + values: CommandDeliveryFormFieldType,
  82 + serviceCommand: Recordable
  83 + ) => {
  84 + const { commandType } = values;
  85 +
  86 + const isTcpDevice = unref(deviceDetail)?.transportType === TransportTypeEnum.TCP;
  87 + if (commandType === CommandTypeEnum.CUSTOM) {
  88 + if (isTcpDevice) {
  89 + return values.tcpCommandValue;
  90 + }
  91 + return parseStringToJSON(values.commandValue!).json;
  92 + } else {
  93 + if (isTcpDevice) return Reflect.get(serviceCommand, CommandFieldsEnum.SERVICE_COMMAND);
  94 + return serviceCommand;
  95 + }
  96 + };
  97 +
  98 + const handleOk = async () => {
  99 + await handleValidate();
  100 +
  101 + try {
  102 + setModalProps({ loading: true, confirmLoading: true });
  103 +
  104 + const values = getFieldsValue() as CommandDeliveryFormFieldType;
  105 + const { callType, commandType } = values;
  106 + const serviceCommand = unref(thingsModelFormRef)?.getFieldsValue() || {};
  107 +
  108 + if (callType === CommandDeliveryWayEnum.TWO_WAY && !(await handleValidateDeviceActive())) {
  109 + createMessage.warn('当前设备不在线');
  110 + return;
  111 + }
  112 +
  113 + const rpcCommands: RpcCommandType = {
  114 + additionalInfo: {
  115 + cmdType:
  116 + commandType === CommandTypeEnum.CUSTOM
  117 + ? CommandTypeEnum.CUSTOM
  118 + : CommandTypeEnum.SERVICE,
  119 + },
  120 + method: RPCCommandMethodEnum.THINGSKIT,
  121 + persistent: true,
  122 + params: handleCommandParams(values, serviceCommand),
  123 + };
  124 +
  125 + await commandIssuanceApi(callType, unref(deviceDetail)!.tbDeviceId, rpcCommands);
  126 +
  127 + createMessage.success('命令下发成功');
  128 + } finally {
  129 + setModalProps({ loading: false, confirmLoading: false });
  130 + }
  131 + };
  132 +</script>
  133 +<style scoped lang="less"></style>
... ...
1   -<template>
2   - <div class="tabs-detail">
3   - <div>
4   - <BasicForm @register="registerForm" />
5   - <Space class="w-full justify-end py-2" justify="end">
6   - <Button :loading="loading" type="primary" @click="handleOk" class="mr-2">确定</Button>
7   - <Button type="default" @click="handleCancel" class="mr-2">重置</Button>
8   - </Space>
9   - </div>
10   - </div>
11   -</template>
12   -<script lang="ts">
13   - import { defineComponent, nextTick, ref } from 'vue';
14   - import { BasicForm, useForm } from '/@/components/Form';
15   - import { CommandFieldsEnum, CommandSchemas, CommandType, ValueType } from '../../config/data';
16   - import { commandIssuanceApi } from '/@/api/device/deviceManager';
17   - import { useMessage } from '/@/hooks/web/useMessage';
18   - import { Button } from '/@/components/Button';
19   - import { Space } from 'ant-design-vue';
20   - import { DeviceRecord } from '/@/api/device/model/deviceModel';
21   - import { TransportTypeEnum } from '../../../profiles/components/TransportDescript/const';
22   - import { parseStringToJSON } from '/@/components/CodeEditor/src/JSONEditor';
23   - import { CommandDeliveryWayEnum } from '/@/enums/toolEnum';
24   -
25   - export default defineComponent({
26   - components: { BasicForm, Button, Space },
27   - props: {
28   - deviceDetail: {
29   - type: Object as PropType<DeviceRecord>,
30   - required: true,
31   - },
32   - },
33   - emits: ['register'],
34   - setup(props) {
35   - const { createMessage } = useMessage();
36   - const loading = ref(false);
37   -
38   - const [registerForm, { getFieldsValue, validate, resetFields, clearValidate }] = useForm({
39   - labelWidth: 120,
40   - schemas: CommandSchemas(
41   - props.deviceDetail.deviceProfile.transportType as TransportTypeEnum,
42   - props.deviceDetail.deviceProfileId
43   - ),
44   - baseColProps: { span: 20 },
45   - labelAlign: 'right',
46   - showSubmitButton: false,
47   - showResetButton: false,
48   - });
49   -
50   - const handleCancel = async () => {
51   - await resetFields();
52   - await nextTick();
53   - await clearValidate();
54   - };
55   -
56   - const handleOk = async () => {
57   - loading.value = true;
58   - try {
59   - // 验证
60   - const valid = await validate();
61   - if (!valid) return;
62   - // 收集表单数据
63   - const field = getFieldsValue();
64   - let command: Recordable = {
65   - persistent: true,
66   - method: 'methodThingskit',
67   - params: field[CommandFieldsEnum.COMMAND_TEXT],
68   - };
69   -
70   - if (field[CommandFieldsEnum.COMMAND_TYPE] === CommandType.CUSTOM) {
71   - if (field[CommandFieldsEnum.VALUE_TYPE] === ValueType.JSON) {
72   - const { json } = parseStringToJSON(field.commandValue);
73   - command.params = json;
74   - }
75   - } else {
76   - const { transportType } = props.deviceDetail.deviceProfile;
77   - command.params =
78   - transportType === TransportTypeEnum.TCP
79   - ? field[CommandFieldsEnum.TCP_SERVICE]
80   - : {
81   - [field[CommandFieldsEnum.SERVICE]]: field[CommandFieldsEnum.MODEL_INPUT],
82   - };
83   - command.additionalInfo = { cmdType: 1 };
84   - }
85   - commandIssuanceApi(
86   - field[CommandFieldsEnum.CUSTOM_TYPE] as CommandDeliveryWayEnum,
87   - props.deviceDetail.tbDeviceId,
88   - command
89   - )
90   - .then((res) => {
91   - if (!res) return;
92   - createMessage.success('命令下发成功');
93   - loading.value = true;
94   - // 请求
95   - handleCancel();
96   - })
97   - .catch((e) => {
98   - if (e?.message) {
99   - createMessage.error(e?.message);
100   - }
101   - handleCancel();
102   - })
103   - .finally(() => {
104   - setTimeout(() => {
105   - loading.value = false;
106   - }, 300);
107   - });
108   - } catch (e) {
109   - throw e;
110   - } finally {
111   - loading.value = false;
112   - }
113   - };
114   - return {
115   - registerForm,
116   - handleCancel,
117   - handleOk,
118   - loading,
119   - };
120   - },
121   - });
122   -</script>
123   -<style scoped lang="less">
124   - .jsoneditor-transform {
125   - background-position: -144px -96px;
126   - display: none !important;
127   - }
128   -
129   - .tabs-detail:deep(.object-model-validate-form) {
130   - > .ant-row {
131   - @apply w-full;
132   - }
133   - }
134   -</style>
... ... @@ -18,7 +18,8 @@
18 18 import { useGlobSetting } from '/@/hooks/setting';
19 19 import { ModeSwitchButton, EnumTableCardMode } from '/@/components/Widget';
20 20 import { toRaw } from 'vue';
21   - import { DataActionModeEnum, ReadAndWriteEnum } from '/@/enums/toolEnum';
  21 + import { DataActionModeEnum } from '/@/enums/toolEnum';
  22 + import { ReadAndWriteEnum } from '/@/enums/deviceEnum';
22 23 import { ObjectModelCommandDeliveryModal } from './ObjectModelCommandDeliveryModal';
23 24 import { ModalParamsType } from '/#/utils';
24 25 import { AreaChartOutlined } from '@ant-design/icons-vue';
... ...
1 1 import { StructJSON } from '/@/api/device/model/modelOfMatterModel';
2 2 import { FormSchema } from '/@/components/Form';
3   -import { validateTCPCustomCommand } from '/@/components/Form/src/externalCompns/components/ThingsModelForm';
  3 +import { validateTCPCustomCommand } from '/@/components/Form/src/components/ThingsModelForm';
4 4 import { DataTypeEnum } from '/@/enums/objectModelEnum';
5 5
6 6 const InsertString = (t, c, n) => {
... ...
... ... @@ -12,8 +12,8 @@
12 12 import { genModbusCommand } from '/@/api/task';
13 13 import { TaskTypeEnum } from '/@/views/task/center/config';
14 14 import { SingleToHex, formSchemasConfig } from './config';
15   - import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
16 15 import { DataTypeEnum } from '/@/enums/objectModelEnum';
  16 + import { TransportTypeEnum } from '/@/enums/deviceEnum';
17 17
18 18 defineEmits(['register']);
19 19 const props = defineProps<{ deviceId: string; deviceName: string }>();
... ...
... ... @@ -6,7 +6,7 @@
6 6 <template #toolbar>
7 7 <Space>
8 8 <Authority value="api:yt:device:rpc">
9   - <Button type="primary" @click="openModal(true)">命令下发</Button>
  9 + <Button type="primary" @click="handleOpenModal">命令下发</Button>
10 10 </Authority>
11 11 </Space>
12 12 </template>
... ... @@ -24,16 +24,7 @@
24 24 </template>
25 25 </BasicTable>
26 26
27   - <BasicModal
28   - @register="registerCommandIssuanceModal"
29   - width="700px"
30   - title="命令下发"
31   - :showOkBtn="false"
32   - cancelText="关闭"
33   - :footer="null"
34   - >
35   - <CommandIssuance :deviceDetail="deviceDetail" />
36   - </BasicModal>
  27 + <CommandDeliveryModal @register="registerCommandDeliverModal" :deviceDetail="deviceDetail" />
37 28 </template>
38 29 <script lang="ts" setup>
39 30 import { h } from 'vue';
... ... @@ -43,9 +34,10 @@
43 34 import { Button, Modal, Space } from 'ant-design-vue';
44 35 import { JsonPreview } from '/@/components/CodeEditor';
45 36 import { DeviceRecord } from '/@/api/device/model/deviceModel';
46   - import { BasicModal, useModal } from '/@/components/Modal';
47   - import CommandIssuance from '../CommandIssuance.vue';
  37 + import { useModal } from '/@/components/Modal';
  38 + import { CommandDeliveryModal } from '../CommandDeliveryModal';
48 39 import { Authority } from '/@/components/Authority';
  40 + import { DataActionModeEnum } from '/@/enums/toolEnum';
49 41
50 42 const props = defineProps({
51 43 fromId: {
... ... @@ -58,7 +50,7 @@
58 50 },
59 51 });
60 52
61   - const [registerCommandIssuanceModal, { openModal }] = useModal();
  53 + const [registerCommandDeliverModal, { openModal }] = useModal();
62 54
63 55 const [registerTable] = useTable({
64 56 api: deviceCommandRecordGetQuery,
... ... @@ -79,6 +71,7 @@
79 71 },
80 72 useSearchForm: true,
81 73 });
  74 +
82 75 const commonModalInfo = (title, value) => {
83 76 Modal.info({
84 77 title,
... ... @@ -86,14 +79,23 @@
86 79 content: h(JsonPreview, { data: value }),
87 80 });
88 81 };
  82 +
89 83 const handleRecordContent = (record) => {
90 84 if (!record?.request?.body) return;
91 85 if (Object.prototype.toString.call(record?.request?.body) !== '[object Object]') return;
92 86 const jsonParams = record?.request?.body?.params;
93 87 commonModalInfo('命令下发内容', jsonParams);
94 88 };
  89 +
95 90 const handleRecordResponseContent = (record) => {
96 91 const jsonParams = record?.response;
97 92 commonModalInfo('响应内容', jsonParams);
98 93 };
  94 +
  95 + function handleOpenModal() {
  96 + openModal(true, {
  97 + mode: DataActionModeEnum.READ,
  98 + record: props.deviceDetail,
  99 + } as ModalParamsType<DeviceRecord>);
  100 + }
99 101 </script>
... ...
1 1 <script lang="ts" setup>
2 2 import { computed } from 'vue';
3 3 import COAPDescription from './COAPDescription.vue';
4   - import { TransportTypeEnum } from './const';
5 4 import DefaultConfiguration from './DefaultConfiguration.vue';
6 5 import LWM2MDescription from './LWM2MDescription.vue';
7 6 import MQTTConfiguration from './MQTTConfiguration.vue';
8 7 import SNMPDescription from './SNMPDescription.vue';
9 8 import TCPDescription from './TCPDescription.vue';
10 9 import { DeviceRecord } from '/@/api/device/model/deviceModel';
  10 + import { TransportTypeEnum } from '/@/enums/deviceEnum';
11 11
12 12 const props = defineProps<{
13 13 record: DeviceRecord;
... ...
1   -export enum TransportTypeEnum {
2   - DEFAULT = 'DEFAULT',
3   - MQTT = 'MQTT',
4   - COAP = 'COAP',
5   - LWM2M = 'LWM2M',
6   - SNMP = 'SNMP',
7   - TCP = 'TCP',
8   -}
9   -
10 1 export enum TransportPayloadTypeEnum {
11 2 PROTOBUF = 'PROTOBUF',
12 3 JSON = 'JSON',
... ...
1 1 <script lang="ts" setup>
2 2 import { BasicForm, useForm } from '/@/components/Form';
3 3 import { DataType, ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
4   - import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type';
  4 + import { StructFormValue } from '/@/components/Form/src/components/StructForm/type';
5 5 import {
6 6 transfromToStructJSON,
7 7 excludeIdInStructJSON,
8   - } from '/@/components/Form/src/externalCompns/components/StructForm/util';
  8 + } from '/@/components/Form/src/components/StructForm/util';
9 9 import { FunctionType } from './config';
10 10 import { isArray } from 'lodash';
11 11 import { OpenModelMode } from '../types';
12   - import { formSchemas } from '/@/components/Form/src/externalCompns/components/StructForm/config';
13   - import { TransportTypeEnum } from '../../../../components/TransportDescript/const';
  12 + import { formSchemas } from '/@/components/Form/src/components/StructForm/config';
14 13 import { DataTypeEnum } from '/@/enums/objectModelEnum';
15 14 import { ref, unref } from 'vue';
16   - import EnumList from '/@/components/Form/src/externalCompns/components/StructForm/EnumList.vue';
  15 + import EnumList from '/@/components/Form/src/components/StructForm/EnumList.vue';
  16 + import { TransportTypeEnum } from '/@/enums/deviceEnum';
17 17
18 18 const props = defineProps<{ openModalMode: OpenModelMode; transportType?: string | undefined }>();
19 19
... ...
... ... @@ -5,8 +5,8 @@
5 5 import { BasicForm, useForm } from '/@/components/Form';
6 6 import { eventSchemas, FunctionType } from './config';
7 7 import { ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel';
8   - import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type';
9   - import { excludeIdInStructJSON } from '/@/components/Form/src/externalCompns/components/StructForm/util';
  8 + import { StructFormValue } from '/@/components/Form/src/components/StructForm/type';
  9 + import { excludeIdInStructJSON } from '/@/components/Form/src/components/StructForm/util';
10 10 import { OpenModelMode } from '../types';
11 11
12 12 defineProps<{ openModalMode: OpenModelMode }>();
... ...
... ... @@ -5,10 +5,10 @@
5 5 import { BasicForm, useForm } from '/@/components/Form';
6 6 import { FormField, serviceSchemas } from './config';
7 7 import { FunctionType } from './config';
8   - import { StructFormValue } from '/@/components/Form/src/externalCompns/components/StructForm/type';
  8 + import { StructFormValue } from '/@/components/Form/src/components/StructForm/type';
9 9 import { ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel';
10 10 import { DeviceRecord } from '/@/api/device/model/deviceModel';
11   - import { excludeIdInStructJSON } from '/@/components/Form/src/externalCompns/components/StructForm/util';
  11 + import { excludeIdInStructJSON } from '/@/components/Form/src/components/StructForm/util';
12 12 import { OpenModelMode } from '../types';
13 13 import { isArray } from '/@/utils/is';
14 14 import { DataTypeEnum } from '/@/enums/objectModelEnum';
... ...
1 1 import { FormSchema, useComponentRegister } from '/@/components/Form';
2 2 import {
3   - CommandTypeEnum,
4   - CommandTypeNameEnum,
5 3 ExecutionActionEnum,
6 4 ExecutionActionNameEnum,
7 5 TriggerEntityTypeEnum,
8 6 TriggerEntityTypeNameEnum,
9 7 } from '/@/enums/linkedgeEnum';
  8 +import { CommandTypeEnum, CommandTypeNameEnum } from '/@/enums/deviceEnum';
10 9 import AlarmProfileSelect from './AlarmProfileSelect.vue';
11 10 import {
12 11 byOrganizationIdGetMasterDevice,
... ... @@ -21,15 +20,15 @@ import { findDictItemByCode } from '/@/api/system/dict';
21 20 import { DictEnum } from '/@/enums/dictEnum';
22 21 import { getDeviceProfile } from '/@/api/alarm/position';
23 22 import { createPickerSearch } from '/@/utils/pickerSearch';
24   -import { ServiceCallTypeEnum, ServiceCallTypeNameEnum } from '/@/enums/toolEnum';
  23 +import { ServiceCallTypeEnum, ServiceCallTypeNameEnum } from '/@/enums/deviceEnum';
25 24 import { DeviceTypeEnum } from '../../../dataFlow/cpns/config';
26 25 import { getModelServices } from '/@/api/device/modelOfMatter';
27 26 import { ModelOfMatterParams, StructJSON } from '/@/api/device/model/modelOfMatterModel';
28 27 import { DeviceProfileModel } from '/@/api/device/model/deviceModel';
29   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
30 28 import { JSONEditor } from '/@/components/CodeEditor';
31 29 import { useJsonParse } from '/@/hooks/business/useJsonParse';
32   -import { validateTCPCustomCommand } from '/@/components/Form/src/externalCompns/components/ThingsModelForm';
  30 +import { validateTCPCustomCommand } from '/@/components/Form/src/components/ThingsModelForm';
  31 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
33 32
34 33 export enum FormFieldsEnum {
35 34 OUT_TARGET = 'outTarget',
... ...
... ... @@ -5,9 +5,9 @@ import { FlipFlopConditionType } from '../FlipFlop/types';
5 5 import { DeviceModelOfMatterAttrs, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
6 6 import { FormActionType, ThingsModelForm } from '/@/components/Form';
7 7 import { AlarmLevelEnum } from '/@/enums/alarmEnum';
8   -import { CommandTypeEnum, ExecutionActionEnum, TriggerEntityTypeEnum } from '/@/enums/linkedgeEnum';
9   -import { ServiceCallTypeEnum } from '/@/enums/toolEnum';
10   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
  8 +import { ExecutionActionEnum, TriggerEntityTypeEnum } from '/@/enums/linkedgeEnum';
  9 +import { CommandTypeEnum, ServiceCallTypeEnum } from '/@/enums/deviceEnum';
  10 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
11 11
12 12 export interface ExecutionActionListRefItemType {
13 13 key: string;
... ...
... ... @@ -7,12 +7,13 @@ import {
7 7 ExecutionActionFormItemRecordType,
8 8 ExecutionActionListRefItemType,
9 9 } from './type';
10   -import { CommandTypeEnum, ExecutionActionEnum } from '/@/enums/linkedgeEnum';
11   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
  10 +import { ExecutionActionEnum } from '/@/enums/linkedgeEnum';
  11 +import { CommandTypeEnum } from '/@/enums/deviceEnum';
12 12 import { useJsonParse } from '/@/hooks/business/useJsonParse';
13 13 import { createNewExecutionActionItem } from '.';
14 14 import { FormFieldsEnum } from './config';
15 15 import { isObject, isString } from '/@/utils/is';
  16 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
16 17
17 18 export function useExecutionActionData(
18 19 executionActionListRef: Ref<ExecutionActionListRefItemType[]>,
... ...
... ... @@ -29,9 +29,9 @@ import { DataTypeEnum } from '/@/enums/objectModelEnum';
29 29 import { getModelTsl } from '/@/api/device/modelOfMatter';
30 30 import { FunctionType } from '/@/views/device/profiles/step/cpns/physical/cpns/config';
31 31 import { GetModelTslParams } from '/@/api/device/model/modelOfMatterModel';
32   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
33 32 import { FlipFlopComponentTypeEnum } from './types';
34 33 import { OptionsType } from 'ant-design-vue/es/vc-select/interface';
  34 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
35 35
36 36 export enum FormFieldEnum {
37 37 FLIP_FLOP_TYPE = 'flipFlopType',
... ...
1   -import { ref, unref } from 'vue';
  1 +import { ref } from 'vue';
2 2 import { BasicColumn, FormSchema } from '/@/components/Table';
3   -import {
4   - byOrganizationIdGetMasterDevice,
5   - screenLinkOrganizationGetApi,
6   - getAttribute,
7   -} from '/@/api/ruleengine/ruleengineApi';
8   -import { scheduleOptions } from './formatData';
  3 +import { screenLinkOrganizationGetApi } from '/@/api/ruleengine/ruleengineApi';
9 4 import { copyTransFun } from '/@/utils/fnUtils';
10   -import { numberAndNonegativeRule } from '/@/utils/rules';
11   -import { findDictItemByCode } from '/@/api/system/dict';
12   -import { queryDeviceProfileBy } from '/@/api/device/deviceManager';
13   -import { getModelServices } from '/@/api/device/modelOfMatter';
14   -import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
15   -import useCommonFun from '../hooks/useCommonFun';
16   -import { DeviceProfileModel } from '/@/api/device/model/deviceModel';
17   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
18 5 import { useComponentRegister } from '/@/components/Form';
19 6 import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
20   -import { isArray } from '/@/utils/is';
21   -import { ReadAndWriteEnum } from '/@/enums/toolEnum';
22 7
23 8 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
24 9
25   -const { useByProductGetAttribute } = useCommonFun();
26 10 export type TOption = {
27 11 label: string;
28 12 value: string;
29 13 };
30 14
31   -export enum CommandTypeEnum {
32   - CUSTOM = 0,
33   - SERVICE = 1,
34   - ATTRIBUTE = 2,
35   -}
36   -
37 15 /**
38 16 * 所使用的枚举值
39 17 */
... ... @@ -174,733 +152,3 @@ export const searchFormSchema: FormSchema[] = [
174 152 colProps: { span: 6 },
175 153 },
176 154 ];
177   -// 持续时间
178   -const isTimeDuration = (type) => {
179   - return type === 'DURATION';
180   -};
181   -const isReplace = (type) => {
182   - return type === 'REPEATING';
183   -};
184   -// 部分
185   -const isPart = (type: string) => {
186   - return type === 'PART';
187   -};
188   -//新增代码2022-11-23
189   -const isPartOrAll = (type: string) => {
190   - return type === 'ALL' || type === 'PART';
191   -};
192   -const isService = (type: string) => {
193   - return Number(type) === 1;
194   -};
195   -const isDefine = (type: string) => {
196   - return Number(type) === 0;
197   -};
198   -//新增代码2022-11-23
199   -
200   -export const trigger_condition_schema: FormSchema[] = [
201   - {
202   - field: 'triggered',
203   - label: '',
204   - component: 'Select',
205   - defaultValue: 'SIMPLE',
206   - componentProps: {
207   - placeholder: '请选择触发类型',
208   - options: [
209   - { label: '简单', value: 'SIMPLE' },
210   - { label: '持续时长', value: 'DURATION' },
211   - { label: '重复次数', value: 'REPEATING' },
212   - ],
213   - },
214   - colProps: { span: 6 },
215   - },
216   - {
217   - field: 'deviceType',
218   - label: '',
219   - component: 'ApiSelect',
220   - colProps: { span: 6 },
221   - defaultValue: 'SENSOR',
222   - componentProps: ({ formActionType }) => {
223   - const { setFieldsValue } = formActionType;
224   - return {
225   - api: findDictItemByCode,
226   - params: {
227   - dictCode: 'device_type',
228   - },
229   - placeholder: '请选择类型',
230   - labelField: 'itemText',
231   - valueField: 'itemValue',
232   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
233   - onChange(e) {
234   - if (e) {
235   - setFieldsValue({ deviceProfileId: '' });
236   - }
237   - },
238   - };
239   - },
240   - },
241   - {
242   - field: 'deviceProfileId',
243   - label: '',
244   - component: 'ApiSelect',
245   - colProps: { span: 6 },
246   - componentProps: ({ formActionType, formModel }) => {
247   - const { updateSchema, setFieldsValue } = formActionType;
248   - const deviceType = formModel['deviceType'];
249   -
250   - return {
251   - api: queryDeviceProfileBy,
252   - params: {
253   - deviceType,
254   - },
255   - showSearch: true,
256   - placeholder: '请选择产品',
257   - labelField: 'name',
258   - valueField: 'id',
259   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
260   - onChange: async (e) => {
261   - if (e) {
262   - setFieldsValue({ type2: '', entityId: [] });
263   - const res = await getAttribute(e);
264   - const options = ref<TOption[]>([]);
265   - useByProductGetAttribute(res, updateSchema, options);
266   - }
267   - },
268   - filterOption: (inputValue: string, option: Record<'label' | 'value', string>) => {
269   - let { label, value } = option;
270   - label = label.toLowerCase();
271   - value = value.toLowerCase();
272   - inputValue = inputValue.toLowerCase();
273   - return label.includes(inputValue) || value.includes(inputValue);
274   - },
275   - };
276   - },
277   - },
278   - {
279   - field: 'device',
280   - label: '',
281   - component: 'Select',
282   - componentProps: {
283   - placeholder: '请选择设备',
284   - options: [
285   - { label: '全部', value: 'ALL' },
286   - { label: '部分', value: 'PART' },
287   - ],
288   - },
289   - colProps: { span: 6 },
290   - },
291   -
292   - {
293   - field: 'entityId',
294   - label: '',
295   - component: 'ApiSelect',
296   - componentProps: ({ formModel }) => {
297   - const deviceProfileId = formModel['deviceProfileId'];
298   - return {
299   - mode: 'multiple',
300   - api: async () => {
301   - if (unref(organizationId)) {
302   - try {
303   - const data = await byOrganizationIdGetMasterDevice({
304   - organizationId: unref(organizationId),
305   - deviceProfileId,
306   - });
307   - if (data)
308   - return data.map((item) => ({
309   - ...item,
310   - label: item.alias || item.name,
311   - value: item.tbDeviceId,
312   - }));
313   - } catch (error) {}
314   - }
315   - return [];
316   - },
317   - placeholder: '请选择设备',
318   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
319   - filterOption: (inputValue: string, option: Record<'label' | 'value', string>) => {
320   - let { label, value } = option;
321   - label = label.toLowerCase();
322   - value = value.toLowerCase();
323   - inputValue = inputValue.toLowerCase();
324   - return label.includes(inputValue) || value.includes(inputValue);
325   - },
326   - };
327   - },
328   - ifShow: ({ values }) => isPart(values.device),
329   - colProps: { span: 6 },
330   - },
331   -
332   - {
333   - field: 'time',
334   - label: '',
335   - component: 'Input',
336   - ifShow: ({ values }) => isTimeDuration(values.triggered),
337   - colProps: { span: 6 },
338   - slot: 'time',
339   - rules: numberAndNonegativeRule,
340   - },
341   - {
342   - field: 'timeUnit',
343   - label: '',
344   - component: 'Select',
345   - defaultValue: 'SECONDS',
346   - ifShow: ({ values }) => isTimeDuration(values.triggered),
347   - show: false,
348   - },
349   - {
350   - field: 'replaceValue',
351   - label: '',
352   - component: 'Input',
353   - componentProps: {
354   - placeholder: '事件计数值',
355   - },
356   - ifShow: ({ values }) => isReplace(values.triggered),
357   - colProps: { span: 6 },
358   - rules: numberAndNonegativeRule,
359   - },
360   - {
361   - field: 'triggerType',
362   - label: '',
363   - component: 'Select',
364   - componentProps: {
365   - placeholder: '设备触发',
366   - options: [
367   - { label: '设备触发', value: 'DEVICE_TRIGGER' },
368   - // { label: '定时触发', value: 'SCHEDULE_TRIGGER' },
369   - // { label: '场景触发', value: 'SCENE_TRIGGER' },
370   - // { label: '手动触发', value: 'HAND_ACT' },
371   - ],
372   - },
373   - colProps: { span: 6 },
374   - },
375   -
376   - {
377   - field: 'type1',
378   - label: '',
379   - component: 'Select',
380   - componentProps: {
381   - placeholder: '属性触发方式',
382   - options: [{ label: '属性触发', value: 'TIME_SERIES' }],
383   - },
384   - ifShow: ({ values }) => isDevice(values.triggerType),
385   - colProps: { span: 6 },
386   - },
387   - {
388   - field: 'type2',
389   - label: '',
390   - component: 'Select',
391   - componentProps: {
392   - placeholder: '请选择属性',
393   - },
394   - ifShow: ({ values }) => isDevice(values.triggerType),
395   - colProps: { span: 6 },
396   - // rules: numberAndEngLishRule,
397   - },
398   - {
399   - field: 'operationType',
400   - label: '',
401   - component: 'Select',
402   - slot: 'operationType',
403   - colProps: { span: 6 },
404   - },
405   - // {
406   - // field: 'detail',
407   - // label: '',
408   - // component: 'InputTextArea',
409   - // componentProps: {
410   - // placeholder: '请输入详情',
411   - // },
412   - // colProps: {
413   - // span: 13,
414   - // },
415   - // },
416   -];
417   -// !!!----------------------------------------------------^_^------------------------------------------------------------!!!
418   -enum ActionEnum {
419   - DEVICE_OUT = 'DEVICE_OUT',
420   - ALARM_OUT = 'MSG_NOTIFY',
421   -}
422   -const isDeviceOut = (type: string) => type === ActionEnum.DEVICE_OUT;
423   -const isAlarmOut = (type: string) => type === ActionEnum.ALARM_OUT;
424   -
425   -export const actionSchema: FormSchema[] = [
426   - {
427   - field: 'outTarget',
428   - label: '',
429   - component: 'Select',
430   - required: true,
431   - componentProps: {
432   - placeholder: '请选择执行动作',
433   - },
434   - slot: 'outTarget',
435   - colProps: { span: 6 },
436   - },
437   - {
438   - field: 'deviceType',
439   - label: '',
440   - component: 'ApiSelect',
441   - colProps: { span: 6 },
442   - defaultValue: 'SENSOR',
443   - componentProps: ({ formActionType }) => {
444   - const { setFieldsValue } = formActionType;
445   - return {
446   - api: findDictItemByCode,
447   - params: {
448   - dictCode: 'device_type',
449   - },
450   - placeholder: '请选择类型',
451   - labelField: 'itemText',
452   - valueField: 'itemValue',
453   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
454   - onChange(e) {
455   - if (e) {
456   - setFieldsValue({ deviceProfileId: '' });
457   - }
458   - },
459   - };
460   - },
461   - ifShow: ({ values }) => isDeviceOut(values.outTarget),
462   - },
463   - {
464   - field: 'transportType',
465   - label: '',
466   - component: 'Input',
467   - show: false,
468   - },
469   - {
470   - field: 'deviceProfileId',
471   - label: '',
472   - component: 'ApiSelect',
473   - colProps: { span: 6 },
474   - componentProps: ({ formActionType, formModel }) => {
475   - const { setFieldsValue } = formActionType;
476   - const deviceType = formModel['deviceType'];
477   - return {
478   - api: queryDeviceProfileBy,
479   - params: {
480   - deviceType,
481   - },
482   - placeholder: '请选择产品',
483   - labelField: 'name',
484   - valueField: 'id',
485   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
486   - onChange: (_value: string, options = {} as DeviceProfileModel) => {
487   - const oldType = formModel['transportType'];
488   -
489   - const updateFlag =
490   - oldType === TransportTypeEnum.TCP || options.transportType === TransportTypeEnum.TCP;
491   -
492   - setFieldsValue({
493   - thingsModelId: '',
494   - deviceId: [],
495   - transportType: options.transportType,
496   - ...(updateFlag ? { doContext: null } : {}),
497   - });
498   - },
499   - onOptionsChange(options: DeviceProfileModel[]) {
500   - const deviceProfileId = formModel['deviceProfileId'];
501   - if (deviceProfileId) {
502   - const index = options.findIndex(
503   - (item) => (item as Recordable).value === deviceProfileId
504   - );
505   -
506   - ~index && setFieldsValue({ transportType: options[index].transportType });
507   - }
508   - },
509   - };
510   - },
511   - ifShow: ({ values }) => isDeviceOut(values.outTarget),
512   - },
513   - {
514   - field: 'device',
515   - label: '',
516   - component: 'Select',
517   - componentProps: ({ formActionType }) => {
518   - const { setFieldsValue } = formActionType;
519   - return {
520   - placeholder: '请选择设备',
521   - options: [
522   - { label: '全部', value: 'ALL' },
523   - { label: '部分', value: 'PART' },
524   - ],
525   - onChange: () => {
526   - setFieldsValue({ deviceId: [], thingsModelId: null });
527   - },
528   - };
529   - },
530   - ifShow: ({ values }) => isDeviceOut(values.outTarget) && values['deviceProfileId'],
531   - colProps: { span: 6 },
532   - },
533   - {
534   - field: 'deviceId',
535   - label: '',
536   - component: 'ApiSelect',
537   - componentProps: ({ formModel }) => {
538   - const deviceProfileId = formModel['deviceProfileId'];
539   - return {
540   - mode: 'multiple',
541   - api: async () => {
542   - if (unref(organizationId)) {
543   - try {
544   - const data = await byOrganizationIdGetMasterDevice({
545   - organizationId: unref(organizationId),
546   - deviceProfileId,
547   - });
548   - if (data)
549   - return data.map((item) => ({
550   - ...item,
551   - label: item.alias || item.name,
552   - value: item.tbDeviceId,
553   - }));
554   - } catch (error) {}
555   - }
556   - return [];
557   - },
558   - placeholder: '请选择设备',
559   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
560   - };
561   - },
562   - ifShow: ({ values }) => isPart(values.device) && isDeviceOut(values.outTarget),
563   - colProps: { span: 6 },
564   - },
565   - //新增代码2022-11-23
566   - {
567   - field: 'commandType',
568   - label: '',
569   - required: true,
570   - component: 'ApiSelect',
571   - colProps: {
572   - span: 6,
573   - },
574   - defaultValue: '0',
575   - componentProps: ({ formActionType }) => {
576   - const { setFieldsValue } = formActionType;
577   - return {
578   - placeholder: '请选择类型',
579   - api: async (parmas: Recordable) => {
580   - try {
581   - const record = await findDictItemByCode(parmas);
582   - return record.filter(
583   - (item) =>
584   - item.itemValue !== CommandTypeEnum.ATTRIBUTE.toString() || item.itemText != '属性'
585   - );
586   - } catch (error) {
587   - return [];
588   - }
589   - },
590   - labelField: 'itemText',
591   - valueField: 'itemValue',
592   - params: {
593   - dictCode: 'custom_define',
594   - },
595   - numberToString: true,
596   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
597   - onChange: () => {
598   - setFieldsValue({ doContext: null, thingsModelId: null });
599   - },
600   - };
601   - },
602   - ifShow: ({ values }) => isDeviceOut(values.outTarget) && isPartOrAll(values.device),
603   - },
604   - //新增代码2022-11-23
605   - {
606   - field: 'callType',
607   - label: '',
608   - required: true,
609   - component: 'ApiSelect',
610   - colProps: {
611   - span: 6,
612   - },
613   - defaultValue: 'SYNC',
614   - componentProps: {
615   - placeholder: '请选择类型',
616   - api: findDictItemByCode,
617   - params: {
618   - dictCode: 'call_mode',
619   - },
620   - labelField: 'itemText',
621   - valueField: 'itemValue',
622   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
623   - },
624   - ifShow: ({ values }) =>
625   - isDeviceOut(values.outTarget) && isPartOrAll(values.device) && isDefine(values.commandType),
626   - },
627   - {
628   - field: 'serviceIdentifier',
629   - label: '',
630   - component: 'Input',
631   - show: false,
632   - },
633   - {
634   - field: 'thingsModelKeys',
635   - label: '',
636   - show: false,
637   - component: 'Select',
638   - componentProps: {
639   - mode: 'multiple',
640   - },
641   - },
642   - {
643   - field: 'thingsModelId',
644   - label: '',
645   - required: true,
646   - component: 'ApiSelect',
647   - colProps: {
648   - span: 6,
649   - },
650   - componentProps: ({ formModel, formActionType }) => {
651   - const { updateSchema, setFieldsValue } = formActionType;
652   - const deviceProfileId = Reflect.get(formModel, 'deviceProfileId');
653   - const thingsModelId = Reflect.get(formModel, 'thingsModelId');
654   - const transportType = Reflect.get(formModel, 'transportType');
655   - return {
656   - placeholder: '请选择服务',
657   - api: async (params: Recordable) => {
658   - try {
659   - if (!Reflect.get(params, 'deviceProfileId')) return [];
660   - const record =
661   - (await getModelServices(params as Record<'deviceProfileId', string>)) || [];
662   - const selected = record.find((item) => item.id === thingsModelId);
663   - selected &&
664   - updateSchema({
665   - field: 'serviceInputValue',
666   - componentProps: {
667   - inputData: selected?.functionJson.inputData,
668   - },
669   - });
670   - selected &&
671   - setFieldsValue({
672   - callType: selected.callType,
673   - serviceIdentifier: selected?.identifier,
674   - thingsModelKeys: isArray(selected?.functionJson?.inputData)
675   - ? selected?.functionJson?.inputData
676   - .filter((item) => item.accessMode === ReadAndWriteEnum.READ_AND_WRITE)
677   - .map((item) => item.identifier)
678   - : [],
679   - });
680   - return record;
681   - } catch (error) {
682   - console.error(error);
683   - return [];
684   - }
685   - },
686   - params: {
687   - deviceProfileId,
688   - },
689   - labelField: 'functionName',
690   - valueField: 'id',
691   - getPopupContainer: (triggerNode) => triggerNode.parentNode,
692   - onChange: (_, options: ModelOfMatterParams) => {
693   - if (options) {
694   - // setFieldsValue({ doContext: { ...options.functionJson, callType: options.callType } });
695   - // if ( )
696   - const record = {
697   - callType: options.callType,
698   - serviceIdentifier: options.identifier,
699   - thingsModelKeys: isArray(options?.functionJson?.inputData)
700   - ? options?.functionJson?.inputData
701   - .filter((item) => item.accessMode === ReadAndWriteEnum.READ_AND_WRITE)
702   - .map((item) => item.identifier)
703   - : [],
704   - };
705   - transportType === TransportTypeEnum.TCP
706   - ? Object.assign(record, {
707   - tcpServiceCommand: options.functionJson?.inputData?.[0]?.serviceCommand,
708   - })
709   - : updateSchema({
710   - field: 'serviceInputValue',
711   - componentProps: {
712   - inputData: options.functionJson.inputData,
713   - },
714   - });
715   -
716   - setFieldsValue(record);
717   - } else {
718   - setFieldsValue({ serviceIdentifier: null });
719   - }
720   - },
721   - };
722   - },
723   - ifShow: ({ values }) => isDeviceOut(values.outTarget) && isService(values.commandType),
724   - },
725   - //新增代码2022-11-23
726   - {
727   - field: 'alarm_config',
728   - label: '',
729   - component: 'Input',
730   - componentProps: {
731   - placeholder: '请选择告警配置',
732   - },
733   - slot: 'alarmConfigSlot',
734   - ifShow: ({ values }) => values.outTarget === 'MSG_NOTIFY',
735   - colProps: { span: 6 },
736   - },
737   - //新增代码2022-11-23
738   - {
739   - field: 'doContext',
740   - component: 'Input',
741   - label: '',
742   - slot: 'doContext',
743   - show: ({ values }) => {
744   - return (
745   - isDeviceOut(values.outTarget) && isPartOrAll(values.device) && isDefine(values.commandType)
746   - );
747   - },
748   - colProps: {
749   - span: 24,
750   - },
751   - },
752   - //新增代码2022-11-23
753   - {
754   - field: 'alarm_level',
755   - component: 'Select',
756   - label: '',
757   - show: ({ values }) => isAlarmOut(values.outTarget),
758   - // dynamicRules: (params) => {
759   - // const { outTarget } = params.values;
760   - // return [
761   - // {
762   - // required: outTarget == 'MSG_NOTIFY' ? true : false,
763   - // validator: (_, value) => {
764   - // if (!value) return Promise.reject('请选择告警配置');
765   - // Promise.resolve();
766   - // },
767   - // },
768   - // ];
769   - // },
770   - componentProps: {
771   - placeholder: '请选择告警等级',
772   - options: [
773   - {
774   - label: '紧急',
775   - value: 'CRITICAL',
776   - },
777   - {
778   - label: '重要',
779   - value: 'MAJOR',
780   - },
781   - {
782   - label: '次要',
783   - value: 'MINOR',
784   - },
785   - {
786   - label: '警告',
787   - value: 'WARNING',
788   - },
789   - {
790   - label: '不确定',
791   - value: 'INDETERMINATE',
792   - },
793   - ],
794   - },
795   - colProps: {
796   - span: 6,
797   - },
798   - },
799   - {
800   - field: 'clear_alarm',
801   - component: 'Checkbox',
802   - label: '',
803   - show: ({ values }) => isAlarmOut(values.outTarget),
804   - colProps: {
805   - span: 8,
806   - },
807   - slot: 'clearAlarm',
808   - },
809   - {
810   - field: 'tcpServiceCommand',
811   - component: 'Input',
812   - label: '服务命令',
813   - colProps: { span: 24 },
814   - dynamicDisabled: true,
815   - show: ({ values }) =>
816   - values['thingsModelId'] && values['transportType'] === TransportTypeEnum.TCP,
817   - },
818   - {
819   - field: 'serviceInputValue',
820   - component: 'ObjectModelValidateForm',
821   - label: '',
822   - changeEvent: 'update:value',
823   - valueField: 'value',
824   - show: ({ values }) =>
825   - values['thingsModelId'] && values['transportType'] !== TransportTypeEnum.TCP,
826   - colProps: {
827   - span: 24,
828   - },
829   - componentProps: {},
830   - },
831   -];
832   -
833   -export const alarmScheduleSchemas: FormSchema[] = [
834   - {
835   - field: 'schedule',
836   - label: '',
837   - component: 'Select',
838   - componentProps({ formActionType }) {
839   - const { resetFields } = formActionType;
840   - return {
841   - options: scheduleOptions,
842   - allowClear: false,
843   - onChange() {
844   - resetFields();
845   - },
846   - };
847   - },
848   - },
849   - {
850   - field: 'timezone',
851   - label: '时区',
852   - component: 'Select',
853   - defaultValue: 'Asia/Shanghai',
854   - componentProps: {
855   - options: [
856   - {
857   - label: 'Asia/Shanghai',
858   - value: 'Asia/Shanghai',
859   - },
860   - ],
861   - allowClear: false,
862   - },
863   - ifShow: ({ values }) => values.schedule !== 'ANY_TIME',
864   - },
865   - {
866   - field: 'daysOfWeek',
867   - label: '天',
868   - component: 'CheckboxGroup',
869   - rules: [
870   - {
871   - message: '请至少选择一天',
872   - required: true,
873   - },
874   - ],
875   - componentProps: {
876   - options: [
877   - { label: '星期一', value: 1 },
878   - { label: '星期二', value: 2 },
879   - { label: '星期三', value: 3 },
880   - { label: '星期四', value: 4 },
881   - { label: '星期五', value: 5 },
882   - { label: '星期六', value: 6 },
883   - { label: '星期日', value: 7 },
884   - ],
885   - },
886   - colProps: {
887   - span: 24,
888   - },
889   - ifShow: ({ values }) => values.schedule === 'SPECIFIC_TIME',
890   - },
891   - {
892   - field: 'time',
893   - label: '时间',
894   - labelWidth: 40,
895   - component: 'RangePicker',
896   - ifShow: ({ values }) => values.schedule === 'SPECIFIC_TIME',
897   - slot: 'timing',
898   - },
899   - {
900   - field: 'day',
901   - label: '天',
902   - component: 'CheckboxGroup',
903   - slot: 'customEnable',
904   - ifShow: ({ values }) => values.schedule === 'CUSTOM',
905   - },
906   -];
... ...
... ... @@ -8,12 +8,12 @@ import {
8 8 } from '../DevicePicker';
9 9 import { PollCommandInput, ModeEnum } from '../PollCommandInput';
10 10 import { DeviceProfileModel } from '/@/api/device/model/deviceModel';
11   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
12 11 import { JSONEditorValidator } from '/@/components/CodeEditor/src/JSONEditor';
13 12 import { BooleanStringEnum, TimeUnitEnum, TimeUnitNameEnum } from '/@/enums/toolEnum';
14 13 import { dateUtil } from '/@/utils/dateUtil';
15 14 import { ProductPicker, validateProductPicker } from '../ProductPicker';
16 15 import { useGlobSetting } from '/@/hooks/setting';
  16 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
17 17
18 18 useComponentRegister('DevicePicker', DevicePicker);
19 19 useComponentRegister('ProductPicker', ProductPicker);
... ...
1 1 import { ref, unref } from 'vue';
2   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
3   -import { CommandTypeEnum } from '/@/views/rule/linkedge/config/config.data';
4 2 import { TaskTypeEnum } from '/@/views/task/center/config';
5 3 import { genModbusCommand } from '/@/api/task';
6 4 import { useMessage } from '/@/hooks/web/useMessage';
7 5 import { SingleToHex } from '/@/views/device/list/cpns/tabs/ObjectModelCommandDeliveryModal/config';
  6 +import { CommandTypeEnum } from '/@/enums/deviceEnum';
  7 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
8 8
9 9 const getArray = (values) => {
10 10 const str = values.replace(/\s+/g, '');
... ...
... ... @@ -10,12 +10,12 @@ import { getModelServices } from '/@/api/device/modelOfMatter';
10 10 import { findDictItemByCode } from '/@/api/system/dict';
11 11 import { FormSchema, useComponentRegister } from '/@/components/Form';
12 12 import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
13   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
14   -import { CommandTypeEnum } from '/@/views/rule/linkedge/config/config.data';
15 13 import { DataActionModeEnum } from '/@/enums/toolEnum';
16 14 import { TaskTypeEnum } from '/@/views/task/center/config';
17 15 import { createPickerSearch } from '/@/utils/pickerSearch';
18 16 import { DataTypeEnum } from '/@/enums/objectModelEnum';
  17 +import { CommandTypeEnum } from '/@/enums/deviceEnum';
  18 +import { TransportTypeEnum } from '/@/enums/deviceEnum';
19 19
20 20 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
21 21
... ...
... ... @@ -2,8 +2,7 @@ import { ref } from 'vue';
2 2 import { DataSource } from '../../palette/types';
3 3 import { sendCommandOneway, sendCommandTwoway } from '/@/api/dataBoard';
4 4 import { useMessage } from '/@/hooks/web/useMessage';
5   -import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
6   -import { ServiceCallTypeEnum } from '/@/enums/toolEnum';
  5 +import { TransportTypeEnum, ServiceCallTypeEnum } from '/@/enums/deviceEnum';
7 6
8 7 const { createMessage } = useMessage();
9 8 export function useSendCommand() {
... ...