Files
pqs-9100_client/frontend/src/views/home/components/table.vue
2025-08-07 08:55:28 +08:00

1078 lines
31 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'>通道配对
</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>
</div>
</template>
<script setup lang='tsx' name='useProTable'>
import { onBeforeMount, onMounted, type PropType, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox, type Action } from 'element-plus'
import TestPopup from './testPopup.vue'
import dataCheckPopup from './dataCheckSingleChannelSingleTestPopup.vue'
import ProTable from '@/components/ProTable/index.vue'
import socketClient from '@/utils/webSocketClient'
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'
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 !== '归档'
}
}
// WebSocket客户端配置用于实时通信
const dataSocket = reactive({
socketServe: socketClient.Instance,
})
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 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,
},
{
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: // 报告生成模式
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
}
}
/**
* 重置表格状态和查询条件
* 在切换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 = () => {
// 检查是否选择了设备
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 dataSources = ref([])
const matchedItem = props.planTable.data.find(item => item.name === props.plan.name)
if (matchedItem) {
dataSources.value = matchedItem.datasourceIds
}
deviceConnectionPopupRef.value?.open(channelsSelection.value, pqStandardDevList.value, dataSources.value)
}
/**
* 检测操作主处理函数
* 根据操作类型(手动检测/一键检测/批量生成/批量归档等)执行相应逻辑
* @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') {
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 })
} 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') {
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 })
} 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') {
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 === '报告生成') {
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)
dataCheckPopupRef.value?.open(row.id, '-1', null)
}
if (title === '误差体系更换') {
checkStore.setShowDetailType(1)
dataCheckPopupRef.value?.open(row.id, '-1', null)
}
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)
})
const handleQuitClicked = () => {
dataSocket.socketServe.closeWs()
emit('batchGenerateClicked') // 触发事件
}
const handleSubmitClicked = async (resolve: (value: boolean) => void) => {
if (!dataSocket.socketServe.connected) {
ElMessage.error('webSocket连接中断请退出重新进行系数校准')
resolve(false)
} else {
resolve(true)
}
}
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>