Merge remote-tracking branch 'origin/master'

This commit is contained in:
贾同学
2025-08-25 14:53:06 +08:00
4 changed files with 930 additions and 895 deletions

View File

@@ -6,7 +6,7 @@
border border
:header-cell-style="{ textAlign: 'center' }" :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }" :cell-style="{ textAlign: 'center' }"
max-height="282px" height="368px"
style="width: 100%" style="width: 100%"
> >
<el-table-column type="index" label="序号" width="70" fixed="left" /> <el-table-column type="index" label="序号" width="70" fixed="left" />

View File

@@ -2,7 +2,7 @@
<div class="table-main"> <div class="table-main">
<el-table <el-table
:data="prop.tableData" :data="prop.tableData"
height="357px" height="368px"
:header-cell-style="{ textAlign: 'center' }" :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }" :cell-style="{ textAlign: 'center' }"
> >

View File

@@ -57,6 +57,17 @@
</el-form> </el-form>
</div> </div>
<div class="data-check-body"> <div class="data-check-body">
<div class="content-left-tree">
<el-tree
style="width: 200px"
:data="scriptData"
:props="defaultProps"
highlight-current
node-key="id"
ref="treeRef"
@node-click="handleNodeClick"
/>
</div>
<div class="content-right"> <div class="content-right">
<div class="content-right-title"> <div class="content-right-title">
<div style="width: 840px"> <div style="width: 840px">
@@ -125,16 +136,18 @@ const modeStore = useModeStore()
const dictStore = useDictStore() const dictStore = useDictStore()
const visible = ref(false) const visible = ref(false)
const treeRef = ref() const treeRef = ref()
const searchValue = ref<string>('')
const pqErrorList = reactive<{ id: string; name: string }[]>([]) const pqErrorList = reactive<{ id: string; name: string }[]>([])
const activeTab = ref('resultTab') const activeTab = ref('resultTab')
const currentCheckItem = ref<any>() const currentCheckItem = ref<any>()
const rowList: any = ref([]) const rowList: any = ref([])
let scriptType: string | null = null let scriptType: string | null = null
watch(searchValue, val => { const defaultProps = {
treeRef.value!.filter(val) children: 'children',
}) label: 'scriptName'
}
const chnMapList: any = ref({}) const chnMapList: any = ref({})
// 表单数据 // 表单数据
@@ -147,6 +160,7 @@ const formContent = reactive<CheckData.DataCheck>({
deviceId: '', deviceId: '',
num: '' num: ''
}) })
const source = ref('1') //1:正式检测进入页面 2:检测数据查询进入
// 通道下拉列表 // 通道下拉列表
const chnList: any = ref([]) const chnList: any = ref([])
@@ -155,7 +169,8 @@ const chnList: any = ref([])
const currentScriptTypeName = ref('') const currentScriptTypeName = ref('')
// 检测结果表格数据 // 检测结果表格数据
const checkResultData = ref<CheckData.CheckResult[]>([]) const checkResultData = ref<CheckData.CheckResult[]>([])
// 检测脚本配置数据
const scriptData = ref<CheckData.ScriptItem[]>([])
// 原始数据表格数据 // 原始数据表格数据
const rawTableData = ref<CheckData.RawDataItem[]>([]) const rawTableData = ref<CheckData.RawDataItem[]>([])
const tesList: any = ref([]) const tesList: any = ref([])
@@ -168,12 +183,17 @@ const currentRawTableData = computed(() => {
const data = rawTableData.value[currentCheckItem.value] const data = rawTableData.value[currentCheckItem.value]
return Array.isArray(data) ? data : [] return Array.isArray(data) ? data : []
}) })
const open = async (row: any, chnNum: string, deviceId: string | null, source: number) => { const open = async (row: any, chnNum: string, deviceId: string | null, source: number) => {
rowList.value = {}
formContent.deviceId = deviceId || ''
formContent.chnNum = chnNum
if (source == 1) { if (source == 1) {
// 正式检测进入页面 // 正式检测进入页面
rowList.value = row rowList.value = row
formContent.chnNum = chnNum } else if (source == 2) {
formContent.deviceId = deviceId || '' // 检测数据查询进入
await initScriptData(row)
} }
visible.value = true visible.value = true
@@ -186,8 +206,32 @@ const open = async (row: any, chnNum: string, deviceId: string | null, source: n
Object.assign(pqErrorList, resPqErrorList) Object.assign(pqErrorList, resPqErrorList)
// 获取基本信息 // 获取基本信息
await getBasicInformation() await getBasicInformation()
await getTestItem()
await getResults()
}
// 查询大项树
const initScriptData = async (row: any) => {
const pattern = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
let response: any = await getBigTestItem({
reCheckType: checkStore.reCheckType,
planId: checkStore.plan.id,
devIds: checkStore.devices.map(item => item.deviceId),
patternId: pattern
})
// 格式化脚本数据
let temp = response.data.map((item: any) => {
return {
...item,
scriptName: item.scriptName
}
})
rowList.value.scriptName = temp[0].scriptName
rowList.value.scriptType = temp[0].id
// 保存脚本数据并设置总数
scriptData.value = temp
setTimeout(() => {
treeRef.value?.setCurrentKey(temp[0].id)
}, 0)
} }
//获取基本信息 //获取基本信息
const getBasicInformation = async () => { const getBasicInformation = async () => {
@@ -207,16 +251,17 @@ const getBasicInformation = async () => {
chnMap.push(key) chnMap.push(key)
} }
chnList.value = chnMap chnList.value = chnMap
formContent.chnNum = formContent.chnNum == null ? chnList.value[0] : formContent.chnNum
// 查询表格数据
getResults()
}) })
} }
// 获取测试项
const getTestItem = async () => { // 左边树变化
getBigTestItem({ const handleNodeClick = (data: any) => {
reCheckType: 1, rowList.value.scriptName = data.scriptName
planId: checkStore.plan.id, rowList.value.scriptType = data.id
devIds: [formContent.deviceId], getResults()
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
}).then((res: any) => {})
} }
// 获取结果 // 获取结果
const getResults = async () => { const getResults = async () => {
@@ -255,13 +300,10 @@ defineExpose({
.dialog { .dialog {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow-y: hidden;
overflow-x: hidden;
.data-check-dialog { .data-check-dialog {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow-y: hidden;
.data-check-head { .data-check-head {
display: flex; display: flex;
@@ -322,9 +364,23 @@ defineExpose({
box-sizing: border-box; box-sizing: border-box;
margin-top: 10px; margin-top: 10px;
margin-bottom: 10px; margin-bottom: 10px;
max-height: 400px; display: flex;
.el-tabs {
width: 100%;
}
}
.content-left {
height: 100%;
border: 1px solid #e0e0e0;
padding: 10px;
margin-right: 10px;
height: 410px;
overflow-y: auto;
} }
} }
} }
} }
:deep(.el-tabs--border-card > .el-tabs__content) {
height: 367px;
}
</style> </style>

View File

@@ -4,176 +4,198 @@
支持手动/一键检测批量操作通道配对等高级功能 支持手动/一键检测批量操作通道配对等高级功能
--> -->
<template> <template>
<div class='table_info'> <div class="table_info">
<!-- 主表格组件支持排序选择动态列等功能 --> <!-- 主表格组件支持排序选择动态列等功能 -->
<ProTable <ProTable
ref='proTable' ref="proTable"
:columns='columns' :columns="columns"
@drag-sort='sortTable' @drag-sort="sortTable"
:default-sort="{ prop: 'check_State', order: 'ascending' }" :default-sort="{ prop: 'check_State', order: 'ascending' }"
:stripe='true' :stripe="true"
:pagination='false' :pagination="false"
:key='tableKey' :key="tableKey"
@selection-change='handleSelectionChange' @selection-change="handleSelectionChange"
:request-api='getTableList' :request-api="getTableList"
:toolButton='false' :toolButton="false"
> >
<!-- 表格头部操作区域包含查询筛选和功能按钮 --> <!-- 表格头部操作区域包含查询筛选和功能按钮 -->
<template #tableHeader=''> <template #tableHeader="">
<el-form :model='form' :inline='true'> <el-form :model="form" :inline="true">
<!-- 查询筛选区域 --> <!-- 查询筛选区域 -->
<el-form-item label='关键字'> <el-form-item label="关键字">
<el-input v-model='form.search' placeholder='请输入设备名称' clearable style='width: 170px;' show-word-limit <el-input
maxlength='32'></el-input> v-model="form.search"
placeholder="请输入设备名称"
clearable
style="width: 170px"
show-word-limit
maxlength="32"
></el-input>
</el-form-item> </el-form-item>
<!-- 检测状态筛选仅在设备检测模式下显示 --> <!-- 检测状态筛选仅在设备检测模式下显示 -->
<el-form-item label='检测状态' v-if='form.activeTabs != 3 && form.activeTabs != 4 && form.activeTabs != 5'> <el-form-item
<el-select v-model='form.checkStatus' clearable> label="检测状态"
v-if="form.activeTabs != 3 && form.activeTabs != 4 && form.activeTabs != 5"
>
<el-select v-model="form.checkStatus" clearable>
<el-option <el-option
v-for='(item, index) in checkStatus' v-for="(item, index) in checkStatus"
:label='item.label' :label="item.label"
:value='item.id' :value="item.id"
:key='index' :key="index"
v-show='shouldShowOption(item)' v-show="shouldShowOption(item)"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 检测结果筛选 --> <!-- 检测结果筛选 -->
<el-form-item label='检测结果'> <el-form-item label="检测结果">
<el-select v-model='form.checkResult' clearable> <el-select v-model="form.checkResult" clearable>
<el-option <el-option
v-for='(item, index) in checkResult' v-for="(item, index) in checkResult"
:label='item.label' :label="item.label"
:value='item.id' :value="item.id"
:key='index' :key="index"
v-show='shouldShowOption(item)' v-show="shouldShowOption(item)"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 报告状态筛选 --> <!-- 报告状态筛选 -->
<el-form-item label='报告状态'> <el-form-item label="报告状态">
<el-select v-model='form.checkReportStatus' clearable> <el-select v-model="form.checkReportStatus" clearable>
<el-option <el-option
v-for='(item, index) in checkReportStatus' v-for="(item, index) in checkReportStatus"
:label='item.label' :label="item.label"
:value='item.id' :value="item.id"
:key='index' :key="index"
v-show='shouldShowOption(item)' v-show="shouldShowOption(item)"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 功能按钮区域 --> <!-- 功能按钮区域 -->
<el-form-item> <el-form-item>
<!-- 基本查询操作 --> <!-- 基本查询操作 -->
<el-button type='primary' icon='Search' @click='handleSearch' <el-button type="primary" icon="Search" @click="handleSearch">查询</el-button>
>查询 <el-button icon="Delete" @click="handleRefresh">重置</el-button>
</el-button
>
<el-button icon='Delete' @click='handleRefresh'
>重置
</el-button
>
<!-- 比对模式下的通道配对功能 --> <!-- 比对模式下的通道配对功能 -->
<el-button <el-button type="primary" icon="Clock" @click="handleTest2">通道配对</el-button>
type='primary'
icon='Clock' @click='handleTest2'>通道配对
</el-button>
<!-- 设备检测模式下的操作按钮 --> <!-- 设备检测模式下的操作按钮 -->
<el-button <el-button
type='primary' type="primary"
icon='Clock' icon="Clock"
@click="handleTest('手动检测')" @click="handleTest('手动检测')"
v-if='form.activeTabs === 0' v-if="form.activeTabs === 0"
>手动检测
</el-button
> >
手动检测
</el-button>
<el-button <el-button
type='primary' type="primary"
icon='ChatLineRound' icon="ChatLineRound"
@click="handleTest('一键检测')" @click="handleTest('一键检测')"
v-if='form.activeTabs === 0' v-if="form.activeTabs === 0"
>一键检测 >
一键检测
</el-button> </el-button>
<!-- 报告生成模式下的批量操作 --> <!-- 报告生成模式下的批量操作 -->
<el-button type='primary' icon='Postcard' @click="handleTest('批量生成')" v-if='form.activeTabs === 3'> <el-button
type="primary"
icon="Postcard"
@click="handleTest('批量生成')"
v-if="form.activeTabs === 3"
>
报告生成 报告生成
</el-button> </el-button>
<!-- 设备归档模式下的批量操作 --> <!-- 设备归档模式下的批量操作 -->
<el-button type='primary' icon='Notebook' @click="handleTest('批量归档')" v-if='form.activeTabs === 4'> <el-button
type="primary"
icon="Notebook"
@click="handleTest('批量归档')"
v-if="form.activeTabs === 4"
>
归档 归档
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<!-- 表格行操作列根据不同模式显示不同的操作按钮 --> <!-- 表格行操作列根据不同模式显示不同的操作按钮 -->
<template #operation='scope'> <template #operation="scope">
<!-- 报告下载仅在报告已生成或已上传时显示 --> <!-- 报告下载仅在报告已生成或已上传时显示 -->
<el-button <el-button
type='primary' type="primary"
link link
icon='Download' icon="Download"
@click="openDrawer('报告下载', scope.row)" @click="openDrawer('报告下载', scope.row)"
v-if='form.activeTabs === 3 && (scope.row.reportState === 1 ||scope.row.reportState === 3)' v-if="form.activeTabs === 3 && (scope.row.reportState === 1 || scope.row.reportState === 3)"
>报告下载 >
报告下载
</el-button> </el-button>
<!-- 单个设备报告生成 --> <!-- 单个设备报告生成 -->
<el-button <el-button
type='primary' type="primary"
link link
icon='Postcard' icon="Postcard"
@click="openDrawer('报告生成', scope.row)" @click="openDrawer('报告生成', scope.row)"
v-if='form.activeTabs === 3 ' v-if="form.activeTabs === 3"
>报告生成 >
报告生成
</el-button> </el-button>
<!-- 设备归档模式下的单个归档操作 --> <!-- 设备归档模式下的单个归档操作 -->
<el-button type='primary' <el-button
type="primary"
link link
icon='Notebook' icon="Notebook"
@click="openDrawer('归档', scope.row)" @click="openDrawer('归档', scope.row)"
v-if='form.activeTabs === 4' v-if="form.activeTabs === 4"
>归档 >
归档
</el-button> </el-button>
<!-- 数据操作模式下的功能 --> <!-- 数据操作模式下的功能 -->
<el-button <el-button
type='primary' type="primary"
link link
icon='PieChart' icon="PieChart"
@click="openDrawer('检测数据查询', scope.row)" @click="openDrawer('检测数据查询', scope.row)"
v-if='form.activeTabs === 5' v-if="form.activeTabs === 5"
>检测数据查询 >
检测数据查询
</el-button> </el-button>
<!-- 误差体系更换功能 --> <!-- 误差体系更换功能 -->
<el-button <el-button
type='primary' type="primary"
link link
icon='Switch' icon="Switch"
@click="openDrawer('误差体系更换', scope.row)" @click="openDrawer('误差体系更换', scope.row)"
v-if='form.activeTabs === 5' v-if="form.activeTabs === 5"
>误差体系更换 >
误差体系更换
</el-button> </el-button>
</template> </template>
</ProTable> </ProTable>
<!-- ======================== 弹窗组件区域 ======================== --> <!-- ======================== 弹窗组件区域 ======================== -->
<!-- 检测过程显示弹窗 --> <!-- 检测过程显示弹窗 -->
<TestPopup ref='testPopup' @quitClicked='handleQuitClicked'></TestPopup> <TestPopup ref="testPopup" @quitClicked="handleQuitClicked"></TestPopup>
<!-- 检测数据查询弹窗 --> <!-- 检测数据查询弹窗 -->
<dataCheckPopup ref='dataCheckPopupRef' /> <dataCheckPopup ref="dataCheckPopupRef" />
<!-- 手动检测检测项选择弹窗 --> <!-- 手动检测检测项选择弹窗 -->
<SelectTestItemPopup ref='selectTestItemPopupRef' @openTestDialog='openTestDialog'></SelectTestItemPopup> <SelectTestItemPopup ref="selectTestItemPopupRef" @openTestDialog="openTestDialog"></SelectTestItemPopup>
<!-- 省平台模式下的温度湿度填写弹窗 --> <!-- 省平台模式下的温度湿度填写弹窗 -->
<WriteTHPopup ref='writeTHPopupRef' @openTestDialog2='openTestDialog2'></WriteTHPopup> <WriteTHPopup ref="writeTHPopupRef" @openTestDialog2="openTestDialog2"></WriteTHPopup>
<!-- 比对模式下的通道配对弹窗 --> <!-- 比对模式下的通道配对弹窗 -->
<DeviceConnectionPopup ref='deviceConnectionPopupRef'></DeviceConnectionPopup> <DeviceConnectionPopup ref="deviceConnectionPopupRef"></DeviceConnectionPopup>
<!-- 检测数据查询弹窗 -->
<CompareDataCheckSingleChannelSingleTestPopup
ref="dataCheckSingleChannelSingleTestPopupRef"
:append-to-body="true"
/>
</div> </div>
</template> </template>
<script setup lang='tsx' name='useProTable'> <script setup lang="tsx" name="useProTable">
import { onBeforeMount, onMounted, type PropType, reactive, ref, watch } from 'vue' import { onBeforeMount, onMounted, type PropType, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox, type Action } from 'element-plus' import { ElMessage, ElMessageBox, type Action } from 'element-plus'
import TestPopup from './testPopup.vue' import TestPopup from './testPopup.vue'
import dataCheckPopup from './dataCheckSingleChannelSingleTestPopup.vue' import dataCheckPopup from './dataCheckSingleChannelSingleTestPopup.vue'
import CompareDataCheckSingleChannelSingleTestPopup from '@/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue'
import ProTable from '@/components/ProTable/index.vue' import ProTable from '@/components/ProTable/index.vue'
import SelectTestItemPopup from '@/views/home/components/selectTestItemPopup.vue' import SelectTestItemPopup from '@/views/home/components/selectTestItemPopup.vue'
import WriteTHPopup from '@/views/home/components/writeTHPopup.vue' import WriteTHPopup from '@/views/home/components/writeTHPopup.vue'
@@ -192,11 +214,11 @@ import { useAuthStore } from '@/stores/modules/auth'
import { useDownload } from '@/hooks/useDownload' import { useDownload } from '@/hooks/useDownload'
import { documentedPqDev } from '@/api/device/report' import { documentedPqDev } from '@/api/device/report'
import { ResultEnum } from '@/enums/httpEnum' import { ResultEnum } from '@/enums/httpEnum'
import {getPqMonList} from '@/api/device/monitor/index.ts' import { getPqMonList } from '@/api/device/monitor/index.ts'
const checkStore = useCheckStore() const checkStore = useCheckStore()
let devNum = 0//当前选取的被检设备数量 let devNum = 0 //当前选取的被检设备数量
let devChannelsNum = 0//当前选择的被检设备通道总数 let devChannelsNum = 0 //当前选择的被检设备通道总数
const tableKey = ref(0) const tableKey = ref(0)
const tableHeight = ref(0) const tableHeight = ref(0)
@@ -222,7 +244,7 @@ const shouldShowOption = (item: any) => {
return item.label !== '归档' return item.label !== '归档'
} }
} }
const dataCheckSingleChannelSingleTestPopupRef = ref()
tableHeight.value = window.innerHeight - 600 tableHeight.value = window.innerHeight - 600
const operationShow = ref(false) const operationShow = ref(false)
const documentStateShow = ref(false) const documentStateShow = ref(false)
@@ -235,105 +257,106 @@ const channelsSelection = ref<Device.ResPqDev[]>([])
const props = defineProps({ const props = defineProps({
id: { id: {
type: String, type: String,
required: true, required: true
}, },
plan: { plan: {
type: Object, type: Object,
default: null, default: null
}, },
planArray: { planArray: {
type: Array as PropType<Plan.ReqPlan[]>, type: Array as PropType<Plan.ReqPlan[]>,
default: null, default: null
}, },
planTable: { planTable: {
type: Array, type: Array,
default: () => [], default: () => []
}, }
}) })
const appSceneStore = useAppSceneStore() const appSceneStore = useAppSceneStore()
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'batchGenerateClicked'): void; (e: 'batchGenerateClicked'): void
}>() }>()
// 存储设备类型选项 // 存储设备类型选项
const devTypeOptions = ref<{ const devTypeOptions = ref<
id: string; {
name: string, id: string
icd: string, name: string
power: string, icd: string
devVolt: number, power: string
devCurr: number, devVolt: number
devChns: number, devCurr: number
}[]>([]) devChns: number
}[]
>([])
//下拉框数据 //下拉框数据
interface Dict { interface Dict {
id: string; id: string
label: string; label: string
} }
//检测状态数据 //检测状态数据
const checkStatus: Dict[] = [ const checkStatus: Dict[] = [
{ {
id: '0', id: '0',
label: '未检', label: '未检'
}, },
{ {
id: '1', id: '1',
label: '检测中', label: '检测中'
}, },
{ {
id: '2', id: '2',
label: '检测完成', label: '检测完成'
}, },
{ {
id: '3', id: '3',
label: '归档', label: '归档'
}, }
] ]
//检测报告状态数据 //检测报告状态数据
const checkReportStatus: Dict[] = [ const checkReportStatus: Dict[] = [
{ {
id: '0', id: '0',
label: '未生成', label: '未生成'
}, },
{ {
id: '1', id: '1',
label: '已生成', label: '已生成'
}, },
{ {
id: '2', id: '2',
label: '未检', label: '未检'
}, }
] ]
//检测结果数组 //检测结果数组
const checkResult: Dict[] = [ const checkResult: Dict[] = [
{ {
id: '0', id: '0',
label: '不符合', label: '不符合'
}, },
{ {
id: '1', id: '1',
label: '符合', label: '符合'
}, },
{ {
id: '2', id: '2',
label: '未检', label: '未检'
}, }
] ]
//查询条件 //查询条件
const form: any = ref({ const form: any = ref({
activeTabs: 0, //功能选择 activeTabs: 0, //功能选择
search: null,//搜索内容 search: null, //搜索内容
checkStatus: null, //检测状态 checkStatus: null, //检测状态
checkResult: null, //检测结果 checkResult: null, //检测结果
checkReportStatus: null, //检测报告状态 checkReportStatus: null, //检测报告状态
deviceBindStatus: 0, //绑定状态 deviceBindStatus: 0, //绑定状态
deviceType: 0, //设备类型 deviceType: 0, //设备类型
manufacturer: 0, //制造厂商 manufacturer: 0 //制造厂商
}) })
// ProTable 实例 // ProTable 实例
const proTable = ref<ProTableInstance>() const proTable = ref<ProTableInstance>()
@@ -362,11 +385,11 @@ const getTableList = async () => {
checkStateList.value = checkStateTable.value checkStateList.value = checkStateTable.value
} }
return getBoundPqDevList({ return getBoundPqDevList({
'planIdList': [props.id], planIdList: [props.id],
'checkStateList': checkStateList.value, checkStateList: checkStateList.value,
'checkResult': form.value.checkResult, checkResult: form.value.checkResult,
'reportState': form.value.checkReportStatus, reportState: form.value.checkReportStatus,
'name': form.value.search, name: form.value.search
}) })
} }
} }
@@ -374,25 +397,27 @@ const getTableList = async () => {
// 表格配置项 // 表格配置项
const columns = reactive<ColumnProps<Device.ResPqDev>[]>([ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
{ {
type: 'selection', fixed: 'left', width: 70, type: 'selection',
fixed: 'left',
width: 70,
isShow: selectionShow, isShow: selectionShow,
selectable(row) { selectable(row) {
if (weiJianTab.value === 4) { if (weiJianTab.value === 4) {
return row.reportState === 1 || row.reportState === 3 return row.reportState === 1 || row.reportState === 3
} }
return true return true
}, }
}, },
{ type: 'index', fixed: 'left', width: 70, label: '序号' }, { type: 'index', fixed: 'left', width: 70, label: '序号' },
{ {
prop: 'name', prop: 'name',
label: '设备名称', label: '设备名称',
minWidth: 220, minWidth: 220
}, },
{ {
prop: 'devType', prop: 'devType',
label: '设备类型', label: '设备类型',
minWidth: 150, minWidth: 150
}, },
{ {
prop: 'boundPlanName', prop: 'boundPlanName',
@@ -401,7 +426,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
isShow: modeStore.currentMode === '比对式', isShow: modeStore.currentMode === '比对式',
render(scope) { render(scope) {
return scope.row.boundPlanName ? scope.row.boundPlanName : props.plan.name return scope.row.boundPlanName ? scope.row.boundPlanName : props.plan.name
}, }
}, },
{ {
prop: 'standardDevs', prop: 'standardDevs',
@@ -419,26 +444,24 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
if (item.children) { if (item.children) {
return item.children return item.children
.filter(child => child.name === boundPlanName.value) .filter(child => child.name === boundPlanName.value)
.flatMap(child => .flatMap(child => child.standardDevs.map(dev => dev.name))
child.standardDevs.map(dev => dev.name),
)
} }
return [] return []
}) })
return standardDevNames.length > 0 ? standardDevNames.join(',') : '/' return standardDevNames.length > 0 ? standardDevNames.join(',') : '/'
}, }
}, },
{ {
prop: 'devChns', prop: 'devChns',
label: '通道数', label: '通道数',
minWidth: 100, minWidth: 100,
sortable: true, sortable: true
}, },
{ {
prop: 'recheckNum', prop: 'recheckNum',
label: '检测次数', label: '检测次数',
minWidth: 100, minWidth: 100,
sortable: true, sortable: true
}, },
{ {
prop: 'checkState', prop: 'checkState',
@@ -447,26 +470,24 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
sortable: true, sortable: true,
isShow: checkStateShow, isShow: checkStateShow,
render: scope => { render: scope => {
return ( return scope.row.checkState === 0 ? '未检' : scope.row.checkState === 1 ? '检测中' : '检测完成'
scope.row.checkState === 0 ? '未检' : scope.row.checkState === 1 ? '检测中' : '检测完成' }
)
},
}, },
{ {
prop: 'checkResult', prop: 'checkResult',
label: '检测结果', label: '检测结果',
minWidth: 100, minWidth: 100,
sortable: true, sortable: true,
render: (scope) => { render: scope => {
if (scope.row.checkResult === 0) { if (scope.row.checkResult === 0) {
return <el-tag type='danger'>不符合</el-tag> return <el-tag type="danger">不符合</el-tag>
} else if (scope.row.checkResult === 1) { } else if (scope.row.checkResult === 1) {
return '符合' return '符合'
} else if (scope.row.checkResult === 2) { } else if (scope.row.checkResult === 2) {
return '未检' return '未检'
} }
return '' return ''
}, }
}, },
{ {
prop: 'reportState', prop: 'reportState',
@@ -484,7 +505,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
return '已上传' return '已上传'
} }
return '' return ''
}, }
}, },
{ {
prop: 'factorCheckResult', prop: 'factorCheckResult',
@@ -500,10 +521,9 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
} else { } else {
return '未检' return '未检'
} }
}
}, },
}, { prop: 'operation', label: '操作', fixed: 'right', minWidth: 200, isShow: operationShow }
{ prop: 'operation', label: '操作', fixed: 'right', minWidth: 200, isShow: operationShow },
]) ])
let testType = 'test' // 检测类型:'test'-检测 'reTest'-复检 let testType = 'test' // 检测类型:'test'-检测 'reTest'-复检
@@ -523,7 +543,7 @@ const handleSelectionChange = (selection: any[]) => {
} }
// 统计已完成检测的设备数量 // 统计已完成检测的设备数量
const result = selection.filter((item) => item.checkResult != 0) const result = selection.filter(item => item.checkResult != 0)
if (result.length > 0) { if (result.length > 0) {
testType = 'test' testType = 'test'
} else { } else {
@@ -539,7 +559,7 @@ const handleSelectionChange = (selection: any[]) => {
devVolt: item.devVolt, devVolt: item.devVolt,
devCurr: item.devCurr, devCurr: item.devCurr,
factorFlag: item.factorFlag, factorFlag: item.factorFlag,
checkResult: item.checkResult, checkResult: item.checkResult
} }
}) })
@@ -565,18 +585,11 @@ const handleRefresh = () => {
} }
// 表格排序 // 表格排序
const sortTable = ({ const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
newIndex,
oldIndex,
}: {
newIndex?: number;
oldIndex?: number;
}) => {
console.log(newIndex, oldIndex) // 避免未使用参数警告 console.log(newIndex, oldIndex) // 避免未使用参数警告
ElMessage.success('修改列表排序成功') ElMessage.success('修改列表排序成功')
} }
/** /**
* 切换顶部功能Tab时的处理函数 * 切换顶部功能Tab时的处理函数
* @param val Tab索引0-设备检测 1-手动检测 2-设备复检 3-报告生成 4-设备归档 5-数据查询 * @param val Tab索引0-设备检测 1-手动检测 2-设备复检 3-报告生成 4-设备归档 5-数据查询
@@ -642,7 +655,6 @@ function tableHeaderInit(val: number) {
tableKey.value += 1 tableKey.value += 1
break break
} }
} }
/** /**
@@ -655,12 +667,11 @@ function refreshStatusList() {
devChannelsNum = 0 devChannelsNum = 0
// 清空查询表单 // 清空查询表单
form.value.search = null form.value.search = null
form.value.checkStatus = null//检测状态默认为未检 form.value.checkStatus = null //检测状态默认为未检
form.value.checkReportStatus = null//检测报告状态默认为未生成报告 form.value.checkReportStatus = null //检测报告状态默认为未生成报告
form.value.checkResult = null//检测结果默认为未出结果 form.value.checkResult = null //检测结果默认为未出结果
} }
/** /**
* 通道配对功能处理函数(比对模式专用) * 通道配对功能处理函数(比对模式专用)
* 校验选中设备的一致性,然后打开通道配对弹窗 * 校验选中设备的一致性,然后打开通道配对弹窗
@@ -668,30 +679,22 @@ function refreshStatusList() {
const handleTest2 = async () => { const handleTest2 = async () => {
// 检查是否选择了设备 // 检查是否选择了设备
if (devNum == 0) { if (devNum == 0) {
ElMessageBox.confirm( ElMessageBox.confirm('请先选择被检设备', '提示', {
'请先选择被检设备',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
// 检查选中设备是否属于同一个计划 // 检查选中设备是否属于同一个计划
const planName = channelsSelection.value.map(item => item.boundPlanName) const planName = channelsSelection.value.map(item => item.boundPlanName)
const isPlanConsistent = new Set(planName).size === 1 const isPlanConsistent = new Set(planName).size === 1
if (!isPlanConsistent) { if (!isPlanConsistent) {
ElMessageBox.confirm( ElMessageBox.confirm('所勾选被检设备所属计划名称不一致,请重新选择', '提示', {
'所勾选被检设备所属计划名称不一致,请重新选择',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
@@ -708,28 +711,22 @@ const handleTest2 = async () => {
if (item.children) { if (item.children) {
return item.children return item.children
.filter(child => child.name === boundPlanName.value) .filter(child => child.name === boundPlanName.value)
.flatMap(child => .flatMap(child => child.standardDevs)
child.standardDevs,
)
} }
return [] return []
}) })
// 检查是否有标准设备可用于配对 // 检查是否有标准设备可用于配对
if (pqStandardDevList.value.length == 0) { if (pqStandardDevList.value.length == 0) {
ElMessageBox.confirm( ElMessageBox.confirm('所勾选被检设备所属计划无标准设备,请重新选择', '提示', {
'所勾选被检设备所属计划无标准设备,请重新选择',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
const devBindMonList = await getPqMonList({devIds: channelsSelection.value.map(d => d.id)}) const devBindMonList = await getPqMonList({ devIds: channelsSelection.value.map(d => d.id) })
// 创建一个映射来存储每个设备的监测点信息(支持多个监测点) // 创建一个映射来存储每个设备的监测点信息(支持多个监测点)
const deviceMonitoringMap = new Map<string, any[]>() const deviceMonitoringMap = new Map<string, any[]>()
@@ -743,7 +740,6 @@ const handleTest2 = async () => {
} }
}) })
// 过滤出至少有一个监测点的设备 // 过滤出至少有一个监测点的设备
const filteredChannelsSelection = channelsSelection.value.filter(device => { const filteredChannelsSelection = channelsSelection.value.filter(device => {
return deviceMonitoringMap.has(device.id) return deviceMonitoringMap.has(device.id)
@@ -751,15 +747,11 @@ const handleTest2 = async () => {
// 如果没有设备有监测点,则提示并返回 // 如果没有设备有监测点,则提示并返回
if (filteredChannelsSelection.length === 0) { if (filteredChannelsSelection.length === 0) {
ElMessageBox.confirm( ElMessageBox.confirm('所选设备均无监测点,请检查设备配置', '提示', {
'所选设备均无监测点,请检查设备配置',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
@@ -774,24 +766,24 @@ const handleTest2 = async () => {
ElMessage.warning(`以下设备没有监测点: ${deviceNames}`) ElMessage.warning(`以下设备没有监测点: ${deviceNames}`)
} }
// 检查监测点数量与通道数是否一致,并指出具体哪些通道未绑定 // 检查监测点数量与通道数是否一致,并指出具体哪些通道未绑定
const inconsistentPointDevices = filteredChannelsSelection.filter(device => { const inconsistentPointDevices = filteredChannelsSelection.filter(device => {
const monitoringInfoArray = deviceMonitoringMap.get(device.id) const monitoringInfoArray = deviceMonitoringMap.get(device.id)
const pointCount = monitoringInfoArray ? monitoringInfoArray.length : 0 const pointCount = monitoringInfoArray ? monitoringInfoArray.length : 0
// 只有当监测点数量与通道数不一致时才需要提示 // 只有当监测点数量与通道数不一致时才需要提示
return pointCount !== device.devChns return pointCount !== device.devChns
}) })
if (inconsistentPointDevices.length > 0) { if (inconsistentPointDevices.length > 0) {
const deviceNames = inconsistentPointDevices.map(d => d.name).join(', ') const deviceNames = inconsistentPointDevices.map(d => d.name).join(', ')
ElMessage.warning(`以下设备存在通道未绑定监测点: ${deviceNames}`) ElMessage.warning(`以下设备存在通道未绑定监测点: ${deviceNames}`)
}
// 只传递有监测点的设备
deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevList.value, props.id)
} }
// 只传递有监测点的设备
deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevList.value, props.id)
}
/** /**
* 检测操作主处理函数 * 检测操作主处理函数
* 根据操作类型(手动检测/一键检测/批量生成/批量归档等)执行相应逻辑 * 根据操作类型(手动检测/一键检测/批量生成/批量归档等)执行相应逻辑
@@ -800,15 +792,11 @@ deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevLis
const handleTest = async (val: string) => { const handleTest = async (val: string) => {
// 检查是否选择了设备 // 检查是否选择了设备
if (devNum == 0) { if (devNum == 0) {
ElMessageBox.confirm( ElMessageBox.confirm('请先选择被检设备', '提示', {
'请先选择被检设备',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
@@ -816,15 +804,11 @@ const handleTest = async (val: string) => {
const checkDevVolt = channelsSelection.value.map(item => item.devVolt) const checkDevVolt = channelsSelection.value.map(item => item.devVolt)
const isDevVoltConsistent = new Set(checkDevVolt).size === 1 const isDevVoltConsistent = new Set(checkDevVolt).size === 1
if (!isDevVoltConsistent) { if (!isDevVoltConsistent) {
ElMessageBox.confirm( ElMessageBox.confirm('所勾选设备额定电压不一致,请重新选择', '提示', {
'所勾选设备额定电压不一致,请重新选择',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
@@ -832,19 +816,14 @@ const handleTest = async (val: string) => {
const checkDevCurr = channelsSelection.value.map(item => item.devCurr) const checkDevCurr = channelsSelection.value.map(item => item.devCurr)
const isDevCurrConsistent = new Set(checkDevCurr).size === 1 const isDevCurrConsistent = new Set(checkDevCurr).size === 1
if (!isDevCurrConsistent) { if (!isDevCurrConsistent) {
ElMessageBox.confirm( ElMessageBox.confirm('所勾选设备额定电流不一致,请重新选择', '提示', {
'所勾选设备额定电流不一致,请重新选择',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
// 处理检测相关操作 // 处理检测相关操作
if (val === '手动检测' || val === '一键检测' || val === '系数校准') { if (val === '手动检测' || val === '一键检测' || val === '系数校准') {
// 检查选中设备的检测状态是否一致 // 检查选中设备的检测状态是否一致
@@ -857,15 +836,11 @@ const handleTest = async (val: string) => {
} }
// 限制每次检测最多12个通道 // 限制每次检测最多12个通道
if (devChannelsNum > 12) { if (devChannelsNum > 12) {
ElMessageBox.confirm( ElMessageBox.confirm('每次检测最多只能检测12个设备通道请重新选择', '提示', {
'每次检测最多只能检测12个设备通道请重新选择',
'提示',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
}, })
)
return return
} }
@@ -873,12 +848,11 @@ const handleTest = async (val: string) => {
if (val === '手动检测') { if (val === '手动检测') {
checkStore.setShowDetailType(2) checkStore.setShowDetailType(2)
if (testType === 'reTest') { if (testType === 'reTest') {
ElMessageBox.confirm('请选择复检检测方式', '设备复检', ElMessageBox.confirm('请选择复检检测方式', '设备复检', {
{
distinguishCancelAndClose: true, distinguishCancelAndClose: true,
confirmButtonText: '不合格项复检', confirmButtonText: '不合格项复检',
cancelButtonText: '全部复检', cancelButtonText: '全部复检',
type: 'warning', type: 'warning'
}) })
.then(() => { .then(() => {
ElMessage.success('不合格项复检') ElMessage.success('不合格项复检')
@@ -913,12 +887,11 @@ const handleTest = async (val: string) => {
checkStore.initSelectTestItems() checkStore.initSelectTestItems()
// 一键检测 // 一键检测
if (testType === 'reTest') { if (testType === 'reTest') {
ElMessageBox.confirm('请选择复检检测方式', '设备复检', ElMessageBox.confirm('请选择复检检测方式', '设备复检', {
{
distinguishCancelAndClose: true, distinguishCancelAndClose: true,
confirmButtonText: '不合格项复检', confirmButtonText: '不合格项复检',
cancelButtonText: '全部复检', cancelButtonText: '全部复检',
type: 'warning', type: 'warning'
}) })
.then(() => { .then(() => {
ElMessage.success('不合格项复检') ElMessage.success('不合格项复检')
@@ -949,9 +922,11 @@ const handleTest = async (val: string) => {
} }
if (val === '批量归档') { if (val === '批量归档') {
documentedPqDev(checkStore.devices.map(item => { documentedPqDev(
checkStore.devices.map(item => {
return item.deviceId return item.deviceId
})).then((res) => { })
).then(res => {
if (res.code === ResultEnum.SUCCESS) { if (res.code === ResultEnum.SUCCESS) {
ElMessage.success('归档成功!') ElMessage.success('归档成功!')
} }
@@ -964,12 +939,12 @@ const handleTest = async (val: string) => {
return item.deviceId return item.deviceId
}) })
await generateDevReport({ await generateDevReport({
'planId': checkStore.plan.id, planId: checkStore.plan.id,
'devIdList': devIdList, devIdList: devIdList,
'scriptId': checkStore.plan.scriptId, scriptId: checkStore.plan.scriptId,
'planCode': checkStore.plan.code + '', planCode: checkStore.plan.code + '',
'pageNum': 1, pageNum: 1,
'pageSize': 999, pageSize: 999
}) })
ElMessage.success({ message: `报告生成成功!` }) ElMessage.success({ message: `报告生成成功!` })
} }
@@ -987,7 +962,6 @@ const openTestDialog = (testData: any) => {
} }
} }
const openTestDialog2 = () => { const openTestDialog2 = () => {
testPopup.value?.open(dialogTitle.value) testPopup.value?.open(dialogTitle.value)
} }
@@ -1003,37 +977,44 @@ const openDrawer = async (title: string, row: any) => {
// 单个设备报告生成 // 单个设备报告生成
if (title === '报告生成') { if (title === '报告生成') {
await generateDevReport({ await generateDevReport({
'planId': checkStore.plan.id, planId: checkStore.plan.id,
'devIdList': [row.id], devIdList: [row.id],
'scriptId': checkStore.plan.scriptId, scriptId: checkStore.plan.scriptId,
'planCode': checkStore.plan.code + '', planCode: checkStore.plan.code + '',
'pageNum': 1, pageNum: 1,
'pageSize': 999, pageSize: 999
}) })
emit('batchGenerateClicked') // 触发事件 emit('batchGenerateClicked') // 触发事件
ElMessage.success({ message: `报告生成成功!` }) ElMessage.success({ message: `报告生成成功!` })
} }
if (title === '报告下载') { if (title === '报告下载') {
await useDownload(downloadDevData, row.createId, { await useDownload(
downloadDevData,
row.createId,
{
planId: checkStore.plan.id, planId: checkStore.plan.id,
devId: row.id, devId: row.id
}, false, '.docx') },
false,
'.docx'
)
emit('batchGenerateClicked') // 触发事件 emit('batchGenerateClicked') // 触发事件
} }
if (title === '检测数据查询') { if (title === '检测数据查询') {
checkStore.setShowDetailType(0) checkStore.setShowDetailType(0)
dataCheckPopupRef.value?.open(row.id, '-1', null)
dataCheckSingleChannelSingleTestPopupRef.value?.open(row, null, row.id, 2)
} }
if (title === '误差体系更换') { if (title === '误差体系更换') {
checkStore.setShowDetailType(1) checkStore.setShowDetailType(1)
dataCheckPopupRef.value?.open(row.id, '-1', null) dataCheckPopupRef.value?.open(row.id, '-1', null)
} }
if (title === '归档') { if (title === '归档') {
await documentedPqDev([row.id]).then((res) => { await documentedPqDev([row.id]).then(res => {
if (res.code === ResultEnum.SUCCESS) { if (res.code === ResultEnum.SUCCESS) {
ElMessage.success('归档成功!') ElMessage.success('归档成功!')
} }
@@ -1042,14 +1023,13 @@ const openDrawer = async (title: string, row: any) => {
} }
} }
// 监听 props.id 的变化 // 监听 props.id 的变化
watch( watch(
() => props.id, () => props.id,
() => { () => {
handleRefresh() handleRefresh()
}, },
{ immediate: true }, { immediate: true }
) )
onBeforeMount(async () => { onBeforeMount(async () => {
@@ -1061,7 +1041,7 @@ onBeforeMount(async () => {
power: item.power, power: item.power,
devVolt: item.devVolt, devVolt: item.devVolt,
devCurr: item.devCurr, devCurr: item.devCurr,
devChns: item.devChns, devChns: item.devChns
})) }))
}) })
@@ -1075,10 +1055,9 @@ const handleQuitClicked = () => {
emit('batchGenerateClicked') // 触发事件 emit('batchGenerateClicked') // 触发事件
} }
defineExpose({ changeActiveTabs }) defineExpose({ changeActiveTabs })
</script> </script>
<style lang='scss' scoped> <style lang="scss" scoped>
/* 当屏幕宽度小于或等于1300像素时 */ /* 当屏幕宽度小于或等于1300像素时 */
@media screen and (max-width: 1300px) { @media screen and (max-width: 1300px) {
.el-select { .el-select {