Commit 2d4c51e3efb57bfcdeebb63438e37dc1b224cbe1
Merge branch 'perf/event-template' into 'main_dev'
perf: 优化事件在模版模式中无法选择产品 See merge request yunteng/thingskit-scada!181
Showing
6 changed files
with
108 additions
and
46 deletions
| ... | ... | @@ -111,6 +111,7 @@ export interface NodeDataDataSourceJsonType { |
| 111 | 111 | export interface DeviceCommandListItemType { |
| 112 | 112 | deviceId: string |
| 113 | 113 | way: CommandWayEnum |
| 114 | + deviceProfileId: string | |
| 114 | 115 | command: string | Recordable |
| 115 | 116 | } |
| 116 | 117 | |
| ... | ... | @@ -142,12 +143,17 @@ export interface DoubleClickEventDataType { |
| 142 | 143 | |
| 143 | 144 | export interface SingleClickEventDataType extends DoubleClickEventDataType { } |
| 144 | 145 | |
| 146 | +export interface OperationPasswordDataType { | |
| 147 | + checked: boolean | |
| 148 | + pawssword?: string | |
| 149 | +} | |
| 150 | + | |
| 145 | 151 | export interface NodeDataEventJsonType { |
| 146 | 152 | [EventTypeEnum.DOUBLE]: DoubleClickEventDataType |
| 147 | 153 | [EventTypeEnum.SINGLE]: SingleClickEventDataType |
| 148 | 154 | [EventTypeEnum.DOWN]: MouseDownEventDataType |
| 149 | 155 | [EventTypeEnum.UP]: MouseUpEventDataType |
| 150 | - [EventTypeEnum.OPERATION_PASSWORD]: { password: string } | any | |
| 156 | + [EventTypeEnum.OPERATION_PASSWORD]: OperationPasswordDataType | |
| 151 | 157 | } |
| 152 | 158 | |
| 153 | 159 | export interface RangeItemType { | ... | ... |
| ... | ... | @@ -9,6 +9,7 @@ export enum TableColumnFieldEnum { |
| 9 | 9 | DEVICE_ID = 'deviceId', |
| 10 | 10 | WAY = 'way', |
| 11 | 11 | COMMAND = 'command', |
| 12 | + DEVICE_PROFILE_ID = 'deviceProfileId', | |
| 12 | 13 | } |
| 13 | 14 | |
| 14 | 15 | export interface TableRecordItemType { |
| ... | ... | @@ -18,6 +19,7 @@ export interface TableRecordItemType { |
| 18 | 19 | [TableColumnFieldEnum.COMMAND]?: Nullable<string | Recordable> |
| 19 | 20 | [ContentDataFieldsEnum.DEVICE_TYPE]?: Nullable<DeviceTypeEnum> |
| 20 | 21 | [ContentDataFieldsEnum.CODE_TYPE]?: Nullable<CodeTypeEnum> |
| 22 | + [ContentDataFieldsEnum.DEVICE_PROFILE_ID]: Nullable<string> | |
| 21 | 23 | [ContentDataFieldsEnum.TRANSPORT_TYPE]?: Nullable<TransportTypeEnum> |
| 22 | 24 | } |
| 23 | 25 | |
| ... | ... | @@ -65,28 +67,38 @@ export const getFormSchemas = (event: EventTypeEnum): FormSchema[] => { |
| 65 | 67 | ] |
| 66 | 68 | } |
| 67 | 69 | |
| 68 | -export const tableColumns: BasicColumn[] = [ | |
| 69 | - { | |
| 70 | - title: '设备', | |
| 71 | - width: 200, | |
| 72 | - key: TableColumnFieldEnum.DEVICE_ID, | |
| 73 | - dataIndex: TableColumnFieldEnum.DEVICE_ID, | |
| 74 | - }, | |
| 75 | - { | |
| 76 | - title: '单向/双向', | |
| 77 | - width: 200, | |
| 78 | - key: TableColumnFieldEnum.WAY, | |
| 79 | - dataIndex: TableColumnFieldEnum.WAY, | |
| 80 | - }, | |
| 81 | - { | |
| 82 | - title: '下发值', | |
| 83 | - key: TableColumnFieldEnum.COMMAND, | |
| 84 | - dataIndex: TableColumnFieldEnum.COMMAND, | |
| 85 | - editComponent: 'JSONEditor', | |
| 86 | - helpMessage: ['点击进行命令编辑'], | |
| 87 | - }, | |
| 88 | - { | |
| 89 | - title: '操作', | |
| 90 | - key: 'action', | |
| 91 | - }, | |
| 92 | -] | |
| 70 | +export const getTableColumns = (isTemplateMode: boolean): BasicColumn[] => { | |
| 71 | + return [ | |
| 72 | + { | |
| 73 | + title: '产品', | |
| 74 | + width: 200, | |
| 75 | + ifShow: isTemplateMode, | |
| 76 | + key: TableColumnFieldEnum.DEVICE_PROFILE_ID, | |
| 77 | + dataIndex: TableColumnFieldEnum.DEVICE_PROFILE_ID, | |
| 78 | + }, | |
| 79 | + { | |
| 80 | + title: '设备', | |
| 81 | + width: 200, | |
| 82 | + ifShow: !isTemplateMode, | |
| 83 | + key: TableColumnFieldEnum.DEVICE_ID, | |
| 84 | + dataIndex: TableColumnFieldEnum.DEVICE_ID, | |
| 85 | + }, | |
| 86 | + { | |
| 87 | + title: '单向/双向', | |
| 88 | + width: 200, | |
| 89 | + key: TableColumnFieldEnum.WAY, | |
| 90 | + dataIndex: TableColumnFieldEnum.WAY, | |
| 91 | + }, | |
| 92 | + { | |
| 93 | + title: '下发值', | |
| 94 | + key: TableColumnFieldEnum.COMMAND, | |
| 95 | + dataIndex: TableColumnFieldEnum.COMMAND, | |
| 96 | + editComponent: 'JSONEditor', | |
| 97 | + helpMessage: ['点击进行命令编辑'], | |
| 98 | + }, | |
| 99 | + { | |
| 100 | + title: '操作', | |
| 101 | + key: 'action', | |
| 102 | + }, | |
| 103 | + ] | |
| 104 | +} | ... | ... |
| 1 | 1 | <script setup lang="ts"> |
| 2 | 2 | import { Button, Empty, FormItem, RadioGroup, Select, Tooltip } from 'ant-design-vue' |
| 3 | -import { onMounted, ref, unref } from 'vue' | |
| 3 | +import { onMounted, ref, toRaw, unref } from 'vue' | |
| 4 | 4 | import type { DefaultOptionType, SelectValue } from 'ant-design-vue/es/select' |
| 5 | 5 | import type { ComponentExposeType } from '../../..' |
| 6 | 6 | import type { TableRecordItemType } from './config' |
| 7 | -import { TableColumnFieldEnum, getFormSchemas, tableColumns } from './config' | |
| 7 | +import { TableColumnFieldEnum, getFormSchemas, getTableColumns } from './config' | |
| 8 | 8 | import CommandEditor from './CommandEditor.vue' |
| 9 | 9 | import { FormLayoutEnum } from '@/components/Form/src/enum' |
| 10 | 10 | import { BasicForm, useForm } from '@/components/Form' |
| ... | ... | @@ -18,6 +18,7 @@ import type { DeviceItemType } from '@/api/device/model' |
| 18 | 18 | import { useContentDataStore } from '@/store/modules/contentData' |
| 19 | 19 | import { useJsonParse } from '@/hooks/business/useJSONParse' |
| 20 | 20 | import type { DeviceCommandListItemType, MouseDownEventDataType } from '@/api/node/model' |
| 21 | +import type { ProductAndDevice } from '@/api/content/model' | |
| 21 | 22 | |
| 22 | 23 | const props = defineProps<{ event: EventTypeEnum }>() |
| 23 | 24 | |
| ... | ... | @@ -37,8 +38,10 @@ const dataSource = ref<TableRecordItemType[]>([getInitTableRecord()]) |
| 37 | 38 | |
| 38 | 39 | const deviceList = ref<DeviceItemType[]>([]) |
| 39 | 40 | |
| 41 | +const productList = ref<ProductAndDevice[]>([]) | |
| 42 | + | |
| 40 | 43 | const [registerTable] = useTable({ |
| 41 | - columns: tableColumns, | |
| 44 | + columns: getTableColumns(!!unref(contentDataStore.getIsTemplate)), | |
| 42 | 45 | showIndexColumn: false, |
| 43 | 46 | pagination: false, |
| 44 | 47 | canResize: true, |
| ... | ... | @@ -53,6 +56,7 @@ function getInitTableRecord(): TableRecordItemType { |
| 53 | 56 | deviceId: null, |
| 54 | 57 | way: CommandWayEnum.ONE_WAY, |
| 55 | 58 | command: null, |
| 59 | + deviceProfileId: null, | |
| 56 | 60 | } |
| 57 | 61 | } |
| 58 | 62 | |
| ... | ... | @@ -65,6 +69,7 @@ const handleDeleteRow = (data: TableRecordItemType) => { |
| 65 | 69 | } |
| 66 | 70 | |
| 67 | 71 | async function getDeviceList() { |
| 72 | + if (unref(contentDataStore.getIsTemplate)) return | |
| 68 | 73 | const organizationId = window.useParseParams().organizationId |
| 69 | 74 | if (!organizationId) return |
| 70 | 75 | const productIds = unref(contentDataStore.getProductIds) |
| ... | ... | @@ -76,9 +81,19 @@ async function getDeviceList() { |
| 76 | 81 | })) |
| 77 | 82 | } |
| 78 | 83 | |
| 84 | +async function getDeviceProfileList() { | |
| 85 | + if (!unref(contentDataStore.getIsTemplate)) return | |
| 86 | + productList.value = toRaw(unref(contentDataStore.getProductAndDevice)) || [] | |
| 87 | +} | |
| 88 | + | |
| 79 | 89 | const handleSelectDevice = (_value: SelectValue, option: DefaultOptionType | DefaultOptionType[], record: TableRecordItemType) => { |
| 80 | - const { codeType, transportType } = option as DeviceItemType | |
| 81 | - Object.assign(record, { codeType, transportType } as TableRecordItemType) | |
| 90 | + const { transportType } = option as DeviceItemType | |
| 91 | + Object.assign(record, { transportType } as TableRecordItemType) | |
| 92 | +} | |
| 93 | + | |
| 94 | +const handleSelectProduct = (_value: SelectValue, option: DefaultOptionType | DefaultOptionType[], record: TableRecordItemType) => { | |
| 95 | + const { transportType } = option as ProductAndDevice | |
| 96 | + Object.assign(record, { transportType }) | |
| 82 | 97 | } |
| 83 | 98 | |
| 84 | 99 | const handleOpenJSONEditorModal = (record: TableRecordItemType) => { |
| ... | ... | @@ -93,11 +108,12 @@ const handleEditComplete = (record: TableRecordItemType, command: string | Recor |
| 93 | 108 | |
| 94 | 109 | const getFieldsValue = (): MouseDownEventDataType => { |
| 95 | 110 | const commandList = unref(dataSource).map((item) => { |
| 96 | - const { deviceId, command, way } = item | |
| 111 | + const { deviceId, command, way, deviceProfileId } = item | |
| 97 | 112 | return { |
| 98 | 113 | deviceId, |
| 99 | 114 | way, |
| 100 | 115 | command, |
| 116 | + deviceProfileId, | |
| 101 | 117 | } as DeviceCommandListItemType |
| 102 | 118 | }) |
| 103 | 119 | |
| ... | ... | @@ -108,7 +124,9 @@ const getFieldsValue = (): MouseDownEventDataType => { |
| 108 | 124 | |
| 109 | 125 | const setFieldsValue = (record: MouseDownEventDataType) => { |
| 110 | 126 | const { commandList = [] } = record || {} |
| 111 | - dataSource.value = commandList ? commandList.map(item => ({ ...item, uuid: buildUUID() })) : [getInitTableRecord()] | |
| 127 | + dataSource.value = commandList | |
| 128 | + ? commandList.map(item => ({ ...item, uuid: buildUUID() })) | |
| 129 | + : [getInitTableRecord()] | |
| 112 | 130 | } |
| 113 | 131 | |
| 114 | 132 | const validate = async () => { |
| ... | ... | @@ -116,8 +134,8 @@ const validate = async () => { |
| 116 | 134 | await fromActionType.validate() |
| 117 | 135 | let passFlag = true |
| 118 | 136 | for (const item of unref(dataSource)) { |
| 119 | - const { deviceId } = item | |
| 120 | - if (deviceId) continue | |
| 137 | + const { deviceId, deviceProfileId } = item | |
| 138 | + if (deviceId || deviceProfileId) continue | |
| 121 | 139 | passFlag = false |
| 122 | 140 | } |
| 123 | 141 | return passFlag ? Promise.resolve(getFieldsValue()) : Promise.reject(new Error('请输入')) |
| ... | ... | @@ -130,6 +148,7 @@ const getValidateStatus = (value: string | number) => { |
| 130 | 148 | |
| 131 | 149 | onMounted(() => { |
| 132 | 150 | getDeviceList() |
| 151 | + getDeviceProfileList() | |
| 133 | 152 | }) |
| 134 | 153 | |
| 135 | 154 | defineExpose<ComponentExposeType>({ |
| ... | ... | @@ -142,11 +161,26 @@ defineExpose<ComponentExposeType>({ |
| 142 | 161 | <template> |
| 143 | 162 | <section> |
| 144 | 163 | <BasicForm @register="registerForm" /> |
| 145 | - <section class="w-full h-24"> | |
| 164 | + <section class="w-full "> | |
| 146 | 165 | <BasicTable @register="registerTable"> |
| 147 | 166 | <template #bodyCell="{ column, record }"> |
| 167 | + <template v-if="column.key === TableColumnFieldEnum.DEVICE_PROFILE_ID"> | |
| 168 | + <FormItem | |
| 169 | + name="record[TableColumnFieldEnum.DEVICE_PROFILE_ID]" | |
| 170 | + :validate-status="getValidateStatus(record[TableColumnFieldEnum.DEVICE_PROFILE_ID])" | |
| 171 | + > | |
| 172 | + <Select | |
| 173 | + v-model:value="record[TableColumnFieldEnum.DEVICE_PROFILE_ID]" :options="productList" :field-names="{ label: 'name', value: 'profileId' }" placeholder="请选择产品" | |
| 174 | + class="w-full" | |
| 175 | + @change="(value, option) => handleSelectProduct(value, option, record as TableRecordItemType)" | |
| 176 | + /> | |
| 177 | + </FormItem> | |
| 178 | + </template> | |
| 148 | 179 | <template v-if="column.key === TableColumnFieldEnum.DEVICE_ID"> |
| 149 | - <FormItem name="record[TableColumnFieldEnum.DEVICE_ID]" :validate-status="getValidateStatus(record[TableColumnFieldEnum.DEVICE_ID])"> | |
| 180 | + <FormItem | |
| 181 | + name="record[TableColumnFieldEnum.DEVICE_ID]" | |
| 182 | + :validate-status="getValidateStatus(record[TableColumnFieldEnum.DEVICE_ID])" | |
| 183 | + > | |
| 150 | 184 | <Select |
| 151 | 185 | v-model:value="record[TableColumnFieldEnum.DEVICE_ID]" :options="deviceList" placeholder="请选择设备" |
| 152 | 186 | class="w-full" |
| ... | ... | @@ -204,7 +238,9 @@ defineExpose<ComponentExposeType>({ |
| 204 | 238 | </template> |
| 205 | 239 | |
| 206 | 240 | <style lang="less" scoped> |
| 207 | - :deep(.ant-table-cell>.css-dev-only-do-not-override-eq3tly){ | |
| 208 | - margin:0 !important | |
| 241 | +:deep(.ant-table-cell>) { | |
| 242 | + .ant-form-item { | |
| 243 | + margin: 0 !important | |
| 209 | 244 | } |
| 245 | +} | |
| 210 | 246 | </style> | ... | ... |
| ... | ... | @@ -20,8 +20,10 @@ const onReceiveActMessage = (commandSource: CommandSource, message: Subscription |
| 20 | 20 | const nodeUtils = new NodeUtils() |
| 21 | 21 | const cell = nodeUtils.getCellById(node) |
| 22 | 22 | if (!cell) return |
| 23 | - const { attr, rangeList, defaultImage } = data as VariableImageActDataType | |
| 24 | - const { latestValue } = useLatestMessageValue(message.data, attr) | |
| 23 | + const { attr, enable, rangeList, defaultImage } = data as VariableImageActDataType | |
| 24 | + if (!enable) return | |
| 25 | + | |
| 26 | + const { latestValue } = useLatestMessageValue(message.data, attr!) | |
| 25 | 27 | const { flag, record } = getMeetTheConditionsRange(rangeList, latestValue) |
| 26 | 28 | let imageSrc |
| 27 | 29 | if (flag) { | ... | ... |
| ... | ... | @@ -57,7 +57,8 @@ export class DataDynamicEffectHandler { |
| 57 | 57 | const { node, data } = commandSource |
| 58 | 58 | const cell = this.nodeUtils.getCellById(node) |
| 59 | 59 | if (!cell) return |
| 60 | - const { attr } = data as FlashActDataType | |
| 60 | + const { attr, enable } = data as FlashActDataType | |
| 61 | + if (!enable) return | |
| 61 | 62 | const { latestValue } = useLatestMessageValue(message.data, attr!) |
| 62 | 63 | const { flag } = getMeetTheConditionsRange((data as FlashActDataType).rangeList, latestValue) |
| 63 | 64 | |
| ... | ... | @@ -76,7 +77,8 @@ export class DataDynamicEffectHandler { |
| 76 | 77 | const { node, data } = commandSource |
| 77 | 78 | const cell = this.nodeUtils.getCellById(node) |
| 78 | 79 | if (!cell) return |
| 79 | - const { attr } = data as DisplayActDataType | |
| 80 | + const { attr, enable } = data as DisplayActDataType | |
| 81 | + if (!enable) return | |
| 80 | 82 | const { latestValue } = useLatestMessageValue(message.data, attr!) |
| 81 | 83 | const { flag, record } = getMeetTheConditionsRange((data as DisplayActDataType).rangeList, latestValue) |
| 82 | 84 | if (flag) { |
| ... | ... | @@ -101,7 +103,8 @@ export class DataDynamicEffectHandler { |
| 101 | 103 | const { node, data } = commandSource |
| 102 | 104 | const cell = this.nodeUtils.getCellById(node) |
| 103 | 105 | if (!cell) return |
| 104 | - const { attr } = data as RotateActDataType | |
| 106 | + const { attr, enable } = data as RotateActDataType | |
| 107 | + if (!enable) return | |
| 105 | 108 | const { latestValue } = useLatestMessageValue(message.data, attr!) |
| 106 | 109 | const { flag } = getMeetTheConditionsRange((data as RotateActDataType).rangeList, latestValue) |
| 107 | 110 | const nodeEl = this.nodeUtils.getNodesForCells<SVGAElement>([cell]) |
| ... | ... | @@ -124,7 +127,8 @@ export class DataDynamicEffectHandler { |
| 124 | 127 | const { node, data } = commandSource |
| 125 | 128 | const cell = this.nodeUtils.getCellById(node) |
| 126 | 129 | if (!cell) return |
| 127 | - const { attr } = data as DynamicActDataType | |
| 130 | + const { attr, enable } = data as DynamicActDataType | |
| 131 | + if (!enable) return | |
| 128 | 132 | const { latestValue } = useLatestMessageValue(message.data, attr!) |
| 129 | 133 | const { flag, record } = getMeetTheConditionsRange((data as DynamicActDataType).rangeList, latestValue) |
| 130 | 134 | const nodeEl = this.nodeUtils.getNodeForCell<SVGAElement>(cell) | ... | ... |
| ... | ... | @@ -2,8 +2,10 @@ import { isString } from 'lodash-es' |
| 2 | 2 | import type { PackageCategoryEnum } from '@/core/Library/enum' |
| 3 | 3 | import type { DrawApp, MxCell } from '@/fitCore/types' |
| 4 | 4 | import type { BasicComponentEnum } from '@/core/Library/packages/Basic' |
| 5 | +import type { ControlComponentEnum } from '@/core/Library/packages/Control' | |
| 6 | +import type { ChartComponentEnum } from '@/core/Library/packages/Chart' | |
| 5 | 7 | |
| 6 | -type ComponentKey = BasicComponentEnum | |
| 8 | +type ComponentKey = BasicComponentEnum | ControlComponentEnum | ChartComponentEnum | |
| 7 | 9 | |
| 8 | 10 | export class NodeUtils { |
| 9 | 11 | App: DrawApp | ... | ... |