From 224248b6ff6baea525c324b2b80db78d00fbcf30 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期三, 21 一月 2026 09:40:51 +0800
Subject: [PATCH] feat: 质量管理-报表管理后端接口数据对接
---
src/views/reportAnalysis/reportManagement/index.vue | 2317 +++++++++++++++++++++++++++++----------------------------
src/api/reportAnalysis/qualityReport.js | 52 +
2 files changed, 1,245 insertions(+), 1,124 deletions(-)
diff --git a/src/api/reportAnalysis/qualityReport.js b/src/api/reportAnalysis/qualityReport.js
new file mode 100644
index 0000000..a179a5f
--- /dev/null
+++ b/src/api/reportAnalysis/qualityReport.js
@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 鑾峰彇鍚勭被鍨嬪畬鎴愭暟閲�
+export function getInspectStatistics() {
+ return request({
+ url: '/qualityReport/getInspectStatistics',
+ method: 'get'
+ })
+}
+
+// 鑾峰彇璐ㄦ鍚堟牸鐜囩粺璁�
+export function getPassRateStatistics() {
+ return request({
+ url: '/qualityReport/getPassRateStatistics',
+ method: 'get'
+ })
+}
+
+// 鑾峰彇鏈堝害鍚堟牸鐜囩粺璁℃暟鎹�
+export function getMonthlyPassRateStatistics(year) {
+ return request({
+ url: '/qualityReport/getMonthlyPassRateStatistics',
+ method: 'get',
+ params: { year }
+ })
+}
+
+// 鑾峰彇骞村害鎬诲悎鏍肩巼缁熻鏁版嵁
+export function getYearlyPassRateStatistics(year) {
+ return request({
+ url: '/qualityReport/getYearlyPassRateStatistics',
+ method: 'get',
+ params: { year }
+ })
+}
+// 鑾峰彇鏈堝害瀹屾垚鏄庣粏鏁版嵁
+export function getMonthlyCompletionDetails(year) {
+ return request({
+ url: '/qualityReport/getMonthlyCompletionDetails',
+ method: 'get',
+ params: { year }
+ })
+}
+
+// 鑾峰彇鐑偣妫�娴嬫寚鏍囩粺璁�
+export function getTopParameters(inspectType) {
+ return request({
+ url: '/qualityReport/getTopParameters',
+ method: 'get',
+ params: { inspectType }
+ })
+}
diff --git a/src/views/reportAnalysis/reportManagement/index.vue b/src/views/reportAnalysis/reportManagement/index.vue
index 4c73f7f..343a2c2 100644
--- a/src/views/reportAnalysis/reportManagement/index.vue
+++ b/src/views/reportAnalysis/reportManagement/index.vue
@@ -5,8 +5,7 @@
<el-row :gutter="20">
<!-- 鍚勭被鍨嬪畬鎴愭暟閲� -->
<el-col :span="9">
- <el-card class="chart-card"
- shadow="hover">
+ <el-card class="chart-card" shadow="hover">
<template #header>
<div class="card-header">
<div class="chart-title-line"></div>
@@ -16,9 +15,8 @@
<div class="top-container">
<div class="typeNum">
<div class="typeNum-left">
- <img src="~@/assets/images/chartCard.svg"
- alt="鍥捐〃"
- style="width: 40px; height: 40px; object-fit: contain;">
+ <img src="~@/assets/images/chartCard.svg" alt="鍥捐〃"
+ style="width: 40px; height: 40px; object-fit: contain;">
<div class="typeNum-left-text">鍘熸潗鏂�</div>
</div>
<div class="typeNum-center">
@@ -28,21 +26,22 @@
<div class="typeNum-right">
<div class="typeNum-right-top">
<div class="typeNum-right-top-name">鎬绘暟閲�</div>
- <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ <div class="typeNum-right-top-text">{{ getInspectStatValue(0, 'totalCount') }} <span
+ class="unit">涓�</span></div>
</div>
<div class="typeNum-right-bottom">
<div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
- <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ <div class="typeNum-right-top-text">{{ getInspectStatValue(0, 'completedCount') }} <span
+ class="unit">涓�</span>
+ </div>
</div>
</div>
</div>
<div class="typeNum">
<div class="typeNum-left">
- <img src="~@/assets/images/chartCard2.svg"
- alt="鍥捐〃"
- style="width: 40px; height: 40px; object-fit: contain;">
- <div class="typeNum-left-text"
- style="color: #5EB334;">鍗婃垚鍝�</div>
+ <img src="~@/assets/images/chartCard2.svg" alt="鍥捐〃"
+ style="width: 40px; height: 40px; object-fit: contain;">
+ <div class="typeNum-left-text" style="color: #5EB334;">鍗婃垚鍝�</div>
</div>
<div class="typeNum-center">
<div class="typeNum-leftLine2">-</div>
@@ -51,21 +50,22 @@
<div class="typeNum-right">
<div class="typeNum-right-top">
<div class="typeNum-right-top-name">鎬绘暟閲�</div>
- <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ <div class="typeNum-right-top-text">{{ getInspectStatValue(1, 'totalCount') }} <span
+ class="unit">涓�</span></div>
</div>
<div class="typeNum-right-bottom">
<div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
- <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ <div class="typeNum-right-top-text">{{ getInspectStatValue(1, 'completedCount') }} <span
+ class="unit">涓�</span>
+ </div>
</div>
</div>
</div>
<div class="typeNum">
<div class="typeNum-left">
- <img src="~@/assets/images/chartCard3.svg"
- alt="鍥捐〃"
- style="width: 40px; height: 40px; object-fit: contain;">
- <div class="typeNum-left-text"
- style="color: #8000FF;">鎴愬搧</div>
+ <img src="~@/assets/images/chartCard3.svg" alt="鍥捐〃"
+ style="width: 40px; height: 40px; object-fit: contain;">
+ <div class="typeNum-left-text" style="color: #8000FF;">鎴愬搧</div>
</div>
<div class="typeNum-center">
<div class="typeNum-leftLine3">-</div>
@@ -74,11 +74,14 @@
<div class="typeNum-right">
<div class="typeNum-right-top">
<div class="typeNum-right-top-name">鎬绘暟閲�</div>
- <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ <div class="typeNum-right-top-text">{{ getInspectStatValue(2, 'totalCount') }} <span
+ class="unit">涓�</span></div>
</div>
<div class="typeNum-right-bottom">
<div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
- <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ <div class="typeNum-right-top-text">{{ getInspectStatValue(2, 'completedCount') }} <span
+ class="unit">涓�</span>
+ </div>
</div>
</div>
</div>
@@ -87,8 +90,7 @@
</el-col>
<!-- 璐ㄦ鍚堟牸鐜� -->
<el-col :span="15">
- <el-card class="chart-card"
- shadow="hover">
+ <el-card class="chart-card" shadow="hover">
<template #header>
<div class="card-header">
<div class="chart-title-line"></div>
@@ -98,9 +100,8 @@
<div class="top-container flex-center">
<div class="quality-card blue-card">
<div class="quality-card-title">
- <img src="~@/assets/images/chartCard.svg"
- alt="鍘熸潗鏂�"
- style="width: 24px; height: 24px; margin-right: 8px;">
+ <img src="~@/assets/images/chartCard.svg" alt="鍘熸潗鏂�"
+ style="width: 24px; height: 24px; margin-right: 8px;">
鍘熸潗鏂欏悎鏍肩巼
</div>
<div class="quality-card-content">
@@ -108,27 +109,24 @@
<div>
<div class="quality-item-label blue-label">瀹屾垚鐜�</div>
<div class="quality-item-tip">鍗犳瘮</div>
- <div class="quality-item-value">80%</div>
+ <div class="quality-item-value">{{ getPassRateStatValue(0, 'completionRate') }}</div>
</div>
- <div class="quality-item-chart"
- ref="materialCompletionChart"></div>
+ <div class="quality-item-chart" ref="materialCompletionChart"></div>
</div>
<div class="quality-item">
<div>
<div class="quality-item-label green-label">鍚堟牸鐜�</div>
<div class="quality-item-tip">鍗犳瘮</div>
- <div class="quality-item-value">80%</div>
+ <div class="quality-item-value">{{ getPassRateStatValue(0, 'passRate') }}</div>
</div>
- <div class="quality-item-chart"
- ref="materialQualityChart"></div>
+ <div class="quality-item-chart" ref="materialQualityChart"></div>
</div>
</div>
</div>
<div class="quality-card green-card">
<div class="quality-card-title">
- <img src="~@/assets/images/chartCard2.svg"
- alt="鍗婃垚鍝�"
- style="width: 24px; height: 24px; margin-right: 8px;">
+ <img src="~@/assets/images/chartCard2.svg" alt="鍗婃垚鍝�"
+ style="width: 24px; height: 24px; margin-right: 8px;">
鍗婃垚鍝佸悎鏍肩巼
</div>
<div class="quality-card-content">
@@ -136,27 +134,24 @@
<div>
<div class="quality-item-label blue-label">瀹屾垚鐜�</div>
<div class="quality-item-tip">鍗犳瘮</div>
- <div class="quality-item-value">80%</div>
+ <div class="quality-item-value">{{ getPassRateStatValue(1, 'completionRate') }}</div>
</div>
- <div class="quality-item-chart"
- ref="semiCompletionChart"></div>
+ <div class="quality-item-chart" ref="semiCompletionChart"></div>
</div>
<div class="quality-item">
<div>
<div class="quality-item-label green-label">鍚堟牸鐜�</div>
<div class="quality-item-tip">鍗犳瘮</div>
- <div class="quality-item-value">80%</div>
+ <div class="quality-item-value">{{ getPassRateStatValue(1, 'passRate') }}</div>
</div>
- <div class="quality-item-chart"
- ref="semiQualityChart"></div>
+ <div class="quality-item-chart" ref="semiQualityChart"></div>
</div>
</div>
</div>
<div class="quality-card purple-card">
<div class="quality-card-title">
- <img src="~@/assets/images/chartCard3.svg"
- alt="鎴愬搧"
- style="width: 24px; height: 24px; margin-right: 8px;">
+ <img src="~@/assets/images/chartCard3.svg" alt="鎴愬搧"
+ style="width: 24px; height: 24px; margin-right: 8px;">
鎴愬搧鍚堟牸鐜�
</div>
<div class="quality-card-content">
@@ -164,19 +159,17 @@
<div>
<div class="quality-item-label blue-label">瀹屾垚鐜�</div>
<div class="quality-item-tip">鍗犳瘮</div>
- <div class="quality-item-value">80%</div>
+ <div class="quality-item-value">{{ getPassRateStatValue(2, 'completionRate') }}</div>
</div>
- <div class="quality-item-chart"
- ref="finalCompletionChart"></div>
+ <div class="quality-item-chart" ref="finalCompletionChart"></div>
</div>
<div class="quality-item">
<div>
<div class="quality-item-label green-label">鍚堟牸鐜�</div>
<div class="quality-item-tip">鍗犳瘮</div>
- <div class="quality-item-value">80%</div>
+ <div class="quality-item-value">{{ getPassRateStatValue(2, 'passRate') }}</div>
</div>
- <div class="quality-item-chart"
- ref="finalQualityChart"></div>
+ <div class="quality-item-chart" ref="finalQualityChart"></div>
</div>
</div>
</div>
@@ -189,8 +182,7 @@
<el-row :gutter="20">
<!-- 璐ㄦ鍚堟牸鐜� -->
<el-col :span="24">
- <el-card class="chart-card"
- shadow="hover">
+ <el-card class="chart-card" shadow="hover">
<template #header>
<div class="card-header">
<div class="chart-title-line"></div>
@@ -199,26 +191,24 @@
</template>
<div class="chart-container-line">
<div class="container-line-left">
- <div style="height: 100%; width: 100%;"
- ref="usageChartRef">
+ <div style="height: 100%; width: 100%;" ref="usageChartRef">
</div>
</div>
<div class="container-line-right">
- <div style="height: 80%; width: 100%;"
- ref="inspectionChartRef">
+ <div style="height: 80%; width: 100%;" ref="inspectionChartRef">
</div>
<div class="container-line-right-bottom">
<div class="inspection-chart-box">
- <div class="chart-box-title">鍘熸潗鏂欐娊妫�鏁�</div>
- <div class="chart-box-num">600</div>
+ <div class="chart-box-title">鍘熸潗鏂欐�绘暟</div>
+ <div class="chart-box-num">{{ getYearlyStatValue(0, 'totalCount') }}</div>
</div>
<div class="inspection-chart-box">
- <div class="chart-box-title">鍗婃垚鍝佹娊妫�鏁�</div>
- <div class="chart-box-num">200</div>
+ <div class="chart-box-title">鍗婃垚鍝佹�绘暟</div>
+ <div class="chart-box-num">{{ getYearlyStatValue(1, 'totalCount') }}</div>
</div>
<div class="inspection-chart-box">
- <div class="chart-box-title">鎴愬搧鎶芥鏁�</div>
- <div class="chart-box-num">200</div>
+ <div class="chart-box-title">鎴愬搧鎬绘暟</div>
+ <div class="chart-box-num">{{ getYearlyStatValue(2, 'totalCount') }}</div>
</div>
</div>
</div>
@@ -228,13 +218,8 @@
class="chart-container"></div> -->
<div class="yearchange">
<div style="margin-right: 8px;font-size: 14px;">骞翠唤:</div>
- <el-date-picker v-model="value3"
- size="mini"
- :clearable="false"
- style="width: 60px;"
- type="year"
- :disabled-date="disabledDate"
- placeholder="">
+ <el-date-picker v-model="value3" size="mini" :clearable="false" style="width: 60px;" type="year"
+ :disabled-date="disabledDate" placeholder="">
</el-date-picker>
</div>
</el-card>
@@ -245,22 +230,19 @@
<el-row :gutter="20">
<!-- 鏍峰搧杩涘害鍥捐〃 -->
<el-col :span="12">
- <el-card class="chart-card"
- shadow="hover">
+ <el-card class="chart-card" shadow="hover">
<template #header>
<div class="card-header">
<div class="chart-title-line"></div>
<span>璐ㄩ噺瀹屾垚鏄庣粏</span>
</div>
</template>
- <div ref="equipmentChartRef"
- class="chart-container"></div>
+ <div ref="equipmentChartRef" class="chart-container"></div>
</el-card>
</el-col>
<!-- 璁惧浣跨敤鍥捐〃 -->
<el-col :span="12">
- <el-card class="chart-card"
- shadow="hover">
+ <el-card class="chart-card" shadow="hover">
<template #header>
<div class="card-header">
<div class="chart-title-line"></div>
@@ -271,58 +253,21 @@
<div class="container-line2-left">
<div class="info-box">
<div class="info-box-header">椤圭洰鍒嗗竷</div>
- <div class="info-line">
- <div class="info-icon"
- style="background-color: #165DFF"></div>
- <div class="info-line-title">鐗╃悊鎬ц兘</div>
- <div class="info-line-value1">30%</div>
- <div class="info-line-value2">300</div>
- </div>
- <div class="info-line">
- <div class="info-icon"
- style="background-color: #14C9C9;"></div>
- <div class="info-line-title">鐗╃悊鎬ц兘</div>
- <div class="info-line-value1">30%</div>
- <div class="info-line-value2">300</div>
- </div>
- <div class="info-line">
- <div class="info-icon"
- style="background-color: #F7BA1E;"></div>
- <div class="info-line-title">鐗╃悊鎬ц兘</div>
- <div class="info-line-value1">30%</div>
- <div class="info-line-value2">300</div>
- </div>
- <div class="info-line">
- <div class="info-icon"
- style="background-color: #722ED1;"></div>
- <div class="info-line-title">鐗╃悊鎬ц兘</div>
- <div class="info-line-value1">30%</div>
- <div class="info-line-value2">300</div>
- </div>
- <div class="info-line">
- <div class="info-icon"
- style="background-color: #3491FA;"></div>
- <div class="info-line-title">鐗╃悊鎬ц兘</div>
- <div class="info-line-value1">30%</div>
- <div class="info-line-value2">300</div>
+ <div class="info-line" v-for="(item, index) in topParametersData.list" :key="index">
+ <div class="info-icon" :style="{ backgroundColor: getParameterColor(index) }"></div>
+ <div class="info-line-title">{{ item.name }}</div>
+ <div class="info-line-value1">{{ item.percentage }}%</div>
+ <div class="info-line-value2">{{ item.count }}</div>
</div>
</div>
</div>
- <div ref="sampleChartRef"
- style="height: 100%; width: 50%;"
- class="chart-container"></div>
+ <div ref="sampleChartRef" style="height: 100%; width: 50%;" class="chart-container"></div>
</div>
<!-- Tab 閫夋嫨鍣� -->
<div class="tab-selector">
- <div class="tab-item"
- :class="{ active: activeTab === 'raw' }"
- @click="activeTab = 'raw'">鍘熸潗鏂�</div>
- <div class="tab-item"
- :class="{ active: activeTab === 'semi' }"
- @click="activeTab = 'semi'">鍗婃垚鍝�</div>
- <div class="tab-item"
- :class="{ active: activeTab === 'final' }"
- @click="activeTab = 'final'">鎴愬搧</div>
+ <div class="tab-item" :class="{ active: activeTab === 'raw' }" @click="activeTab = 'raw'">鍘熸潗鏂�</div>
+ <div class="tab-item" :class="{ active: activeTab === 'semi' }" @click="activeTab = 'semi'">鍗婃垚鍝�</div>
+ <div class="tab-item" :class="{ active: activeTab === 'final' }" @click="activeTab = 'final'">鎴愬搧</div>
</div>
</el-card>
</el-col>
@@ -332,1071 +277,1195 @@
</template>
<script setup>
- import { ref, reactive, onMounted, nextTick } from "vue";
- import { ElMessage, ElMessageBox } from "element-plus";
- import * as echarts from "echarts";
- import { Box, Tools, Document, ShoppingCart } from "@element-plus/icons-vue";
+import { ref, reactive, onMounted, nextTick } from "vue";
+import { ElMessage } from "element-plus";
+import * as echarts from "echarts";
+import { getInspectStatistics, getPassRateStatistics, getMonthlyPassRateStatistics, getYearlyPassRateStatistics, getMonthlyCompletionDetails, getTopParameters } from "@/api/reportAnalysis/qualityReport";
- // 鍝嶅簲寮忔暟鎹�
- const filterForm = reactive({
- dateRange: [],
- reportType: "sample",
- });
+// 鍝嶅簲寮忔暟鎹�
+const filterForm = reactive({
+ dateRange: [],
+ reportType: "sample",
+});
- const statistics = reactive({
- totalSamples: 1250,
- activeEquipment: 45,
- completedInspections: 890,
- totalUsage: 2340,
- });
+const inspectStatisticsData = ref([]);
+const passRateStatisticsData = ref([]);
+const monthlyPassRateData = ref([]);
+const yearlyPassRateData = ref([]);
+const monthlyCompletionDetailsData = ref([]);
+const topParametersData = ref({ totalCount: 0, list: [] });
+const activeTab = ref("raw");
- const tableData = ref([]);
- const tableLoading = ref(false);
- const pagination = reactive({
- currentPage: 1,
- pageSize: 20,
- total: 0,
- });
+const getParameterColor = (index) => {
+ const colors = ['#165DFF', '#14C9C9', '#F7BA1E', '#722ED1', '#3491FA', '#FF7D00', '#F53F3F'];
+ return colors[index % colors.length];
+};
- // 鍒濆鍖栧勾浠戒负褰撳墠骞翠唤锛堜娇鐢―ate瀵硅薄锛�
- const currentYear = new Date().getFullYear();
- const value3 = ref(new Date(currentYear, 0, 1));
+const getYearlyStatValue = (type, field) => {
+ const stat = yearlyPassRateData.value.find(item => item.inspectType === type);
+ return stat ? stat[field] : 0;
+};
- // 闄愬埗鏃ユ湡閫夋嫨锛屼笉鍏佽閫夋嫨浠婂勾涔嬪悗鐨勫勾浠�
- const disabledDate = time => {
- const currentYear = new Date().getFullYear();
- return time.getFullYear() > currentYear;
- };
+const getInspectStatValue = (type, field) => {
+ const stat = inspectStatisticsData.value.find(item => item.inspectType === type);
+ return stat ? stat[field] : 0;
+};
- // Tab 閫夋嫨鍣ㄥ綋鍓嶆縺娲婚」
- const activeTab = ref("raw");
-
- // 鍥捐〃寮曠敤
- const sampleChartRef = ref(null);
- const equipmentChartRef = ref(null);
- const inspectionChartRef = ref(null);
- const usageChartRef = ref(null);
-
- // 璐ㄦ鍚堟牸鐜囧浘琛ㄥ紩鐢�
- const materialCompletionChart = ref(null);
- const materialQualityChart = ref(null);
- const semiCompletionChart = ref(null);
- const semiQualityChart = ref(null);
- const finalCompletionChart = ref(null);
- const finalQualityChart = ref(null);
-
- // 鍥捐〃瀹炰緥
- let sampleChart = null;
- let equipmentChart = null;
- let inspectionChart = null;
- let usageChart = null;
-
- // 璐ㄦ鍚堟牸鐜囧浘琛ㄥ疄渚�
- let materialCompletionChartInstance = null;
- let materialQualityChartInstance = null;
- let semiCompletionChartInstance = null;
- let semiQualityChartInstance = null;
- let finalCompletionChartInstance = null;
- let finalQualityChartInstance = null;
-
- // 鍒濆鍖栨暟鎹�
- const initData = () => {
- // 妯℃嫙琛ㄦ牸鏁版嵁
- tableData.value = [
- {
- id: "SP001",
- name: "鏍峰搧A-001",
- type: "閲戝睘鏉愭枡",
- status: "妫�娴嬩腑",
- progress: 75,
- createTime: "2025-01-15 09:30:00",
- updateTime: "2025-01-20 14:20:00",
- },
- {
- id: "SP002",
- name: "鏍峰搧B-002",
- type: "濉戞枡鍒跺搧",
- status: "宸插畬鎴�",
- progress: 100,
- createTime: "2025-01-10 10:15:00",
- updateTime: "2025-01-18 16:45:00",
- },
- {
- id: "SP003",
- name: "鏍峰搧C-003",
- type: "鐢靛瓙鍏冧欢",
- status: "寰呮娴�",
- progress: 0,
- createTime: "2025-01-22 08:45:00",
- updateTime: "2025-01-22 08:45:00",
- },
- {
- id: "EQ001",
- name: "妫�娴嬭澶嘇",
- type: "鍘熸潗鏂�",
- status: "浣跨敤涓�",
- progress: 60,
- createTime: "2025-01-05 14:20:00",
- updateTime: "2025-01-20 11:30:00",
- },
- {
- id: "EQ002",
- name: "妫�娴嬭澶嘊",
- type: "鍗婃垚鍝�",
- status: "绌洪棽",
- progress: 0,
- createTime: "2025-01-08 16:10:00",
- updateTime: "2025-01-19 09:15:00",
- },
- ];
-
- pagination.total = tableData.value.length;
- };
-
- // 鍒濆鍖栨牱鍝佽繘搴﹀浘琛�
- const initSampleChart = () => {
- if (sampleChartRef.value) {
- sampleChart = echarts.init(sampleChartRef.value);
- const option = {
- title: {
- show: false,
- },
- tooltip: {
- trigger: "item",
- formatter: "{a} <br/>{b}: {c} ({d}%)",
- },
- // legend: {
- // orient: "vertical",
- // left: "left",
- // },
- series: [
- {
- name: "鏍峰搧鐘舵��",
- type: "pie",
- radius: ["40%", "80%"],
- avoidLabelOverlap: false,
- label: {
- show: false,
- position: "center",
- },
- emphasis: {
- label: {
- show: true,
- fontSize: "18",
- fontWeight: "bold",
- },
- },
- labelLine: {
- show: false,
- },
- data: [
- { value: 450, name: "宸插畬鎴�" },
- { value: 320, name: "妫�娴嬩腑" },
- { value: 280, name: "寰呮娴�" },
- { value: 200, name: "宸叉殏鍋�" },
- ],
- },
- ],
- };
- sampleChart.setOption(option);
+const getPassRateStatValue = (type, field) => {
+ const stat = passRateStatisticsData.value.find(item => item.inspectType === type);
+ if (stat) {
+ if (field === 'completionRate' || field === 'passRate') {
+ return stat[field] ? Number(stat[field]).toFixed(0) + '%' : '0%';
}
- };
+ return stat[field];
+ }
+ return field === 'completionRate' || field === 'passRate' ? '0%' : 0;
+};
- // 鍒濆鍖栬澶囦娇鐢ㄥ浘琛�
- const initEquipmentChart = () => {
- if (equipmentChartRef.value) {
- equipmentChart = echarts.init(equipmentChartRef.value);
- const option = {
- title: {
- show: false,
- },
- tooltip: {
- trigger: "axis",
- axisPointer: {
- type: "shadow",
- },
- },
- grid: {
- left: "1%",
- right: "1%",
- bottom: "1%",
- containLabel: true,
- },
- legend: {
- data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
- icon: ["circle", "circle", "circle"],
- itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
- itemHeight: 10,
- itemGap: 30,
- right: 10,
- },
- xAxis: {
- type: "category",
- data: [
- value3.value.getFullYear() + "-1",
- value3.value.getFullYear() + "-2",
- value3.value.getFullYear() + "-3",
- value3.value.getFullYear() + "-4",
- value3.value.getFullYear() + "-5",
- value3.value.getFullYear() + "-6",
- value3.value.getFullYear() + "-7",
- value3.value.getFullYear() + "-8",
- value3.value.getFullYear() + "-9",
- value3.value.getFullYear() + "-10",
- value3.value.getFullYear() + "-11",
- value3.value.getFullYear() + "-12",
- ], // 鏀逛负鍗佷簩涓湀
- },
- yAxis: {
- type: "value",
- name: "鏁�(涓�)",
- },
- series: [
- {
- name: "鍘熸潗鏂�",
- type: "bar",
- barWidth: "15%",
- data: [85, 75, 80, 85, 90, 88, 92, 87, 89, 91, 93, 95],
- itemStyle: {
- color: "#409EFF",
- },
- },
- {
- name: "鍗婃垚鍝�",
- type: "bar",
- barWidth: "15%",
-
- data: [60, 65, 70, 68, 72, 75, 78, 80, 79, 82, 84, 85],
- itemStyle: {
- color: "#67C23A",
- },
- },
- {
- name: "鎴愬搧",
- type: "bar",
- barWidth: "15%",
-
- data: [75, 78, 80, 82, 85, 83, 86, 88, 87, 89, 90, 92],
- itemStyle: {
- color: "#E6A23C",
- },
- },
- ],
- };
- equipmentChart.setOption(option);
+const fetchInspectStatisticsData = async () => {
+ try {
+ const res = await getInspectStatistics();
+ if (res.code === 200) {
+ inspectStatisticsData.value = res.data;
}
- };
+ } catch (error) {
+ console.error("Failed to fetch inspect statistics:", error);
+ }
+};
- // 鍒濆鍖栨娴嬮」鐩浘琛�
- const initInspectionChart = () => {
- if (inspectionChartRef.value) {
- inspectionChart = echarts.init(inspectionChartRef.value);
- const option = {
- title: {
- show: false,
- },
- tooltip: {
- trigger: "item",
- },
- series: [
- {
- type: "pie",
- radius: "80%",
- data: [
- { value: 335, name: "鍘熸潗鏂�", itemStyle: { color: "#1890FF" } },
- { value: 310, name: "鍗婃垚鍝�", itemStyle: { color: "#F7BA1E" } },
- { value: 234, name: "鎴愬搧", itemStyle: { color: "#14C9C9" } },
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: "rgba(0, 0, 0, 0.5)",
- },
- },
- },
- ],
- };
- inspectionChart.setOption(option);
- }
- };
-
- // 鍒濆鍖栭鐢ㄨ褰曞浘琛�
- const initUsageChart = () => {
- // 妫�鏌ュ浘琛ㄥ鍣ㄦ槸鍚﹀瓨鍦�
- if (usageChartRef.value) {
- // 鍒濆鍖� ECharts 瀹炰緥
- usageChart = echarts.init(usageChartRef.value);
- // 閰嶇疆鍥捐〃閫夐」
- const option = {
- // 鏍囬閰嶇疆锛堥殣钘忥級
- title: {
- show: false,
- },
-
- // 缃戞牸閰嶇疆锛堣皟鏁磋竟璺濓級
- grid: {
- left: "1%",
- right: "4%",
- bottom: "3%",
- top: "14%",
- containLabel: true,
- },
- // 鎻愮ず妗嗛厤缃�
- tooltip: {
- trigger: "axis", // 瑙﹀彂绫诲瀷涓哄潗鏍囪酱瑙﹀彂
- },
- // 鍥句緥閰嶇疆
- legend: {
- data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
- icon: ["circle", "circle", "circle"],
- itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
- itemHeight: 10,
- itemGap: 30,
- },
- // X杞撮厤缃�
- xAxis: {
- type: "category", // 绫诲埆杞�
- boundaryGap: false, // 鍧愭爣杞翠袱杈圭暀鐧界瓥鐣�
- data: [
- value3.value.getFullYear() + "-1",
- value3.value.getFullYear() + "-2",
- value3.value.getFullYear() + "-3",
- value3.value.getFullYear() + "-4",
- value3.value.getFullYear() + "-5",
- value3.value.getFullYear() + "-6",
- value3.value.getFullYear() + "-7",
- value3.value.getFullYear() + "-8",
- value3.value.getFullYear() + "-9",
- value3.value.getFullYear() + "-10",
- value3.value.getFullYear() + "-11",
- value3.value.getFullYear() + "-12",
- ], // X杞存暟鎹�
- },
- // Y杞撮厤缃�
- yAxis: {
- type: "value", // 鏁板�艰酱
- name: "鍗曚綅锛�%",
- },
- // 绯诲垪鏁版嵁
- series: [
- {
- name: "鍘熸潗鏂�", // 绯诲垪鍚嶇О
- type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
- stack: "Total", // 鍫嗗彔鍚嶇О
- symbol: "none",
- itemStyle: {
- color: "#1890FF", // 璁剧疆杩欐潯绾跨殑棰滆壊
- },
- data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330], // 棰嗙敤娆℃暟鏁版嵁
- },
- {
- name: "鍗婃垚鍝�", // 绯诲垪鍚嶇О
- type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
- stack: "Total", // 鍫嗗彔鍚嶇О
- symbol: "none",
- itemStyle: {
- color: "#F7BA1E", // 璁剧疆杩欐潯绾跨殑棰滆壊
- },
- data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320], // 褰掕繕娆℃暟鏁版嵁
- },
- {
- name: "鎴愬搧", // 绯诲垪鍚嶇О
- type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
- stack: "Total", // 鍫嗗彔鍚嶇О
- symbol: "none",
- itemStyle: {
- color: "#14C9C9", // 璁剧疆杩欐潯绾跨殑棰滆壊
- },
- data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320], // 褰掕繕娆℃暟鏁版嵁
- },
- ],
- };
- // 灏嗛厤缃簲鐢ㄥ埌鍥捐〃
- usageChart.setOption(option);
- }
- };
-
- // 鍒濆鍖栬川妫�鍚堟牸鐜囧浘琛�
- const initQualityChart = (chartRef, color) => {
- if (chartRef.value) {
- const chart = echarts.init(chartRef.value);
- const option = {
- series: [
- {
- type: "pie",
- radius: ["45%", "90%"],
- itemStyle: {
- borderColor: "#f5f5f5",
- // borderWidth: 2,
- },
- labelLine: {
- show: false,
- },
- data: [
- { value: 0.8, itemStyle: { color: color } },
- { value: 0.2, itemStyle: { color: "#f5f5f5" } },
- ],
- },
- ],
- };
- chart.setOption(option);
- return chart;
- }
- return null;
- };
-
- // 鍒濆鍖栨墍鏈夎川妫�鍚堟牸鐜囧浘琛�
- const initAllQualityCharts = () => {
- materialCompletionChartInstance = initQualityChart(
- materialCompletionChart,
- "#1890ff"
- );
- materialQualityChartInstance = initQualityChart(
- materialQualityChart,
- "#52c41a"
- );
- semiCompletionChartInstance = initQualityChart(
- semiCompletionChart,
- "#1890ff"
- );
- semiQualityChartInstance = initQualityChart(semiQualityChart, "#52c41a");
- finalCompletionChartInstance = initQualityChart(
- finalCompletionChart,
- "#1890ff"
- );
- finalQualityChartInstance = initQualityChart(finalQualityChart, "#722ed1");
- };
-
- // 浜嬩欢澶勭悊鍑芥暟
- const handleFilterChange = () => {
- ElMessage.success("绛涢�夋潯浠跺凡鏇存柊");
- // 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
- };
-
- const resetFilter = () => {
- filterForm.dateRange = [];
- filterForm.reportType = "sample";
- ElMessage.info("绛涢�夋潯浠跺凡閲嶇疆");
- };
-
- const exportReport = () => {
- ElMessage.success("鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...");
- };
-
- const refreshSampleChart = () => {
- initSampleChart();
- ElMessage.success("鏍峰搧杩涘害鍥捐〃宸插埛鏂�");
- };
-
- const refreshEquipmentChart = () => {
- initEquipmentChart();
- ElMessage.success("璁惧浣跨敤鍥捐〃宸插埛鏂�");
- };
-
- const refreshInspectionChart = () => {
- initInspectionChart();
- ElMessage.success("妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊");
- };
-
- const refreshUsageChart = () => {
- initUsageChart();
- ElMessage.success("棰嗙敤璁板綍鍥捐〃宸插埛鏂�");
- };
-
- const refreshTable = () => {
- tableLoading.value = true;
- setTimeout(() => {
- tableLoading.value = false;
- ElMessage.success("琛ㄦ牸鏁版嵁宸插埛鏂�");
- }, 1000);
- };
-
- const exportTable = () => {
- ElMessage.success("琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...");
- };
-
- const handleSizeChange = val => {
- pagination.pageSize = val;
- // 閲嶆柊鍔犺浇鏁版嵁
- };
-
- const handleCurrentChange = val => {
- pagination.currentPage = val;
- // 閲嶆柊鍔犺浇鏁版嵁
- };
-
- const getStatusType = status => {
- const statusMap = {
- 宸插畬鎴�: "success",
- 妫�娴嬩腑: "warning",
- 寰呮娴�: "info",
- 宸叉殏鍋�: "danger",
- 浣跨敤涓�: "primary",
- 绌洪棽: "info",
- };
- return statusMap[status] || "info";
- };
-
- const getProgressStatus = progress => {
- if (progress === 100) return "success";
- if (progress >= 80) return "warning";
- if (progress >= 50) return "";
- return "exception";
- };
-
- const viewDetail = row => {
- ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`);
- };
-
- const editItem = row => {
- ElMessage.info(`缂栬緫椤圭洰: ${row.name}`);
- };
-
- // 鐢熷懡鍛ㄦ湡
- onMounted(() => {
- initData();
- nextTick(() => {
- initSampleChart();
- initEquipmentChart();
- initInspectionChart();
- initUsageChart();
+const fetchPassRateStatisticsData = async () => {
+ try {
+ const res = await getPassRateStatistics();
+ if (res.code === 200) {
+ passRateStatisticsData.value = res.data;
+ // 鏁版嵁鑾峰彇鍚庨噸鏂板垵濮嬪寲鍥捐〃
initAllQualityCharts();
- });
- // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
- window.addEventListener("resize", () => {
- sampleChart?.resize();
- equipmentChart?.resize();
- inspectionChart?.resize();
- usageChart?.resize();
+ }
+ } catch (error) {
+ console.error("Failed to fetch pass rate statistics:", error);
+ }
+};
- // 璋冩暣璐ㄦ鍚堟牸鐜囧浘琛ㄥぇ灏�
- materialCompletionChartInstance?.resize();
- materialQualityChartInstance?.resize();
- semiCompletionChartInstance?.resize();
- semiQualityChartInstance?.resize();
- finalCompletionChartInstance?.resize();
- finalQualityChartInstance?.resize();
- });
+const fetchMonthlyPassRateData = async () => {
+ try {
+ const year = value3.value.getFullYear().toString();
+ const res = await getMonthlyPassRateStatistics(year);
+ if (res.code === 200) {
+ monthlyPassRateData.value = res.data;
+ initUsageChart();
+ }
+ } catch (error) {
+ console.error("Failed to fetch monthly pass rate statistics:", error);
+ }
+};
+
+const fetchYearlyPassRateData = async () => {
+ try {
+ const year = value3.value.getFullYear().toString();
+ const res = await getYearlyPassRateStatistics(year);
+ if (res.code === 200) {
+ yearlyPassRateData.value = res.data;
+ initInspectionChart();
+ }
+ } catch (error) {
+ console.error("Failed to fetch yearly pass rate statistics:", error);
+ }
+};
+
+const fetchMonthlyCompletionDetailsData = async () => {
+ try {
+ const year = value3.value.getFullYear().toString();
+ const res = await getMonthlyCompletionDetails(year);
+ if (res.code === 200) {
+ monthlyCompletionDetailsData.value = res.data;
+ initEquipmentChart();
+ }
+ } catch (error) {
+ console.error("Failed to fetch monthly completion details:", error);
+ }
+};
+
+const fetchTopParametersData = async () => {
+ try {
+ const typeMap = { raw: 0, semi: 1, final: 2 };
+ const res = await getTopParameters(typeMap[activeTab.value]);
+ if (res.code === 200) {
+ topParametersData.value = res.data;
+ initSampleChart();
+ }
+ } catch (error) {
+ console.error("Failed to fetch top parameters:", error);
+ }
+};
+
+const tableData = ref([]);
+const tableLoading = ref(false);
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 20,
+ total: 0,
+});
+
+// 鍒濆鍖栧勾浠戒负褰撳墠骞翠唤锛堜娇鐢―ate瀵硅薄锛�
+const currentYear = new Date().getFullYear();
+const value3 = ref(new Date(currentYear, 0, 1));
+
+// 闄愬埗鏃ユ湡閫夋嫨锛屼笉鍏佽閫夋嫨浠婂勾涔嬪悗鐨勫勾浠�
+const disabledDate = time => {
+ const currentYear = new Date().getFullYear();
+ return time.getFullYear() > currentYear;
+};
+
+// 鐩戝惉骞翠唤鍙樺寲
+import { watch } from "vue";
+watch(value3, () => {
+ fetchMonthlyPassRateData();
+ fetchYearlyPassRateData();
+ fetchMonthlyCompletionDetailsData();
+});
+
+watch(activeTab, () => {
+ fetchTopParametersData();
+});
+
+
+// 鍥捐〃寮曠敤
+const sampleChartRef = ref(null);
+const equipmentChartRef = ref(null);
+const inspectionChartRef = ref(null);
+const usageChartRef = ref(null);
+
+// 璐ㄦ鍚堟牸鐜囧浘琛ㄥ紩鐢�
+const materialCompletionChart = ref(null);
+const materialQualityChart = ref(null);
+const semiCompletionChart = ref(null);
+const semiQualityChart = ref(null);
+const finalCompletionChart = ref(null);
+const finalQualityChart = ref(null);
+
+// 鍥捐〃瀹炰緥
+let sampleChart = null;
+let equipmentChart = null;
+let inspectionChart = null;
+let usageChart = null;
+
+// 璐ㄦ鍚堟牸鐜囧浘琛ㄥ疄渚�
+let materialCompletionChartInstance = null;
+let materialQualityChartInstance = null;
+let semiCompletionChartInstance = null;
+let semiQualityChartInstance = null;
+let finalCompletionChartInstance = null;
+let finalQualityChartInstance = null;
+
+// 鍒濆鍖栨牱鍝佽繘搴﹀浘琛�
+const initSampleChart = () => {
+ if (sampleChartRef.value) {
+ sampleChart = echarts.init(sampleChartRef.value);
+ const option = {
+ title: {
+ show: false,
+ },
+ tooltip: {
+ trigger: "item",
+ formatter: "{a} <br/>{b}: {c} ({d}%)",
+ },
+ // legend: {
+ // orient: "vertical",
+ // left: "left",
+ // },
+ series: [
+ {
+ name: "妫�娴嬮」鐩�",
+ type: "pie",
+ radius: ["40%", "80%"],
+ avoidLabelOverlap: false,
+ label: {
+ show: false,
+ position: "center",
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: "18",
+ fontWeight: "bold",
+ },
+ },
+ labelLine: {
+ show: false,
+ },
+ data: topParametersData.value.list.map((item, index) => ({
+ value: item.count,
+ name: item.name,
+ itemStyle: { color: getParameterColor(index) }
+ })),
+ },
+ ],
+ };
+ sampleChart.setOption(option);
+ }
+};
+
+// 鍒濆鍖栬澶囦娇鐢ㄥ浘琛�
+const initEquipmentChart = () => {
+ if (equipmentChartRef.value) {
+ equipmentChart = echarts.init(equipmentChartRef.value);
+ const option = {
+ title: {
+ show: false,
+ },
+ tooltip: {
+ trigger: "axis",
+ axisPointer: {
+ type: "shadow",
+ },
+ },
+ grid: {
+ left: "1%",
+ right: "1%",
+ bottom: "1%",
+ containLabel: true,
+ },
+ legend: {
+ data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
+ icon: ["circle", "circle", "circle"],
+ itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
+ itemHeight: 10,
+ itemGap: 30,
+ right: 10,
+ },
+ xAxis: {
+ type: "category",
+ data: [
+ value3.value.getFullYear() + "-1",
+ value3.value.getFullYear() + "-2",
+ value3.value.getFullYear() + "-3",
+ value3.value.getFullYear() + "-4",
+ value3.value.getFullYear() + "-5",
+ value3.value.getFullYear() + "-6",
+ value3.value.getFullYear() + "-7",
+ value3.value.getFullYear() + "-8",
+ value3.value.getFullYear() + "-9",
+ value3.value.getFullYear() + "-10",
+ value3.value.getFullYear() + "-11",
+ value3.value.getFullYear() + "-12",
+ ], // 鏀逛负鍗佷簩涓湀
+ },
+ yAxis: {
+ type: "value",
+ name: "鏁�(涓�)",
+ },
+ series: [
+ {
+ name: "鍘熸潗鏂�",
+ type: "bar",
+ barWidth: "15%",
+ data: monthlyCompletionDetailsData.value.map(item => item.rawMaterialCount),
+ itemStyle: {
+ color: "#409EFF",
+ },
+ },
+ {
+ name: "鍗婃垚鍝�",
+ type: "bar",
+ barWidth: "15%",
+
+ data: monthlyCompletionDetailsData.value.map(item => item.processCount),
+ itemStyle: {
+ color: "#67C23A",
+ },
+ },
+ {
+ name: "鎴愬搧",
+ type: "bar",
+ barWidth: "15%",
+
+ data: monthlyCompletionDetailsData.value.map(item => item.outgoingCount),
+ itemStyle: {
+ color: "#E6A23C",
+ },
+ },
+ ],
+ };
+ equipmentChart.setOption(option);
+ }
+};
+
+// 鍒濆鍖栨娴嬮」鐩浘琛�
+const initInspectionChart = () => {
+ if (inspectionChartRef.value) {
+ inspectionChart = echarts.init(inspectionChartRef.value);
+ const option = {
+ title: {
+ show: false,
+ },
+ tooltip: {
+ trigger: "item",
+ },
+ series: [
+ {
+ type: "pie",
+ radius: "70%",
+ data: [
+ { value: getYearlyStatValue(0, 'totalCount'), name: "鍘熸潗鏂�", itemStyle: { color: "#1890FF" } },
+ { value: getYearlyStatValue(1, 'totalCount'), name: "鍗婃垚鍝�", itemStyle: { color: "#F7BA1E" } },
+ { value: getYearlyStatValue(2, 'totalCount'), name: "鎴愬搧", itemStyle: { color: "#14C9C9" } },
+ ],
+ label: {
+ show: true,
+ formatter: '{b}: {c}'
+ },
+ emphasis: {
+ itemStyle: {
+ shadowBlur: 10,
+ shadowOffsetX: 0,
+ shadowColor: "rgba(0, 0, 0, 0.5)",
+ },
+ },
+ },
+ ],
+ };
+ inspectionChart.setOption(option);
+ }
+};
+
+// 鍒濆鍖栭鐢ㄨ褰曞浘琛�
+const initUsageChart = () => {
+ // 妫�鏌ュ浘琛ㄥ鍣ㄦ槸鍚﹀瓨鍦�
+ if (usageChartRef.value) {
+ // 鍒濆鍖� ECharts 瀹炰緥
+ usageChart = echarts.init(usageChartRef.value);
+ // 閰嶇疆鍥捐〃閫夐」
+ const option = {
+ // 鏍囬閰嶇疆锛堥殣钘忥級
+ title: {
+ show: false,
+ },
+
+ // 缃戞牸閰嶇疆锛堣皟鏁磋竟璺濓級
+ grid: {
+ left: "1%",
+ right: "4%",
+ bottom: "3%",
+ top: "14%",
+ containLabel: true,
+ },
+ // 鎻愮ず妗嗛厤缃�
+ tooltip: {
+ trigger: "axis", // 瑙﹀彂绫诲瀷涓哄潗鏍囪酱瑙﹀彂
+ },
+ // 鍥句緥閰嶇疆
+ legend: {
+ data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
+ icon: ["circle", "circle", "circle"],
+ itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
+ itemHeight: 10,
+ itemGap: 30,
+ },
+ // X杞撮厤缃�
+ xAxis: {
+ type: "category", // 绫诲埆杞�
+ boundaryGap: false, // 鍧愭爣杞翠袱杈圭暀鐧界瓥鐣�
+ data: [
+ value3.value.getFullYear() + "-1",
+ value3.value.getFullYear() + "-2",
+ value3.value.getFullYear() + "-3",
+ value3.value.getFullYear() + "-4",
+ value3.value.getFullYear() + "-5",
+ value3.value.getFullYear() + "-6",
+ value3.value.getFullYear() + "-7",
+ value3.value.getFullYear() + "-8",
+ value3.value.getFullYear() + "-9",
+ value3.value.getFullYear() + "-10",
+ value3.value.getFullYear() + "-11",
+ value3.value.getFullYear() + "-12",
+ ], // X杞存暟鎹�
+ },
+ // Y杞撮厤缃�
+ yAxis: {
+ type: "value", // 鏁板�艰酱
+ name: "鍗曚綅锛�%",
+ },
+ // 绯诲垪鏁版嵁
+ series: [
+ {
+ name: "鍘熸潗鏂�", // 绯诲垪鍚嶇О
+ type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+ // stack: "Total", // 鍫嗗彔鍚嶇О
+ symbol: "circle",
+ itemStyle: {
+ color: "#1890FF", // 璁剧疆杩欐潯绾跨殑棰滆壊
+ },
+ data: monthlyPassRateData.value.map(item => item.rawMaterial.passRate),
+ },
+ {
+ name: "鍗婃垚鍝�", // 绯诲垪鍚嶇О
+ type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+ // stack: "Total", // 鍫嗗彔鍚嶇О
+ symbol: "circle",
+ itemStyle: {
+ color: "#F7BA1E", // 璁剧疆杩欐潯绾跨殑棰滆壊
+ },
+ data: monthlyPassRateData.value.map(item => item.process.passRate),
+ },
+ {
+ name: "鎴愬搧", // 绯诲垪鍚嶇О
+ type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+ // stack: "Total", // 鍫嗗彔鍚嶇О
+ symbol: "circle",
+ itemStyle: {
+ color: "#14C9C9", // 璁剧疆杩欐潯绾跨殑棰滆壊
+ },
+ data: monthlyPassRateData.value.map(item => item.outgoing.passRate),
+ },
+ ],
+ };
+ // 灏嗛厤缃簲鐢ㄥ埌鍥捐〃
+ usageChart.setOption(option);
+ }
+};
+
+// 鍒濆鍖栬川妫�鍚堟牸鐜囧浘琛�
+const initQualityChart = (chartRef, color, value = 0.8) => {
+ if (chartRef.value) {
+ let chart = echarts.getInstanceByDom(chartRef.value);
+ if (!chart) {
+ chart = echarts.init(chartRef.value);
+ }
+ const numericValue = typeof value === 'string' ? parseFloat(value) / 100 : value / 100;
+ const option = {
+ series: [
+ {
+ type: "pie",
+ radius: ["45%", "90%"],
+ itemStyle: {
+ borderColor: "#f5f5f5",
+ // borderWidth: 2,
+ },
+ labelLine: {
+ show: false,
+ },
+ data: [
+ { value: numericValue, itemStyle: { color: color } },
+ { value: 1 - numericValue, itemStyle: { color: "#f5f5f5" } },
+ ],
+ },
+ ],
+ };
+ chart.setOption(option);
+ return chart;
+ }
+ return null;
+};
+
+// 鍒濆鍖栨墍鏈夎川妫�鍚堟牸鐜囧浘琛�
+const initAllQualityCharts = () => {
+ materialCompletionChartInstance = initQualityChart(
+ materialCompletionChart,
+ "#1890ff",
+ getPassRateStatValue(0, 'completionRate')
+ );
+ materialQualityChartInstance = initQualityChart(
+ materialQualityChart,
+ "#52c41a",
+ getPassRateStatValue(0, 'passRate')
+ );
+ semiCompletionChartInstance = initQualityChart(
+ semiCompletionChart,
+ "#1890ff",
+ getPassRateStatValue(1, 'completionRate')
+ );
+ semiQualityChartInstance = initQualityChart(
+ semiQualityChart,
+ "#52c41a",
+ getPassRateStatValue(1, 'passRate')
+ );
+ finalCompletionChartInstance = initQualityChart(
+ finalCompletionChart,
+ "#1890ff",
+ getPassRateStatValue(2, 'completionRate')
+ );
+ finalQualityChartInstance = initQualityChart(
+ finalQualityChart,
+ "#722ed1",
+ getPassRateStatValue(2, 'passRate')
+ );
+};
+
+// 浜嬩欢澶勭悊鍑芥暟
+const handleFilterChange = () => {
+ ElMessage.success("绛涢�夋潯浠跺凡鏇存柊");
+ // 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
+};
+
+const resetFilter = () => {
+ filterForm.dateRange = [];
+ filterForm.reportType = "sample";
+ ElMessage.info("绛涢�夋潯浠跺凡閲嶇疆");
+};
+
+const exportReport = () => {
+ ElMessage.success("鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...");
+};
+
+const refreshSampleChart = () => {
+ initSampleChart();
+ ElMessage.success("鏍峰搧杩涘害鍥捐〃宸插埛鏂�");
+};
+
+const refreshEquipmentChart = () => {
+ initEquipmentChart();
+ ElMessage.success("璁惧浣跨敤鍥捐〃宸插埛鏂�");
+};
+
+const refreshInspectionChart = () => {
+ initInspectionChart();
+ ElMessage.success("妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊");
+};
+
+const refreshUsageChart = () => {
+ initUsageChart();
+ ElMessage.success("棰嗙敤璁板綍鍥捐〃宸插埛鏂�");
+};
+
+const refreshTable = () => {
+ tableLoading.value = true;
+ setTimeout(() => {
+ tableLoading.value = false;
+ ElMessage.success("琛ㄦ牸鏁版嵁宸插埛鏂�");
+ }, 1000);
+};
+
+const exportTable = () => {
+ ElMessage.success("琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...");
+};
+
+const handleSizeChange = val => {
+ pagination.pageSize = val;
+ // 閲嶆柊鍔犺浇鏁版嵁
+};
+
+const handleCurrentChange = val => {
+ pagination.currentPage = val;
+ // 閲嶆柊鍔犺浇鏁版嵁
+};
+
+const getStatusType = status => {
+ const statusMap = {
+ 宸插畬鎴�: "success",
+ 妫�娴嬩腑: "warning",
+ 寰呮娴�: "info",
+ 宸叉殏鍋�: "danger",
+ 浣跨敤涓�: "primary",
+ 绌洪棽: "info",
+ };
+ return statusMap[status] || "info";
+};
+
+const getProgressStatus = progress => {
+ if (progress === 100) return "success";
+ if (progress >= 80) return "warning";
+ if (progress >= 50) return "";
+ return "exception";
+};
+
+const viewDetail = row => {
+ ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`);
+};
+
+const editItem = row => {
+ ElMessage.info(`缂栬緫椤圭洰: ${row.name}`);
+};
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+ fetchInspectStatisticsData();
+ fetchPassRateStatisticsData();
+ fetchMonthlyPassRateData();
+ fetchYearlyPassRateData();
+ fetchMonthlyCompletionDetailsData();
+ fetchTopParametersData();
+ nextTick(() => {
+ initSampleChart();
+ initEquipmentChart();
+ initInspectionChart();
+ initUsageChart();
+ initAllQualityCharts();
});
+ // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
+ window.addEventListener("resize", () => {
+ sampleChart?.resize();
+ equipmentChart?.resize();
+ inspectionChart?.resize();
+ usageChart?.resize();
+
+ // 璋冩暣璐ㄦ鍚堟牸鐜囧浘琛ㄥぇ灏�
+ materialCompletionChartInstance?.resize();
+ materialQualityChartInstance?.resize();
+ semiCompletionChartInstance?.resize();
+ semiQualityChartInstance?.resize();
+ finalCompletionChartInstance?.resize();
+ finalQualityChartInstance?.resize();
+ });
+});
</script>
<style scoped>
- .report-management {
- padding: 20px;
- background-color: #f5f5f5;
- min-height: 100vh;
- /* height: 87vh;
- overflow: hidden; */
- }
+.report-management {
+ padding: 20px;
+ background-color: #f5f5f5;
+ min-height: 100vh;
+ /* height: 87vh;
+ overflow: hidden; */
+}
- .page-header {
- margin-bottom: 20px;
- text-align: center;
- }
+.page-header {
+ margin-bottom: 20px;
+ text-align: center;
+}
- .page-header h2 {
- color: #303133;
- margin-bottom: 8px;
- font-size: 24px;
- font-weight: 600;
- }
+.page-header h2 {
+ color: #303133;
+ margin-bottom: 8px;
+ font-size: 24px;
+ font-weight: 600;
+}
- .page-header p {
- color: #909399;
- font-size: 14px;
- margin: 0;
- }
+.page-header p {
+ color: #909399;
+ font-size: 14px;
+ margin: 0;
+}
- .filter-card {
- margin-bottom: 20px;
- }
+.filter-card {
+ margin-bottom: 20px;
+}
- .statistics-cards {
- margin-bottom: 20px;
- }
+.statistics-cards {
+ margin-bottom: 20px;
+}
- .stat-card {
- height: 120px;
- }
+.stat-card {
+ height: 120px;
+}
- .stat-content {
- display: flex;
- align-items: center;
- height: 100%;
- }
+.stat-content {
+ display: flex;
+ align-items: center;
+ height: 100%;
+}
- .stat-icon {
- width: 60px;
- height: 60px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 20px;
- font-size: 24px;
- color: white;
- }
+.stat-icon {
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 20px;
+ font-size: 24px;
+ color: white;
+}
- .stat-card:nth-child(1) .stat-icon {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- }
+.stat-card:nth-child(1) .stat-icon {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+}
- .stat-card:nth-child(2) .stat-icon {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
- }
+.stat-card:nth-child(2) .stat-icon {
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+}
- .stat-card:nth-child(3) .stat-icon {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
- }
+.stat-card:nth-child(3) .stat-icon {
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+}
- .stat-card:nth-child(4) .stat-icon {
- background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
- }
+.stat-card:nth-child(4) .stat-icon {
+ background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+}
- .stat-info {
- flex: 1;
- }
+.stat-info {
+ flex: 1;
+}
- .stat-number {
- font-size: 28px;
- font-weight: bold;
- color: #303133;
- margin-bottom: 8px;
- }
+.stat-number {
+ font-size: 28px;
+ font-weight: bold;
+ color: #303133;
+ margin-bottom: 8px;
+}
- .stat-label {
- font-size: 14px;
- color: #909399;
- }
+.stat-label {
+ font-size: 14px;
+ color: #909399;
+}
- .charts-container {
- /* margin-bottom: 20px; */
- position: relative;
- }
+.charts-container {
+ /* margin-bottom: 20px; */
+ position: relative;
+}
- .chart-card {
- margin-bottom: 20px;
- }
- .container-line-right-bottom {
- height: 20%;
- width: 100%;
- display: flex;
- justify-content: space-evenly;
- align-items: center;
- /* background-color: #5b3f3f; */
- }
- .card-header {
- display: flex;
- justify-content: flex-start;
- align-items: center;
- font-family: Source Han Sans, Source Han Sans;
- font-weight: 700;
- font-size: 18px;
- color: #000000;
- /* line-height: 27px; */
- text-align: left;
- font-style: normal;
- text-transform: none;
- }
- .chart-title-line {
- width: 6px;
- height: 22px;
- background-color: #161a9a;
- margin-right: 16px;
- border-radius: 3px;
- }
+.chart-card {
+ margin-bottom: 20px;
+}
- .chart-container {
- height: 250px;
- width: 100%;
- }
- .chart-container-line {
- height: 250px;
- width: 100%;
- display: flex;
- position: relative;
- }
+.container-line-right-bottom {
+ height: 20%;
+ width: 100%;
+ display: flex;
+ justify-content: space-evenly;
+ align-items: center;
+ /* background-color: #5b3f3f; */
+}
- /* Tab 閫夋嫨鍣ㄦ牱寮� */
- .tab-selector {
- position: absolute;
- top: 20px;
- right: 40px;
- display: flex;
- border: 1px solid #dcdfe6;
- border-radius: 4px;
- overflow: hidden;
- }
+.card-header {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ font-family: Source Han Sans, Source Han Sans;
+ font-weight: 700;
+ font-size: 18px;
+ color: #000000;
+ /* line-height: 27px; */
+ text-align: left;
+ font-style: normal;
+ text-transform: none;
+}
- .tab-item {
- padding: 4px 12px;
- cursor: pointer;
- font-size: 14px;
- color: #606266;
- background-color: #fff;
- border-right: 1px solid #dcdfe6;
- transition: all 0.3s;
- }
+.chart-title-line {
+ width: 6px;
+ height: 22px;
+ background-color: #161a9a;
+ margin-right: 16px;
+ border-radius: 3px;
+}
- .tab-item:last-child {
- border-right: none;
- }
+.chart-container {
+ height: 250px;
+ width: 100%;
+}
- .tab-item:hover {
- color: #409eff;
- }
+.chart-container-line {
+ height: 250px;
+ width: 100%;
+ display: flex;
+ position: relative;
+}
- .tab-item.active {
- color: #fff;
- background-color: #409eff;
- }
- .container-line-left {
- height: 100%;
- width: 66%;
- }
- .container-line-right {
- height: 100%;
- width: 34%;
- }
- .container-line2-left {
- height: 100%;
- width: 50%;
- }
- .info-box {
- width: 92%;
- margin-left: 4%;
- height: 100%;
- background-color: #f7f8fa;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: space-around;
- }
- .info-box-header {
- width: 100%;
- margin-left: 20px;
- color: #1d2129;
- font-size: 16px;
- font-weight: 500;
- }
+/* Tab 閫夋嫨鍣ㄦ牱寮� */
+.tab-selector {
+ position: absolute;
+ top: 20px;
+ right: 40px;
+ display: flex;
+ border: 1px solid #dcdfe6;
+ border-radius: 4px;
+ overflow: hidden;
+}
- .info-line {
- width: 100%;
- display: flex;
- padding-left: 20px;
- align-items: center;
- }
- .info-icon {
- width: 7px;
- height: 7px;
- border-radius: 50%;
- margin-right: 8px;
- }
- .info-line-title {
- font-size: 12px;
- color: #4e5969;
- flex: 1;
- }
- .info-line-value1 {
- font-size: 12px;
- color: #3d3d3d;
- color: #1d2129;
- font-weight: 500;
- margin-right: 15%;
- }
- .info-line-value2 {
- font-size: 12px;
- color: #3d3d3d;
- color: #1d2129;
- font-weight: 500;
- margin-right: 10%;
- }
- .top-container {
- height: 130px;
- width: 100%;
- display: flex;
- }
- .typeNum {
- height: 100%;
- width: 33.33%;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .typeNum-left {
- font-size: 12px;
- color: #909399;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- .typeNum-left-text {
- font-size: 12px;
- color: #3491fa;
- font-weight: 500;
- margin-top: 5px;
- }
- .table-card {
- margin-bottom: 20px;
- }
- .typeNum-center {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-left: 10px;
- }
- .typeNum-leftLine {
- color: #3491fa;
- font-size: 12px;
- }
- .typeNum-rightLine {
- border-top: 1px solid #3491fa;
- border-left: 1px solid #3491fa;
- border-bottom: 1px solid #3491fa;
- height: 80px;
- width: 8px;
- }
- .typeNum-leftLine2 {
- color: #5eb334;
- font-size: 12px;
- }
- .typeNum-rightLine2 {
- border-top: 1px solid #3491fa;
- border-left: 1px solid #5eb334;
- border-bottom: 1px solid #5eb334;
- height: 80px;
- width: 8px;
- }
- .typeNum-leftLine3 {
- color: #8000ff;
- font-size: 12px;
- }
- .typeNum-rightLine3 {
- border-top: 1px solid #8000ff;
- border-left: 1px solid #8000ff;
- border-bottom: 1px solid #8000ff;
- height: 80px;
- width: 8px;
- }
- .typeNum-right {
- margin-left: 10px;
- display: flex;
- flex-direction: column;
- height: 90%;
- justify-content: space-between;
- }
- .typeNum-right-top-name {
- font-weight: 400;
- font-size: 12px;
- color: #3d3d3d;
- }
- .typeNum-right-top-text {
- font-weight: 400;
- font-size: 16px;
- color: rgba(0, 0, 0, 0.85);
- margin-top: 5px;
- }
- .unit {
- font-size: 12px;
- color: #3d3d3d;
- }
- .inspection-chart-box {
- height: 50px;
- width: 30%;
- background-color: #f7f8fa;
- border-radius: 8px;
- padding-left: 15px;
- }
- .chart-box-title {
- font-size: 12px;
- color: #4e5969;
- margin-top: 5px;
- }
- .unit {
- font-size: 12px;
- color: #3d3d3d;
- }
- .chart-box-num {
- font-size: 18px;
- color: #000;
- margin-top: 5px;
- font-weight: 500;
- }
- /* 璐ㄦ鍚堟牸鐜囧崱鐗囨牱寮� */
- .top-container鍚堟牸鐜� {
- height: 130px;
- width: 100%;
- display: flex;
- gap: 15px;
- align-items: center;
- justify-content: space-between;
- }
- .flex-center {
- justify-content: space-evenly;
- }
- .quality-card {
- /* flex: 1; */
- width: 32%;
- /* height: 100px; */
- border-radius: 8px;
- padding: 12px;
- display: flex;
- flex-direction: column;
- }
+.tab-item {
+ padding: 4px 12px;
+ cursor: pointer;
+ font-size: 14px;
+ color: #606266;
+ background-color: #fff;
+ border-right: 1px solid #dcdfe6;
+ transition: all 0.3s;
+}
- .blue-card {
- background-color: #e6f7ff;
- }
+.tab-item:last-child {
+ border-right: none;
+}
- .green-card {
- background-color: #f6ffed;
- color: #000000;
- }
+.tab-item:hover {
+ color: #409eff;
+}
- .purple-card {
- background-color: #f9f0ff;
- }
+.tab-item.active {
+ color: #fff;
+ background-color: #409eff;
+}
- .quality-card-title {
- font-size: 14px;
- font-weight: 500;
- margin-bottom: 10px;
- display: flex;
- align-items: center;
- }
+.container-line-left {
+ height: 100%;
+ width: 66%;
+}
- .quality-item-tip {
- font-size: 12px;
- color: #666666;
- margin-bottom: 3px;
- }
- .blue-label {
- color: #1890ff;
- }
- .green-label {
- color: #52c41a;
- }
+.container-line-right {
+ height: 100%;
+ width: 34%;
+}
- .quality-card-title {
- color: #000;
- font-weight: bold;
- }
+.container-line2-left {
+ height: 100%;
+ width: 50%;
+}
- .quality-card-content {
- display: flex;
- justify-content: space-between;
- align-items: center;
- flex: 1;
- }
+.info-box {
+ width: 92%;
+ margin-left: 4%;
+ height: 100%;
+ background-color: #f7f8fa;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: space-around;
+}
- .quality-item {
- display: flex;
- /* flex-direction: column; */
- align-items: center;
- justify-content: center;
- margin-top: 5px;
- flex: 1;
- }
+.info-box-header {
+ width: 100%;
+ margin-left: 20px;
+ color: #1d2129;
+ font-size: 16px;
+ font-weight: 500;
+}
- .quality-item-label {
- font-size: 12px;
- /* color: #666; */
- margin-bottom: 4px;
- }
+.info-line {
+ width: 100%;
+ display: flex;
+ padding-left: 20px;
+ align-items: center;
+}
- .quality-item-value {
- font-size: 20px;
- font-weight: 500;
- margin-bottom: 4px;
- }
+.info-icon {
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ margin-right: 8px;
+}
- .quality-item-chart {
- width: 60px;
- height: 60px;
- margin-left: 10px;
- }
- /* .flex-center {
- justify-content: space-evenly;
- } */
+.info-line-title {
+ font-size: 12px;
+ color: #4e5969;
+ flex: 1;
+}
- .blue-chart {
- /* background-color: rgba(24, 144, 255, 0.1); */
- }
+.info-line-value1 {
+ font-size: 12px;
+ color: #3d3d3d;
+ color: #1d2129;
+ font-weight: 500;
+ margin-right: 15%;
+}
- .green-chart {
- /* background-color: rgba(82, 196, 26, 0.1); */
- }
+.info-line-value2 {
+ font-size: 12px;
+ color: #3d3d3d;
+ color: #1d2129;
+ font-weight: 500;
+ margin-right: 10%;
+}
- .purple-chart {
- /* background-color: rgba(114, 46, 209, 0.1); */
- }
+.top-container {
+ height: 130px;
+ width: 100%;
+ display: flex;
+}
- .chart-ring {
- width: 60px;
- height: 60px;
- border-radius: 50%;
- border: 15px solid transparent;
- position: relative;
- }
+.typeNum {
+ height: 100%;
+ width: 33.33%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
- .blue-chart .chart-ring {
- border-top-color: #1890ff;
- border-right-color: #1890ff;
- border-bottom-color: #1890ff;
- transform: rotate(45deg);
- }
+.typeNum-left {
+ font-size: 12px;
+ color: #909399;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
- .green-chart .chart-ring {
- border-top-color: #52c41a;
- border-right-color: #52c41a;
- border-bottom-color: #52c41a;
- transform: rotate(45deg);
- }
+.typeNum-left-text {
+ font-size: 12px;
+ color: #3491fa;
+ font-weight: 500;
+ margin-top: 5px;
+}
- .purple-chart .chart-ring {
- border-top-color: #722ed1;
- border-right-color: #722ed1;
- border-bottom-color: #722ed1;
- transform: rotate(45deg);
- }
+.table-card {
+ margin-bottom: 20px;
+}
- .pagination-container {
- margin-top: 20px;
- text-align: right;
- }
- .yearchange {
- position: absolute;
- right: 40px;
- top: 20px;
- display: flex;
- align-items: center;
- /* width: 60px; */
- }
+.typeNum-center {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-left: 10px;
+}
- :deep(.el-card__header) {
- padding: 15px 20px;
- border-bottom: 1px solid #ffffff;
- background-color: #ffffff;
- }
+.typeNum-leftLine {
+ color: #3491fa;
+ font-size: 12px;
+}
- :deep(.el-card__body) {
- padding: 20px;
- }
+.typeNum-rightLine {
+ border-top: 1px solid #3491fa;
+ border-left: 1px solid #3491fa;
+ border-bottom: 1px solid #3491fa;
+ height: 80px;
+ width: 8px;
+}
- :deep(.el-table) {
- margin-bottom: 20px;
- }
+.typeNum-leftLine2 {
+ color: #5eb334;
+ font-size: 12px;
+}
- :deep(.el-progress) {
- margin: 0;
- }
+.typeNum-rightLine2 {
+ border-top: 1px solid #3491fa;
+ border-left: 1px solid #5eb334;
+ border-bottom: 1px solid #5eb334;
+ height: 80px;
+ width: 8px;
+}
- :deep(.el-tag) {
- margin: 0;
- }
- :deep(.el-input__prefix) {
- display: none !important;
- }
+.typeNum-leftLine3 {
+ color: #8000ff;
+ font-size: 12px;
+}
+
+.typeNum-rightLine3 {
+ border-top: 1px solid #8000ff;
+ border-left: 1px solid #8000ff;
+ border-bottom: 1px solid #8000ff;
+ height: 80px;
+ width: 8px;
+}
+
+.typeNum-right {
+ margin-left: 10px;
+ display: flex;
+ flex-direction: column;
+ height: 90%;
+ justify-content: space-between;
+}
+
+.typeNum-right-top-name {
+ font-weight: 400;
+ font-size: 12px;
+ color: #3d3d3d;
+}
+
+.typeNum-right-top-text {
+ font-weight: 400;
+ font-size: 16px;
+ color: rgba(0, 0, 0, 0.85);
+ margin-top: 5px;
+}
+
+.unit {
+ font-size: 12px;
+ color: #3d3d3d;
+}
+
+.inspection-chart-box {
+ height: 50px;
+ width: 30%;
+ background-color: #f7f8fa;
+ border-radius: 8px;
+ padding-left: 15px;
+}
+
+.chart-box-title {
+ font-size: 12px;
+ color: #4e5969;
+ margin-top: 5px;
+}
+
+.unit {
+ font-size: 12px;
+ color: #3d3d3d;
+}
+
+.chart-box-num {
+ font-size: 18px;
+ color: #000;
+ margin-top: 5px;
+ font-weight: 500;
+}
+
+/* 璐ㄦ鍚堟牸鐜囧崱鐗囨牱寮� */
+.top-container鍚堟牸鐜� {
+ height: 130px;
+ width: 100%;
+ display: flex;
+ gap: 15px;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.flex-center {
+ justify-content: space-evenly;
+}
+
+.quality-card {
+ /* flex: 1; */
+ width: 32%;
+ /* height: 100px; */
+ border-radius: 8px;
+ padding: 12px;
+ display: flex;
+ flex-direction: column;
+}
+
+.blue-card {
+ background-color: #e6f7ff;
+}
+
+.green-card {
+ background-color: #f6ffed;
+ color: #000000;
+}
+
+.purple-card {
+ background-color: #f9f0ff;
+}
+
+.quality-card-title {
+ font-size: 14px;
+ font-weight: 500;
+ margin-bottom: 10px;
+ display: flex;
+ align-items: center;
+}
+
+.quality-item-tip {
+ font-size: 12px;
+ color: #666666;
+ margin-bottom: 3px;
+}
+
+.blue-label {
+ color: #1890ff;
+}
+
+.green-label {
+ color: #52c41a;
+}
+
+.quality-card-title {
+ color: #000;
+ font-weight: bold;
+}
+
+.quality-card-content {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex: 1;
+}
+
+.quality-item {
+ display: flex;
+ /* flex-direction: column; */
+ align-items: center;
+ justify-content: center;
+ margin-top: 5px;
+ flex: 1;
+}
+
+.quality-item-label {
+ font-size: 12px;
+ /* color: #666; */
+ margin-bottom: 4px;
+}
+
+.quality-item-value {
+ font-size: 20px;
+ font-weight: 500;
+ margin-bottom: 4px;
+}
+
+.quality-item-chart {
+ width: 60px;
+ height: 60px;
+ margin-left: 10px;
+}
+
+/* .flex-center {
+justify-content: space-evenly;
+} */
+
+.blue-chart {
+ /* background-color: rgba(24, 144, 255, 0.1); */
+}
+
+.green-chart {
+ /* background-color: rgba(82, 196, 26, 0.1); */
+}
+
+.purple-chart {
+ /* background-color: rgba(114, 46, 209, 0.1); */
+}
+
+.chart-ring {
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ border: 15px solid transparent;
+ position: relative;
+}
+
+.blue-chart .chart-ring {
+ border-top-color: #1890ff;
+ border-right-color: #1890ff;
+ border-bottom-color: #1890ff;
+ transform: rotate(45deg);
+}
+
+.green-chart .chart-ring {
+ border-top-color: #52c41a;
+ border-right-color: #52c41a;
+ border-bottom-color: #52c41a;
+ transform: rotate(45deg);
+}
+
+.purple-chart .chart-ring {
+ border-top-color: #722ed1;
+ border-right-color: #722ed1;
+ border-bottom-color: #722ed1;
+ transform: rotate(45deg);
+}
+
+.pagination-container {
+ margin-top: 20px;
+ text-align: right;
+}
+
+.yearchange {
+ position: absolute;
+ right: 40px;
+ top: 20px;
+ display: flex;
+ align-items: center;
+ /* width: 60px; */
+}
+
+:deep(.el-card__header) {
+ padding: 15px 20px;
+ border-bottom: 1px solid #ffffff;
+ background-color: #ffffff;
+}
+
+:deep(.el-card__body) {
+ padding: 20px;
+}
+
+:deep(.el-table) {
+ margin-bottom: 20px;
+}
+
+:deep(.el-progress) {
+ margin: 0;
+}
+
+:deep(.el-tag) {
+ margin: 0;
+}
+
+:deep(.el-input__prefix) {
+ display: none !important;
+}
</style>
--
Gitblit v1.9.3