UPDATE: 优化客户端桌面窗口内容自适应

This commit is contained in:
贾同学
2025-10-10 15:29:54 +08:00
parent b319a89501
commit 666fb22c49
6 changed files with 1611 additions and 1593 deletions

View File

@@ -25,10 +25,10 @@ module.exports = (appInfo) => {
*/ */
config.windowsOption = { config.windowsOption = {
title: '自动检测平台', title: '自动检测平台',
width: 1600, width: 1920 /1.5,
height: 950, height: 1080 /1.2,
minWidth: 1600, minWidth: 1920 /1.5,
minHeight: 950, minHeight: 1080 /1.2,
webPreferences: { webPreferences: {
//webSecurity: false, //webSecurity: false,
contextIsolation: false, // false -> 可在渲染进程中使用electron的apitrue->需要bridge.js(contextBridge) contextIsolation: false, // false -> 可在渲染进程中使用electron的apitrue->需要bridge.js(contextBridge)

View File

@@ -9,7 +9,7 @@ module.exports = (appInfo) => {
/** /**
* 开发者工具 * 开发者工具
*/ */
config.openDevTools = true; config.openDevTools = false;
/** /**
* 应用程序顶部菜单 * 应用程序顶部菜单

View File

@@ -17,6 +17,7 @@
"@types/event-source-polyfill": "^1.0.5", "@types/event-source-polyfill": "^1.0.5",
"@vue-flow/core": "^1.45.0", "@vue-flow/core": "^1.45.0",
"@vueuse/core": "^10.4.1", "@vueuse/core": "^10.4.1",
"autofit.js": "^3.2.8",
"axios": "^1.7.3", "axios": "^1.7.3",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"dayjs": "^1.11.9", "dayjs": "^1.11.9",

View File

@@ -1,27 +1,25 @@
<template> <template>
<!--element-plus语言国际化全局修改为中文--> <!--element-plus语言国际化全局修改为中文-->
<el-config-provider <el-config-provider :locale="locale" :size="assemblySize" :button="buttonConfig">
:locale='locale'
:size='assemblySize'
:button='buttonConfig'
>
<router-view /> <router-view />
</el-config-provider> </el-config-provider>
</template> </template>
<script lang='ts' setup> <script lang="ts" setup>
defineOptions({ import autofit from 'autofit.js'
name: 'App',
})
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { getBrowserLang } from '@/utils' import { getBrowserLang } from '@/utils'
import { useTheme } from '@/hooks/useTheme' import { useTheme } from '@/hooks/useTheme'
import { ElConfigProvider } from 'element-plus' import { ElConfigProvider } from 'element-plus'
import { LanguageType } from './stores/interface' import { type LanguageType } from './stores/interface'
import { useGlobalStore } from '@/stores/modules/global' import { useGlobalStore } from '@/stores/modules/global'
import en from 'element-plus/es/locale/lang/en' import en from 'element-plus/es/locale/lang/en'
import zhCn from 'element-plus/es/locale/lang/zh-cn' import zhCn from 'element-plus/es/locale/lang/zh-cn'
defineOptions({
name: 'App'
})
const globalStore = useGlobalStore() const globalStore = useGlobalStore()
// init theme // init theme
@@ -34,6 +32,16 @@ onMounted(() => {
const language = globalStore.language ?? getBrowserLang() const language = globalStore.language ?? getBrowserLang()
i18n.locale.value = language i18n.locale.value = language
globalStore.setGlobalState('language', language as LanguageType) globalStore.setGlobalState('language', language as LanguageType)
// 自动适配
autofit.init({
el: '#app',
//dh: 720 * 1,
//dw: 1280 * 1.2,
dw: 1920 / 1.5,
dh: 1080 / 1.2,
resize: true,
limit: 0.1
})
}) })
// element language // element language

View File

@@ -17,6 +17,7 @@
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
:request-api="getTableList" :request-api="getTableList"
:toolButton="false" :toolButton="false"
:height="props.height"
> >
<!-- 表格头部操作区域包含查询筛选和功能按钮 --> <!-- 表格头部操作区域包含查询筛选和功能按钮 -->
<template #tableHeader=""> <template #tableHeader="">
@@ -156,22 +157,15 @@
归档 归档
</el-button> </el-button>
<!-- 数据操作模式下的功能 --> <!-- 数据操作模式下的功能 -->
<div v-if="form.activeTabs === 5" style="overflow-x: auto;width: 260px; display: flex; justify-content: center;align-items: center;"> <div
<el-button v-if="form.activeTabs === 5"
type="primary" style="overflow-x: auto; width: 260px; display: flex; justify-content: center; align-items: center"
link
icon="PieChart"
@click="openDrawer('检测数据查询', scope.row)"
> >
<el-button type="primary" link icon="PieChart" @click="openDrawer('检测数据查询', scope.row)">
检测数据查询 检测数据查询
</el-button> </el-button>
<!-- 误差体系更换功能 --> <!-- 误差体系更换功能 -->
<el-button <el-button type="primary" link icon="Switch" @click="openDrawer('误差体系更换', scope.row)">
type="primary"
link
icon="Switch"
@click="openDrawer('误差体系更换', scope.row)"
>
误差体系更换 误差体系更换
</el-button> </el-button>
</div> </div>
@@ -182,7 +176,7 @@
<!-- 检测过程显示弹窗 --> <!-- 检测过程显示弹窗 -->
<TestPopup ref="testPopup" @quitClicked="handleQuitClicked"></TestPopup> <TestPopup ref="testPopup" @quitClicked="handleQuitClicked"></TestPopup>
<!-- 检测数据查询弹窗 --> <!-- 检测数据查询弹窗 -->
<dataCheckPopup ref="dataCheckPopupRef" :append-to-body="true"/> <dataCheckPopup ref="dataCheckPopupRef" :append-to-body="true" />
<!-- 手动检测检测项选择弹窗 --> <!-- 手动检测检测项选择弹窗 -->
<SelectTestItemPopup ref="selectTestItemPopupRef" @openTestDialog="openTestDialog"></SelectTestItemPopup> <SelectTestItemPopup ref="selectTestItemPopupRef" @openTestDialog="openTestDialog"></SelectTestItemPopup>
<!-- 省平台模式下的温度湿度填写弹窗 --> <!-- 省平台模式下的温度湿度填写弹窗 -->
@@ -200,8 +194,8 @@
</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 {type Action, ElMessage, ElMessageBox} from 'element-plus' import { type Action, ElMessage, ElMessageBox } 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 CompareDataCheckSingleChannelSingleTestPopup from '@/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue'
@@ -209,20 +203,20 @@ 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'
import DeviceConnectionPopup from '@/views/home/components/deviceConnectionPopup.vue' import DeviceConnectionPopup from '@/views/home/components/deviceConnectionPopup.vue'
import {type Device} from '@/api/device/interface/device' import { type Device } from '@/api/device/interface/device'
import {type ColumnProps, type ProTableInstance} from '@/components/ProTable/interface' import { type ColumnProps, type ProTableInstance } from '@/components/ProTable/interface'
import {type Plan} from '@/api/plan/interface' import { type Plan } from '@/api/plan/interface'
import {type StandardDevice} from '@/api/device/interface/standardDevice' import { type StandardDevice } from '@/api/device/interface/standardDevice'
import {downloadDevData, generateDevReport, getBoundPqDevList} from '@/api/plan/plan' import { downloadDevData, generateDevReport, getBoundPqDevList } from '@/api/plan/plan'
import {getPqDev} from '@/api/device/device' import { getPqDev } from '@/api/device/device'
import {useAppSceneStore, useModeStore} from '@/stores/modules/mode' // 引入模式 store import { useAppSceneStore, useModeStore } from '@/stores/modules/mode' // 引入模式 store
import {useCheckStore} from '@/stores/modules/check' import { useCheckStore } from '@/stores/modules/check'
import {CheckData} from '@/api/check/interface' import { CheckData } from '@/api/check/interface'
import {useAuthStore} from '@/stores/modules/auth' 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'
import ReportResultPopup from '@/views/home/components/reportResultPopup.vue' import ReportResultPopup from '@/views/home/components/reportResultPopup.vue'
const checkStore = useCheckStore() const checkStore = useCheckStore()
@@ -280,6 +274,10 @@ const props = defineProps({
planTable: { planTable: {
type: Array, type: Array,
default: () => [] default: () => []
},
height: {
type: Number,
default: 200
} }
}) })
const appSceneStore = useAppSceneStore() const appSceneStore = useAppSceneStore()
@@ -418,7 +416,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
return true return true
} }
}, },
{type: 'index', fixed: 'left', width: 70, label: '序号'}, { type: 'index', fixed: 'left', width: 70, label: '序号' },
{ {
prop: 'name', prop: 'name',
label: '设备名称', label: '设备名称',
@@ -534,7 +532,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
} }
} }
}, },
{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'-复检
@@ -596,7 +594,7 @@ const handleRefresh = () => {
} }
// 表格排序 // 表格排序
const sortTable = ({newIndex, oldIndex}: { newIndex?: number; oldIndex?: number }) => { const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
console.log(newIndex, oldIndex) // 避免未使用参数警告 console.log(newIndex, oldIndex) // 避免未使用参数警告
ElMessage.success('修改列表排序成功') ElMessage.success('修改列表排序成功')
} }
@@ -696,7 +694,6 @@ function refreshStatusList() {
* 校验选中设备的一致性,然后打开通道配对弹窗 * 校验选中设备的一致性,然后打开通道配对弹窗
*/ */
const handleTest2 = async (val: string) => { const handleTest2 = async (val: string) => {
// 检查是否选择了设备 // 检查是否选择了设备
if (devNum == 0) { if (devNum == 0) {
ElMessageBox.confirm('请先选择被检设备', '提示', { ElMessageBox.confirm('请先选择被检设备', '提示', {
@@ -746,7 +743,7 @@ const handleTest2 = async (val: string) => {
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[]>()
devBindMonList.data.forEach((item: any) => { devBindMonList.data.forEach((item: any) => {
@@ -760,29 +757,29 @@ const handleTest2 = async (val: string) => {
}) })
// 收集所有监测点都未参与检测的设备 // 收集所有监测点都未参与检测的设备
const allUncheckedDevices: string[] = []; const allUncheckedDevices: string[] = []
// 创建新对象存储过滤掉checkFlag === 0的监测点 // 创建新对象存储过滤掉checkFlag === 0的监测点
const filteredDeviceMonitoringMap = new Map<string, any[]>(); const filteredDeviceMonitoringMap = new Map<string, any[]>()
deviceMonitoringMap.forEach((monitoringPoints, deviceId) => { deviceMonitoringMap.forEach((monitoringPoints, deviceId) => {
// 检查是否所有监测点的 checkFlag 都为 0 // 检查是否所有监测点的 checkFlag 都为 0
const allUnchecked = monitoringPoints.every(point => point.checkFlag === 0); const allUnchecked = monitoringPoints.every(point => point.checkFlag === 0)
if (allUnchecked) { if (allUnchecked) {
// 根据deviceId找到设备名称 // 根据deviceId找到设备名称
const device = channelsSelection.value.find(d => d.id === deviceId); const device = channelsSelection.value.find(d => d.id === deviceId)
if (device) { if (device) {
allUncheckedDevices.push(device.name); allUncheckedDevices.push(device.name)
} }
} else { } else {
// 过滤掉checkFlag === 0的监测点只保留参与检测的监测点 // 过滤掉checkFlag === 0的监测点只保留参与检测的监测点
const filteredPoints = monitoringPoints.filter(point => point.checkFlag !== 0); const filteredPoints = monitoringPoints.filter(point => point.checkFlag !== 0)
filteredDeviceMonitoringMap.set(deviceId, filteredPoints); filteredDeviceMonitoringMap.set(deviceId, filteredPoints)
} }
}); })
// 统一提示所有所有监测点都未参与检测的设备 // 统一提示所有所有监测点都未参与检测的设备
if (allUncheckedDevices.length > 0) { if (allUncheckedDevices.length > 0) {
ElMessage.warning(`以下设备的所有监测点都不参与检测,请重新选择: ${allUncheckedDevices.join(', ')}`); ElMessage.warning(`以下设备的所有监测点都不参与检测,请重新选择: ${allUncheckedDevices.join(', ')}`)
return return
} }
@@ -793,7 +790,6 @@ const handleTest2 = async (val: string) => {
// 如果没有设备有监测点,则提示并返回 // 如果没有设备有监测点,则提示并返回
if (filteredChannelsSelection.length === 0) { if (filteredChannelsSelection.length === 0) {
ElMessageBox.confirm('所选设备均无监测点,请检查设备配置', '提示', { ElMessageBox.confirm('所选设备均无监测点,请检查设备配置', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
@@ -828,11 +824,18 @@ const handleTest2 = async (val: string) => {
// 只传递有监测点的设备 // 只传递有监测点的设备
const targetPlan = props.planTable.data.find((item: any) => item.id === props.plan.id); const targetPlan = props.planTable.data.find((item: any) => item.id === props.plan.id)
// 检查数组长度是否为1且唯一元素是'wave_data' // 检查数组长度是否为1且唯一元素是'wave_data'
const isOnlyWave = targetPlan.datasourceIds.length === 1 && targetPlan.datasourceIds[0] === 'wave_data'; const isOnlyWave = targetPlan.datasourceIds.length === 1 && targetPlan.datasourceIds[0] === 'wave_data'
deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevList.value, props.id, filteredDeviceMonitoringMap, val, isOnlyWave) deviceConnectionPopupRef.value?.open(
filteredChannelsSelection,
pqStandardDevList.value,
props.id,
filteredDeviceMonitoringMap,
val,
isOnlyWave
)
} }
/** /**
@@ -927,7 +930,7 @@ const handleTest = async (val: string) => {
} }
}) })
checkStore.setSelectTestItems({preTest: false, timeTest: false, channelsTest: false, test: true}) checkStore.setSelectTestItems({ preTest: false, timeTest: false, channelsTest: false, test: true })
} else { } else {
selectTestItemPopupRef.value?.open() selectTestItemPopupRef.value?.open()
checkStore.setReCheckType(1) checkStore.setReCheckType(1)
@@ -964,7 +967,7 @@ const handleTest = async (val: string) => {
} }
} }
}) })
checkStore.setSelectTestItems({preTest: false, timeTest: false, channelsTest: false, test: true}) checkStore.setSelectTestItems({ preTest: false, timeTest: false, channelsTest: false, test: true })
} else { } else {
checkStore.setReCheckType(1) checkStore.setReCheckType(1)
if (modeStore.currentMode == '比对式') { if (modeStore.currentMode == '比对式') {
@@ -1001,7 +1004,7 @@ const handleTest = async (val: string) => {
pageNum: 1, pageNum: 1,
pageSize: 999 pageSize: 999
}) })
ElMessage.success({message: `报告生成成功!`}) ElMessage.success({ message: `报告生成成功!` })
} }
} }
@@ -1043,7 +1046,7 @@ const openDrawer = async (title: string, row: any) => {
pageSize: 999 pageSize: 999
}) })
emit('batchGenerateClicked') // 触发事件 emit('batchGenerateClicked') // 触发事件
ElMessage.success({message: `报告生成成功!`}) ElMessage.success({ message: `报告生成成功!` })
} }
} }
@@ -1094,7 +1097,7 @@ watch(
() => { () => {
handleRefresh() handleRefresh()
}, },
{immediate: true} { immediate: true }
) )
onBeforeMount(async () => { onBeforeMount(async () => {
@@ -1120,7 +1123,7 @@ const handleQuitClicked = () => {
emit('batchGenerateClicked') // 触发事件 emit('batchGenerateClicked') // 触发事件
} }
defineExpose({changeActiveTabs}) defineExpose({ changeActiveTabs })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/* 当屏幕宽度小于或等于1300像素时 */ /* 当屏幕宽度小于或等于1300像素时 */

View File

@@ -3,90 +3,95 @@
布局左侧计划树 + 右侧功能区域功能选择饼图统计表格数据 布局左侧计划树 + 右侧功能区域功能选择饼图统计表格数据
--> -->
<template> <template>
<div class='static' ref='popupBaseView'> <div class="static" ref="popupBaseView">
<el-row :gutter='10'> <el-row :gutter="10">
<!-- 左侧计划树区域 (20%) --> <!-- 左侧计划树区域 (20%) -->
<el-col :lg='4' :xl='4' :md='4' :sm='4'> <el-col :lg="4" :xl="4" :md="4" :sm="4">
<div class='left_tree'> <div class="left_tree">
<tree ref='treeRef' :updateSelectedTreeNode='updateData|| (() => {})' :width='viewWidth' :height='viewHeight' <tree
:planTable='planTable' /> ref="treeRef"
:updateSelectedTreeNode="updateData || (() => {})"
:width="viewWidth"
:height="viewHeight"
:planTable="planTable"
/>
</div> </div>
</el-col> </el-col>
<!-- 右侧主要内容区域 (80%) --> <!-- 右侧主要内容区域 (80%) -->
<el-col :lg='20' :xl='20' :md='20' :sm='20'> <el-col :lg="20" :xl="20" :md="20" :sm="20">
<div class='right_container'> <div class="right_container">
<!-- 功能选择 --> <!-- 功能选择 -->
<div class='container_function'> <div class="container_function">
<div <div
class='function_item' class="function_item"
:class="item.checked ? 'function_item checked_function' : 'function_item'" :class="item.checked ? 'function_item checked_function' : 'function_item'"
v-for='(item, index) in tabsList' v-for="(item, index) in tabsList"
:key='index' :key="index"
@click='handleCheckFunction(item.value)' @click="handleCheckFunction(item.value)"
> >
<div class='item_img'> <div class="item_img">
<img :src='item.img' /> <img :src="item.img" />
</div> </div>
<div class='item_text'> <div class="item_text">
<p>{{ item.label }}</p> <p>{{ item.label }}</p>
</div> </div>
</div> </div>
</div> </div>
<!--检测计划统计 饼图统计--> <!--检测计划统计 饼图统计-->
<div class='container_pieShow'> <div class="container_pieShow">
<el-collapse model-value='1' accordion @change='handleCollapseChange'> <el-collapse model-value="1" accordion @change="handleCollapseChange">
<el-collapse-item name='1'> <el-collapse-item name="1">
<template #title> <template #title>
<div class='container_pieShow_title'> <div class="container_pieShow_title">
<span>检测计划统计</span> <span>检测计划统计</span>
<span>{{ planName }}</span> <span>{{ planName }}</span>
</div> </div>
</template> </template>
<!-- 饼图 --> <!-- 饼图 -->
<div class='container_charts'> <div class="container_charts">
<div class='charts_info' ref='chartsInfoRef'> <div class="charts_info" ref="chartsInfoRef">
<pie <pie
:customData="{ :customData="{
title: '设备检测状态', title: '设备检测状态',
textAlign: 'left', textAlign: 'left'
}" }"
:legendData="{ :legendData="{
icon: 'circle', icon: 'circle',
left: 'left', left: 'left',
top: 'bottom', top: 'bottom'
}" }"
:chartsData='chartsData1' :chartsData="chartsData1"
ref='pieRef1' ref="pieRef1"
></pie> ></pie>
</div> </div>
<div class='charts_info'> <div class="charts_info">
<pie <pie
:customData="{ :customData="{
title: '设备检测结果', title: '设备检测结果',
textAlign: 'left', textAlign: 'left'
}" }"
:legendData="{ :legendData="{
icon: 'circle', icon: 'circle',
left: 'left', left: 'left',
top: 'bottom', top: 'bottom'
}" }"
:chartsData='chartsData2' :chartsData="chartsData2"
ref='pieRef2' ref="pieRef2"
></pie> ></pie>
</div> </div>
<div class='charts_info'> <div class="charts_info">
<pie <pie
:customData="{ :customData="{
title: '设备报告状态', title: '设备报告状态',
textAlign: 'left', textAlign: 'left'
}" }"
:legendData="{ :legendData="{
icon: 'circle', icon: 'circle',
left: 'left', left: 'left',
top: 'bottom', top: 'bottom'
}" }"
:chartsData='chartsData3' :chartsData="chartsData3"
ref='pieRef3' ref="pieRef3"
></pie> ></pie>
</div> </div>
</div> </div>
@@ -95,13 +100,24 @@
</div> </div>
<!--下方表格数据--> <!--下方表格数据-->
<el-tabs class='tabs-menu' type='border-card' v-model='editableTabsValue' <el-tabs
:style='{ height: tabsHeight }'> class="tabs-menu"
<el-tab-pane :label='tabLabel1' :style='{ height: tabPaneHeight}'> type="border-card"
v-model="editableTabsValue"
:style="{ height: tabsHeight }"
>
<el-tab-pane :label="tabLabel1" :style="{ height: tabPaneHeight }">
<!-- 设备数据表格 --> <!-- 设备数据表格 -->
<div class='container_table' :style='{ height: tableHeight }'> <div class="container_table" :style="{ height: tableHeight }">
<Table ref='tableRef1' :id='currentId' :plan='select_Plan' :planArray='planList2' <Table
:planTable='planTable' @batchGenerateClicked='handleBatchGenerate'></Table> ref="tableRef1"
:id="currentId"
:plan="select_Plan"
:planArray="planList2"
:planTable="planTable"
@batchGenerateClicked="handleBatchGenerate"
:height="tabPaneHeight"
></Table>
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@@ -110,7 +126,7 @@
</el-row> </el-row>
</div> </div>
</template> </template>
<script lang='ts' setup> <script lang="ts" setup>
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { type Plan } from '@/api/plan/interface' import { type Plan } from '@/api/plan/interface'
import { type CollapseModelValue } from 'element-plus/es/components/collapse/src/collapse.mjs' import { type CollapseModelValue } from 'element-plus/es/components/collapse/src/collapse.mjs'
@@ -119,8 +135,8 @@ import { type ResultData } from '@/api/interface'
import pie from '@/components/echarts/pie/default.vue' import pie from '@/components/echarts/pie/default.vue'
import tree from '../components/tree.vue' import tree from '../components/tree.vue'
import Table from '../components/table.vue' import Table from '../components/table.vue'
import { getBoundPqDevList, getPlanListByPattern, getPlanList } from '@/api/plan/plan' import { getBoundPqDevList, getPlanList, getPlanListByPattern } from '@/api/plan/plan'
import { onBeforeMount, onUnmounted, ref, watch, nextTick } from 'vue' import { nextTick, onBeforeMount, onUnmounted, ref, watch } from 'vue'
import { useModeStore } from '@/stores/modules/mode' // 引入模式 store import { useModeStore } from '@/stores/modules/mode' // 引入模式 store
import { useDictStore } from '@/stores/modules/dict' import { useDictStore } from '@/stores/modules/dict'
import { useViewSize } from '@/hooks/useViewSize' import { useViewSize } from '@/hooks/useViewSize'
@@ -138,7 +154,7 @@ const form: any = ref({
checkResult: 0, //检测结果 checkResult: 0, //检测结果
deviceBindStatus: 0, //绑定状态 deviceBindStatus: 0, //绑定状态
deviceType: 0, //设备类型 deviceType: 0, //设备类型
manufacturer: 0, //制造厂商 manufacturer: 0 //制造厂商
}) })
const router = useRouter() const router = useRouter()
const tabShow = ref(false) const tabShow = ref(false)
@@ -180,7 +196,6 @@ const handleCollapseChange = (val: CollapseModelValue) => {
tableHeight.value = `calc(100% - 5px)` tableHeight.value = `calc(100% - 5px)`
} }
// 设置默认主题颜色 // 设置默认主题颜色
localStorage.setItem('color', '#91cc75') localStorage.setItem('color', '#91cc75')
// ============================ 功能按钮配置 ============================ // ============================ 功能按钮配置 ============================
@@ -193,26 +208,26 @@ const tabsList = ref([
label: '设备检测', // 设备检测功能 label: '设备检测', // 设备检测功能
value: 0, value: 0,
img: new URL('/src/assets/images/plan/static/1.svg', import.meta.url).href, img: new URL('/src/assets/images/plan/static/1.svg', import.meta.url).href,
checked: true, // 默认选中 checked: true // 默认选中
}, },
{ {
label: '报告生成', // 检测报告生成功能 label: '报告生成', // 检测报告生成功能
value: 3, value: 3,
img: new URL('/src/assets/images/plan/static/3.svg', import.meta.url).href, img: new URL('/src/assets/images/plan/static/3.svg', import.meta.url).href,
checked: false, checked: false
}, },
{ {
label: '设备归档', // 设备归档管理功能 label: '设备归档', // 设备归档管理功能
value: 4, value: 4,
img: new URL('/src/assets/images/plan/static/4.svg', import.meta.url).href, img: new URL('/src/assets/images/plan/static/4.svg', import.meta.url).href,
checked: false, checked: false
}, },
{ {
label: '数据操作', // 数据查询和操作功能 label: '数据操作', // 数据查询和操作功能
value: 5, value: 5,
img: new URL('/src/assets/images/plan/static/5.svg', import.meta.url).href, img: new URL('/src/assets/images/plan/static/5.svg', import.meta.url).href,
checked: false, checked: false
}, }
]) ])
// 初始化默认选中第一个功能选项卡 // 初始化默认选中第一个功能选项卡
@@ -231,7 +246,7 @@ let isUpdatingTabs = false // 防止重复调用的标志
*/ */
watch( watch(
() => form.value.activeTabs, () => form.value.activeTabs,
async (newTabs) => { async newTabs => {
if (isUpdatingTabs) return // 如果正在更新中,跳过 if (isUpdatingTabs) return // 如果正在更新中,跳过
isUpdatingTabs = true isUpdatingTabs = true
@@ -279,7 +294,6 @@ const findPlanById = (plans: any, id: string): Plan.ReqPlan | undefined => {
return undefined return undefined
} }
/** /**
* 处理树节点选中事件的回调函数 * 处理树节点选中事件的回调函数
* 根据选中的计划节点更新饼图数据并切换相应的功能模式 * 根据选中的计划节点更新饼图数据并切换相应的功能模式
@@ -326,11 +340,11 @@ const getPieData = async (id: string) => {
const checkResultCount: { [key: number]: number } = { 0: 0, 1: 0, 2: 0 } // 检测结果计数:不符合(0)、符合(1)、未检(2) const checkResultCount: { [key: number]: number } = { 0: 0, 1: 0, 2: 0 } // 检测结果计数:不符合(0)、符合(1)、未检(2)
const reportStateCount: { [key: number]: number } = { 0: 0, 1: 0, 2: 0 } // 报告状态计数:未生成(0)、已生成(1)、未检(2) const reportStateCount: { [key: number]: number } = { 0: 0, 1: 0, 2: 0 } // 报告状态计数:未生成(0)、已生成(1)、未检(2)
if (id) { if (id) {
const boundPqDevList = ref<Device.ResPqDev[]>([])//根据检测计划id查询出所有已绑定的设备 const boundPqDevList = ref<Device.ResPqDev[]>([]) //根据检测计划id查询出所有已绑定的设备
const plan = findPlanById(planList.value, id) const plan = findPlanById(planList.value, id)
planName.value = '所选计划:' + (plan?.name || '') planName.value = '所选计划:' + (plan?.name || '')
select_Plan.value = plan select_Plan.value = plan
const pqDevList_Result2 = await getBoundPqDevList({ 'planIdList': [id], 'checkStateList': [0, 1, 2, 3] }) const pqDevList_Result2 = await getBoundPqDevList({ planIdList: [id], checkStateList: [0, 1, 2, 3] })
boundPqDevList.value = pqDevList_Result2.data as Device.ResPqDev[] boundPqDevList.value = pqDevList_Result2.data as Device.ResPqDev[]
// 遍历 boundPqDevList 并更新计数对象 // 遍历 boundPqDevList 并更新计数对象
boundPqDevList.value.forEach(t => { boundPqDevList.value.forEach(t => {
@@ -339,42 +353,49 @@ const getPieData = async (id: string) => {
} }
}) })
boundPqDevList.value.forEach(t => { boundPqDevList.value.forEach(t => {
if (t.checkResult !== undefined && t.checkResult !== null && checkResultCount[t.checkResult] !== undefined) { if (
t.checkResult !== undefined &&
t.checkResult !== null &&
checkResultCount[t.checkResult] !== undefined
) {
checkResultCount[t.checkResult]++ checkResultCount[t.checkResult]++
} }
}) })
boundPqDevList.value.forEach(t => { boundPqDevList.value.forEach(t => {
if (t.reportState !== undefined && t.reportState !== null && reportStateCount[t.reportState] !== undefined) { if (
t.reportState !== undefined &&
t.reportState !== null &&
reportStateCount[t.reportState] !== undefined
) {
reportStateCount[t.reportState]++ reportStateCount[t.reportState]++
} }
}) })
// 检查 checkStateCount 是否全为 0 // 检查 checkStateCount 是否全为 0
if (boundPqDevList.value.length != 0) { if (boundPqDevList.value.length != 0) {
isLabelLineShow.value = true isLabelLineShow.value = true
const allZero = Object.values(checkStateCount).every(count => count === 0) const allZero = Object.values(checkStateCount).every(count => count === 0)
chartsData1.value = [ chartsData1.value = [
{ {
value: allZero ? 0 : checkStateCount[0] === 0 ? null : checkStateCount[0], value: allZero ? 0 : checkStateCount[0] === 0 ? null : checkStateCount[0],
name: '未检', name: '未检',
itemStyle: { color: '#fac858' }, itemStyle: { color: '#fac858' }
}, },
{ {
value: allZero ? 0 : checkStateCount[1] === 0 ? null : checkStateCount[1], value: allZero ? 0 : checkStateCount[1] === 0 ? null : checkStateCount[1],
name: '检测中', name: '检测中',
itemStyle: { color: '#ee6666' }, itemStyle: { color: '#ee6666' }
}, },
{ {
value: allZero ? 0 : checkStateCount[2] === 0 ? null : checkStateCount[2], value: allZero ? 0 : checkStateCount[2] === 0 ? null : checkStateCount[2],
name: '检测完成', name: '检测完成',
itemStyle: { color: '#91cc75' }, itemStyle: { color: '#91cc75' }
}, },
{ {
value: allZero ? 0 : checkStateCount[3] === 0 ? null : checkStateCount[3], value: allZero ? 0 : checkStateCount[3] === 0 ? null : checkStateCount[3],
name: '归档', name: '归档',
itemStyle: { color: '#5470c6' }, itemStyle: { color: '#5470c6' }
}, }
] ]
// 同样处理 chartsData2 和 chartsData3 // 同样处理 chartsData2 和 chartsData3
const allZeroResult = Object.values(checkResultCount).every(count => count === 0) const allZeroResult = Object.values(checkResultCount).every(count => count === 0)
@@ -382,71 +403,67 @@ const getPieData = async (id: string) => {
{ {
value: allZeroResult ? 0 : checkResultCount[2] === 0 ? null : checkResultCount[2], value: allZeroResult ? 0 : checkResultCount[2] === 0 ? null : checkResultCount[2],
name: '未检', name: '未检',
itemStyle: { color: '#fac858' }, itemStyle: { color: '#fac858' }
}, },
{ {
value: allZeroResult ? 0 : checkResultCount[0] === 0 ? null : checkResultCount[0], value: allZeroResult ? 0 : checkResultCount[0] === 0 ? null : checkResultCount[0],
name: '不符合', name: '不符合',
itemStyle: { color: '#ee6666' }, itemStyle: { color: '#ee6666' }
}, },
{ {
value: allZeroResult ? 0 : checkResultCount[1] === 0 ? null : checkResultCount[1], value: allZeroResult ? 0 : checkResultCount[1] === 0 ? null : checkResultCount[1],
name: '符合', name: '符合',
itemStyle: { color: '#91cc75' }, itemStyle: { color: '#91cc75' }
}, }
] ]
// 检查 reportStateCount 是否全为 0 // 检查 reportStateCount 是否全为 0
const allZeroReport = Object.values(reportStateCount).every(count => count === 0) const allZeroReport = Object.values(reportStateCount).every(count => count === 0)
chartsData3.value = [ chartsData3.value = [
{ {
value: allZeroReport ? 0 : reportStateCount[2] === 0 ? null : reportStateCount[2], value: allZeroReport ? 0 : reportStateCount[2] === 0 ? null : reportStateCount[2],
name: '未检', name: '未检',
itemStyle: { color: '#fac858' }, itemStyle: { color: '#fac858' }
}, },
{ {
value: allZeroReport ? 0 : reportStateCount[0] === 0 ? null : reportStateCount[0], value: allZeroReport ? 0 : reportStateCount[0] === 0 ? null : reportStateCount[0],
name: '未生成', name: '未生成',
itemStyle: { color: '#ee6666' }, itemStyle: { color: '#ee6666' }
}, },
{ {
value: allZeroReport ? 0 : reportStateCount[1] === 0 ? null : reportStateCount[1], value: allZeroReport ? 0 : reportStateCount[1] === 0 ? null : reportStateCount[1],
name: '已生成', name: '已生成',
itemStyle: { color: '#91cc75' }, itemStyle: { color: '#91cc75' }
}, }
] ]
} else { } else {
isLabelLineShow.value = false //不展示引导线
isLabelLineShow.value = false//不展示引导线
chartsData1.value = [ chartsData1.value = [
{ value: null, name: '未检', itemStyle: { color: '#fac858' } }, { value: null, name: '未检', itemStyle: { color: '#fac858' } },
{ value: null, name: '检测中', itemStyle: { color: '#ee6666' } }, { value: null, name: '检测中', itemStyle: { color: '#ee6666' } },
{ value: null, name: '检测完成', itemStyle: { color: '#91cc75' } }, { value: null, name: '检测完成', itemStyle: { color: '#91cc75' } },
{ value: null, name: '归档', itemStyle: { color: '#5470c6' } }, { value: null, name: '归档', itemStyle: { color: '#5470c6' } },
{ value: 0, itemStyle: { color: '#eeeeee' } }, { value: 0, itemStyle: { color: '#eeeeee' } }
] ]
chartsData2.value = [ chartsData2.value = [
{ value: null, name: '未检', itemStyle: { color: '#fac858' } }, { value: null, name: '未检', itemStyle: { color: '#fac858' } },
{ value: null, name: '不符合', itemStyle: { color: '#ee6666' } }, { value: null, name: '不符合', itemStyle: { color: '#ee6666' } },
{ value: null, name: '符合', itemStyle: { color: '#91cc75' } }, { value: null, name: '符合', itemStyle: { color: '#91cc75' } },
{ value: 0, itemStyle: { color: '#eeeeee' } }, { value: 0, itemStyle: { color: '#eeeeee' } }
] ]
chartsData3.value = [ chartsData3.value = [
{ value: null, name: '未检', itemStyle: { color: '#fac858' } }, { value: null, name: '未检', itemStyle: { color: '#fac858' } },
{ value: null, name: '未生成', itemStyle: { color: '#ee6666' } }, { value: null, name: '未生成', itemStyle: { color: '#ee6666' } },
{ value: null, name: '已生成', itemStyle: { color: '#91cc75' } }, { value: null, name: '已生成', itemStyle: { color: '#91cc75' } },
{ value: 0, itemStyle: { color: '#eeeeee' } }, { value: 0, itemStyle: { color: '#eeeeee' } }
] ]
} }
} else { } else {
planName.value = '所选计划:' planName.value = '所选计划:'
} }
pieRef1.value.init() pieRef1.value.init()
pieRef2.value.init() pieRef2.value.init()
pieRef3.value.init() pieRef3.value.init()
@@ -465,7 +482,7 @@ const getTree = (data?: any) => {
*/ */
const handleDetection = () => { const handleDetection = () => {
router.push({ router.push({
path: '/detection', path: '/detection'
}) })
} }
@@ -474,11 +491,10 @@ const handleDetection = () => {
*/ */
const planDetail = () => { const planDetail = () => {
router.push({ router.push({
path: '/plan/planList', path: '/plan/planList'
}) })
} }
// ============================ 主要业务逻辑函数 ============================ // ============================ 主要业务逻辑函数 ============================
/** /**
* 处理功能选项卡切换 * 处理功能选项卡切换
@@ -491,7 +507,7 @@ const handleCheckFunction = (val: any) => {
// 更新功能按钮的选中状态 // 更新功能按钮的选中状态
tabsList.value.map((item: any, index: any) => { tabsList.value.map((item: any, index: any) => {
item.checked = (val == item.value) item.checked = val == item.value
}) })
tabShow.value = false tabShow.value = false
@@ -530,7 +546,6 @@ const handleCheckFunction = (val: any) => {
} }
} }
// ============================ 监听器和事件处理 ============================ // ============================ 监听器和事件处理 ============================
/** /**
* 饼图容器尺寸变化监听器 * 饼图容器尺寸变化监听器
@@ -548,7 +563,6 @@ const resizeObserver = new ResizeObserver(entries => {
} }
}) })
// ============================ 初始化函数 ============================ // ============================ 初始化函数 ============================
/** /**
* 初始化计划数据 * 初始化计划数据
@@ -587,11 +601,11 @@ const initPlan = async () => {
testItemNameStr: '', testItemNameStr: '',
testItems: [], testItems: [],
standardDevIds: [], standardDevIds: [],
standardDevMap: new Map<string, number>(), standardDevMap: new Map<string, number>()
} }
// 获取计划数据 // 获取计划数据
const result = await getPlanListByPattern(reqPlan) as ResultData<Plan.ReqPlan[]> const result = (await getPlanListByPattern(reqPlan)) as ResultData<Plan.ReqPlan[]>
planList2.value = result.data || [] planList2.value = result.data || []
// 创建计划数据的副本用于过滤处理 // 创建计划数据的副本用于过滤处理
@@ -639,13 +653,12 @@ onBeforeMount(async () => {
getPieData(currentId.value) getPieData(currentId.value)
// 如果不是比对模式,直接返回 // 如果不是比对模式,直接返回
if (modeStore.currentMode != '比对式') if (modeStore.currentMode != '比对式') return
return
// 比对模式下加载额外的计划表格数据 // 比对模式下加载额外的计划表格数据
const patternId2 = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id const patternId2 = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id
if (patternId2 !== undefined) { if (patternId2 !== undefined) {
planTable.value = await getPlanList({ 'patternId': patternId2 } ) planTable.value = await getPlanList({ patternId: patternId2 })
} }
}) })
@@ -675,10 +688,8 @@ const handleBatchGenerate = async () => {
tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs) tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs)
} }
</script> </script>
<style lang='scss' scoped> <style lang="scss" scoped>
.static { .static {
.left_tree { .left_tree {
height: 100%; height: 100%;
background-color: #fff; background-color: #fff;
@@ -690,7 +701,6 @@ const handleBatchGenerate = async () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.container_function { .container_function {
width: 100%; width: 100%;
height: auto; height: auto;
@@ -715,7 +725,7 @@ const handleBatchGenerate = async () => {
background-color: #607eab; background-color: #607eab;
border-radius: 8px; border-radius: 8px;
padding: 0px 30px; padding: 0px 30px;
margin-right: 50px;; margin-right: 50px;
.item_img { .item_img {
width: 60px; width: 60px;
@@ -748,7 +758,7 @@ const handleBatchGenerate = async () => {
font-weight: 800; font-weight: 800;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
font-family: "Microsoft YaHei", "微软雅黑", "Arial", sans-serif; font-family: 'Microsoft YaHei', '微软雅黑', 'Arial', sans-serif;
} }
} }
} }
@@ -784,7 +794,6 @@ const handleBatchGenerate = async () => {
width: 99%; width: 99%;
font-size: 14px; font-size: 14px;
} }
} }
.el-collapse { .el-collapse {
@@ -820,7 +829,6 @@ const handleBatchGenerate = async () => {
border-radius: 4px; border-radius: 4px;
} }
.tabs-menu { .tabs-menu {
height: 100%; height: 100%;
border: 0; border: 0;
@@ -845,20 +853,18 @@ const handleBatchGenerate = async () => {
:deep(.el-collapse-item__header) { :deep(.el-collapse-item__header) {
color: var(--el-color-primary); color: var(--el-color-primary);
font-size: 14px; font-size: 14px;
font-family: "Microsoft YaHei", "微软雅黑", "Arial", sans-serif; font-family: 'Microsoft YaHei', '微软雅黑', 'Arial', sans-serif;
} }
:deep(.el-collapse-item__conten) { :deep(.el-collapse-item__conten) {
padding-bottom: 0px !important; padding-bottom: 0px !important;
} }
:deep(.el-collapse-item__content ) { :deep(.el-collapse-item__content) {
padding-bottom: 0px !important; padding-bottom: 0px !important;
} }
:deep(.el-tabs--border-card > .el-tabs__content) { :deep(.el-tabs--border-card > .el-tabs__content) {
padding: 0 !important; padding: 0 !important;
} }
</style> </style>