Files
pqs-9100_client/frontend/src/views/home/components/table.vue

1120 lines
39 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
设备管理表格组件 - 支持多种业务模式
主要功能设备检测报告生成设备归档数据操作
支持手动/一键检测批量操作通道配对等高级功能
-->
<template>
<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"
v-if="modeStore.currentMode == '比对式'"
>
手动检测
</el-button>
<!-- 设备检测模式下的操作按钮 -->
<el-button
type="primary"
icon="Clock"
@click="handleTest('手动检测')"
v-if="form.activeTabs === 0 && modeStore.currentMode == '模拟式'"
>
手动检测
</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" :append-to-body="true" />
<!-- 手动检测检测项选择弹窗 -->
<SelectTestItemPopup ref="selectTestItemPopupRef" @openTestDialog="openTestDialog"></SelectTestItemPopup>
<!-- 省平台模式下的温度湿度填写弹窗 -->
<WriteTHPopup ref="writeTHPopupRef" @openTestDialog2="openTestDialog2"></WriteTHPopup>
<!-- 比对模式下的通道配对弹窗 -->
<DeviceConnectionPopup ref="deviceConnectionPopupRef"></DeviceConnectionPopup>
<!-- 检测数据查询弹窗 -->
<CompareDataCheckSingleChannelSingleTestPopup
ref="dataCheckSingleChannelSingleTestPopupRef"
:append-to-body="true"
/>
<!-- 报告生成弹框 -->
<ReportResultPopup ref="reportPopup"></ReportResultPopup>
</div>
</template>
<script setup lang="tsx" name="useProTable">
import { onBeforeMount, onMounted, type PropType, reactive, ref, watch } from 'vue'
import { type Action, ElMessage, ElMessageBox } from 'element-plus'
import TestPopup from './testPopup.vue'
import dataCheckPopup from './dataCheckSingleChannelSingleTestPopup.vue'
import CompareDataCheckSingleChannelSingleTestPopup from '@/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue'
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 ColumnProps, type ProTableInstance } from '@/components/ProTable/interface'
import { type Plan } from '@/api/plan/interface'
import { type StandardDevice } from '@/api/device/interface/standardDevice'
import { downloadDevData, generateDevReport, getBoundPqDevList } from '@/api/plan/plan'
import { getPqDev } from '@/api/device/device'
import { useAppSceneStore, useModeStore } 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'
import { getPqMonList } from '@/api/device/monitor/index.ts'
import ReportResultPopup from '@/views/home/components/reportResultPopup.vue'
const checkStore = useCheckStore()
let devNum = 0 //当前选取的被检设备数量
let devChannelsNum = 0 //当前选择的被检设备通道总数
const tableKey = ref(0)
const tableHeight = ref(0)
const dataCheckPopupRef = ref<InstanceType<typeof dataCheckPopup>>()
const selectTestItemPopupRef = ref<InstanceType<typeof SelectTestItemPopup>>()
const writeTHPopupRef = ref<InstanceType<typeof WriteTHPopup>>()
const deviceConnectionPopupRef = ref<InstanceType<typeof DeviceConnectionPopup>>()
const dialogTitle = ref('手动检测')
const checkStateTable = ref<number[]>([0, 1, 2])
const modeStore = useModeStore()
/**
* 控制下拉框选项的显示逻辑
* 根据当前Tab模式动态控制哪些选项可见
* @param item 下拉框选项对象
* @returns 是否显示该选项
*/
const shouldShowOption = (item: any) => {
// 非设备检测模式weiJianTab !== 0隐藏"归档"和"未检"选项
if (weiJianTab.value !== 0) {
return item.label !== '归档' && item.label !== '未检'
} else {
// 设备检测模式只隐藏"归档"选项
return item.label !== '归档'
}
}
const dataCheckSingleChannelSingleTestPopupRef = ref()
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)
const testPopup = ref()
const reportPopup = ref()
const weiJianTab = ref(0) // 当前Tab索引用于控制选项显示逻辑
const channelsSelection = ref<Device.ResPqDev[]>([])
const props = defineProps({
id: {
type: String,
required: true
},
plan: {
type: Object,
default: null
},
planArray: {
type: Array as PropType<Plan.ReqPlan[]>,
default: null
},
planTable: {
type: Array,
default: () => []
}
})
const appSceneStore = useAppSceneStore()
const emit = defineEmits<{
(e: 'batchGenerateClicked'): void
}>()
// 存储设备类型选项
const devTypeOptions = ref<
{
id: string
name: string
icd: string
power: string
devVolt: number
devCurr: number
devChns: number
}[]
>([])
//下拉框数据
interface Dict {
id: string
label: string
}
//检测状态数据
const checkStatus: Dict[] = [
{
id: '0',
label: '未检'
},
{
id: '1',
label: '检测中'
},
{
id: '2',
label: '检测完成'
},
{
id: '3',
label: '归档'
}
]
//检测报告状态数据
const checkReportStatus: Dict[] = [
{
id: '0',
label: '未生成'
},
{
id: '1',
label: '已生成'
},
{
id: '2',
label: '未检'
}
]
//检测结果数组
const checkResult: Dict[] = [
{
id: '0',
label: '不符合'
},
{
id: '1',
label: '符合'
},
{
id: '2',
label: '未检'
}
]
//查询条件
const form: any = ref({
activeTabs: 0, //功能选择
search: null, //搜索内容
checkStatus: null, //检测状态
checkResult: null, //检测结果
checkReportStatus: null, //检测报告状态
deviceBindStatus: 0, //绑定状态
deviceType: 0, //设备类型
manufacturer: 0 //制造厂商
})
// ProTable 实例
const proTable = ref<ProTableInstance>()
/**
* 获取表格数据的异步函数
* 根据权限控制列显示,根据查询条件获取设备列表
*/
const getTableList = async () => {
// 权限控制:没有通道系数权限时隐藏相关列
const authStore = useAuthStore()
const currentPageRoles = authStore.authButtonListGet[authStore.routeName] ?? []
if (!currentPageRoles.includes('channelsTest')) {
factorCheckShow.value = false
}
// 清空当前表格选择
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
})
}
}
// 表格配置项
const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
{
type: 'selection',
fixed: 'left',
width: 70,
isShow: selectionShow,
selectable(row) {
if (weiJianTab.value === 4) {
return row.reportState === 1 || row.reportState === 3
}
return true
}
},
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'name',
label: '设备名称',
minWidth: 220
},
{
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
}
},
{
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(',') : '/'
}
},
{
prop: 'devChns',
label: '通道数',
minWidth: 100,
sortable: true
},
{
prop: 'recheckNum',
label: '检测次数',
minWidth: 100,
sortable: true,
isShow: modeStore.currentMode != '比对式'
},
{
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 '未检'
}
}
},
{ prop: 'operation', label: '操作', fixed: 'right', minWidth: 200, isShow: operationShow }
])
let testType = 'test' // 检测类型:'test'-检测 'reTest'-复检
/**
* 表格行选择变化时的处理函数
* 更新全局统计信息,用于后续操作的校验和限制
*/
const handleSelectionChange = (selection: any[]) => {
channelsSelection.value = selection
// 统计选中设备数量
devNum = selection.length
// 统计选中设备的总通道数
devChannelsNum = 0
for (let i = 0; i < selection.length; i++) {
devChannelsNum += selection[i].devChns
}
// 统计已完成检测的设备数量
const result = selection.filter(item => item.checkResult != 0)
if (result.length > 0) {
testType = 'test'
} else {
testType = 'reTest'
}
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
}
})
if (selection.length > 0) {
checkStore.clearDevices()
checkStore.addDevices(devices)
} else {
checkStore.clearDevices()
}
}
//查询
const handleSearch = () => {
proTable.value?.getTableList()
}
//重置
const handleRefresh = () => {
form.value.search = null
form.value.checkStatus = null
form.value.checkResult = null
form.value.checkReportStatus = null
proTable.value?.getTableList()
}
// 表格排序
const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
console.log(newIndex, oldIndex) // 避免未使用参数警告
ElMessage.success('修改列表排序成功')
}
/**
* 切换顶部功能Tab时的处理函数
* @param val Tab索引0-设备检测 1-手动检测 2-设备复检 3-报告生成 4-设备归档 5-数据查询
* 现在1和2已不做考虑了其他4种tab满足当前的工作需求
*/
const changeActiveTabs = (val: number) => {
form.value.activeTabs = val
tableHeaderInit(val)
}
/**
* 根据当前功能Tab初始化表格配置
* 不同Tab模式下表格会显示不同的列和操作按钮
* @param val Tab索引0-设备检测 1-手动检测 2-设备复检 3-报告生成 4-设备归档 5-数据查询
*/
function tableHeaderInit(val: number) {
// 重置查询条件和选择状态
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: // 报告生成模式
if(modeStore.currentMode === '比对式'){
checkStateTable.value = [1,2, 3] // 显示检测中,检测完成和归档状态
}else{
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: // 数据查询模式
if (modeStore.currentMode === '比对式') {
checkStateTable.value = [1, 2, 3] // 显示检测中,检测完成和归档状态
} else {
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
}
}
/**
* 重置表格状态和查询条件
* 在切换Tab或重置操作时调用清空所有筛选条件和选择状态
*/
function refreshStatusList() {
// 重置设备选择统计信息
devNum = 0
devChannelsNum = 0
// 清空查询表单
form.value.search = null
form.value.checkStatus = null //检测状态默认为未检
form.value.checkReportStatus = null //检测报告状态默认为未生成报告
form.value.checkResult = null //检测结果默认为未出结果
}
/**
* 通道配对功能处理函数(比对模式专用)
* 校验选中设备的一致性,然后打开通道配对弹窗
*/
const handleTest2 = async () => {
// 检查是否选择了设备
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
}
// 获取设备所属计划名称
const boundPlanName = ref('')
if (channelsSelection.value[0].boundPlanName) {
boundPlanName.value = channelsSelection.value[0].boundPlanName
} else {
boundPlanName.value = props.plan.name
}
// 查找选中设备所属计划的标准设备列表
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 []
})
// 检查是否有标准设备可用于配对
if (pqStandardDevList.value.length == 0) {
ElMessageBox.confirm('所勾选被检设备所属计划无标准设备,请重新选择', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
return
}
const devBindMonList = await getPqMonList({ devIds: channelsSelection.value.map(d => d.id) })
// 创建一个映射来存储每个设备的监测点信息(支持多个监测点)
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])
}
})
// 过滤出至少有一个监测点的设备
const filteredChannelsSelection = channelsSelection.value.filter(device => {
return deviceMonitoringMap.has(device.id)
})
// 如果没有设备有监测点,则提示并返回
if (filteredChannelsSelection.length === 0) {
ElMessageBox.confirm('所选设备均无监测点,请检查设备配置', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
return
}
// 检查是否有设备被过滤掉
const devicesWithoutMonitoring = channelsSelection.value.filter(device => {
return !deviceMonitoringMap.has(device.id)
})
// 提示完全没有监测点的设备
if (devicesWithoutMonitoring.length > 0) {
const deviceNames = devicesWithoutMonitoring.map(d => d.name).join(', ')
ElMessage.warning(`以下设备没有监测点: ${deviceNames}`)
}
// 检查监测点数量与通道数是否一致,并指出具体哪些通道未绑定
const inconsistentPointDevices = filteredChannelsSelection.filter(device => {
const monitoringInfoArray = deviceMonitoringMap.get(device.id)
const pointCount = monitoringInfoArray ? monitoringInfoArray.length : 0
// 只有当监测点数量与通道数不一致时才需要提示
return pointCount !== device.devChns
})
if (inconsistentPointDevices.length > 0) {
const deviceNames = inconsistentPointDevices.map(d => d.name).join(', ')
ElMessage.warning(`以下设备存在通道未绑定监测点: ${deviceNames}`)
}
// 只传递有监测点的设备
deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevList.value, props.id)
}
/**
* 检测操作主处理函数
* 根据操作类型(手动检测/一键检测/批量生成/批量归档等)执行相应逻辑
* @param val 操作类型字符串
*/
const handleTest = async (val: string) => {
// 检查是否选择了设备
if (devNum == 0) {
ElMessageBox.confirm('请先选择被检设备', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
return
}
// 检查选中设备的额定电压是否一致
const checkDevVolt = channelsSelection.value.map(item => item.devVolt)
const isDevVoltConsistent = new Set(checkDevVolt).size === 1
if (!isDevVoltConsistent) {
ElMessageBox.confirm('所勾选设备额定电压不一致,请重新选择', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
return
}
// 检查选中设备的额定电流是否一致
const checkDevCurr = channelsSelection.value.map(item => item.devCurr)
const isDevCurrConsistent = new Set(checkDevCurr).size === 1
if (!isDevCurrConsistent) {
ElMessageBox.confirm('所勾选设备额定电流不一致,请重新选择', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
return
}
// 处理检测相关操作
if (val === '手动检测' || val === '一键检测' || val === '系数校准') {
// 检查选中设备的检测状态是否一致
const checkStates = channelsSelection.value.map(item => item.checkState)
const allCheckStatesEqual = new Set(checkStates).size <= 1
// 如果检测状态不一致,设置为复检模式
if (!allCheckStatesEqual) {
checkStore.setReCheckType(1)
}
// 限制每次检测最多12个通道
if (devChannelsNum > 12) {
ElMessageBox.confirm('每次检测最多只能检测12个设备通道请重新选择', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
return
}
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' && modeStore.currentMode != '比对式') {
writeTHPopupRef.value?.open()
} else {
selectTestItemPopupRef.value?.open()
}
})
.catch((action: Action) => {
if (action === 'cancel') {
ElMessage.success('全部复检')
checkStore.setReCheckType(1)
if (appSceneStore.currentScene === '0' && modeStore.currentMode != '比对式') {
writeTHPopupRef.value?.open()
} else {
selectTestItemPopupRef.value?.open()
}
}
})
checkStore.setSelectTestItems({ preTest: false, timeTest: false, channelsTest: false, test: true })
} else {
selectTestItemPopupRef.value?.open()
checkStore.setReCheckType(1)
}
} 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' && modeStore.currentMode != '比对式') {
writeTHPopupRef.value?.open()
} else {
openTestDialog(true)
}
})
.catch((action: Action) => {
if (action === 'cancel') {
ElMessage.success('全部复检')
checkStore.setReCheckType(1)
if (appSceneStore.currentScene === '0' && modeStore.currentMode != '比对式') {
writeTHPopupRef.value?.open()
} else {
openTestDialog(true)
}
}
})
checkStore.setSelectTestItems({ preTest: false, timeTest: false, channelsTest: false, test: true })
} else {
checkStore.setReCheckType(1)
openTestDialog(true)
}
}
}
if (val === '批量归档') {
documentedPqDev(
checkStore.devices.map(item => {
return item.deviceId
})
).then(res => {
if (res.code === ResultEnum.SUCCESS) {
ElMessage.success('归档成功!')
}
})
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: `报告生成成功!` })
}
}
const openTestDialog = (testData: any) => {
if (appSceneStore.currentScene === '0' && modeStore.currentMode != '比对式') {
if (testData) {
writeTHPopupRef.value?.open()
} else {
testPopup.value?.open(dialogTitle.value)
}
} else {
testPopup.value?.open(dialogTitle.value)
}
}
const openTestDialog2 = () => {
testPopup.value?.open(dialogTitle.value)
}
// 打开 drawer(新增、查看、编辑)
/**
* 打开操作弹窗或执行单行操作
* 根据操作类型处理报告生成、下载、归档、数据查询等功能
* @param title 操作类型
* @param row 当前行数据
*/
const openDrawer = async (title: string, row: any) => {
// 单个设备报告生成
if (title === '报告生成') {
reportPopup.value?.open(row)
/*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: `报告生成成功!` })*/
}
if (title === '报告下载') {
await useDownload(
downloadDevData,
row.createId,
{
planId: checkStore.plan.id,
devId: row.id
},
false,
'.docx'
)
emit('batchGenerateClicked') // 触发事件
}
if (title === '检测数据查询') {
checkStore.setShowDetailType(0)
if (modeStore.currentMode == '模拟式') {
dataCheckPopupRef.value?.open(row.id, '-1', null)
} else if (modeStore.currentMode == '比对式') {
dataCheckSingleChannelSingleTestPopupRef.value?.open(row, null, row.id, 2)
}
}
if (title === '误差体系更换') {
checkStore.setShowDetailType(1)
if (modeStore.currentMode == '模拟式') {
dataCheckPopupRef.value?.open(row.id, '-1', null)
} else if (modeStore.currentMode == '比对式') {
dataCheckSingleChannelSingleTestPopupRef.value?.open(row, null, row.id, 2)
}
}
if (title === '归档') {
await documentedPqDev([row.id]).then(res => {
if (res.code === ResultEnum.SUCCESS) {
ElMessage.success('归档成功!')
}
})
emit('batchGenerateClicked') // 触发事件
}
}
// 监听 props.id 的变化
watch(
() => props.id,
() => {
handleRefresh()
},
{ immediate: true }
)
onBeforeMount(async () => {
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
}))
})
onMounted(async () => {
// 初始化表格配置,使用默认的设备检测模式(activeTabs = 0)
tableHeaderInit(form.value.activeTabs)
})
// 通知dashboard组件刷新数据
const handleQuitClicked = () => {
emit('batchGenerateClicked') // 触发事件
}
defineExpose({ changeActiveTabs })
</script>
<style lang="scss" scoped>
/* 当屏幕宽度小于或等于1300像素时 */
@media screen and (max-width: 1300px) {
.el-select {
width: 130px !important;
}
}
@media screen and (min-width: 1300px) {
.el-select {
width: 150px !important;
}
}
.el-form {
width: 100%;
display: flex;
flex-wrap: wrap;
.el-form-item {
display: flex;
align-items: center;
justify-content: space-between;
.el-button {
margin: 0 !important;
margin-right: 10px !important;
}
}
}
:deep(.card) {
border: 0 !important;
}
</style>