2025-08-07 08:47:56 +08:00
|
|
|
|
<!--
|
|
|
|
|
|
设备管理表格组件 - 支持多种业务模式
|
|
|
|
|
|
主要功能:设备检测、报告生成、设备归档、数据操作
|
|
|
|
|
|
支持手动/一键检测、批量操作、通道配对等高级功能
|
|
|
|
|
|
-->
|
2024-08-23 13:19:20 +08:00
|
|
|
|
<template>
|
2025-08-25 11:35:38 +08:00
|
|
|
|
<div class="table_info">
|
|
|
|
|
|
<!-- 主表格组件:支持排序、选择、动态列等功能 -->
|
|
|
|
|
|
<ProTable
|
|
|
|
|
|
ref="proTable"
|
|
|
|
|
|
:columns="columns"
|
|
|
|
|
|
@drag-sort="sortTable"
|
|
|
|
|
|
:default-sort="{ prop: 'check_State', order: 'ascending' }"
|
|
|
|
|
|
:stripe="true"
|
|
|
|
|
|
:pagination="false"
|
|
|
|
|
|
:key="tableKey"
|
|
|
|
|
|
@selection-change="handleSelectionChange"
|
|
|
|
|
|
:request-api="getTableList"
|
|
|
|
|
|
:toolButton="false"
|
|
|
|
|
|
>
|
|
|
|
|
|
<!-- 表格头部操作区域:包含查询筛选和功能按钮 -->
|
|
|
|
|
|
<template #tableHeader="">
|
|
|
|
|
|
<el-form :model="form" :inline="true">
|
|
|
|
|
|
<!-- 查询筛选区域 -->
|
|
|
|
|
|
<el-form-item label="关键字">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
v-model="form.search"
|
|
|
|
|
|
placeholder="请输入设备名称"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
style="width: 170px"
|
|
|
|
|
|
show-word-limit
|
|
|
|
|
|
maxlength="32"
|
|
|
|
|
|
></el-input>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 检测状态筛选(仅在设备检测模式下显示) -->
|
|
|
|
|
|
<el-form-item
|
|
|
|
|
|
label="检测状态"
|
|
|
|
|
|
v-if="form.activeTabs != 3 && form.activeTabs != 4 && form.activeTabs != 5"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-select v-model="form.checkStatus" clearable>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="(item, index) in checkStatus"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.id"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
v-show="shouldShowOption(item)"
|
|
|
|
|
|
></el-option>
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 检测结果筛选 -->
|
|
|
|
|
|
<el-form-item label="检测结果">
|
|
|
|
|
|
<el-select v-model="form.checkResult" clearable>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="(item, index) in checkResult"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.id"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
v-show="shouldShowOption(item)"
|
|
|
|
|
|
></el-option>
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 报告状态筛选 -->
|
|
|
|
|
|
<el-form-item label="报告状态">
|
|
|
|
|
|
<el-select v-model="form.checkReportStatus" clearable>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="(item, index) in checkReportStatus"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.id"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
v-show="shouldShowOption(item)"
|
|
|
|
|
|
></el-option>
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 功能按钮区域 -->
|
|
|
|
|
|
<el-form-item>
|
|
|
|
|
|
<!-- 基本查询操作 -->
|
|
|
|
|
|
<el-button type="primary" icon="Search" @click="handleSearch">查询</el-button>
|
|
|
|
|
|
<el-button icon="Delete" @click="handleRefresh">重置</el-button>
|
|
|
|
|
|
<!-- 比对模式下的通道配对功能 -->
|
|
|
|
|
|
<el-button type="primary" icon="Clock" @click="handleTest2">通道配对</el-button>
|
|
|
|
|
|
<!-- 设备检测模式下的操作按钮 -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
icon="Clock"
|
|
|
|
|
|
@click="handleTest('手动检测')"
|
|
|
|
|
|
v-if="form.activeTabs === 0"
|
|
|
|
|
|
>
|
|
|
|
|
|
手动检测
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
icon="ChatLineRound"
|
|
|
|
|
|
@click="handleTest('一键检测')"
|
|
|
|
|
|
v-if="form.activeTabs === 0"
|
|
|
|
|
|
>
|
|
|
|
|
|
一键检测
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<!-- 报告生成模式下的批量操作 -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
icon="Postcard"
|
|
|
|
|
|
@click="handleTest('批量生成')"
|
|
|
|
|
|
v-if="form.activeTabs === 3"
|
|
|
|
|
|
>
|
|
|
|
|
|
报告生成
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<!-- 设备归档模式下的批量操作 -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
icon="Notebook"
|
|
|
|
|
|
@click="handleTest('批量归档')"
|
|
|
|
|
|
v-if="form.activeTabs === 4"
|
|
|
|
|
|
>
|
|
|
|
|
|
归档
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<!-- 表格行操作列:根据不同模式显示不同的操作按钮 -->
|
|
|
|
|
|
<template #operation="scope">
|
|
|
|
|
|
<!-- 报告下载(仅在报告已生成或已上传时显示) -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
link
|
|
|
|
|
|
icon="Download"
|
|
|
|
|
|
@click="openDrawer('报告下载', scope.row)"
|
|
|
|
|
|
v-if="form.activeTabs === 3 && (scope.row.reportState === 1 || scope.row.reportState === 3)"
|
|
|
|
|
|
>
|
|
|
|
|
|
报告下载
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<!-- 单个设备报告生成 -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
link
|
|
|
|
|
|
icon="Postcard"
|
|
|
|
|
|
@click="openDrawer('报告生成', scope.row)"
|
|
|
|
|
|
v-if="form.activeTabs === 3"
|
|
|
|
|
|
>
|
|
|
|
|
|
报告生成
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<!-- 设备归档模式下的单个归档操作 -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
link
|
|
|
|
|
|
icon="Notebook"
|
|
|
|
|
|
@click="openDrawer('归档', scope.row)"
|
|
|
|
|
|
v-if="form.activeTabs === 4"
|
|
|
|
|
|
>
|
|
|
|
|
|
归档
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<!-- 数据操作模式下的功能 -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
link
|
|
|
|
|
|
icon="PieChart"
|
|
|
|
|
|
@click="openDrawer('检测数据查询', scope.row)"
|
|
|
|
|
|
v-if="form.activeTabs === 5"
|
|
|
|
|
|
>
|
|
|
|
|
|
检测数据查询
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<!-- 误差体系更换功能 -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
link
|
|
|
|
|
|
icon="Switch"
|
|
|
|
|
|
@click="openDrawer('误差体系更换', scope.row)"
|
|
|
|
|
|
v-if="form.activeTabs === 5"
|
|
|
|
|
|
>
|
|
|
|
|
|
误差体系更换
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</ProTable>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ======================== 弹窗组件区域 ======================== -->
|
|
|
|
|
|
<!-- 检测过程显示弹窗 -->
|
|
|
|
|
|
<TestPopup ref="testPopup" @quitClicked="handleQuitClicked"></TestPopup>
|
|
|
|
|
|
<!-- 检测数据查询弹窗 -->
|
|
|
|
|
|
<dataCheckPopup ref="dataCheckPopupRef" />
|
|
|
|
|
|
<!-- 手动检测检测项选择弹窗 -->
|
|
|
|
|
|
<SelectTestItemPopup ref="selectTestItemPopupRef" @openTestDialog="openTestDialog"></SelectTestItemPopup>
|
|
|
|
|
|
<!-- 省平台模式下的温度湿度填写弹窗 -->
|
|
|
|
|
|
<WriteTHPopup ref="writeTHPopupRef" @openTestDialog2="openTestDialog2"></WriteTHPopup>
|
|
|
|
|
|
<!-- 比对模式下的通道配对弹窗 -->
|
|
|
|
|
|
<DeviceConnectionPopup ref="deviceConnectionPopupRef"></DeviceConnectionPopup>
|
|
|
|
|
|
<!-- 检测数据查询弹窗 -->
|
|
|
|
|
|
<CompareDataCheckSingleChannelSingleTestPopup
|
|
|
|
|
|
ref="dataCheckSingleChannelSingleTestPopupRef"
|
|
|
|
|
|
:append-to-body="true"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
2024-08-23 13:19:20 +08:00
|
|
|
|
</template>
|
2024-08-27 18:37:46 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
<script setup lang="tsx" name="useProTable">
|
2025-08-07 08:47:56 +08:00
|
|
|
|
import { onBeforeMount, onMounted, type PropType, reactive, ref, watch } from 'vue'
|
|
|
|
|
|
import { ElMessage, ElMessageBox, type Action } from 'element-plus'
|
2025-01-15 18:01:12 +08:00
|
|
|
|
import TestPopup from './testPopup.vue'
|
|
|
|
|
|
import dataCheckPopup from './dataCheckSingleChannelSingleTestPopup.vue'
|
2025-08-25 11:35:38 +08:00
|
|
|
|
import CompareDataCheckSingleChannelSingleTestPopup from '@/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue'
|
2025-08-07 08:47:56 +08:00
|
|
|
|
import ProTable from '@/components/ProTable/index.vue'
|
|
|
|
|
|
import SelectTestItemPopup from '@/views/home/components/selectTestItemPopup.vue'
|
|
|
|
|
|
import WriteTHPopup from '@/views/home/components/writeTHPopup.vue'
|
|
|
|
|
|
import DeviceConnectionPopup from '@/views/home/components/deviceConnectionPopup.vue'
|
|
|
|
|
|
import { type Device } from '@/api/device/interface/device'
|
|
|
|
|
|
import { type ProTableInstance, type ColumnProps } from '@/components/ProTable/interface'
|
|
|
|
|
|
import { type Plan } from '@/api/plan/interface'
|
|
|
|
|
|
import { type StandardDevice } from '@/api/device/interface/standardDevice'
|
|
|
|
|
|
import { generateDevReport, getBoundPqDevList } from '@/api/plan/plan'
|
|
|
|
|
|
import { downloadDevData } from '@/api/plan/plan'
|
|
|
|
|
|
import { getPqDev } from '@/api/device/device'
|
|
|
|
|
|
import { useModeStore, useAppSceneStore } from '@/stores/modules/mode' // 引入模式 store
|
|
|
|
|
|
import { useCheckStore } from '@/stores/modules/check'
|
|
|
|
|
|
import { CheckData } from '@/api/check/interface'
|
|
|
|
|
|
import { useAuthStore } from '@/stores/modules/auth'
|
|
|
|
|
|
import { useDownload } from '@/hooks/useDownload'
|
|
|
|
|
|
import { documentedPqDev } from '@/api/device/report'
|
|
|
|
|
|
import { ResultEnum } from '@/enums/httpEnum'
|
2025-08-25 11:35:38 +08:00
|
|
|
|
import { getPqMonList } from '@/api/device/monitor/index.ts'
|
2025-08-07 08:47:56 +08:00
|
|
|
|
|
2024-12-20 18:19:18 +08:00
|
|
|
|
const checkStore = useCheckStore()
|
2025-08-25 11:35:38 +08:00
|
|
|
|
let devNum = 0 //当前选取的被检设备数量
|
|
|
|
|
|
let devChannelsNum = 0 //当前选择的被检设备通道总数
|
2025-01-15 18:01:12 +08:00
|
|
|
|
const tableKey = ref(0)
|
|
|
|
|
|
const tableHeight = ref(0)
|
2024-12-20 10:19:58 +08:00
|
|
|
|
|
2025-01-15 18:01:12 +08:00
|
|
|
|
const dataCheckPopupRef = ref<InstanceType<typeof dataCheckPopup>>()
|
2025-02-25 10:17:33 +08:00
|
|
|
|
const selectTestItemPopupRef = ref<InstanceType<typeof SelectTestItemPopup>>()
|
2025-05-15 08:57:24 +08:00
|
|
|
|
const writeTHPopupRef = ref<InstanceType<typeof WriteTHPopup>>()
|
2025-07-09 20:12:40 +08:00
|
|
|
|
const deviceConnectionPopupRef = ref<InstanceType<typeof DeviceConnectionPopup>>()
|
2024-11-18 22:04:59 +08:00
|
|
|
|
const dialogTitle = ref('手动检测')
|
2025-01-15 18:01:12 +08:00
|
|
|
|
const checkStateTable = ref<number[]>([0, 1, 2])
|
|
|
|
|
|
const modeStore = useModeStore()
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 控制下拉框选项的显示逻辑
|
|
|
|
|
|
* 根据当前Tab模式动态控制哪些选项可见
|
|
|
|
|
|
* @param item 下拉框选项对象
|
|
|
|
|
|
* @returns 是否显示该选项
|
|
|
|
|
|
*/
|
|
|
|
|
|
const shouldShowOption = (item: any) => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 非设备检测模式(weiJianTab !== 0)时,隐藏"归档"和"未检"选项
|
|
|
|
|
|
if (weiJianTab.value !== 0) {
|
|
|
|
|
|
return item.label !== '归档' && item.label !== '未检'
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 设备检测模式只隐藏"归档"选项
|
|
|
|
|
|
return item.label !== '归档'
|
|
|
|
|
|
}
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2025-08-25 11:35:38 +08:00
|
|
|
|
const dataCheckSingleChannelSingleTestPopupRef = ref()
|
2025-01-15 18:01:12 +08:00
|
|
|
|
tableHeight.value = window.innerHeight - 600
|
|
|
|
|
|
const operationShow = ref(false)
|
|
|
|
|
|
const documentStateShow = ref(false)
|
|
|
|
|
|
const checkStateShow = ref(true)
|
|
|
|
|
|
const factorCheckShow = ref(true)
|
|
|
|
|
|
const selectionShow = ref(true)
|
2024-12-18 15:49:29 +08:00
|
|
|
|
const testPopup = ref()
|
2025-08-07 08:47:56 +08:00
|
|
|
|
const weiJianTab = ref(0) // 当前Tab索引,用于控制选项显示逻辑
|
2024-12-20 10:21:36 +08:00
|
|
|
|
const channelsSelection = ref<Device.ResPqDev[]>([])
|
2024-12-13 16:35:27 +08:00
|
|
|
|
const props = defineProps({
|
2025-08-25 11:35:38 +08:00
|
|
|
|
id: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
required: true
|
|
|
|
|
|
},
|
|
|
|
|
|
plan: {
|
|
|
|
|
|
type: Object,
|
|
|
|
|
|
default: null
|
|
|
|
|
|
},
|
|
|
|
|
|
planArray: {
|
|
|
|
|
|
type: Array as PropType<Plan.ReqPlan[]>,
|
|
|
|
|
|
default: null
|
|
|
|
|
|
},
|
|
|
|
|
|
planTable: {
|
|
|
|
|
|
type: Array,
|
|
|
|
|
|
default: () => []
|
|
|
|
|
|
}
|
2024-12-13 16:35:27 +08:00
|
|
|
|
})
|
2025-05-06 11:00:12 +08:00
|
|
|
|
const appSceneStore = useAppSceneStore()
|
2025-08-06 15:18:27 +08:00
|
|
|
|
|
2025-01-13 21:06:24 +08:00
|
|
|
|
const emit = defineEmits<{
|
2025-08-25 11:35:38 +08:00
|
|
|
|
(e: 'batchGenerateClicked'): void
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}>()
|
2025-01-13 19:28:51 +08:00
|
|
|
|
|
|
|
|
|
|
// 存储设备类型选项
|
2025-08-25 11:35:38 +08:00
|
|
|
|
const devTypeOptions = ref<
|
|
|
|
|
|
{
|
|
|
|
|
|
id: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
icd: string
|
|
|
|
|
|
power: string
|
|
|
|
|
|
devVolt: number
|
|
|
|
|
|
devCurr: number
|
|
|
|
|
|
devChns: number
|
|
|
|
|
|
}[]
|
|
|
|
|
|
>([])
|
2025-01-13 19:28:51 +08:00
|
|
|
|
|
2024-09-02 16:10:33 +08:00
|
|
|
|
//下拉框数据
|
2024-12-16 16:33:18 +08:00
|
|
|
|
interface Dict {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
id: string
|
|
|
|
|
|
label: string
|
2024-12-16 16:33:18 +08:00
|
|
|
|
}
|
2025-01-15 18:01:12 +08:00
|
|
|
|
|
2024-09-02 16:10:33 +08:00
|
|
|
|
//检测状态数据
|
2024-12-16 16:33:18 +08:00
|
|
|
|
const checkStatus: Dict[] = [
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
id: '0',
|
|
|
|
|
|
label: '未检'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '1',
|
|
|
|
|
|
label: '检测中'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '2',
|
|
|
|
|
|
label: '检测完成'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '3',
|
|
|
|
|
|
label: '归档'
|
|
|
|
|
|
}
|
2024-12-16 16:33:18 +08:00
|
|
|
|
]
|
2024-09-02 16:10:33 +08:00
|
|
|
|
//检测报告状态数据
|
2024-12-16 16:33:18 +08:00
|
|
|
|
const checkReportStatus: Dict[] = [
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
id: '0',
|
|
|
|
|
|
label: '未生成'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '1',
|
|
|
|
|
|
label: '已生成'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '2',
|
|
|
|
|
|
label: '未检'
|
|
|
|
|
|
}
|
2024-12-16 16:33:18 +08:00
|
|
|
|
]
|
2024-09-02 16:10:33 +08:00
|
|
|
|
//检测结果数组
|
2024-12-16 16:33:18 +08:00
|
|
|
|
const checkResult: Dict[] = [
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
id: '0',
|
|
|
|
|
|
label: '不符合'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '1',
|
|
|
|
|
|
label: '符合'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '2',
|
|
|
|
|
|
label: '未检'
|
|
|
|
|
|
}
|
2024-12-16 16:33:18 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
2024-09-02 16:10:33 +08:00
|
|
|
|
//查询条件
|
|
|
|
|
|
const form: any = ref({
|
2025-08-25 11:35:38 +08:00
|
|
|
|
activeTabs: 0, //功能选择
|
|
|
|
|
|
search: null, //搜索内容
|
|
|
|
|
|
checkStatus: null, //检测状态
|
|
|
|
|
|
checkResult: null, //检测结果
|
|
|
|
|
|
checkReportStatus: null, //检测报告状态
|
|
|
|
|
|
deviceBindStatus: 0, //绑定状态
|
|
|
|
|
|
deviceType: 0, //设备类型
|
|
|
|
|
|
manufacturer: 0 //制造厂商
|
2025-01-15 18:01:12 +08:00
|
|
|
|
})
|
2024-08-27 18:37:46 +08:00
|
|
|
|
// ProTable 实例
|
2025-01-15 18:01:12 +08:00
|
|
|
|
const proTable = ref<ProTableInstance>()
|
2024-08-23 13:19:20 +08:00
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取表格数据的异步函数
|
|
|
|
|
|
* 根据权限控制列显示,根据查询条件获取设备列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
const getTableList = async () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 权限控制:没有通道系数权限时隐藏相关列
|
|
|
|
|
|
const authStore = useAuthStore()
|
|
|
|
|
|
const currentPageRoles = authStore.authButtonListGet[authStore.routeName] ?? []
|
|
|
|
|
|
if (!currentPageRoles.includes('channelsTest')) {
|
|
|
|
|
|
factorCheckShow.value = false
|
|
|
|
|
|
}
|
2025-01-09 13:56:56 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 清空当前表格选择
|
|
|
|
|
|
if (proTable.value) {
|
|
|
|
|
|
proTable.value.clearSelection()
|
|
|
|
|
|
}
|
|
|
|
|
|
if (props.id) {
|
|
|
|
|
|
const checkStateList = ref<any>()
|
|
|
|
|
|
if (form.value.checkStatus != null) {
|
|
|
|
|
|
checkStateList.value = [form.value.checkStatus]
|
|
|
|
|
|
} else {
|
|
|
|
|
|
checkStateList.value = checkStateTable.value
|
|
|
|
|
|
}
|
|
|
|
|
|
return getBoundPqDevList({
|
|
|
|
|
|
planIdList: [props.id],
|
|
|
|
|
|
checkStateList: checkStateList.value,
|
|
|
|
|
|
checkResult: form.value.checkResult,
|
|
|
|
|
|
reportState: form.value.checkReportStatus,
|
|
|
|
|
|
name: form.value.search
|
|
|
|
|
|
})
|
2025-01-13 21:06:24 +08:00
|
|
|
|
}
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2024-11-07 20:41:32 +08:00
|
|
|
|
|
2024-08-27 18:37:46 +08:00
|
|
|
|
// 表格配置项
|
2024-12-13 16:35:27 +08:00
|
|
|
|
const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
type: 'selection',
|
|
|
|
|
|
fixed: 'left',
|
|
|
|
|
|
width: 70,
|
|
|
|
|
|
isShow: selectionShow,
|
|
|
|
|
|
selectable(row) {
|
|
|
|
|
|
if (weiJianTab.value === 4) {
|
|
|
|
|
|
return row.reportState === 1 || row.reportState === 3
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
2024-08-27 18:37:46 +08:00
|
|
|
|
},
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
|
|
|
|
|
|
{
|
|
|
|
|
|
prop: 'name',
|
|
|
|
|
|
label: '设备名称',
|
|
|
|
|
|
minWidth: 220
|
2025-08-07 08:47:56 +08:00
|
|
|
|
},
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
prop: 'devType',
|
|
|
|
|
|
label: '设备类型',
|
|
|
|
|
|
minWidth: 150
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
prop: 'boundPlanName',
|
|
|
|
|
|
label: '来源计划名称',
|
|
|
|
|
|
minWidth: 200,
|
|
|
|
|
|
isShow: modeStore.currentMode === '比对式',
|
|
|
|
|
|
render(scope) {
|
|
|
|
|
|
return scope.row.boundPlanName ? scope.row.boundPlanName : props.plan.name
|
2025-07-24 08:29:03 +08:00
|
|
|
|
}
|
2025-08-07 08:47:56 +08:00
|
|
|
|
},
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
prop: 'standardDevs',
|
|
|
|
|
|
label: '标准设备',
|
|
|
|
|
|
minWidth: 200,
|
|
|
|
|
|
isShow: modeStore.currentMode === '比对式',
|
|
|
|
|
|
render(scope) {
|
|
|
|
|
|
const boundPlanName = ref('')
|
|
|
|
|
|
if (scope.row.boundPlanName) {
|
|
|
|
|
|
boundPlanName.value = scope.row.boundPlanName
|
|
|
|
|
|
} else {
|
|
|
|
|
|
boundPlanName.value = props.plan.name
|
|
|
|
|
|
}
|
|
|
|
|
|
const standardDevNames = props.planArray.flatMap(item => {
|
|
|
|
|
|
if (item.children) {
|
|
|
|
|
|
return item.children
|
|
|
|
|
|
.filter(child => child.name === boundPlanName.value)
|
|
|
|
|
|
.flatMap(child => child.standardDevs.map(dev => dev.name))
|
|
|
|
|
|
}
|
|
|
|
|
|
return []
|
|
|
|
|
|
})
|
|
|
|
|
|
return standardDevNames.length > 0 ? standardDevNames.join(',') : '/'
|
|
|
|
|
|
}
|
2024-08-27 18:37:46 +08:00
|
|
|
|
},
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
prop: 'devChns',
|
|
|
|
|
|
label: '通道数',
|
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
|
sortable: true
|
2024-11-07 20:41:32 +08:00
|
|
|
|
},
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
prop: 'recheckNum',
|
|
|
|
|
|
label: '检测次数',
|
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
|
sortable: true
|
2024-11-07 20:41:32 +08:00
|
|
|
|
},
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
prop: 'checkState',
|
|
|
|
|
|
label: '检测状态',
|
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
|
sortable: true,
|
|
|
|
|
|
isShow: checkStateShow,
|
|
|
|
|
|
render: scope => {
|
|
|
|
|
|
return scope.row.checkState === 0 ? '未检' : scope.row.checkState === 1 ? '检测中' : '检测完成'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
prop: 'checkResult',
|
|
|
|
|
|
label: '检测结果',
|
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
|
sortable: true,
|
|
|
|
|
|
render: scope => {
|
|
|
|
|
|
if (scope.row.checkResult === 0) {
|
|
|
|
|
|
return <el-tag type="danger">不符合</el-tag>
|
|
|
|
|
|
} else if (scope.row.checkResult === 1) {
|
|
|
|
|
|
return '符合'
|
|
|
|
|
|
} else if (scope.row.checkResult === 2) {
|
|
|
|
|
|
return '未检'
|
|
|
|
|
|
}
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
prop: 'reportState',
|
|
|
|
|
|
label: '报告状态',
|
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
|
sortable: true,
|
|
|
|
|
|
render: scope => {
|
|
|
|
|
|
if (scope.row.reportState === 0) {
|
|
|
|
|
|
return '未生成'
|
|
|
|
|
|
} else if (scope.row.reportState === 1) {
|
|
|
|
|
|
return '已生成'
|
|
|
|
|
|
} else if (scope.row.reportState === 2) {
|
|
|
|
|
|
return '未检'
|
|
|
|
|
|
} else if (scope.row.reportState === 3) {
|
|
|
|
|
|
return '已上传'
|
|
|
|
|
|
}
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
prop: 'factorCheckResult',
|
|
|
|
|
|
label: '系数校准结果',
|
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
|
sortable: true,
|
|
|
|
|
|
isShow: factorCheckShow.value && appSceneStore.currentScene === '1',
|
|
|
|
|
|
render: scope => {
|
|
|
|
|
|
if (scope.row.factorCheckResult === 0) {
|
|
|
|
|
|
return '不合格'
|
|
|
|
|
|
} else if (scope.row.factorCheckResult === 1) {
|
|
|
|
|
|
return '合格'
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return '未检'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-09 13:56:56 +08:00
|
|
|
|
},
|
2025-08-25 11:35:38 +08:00
|
|
|
|
{ prop: 'operation', label: '操作', fixed: 'right', minWidth: 200, isShow: operationShow }
|
2025-01-15 18:01:12 +08:00
|
|
|
|
])
|
2025-08-07 08:47:56 +08:00
|
|
|
|
let testType = 'test' // 检测类型:'test'-检测 'reTest'-复检
|
2024-12-04 21:36:12 +08:00
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 表格行选择变化时的处理函数
|
|
|
|
|
|
* 更新全局统计信息,用于后续操作的校验和限制
|
|
|
|
|
|
*/
|
2024-11-25 21:11:10 +08:00
|
|
|
|
const handleSelectionChange = (selection: any[]) => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
channelsSelection.value = selection
|
|
|
|
|
|
// 统计选中设备数量
|
|
|
|
|
|
devNum = selection.length
|
|
|
|
|
|
// 统计选中设备的总通道数
|
|
|
|
|
|
devChannelsNum = 0
|
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < selection.length; i++) {
|
|
|
|
|
|
devChannelsNum += selection[i].devChns
|
|
|
|
|
|
}
|
2024-12-04 21:36:12 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 统计已完成检测的设备数量
|
|
|
|
|
|
const result = selection.filter(item => item.checkResult != 0)
|
|
|
|
|
|
if (result.length > 0) {
|
|
|
|
|
|
testType = 'test'
|
|
|
|
|
|
} else {
|
|
|
|
|
|
testType = 'reTest'
|
2024-12-20 18:19:18 +08:00
|
|
|
|
}
|
2025-08-25 11:35:38 +08:00
|
|
|
|
let devices: CheckData.Device[] = selection.map((item: any) => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
deviceId: item.id,
|
|
|
|
|
|
deviceName: item.name,
|
|
|
|
|
|
chnNum: item.devChns,
|
|
|
|
|
|
planId: item.planId,
|
|
|
|
|
|
deviceType: item.devType,
|
|
|
|
|
|
devVolt: item.devVolt,
|
|
|
|
|
|
devCurr: item.devCurr,
|
|
|
|
|
|
factorFlag: item.factorFlag,
|
|
|
|
|
|
checkResult: item.checkResult
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2024-12-26 09:28:19 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
if (selection.length > 0) {
|
|
|
|
|
|
checkStore.clearDevices()
|
|
|
|
|
|
checkStore.addDevices(devices)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
checkStore.clearDevices()
|
|
|
|
|
|
}
|
2024-11-25 21:11:10 +08:00
|
|
|
|
}
|
2024-11-29 13:45:48 +08:00
|
|
|
|
|
2024-08-27 18:37:46 +08:00
|
|
|
|
//查询
|
|
|
|
|
|
const handleSearch = () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
proTable.value?.getTableList()
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2024-08-27 18:37:46 +08:00
|
|
|
|
//重置
|
|
|
|
|
|
const handleRefresh = () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
form.value.search = null
|
|
|
|
|
|
form.value.checkStatus = null
|
|
|
|
|
|
form.value.checkResult = null
|
|
|
|
|
|
form.value.checkReportStatus = null
|
|
|
|
|
|
proTable.value?.getTableList()
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2025-08-07 08:47:56 +08:00
|
|
|
|
|
|
|
|
|
|
// 表格排序
|
2025-08-25 11:35:38 +08:00
|
|
|
|
const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
|
|
|
|
|
|
console.log(newIndex, oldIndex) // 避免未使用参数警告
|
|
|
|
|
|
ElMessage.success('修改列表排序成功')
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2024-08-27 18:37:46 +08:00
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 切换顶部功能Tab时的处理函数
|
|
|
|
|
|
* @param val Tab索引:0-设备检测 1-手动检测 2-设备复检 3-报告生成 4-设备归档 5-数据查询
|
|
|
|
|
|
* 现在1和2已不做考虑了,其他4种tab满足当前的工作需求
|
|
|
|
|
|
*/
|
|
|
|
|
|
const changeActiveTabs = (val: number) => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
form.value.activeTabs = val
|
|
|
|
|
|
tableHeaderInit(val)
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2024-11-07 20:41:32 +08:00
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 根据当前功能Tab初始化表格配置
|
|
|
|
|
|
* 不同Tab模式下表格会显示不同的列和操作按钮
|
|
|
|
|
|
* @param val Tab索引:0-设备检测 1-手动检测 2-设备复检 3-报告生成 4-设备归档 5-数据查询
|
|
|
|
|
|
*/
|
2024-11-07 20:41:32 +08:00
|
|
|
|
function tableHeaderInit(val: number) {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 重置查询条件和选择状态
|
|
|
|
|
|
refreshStatusList()
|
|
|
|
|
|
weiJianTab.value = val
|
|
|
|
|
|
// 根据Tab索引配置不同的表格显示模式
|
|
|
|
|
|
switch (val) {
|
|
|
|
|
|
case 0: // 设备检测模式
|
|
|
|
|
|
case 1: // 手动检测模式
|
|
|
|
|
|
checkStateTable.value = [0, 1, 2] // 显示所有检测状态
|
|
|
|
|
|
tableKey.value++
|
|
|
|
|
|
operationShow.value = false // 隐藏操作列
|
|
|
|
|
|
documentStateShow.value = false // 隐藏文档状态
|
|
|
|
|
|
checkStateShow.value = true // 显示检测状态
|
|
|
|
|
|
selectionShow.value = true // 显示选择框
|
|
|
|
|
|
factorCheckShow.value = true // 显示系数校准
|
|
|
|
|
|
break
|
|
|
|
|
|
case 2: // 设备复检模式
|
|
|
|
|
|
break
|
|
|
|
|
|
case 3: // 报告生成模式
|
|
|
|
|
|
checkStateTable.value = [2, 3] // 只显示检测完成和归档状态
|
|
|
|
|
|
columns[columns.length - 1].minWidth = 180
|
|
|
|
|
|
tableKey.value += 1
|
|
|
|
|
|
operationShow.value = true // 显示操作列
|
|
|
|
|
|
documentStateShow.value = true // 显示文档状态
|
|
|
|
|
|
checkStateShow.value = false // 隐藏检测状态
|
|
|
|
|
|
factorCheckShow.value = false // 隐藏系数校准
|
|
|
|
|
|
selectionShow.value = true // 显示选择框
|
|
|
|
|
|
break
|
|
|
|
|
|
case 4: // 设备归档模式
|
|
|
|
|
|
checkStateTable.value = [2] // 只显示检测完成状态
|
|
|
|
|
|
columns[columns.length - 1].minWidth = 100
|
|
|
|
|
|
tableKey.value += 1
|
|
|
|
|
|
operationShow.value = true // 显示操作列
|
|
|
|
|
|
documentStateShow.value = false // 隐藏文档状态
|
|
|
|
|
|
checkStateShow.value = false // 隐藏检测状态
|
|
|
|
|
|
factorCheckShow.value = false // 隐藏系数校准
|
|
|
|
|
|
selectionShow.value = true // 显示选择框
|
|
|
|
|
|
break
|
|
|
|
|
|
case 5: // 数据查询模式
|
|
|
|
|
|
checkStateTable.value = [2, 3] // 显示检测完成和归档状态
|
|
|
|
|
|
columns[columns.length - 1].minWidth = 290
|
|
|
|
|
|
operationShow.value = true // 显示操作列
|
|
|
|
|
|
documentStateShow.value = true // 显示文档状态
|
|
|
|
|
|
checkStateShow.value = false // 隐藏检测状态
|
|
|
|
|
|
factorCheckShow.value = false // 隐藏系数校准
|
|
|
|
|
|
selectionShow.value = false // 隐藏选择框
|
|
|
|
|
|
columns[0].isShow = false // 隐藏序号列
|
|
|
|
|
|
tableKey.value += 1
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2024-11-07 20:41:32 +08:00
|
|
|
|
}
|
2024-11-29 13:45:48 +08:00
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 重置表格状态和查询条件
|
|
|
|
|
|
* 在切换Tab或重置操作时调用,清空所有筛选条件和选择状态
|
|
|
|
|
|
*/
|
2025-01-15 18:01:12 +08:00
|
|
|
|
function refreshStatusList() {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 重置设备选择统计信息
|
|
|
|
|
|
devNum = 0
|
|
|
|
|
|
devChannelsNum = 0
|
|
|
|
|
|
// 清空查询表单
|
|
|
|
|
|
form.value.search = null
|
|
|
|
|
|
form.value.checkStatus = null //检测状态默认为未检
|
|
|
|
|
|
form.value.checkReportStatus = null //检测报告状态默认为未生成报告
|
|
|
|
|
|
form.value.checkResult = null //检测结果默认为未出结果
|
2024-11-07 20:41:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 通道配对功能处理函数(比对模式专用)
|
|
|
|
|
|
* 校验选中设备的一致性,然后打开通道配对弹窗
|
|
|
|
|
|
*/
|
2025-08-15 16:22:58 +08:00
|
|
|
|
const handleTest2 = async () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 检查是否选择了设备
|
|
|
|
|
|
if (devNum == 0) {
|
|
|
|
|
|
ElMessageBox.confirm('请先选择被检设备', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 检查选中设备是否属于同一个计划
|
|
|
|
|
|
const planName = channelsSelection.value.map(item => item.boundPlanName)
|
|
|
|
|
|
const isPlanConsistent = new Set(planName).size === 1
|
|
|
|
|
|
if (!isPlanConsistent) {
|
|
|
|
|
|
ElMessageBox.confirm('所勾选被检设备所属计划名称不一致,请重新选择', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-07-24 08:29:03 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 获取设备所属计划名称
|
|
|
|
|
|
const boundPlanName = ref('')
|
|
|
|
|
|
if (channelsSelection.value[0].boundPlanName) {
|
|
|
|
|
|
boundPlanName.value = channelsSelection.value[0].boundPlanName
|
|
|
|
|
|
} else {
|
|
|
|
|
|
boundPlanName.value = props.plan.name
|
2025-08-07 08:47:56 +08:00
|
|
|
|
}
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 查找选中设备所属计划的标准设备列表
|
|
|
|
|
|
const pqStandardDevList = ref<StandardDevice.ResPqStandardDevice[]>([])
|
|
|
|
|
|
pqStandardDevList.value = props.planArray.flatMap(item => {
|
|
|
|
|
|
if (item.children) {
|
|
|
|
|
|
return item.children
|
|
|
|
|
|
.filter(child => child.name === boundPlanName.value)
|
|
|
|
|
|
.flatMap(child => child.standardDevs)
|
|
|
|
|
|
}
|
|
|
|
|
|
return []
|
|
|
|
|
|
})
|
2025-07-24 08:29:03 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 检查是否有标准设备可用于配对
|
|
|
|
|
|
if (pqStandardDevList.value.length == 0) {
|
|
|
|
|
|
ElMessageBox.confirm('所勾选被检设备所属计划无标准设备,请重新选择', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-08-07 08:47:56 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
const devBindMonList = await getPqMonList({ devIds: channelsSelection.value.map(d => d.id) })
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建一个映射来存储每个设备的监测点信息(支持多个监测点)
|
2025-08-25 11:35:38 +08:00
|
|
|
|
const deviceMonitoringMap = new Map<string, any[]>()
|
|
|
|
|
|
devBindMonList.data.forEach((item: any) => {
|
|
|
|
|
|
if (deviceMonitoringMap.has(item.devId)) {
|
|
|
|
|
|
// 如果设备已存在,添加新的监测点信息
|
|
|
|
|
|
deviceMonitoringMap.get(item.devId)?.push(item)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果设备不存在,创建新的数组存储监测点信息
|
|
|
|
|
|
deviceMonitoringMap.set(item.devId, [item])
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 过滤出至少有一个监测点的设备
|
|
|
|
|
|
const filteredChannelsSelection = channelsSelection.value.filter(device => {
|
|
|
|
|
|
return deviceMonitoringMap.has(device.id)
|
|
|
|
|
|
})
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 如果没有设备有监测点,则提示并返回
|
|
|
|
|
|
if (filteredChannelsSelection.length === 0) {
|
|
|
|
|
|
ElMessageBox.confirm('所选设备均无监测点,请检查设备配置', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 检查是否有设备被过滤掉
|
|
|
|
|
|
const devicesWithoutMonitoring = channelsSelection.value.filter(device => {
|
|
|
|
|
|
return !deviceMonitoringMap.has(device.id)
|
|
|
|
|
|
})
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 提示完全没有监测点的设备
|
|
|
|
|
|
if (devicesWithoutMonitoring.length > 0) {
|
|
|
|
|
|
const deviceNames = devicesWithoutMonitoring.map(d => d.name).join(', ')
|
|
|
|
|
|
ElMessage.warning(`以下设备没有监测点: ${deviceNames}`)
|
|
|
|
|
|
}
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 检查监测点数量与通道数是否一致,并指出具体哪些通道未绑定
|
|
|
|
|
|
const inconsistentPointDevices = filteredChannelsSelection.filter(device => {
|
|
|
|
|
|
const monitoringInfoArray = deviceMonitoringMap.get(device.id)
|
|
|
|
|
|
const pointCount = monitoringInfoArray ? monitoringInfoArray.length : 0
|
|
|
|
|
|
// 只有当监测点数量与通道数不一致时才需要提示
|
|
|
|
|
|
return pointCount !== device.devChns
|
|
|
|
|
|
})
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
if (inconsistentPointDevices.length > 0) {
|
|
|
|
|
|
const deviceNames = inconsistentPointDevices.map(d => d.name).join(', ')
|
|
|
|
|
|
ElMessage.warning(`以下设备存在通道未绑定监测点: ${deviceNames}`)
|
|
|
|
|
|
}
|
2025-08-26 20:52:24 +08:00
|
|
|
|
console.log("🚀 ~ handleTest2 ~ filteredChannelsSelection, pqStandardDevList.value, props.id:", filteredChannelsSelection, )
|
|
|
|
|
|
console.log("🚀 ~ handleTest2 ~ filteredChannelsSelection, pqStandardDevList.value, props.id:", pqStandardDevList.value, )
|
|
|
|
|
|
console.log("🚀 ~ handleTest2 ~ filteredChannelsSelection, pqStandardDevList.value, props.id:", props.id)
|
2025-08-15 16:22:58 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 只传递有监测点的设备
|
|
|
|
|
|
deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevList.value, props.id)
|
2025-07-09 20:12:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 检测操作主处理函数
|
|
|
|
|
|
* 根据操作类型(手动检测/一键检测/批量生成/批量归档等)执行相应逻辑
|
|
|
|
|
|
* @param val 操作类型字符串
|
|
|
|
|
|
*/
|
2025-01-15 18:01:12 +08:00
|
|
|
|
const handleTest = async (val: string) => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 检查是否选择了设备
|
|
|
|
|
|
if (devNum == 0) {
|
|
|
|
|
|
ElMessageBox.confirm('请先选择被检设备', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-12-24 20:22:36 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 检查选中设备的额定电压是否一致
|
|
|
|
|
|
const checkDevVolt = channelsSelection.value.map(item => item.devVolt)
|
|
|
|
|
|
const isDevVoltConsistent = new Set(checkDevVolt).size === 1
|
|
|
|
|
|
if (!isDevVoltConsistent) {
|
|
|
|
|
|
ElMessageBox.confirm('所勾选设备额定电压不一致,请重新选择', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-12-24 20:22:36 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 检查选中设备的额定电流是否一致
|
|
|
|
|
|
const checkDevCurr = channelsSelection.value.map(item => item.devCurr)
|
|
|
|
|
|
const isDevCurrConsistent = new Set(checkDevCurr).size === 1
|
|
|
|
|
|
if (!isDevCurrConsistent) {
|
|
|
|
|
|
ElMessageBox.confirm('所勾选设备额定电流不一致,请重新选择', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-12-24 20:22:36 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 处理检测相关操作
|
|
|
|
|
|
if (val === '手动检测' || val === '一键检测' || val === '系数校准') {
|
|
|
|
|
|
// 检查选中设备的检测状态是否一致
|
|
|
|
|
|
const checkStates = channelsSelection.value.map(item => item.checkState)
|
|
|
|
|
|
const allCheckStatesEqual = new Set(checkStates).size <= 1
|
2025-01-09 13:56:56 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 如果检测状态不一致,设置为复检模式
|
|
|
|
|
|
if (!allCheckStatesEqual) {
|
|
|
|
|
|
checkStore.setReCheckType(1)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 限制每次检测最多12个通道
|
|
|
|
|
|
if (devChannelsNum > 12) {
|
|
|
|
|
|
ElMessageBox.confirm('每次检测最多只能检测12个设备通道,请重新选择', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-01-09 13:56:56 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
dialogTitle.value = val
|
|
|
|
|
|
if (val === '手动检测') {
|
|
|
|
|
|
checkStore.setShowDetailType(2)
|
|
|
|
|
|
if (testType === 'reTest') {
|
|
|
|
|
|
ElMessageBox.confirm('请选择复检检测方式', '设备复检', {
|
|
|
|
|
|
distinguishCancelAndClose: true,
|
|
|
|
|
|
confirmButtonText: '不合格项复检',
|
|
|
|
|
|
cancelButtonText: '全部复检',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
.then(() => {
|
|
|
|
|
|
ElMessage.success('不合格项复检')
|
|
|
|
|
|
checkStore.setReCheckType(0)
|
|
|
|
|
|
// 控制是否显示温度湿度输入框
|
|
|
|
|
|
if (appSceneStore.currentScene === '0') {
|
|
|
|
|
|
writeTHPopupRef.value?.open()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
selectTestItemPopupRef.value?.open()
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((action: Action) => {
|
|
|
|
|
|
if (action === 'cancel') {
|
|
|
|
|
|
ElMessage.success('全部复检')
|
|
|
|
|
|
checkStore.setReCheckType(1)
|
|
|
|
|
|
if (appSceneStore.currentScene === '0') {
|
|
|
|
|
|
writeTHPopupRef.value?.open()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
selectTestItemPopupRef.value?.open()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
checkStore.setSelectTestItems({ preTest: false, timeTest: false, channelsTest: false, test: true })
|
2025-08-07 08:47:56 +08:00
|
|
|
|
} else {
|
2025-08-14 15:02:58 +08:00
|
|
|
|
selectTestItemPopupRef.value?.open()
|
2025-08-25 11:35:38 +08:00
|
|
|
|
checkStore.setReCheckType(1)
|
2025-08-07 08:47:56 +08:00
|
|
|
|
}
|
2025-08-25 11:35:38 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
checkStore.setShowDetailType(2)
|
|
|
|
|
|
checkStore.setCheckType(1)
|
|
|
|
|
|
checkStore.initSelectTestItems()
|
|
|
|
|
|
// 一键检测
|
|
|
|
|
|
if (testType === 'reTest') {
|
|
|
|
|
|
ElMessageBox.confirm('请选择复检检测方式', '设备复检', {
|
|
|
|
|
|
distinguishCancelAndClose: true,
|
|
|
|
|
|
confirmButtonText: '不合格项复检',
|
|
|
|
|
|
cancelButtonText: '全部复检',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
})
|
|
|
|
|
|
.then(() => {
|
|
|
|
|
|
ElMessage.success('不合格项复检')
|
|
|
|
|
|
checkStore.setReCheckType(0)
|
|
|
|
|
|
if (appSceneStore.currentScene === '0') {
|
|
|
|
|
|
writeTHPopupRef.value?.open()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
openTestDialog(true)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((action: Action) => {
|
|
|
|
|
|
if (action === 'cancel') {
|
|
|
|
|
|
ElMessage.success('全部复检')
|
|
|
|
|
|
checkStore.setReCheckType(1)
|
|
|
|
|
|
if (appSceneStore.currentScene === '0') {
|
|
|
|
|
|
writeTHPopupRef.value?.open()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
openTestDialog(true)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
checkStore.setSelectTestItems({ preTest: false, timeTest: false, channelsTest: false, test: true })
|
2025-08-07 08:47:56 +08:00
|
|
|
|
} else {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
checkStore.setReCheckType(1)
|
2025-08-07 08:47:56 +08:00
|
|
|
|
openTestDialog(true)
|
|
|
|
|
|
}
|
2025-08-25 11:35:38 +08:00
|
|
|
|
}
|
2025-02-25 10:17:33 +08:00
|
|
|
|
}
|
2024-11-18 22:04:59 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
if (val === '批量归档') {
|
|
|
|
|
|
documentedPqDev(
|
|
|
|
|
|
checkStore.devices.map(item => {
|
|
|
|
|
|
return item.deviceId
|
|
|
|
|
|
})
|
|
|
|
|
|
).then(res => {
|
|
|
|
|
|
if (res.code === ResultEnum.SUCCESS) {
|
|
|
|
|
|
ElMessage.success('归档成功!')
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-01-16 14:24:55 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
emit('batchGenerateClicked') // 触发事件
|
|
|
|
|
|
}
|
|
|
|
|
|
if (val === '批量生成') {
|
|
|
|
|
|
let devIdList = checkStore.devices.map(item => {
|
|
|
|
|
|
return item.deviceId
|
|
|
|
|
|
})
|
|
|
|
|
|
await generateDevReport({
|
|
|
|
|
|
planId: checkStore.plan.id,
|
|
|
|
|
|
devIdList: devIdList,
|
|
|
|
|
|
scriptId: checkStore.plan.scriptId,
|
|
|
|
|
|
planCode: checkStore.plan.code + '',
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 999
|
|
|
|
|
|
})
|
|
|
|
|
|
ElMessage.success({ message: `报告生成成功!` })
|
|
|
|
|
|
}
|
2025-02-25 10:17:33 +08:00
|
|
|
|
}
|
2024-12-18 15:49:29 +08:00
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
const openTestDialog = (testData: any) => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
if (appSceneStore.currentScene === '0') {
|
|
|
|
|
|
if (testData) {
|
|
|
|
|
|
writeTHPopupRef.value?.open()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
testPopup.value?.open(dialogTitle.value)
|
|
|
|
|
|
}
|
2025-08-07 08:47:56 +08:00
|
|
|
|
} else {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
testPopup.value?.open(dialogTitle.value)
|
2025-08-07 08:47:56 +08:00
|
|
|
|
}
|
2025-05-15 08:57:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const openTestDialog2 = () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
testPopup.value?.open(dialogTitle.value)
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2024-11-07 20:41:32 +08:00
|
|
|
|
|
2024-11-12 20:35:12 +08:00
|
|
|
|
// 打开 drawer(新增、查看、编辑)
|
2025-08-07 08:47:56 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 打开操作弹窗或执行单行操作
|
|
|
|
|
|
* 根据操作类型处理报告生成、下载、归档、数据查询等功能
|
|
|
|
|
|
* @param title 操作类型
|
|
|
|
|
|
* @param row 当前行数据
|
|
|
|
|
|
*/
|
2025-01-13 21:38:52 +08:00
|
|
|
|
const openDrawer = async (title: string, row: any) => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 单个设备报告生成
|
|
|
|
|
|
if (title === '报告生成') {
|
|
|
|
|
|
await generateDevReport({
|
|
|
|
|
|
planId: checkStore.plan.id,
|
|
|
|
|
|
devIdList: [row.id],
|
|
|
|
|
|
scriptId: checkStore.plan.scriptId,
|
|
|
|
|
|
planCode: checkStore.plan.code + '',
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 999
|
|
|
|
|
|
})
|
|
|
|
|
|
emit('batchGenerateClicked') // 触发事件
|
|
|
|
|
|
ElMessage.success({ message: `报告生成成功!` })
|
|
|
|
|
|
}
|
2025-01-15 18:01:12 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
if (title === '报告下载') {
|
|
|
|
|
|
await useDownload(
|
|
|
|
|
|
downloadDevData,
|
|
|
|
|
|
row.createId,
|
|
|
|
|
|
{
|
|
|
|
|
|
planId: checkStore.plan.id,
|
|
|
|
|
|
devId: row.id
|
|
|
|
|
|
},
|
|
|
|
|
|
false,
|
|
|
|
|
|
'.docx'
|
|
|
|
|
|
)
|
|
|
|
|
|
emit('batchGenerateClicked') // 触发事件
|
|
|
|
|
|
}
|
2025-01-15 18:01:12 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
if (title === '检测数据查询') {
|
|
|
|
|
|
checkStore.setShowDetailType(0)
|
2025-08-26 15:16:18 +08:00
|
|
|
|
if (modeStore.currentMode == '模拟式') {
|
|
|
|
|
|
dataCheckPopupRef.value?.open(row.id, '-1', null)
|
|
|
|
|
|
} else if (modeStore.currentMode == '比对式') {
|
|
|
|
|
|
dataCheckSingleChannelSingleTestPopupRef.value?.open(row, null, row.id, 2)
|
|
|
|
|
|
}
|
2025-08-25 11:35:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (title === '误差体系更换') {
|
|
|
|
|
|
checkStore.setShowDetailType(1)
|
2025-08-26 20:52:24 +08:00
|
|
|
|
if (modeStore.currentMode == '模拟式') {
|
|
|
|
|
|
dataCheckPopupRef.value?.open(row.id, '-1', null)
|
2025-08-26 18:29:14 +08:00
|
|
|
|
} else if (modeStore.currentMode == '比对式') {
|
|
|
|
|
|
dataCheckSingleChannelSingleTestPopupRef.value?.open(row, null, row.id, 2)
|
|
|
|
|
|
}
|
2025-08-26 20:52:24 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
}
|
2024-11-12 20:35:12 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
if (title === '归档') {
|
|
|
|
|
|
await documentedPqDev([row.id]).then(res => {
|
|
|
|
|
|
if (res.code === ResultEnum.SUCCESS) {
|
|
|
|
|
|
ElMessage.success('归档成功!')
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
emit('batchGenerateClicked') // 触发事件
|
|
|
|
|
|
}
|
2024-11-12 20:35:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-13 16:35:27 +08:00
|
|
|
|
// 监听 props.id 的变化
|
|
|
|
|
|
watch(
|
2025-08-25 11:35:38 +08:00
|
|
|
|
() => props.id,
|
|
|
|
|
|
() => {
|
|
|
|
|
|
handleRefresh()
|
|
|
|
|
|
},
|
|
|
|
|
|
{ immediate: true }
|
2025-01-15 18:01:12 +08:00
|
|
|
|
)
|
2024-12-13 16:35:27 +08:00
|
|
|
|
|
2025-01-13 19:28:51 +08:00
|
|
|
|
onBeforeMount(async () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
const response = await getPqDev()
|
|
|
|
|
|
devTypeOptions.value = response.data.map(item => ({
|
|
|
|
|
|
id: item.id,
|
|
|
|
|
|
name: item.name,
|
|
|
|
|
|
icd: item.icd,
|
|
|
|
|
|
power: item.power,
|
|
|
|
|
|
devVolt: item.devVolt,
|
|
|
|
|
|
devCurr: item.devCurr,
|
|
|
|
|
|
devChns: item.devChns
|
|
|
|
|
|
}))
|
2025-01-13 19:28:51 +08:00
|
|
|
|
})
|
2025-01-13 21:06:24 +08:00
|
|
|
|
|
2025-08-05 10:37:40 +08:00
|
|
|
|
onMounted(async () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
// 初始化表格配置,使用默认的设备检测模式(activeTabs = 0)
|
|
|
|
|
|
tableHeaderInit(form.value.activeTabs)
|
2025-08-05 10:37:40 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2025-08-07 15:44:17 +08:00
|
|
|
|
// 通知dashboard组件刷新数据
|
2025-01-13 21:06:24 +08:00
|
|
|
|
const handleQuitClicked = () => {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
emit('batchGenerateClicked') // 触发事件
|
2025-01-15 18:01:12 +08:00
|
|
|
|
}
|
2025-01-13 21:06:24 +08:00
|
|
|
|
|
2025-08-07 08:47:56 +08:00
|
|
|
|
defineExpose({ changeActiveTabs })
|
2024-08-23 13:19:20 +08:00
|
|
|
|
</script>
|
2025-08-25 11:35:38 +08:00
|
|
|
|
<style lang="scss" scoped>
|
2024-09-02 16:10:33 +08:00
|
|
|
|
/* 当屏幕宽度小于或等于1300像素时 */
|
|
|
|
|
|
@media screen and (max-width: 1300px) {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
.el-select {
|
|
|
|
|
|
width: 130px !important;
|
|
|
|
|
|
}
|
2024-08-23 13:19:20 +08:00
|
|
|
|
}
|
2025-01-15 18:01:12 +08:00
|
|
|
|
|
2024-09-02 16:10:33 +08:00
|
|
|
|
@media screen and (min-width: 1300px) {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
.el-select {
|
|
|
|
|
|
width: 150px !important;
|
|
|
|
|
|
}
|
2024-08-27 18:37:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.el-form {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
width: 100%;
|
2024-08-27 18:37:46 +08:00
|
|
|
|
display: flex;
|
2025-08-25 11:35:38 +08:00
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
|
|
|
|
.el-form-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
2025-01-15 18:01:12 +08:00
|
|
|
|
|
2025-08-25 11:35:38 +08:00
|
|
|
|
.el-button {
|
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
|
margin-right: 10px !important;
|
|
|
|
|
|
}
|
2024-08-27 18:37:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-15 18:01:12 +08:00
|
|
|
|
|
|
|
|
|
|
:deep(.card) {
|
2025-08-25 11:35:38 +08:00
|
|
|
|
border: 0 !important;
|
2025-01-06 14:02:22 +08:00
|
|
|
|
}
|
2024-08-23 13:19:20 +08:00
|
|
|
|
</style>
|