feat: 参数树

master
李小林 7 months ago
parent 47f9230ab1
commit 8dffb3fe8f
  1. 75
      src/api/remote/index.ts
  2. 12
      src/api/remote/types.ts
  3. 1
      src/assets/icons/file.svg
  4. 1
      src/layout/components/TagsView/index.vue
  5. 15
      src/router/index.ts
  6. 2
      src/utils/confirm.ts
  7. 385
      src/views/family/operate/remote-operation/components/DeviceParamTree.vue
  8. 2
      src/views/family/operate/remote-operation/components/DeviceSpeed.vue
  9. 78
      src/views/family/operate/remote-operation/components/RemoteOperateList.vue
  10. 165
      src/views/family/operate/remote-operation/components/TreeParamAttribute.vue

@ -1,14 +1,16 @@
import request from "@/utils/request";
import { AxiosPromise } from "axios";
import {
DeviceMonitorForm,
DeviceMonitorForm, OptionTree,
PingForm,
RemoteDevInfoVO,
RemoteOperateResult, SpeedInfo,
RemoteOperateResult,
SpeedInfo,
UnBindingForm
} from "@/api/remote/types";
import { DeviceLinkVO } from "@/api/operate-log/types";
import { FTTRInfoVO, ServiceCompareVO } from "@/api/operate-result-args/types";
import { string } from "fast-glob/out/utils";
export function remoteDevInfo(devId: number): AxiosPromise<RemoteDevInfoVO> {
return request({
@ -170,3 +172,72 @@ export function remoteVendorProfile(devId: number, fileId?: number) {
method: "GET",
});
}
export function remoteTreeNode(
devId?: number,
nodePath?: string
): AxiosPromise<OptionTree[]> {
return request({
url: `/api/equipment/v1/remote/tree/infos/${devId}`,
method: "GET",
params: { nodePath },
});
}
export function remoteGetParameterValues(
devId?: number,
nodePath?: string
): AxiosPromise<OptionTree> {
return request({
url: `/api/equipment/v1/remote/tree/param-value/${devId}`,
method: "GET",
params: { nodePath },
});
}
export function remoteSetParameterValues(
devId?: number,
nodePath?: string,
argValue?: string
) {
return request({
url: `/api/equipment/v1/remote/tree/set-param-value/${devId}`,
method: "PUT",
params: { nodePath, argValue },
});
}
export function remoteGetParameterAttributes(
devId?: number,
nodePath?: string
): AxiosPromise<OptionTree> {
return request({
url: `/api/equipment/v1/remote/tree/param-attribute/${devId}`,
method: "GET",
params: { nodePath },
});
}
export function remoteSetParameterAttributes(
devId?: number,
nodePath?: string,
argValue?: string
): AxiosPromise<OptionTree> {
return request({
url: `/api/equipment/v1/remote/tree/set-param-attribute/${devId}`,
method: "PUT",
params: { nodePath, argValue },
});
}
export function remoteAddInstanceNode(
devId?: number,
nodePath?: string
): AxiosPromise<OptionTree> {
return request({
url: `/api/equipment/v1/remote/tree/add-instance-node/${devId}`,
method: "GET",
params: { nodePath },
});
}
export function remoteDeleteInstanceNode(devId?: number, nodePath?: string) {
return request({
url: `/api/equipment/v1/remote/tree/delete-instance-node/${devId}`,
method: "GET",
params: { nodePath },
});
}

@ -85,3 +85,15 @@ export interface SpeedInfo {
downloadUrls: string[];
speedMaxRate: string;
}
export interface OptionTree {
/** 值 */
value?: string | number;
/** 文本 */
label?: string;
/**是否有子节点*/
childNode?: boolean;
nodePath?: string;
/** 子列表 */
children?: OptionTree[];
}

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1722849931165" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11624" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M842.666667 981.333333H181.333333a53.393333 53.393333 0 0 1-53.333333-53.333333V96a53.393333 53.393333 0 0 1 53.333333-53.333333h466.746667a52.986667 52.986667 0 0 1 37.713333 15.62l194.586667 194.586666a52.986667 52.986667 0 0 1 15.62 37.713334V928a53.393333 53.393333 0 0 1-53.333333 53.333333zM181.333333 85.333333a10.666667 10.666667 0 0 0-10.666666 10.666667v832a10.666667 10.666667 0 0 0 10.666666 10.666667h661.333334a10.666667 10.666667 0 0 0 10.666666-10.666667V298.666667h-160a53.393333 53.393333 0 0 1-53.333333-53.333334V85.333333z m501.333334 30.166667V245.333333a10.666667 10.666667 0 0 0 10.666666 10.666667h129.833334z m21.333333 652.5H320a21.333333 21.333333 0 0 1 0-42.666667h384a21.333333 21.333333 0 0 1 0 42.666667z m0-213.333333H320a21.333333 21.333333 0 0 1 0-42.666667h384a21.333333 21.333333 0 0 1 0 42.666667zM490.666667 298.666667H320a21.333333 21.333333 0 0 1 0-42.666667h170.666667a21.333333 21.333333 0 0 1 0 42.666667z" fill="#5C5C66" p-id="11625"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -283,7 +283,6 @@ function closeAllTags(view: TagView) {
*/
function openContentMenu(tag: TagView, e: MouseEvent) {
const menuMinWidth = 105;
const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left
const offsetWidth = proxy?.$el.offsetWidth; // container width
const maxLeft = offsetWidth - menuMinWidth; // left boundary

@ -346,7 +346,7 @@ export const constantRoutes: RouteRecordRaw[] = [
},
},
{
path: "/resources/remote/device-speed/:devId/:pppoe",
path: "/resources/remote/device-speed/:devId",
name: "DeviceSpeed",
component: () =>
import(
@ -397,6 +397,19 @@ export const constantRoutes: RouteRecordRaw[] = [
title: "自定义节点",
},
},
{
path: "/resources/remote/device-param-tree/:devId",
name: "DeviceParamTree",
component: () =>
import(
"@/views/family/operate/remote-operation/components/DeviceParamTree.vue"
),
meta: {
hidden: true,
keepAlive: true,
title: "设备参数树",
},
},
],
},
];

