|
@@ -0,0 +1,358 @@
|
|
|
|
+<script setup lang="ts">
|
|
|
|
+import { ref } from 'vue';
|
|
|
|
+import { message } from 'ant-design-vue';
|
|
|
|
+
|
|
|
|
+import { useRequest } from '@/hooks/request';
|
|
|
|
+import { useViewVisible } from '@/hooks/view-visible';
|
|
|
|
+import { getDeviceGroupList, getDeviceListSimple, queryDevicesList } from '@/api';
|
|
|
|
+
|
|
|
|
+import type { DataSelection, DeviceGroup, DeviceParams, DevicesListItem } from '@/types';
|
|
|
|
+
|
|
|
|
+interface Props {
|
|
|
|
+ form: DataSelection;
|
|
|
|
+ selectType: number;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const props = defineProps<Props>();
|
|
|
|
+const { handleRequest } = useRequest();
|
|
|
|
+const { visible, showView, hideView } = useViewVisible();
|
|
|
|
+const emit = defineEmits(['confirmClick']);
|
|
|
|
+const oneDeviceGroup = ref<DeviceGroup[]>([]);
|
|
|
|
+const twoDeviceGroup = ref<DeviceGroup[]>([]);
|
|
|
|
+const equipmentList = ref<DevicesListItem[]>([]);
|
|
|
|
+const parametersList = ref<DeviceParams[]>([]);
|
|
|
|
+const gradeOne = ref<number | undefined>(undefined);
|
|
|
|
+const gradeTwo = ref<number | undefined>(undefined);
|
|
|
|
+const equipmentId = ref<number | undefined>(undefined);
|
|
|
|
+const equipmentName = ref<string>('');
|
|
|
|
+const parametersId = ref<number | undefined>(undefined);
|
|
|
|
+const parametersCode = ref<string>('');
|
|
|
|
+const parametersName = ref<string>('');
|
|
|
|
+
|
|
|
|
+const addAllGatewayList = (value: number) => {
|
|
|
|
+ handleRequest(async () => {
|
|
|
|
+ const data = await getDeviceGroupList({
|
|
|
|
+ parentId: value,
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (value === -1) {
|
|
|
|
+ oneDeviceGroup.value = data;
|
|
|
|
+ if (data.length) {
|
|
|
|
+ if (props.form.groupId) {
|
|
|
|
+ gradeOne.value = props.form.groupId;
|
|
|
|
+ addAllGatewayList(props.form.groupId);
|
|
|
|
+ } else {
|
|
|
|
+ gradeOne.value = data[0].id;
|
|
|
|
+ addAllGatewayList(data[0].id);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ twoDeviceGroup.value = [];
|
|
|
|
+ gradeTwo.value = undefined;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ twoDeviceGroup.value = data;
|
|
|
|
+ if (data.length) {
|
|
|
|
+ if (props.form.childGroupId) {
|
|
|
|
+ gradeTwo.value = props.form.childGroupId;
|
|
|
|
+ getEquipmentList(props.form.childGroupId);
|
|
|
|
+ } else {
|
|
|
|
+ gradeTwo.value = data[0].id;
|
|
|
|
+ getEquipmentList(data[0].id);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ parametersList.value = [];
|
|
|
|
+ equipmentId.value = undefined;
|
|
|
|
+ equipmentName.value = '';
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const getEquipmentList = (id: number) => {
|
|
|
|
+ handleRequest(async () => {
|
|
|
|
+ const { records } = await queryDevicesList({
|
|
|
|
+ pageIndex: 1,
|
|
|
|
+ pageSize: 99999,
|
|
|
|
+ groupId: id,
|
|
|
|
+ });
|
|
|
|
+ equipmentList.value = records;
|
|
|
|
+ if (records.length) {
|
|
|
|
+ if (props.form.deviceId) {
|
|
|
|
+ equipmentId.value = props.form.deviceId;
|
|
|
|
+ records.forEach((item) => {
|
|
|
|
+ if (item.id === props.form.deviceId) {
|
|
|
|
+ equipmentName.value = item.deviceName;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ getParameters(props.form.deviceId);
|
|
|
|
+ } else {
|
|
|
|
+ equipmentId.value = records[0].id;
|
|
|
|
+ equipmentName.value = records[0].deviceName;
|
|
|
|
+ getParameters(records[0].id);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ parametersList.value = [];
|
|
|
|
+ parametersId.value = undefined;
|
|
|
|
+ parametersCode.value = '';
|
|
|
|
+ parametersName.value = '';
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const getParameters = (id: number) => {
|
|
|
|
+ handleRequest(async () => {
|
|
|
|
+ parametersList.value = await getDeviceListSimple(id);
|
|
|
|
+ if (parametersList.value.length) {
|
|
|
|
+ if (props.form.paramCode) {
|
|
|
|
+ parametersList.value.forEach((item) => {
|
|
|
|
+ if (item.deviceParamCode === props.form.paramCode) {
|
|
|
|
+ parametersId.value = item.id;
|
|
|
|
+ parametersCode.value = item.deviceParamCode;
|
|
|
|
+ parametersName.value = item.deviceParamName;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ parametersId.value = parametersList.value[0].id;
|
|
|
|
+ parametersCode.value = parametersList.value[0].deviceParamCode;
|
|
|
|
+ parametersName.value = parametersList.value[0].deviceParamName;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const addParameters = (id: number, index: number) => {
|
|
|
|
+ if (index === 1) {
|
|
|
|
+ gradeOne.value = id;
|
|
|
|
+ addAllGatewayList(id);
|
|
|
|
+ } else if (index === 2) {
|
|
|
|
+ gradeTwo.value = id;
|
|
|
|
+ getEquipmentList(id);
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const chooseEquipment = (item: DevicesListItem) => {
|
|
|
|
+ equipmentId.value = item.id;
|
|
|
|
+ equipmentName.value = item.deviceName;
|
|
|
|
+ getParameters(item.id);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const chooseParameters = (item: DeviceParams) => {
|
|
|
|
+ parametersId.value = item.id;
|
|
|
|
+ parametersCode.value = item.deviceParamCode;
|
|
|
|
+ parametersName.value = item.deviceParamName;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const okConfirm = () => {
|
|
|
|
+ if (props.selectType === 0) {
|
|
|
|
+ if (!parametersId.value) {
|
|
|
|
+ return message.warning('参数未选择!');
|
|
|
|
+ }
|
|
|
|
+ } else if (props.selectType === 1) {
|
|
|
|
+ if (!equipmentId.value) {
|
|
|
|
+ return message.warning('下属设备未选择!');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ emit('confirmClick', {
|
|
|
|
+ groupId: gradeOne.value,
|
|
|
|
+ childGroupId: gradeTwo.value,
|
|
|
|
+ deviceId: equipmentId.value,
|
|
|
|
+ deviceName: equipmentName.value,
|
|
|
|
+ parametersName: parametersName.value,
|
|
|
|
+ paramCode: parametersCode.value,
|
|
|
|
+ selectType: props.selectType,
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+defineExpose({
|
|
|
|
+ showView,
|
|
|
|
+ hideView,
|
|
|
|
+ addAllGatewayList,
|
|
|
|
+});
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<template>
|
|
|
|
+ <div>
|
|
|
|
+ <AModal
|
|
|
|
+ v-model:open="visible"
|
|
|
|
+ title="选择参数"
|
|
|
|
+ @ok="okConfirm"
|
|
|
|
+ :centered="true"
|
|
|
|
+ :width="selectType === 0 ? 1070 : 814"
|
|
|
|
+ >
|
|
|
|
+ <AFlex class="parameters-content">
|
|
|
|
+ <div class="content-div">
|
|
|
|
+ <AFlex align="center" class="content-div-top">
|
|
|
|
+ <div class="content-div-top-text">设备组一</div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ <div class="content-div-content">
|
|
|
|
+ <AFlex class="no-data" justify="center" align="center" v-if="!oneDeviceGroup.length">暂无数据</AFlex>
|
|
|
|
+ <div v-else v-for="item in oneDeviceGroup" :key="item.id">
|
|
|
|
+ <div @click="addParameters(item.id, 1)">
|
|
|
|
+ <AFlex
|
|
|
|
+ justify="space-between"
|
|
|
|
+ align="center"
|
|
|
|
+ :class="gradeOne === item.id ? 'parameters-dev-bgd' : 'parameters-dev'"
|
|
|
|
+ >
|
|
|
|
+ <div class="parameters-text">{{ item.groupName }}</div>
|
|
|
|
+ <div v-if="gradeOne === item.id">
|
|
|
|
+ <SvgIcon class="icon-style" name="right" />
|
|
|
|
+ </div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="content-div border-radius">
|
|
|
|
+ <AFlex align="center" class="content-div-top">
|
|
|
|
+ <div class="content-div-top-text">设备组二</div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ <div class="content-div-content">
|
|
|
|
+ <AFlex class="no-data" justify="center" align="center" v-if="!twoDeviceGroup.length">暂无数据</AFlex>
|
|
|
|
+ <div v-else v-for="item in twoDeviceGroup" :key="item.id">
|
|
|
|
+ <div @click="addParameters(item.id, 2)">
|
|
|
|
+ <AFlex
|
|
|
|
+ justify="space-between"
|
|
|
|
+ align="center"
|
|
|
|
+ :class="gradeTwo === item.id ? 'parameters-dev-bgd' : 'parameters-dev'"
|
|
|
|
+ >
|
|
|
|
+ <div class="parameters-text">{{ item.groupName }}</div>
|
|
|
|
+ <div v-if="gradeTwo === item.id">
|
|
|
|
+ <SvgIcon class="icon-style" name="right" />
|
|
|
|
+ </div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div :class="selectType === 0 ? 'content-div border-radius' : 'content-div border-radius border-right'">
|
|
|
|
+ <AFlex align="center" class="content-div-top">
|
|
|
|
+ <div class="content-div-top-text">设备组属性/下属设备</div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ <div class="content-div-content">
|
|
|
|
+ <AFlex class="no-data" justify="center" align="center" v-if="!equipmentList.length">暂无数据</AFlex>
|
|
|
|
+ <div v-else v-for="item in equipmentList" :key="item.id">
|
|
|
|
+ <div @click="chooseEquipment(item)">
|
|
|
|
+ <AFlex
|
|
|
|
+ justify="space-between"
|
|
|
|
+ align="center"
|
|
|
|
+ :class="equipmentId === item.id ? 'parameters-dev-bgd' : 'parameters-dev'"
|
|
|
|
+ >
|
|
|
|
+ <div class="parameters-text">{{ item.deviceName }}</div>
|
|
|
|
+ <div v-if="equipmentId === item.id && selectType === 0">
|
|
|
|
+ <SvgIcon class="icon-style" name="right" />
|
|
|
|
+ </div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div v-if="selectType === 0" class="content-div border-radius border-right">
|
|
|
|
+ <AFlex align="center" class="content-div-top">
|
|
|
|
+ <div class="content-div-top-text">参数</div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ <div class="content-div-content">
|
|
|
|
+ <AFlex class="no-data" justify="center" align="center" v-if="!parametersList.length">暂无数据</AFlex>
|
|
|
|
+ <div v-else v-for="item in parametersList" :key="item.id">
|
|
|
|
+ <div @click="chooseParameters(item)">
|
|
|
|
+ <AFlex
|
|
|
|
+ justify="space-between"
|
|
|
|
+ align="center"
|
|
|
|
+ :class="parametersId === item.id ? 'parameters-dev-bgd' : 'parameters-dev'"
|
|
|
|
+ >
|
|
|
|
+ <div class="parameters-text">{{ item.deviceParamName }}</div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </AFlex>
|
|
|
|
+ </AModal>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.no-data {
|
|
|
|
+ height: 100%;
|
|
|
|
+ color: rgb(0 0 0 / 65%);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.parameters-text {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ font-style: normal;
|
|
|
|
+ font-weight: 400;
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ color: rgb(0 0 0 / 65%);
|
|
|
|
+ text-align: left;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.icon-style {
|
|
|
|
+ margin-top: 5px;
|
|
|
|
+ color: #8c94a8;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.parameters-dev {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 48px;
|
|
|
|
+ padding: 0 12px 0 16px;
|
|
|
|
+ margin-top: 8px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ background: #fff;
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.parameters-dev-bgd {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 48px;
|
|
|
|
+ padding: 0 12px 0 16px;
|
|
|
|
+ margin-top: 8px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ background: rgb(50 186 192 / 15%);
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.content-div-content {
|
|
|
|
+ height: 375px;
|
|
|
|
+ padding: 0 8px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ overflow: hidden auto; /* 隐藏水平滚动条 */ /* 只显示垂直滚动条 */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.content-div-top-text {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ font-style: normal;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ color: #000;
|
|
|
|
+ text-align: left;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.content-div-top {
|
|
|
|
+ height: 56px;
|
|
|
|
+ padding-left: 24px;
|
|
|
|
+ background: #f5f6f7;
|
|
|
|
+ border-radius: 4px 0 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.content-div {
|
|
|
|
+ width: 256px;
|
|
|
|
+ height: 436px;
|
|
|
|
+ background: #fff;
|
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
|
+ border-right: none;
|
|
|
|
+ border-radius: 4px 0 0 4px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.border-radius {
|
|
|
|
+ border-radius: 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.border-right {
|
|
|
|
+ border-right: 1px solid #e4e7ed;
|
|
|
|
+ border-radius: 0 4px 4px 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.parameters-content {
|
|
|
|
+ height: 470px;
|
|
|
|
+ padding-top: 16px;
|
|
|
|
+}
|
|
|
|
+</style>
|