UPDATE: 重构检修计划选择被检设备组件,并处理对应数据逻辑
This commit is contained in:
@@ -1,123 +1,119 @@
|
||||
import type {ReqPage, ResPage} from '@/api/interface'
|
||||
import type { Monitor } from './monitor';
|
||||
import type { ReqPage, ResPage } from '@/api/interface'
|
||||
import type { Monitor } from './monitor'
|
||||
|
||||
// 被检设备模块
|
||||
export namespace Device {
|
||||
|
||||
/**
|
||||
* 被检设备表格分页查询参数
|
||||
*/
|
||||
export interface ReqPqDevParams extends ReqPage {
|
||||
id: string; // 装置序号id 必填
|
||||
name: string; //设备名称
|
||||
devType?: string; // 设备名称
|
||||
createTime?: string; //创建时间
|
||||
pattern: string;
|
||||
id: string // 装置序号id 必填
|
||||
name: string //设备名称
|
||||
devType?: string // 设备名称
|
||||
createTime?: string //创建时间
|
||||
pattern: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 被检设备表格分页查询参数
|
||||
*/
|
||||
export interface ReqDevReportParams extends ReqPage {
|
||||
planId?: string; // 计划id
|
||||
devId?: string; // 装置id
|
||||
scriptId?: string; // 脚本id
|
||||
planCode?: string;
|
||||
devIdList?: string[]; // 装置id列表
|
||||
planId?: string // 计划id
|
||||
devId?: string // 装置id
|
||||
scriptId?: string // 脚本id
|
||||
planCode?: string
|
||||
devIdList?: string[] // 装置id列表
|
||||
}
|
||||
|
||||
/**
|
||||
* 被检设备新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResPqDev {
|
||||
id: string; //装置序号ID
|
||||
name: string; //设备名称
|
||||
pattern: string; //设备模式 模拟 数字 比对
|
||||
devType: string;//设备类型
|
||||
manufacturer?: string | null;//生产厂家
|
||||
createDate: string; //生产日期
|
||||
createId: string; //出厂编号
|
||||
hardwareVersion: string; //固件版本
|
||||
softwareVersion: string; //软件版本
|
||||
protocol: string; //通讯协议
|
||||
ip: string; //IP地址
|
||||
port: number; //端口号
|
||||
encryptionFlag: number; //装置是否为加密版本
|
||||
series?: string | null; //装置识别码(3ds加密)
|
||||
devKey?: string | null; //装置秘钥(3ds加密)
|
||||
sampleId?: string | null; //样品编号
|
||||
arrivedDate?: string; //送样日期
|
||||
cityName?: string | null; //所属地市名称
|
||||
gdName?: string | null; //所属供电公司名称
|
||||
subName?: string | null; //所属电站名称
|
||||
reportPath?: string | null; //报告路径
|
||||
planId?: string;//检测计划Id
|
||||
factorFlag?: number;//是否支持系数校准(0:不支持,1:支持)
|
||||
preinvestmentPlan: string | null;//预投计划
|
||||
delegate: string | null; //委托方
|
||||
inspectChannel?: string[] | string;//被检通道
|
||||
inspectDate?: string | null;//定检日期
|
||||
harmSysId?: string | null;//谐波系统设备id
|
||||
importFlag?: number;//是否为导入设备 0否 1是
|
||||
state: number; //状态
|
||||
createBy?: string | null; //创建用户
|
||||
createTime?: string | null; //创建时间
|
||||
updateBy?: string | null; //更新用户
|
||||
updateTime?: string | null; //更新时间
|
||||
|
||||
devChns: number; //设备通道数
|
||||
devVolt: number; //额定电压(V)
|
||||
devCurr: number; //额定电流(A)
|
||||
icdId: string | null;
|
||||
power: string | null;//工作电源
|
||||
id: string //装置序号ID
|
||||
name: string //设备名称
|
||||
pattern: string //设备模式 模拟 数字 比对
|
||||
devType: string //设备类型
|
||||
manufacturer?: string | null //生产厂家
|
||||
createDate: string //生产日期
|
||||
createId: string //出厂编号
|
||||
hardwareVersion: string //固件版本
|
||||
softwareVersion: string //软件版本
|
||||
protocol: string //通讯协议
|
||||
ip: string //IP地址
|
||||
port: number //端口号
|
||||
encryptionFlag: number //装置是否为加密版本
|
||||
series?: string | null //装置识别码(3ds加密)
|
||||
devKey?: string | null //装置秘钥(3ds加密)
|
||||
sampleId?: string | null //样品编号
|
||||
arrivedDate?: string //送样日期
|
||||
cityName?: string | null //所属地市名称
|
||||
gdName?: string | null //所属供电公司名称
|
||||
subName?: string | null //所属电站名称
|
||||
reportPath?: string | null //报告路径
|
||||
planId?: string //检测计划Id
|
||||
factorFlag?: number //是否支持系数校准(0:不支持,1:支持)
|
||||
preinvestmentPlan: string | null //预投计划
|
||||
delegate: string | null //委托方
|
||||
inspectChannel?: string[] | string //被检通道
|
||||
inspectDate?: string | null //定检日期
|
||||
harmSysId?: string | null //谐波系统设备id
|
||||
importFlag?: number //是否为导入设备 0否 1是
|
||||
state: number //状态
|
||||
createBy?: string | null //创建用户
|
||||
createTime?: string | null //创建时间
|
||||
updateBy?: string | null //更新用户
|
||||
updateTime?: string | null //更新时间
|
||||
|
||||
devId?: number;
|
||||
checkState?: number | null; //检测状态(0:未检,1:检测中,2:检测完成 3:归档)
|
||||
checkResult?: number | null; //检测结果(0:不符合,1:符合,2:未检)
|
||||
reportState?: number | null; //报告状态(0:未生成,1:已生成,2:未检)
|
||||
recheckNum: number; //复检次数
|
||||
timeCheckResult?: number;//守时检测结果(0:不符合1:符合)
|
||||
factorCheckResult?: number;//系数校准结果(0:不合格,1:合格,2:未检)
|
||||
realtimeResult?: number;//实时数据结论(0:不符合,1:符合,2:未检)
|
||||
statisticsResult?: number;//统计数据结论(0:不符合,1:符合,2:未检)
|
||||
recordedResult?: number;//录波数据结论(0:不符合,1:符合,2:未检)
|
||||
checkBy?: string | null;//检测人
|
||||
checkTime?: string | null;//检测时间
|
||||
preDetectTime?: number;//预检测耗时
|
||||
coefficientTime?: number;//系数校准耗时
|
||||
formalCheckTime?: number;//正式检测耗时
|
||||
devChns: number //设备通道数
|
||||
devVolt: number //额定电压(V)
|
||||
devCurr: number //额定电流(A)
|
||||
icdId: string | null
|
||||
power: string | null //工作电源
|
||||
|
||||
boundPlanName?: string| null;
|
||||
assign?: number;////是否分配给检测人员 0否 1是
|
||||
monitorList: Monitor.ResPqMon[] ;
|
||||
devId?: number
|
||||
checkState?: number | null //检测状态(0:未检,1:检测中,2:检测完成 3:归档)
|
||||
checkResult?: number | null //检测结果(0:不符合,1:符合,2:未检)
|
||||
reportState?: number | null //报告状态(0:未生成,1:已生成,2:未检)
|
||||
recheckNum: number //复检次数
|
||||
timeCheckResult?: number //守时检测结果(0:不符合1:符合)
|
||||
factorCheckResult?: number //系数校准结果(0:不合格,1:合格,2:未检)
|
||||
realtimeResult?: number //实时数据结论(0:不符合,1:符合,2:未检)
|
||||
statisticsResult?: number //统计数据结论(0:不符合,1:符合,2:未检)
|
||||
recordedResult?: number //录波数据结论(0:不符合,1:符合,2:未检)
|
||||
checkBy?: string | null //检测人
|
||||
checkTime?: string | null //检测时间
|
||||
preDetectTime?: number //预检测耗时
|
||||
coefficientTime?: number //系数校准耗时
|
||||
formalCheckTime?: number //正式检测耗时
|
||||
|
||||
boundPlanName?: string | null
|
||||
assign?: number ////是否分配给检测人员 0否 1是
|
||||
monitorList: Monitor.ResPqMon[]
|
||||
checked: boolean // 是否已选择
|
||||
disabled: boolean // 是否禁用
|
||||
}
|
||||
|
||||
export interface SelectOption {
|
||||
label: string;
|
||||
value: string | number;
|
||||
label: string
|
||||
value: string | number
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface ResDev {
|
||||
id: string;
|
||||
name: string,
|
||||
icd: string,
|
||||
power: string,
|
||||
devVolt: number,
|
||||
devCurr: number,
|
||||
devChns: number,
|
||||
id: string
|
||||
name: string
|
||||
icd: string
|
||||
power: string
|
||||
devVolt: number
|
||||
devCurr: number
|
||||
devChns: number
|
||||
}
|
||||
|
||||
export interface ResTH {
|
||||
temperature :number | null;//温度
|
||||
humidity:number | null;//湿度
|
||||
temperature: number | null //温度
|
||||
humidity: number | null //湿度
|
||||
}
|
||||
/**
|
||||
* 被检设备表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResPqDevPage extends ResPage<ResPqDev> {
|
||||
|
||||
}
|
||||
export interface ResPqDevPage extends ResPage<ResPqDev> {}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ export const getBoundStandardDevList = (params: Plan.ResPlan) => {
|
||||
}
|
||||
|
||||
//根据计划ID获取已绑定的所有标准设备
|
||||
export const getBoundStandardDevAllList = (params: Plan.ResPlan) => {
|
||||
export const getBoundStandardDevAllList = (params: { id: string }) => {
|
||||
return http.get(`/adPlan/getBoundStandardDev?planId=${params.id}&all=1`)
|
||||
}
|
||||
|
||||
@@ -134,10 +134,11 @@ export const importSubPlan = (params: Plan.ResPlan) => {
|
||||
return http.upload(`/adPlan/importSubPlan`, params)
|
||||
}
|
||||
|
||||
|
||||
// 导出计划检测结果数据
|
||||
export const exportPlanCheckData = (params: any) => {
|
||||
return http.download(`/adPlan/exportPlanCheckData?planId=${params.id}&devIds=${params.devIds}&report=${params.report}`)
|
||||
return http.download(
|
||||
`/adPlan/exportPlanCheckData?planId=${params.id}&devIds=${params.devIds}&report=${params.report}`
|
||||
)
|
||||
}
|
||||
|
||||
// 导入子检测计划检测结果数据
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import http from '@/api'
|
||||
import {type VersionRegister} from '@/api/system/versionRegister/interface'
|
||||
import { type VersionRegister } from '@/api/system/versionRegister/interface'
|
||||
|
||||
//获取有效数据配置
|
||||
export const getRegRes = (params: VersionRegister.ResSys_Reg_Res) => {
|
||||
export const getRegRes = (params: { type: string }) => {
|
||||
return http.get(`/sysRegRes/getRegResByType?id=${params.type}`)
|
||||
}
|
||||
|
||||
|
||||
//编辑有效数据配置
|
||||
export const updateRegRes = (params: VersionRegister.Sys_Reg_Res) => {
|
||||
return http.post(`/sysRegRes/update`, params)
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" :title="parameter.title" :destroy-on-close="true" width="580px" draggable>
|
||||
<el-form class="drawer-multiColumn-form" style="margin-top: 10px" label-width="100px">
|
||||
<el-form-item label="文件上传:">
|
||||
<el-dialog v-model="dialogVisible" :title="parameter.title" :destroy-on-close="true" width="450px" draggable>
|
||||
<el-form class="drawer-multiColumn-form" label-width="100px">
|
||||
<el-form-item label="">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action="#"
|
||||
class="upload"
|
||||
drag
|
||||
:http-request="uploadZip"
|
||||
accept=".zip"
|
||||
:auto-upload="!parameter.confirmMessage"
|
||||
@@ -18,8 +17,7 @@
|
||||
<upload-filled />
|
||||
</el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或
|
||||
<em>点击上传</em>
|
||||
<spam>点击上传</spam>
|
||||
</div>
|
||||
</slot>
|
||||
<template #tip>
|
||||
|
||||
305
frontend/src/views/plan/planList/components/devSelect.vue
Normal file
305
frontend/src/views/plan/planList/components/devSelect.vue
Normal file
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-card header-class="card-header" body-class="card-body" footer-class="card-footer">
|
||||
<template #header>
|
||||
<el-text size="large">{{ props.title }}</el-text>
|
||||
<el-text type="info" size="small">{{ statistics.checked }}/{{ statistics.total }}</el-text>
|
||||
</template>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<el-checkbox
|
||||
:disabled="props.disabled"
|
||||
size="small"
|
||||
v-model="filter.checkAll"
|
||||
label="全选"
|
||||
></el-checkbox>
|
||||
<el-input
|
||||
style="width: 82%; margin: 0 10px"
|
||||
size="small"
|
||||
v-model="filter.text"
|
||||
:placeholder="props.filterPlaceholder"
|
||||
/>
|
||||
<el-dropdown size="small" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
<el-icon size="16"><Filter /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="">默认</el-dropdown-item>
|
||||
<el-dropdown-item command="manufacturer">设备厂家</el-dropdown-item>
|
||||
<el-dropdown-item command="cityName">所属地市</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
show-checkbox
|
||||
accordion
|
||||
default-expand-all
|
||||
:data="treeData"
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
:style="{ marginTop: '20px', height: `${props.height}px` }"
|
||||
@check-change="handleCheckChange"
|
||||
>
|
||||
<template #empty>
|
||||
<el-empty :image-size="80" description="暂无可选设备" />
|
||||
</template>
|
||||
<template #default="{ node, data }">
|
||||
<div v-if="data.id.startsWith('manufacturer')" style="display: flex; align-items: center">
|
||||
<el-icon><OfficeBuilding /></el-icon>
|
||||
<span style="margin-left: 4px">{{ data.label }}</span>
|
||||
</div>
|
||||
<div v-else-if="data.id.startsWith('cityName')" style="display: flex; align-items: center">
|
||||
<el-icon><Location /></el-icon>
|
||||
<span style="margin-left: 4px">{{ data.label }}</span>
|
||||
</div>
|
||||
<div v-else style="flex: 1; display: flex; align-items: center; justify-content: space-between">
|
||||
<span>
|
||||
<el-icon><Cpu /></el-icon>
|
||||
<span v-if="node.level === 1" style="margin-left: 4px">
|
||||
{{ data.cityName + ' - ' + data.manufacturer + ' - ' + data.name }}
|
||||
</span>
|
||||
<span v-if="node.level === 2" style="margin-left: 4px">
|
||||
{{ data.name }}
|
||||
</span>
|
||||
</span>
|
||||
<el-tooltip effect="light" placement="top">
|
||||
<template #content>
|
||||
<el-descriptions border size="small" title="被检设备详情">
|
||||
<el-descriptions-item label="设备名称">
|
||||
{{ data.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备厂家">
|
||||
{{ data.manufacturer }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属地市">
|
||||
{{ data.cityName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属供电公司">
|
||||
{{ data.gdName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属电站">
|
||||
{{ data.subName }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
<el-icon>
|
||||
<Warning />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
<!-- 传递 footer 插槽到 el-card -->
|
||||
<template #footer>
|
||||
<slot name="footer"></slot>
|
||||
</template>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script lang="ts" name="DevSelect" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import type { FilterNodeMethodFunction, TreeInstance } from 'element-plus'
|
||||
|
||||
interface Tree {
|
||||
[key: string]: any
|
||||
}
|
||||
interface Device {
|
||||
id: string
|
||||
name: string
|
||||
checked: boolean
|
||||
importFlag: number
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
const modelValue = defineModel<string[]>({ default: [] })
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array as unknown as PropType<Device[]>,
|
||||
default: (): Device[] => []
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 240
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
filterPlaceholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const treeRef = ref<TreeInstance>()
|
||||
const treeData = ref<Tree[]>([])
|
||||
const defaultCheckedKeys = ref<string[]>([])
|
||||
const filter = ref({
|
||||
groupBy: '',
|
||||
text: '',
|
||||
checkAll: false
|
||||
})
|
||||
const statistics = ref({
|
||||
total: 0,
|
||||
checked: 0
|
||||
})
|
||||
const disabledKeys = ref<string[]>([])
|
||||
onMounted(() => {
|
||||
if (props.data) {
|
||||
initTree(props.data)
|
||||
}
|
||||
})
|
||||
watch(
|
||||
() => props.data,
|
||||
(newVal: Device[]) => {
|
||||
if (newVal) {
|
||||
initTree(newVal)
|
||||
}
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => filter.value.checkAll,
|
||||
val => {
|
||||
setCheckedStatus(val)
|
||||
if (val) {
|
||||
statistics.value.checked = statistics.value.total
|
||||
} else {
|
||||
statistics.value.checked = treeRef.value?.getCheckedNodes().length || 0
|
||||
}
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => filter.value.text,
|
||||
val => {
|
||||
treeRef.value!.filter(val)
|
||||
}
|
||||
)
|
||||
const initTree = (data: Device[]) => {
|
||||
disabledKeys.value = data.filter(item => item.disabled).map(item => item.id)
|
||||
if (disabledKeys.value.length > 0) {
|
||||
modelValue.value = []
|
||||
}
|
||||
treeData.value = convertToTree(data, filter.value.groupBy)
|
||||
defaultCheckedKeys.value = data.filter(item => item.checked).map(item => item.id)
|
||||
statistics.value.checked = defaultCheckedKeys.value.length
|
||||
statistics.value.total = data.length
|
||||
if (statistics.value.total > 0) {
|
||||
filter.value.checkAll = statistics.value.checked === statistics.value.total
|
||||
}
|
||||
}
|
||||
const setCheckedStatus = (checked: boolean) => {
|
||||
treeData.value.forEach(item => {
|
||||
if (!disabledKeys.value.includes(item.id)) {
|
||||
treeRef.value?.setChecked(item.id, checked, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
const convertToTree = (data: any[], groupBy?: string | undefined) => {
|
||||
if (groupBy) {
|
||||
// 创建一个映射来存储每个分组
|
||||
const groupMap = new Map()
|
||||
|
||||
// 遍历数据,根据groupBy字段值进行分组
|
||||
data.forEach(item => {
|
||||
const groupValue = item[groupBy] || '未分组'
|
||||
if (!groupMap.has(groupValue)) {
|
||||
groupMap.set(groupValue, [])
|
||||
}
|
||||
groupMap.get(groupValue).push(item)
|
||||
})
|
||||
|
||||
// 将分组转换为树形结构
|
||||
const treeData: Tree[] = []
|
||||
groupMap.forEach((items, groupName) => {
|
||||
const groupNode: Tree = {
|
||||
id: `${groupBy}_${groupName}`,
|
||||
label: groupName,
|
||||
disabled: props.disabled,
|
||||
children: (items as any[]).map((item: any) => ({
|
||||
label: item.name,
|
||||
children: [],
|
||||
disabled: item.disabled ? item.disabled : props.disabled,
|
||||
...item
|
||||
}))
|
||||
}
|
||||
treeData.push(groupNode)
|
||||
})
|
||||
|
||||
return treeData
|
||||
} else {
|
||||
return data.map(item => {
|
||||
const treeItem: Tree = {
|
||||
label: item.name,
|
||||
children: [],
|
||||
disabled: item.disabled ? item.disabled : props.disabled,
|
||||
...item
|
||||
}
|
||||
return treeItem
|
||||
})
|
||||
}
|
||||
}
|
||||
const filterNode: FilterNodeMethodFunction = (value: string, data: Tree) => {
|
||||
if (!value) return true
|
||||
return data.label.includes(value)
|
||||
}
|
||||
const handleCommand = (command: string) => {
|
||||
filter.value.groupBy = command
|
||||
const oldCheckedKeys = treeRef.value?.getCheckedKeys() || []
|
||||
treeData.value = convertToTree(props.data, filter.value.groupBy)
|
||||
treeRef.value?.setCheckedKeys(oldCheckedKeys)
|
||||
if (filter.value.checkAll) {
|
||||
setCheckedStatus(true)
|
||||
}
|
||||
}
|
||||
const handleCheckChange = () => {
|
||||
const checkedKeys = treeRef.value?.getCheckedKeys().filter(item => !item.toString().includes('_')) || []
|
||||
|
||||
modelValue.value = checkedKeys
|
||||
.filter(key => !disabledKeys.value.includes(key.toString()))
|
||||
.map(key => key.toString())
|
||||
statistics.value.checked = checkedKeys.length || 0
|
||||
filter.value.checkAll = statistics.value.checked === statistics.value.total
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--el-color-info-light-9);
|
||||
margin: 0;
|
||||
padding: 10px 15px;
|
||||
color: var(--el-color-black);
|
||||
border: 1px solid var(--el-border-color);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
margin: 0;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: var(--el-color-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -10,7 +10,7 @@
|
||||
>
|
||||
<el-form ref="dialogFormRef" :model="formContent" :rules="rules">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="10">
|
||||
<el-col :span="12">
|
||||
<el-form-item :label-width="110" label="名称" prop="name">
|
||||
<el-input
|
||||
v-model="formContent.name"
|
||||
@@ -122,7 +122,7 @@
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择误差体系"
|
||||
@change="handleErrorSysChange"
|
||||
@change="handleErrorSysChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="(option, index) in pqErrorArray"
|
||||
@@ -181,81 +181,42 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-transfer
|
||||
v-model="value"
|
||||
:data="allData"
|
||||
:filter-method="filterMethod"
|
||||
:titles="['未绑定被检设备', '已绑定被检设备']"
|
||||
<el-col :span="12">
|
||||
<DevSelect
|
||||
v-model="formContent.devIds"
|
||||
title="被检设备列表"
|
||||
filter-placeholder="请输入内容搜索"
|
||||
filterable
|
||||
:data="devData"
|
||||
:height="250"
|
||||
:disabled="allDisabled"
|
||||
>
|
||||
<template #default="{ option }">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
<span>
|
||||
{{ JSON.parse(option.label).manufacturer }} - {{ JSON.parse(option.label).name }}
|
||||
</span>
|
||||
<el-tooltip effect="light" placement="top">
|
||||
<template #content>
|
||||
<el-descriptions border size="small" title="被检设备详情">
|
||||
<el-descriptions-item label="设备名称">
|
||||
{{ JSON.parse(option.label).name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备厂家">
|
||||
{{ JSON.parse(option.label).manufacturer }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属地市">
|
||||
{{ JSON.parse(option.label).cityName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属供电公司">
|
||||
{{ JSON.parse(option.label).gdName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属电站">
|
||||
{{ JSON.parse(option.label).subName }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
<el-icon>
|
||||
<Warning />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<template v-if="planType === 0 && !allDisabled" #footer>
|
||||
<div style="text-align: right">
|
||||
<el-button
|
||||
v-if="modeStore.currentMode !== '比对式'"
|
||||
v-auth.plan="'import'"
|
||||
icon="Download"
|
||||
class="transfer-footer"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="importFile('')"
|
||||
>
|
||||
导入被检设备
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="modeStore.currentMode === '比对式'"
|
||||
v-auth.plan="'import'"
|
||||
icon="Download"
|
||||
class="transfer-footer"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="importFile('比对式')"
|
||||
>
|
||||
导入被检设备
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="planType === 0 && !allDisabled" #left-footer>
|
||||
<el-button
|
||||
v-if="modeStore.currentMode !== '比对式'"
|
||||
v-auth.plan="'import'"
|
||||
:icon="Download"
|
||||
class="transfer-footer"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="importFile('')"
|
||||
>
|
||||
导入被检设备
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="modeStore.currentMode === '比对式'"
|
||||
v-auth.plan="'import'"
|
||||
:icon="Download"
|
||||
class="transfer-footer"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="importFile('比对式')"
|
||||
>
|
||||
导入被检设备
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-if="planType === 0 && !allDisabled" #right-footer>
|
||||
<el-text></el-text>
|
||||
</template>
|
||||
<template #left-empty>
|
||||
<el-empty :image-size="60" description="暂无被检设备" />
|
||||
</template>
|
||||
<template #right-empty>
|
||||
<el-empty :image-size="60" description="暂无被检设备" />
|
||||
</template>
|
||||
</el-transfer>
|
||||
</DevSelect>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -274,7 +235,7 @@
|
||||
<el-input-number
|
||||
:disabled="isSelectDisabled || allDisabled"
|
||||
style="width: 240px"
|
||||
v-model="formContent.testConfig.maxTime"
|
||||
v-model="formContent.testConfig!.maxTime"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
@@ -292,7 +253,7 @@
|
||||
<el-input-number
|
||||
:disabled="isSelectDisabled || allDisabled"
|
||||
style="width: 240px"
|
||||
v-model="formContent.testConfig.waveRecord"
|
||||
v-model="formContent.testConfig!.waveRecord"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
@@ -310,7 +271,7 @@
|
||||
<el-input-number
|
||||
:disabled="isSelectDisabled || allDisabled"
|
||||
style="width: 240px"
|
||||
v-model="formContent.testConfig.realTime"
|
||||
v-model="formContent.testConfig!.realTime"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
@@ -328,7 +289,7 @@
|
||||
<el-input-number
|
||||
:disabled="isSelectDisabled || allDisabled"
|
||||
style="width: 240px"
|
||||
v-model="formContent.testConfig.statistics"
|
||||
v-model="formContent.testConfig!.statistics"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
@@ -346,7 +307,7 @@
|
||||
<el-input-number
|
||||
:disabled="isSelectDisabled || allDisabled"
|
||||
style="width: 240px"
|
||||
v-model="formContent.testConfig.flicker"
|
||||
v-model="formContent.testConfig!.flicker"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
@@ -371,7 +332,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { CascaderOption, ElMessage, type FormItemRule } from 'element-plus'
|
||||
import { type CascaderOption, ElMessage, type FormItemRule } from 'element-plus'
|
||||
import { computed, defineProps, reactive, ref } from 'vue'
|
||||
import { dialogBig } from '@/utils/elementBind'
|
||||
import { type Plan } from '@/api/plan/interface'
|
||||
@@ -380,31 +341,28 @@ import {
|
||||
getBoundPqDevList,
|
||||
getBoundStandardDevAllList,
|
||||
getPqErrSysList,
|
||||
getPqErrSysTestItemList,
|
||||
getPqScriptList,
|
||||
getTestSourceList,
|
||||
getUnboundPqDevList,
|
||||
updatePlan,
|
||||
getPqErrSysTestItemList
|
||||
} from '@/api/plan/plan.ts'
|
||||
updatePlan
|
||||
} from '@/api/plan/plan'
|
||||
import { useDictStore } from '@/stores/modules/dict'
|
||||
import { type TestSource } from '@/api/device/interface/testSource'
|
||||
import { type TestScript } from '@/api/device/interface/testScript'
|
||||
import { type ErrorSystem } from '@/api/device/interface/error'
|
||||
import { type Device } from '@/api/device/interface/device'
|
||||
import { getPqReportAllName } from '@/api/device/report/index.ts'
|
||||
import { getPqReportAllName } from '@/api/device/report/index'
|
||||
import { useAppSceneStore, useModeStore } from '@/stores/modules/mode'
|
||||
import { Download } from '@element-plus/icons-vue'
|
||||
import { getAllPqStandardDev } from '@/api/device/standardDevice/index.ts'
|
||||
import { StandardDevice } from '@/api/device/interface/standardDevice'
|
||||
import { Dict } from '@/api/system/dictionary/interface'
|
||||
import { getDictTreeByCode } from '@/api/system/dictionary/dictTree'
|
||||
import { getAllPqStandardDev } from '@/api/device/standardDevice/index'
|
||||
import { type StandardDevice } from '@/api/device/interface/standardDevice'
|
||||
import { type Dict } from '@/api/system/dictionary/interface'
|
||||
import { getAllUser } from '@/api/user/user'
|
||||
import ImportExcel from '@/components/ImportExcel/index.vue'
|
||||
import { downloadTemplate, importPqDev } from '@/api/device/device/index'
|
||||
import { getTestConfig } from '@/api/system/base'
|
||||
import { getRegRes } from '@/api/system/versionRegister'
|
||||
|
||||
|
||||
const modeStore = useModeStore()
|
||||
const AppSceneStore = useAppSceneStore()
|
||||
const dictStore = useDictStore()
|
||||
@@ -423,15 +381,13 @@ const pqReportName = ref<{ name: string }[]>([])
|
||||
const pqSourceArray = ref<{ label: string; value: string }[]>()
|
||||
const pqScriptArray = ref<{ label: string; value: string }[]>()
|
||||
const pqErrorArray = ref<{ label: string; value: string }[]>()
|
||||
const pqDevArray = ref<{ label: string; value: string }[]>()
|
||||
const pqStandardDevArray = ref<{ label: string; value: string }[]>()
|
||||
const secondLevelOptions: any[] = []
|
||||
const userArray = ref<{ label: string; value: string }[]>([])
|
||||
|
||||
const unboundPqDevList = ref<Device.ResPqDev[]>([]) //指定模式下所有未绑定的设备
|
||||
const boundPqDevList = ref<Device.ResPqDev[]>([]) //根据检测计划id查询出所有已绑定的设备
|
||||
const value = ref<string[]>([])
|
||||
const allData = ref<[any[], any[]]>([])
|
||||
const devData = ref<any[]>([])
|
||||
const isSelectDisabled = ref(false)
|
||||
const planType = ref<number>(0)
|
||||
const subPlanBindStandardDev = ref<any>([]) //哪些标准设备已经被子计划绑定
|
||||
@@ -439,7 +395,11 @@ const activeNames = ref(['1'])
|
||||
const allDisabled = ref(false)
|
||||
const generateData = () => {
|
||||
const manufacturerDict = dictStore.getDictData('Dev_Manufacturers')
|
||||
unboundPqDevList.value.forEach(i => {
|
||||
|
||||
const boundPqDevIds: string[] = boundPqDevList.value.map(i => i.id)
|
||||
const allPqDevList = [...unboundPqDevList.value, ...boundPqDevList.value]
|
||||
|
||||
allPqDevList.forEach(i => {
|
||||
// 确保字段不为空且字典存在再进行查找
|
||||
if (i.manufacturer && manufacturerDict) {
|
||||
const manufacturer = manufacturerDict.find(item => item.id === i.manufacturer)
|
||||
@@ -447,42 +407,14 @@ const generateData = () => {
|
||||
i.manufacturer = manufacturer.name
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const unboundData = unboundPqDevList.value.map((i: Device.ResPqDev) => ({
|
||||
key: i.id,
|
||||
label: JSON.stringify(i),
|
||||
disabled: allDisabled.value
|
||||
}))
|
||||
boundPqDevList.value.forEach(i => {
|
||||
// 确保字段不为空且字典存在再进行查找
|
||||
if (i.manufacturer && manufacturerDict) {
|
||||
const manufacturer = manufacturerDict.find(item => item.id === i.manufacturer)
|
||||
if (manufacturer) {
|
||||
i.manufacturer = manufacturer.name
|
||||
}
|
||||
i.checked = boundPqDevIds.includes(i.id)
|
||||
if (i.assign) {
|
||||
i.disabled = i.checkState != 0 || i.assign == 1 || allDisabled.value
|
||||
} else {
|
||||
i.disabled = allDisabled.value
|
||||
}
|
||||
})
|
||||
const boundData = boundPqDevList.value.map((i: Device.ResPqDev) => ({
|
||||
key: i.id,
|
||||
label: JSON.stringify(i),
|
||||
//tips: i.description
|
||||
disabled: i.checkState != 0 || i.assign == 1 || allDisabled.value
|
||||
}))
|
||||
allData.value = [...unboundData, ...boundData]
|
||||
}
|
||||
|
||||
const filterMethod = (query: string, item: { label?: string }) => {
|
||||
const dataJSON = item.label ? JSON.parse(item.label) : {}
|
||||
|
||||
return (
|
||||
(dataJSON.name?.toLowerCase().includes(query.toLowerCase()) ||
|
||||
dataJSON.manufacturer?.toLowerCase().includes(query.toLowerCase()) ||
|
||||
dataJSON.subName?.toLowerCase().includes(query.toLowerCase()) ||
|
||||
dataJSON.gdName?.toLowerCase().includes(query.toLowerCase()) ||
|
||||
dataJSON.cityName?.toLowerCase().includes(query.toLowerCase())) ??
|
||||
false
|
||||
)
|
||||
devData.value = allPqDevList
|
||||
}
|
||||
|
||||
function useMetaInfo() {
|
||||
@@ -621,7 +553,6 @@ const rules = computed(() => {
|
||||
|
||||
// 关闭弹窗
|
||||
const close = () => {
|
||||
value.value = []
|
||||
dialogVisible.value = false
|
||||
// 清空dialogForm中的值
|
||||
resetFormContent()
|
||||
@@ -636,7 +567,6 @@ const save = () => {
|
||||
try {
|
||||
dialogFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
formContent.devIds = value.value
|
||||
if (formContent.id) {
|
||||
// 把数据处理原则转成字典ID
|
||||
const patternItem = dictStore
|
||||
@@ -650,9 +580,6 @@ const save = () => {
|
||||
if (planType.value == 1) {
|
||||
formContent.fatherPlanId = formContent.id
|
||||
formContent.id = ''
|
||||
//formContent.devIds = []
|
||||
//formContent.standardDevIds = []
|
||||
// formContent.standardDevMap = new Map<string, number>()
|
||||
await addPlan(formContent)
|
||||
emit('update:tab')
|
||||
// 编辑子计划
|
||||
@@ -709,7 +636,6 @@ const save = () => {
|
||||
|
||||
// 打开弹窗,可能是新增,也可能是编辑
|
||||
const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan: number) => {
|
||||
|
||||
unboundPqDevList.value = []
|
||||
boundPqDevList.value = []
|
||||
//处理异步调用
|
||||
@@ -753,11 +679,13 @@ const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan:
|
||||
// 比对式下这两个接口不需要
|
||||
pqSource_Result = { data: [] }
|
||||
PqScript_Result = { data: [] }
|
||||
formContent.testConfig.maxTime = sysTestConfig_Result.data?.maxTime
|
||||
formContent.testConfig.waveRecord = sysRegRes_Result.data?.waveRecord
|
||||
formContent.testConfig.realTime = sysRegRes_Result.data?.realTime
|
||||
formContent.testConfig.statistics = sysRegRes_Result.data?.statistics
|
||||
formContent.testConfig.flicker = sysRegRes_Result.data?.flicker
|
||||
if (formContent.testConfig) {
|
||||
formContent.testConfig.maxTime = (sysTestConfig_Result.data as { maxTime?: number })?.maxTime || 3
|
||||
formContent.testConfig.waveRecord = (sysRegRes_Result.data as { waveRecord?: number })?.waveRecord || 0
|
||||
formContent.testConfig.realTime = (sysRegRes_Result.data as { realTime?: number })?.realTime || 0
|
||||
formContent.testConfig.statistics = (sysRegRes_Result.data as { statistics?: number })?.statistics || 0
|
||||
formContent.testConfig.flicker = (sysRegRes_Result.data as { flicker?: number })?.flicker || 0
|
||||
}
|
||||
} else {
|
||||
const commonResults = await Promise.all([
|
||||
getTestSourceList(data),
|
||||
@@ -793,9 +721,6 @@ const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan:
|
||||
formContent.sourceIds = pqSourceList.value[0]?.id ?? ''
|
||||
formContent.datasourceIds = dictStore.getDictData('Datasource')[0]?.code ?? ''
|
||||
formContent.dataRule = dictStore.getDictData('Data_Rule')[0]?.id ?? ''
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
//编辑时先给表单赋值(这会没接收被检设备),需要手动再给被检设备复制后整体表单赋值
|
||||
|
||||
@@ -911,16 +836,14 @@ const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan:
|
||||
|
||||
pqToArray() //将对象转为数组
|
||||
|
||||
|
||||
//比对式测试项下拉框
|
||||
if (mode.value == '比对式') {
|
||||
// 如果是编辑模式且已有误差体系ID,则加载对应的测试项
|
||||
if (formContent.errorSysId) {
|
||||
await loadTestItemsForErrorSys(formContent.errorSysId);
|
||||
await loadTestItemsForErrorSys(formContent.errorSysId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mode.value != '比对式') {
|
||||
selectByMode.value = false
|
||||
// 将 formContent.sourceIds 从数组转换为字符串
|
||||
@@ -933,8 +856,6 @@ const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan:
|
||||
}
|
||||
}
|
||||
|
||||
value.value = boundPqDevList.value.map((i: { id: { toString: () => any } }) => i.id.toString())
|
||||
|
||||
if (AppSceneStore.currentScene == '1') {
|
||||
//楼下场景不用报告模版
|
||||
formContent.associateReport = 0
|
||||
@@ -960,14 +881,14 @@ const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan:
|
||||
// 误差体系选择变化时的处理函数
|
||||
const handleErrorSysChange = async (value: string) => {
|
||||
// 清空测试项选择
|
||||
formContent.testItems = [];
|
||||
|
||||
formContent.testItems = []
|
||||
|
||||
// 如果是比对式模式且选择了误差体系
|
||||
if (mode.value === '比对式' && value) {
|
||||
try {
|
||||
const res = await getPqErrSysTestItemList({ errorSysId: value });
|
||||
const res = await getPqErrSysTestItemList({ errorSysId: value })
|
||||
// 清空原有选项
|
||||
secondLevelOptions.length = 0;
|
||||
secondLevelOptions.length = 0
|
||||
|
||||
if (res.data) {
|
||||
// 将返回的键值对对象转换为下拉选项格式
|
||||
@@ -975,29 +896,28 @@ const handleErrorSysChange = async (value: string) => {
|
||||
secondLevelOptions.push({
|
||||
value: key,
|
||||
label: res.data[key]
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取测试项失败:', error);
|
||||
console.error('获取测试项失败:', error)
|
||||
// 发生错误时清空选项
|
||||
secondLevelOptions.length = 0;
|
||||
secondLevelOptions.length = 0
|
||||
}
|
||||
} else {
|
||||
// 如果没有选择误差体系,清空测试项选项
|
||||
secondLevelOptions.length = 0;
|
||||
secondLevelOptions.length = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 根据误差体系ID加载测试项(用于初始化)
|
||||
const loadTestItemsForErrorSys = async (errorSysId: string) => {
|
||||
if (!errorSysId) return;
|
||||
|
||||
if (!errorSysId) return
|
||||
|
||||
try {
|
||||
const res = await getPqErrSysTestItemList({ errorSysId: errorSysId });
|
||||
const res = await getPqErrSysTestItemList({ errorSysId: errorSysId })
|
||||
// 清空原有选项
|
||||
secondLevelOptions.length = 0;
|
||||
secondLevelOptions.length = 0
|
||||
|
||||
if (res.data) {
|
||||
// 将返回的键值对对象转换为下拉选项格式
|
||||
@@ -1005,12 +925,12 @@ const loadTestItemsForErrorSys = async (errorSysId: string) => {
|
||||
secondLevelOptions.push({
|
||||
value: key,
|
||||
label: res.data[key]
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取测试项失败:', error);
|
||||
secondLevelOptions.length = 0;
|
||||
console.error('获取测试项失败:', error)
|
||||
secondLevelOptions.length = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,12 +965,6 @@ function pqToArray() {
|
||||
value: item.id
|
||||
}))
|
||||
|
||||
const sourceArray4 = Array.isArray(pqDevList.value) ? pqDevList.value : []
|
||||
pqDevArray.value = sourceArray4.map(item => ({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}))
|
||||
|
||||
const sourceArray5 = Array.isArray(pqStandardDevList.value) ? pqStandardDevList.value : []
|
||||
if (planType.value === 0) {
|
||||
pqStandardDevArray.value = sourceArray5.map(item => ({
|
||||
|
||||
Reference in New Issue
Block a user