@ -12,7 +12,7 @@ function confirm(message: string, ok: Function) {
.catch((err) => {
ElMessage({
type: "info",
message: "取消操作" + err,
message: "取消操作",
});
});
}

@ -0,0 +1,385 @@
<template>
<div class="app-container">
<el-card shadow="never">
<template #header>
<div class="flex justify-between">
<div style="display: flex; align-items: center">
<el-icon><Grid /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>设备参数树</span
>
</div>
<div style="display: flex; align-items: center" v-if="loading">
<div class="rotate mr-0.5">
<el-icon><Loading /></el-icon>
</div>
<span style="font-weight: 700; font-size: 14px; line-height: 16px"
>正在加载请稍后...</span
>
</div>
</div>
</template>
<el-scrollbar max-height="300">
<el-tree
ref="deviceTreeRef"
:highlight-current="true"
:data="treeList"
:props="{
children: 'children',
label: 'label',
}"
:expand-on-click-node="false"
default-expand-all
>
<template #default="{ node, data }">
<div class="custom-tree-node">
<div style="display: flex; justify-content: flex-start">
<div v-if="data.childNode === true">
<div style="margin-top: 1px" @click="handleNodeClick(data)">
<svg-icon class="mr-5px" size="15" icon-class="folder" />
</div>
</div>
<div v-else>
<div style="margin-top: 1px">
<svg-icon class="mr-5px" size="15" icon-class="file" />
</div>
</div>
<div @click="changeCurrentTree(data)">{{ node.label }}</div>
</div>
</div>
</template>
</el-tree>
</el-scrollbar>
</el-card>
<el-card shadow="never" class="mt-1">
<template #header>
<div style="display: flex; align-items: center">
<el-icon><Grid /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>设备操作</span
>
</div>
</template>
<div v-if="currentTree.childNode === false">
<el-form :model="currentTree" v-loading="loading">
<el-descriptions :column="1" border>
<el-descriptions-item
label="参数名称"
label-align="left"
align="left"
label-class-name="my-label"
class-name="my-content"
width="15px"
>
{{ currentTree?.nodePath }}
</el-descriptions-item>
<el-descriptions-item
label="参数值"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="15px"
>
<el-form-item>
<el-input v-model="currentTree.value" />
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
</div>
<div v-else>
<el-descriptions :column="1" border>
<el-descriptions-item
label="路径"
label-align="center"
align="left"
label-class-name="my-label"
class-name="my-content"
width="15px"
>
{{ currentTree?.nodePath }}
</el-descriptions-item>
</el-descriptions>
</div>
<template #footer>
<div class="flex-center">
<div v-if="!currentTree.childNode">
<el-button type="primary" @click="saveParam">保存参数</el-button>
<el-button type="primary" @click="openParamAttribute"
>参数属性</el-button
>
</div>
<div v-else>
<div v-if="currentTree.label != 'InternetGatewayDevice'">
<el-button type="primary" @click="addInstanceNode"
>新增实例</el-button
>
<el-button type="primary" @click="deleteInstanceNode"
>删除实例</el-button
>
</div>
</div>
<div class="ml-2">
<el-button type="danger" plain @click="reboot">远程重启</el-button>
<el-button type="danger" plain @click="factoryReset"
>恢复出厂</el-button
>
</div>
</div>
</template>
</el-card>
<tree-param-attribute ref="treeParamAttributeRef" />
</div>
</template>
<script setup lang="ts">
import { Grid, Loading } from "@element-plus/icons-vue";
import { OptionTree } from "@/api/remote/types";
import {
remoteAddInstanceNode,
remoteDeleteInstanceNode,
remoteFactoryReset,
remoteGetParameterValues,
remoteReboot,
remoteSetParameterValues,
remoteTreeNode,
} from "@/api/remote";
import { confirm } from "@/utils/confirm";
import TreeParamAttribute from "@/views/family/operate/remote-operation/components/TreeParamAttribute.vue";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);
const treeParamAttributeRef = ref();
const deviceTreeRef = ref();
const loading = ref<boolean>(false);
const treeList = ref<OptionTree[]>([
{
label: "InternetGatewayDevice",
nodePath: "InternetGatewayDevice.",
childNode: true,
children: [],
},
]);
const currentTree = ref<OptionTree>({
label: "InternetGatewayDevice",
nodePath: "InternetGatewayDevice.",
childNode: true,
children: [],
});
const handleNodeClick = (data_: OptionTree) => {
loading.value = true;
let nodePath = data_.nodePath;
remoteTreeNode(devId, nodePath)
.then(({ data }) => {
if (!data_.children) {
data_.children = [];
}
data_.children = data;
treeList.value = [...treeList.value];
})
.finally(() => {
loading.value = false;
});
};
const changeCurrentTree = (data: OptionTree) => {
currentTree.value = data;
if (data.childNode) {
return;
}
let nodePath = data.nodePath;
loading.value = true;
remoteGetParameterValues(devId, nodePath)
.then(({ data }) => {
currentTree.value.value = data.value;
})
.finally(() => {
loading.value = false;
});
};
const saveParam = () => {
confirm("确定保存该节点参数", () => {
loading.value = true;
remoteSetParameterValues(
devId,
currentTree.value.nodePath,
<string>currentTree.value.value
)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
const openParamAttribute = () => {
treeParamAttributeRef.value.open(devId, currentTree.value.nodePath);
};
const childNode = ref<OptionTree>({});
const addInstanceNode = () => {
confirm("确定添加实例吗", () => {
loading.value = true;
remoteAddInstanceNode(devId, currentTree.value.nodePath)
.then(({ data }) => {
childNode.value = data;
addInstanceNode_(treeList.value[0], currentTree.value.nodePath);
})
.finally(() => {
loading.value = false;
});
});
};
const deleteInstanceNode = () => {
confirm(`确定删除${currentTree.value.label}实例吗`, () => {
loading.value = true;
remoteDeleteInstanceNode(devId, currentTree.value.nodePath)
.then(() => {
removeInstanceNode_(treeList.value[0], currentTree.value.nodePath);
})
.finally(() => {
loading.value = false;
});
});
};
//
const addInstanceNode_ = (tree: OptionTree, nodePath?: string) => {
// nodePath
if (tree.nodePath === nodePath) {
if (!tree.children) {
tree.children = [];
}
tree.children?.push(childNode.value);
console.log(treeList.value[0]);
return;
}
//
if (tree.children) {
for (const child of tree.children) {
const result = addInstanceNode_(child, nodePath);
if (result) {
return;
}
}
}
// undefined
return undefined;
};
const removeInstanceNode_ = (tree: OptionTree, nodePath?: string) => {
if (!tree.children) return false;
for (let i = 0; i < tree.children.length; i++) {
const child = tree.children[i];
if (child.nodePath === nodePath) {
//
tree.children.splice(i, 1);
return true;
}
//
const result = removeInstanceNode_(child, nodePath);
if (result) {
return true;
}
}
return false;
};
const reboot = () => {
confirm("确认重启设备吗", () => {
loading.value = true;
remoteReboot(devId)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
const factoryReset = () => {
confirm("确认恢复出厂设置吗", () => {
loading.value = true;
remoteFactoryReset(devId)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
</script>
<style scoped>
:deep(.el-card__body) {
padding: 10px 0;
}
:deep(.my-label) {
width: 50px !important;
text-align: center !important;
background: var(--el-color-white) !important;
}
.rotate {
animation: rotate 10s linear infinite;
-webkit-animation: rotate 10s linear infinite;
}
@keyframes rotate {
0% {
transform: rotate(0);
}
25% {
transform: rotate(90deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(270deg);
}
100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes rotate {
0% {
transform: rotate(0);
}
25% {
transform: rotate(90deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(270deg);
}
100% {
transform: rotate(360deg);
}
}
:deep(.el-form-item--default) {
margin-bottom: 0;
}
</style>

@ -115,7 +115,7 @@ import { RemoteOperateResult } from "@/api/remote/types";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);
let pppoe: string = <string>route.params?.pppoe;
let pppoe: string = <string>route.query?.pppoe;
const options = ref<string[]>([]);
const downloadUrl = ref<string>("");
const speedMaxRate = ref<string>("");

@ -5,65 +5,49 @@
<el-dropdown-menu>
<el-scrollbar height="300">
<div v-hasPerm="['family:remote:parameter:tree']">
<el-dropdown-item>设备参数树浏览</el-dropdown-item>
<el-dropdown-item @click="openParamTree"
>参数树浏览</el-dropdown-item
>
</div>
<div v-hasPerm="['family:remote:ping:test']">
<el-dropdown-item @click="openPing" divided
>设备Ping测试
>Ping测试
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:profiles:upload']">
<el-dropdown-item @click="uploadConfig" divided
>设备配置文件上传
>获取配置文件
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:terminal:log_file']">
<el-dropdown-item @click="uploadLog" divided
>获取设备终端日志文件
>获取日志文件
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:dev:change']">
<el-dropdown-item divided>设备更换</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:dev:reload']">
<el-dropdown-item @click="reboot" divided
>设备远程重启
>远程重启
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:factory-reset']">
<el-dropdown-item @click="factoryReset" divided
>恢复设备出厂设置
>远程工厂复位
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:profiles:issued']">
<el-dropdown-item @click="vendorProfile" divided
>设备厂商配置文件下发
>下发配置文件
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:full_service:issued']">
<el-dropdown-item divided>设备全业务配置下发 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:soft_ver:upgrade']">
<el-dropdown-item @click="upgradeSoftVer" divided
>设备软件版本升级
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:loop_back:diagnosis']">
<el-dropdown-item divided>ATMF5Loopback诊断 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:dsl_loop:diagnosis']">
<el-dropdown-item divided>DslLoop诊断</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:dev:monitor']">
<el-dropdown-item @click="deviceMonitor" divided
>设备监控</el-dropdown-item
>
</div>
<div v-hasPerm="['family:remote:ida:diagnosis']">
<el-dropdown-item divided>IAD诊断</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:service_port:binding']">
<el-dropdown-item divided>修改业务端口绑定 </el-dropdown-item>
>设备监控
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:terminal:registration']">
<el-dropdown-item @click="registration" divided
@ -72,42 +56,16 @@
</div>
<div v-hasPerm="['family:remote:speed:operation']">
<el-dropdown-item @click="speedOperate" divided
>测速操作</el-dropdown-item
>
</div>
<div v-hasPerm="['family:remote:reset:graphs']">
<el-dropdown-item divided>终端重置数图 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:iptv:multicast']">
<el-dropdown-item divided>重置IPTV组播 </el-dropdown-item>
>测速操作
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:node:customize']">
<el-dropdown-item @click="customTask" divided
>自定义节点定制
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:broadband_1_4:itv_2_3']">
<el-dropdown-item divided>宽带14;ITV 23 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:broadband_3_4:itv_1_2']">
<el-dropdown-item divided>宽带34;ITV 12 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:broadband_1:itv_2_3_4']">
<el-dropdown-item divided>宽带1口;ITV 234 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:broadband_1_3_4:itv_2']">
<el-dropdown-item divided>宽带134;ITV 2 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:broadband_1_2_3_4']">
<el-dropdown-item divided>宽带1 234 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:broadband_1_3:itv_2']">
<el-dropdown-item divided
>三合一终端宽带13;ITV 2
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:info:update']">
<el-dropdown-item divided>通用信息修改 </el-dropdown-item>
<el-dropdown-item divided>通用信息修改</el-dropdown-item>
</div>
</el-scrollbar>
</el-dropdown-menu>
@ -137,6 +95,11 @@ const openPing = () => {
path: `/resources/remote/ping/${prop.devId}`,
});
};
const openParamTree = () => {
router.push({
path: `/resources/remote/device-param-tree/${prop.devId}`,
});
};
const uploadConfig = () => {
confirm("确认上传配置文件吗", () => {
loading.value = true;
@ -204,7 +167,8 @@ const factoryReset = () => {
};
const speedOperate = () => {
router.push({
path: `/resources/remote/device-speed/${prop.devId}/${prop.pppoe}`,
path: `/resources/remote/device-speed/${prop.devId}`,
query: { pppoe: prop.pppoe },
});
};
const deviceMonitor = () => {

@ -0,0 +1,165 @@
<template>
<el-dialog class="com-dialog" v-model="openFlag" title="修改参数属性">
<el-form :model="formData" v-loading="loading">
<el-descriptions :column="1" border>
<el-descriptions-item
label="参数名称"
label-align="center"
align="left"
label-class-name="my-label"
class-name="my-content"
width="15px"
>
InternetGatewayDevice.DeviceSummary
</el-descriptions-item>
<el-descriptions-item
label="NotificationChange"
label-align="center"
align="left"
label-class-name="my-label"
class-name="my-content"
width="15px"
>
<div class="flex justify-between">
<el-form-item>
<el-checkbox-group v-model="formData.notification">
<el-checkbox value="true">Notification</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-radio-group
v-model="formData.param1"
:disabled="formData.notification?.length != 1"
>
<el-radio value="0">OFF</el-radio>
<el-radio value="1">PASSIVE</el-radio>
<el-radio value="2">ACTIVE</el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-descriptions-item>
<el-descriptions-item
label="AccessListChange"
label-align="center"
align="left"
label-class-name="my-label"
class-name="my-content"
width="15px"
>
<div class="flex justify-between">
<el-form-item>
<el-checkbox-group v-model="formData.accessList">
<el-checkbox value="true">AccessList</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-checkbox-group
v-model="formData.param2"
:disabled="formData.accessList?.length != 1"
>
<el-checkbox value="Subscriber">Subscriber</el-checkbox>
<el-checkbox value="customAttribute"
><el-input v-model="customAttribute" style="width: 130px"
/></el-checkbox>
</el-checkbox-group>
</el-form-item>
</div>
</el-descriptions-item>
</el-descriptions>
</el-form>
<template #footer>
<el-button type="primary" @click="submitForm">确定</el-button>
<el-button @click="openFlag = false">取消</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {
remoteGetParameterAttributes,
remoteSetParameterAttributes,
} from "@/api/remote";
import { confirm } from "@/utils/confirm";
interface ParamAttribute {
accessList?: string[];
notification?: string[];
param1?: string;
param2?: string[];
}
const devId = ref<number>(0);
const nodePath = ref<string>("");
const loading = ref<boolean>(false);
const openFlag = ref<boolean>(false);
const formData = ref<ParamAttribute>({});
const customAttribute = ref<string>("");
const open = (devId_: number, nodePath_: string) => {
formData.value = {
accessList: [],
notification: [],
};
devId.value = devId_;
nodePath.value = nodePath_;
getData(devId_, nodePath_);
openFlag.value = true;
};
const getData = (devId?: number, nodePath?: string) => {
loading.value = true;
remoteGetParameterAttributes(devId, nodePath)
.then(({ data }) => {
let value_: string = <string>data.value;
let attributes = value_.split("|");
formData.value.param1 = attributes[0];
formData.value.param2 = [attributes[1]];
})
.finally(() => {
loading.value = false;
});
};
defineExpose({ open });
const submitForm = () => {
confirm("确定修改参数属性吗", () => {
let argValue = [];
if (formData.value.notification?.length === 1) {
argValue.push("true");
} else {
argValue.push("false");
}
argValue.push(formData.value.param1);
if (formData.value.accessList?.length === 1) {
argValue.push("true");
} else {
argValue.push("false");
}
if (formData.value.param2?.length === 1) {
argValue.push(formData.value.param2[0]);
} else if (formData.value.param2?.length === 2) {
argValue.push(formData.value.param2[0] + "~" + customAttribute.value);
}
loading.value = true;
remoteSetParameterAttributes(
devId.value,
nodePath.value,
argValue.join("|")
)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
</script>
<style scoped>
:deep(.my-label) {
width: 50px !important;
text-align: center !important;
background: var(--el-color-white) !important;
}
</style>
Loading…
Cancel
Save