Эх сурвалжийг харах

perf(components): 优化“协议内容”组件协议参数表格

1. 初步编写手动匹配和从多个识别结果中选择的逻辑
wangcong 2 сар өмнө
parent
commit
fb9d9d3d69

+ 2 - 0
src/i18n/locales/zh.json

@@ -350,6 +350,7 @@
     "howToJudgeProtocolType": "如何判断协议类型",
     "importFromTemplate": "从模板导入",
     "manuallyCreate": "手动创建",
+    "manuallyMatch": "手动匹配",
     "nextDataReadDelay": "下条数据读取延时",
     "nextRoundDataReadDelay": "下轮数据读取延时",
     "paramList": "参数列表",
@@ -404,6 +405,7 @@
     "selectConfigMethodTip": "推荐使用模板导入,支持语义识别、自动填充序号、自动填充非必填项;参数较少的协议可选择手动创建",
     "selectDeviceType": "选择设备类型",
     "selectDeviceTypeTip": "推荐使用模板导入,支持语义识别、自动填充序号、自动填充非必填项;参数较少的协议可选择手动创建",
+    "selectFromProtocolLibrary": "从库中选",
     "selectProtocolType": "选择协议类型",
     "selectProtocolTypeTip": "目前仅支持 ModbusRTU、ModbusTCP 和 S7 协议,协议类型在完成配置后无法修改,请谨慎选择",
     "selectStandardParams": "选择标准参数",

+ 7 - 0
src/types/index.ts

@@ -217,6 +217,13 @@ export interface ProtocolParamInfo {
   readCalcFormula: string;
   writeCalcFormula: string;
   decimalPlace: number;
+  recognizeResult: string | null;
+  candidateResults: string | null;
+}
+
+export interface ProtocolCandidateResult {
+  platformProtocolId: number;
+  platformProtocolGatewayParamName: string;
 }
 
 export interface ProtocolParamSearchParams extends PageParams {

+ 121 - 4
src/views/setup-protocol/ProtocolContent.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { computed, onMounted, ref, useTemplateRef } from 'vue';
+import { computed, defineComponent, onMounted, ref, useTemplateRef } from 'vue';
 import { message, Modal } from 'ant-design-vue';
 import { debounce } from 'lodash-es';
 
@@ -16,7 +16,15 @@ import SelectStandardParams from './SelectStandardParams.vue';
 import type { FormInstance, TableProps } from 'ant-design-vue';
 import type { DefaultOptionType, SelectValue } from 'ant-design-vue/es/select';
 import type { Key, SorterResult } from 'ant-design-vue/es/table/interface';
-import type { CheckedType, FormRules, PageParams, PageSorts, ProtocolBaseInfo, ProtocolParamInfo } from '@/types';
+import type {
+  CheckedType,
+  FormRules,
+  PageParams,
+  PageSorts,
+  ProtocolBaseInfo,
+  ProtocolCandidateResult,
+  ProtocolParamInfo,
+} from '@/types';
 
 interface Props {
   info: Partial<ProtocolBaseInfo>;
@@ -24,6 +32,18 @@ interface Props {
 
 const props = defineProps<Props>();
 
+const VNodes = defineComponent({
+  props: {
+    vnodes: {
+      type: Object,
+      required: true,
+    },
+  },
+  render() {
+    return this.vnodes;
+  },
+});
+
 const { dictData: protocolTypes, getDictData: getProtocolTypes } = useDictData(DictCode.AllProtocolType);
 const { dictData: baudRateList, getDictData: getBaudRateList } = useDictData(DictCode.BaudRate);
 const { dictData: readContinuousAddr, getDictData: getReadContinuousAddr } = useDictData(DictCode.ReadContinuousAddr);
@@ -281,9 +301,25 @@ const deleteSelectedParams = () => {
   });
 };
 
+const filterProtocolCandidateResult = (input: string, option: ProtocolCandidateResult) => {
+  return option.platformProtocolGatewayParamName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
+};
+
+const handleProtocolCandidateChange = (_value: SelectValue, option: DefaultOptionType) => {
+  console.log(_value, option);
+};
+
 const customParamsRef = useTemplateRef('customParams');
 const selectStandardParamsRef = useTemplateRef('selectStandardParams');
 
+const changeToCustomParams = (params: ProtocolParamInfo) => {
+  console.log(params);
+};
+
+const changeToStandardParams = (params: ProtocolParamInfo) => {
+  console.log(params);
+};
+
 defineExpose({
   validateProtocolInfo,
 });
@@ -535,8 +571,53 @@ defineExpose({
         class="table-column-item-required"
         :title="$t('setupProtocol.protocolParamFields.platformParamName')"
         data-index="platformParamName"
-        :width="170"
-      />
+        :width="188"
+      >
+        <template #default="{ record }">
+          <a v-if="record.recognizeResult === ProtocolRecognitionResult.Success">
+            {{ record.platformParamName }}
+          </a>
+          <ADropdown v-else-if="record.recognizeResult === ProtocolRecognitionResult.Unrecognized">
+            <template #overlay>
+              <AMenu>
+                <AMenuItem key="select" @click="changeToStandardParams(record)">
+                  {{ $t('setupProtocol.selectFromProtocolLibrary') }}
+                </AMenuItem>
+                <AMenuItem key="custom" @click="changeToCustomParams(record)">
+                  {{ $t('common.custom') }}
+                </AMenuItem>
+              </AMenu>
+            </template>
+            <AButton class="manually-match-button">
+              {{ $t('setupProtocol.manuallyMatch') }}
+              <SvgIcon name="down" />
+            </AButton>
+          </ADropdown>
+          <ASelect
+            v-else-if="record.recognizeResult === ProtocolRecognitionResult.MultipleResults"
+            class="multiple-results-select"
+            :options="JSON.parse(record.candidateResults || '[]')"
+            :field-names="{ label: 'platformProtocolGatewayParamName', value: 'platformProtocolId' }"
+            :dropdown-match-select-width="176"
+            :placeholder="$t('common.plzSelect')"
+            show-search
+            :filter-option="filterProtocolCandidateResult"
+            @change="handleProtocolCandidateChange"
+          >
+            <template #dropdownRender="{ menuNode: menu }">
+              <div class="multiple-results-select-header">
+                <AButton type="primary" @click="changeToStandardParams(record)">
+                  {{ $t('setupProtocol.selectFromProtocolLibrary') }}
+                </AButton>
+                <AButton @click="changeToCustomParams(record)">
+                  {{ $t('common.custom') }}
+                </AButton>
+              </div>
+              <VNodes :vnodes="menu" />
+            </template>
+          </ASelect>
+        </template>
+      </ATableColumn>
       <ATableColumn
         class="table-column-item-required"
         :title="$t('setupProtocol.protocolParamFields.platformParamCode')"
@@ -781,4 +862,40 @@ defineExpose({
     border-color: var(--antd-color-primary-opacity-60);
   }
 }
+
+.manually-match-button {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+  color: #333;
+
+  i {
+    color: #8c94a8;
+  }
+
+  &:hover {
+    color: #333;
+  }
+}
+
+.multiple-results-select {
+  width: 100%;
+}
+
+.multiple-results-select-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 12px;
+  padding-top: 8px;
+  margin-bottom: 8px;
+  border-bottom: 1px solid #e4e7ed;
+
+  /* stylelint-disable-next-line no-descending-specificity */
+  button {
+    height: 24px;
+    padding: 1px 8px;
+  }
+}
 </style>