2025-08-06 19:53:22 +08:00
|
|
|
|
<!--
|
|
|
|
|
|
首页Dashboard组件 - 主要功能页面
|
|
|
|
|
|
布局:左侧计划树 + 右侧功能区域(功能选择、饼图统计、表格数据)
|
|
|
|
|
|
-->
|
2024-08-23 13:19:20 +08:00
|
|
|
|
<template>
|
2025-10-10 15:29:54 +08:00
|
|
|
|
<div class="static" ref="popupBaseView">
|
|
|
|
|
|
<el-row :gutter="10">
|
|
|
|
|
|
<!-- 左侧计划树区域 (20%) -->
|
|
|
|
|
|
<el-col :lg="4" :xl="4" :md="4" :sm="4">
|
|
|
|
|
|
<div class="left_tree">
|
|
|
|
|
|
<tree
|
|
|
|
|
|
ref="treeRef"
|
|
|
|
|
|
:updateSelectedTreeNode="updateData || (() => {})"
|
|
|
|
|
|
:width="viewWidth"
|
|
|
|
|
|
:height="viewHeight"
|
|
|
|
|
|
:planTable="planTable"
|
|
|
|
|
|
/>
|
2025-01-06 14:07:21 +08:00
|
|
|
|
</div>
|
2025-10-10 15:29:54 +08:00
|
|
|
|
</el-col>
|
|
|
|
|
|
<!-- 右侧主要内容区域 (80%) -->
|
|
|
|
|
|
<el-col :lg="20" :xl="20" :md="20" :sm="20">
|
|
|
|
|
|
<div class="right_container">
|
|
|
|
|
|
<!-- 功能选择 -->
|
|
|
|
|
|
<div class="container_function">
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="function_item"
|
|
|
|
|
|
:class="item.checked ? 'function_item checked_function' : 'function_item'"
|
|
|
|
|
|
v-for="(item, index) in tabsList"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
@click="handleCheckFunction(item.value)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="item_img">
|
|
|
|
|
|
<img :src="item.img" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item_text">
|
|
|
|
|
|
<p>{{ item.label }}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!--检测计划统计 饼图统计-->
|
|
|
|
|
|
<div class="container_pieShow">
|
|
|
|
|
|
<el-collapse model-value="1" accordion @change="handleCollapseChange">
|
|
|
|
|
|
<el-collapse-item name="1">
|
|
|
|
|
|
<template #title>
|
|
|
|
|
|
<div class="container_pieShow_title">
|
|
|
|
|
|
<span>检测计划统计</span>
|
|
|
|
|
|
<span>{{ planName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<!-- 饼图 -->
|
|
|
|
|
|
<div class="container_charts">
|
|
|
|
|
|
<div class="charts_info" ref="chartsInfoRef">
|
|
|
|
|
|
<pie
|
|
|
|
|
|
:customData="{
|
|
|
|
|
|
title: '设备检测状态',
|
|
|
|
|
|
textAlign: 'left'
|
|
|
|
|
|
}"
|
|
|
|
|
|
:legendData="{
|
|
|
|
|
|
icon: 'circle',
|
|
|
|
|
|
left: 'left',
|
|
|
|
|
|
top: 'bottom'
|
|
|
|
|
|
}"
|
|
|
|
|
|
:chartsData="chartsData1"
|
|
|
|
|
|
ref="pieRef1"
|
|
|
|
|
|
></pie>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="charts_info">
|
|
|
|
|
|
<pie
|
|
|
|
|
|
:customData="{
|
|
|
|
|
|
title: '设备检测结果',
|
|
|
|
|
|
textAlign: 'left'
|
|
|
|
|
|
}"
|
|
|
|
|
|
:legendData="{
|
|
|
|
|
|
icon: 'circle',
|
|
|
|
|
|
left: 'left',
|
|
|
|
|
|
top: 'bottom'
|
|
|
|
|
|
}"
|
|
|
|
|
|
:chartsData="chartsData2"
|
|
|
|
|
|
ref="pieRef2"
|
|
|
|
|
|
></pie>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="charts_info">
|
|
|
|
|
|
<pie
|
|
|
|
|
|
:customData="{
|
|
|
|
|
|
title: '设备报告状态',
|
|
|
|
|
|
textAlign: 'left'
|
|
|
|
|
|
}"
|
|
|
|
|
|
:legendData="{
|
|
|
|
|
|
icon: 'circle',
|
|
|
|
|
|
left: 'left',
|
|
|
|
|
|
top: 'bottom'
|
|
|
|
|
|
}"
|
|
|
|
|
|
:chartsData="chartsData3"
|
|
|
|
|
|
ref="pieRef3"
|
|
|
|
|
|
></pie>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-collapse-item>
|
|
|
|
|
|
</el-collapse>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!--下方表格数据-->
|
|
|
|
|
|
<el-tabs
|
|
|
|
|
|
class="tabs-menu"
|
|
|
|
|
|
type="border-card"
|
|
|
|
|
|
v-model="editableTabsValue"
|
|
|
|
|
|
:style="{ height: tabsHeight }"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-tab-pane :label="tabLabel1" :style="{ height: tabPaneHeight }">
|
|
|
|
|
|
<!-- 设备数据表格 -->
|
|
|
|
|
|
<div class="container_table" :style="{ height: tableHeight }">
|
|
|
|
|
|
<Table
|
|
|
|
|
|
ref="tableRef1"
|
|
|
|
|
|
:id="currentId"
|
|
|
|
|
|
:plan="select_Plan"
|
|
|
|
|
|
:planArray="planList2"
|
|
|
|
|
|
:planTable="planTable"
|
|
|
|
|
|
@batchGenerateClicked="handleBatchGenerate"
|
|
|
|
|
|
:height="tabPaneHeight"
|
|
|
|
|
|
></Table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
|
</el-tabs>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
</div>
|
2024-08-23 13:19:20 +08:00
|
|
|
|
</template>
|
2025-10-10 15:29:54 +08:00
|
|
|
|
<script lang="ts" setup>
|
2025-01-06 14:07:21 +08:00
|
|
|
|
import { useRouter } from 'vue-router'
|
2025-08-06 19:53:22 +08:00
|
|
|
|
import { type Plan } from '@/api/plan/interface'
|
|
|
|
|
|
import { type CollapseModelValue } from 'element-plus/es/components/collapse/src/collapse.mjs'
|
|
|
|
|
|
import { type Device } from '@/api/device/interface/device'
|
|
|
|
|
|
import { type ResultData } from '@/api/interface'
|
|
|
|
|
|
import pie from '@/components/echarts/pie/default.vue'
|
2025-01-06 14:07:21 +08:00
|
|
|
|
import tree from '../components/tree.vue'
|
|
|
|
|
|
import Table from '../components/table.vue'
|
2025-10-10 15:29:54 +08:00
|
|
|
|
import { getBoundPqDevList, getPlanList, getPlanListByPattern } from '@/api/plan/plan'
|
|
|
|
|
|
import { nextTick, onBeforeMount, onUnmounted, ref, watch } from 'vue'
|
2025-01-06 14:07:21 +08:00
|
|
|
|
import { useModeStore } from '@/stores/modules/mode' // 引入模式 store
|
|
|
|
|
|
import { useDictStore } from '@/stores/modules/dict'
|
2025-07-21 13:47:56 +08:00
|
|
|
|
import { useViewSize } from '@/hooks/useViewSize'
|
2024-11-29 13:45:48 +08:00
|
|
|
|
|
2024-12-30 14:43:13 +08:00
|
|
|
|
const planName = ref('')
|
2024-12-13 16:35:27 +08:00
|
|
|
|
const dictStore = useDictStore()
|
2025-01-06 14:07:21 +08:00
|
|
|
|
const modeStore = useModeStore()
|
|
|
|
|
|
const chartsInfoRef = ref<HTMLElement | null>(null)
|
|
|
|
|
|
const chartsWidth = ref<number>(0)
|
|
|
|
|
|
const treeRef = ref()
|
2024-08-23 13:19:20 +08:00
|
|
|
|
const form: any = ref({
|
2025-10-10 15:29:54 +08:00
|
|
|
|
activeTabs: 0, //功能选择,例如报告生成
|
|
|
|
|
|
checkStatus: 0, //检测状态
|
|
|
|
|
|
checkReportStatus: 0, //检测报告状态
|
|
|
|
|
|
checkResult: 0, //检测结果
|
|
|
|
|
|
deviceBindStatus: 0, //绑定状态
|
|
|
|
|
|
deviceType: 0, //设备类型
|
|
|
|
|
|
manufacturer: 0 //制造厂商
|
2025-01-06 14:07:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
const tabShow = ref(false)
|
2024-11-15 09:34:43 +08:00
|
|
|
|
const tabLabel1 = ref('设备检测')
|
2024-11-12 20:35:12 +08:00
|
|
|
|
const editableTabsValue = ref('0')
|
2024-12-20 10:19:58 +08:00
|
|
|
|
const checkStateTable = ref<number[]>([0, 1, 2])
|
2025-01-06 14:07:21 +08:00
|
|
|
|
const tabsHeight = ref('calc(100vh - 522px)') // 初始高度
|
|
|
|
|
|
const tabPaneHeight = ref('calc(100% - 5px)') // 初始高度
|
|
|
|
|
|
const tableHeight = ref('calc(100% - 50px)') // 初始高度
|
2024-11-29 13:45:48 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 计划数据状态 ============================
|
|
|
|
|
|
const planList = ref<Plan.ReqPlan[]>([]) // 计划列表(过滤后)
|
|
|
|
|
|
const planList2 = ref<Plan.ReqPlan[]>([]) // 计划列表原始数据(包含子计划)
|
|
|
|
|
|
const select_Plan = ref<Plan.ReqPlan>() // 当前选中的计划
|
|
|
|
|
|
const planTable = ref<any[]>([]) // 比对模式下的计划表格数据
|
|
|
|
|
|
|
|
|
|
|
|
// ============================ 视图状态 ============================
|
|
|
|
|
|
const isLabelLineShow = ref(true) // 饼图是否显示引导线
|
|
|
|
|
|
const { popupBaseView, viewWidth, viewHeight } = useViewSize() // 视口尺寸hook
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理折叠面板展开/收起事件
|
|
|
|
|
|
* 根据面板状态动态调整表格高度,优化空间利用
|
|
|
|
|
|
* @param val - 当前展开的面板值
|
|
|
|
|
|
*/
|
2024-12-13 16:35:27 +08:00
|
|
|
|
const handleCollapseChange = (val: CollapseModelValue) => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
// 计算新的高度值
|
|
|
|
|
|
let newHeight
|
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
|
|
// 数组情况:有展开项时高度更小,无展开项时高度更大
|
|
|
|
|
|
newHeight = val.length > 0 ? 'calc(100vh - 522px)' : 'calc(100vh - 333px)'
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 单个值情况:展开时高度更小,收起时高度更大
|
|
|
|
|
|
newHeight = val ? 'calc(100vh - 538px)' : 'calc(100vh - 333px)'
|
|
|
|
|
|
}
|
|
|
|
|
|
// 更新各个容器的高度
|
|
|
|
|
|
tabsHeight.value = newHeight
|
|
|
|
|
|
tabPaneHeight.value = `calc(100% - 5px)`
|
|
|
|
|
|
tableHeight.value = `calc(100% - 5px)`
|
2025-01-06 14:07:21 +08:00
|
|
|
|
}
|
2024-11-29 13:45:48 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// 设置默认主题颜色
|
2025-03-19 10:26:41 +08:00
|
|
|
|
localStorage.setItem('color', '#91cc75')
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 功能按钮配置 ============================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 主功能选项卡配置
|
|
|
|
|
|
* 包含4个主要功能:设备检测、报告生成、设备归档、数据操作
|
|
|
|
|
|
*/
|
2024-08-27 14:01:26 +08:00
|
|
|
|
const tabsList = ref([
|
2025-10-10 15:29:54 +08:00
|
|
|
|
{
|
|
|
|
|
|
label: '设备检测', // 设备检测功能
|
|
|
|
|
|
value: 0,
|
|
|
|
|
|
img: new URL('/src/assets/images/plan/static/1.svg', import.meta.url).href,
|
|
|
|
|
|
checked: true // 默认选中
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '报告生成', // 检测报告生成功能
|
|
|
|
|
|
value: 3,
|
|
|
|
|
|
img: new URL('/src/assets/images/plan/static/3.svg', import.meta.url).href,
|
|
|
|
|
|
checked: false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '设备归档', // 设备归档管理功能
|
|
|
|
|
|
value: 4,
|
|
|
|
|
|
img: new URL('/src/assets/images/plan/static/4.svg', import.meta.url).href,
|
|
|
|
|
|
checked: false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '数据操作', // 数据查询和操作功能
|
|
|
|
|
|
value: 5,
|
|
|
|
|
|
img: new URL('/src/assets/images/plan/static/5.svg', import.meta.url).href,
|
|
|
|
|
|
checked: false
|
|
|
|
|
|
}
|
2025-01-06 14:07:21 +08:00
|
|
|
|
])
|
2024-11-29 13:45:48 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// 初始化默认选中第一个功能选项卡
|
2025-01-06 14:07:21 +08:00
|
|
|
|
form.value.activeTabs = tabsList.value[0].value
|
2024-11-29 13:45:48 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 组件引用和状态 ============================
|
|
|
|
|
|
const tableRef1 = ref() // 主表格组件引用
|
|
|
|
|
|
const currentId = ref('') // 当前选中的计划ID
|
|
|
|
|
|
|
|
|
|
|
|
// ============================ 监听器 ============================
|
2025-08-07 08:47:56 +08:00
|
|
|
|
let isUpdatingTabs = false // 防止重复调用的标志
|
|
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 监听功能切换并通知表格组件更新配置
|
|
|
|
|
|
* 不再传递静态数据,让表格组件通过API获取真实数据
|
|
|
|
|
|
*/
|
2024-09-02 16:10:33 +08:00
|
|
|
|
watch(
|
2025-10-10 15:29:54 +08:00
|
|
|
|
() => form.value.activeTabs,
|
|
|
|
|
|
async newTabs => {
|
|
|
|
|
|
if (isUpdatingTabs) return // 如果正在更新中,跳过
|
|
|
|
|
|
|
|
|
|
|
|
isUpdatingTabs = true
|
|
|
|
|
|
// 只传递功能模式,不传递静态假数据
|
|
|
|
|
|
// 表格组件会根据功能模式通过API获取对应的真实数据
|
|
|
|
|
|
tableRef1.value && tableRef1.value.changeActiveTabs(newTabs)
|
|
|
|
|
|
|
|
|
|
|
|
// 等待一个微任务队列后重置标志
|
|
|
|
|
|
await nextTick()
|
|
|
|
|
|
isUpdatingTabs = false
|
|
|
|
|
|
}
|
|
|
|
|
|
// 去掉 immediate: true,避免初始化时重复调用
|
2025-01-06 14:07:21 +08:00
|
|
|
|
)
|
2025-01-13 21:26:12 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 饼图组件引用和数据 ============================
|
|
|
|
|
|
const pieRef1 = ref(), // 设备检测状态饼图引用
|
2025-10-10 15:29:54 +08:00
|
|
|
|
pieRef2 = ref(), // 设备检测结果饼图引用
|
|
|
|
|
|
pieRef3 = ref() // 设备报告状态饼图引用
|
2025-08-06 19:53:22 +08:00
|
|
|
|
|
|
|
|
|
|
const chartsData1: any = ref([]), // 设备检测状态统计数据
|
2025-10-10 15:29:54 +08:00
|
|
|
|
chartsData2: any = ref([]), // 设备检测结果统计数据
|
|
|
|
|
|
chartsData3: any = ref([]) // 设备报告状态统计数据
|
2025-08-06 19:53:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ============================ 工具函数 ============================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 递归查找指定 ID 的计划
|
|
|
|
|
|
* @param plans - 计划数组
|
|
|
|
|
|
* @param id - 计划 ID
|
|
|
|
|
|
* @returns 找到的计划对象或 undefined
|
|
|
|
|
|
*/
|
|
|
|
|
|
const findPlanById = (plans: any, id: string): Plan.ReqPlan | undefined => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
if (!plans) return undefined
|
|
|
|
|
|
for (const plan of plans) {
|
|
|
|
|
|
if (plan?.id === id) {
|
|
|
|
|
|
return plan
|
|
|
|
|
|
}
|
|
|
|
|
|
// 递归搜索子计划
|
|
|
|
|
|
if (plan?.children) {
|
|
|
|
|
|
const foundPlan = findPlanById(plan.children, id)
|
|
|
|
|
|
if (foundPlan) {
|
|
|
|
|
|
return foundPlan
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-18 15:49:29 +08:00
|
|
|
|
}
|
2025-10-10 15:29:54 +08:00
|
|
|
|
return undefined
|
2025-01-06 14:07:21 +08:00
|
|
|
|
}
|
2024-12-18 15:49:29 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 处理树节点选中事件的回调函数
|
|
|
|
|
|
* 根据选中的计划节点更新饼图数据并切换相应的功能模式
|
|
|
|
|
|
* @param id - 选中的计划 ID
|
|
|
|
|
|
*/
|
2025-01-16 14:24:55 +08:00
|
|
|
|
const updateData = (id: string) => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
// 刷新饼图数据
|
|
|
|
|
|
getPieData(id)
|
|
|
|
|
|
|
|
|
|
|
|
// 查找当前计划的父节点名称
|
|
|
|
|
|
const parentNodeName = ref('')
|
|
|
|
|
|
if (planList.value?.length) {
|
|
|
|
|
|
for (let i = 0; i < planList.value.length; i++) {
|
|
|
|
|
|
const children = planList.value[i]?.children
|
|
|
|
|
|
if (Array.isArray(children) && children.length > 0) {
|
|
|
|
|
|
for (let j = 0; j < children.length; j++) {
|
|
|
|
|
|
if (children[j]?.id === id) {
|
|
|
|
|
|
parentNodeName.value = planList.value[i]?.name || ''
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-15 13:26:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-10 15:29:54 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据父节点名称自动切换功能模式
|
|
|
|
|
|
if (parentNodeName.value === '检测完成') {
|
|
|
|
|
|
handleCheckFunction(5) // 切换到数据操作模式
|
|
|
|
|
|
} else {
|
|
|
|
|
|
handleCheckFunction(0) // 切换到设备检测模式
|
|
|
|
|
|
}
|
2025-01-16 14:24:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取指定计划的设备统计数据并更新饼图
|
|
|
|
|
|
* 分别统计设备的检测状态、检测结果、报告状态分布情况
|
|
|
|
|
|
* @param id - 计划 ID
|
|
|
|
|
|
*/
|
2025-01-16 14:24:55 +08:00
|
|
|
|
const getPieData = async (id: string) => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
currentId.value = id // 设置当前选中的计划ID
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化各类统计计数器
|
|
|
|
|
|
const checkStateCount: { [key: number]: number } = { 0: 0, 1: 0, 2: 0, 3: 0 } // 检测状态计数:未检(0)、检测中(1)、检测完成(2)、归档(3)
|
|
|
|
|
|
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)
|
|
|
|
|
|
if (id) {
|
|
|
|
|
|
const boundPqDevList = ref<Device.ResPqDev[]>([]) //根据检测计划id查询出所有已绑定的设备
|
|
|
|
|
|
const plan = findPlanById(planList.value, id)
|
|
|
|
|
|
planName.value = '所选计划:' + (plan?.name || '')
|
|
|
|
|
|
select_Plan.value = plan
|
|
|
|
|
|
const pqDevList_Result2 = await getBoundPqDevList({ planIdList: [id], checkStateList: [0, 1, 2, 3] })
|
|
|
|
|
|
boundPqDevList.value = pqDevList_Result2.data as Device.ResPqDev[]
|
|
|
|
|
|
// 遍历 boundPqDevList 并更新计数对象
|
|
|
|
|
|
boundPqDevList.value.forEach(t => {
|
|
|
|
|
|
if (t.checkState !== undefined && t.checkState !== null && checkStateCount[t.checkState] !== undefined) {
|
|
|
|
|
|
checkStateCount[t.checkState]++
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
boundPqDevList.value.forEach(t => {
|
|
|
|
|
|
if (
|
|
|
|
|
|
t.checkResult !== undefined &&
|
|
|
|
|
|
t.checkResult !== null &&
|
|
|
|
|
|
checkResultCount[t.checkResult] !== undefined
|
|
|
|
|
|
) {
|
|
|
|
|
|
checkResultCount[t.checkResult]++
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
boundPqDevList.value.forEach(t => {
|
|
|
|
|
|
if (
|
|
|
|
|
|
t.reportState !== undefined &&
|
|
|
|
|
|
t.reportState !== null &&
|
|
|
|
|
|
reportStateCount[t.reportState] !== undefined
|
|
|
|
|
|
) {
|
|
|
|
|
|
reportStateCount[t.reportState]++
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 检查 checkStateCount 是否全为 0
|
|
|
|
|
|
if (boundPqDevList.value.length != 0) {
|
|
|
|
|
|
isLabelLineShow.value = true
|
|
|
|
|
|
const allZero = Object.values(checkStateCount).every(count => count === 0)
|
|
|
|
|
|
chartsData1.value = [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZero ? 0 : checkStateCount[0] === 0 ? null : checkStateCount[0],
|
|
|
|
|
|
name: '未检',
|
|
|
|
|
|
itemStyle: { color: '#fac858' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZero ? 0 : checkStateCount[1] === 0 ? null : checkStateCount[1],
|
|
|
|
|
|
name: '检测中',
|
|
|
|
|
|
itemStyle: { color: '#ee6666' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZero ? 0 : checkStateCount[2] === 0 ? null : checkStateCount[2],
|
|
|
|
|
|
name: '检测完成',
|
|
|
|
|
|
itemStyle: { color: '#91cc75' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZero ? 0 : checkStateCount[3] === 0 ? null : checkStateCount[3],
|
|
|
|
|
|
name: '归档',
|
|
|
|
|
|
itemStyle: { color: '#5470c6' }
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
// 同样处理 chartsData2 和 chartsData3
|
|
|
|
|
|
const allZeroResult = Object.values(checkResultCount).every(count => count === 0)
|
|
|
|
|
|
chartsData2.value = [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZeroResult ? 0 : checkResultCount[2] === 0 ? null : checkResultCount[2],
|
|
|
|
|
|
name: '未检',
|
|
|
|
|
|
itemStyle: { color: '#fac858' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZeroResult ? 0 : checkResultCount[0] === 0 ? null : checkResultCount[0],
|
|
|
|
|
|
name: '不符合',
|
|
|
|
|
|
itemStyle: { color: '#ee6666' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZeroResult ? 0 : checkResultCount[1] === 0 ? null : checkResultCount[1],
|
|
|
|
|
|
name: '符合',
|
|
|
|
|
|
itemStyle: { color: '#91cc75' }
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
// 检查 reportStateCount 是否全为 0
|
|
|
|
|
|
const allZeroReport = Object.values(reportStateCount).every(count => count === 0)
|
|
|
|
|
|
chartsData3.value = [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZeroReport ? 0 : reportStateCount[2] === 0 ? null : reportStateCount[2],
|
|
|
|
|
|
name: '未检',
|
|
|
|
|
|
itemStyle: { color: '#fac858' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZeroReport ? 0 : reportStateCount[0] === 0 ? null : reportStateCount[0],
|
|
|
|
|
|
name: '未生成',
|
|
|
|
|
|
itemStyle: { color: '#ee6666' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: allZeroReport ? 0 : reportStateCount[1] === 0 ? null : reportStateCount[1],
|
|
|
|
|
|
name: '已生成',
|
|
|
|
|
|
itemStyle: { color: '#91cc75' }
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
} else {
|
|
|
|
|
|
isLabelLineShow.value = false //不展示引导线
|
|
|
|
|
|
chartsData1.value = [
|
|
|
|
|
|
{ value: null, name: '未检', itemStyle: { color: '#fac858' } },
|
|
|
|
|
|
{ value: null, name: '检测中', itemStyle: { color: '#ee6666' } },
|
|
|
|
|
|
{ value: null, name: '检测完成', itemStyle: { color: '#91cc75' } },
|
|
|
|
|
|
{ value: null, name: '归档', itemStyle: { color: '#5470c6' } },
|
|
|
|
|
|
{ value: 0, itemStyle: { color: '#eeeeee' } }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
chartsData2.value = [
|
|
|
|
|
|
{ value: null, name: '未检', itemStyle: { color: '#fac858' } },
|
|
|
|
|
|
{ value: null, name: '不符合', itemStyle: { color: '#ee6666' } },
|
|
|
|
|
|
{ value: null, name: '符合', itemStyle: { color: '#91cc75' } },
|
|
|
|
|
|
{ value: 0, itemStyle: { color: '#eeeeee' } }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
chartsData3.value = [
|
|
|
|
|
|
{ value: null, name: '未检', itemStyle: { color: '#fac858' } },
|
|
|
|
|
|
{ value: null, name: '未生成', itemStyle: { color: '#ee6666' } },
|
|
|
|
|
|
{ value: null, name: '已生成', itemStyle: { color: '#91cc75' } },
|
|
|
|
|
|
{ value: 0, itemStyle: { color: '#eeeeee' } }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
2025-08-06 19:53:22 +08:00
|
|
|
|
} else {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
planName.value = '所选计划:'
|
2025-01-22 16:28:09 +08:00
|
|
|
|
}
|
2024-12-13 16:35:27 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
pieRef1.value.init()
|
|
|
|
|
|
pieRef2.value.init()
|
|
|
|
|
|
pieRef3.value.init()
|
2025-01-06 14:07:21 +08:00
|
|
|
|
}
|
2025-08-06 19:53:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 初始化树组件数据
|
|
|
|
|
|
* @param data - 计划数据
|
|
|
|
|
|
*/
|
2024-12-13 16:35:27 +08:00
|
|
|
|
const getTree = (data?: any) => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
treeRef.value.getTreeData(data)
|
2025-01-06 14:07:21 +08:00
|
|
|
|
}
|
2025-08-06 19:53:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ============================ 路由跳转函数 ============================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 跳转到检测页面
|
|
|
|
|
|
*/
|
2024-08-23 16:51:49 +08:00
|
|
|
|
const handleDetection = () => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
router.push({
|
|
|
|
|
|
path: '/detection'
|
|
|
|
|
|
})
|
2025-01-06 14:07:21 +08:00
|
|
|
|
}
|
2025-08-06 19:53:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 跳转到计划详情页面
|
|
|
|
|
|
*/
|
2024-08-26 20:05:04 +08:00
|
|
|
|
const planDetail = () => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
router.push({
|
|
|
|
|
|
path: '/plan/planList'
|
|
|
|
|
|
})
|
2025-01-06 14:07:21 +08:00
|
|
|
|
}
|
2025-01-13 21:26:12 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 主要业务逻辑函数 ============================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理功能选项卡切换
|
|
|
|
|
|
* 根据选中的功能更新UI状态和表格显示内容
|
|
|
|
|
|
* @param val - 功能选项卡值 (0:设备检测, 3:报告生成, 4:设备归档, 5:数据操作)
|
|
|
|
|
|
*/
|
2024-08-27 14:01:26 +08:00
|
|
|
|
const handleCheckFunction = (val: any) => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
// 重置tab状态
|
|
|
|
|
|
editableTabsValue.value = '0'
|
|
|
|
|
|
|
|
|
|
|
|
// 更新功能按钮的选中状态
|
|
|
|
|
|
tabsList.value.map((item: any, index: any) => {
|
|
|
|
|
|
item.checked = val == item.value
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
tabShow.value = false
|
|
|
|
|
|
|
|
|
|
|
|
// 根据选中的功能设置不同的过滤条件和标签
|
|
|
|
|
|
switch (val) {
|
|
|
|
|
|
case 0: // 设备检测模式
|
|
|
|
|
|
checkStateTable.value = [0, 1, 2] // 显示未检、检测中、检测完成的设备
|
|
|
|
|
|
tabLabel1.value = '设备检测'
|
|
|
|
|
|
break
|
|
|
|
|
|
case 1: // 手动检测模式(预留)
|
|
|
|
|
|
tabLabel1.value = '手动检测'
|
|
|
|
|
|
break
|
|
|
|
|
|
case 2: // 设备复检模式(预留)
|
|
|
|
|
|
tabLabel1.value = '设备复检'
|
|
|
|
|
|
break
|
|
|
|
|
|
case 3: // 报告生成模式
|
|
|
|
|
|
checkStateTable.value = [2, 3] // 显示检测完成和已归档的设备
|
|
|
|
|
|
tabLabel1.value = '报告生成'
|
|
|
|
|
|
break
|
|
|
|
|
|
case 4: // 设备归档模式
|
|
|
|
|
|
checkStateTable.value = [2] // 只显示检测完成的设备
|
|
|
|
|
|
tabLabel1.value = '设备归档'
|
|
|
|
|
|
break
|
|
|
|
|
|
case 5: // 数据查询模式
|
|
|
|
|
|
checkStateTable.value = [2, 3] // 显示检测完成和已归档的设备
|
|
|
|
|
|
tabLabel1.value = '数据查询'
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
// 更新当前激活的功能选项卡
|
|
|
|
|
|
form.value.activeTabs = val
|
2024-10-11 08:49:31 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
// 刷新饼图数据以确保统计信息同步
|
|
|
|
|
|
if (currentId.value) {
|
|
|
|
|
|
getPieData(currentId.value)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-03 17:13:47 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 监听器和事件处理 ============================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 饼图容器尺寸变化监听器
|
|
|
|
|
|
* 当容器大小变化时自动调整饼图尺寸,保持响应式设计
|
|
|
|
|
|
*/
|
2024-12-03 17:13:47 +08:00
|
|
|
|
const resizeObserver = new ResizeObserver(entries => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
for (let entry of entries) {
|
|
|
|
|
|
// 更新容器宽度
|
|
|
|
|
|
chartsWidth.value = entry.contentRect.width
|
|
|
|
|
|
|
|
|
|
|
|
// 同步调整三个饼图的尺寸(宽度为容器的95%,高度固定180px)
|
|
|
|
|
|
pieRef1.value?.reSize(chartsWidth.value * 0.95, 180, true)
|
|
|
|
|
|
pieRef2.value?.reSize(chartsWidth.value * 0.95, 180, true)
|
|
|
|
|
|
pieRef3.value?.reSize(chartsWidth.value * 0.95, 180, true)
|
|
|
|
|
|
}
|
2025-01-06 14:07:21 +08:00
|
|
|
|
})
|
2024-12-03 17:13:47 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 初始化函数 ============================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 初始化计划数据
|
|
|
|
|
|
* 根据当前模式获取相应的计划列表数据
|
|
|
|
|
|
*/
|
2025-01-16 14:24:55 +08:00
|
|
|
|
const initPlan = async () => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
// 获取当前模式对应的数据字典ID
|
|
|
|
|
|
const patternId = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
|
|
|
|
|
|
|
|
|
|
|
|
// 构建计划查询请求对象
|
|
|
|
|
|
const reqPlan: Plan.ReqPlan = {
|
|
|
|
|
|
pattern: patternId, // 模式ID
|
|
|
|
|
|
datasourceIds: '',
|
|
|
|
|
|
sourceIds: '',
|
|
|
|
|
|
planId: '',
|
|
|
|
|
|
scriptName: '',
|
|
|
|
|
|
errorSysName: '',
|
|
|
|
|
|
sourceName: '',
|
|
|
|
|
|
devIds: [],
|
|
|
|
|
|
id: '',
|
|
|
|
|
|
name: '',
|
|
|
|
|
|
dataSourceId: '',
|
|
|
|
|
|
scriptId: '',
|
|
|
|
|
|
errorSysId: '',
|
|
|
|
|
|
timeCheck: 0,
|
|
|
|
|
|
testState: 0,
|
|
|
|
|
|
reportState: 0,
|
|
|
|
|
|
result: 0,
|
|
|
|
|
|
code: 0,
|
|
|
|
|
|
state: 0,
|
|
|
|
|
|
standardDevNameStr: '',
|
|
|
|
|
|
associateReport: 0,
|
|
|
|
|
|
reportTemplateName: '',
|
|
|
|
|
|
reportTemplateVersion: '',
|
|
|
|
|
|
dataRule: '',
|
|
|
|
|
|
testItemNameStr: '',
|
|
|
|
|
|
testItems: [],
|
|
|
|
|
|
standardDevIds: [],
|
|
|
|
|
|
standardDevMap: new Map<string, number>()
|
2025-08-06 19:53:22 +08:00
|
|
|
|
}
|
2025-10-10 15:29:54 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取计划数据
|
|
|
|
|
|
const result = (await getPlanListByPattern(reqPlan)) as ResultData<Plan.ReqPlan[]>
|
|
|
|
|
|
planList2.value = result.data || []
|
|
|
|
|
|
|
|
|
|
|
|
// 创建计划数据的副本用于过滤处理
|
|
|
|
|
|
planList.value = JSON.parse(JSON.stringify(planList2.value))
|
|
|
|
|
|
|
|
|
|
|
|
// 过滤子计划,只保留 pid 为 '0' 的项目
|
|
|
|
|
|
planList.value = planList.value.map((item: any) => {
|
|
|
|
|
|
if (item?.children) {
|
|
|
|
|
|
item.children = item.children.filter((child: any) => child?.pid === '0')
|
|
|
|
|
|
}
|
|
|
|
|
|
return item
|
|
|
|
|
|
})
|
2025-01-16 14:24:55 +08:00
|
|
|
|
}
|
2024-12-20 10:19:58 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
// ============================ 生命周期函数 ============================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 组件挂载前的初始化操作
|
|
|
|
|
|
* 1. 初始化计划数据
|
|
|
|
|
|
* 2. 设置默认选中的计划
|
|
|
|
|
|
* 3. 初始化图表和树组件
|
|
|
|
|
|
* 4. 根据模式加载额外数据
|
|
|
|
|
|
*/
|
2025-01-16 14:24:55 +08:00
|
|
|
|
onBeforeMount(async () => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
// 初始化计划数据
|
|
|
|
|
|
await initPlan()
|
|
|
|
|
|
|
|
|
|
|
|
// 找到第一个有子计划的项目,并设置为默认选中
|
|
|
|
|
|
if (planList.value?.length) {
|
|
|
|
|
|
for (let i = 0; i < planList.value.length; i++) {
|
|
|
|
|
|
const children = planList.value[i]?.children
|
|
|
|
|
|
if (Array.isArray(children) && children.length > 0) {
|
|
|
|
|
|
currentId.value = children[0]?.id // 选中第一个子计划
|
|
|
|
|
|
break // 确保只选中一个
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化图表尺寸监听器
|
|
|
|
|
|
if (chartsInfoRef.value) {
|
|
|
|
|
|
resizeObserver.observe(chartsInfoRef.value)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化树组件和饼图数据
|
|
|
|
|
|
getTree(planList.value || [])
|
|
|
|
|
|
getPieData(currentId.value)
|
|
|
|
|
|
|
|
|
|
|
|
// 如果不是比对模式,直接返回
|
|
|
|
|
|
if (modeStore.currentMode != '比对式') return
|
|
|
|
|
|
|
|
|
|
|
|
// 比对模式下加载额外的计划表格数据
|
|
|
|
|
|
const patternId2 = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id
|
|
|
|
|
|
if (patternId2 !== undefined) {
|
|
|
|
|
|
planTable.value = await getPlanList({ patternId: patternId2 })
|
2025-01-14 15:14:37 +08:00
|
|
|
|
}
|
2025-01-06 14:07:21 +08:00
|
|
|
|
})
|
2024-12-03 17:13:47 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 组件卸载时的清理操作
|
|
|
|
|
|
* 移除尺寸监听器,防止内存泄漏
|
|
|
|
|
|
*/
|
2025-08-06 15:18:27 +08:00
|
|
|
|
onUnmounted(async () => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
if (chartsInfoRef.value) {
|
|
|
|
|
|
resizeObserver.unobserve(chartsInfoRef.value)
|
|
|
|
|
|
}
|
2025-01-06 14:07:21 +08:00
|
|
|
|
})
|
2024-12-13 16:35:27 +08:00
|
|
|
|
|
2025-08-06 19:53:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 处理批量操作完成后的数据更新
|
|
|
|
|
|
* 更新计划数据、树状态和饼图,表格会通过watch自动更新
|
|
|
|
|
|
*/
|
2025-01-16 14:24:55 +08:00
|
|
|
|
const handleBatchGenerate = async () => {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
// 重新获取计划数据
|
|
|
|
|
|
await initPlan()
|
|
|
|
|
|
// 更新树的选中状态
|
|
|
|
|
|
treeRef.value.clickTableToTree(planList.value || [], currentId.value)
|
|
|
|
|
|
// 重新获取饼图数据,deviceData更新后watch会自动触发表格更新
|
|
|
|
|
|
getPieData(currentId.value)
|
|
|
|
|
|
|
|
|
|
|
|
// 批量操作后的表格刷新 - 这个调用与watch监听器无关,是通过emit触发的
|
|
|
|
|
|
tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs)
|
2025-08-06 19:53:22 +08:00
|
|
|
|
}
|
2024-08-23 13:19:20 +08:00
|
|
|
|
</script>
|
2025-10-10 15:29:54 +08:00
|
|
|
|
<style lang="scss" scoped>
|
2024-08-23 13:19:20 +08:00
|
|
|
|
.static {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.left_tree {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
}
|
2024-09-02 16:10:33 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.right_container {
|
2024-09-02 16:10:33 +08:00
|
|
|
|
flex: none;
|
2025-10-10 15:29:54 +08:00
|
|
|
|
height: 100%;
|
2024-08-27 16:06:16 +08:00
|
|
|
|
display: flex;
|
2024-11-29 13:45:48 +08:00
|
|
|
|
flex-direction: column;
|
2025-10-10 15:29:54 +08:00
|
|
|
|
|
|
|
|
|
|
.container_function {
|
|
|
|
|
|
width: 100%;
|
2024-09-02 16:10:33 +08:00
|
|
|
|
height: auto;
|
2025-10-10 15:29:54 +08:00
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
padding: 10px 20px 10px 20px;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
|
|
|
|
.function_item {
|
|
|
|
|
|
flex: none;
|
|
|
|
|
|
width: 6%;
|
|
|
|
|
|
height: 70px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
background-color: #607eab;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
padding: 0px 30px;
|
|
|
|
|
|
margin-right: 50px;
|
|
|
|
|
|
|
|
|
|
|
|
.item_img {
|
|
|
|
|
|
width: 60px;
|
|
|
|
|
|
height: 60px;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
// background-color: #607eab;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
|
width: 40px;
|
|
|
|
|
|
height: auto;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.item_img:nth-child(3),
|
|
|
|
|
|
.item_img:nth-child(6) {
|
|
|
|
|
|
padding: 10px !important;
|
|
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
|
width: 20px !important;
|
|
|
|
|
|
height: auto;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.item_text {
|
|
|
|
|
|
p {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-family: 'Microsoft YaHei', '微软雅黑', 'Arial', sans-serif;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.function_item:hover,
|
|
|
|
|
|
.checked_function {
|
|
|
|
|
|
background-color: var(--el-color-primary);
|
|
|
|
|
|
|
|
|
|
|
|
.item_img {
|
|
|
|
|
|
// background-color: var(--el-color-primary);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.item_text {
|
|
|
|
|
|
p {
|
|
|
|
|
|
// color: var(--el-color-primary);
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-02 16:10:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.container_pieShow {
|
|
|
|
|
|
width: 100% !important;
|
2024-09-02 16:10:33 +08:00
|
|
|
|
height: auto;
|
2025-10-10 15:29:54 +08:00
|
|
|
|
background-color: #eee;
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
|
|
|
|
|
|
.container_pieShow_title {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
padding: 0 15px;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
width: 99%;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
2024-08-27 14:01:26 +08:00
|
|
|
|
}
|
2024-09-02 16:10:33 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.el-collapse {
|
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
|
height: 100% !important;
|
|
|
|
|
|
background-color: #eee;
|
2024-09-02 16:10:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.el-collapse-item {
|
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
|
height: 100% !important;
|
|
|
|
|
|
background-color: #eee;
|
2024-09-02 16:10:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.container_charts {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
background-color: #eee;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
|
|
|
|
.charts_info {
|
|
|
|
|
|
margin-top: 1px;
|
|
|
|
|
|
flex: none;
|
|
|
|
|
|
width: 33.1%;
|
|
|
|
|
|
height: 100% !important;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
}
|
2024-08-27 14:01:26 +08:00
|
|
|
|
}
|
2024-11-12 20:35:12 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.el-tabs {
|
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
2025-01-06 14:07:21 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.tabs-menu {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
border: 0;
|
|
|
|
|
|
}
|
2024-12-20 10:19:58 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
.container_table {
|
|
|
|
|
|
// width: 100%;
|
|
|
|
|
|
flex: 1 !important;
|
|
|
|
|
|
//height: calc(100vh - 360px - 180px);
|
|
|
|
|
|
height: 100% !important;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
|
// display: none;
|
|
|
|
|
|
.table_info {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-08-23 13:19:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-20 10:19:58 +08:00
|
|
|
|
|
|
|
|
|
|
:deep(.el-collapse-item__header) {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
color: var(--el-color-primary);
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-family: 'Microsoft YaHei', '微软雅黑', 'Arial', sans-serif;
|
2024-12-11 17:46:59 +08:00
|
|
|
|
}
|
2024-12-20 10:19:58 +08:00
|
|
|
|
|
|
|
|
|
|
:deep(.el-collapse-item__conten) {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
padding-bottom: 0px !important;
|
2024-12-05 11:07:54 +08:00
|
|
|
|
}
|
2024-12-20 10:19:58 +08:00
|
|
|
|
|
2025-10-10 15:29:54 +08:00
|
|
|
|
:deep(.el-collapse-item__content) {
|
|
|
|
|
|
padding-bottom: 0px !important;
|
2024-12-05 11:07:54 +08:00
|
|
|
|
}
|
2025-01-06 14:07:21 +08:00
|
|
|
|
|
|
|
|
|
|
:deep(.el-tabs--border-card > .el-tabs__content) {
|
2025-10-10 15:29:54 +08:00
|
|
|
|
padding: 0 !important;
|
2025-01-06 14:07:21 +08:00
|
|
|
|
}
|
2024-08-23 13:19:20 +08:00
|
|
|
|
</style>
|