From b1a0d701cf898c8b7812e66a808a1c91f2bae6cc Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期二, 17 三月 2026 16:44:11 +0800
Subject: [PATCH] 2026.3.17
---
src/views/inspection/MonitorControl.vue | 1418 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1,417 insertions(+), 1 deletions(-)
diff --git a/src/views/inspection/MonitorControl.vue b/src/views/inspection/MonitorControl.vue
index 50ede86..e1a2f1a 100644
--- a/src/views/inspection/MonitorControl.vue
+++ b/src/views/inspection/MonitorControl.vue
@@ -1 +1,1417 @@
-<template>s</template>
+<template>
+ <div class="monitor-control">
+ <!-- 鎬昏鐜板満宸℃煡鍗$墖 -->
+ <el-card class="mb-4">
+ <template #header>
+ <div class="card-header">
+ <span>鐜板満宸℃煡鎬昏</span>
+ <div class="filter-group">
+ <FYOptionTime
+ :initValue="false"
+ type="daterange"
+ v-model:value="params.timeRange"
+ style="width: 300px; margin-bottom: 0px"
+ :shortcuts="shortcuts"
+ ></FYOptionTime>
+ <!-- 鍖哄幙 -->
+ <FYOptionLocation
+ class="m-l-8"
+ :allOption="false"
+ :level="3"
+ :checkStrictly="false"
+ :initValue="false"
+ v-model:value="params.locations"
+ style="width: 300px; margin-bottom: 0px"
+ ></FYOptionLocation>
+ </div>
+ </div>
+ </template>
+
+ <!-- 缁熻鏁版嵁鍖哄煙 -->
+ <div class="stats-sections">
+ <!-- 宸︿晶锛氬凡宸℃煡搴楅摵鐜囥�佸贰鏌ョ偣娆°�佸鏌ョ偣娆� -->
+ <div class="stats-section left-section">
+ <h3>宸℃煡姒傚喌</h3>
+ <div class="chart-item">
+ <div class="progress-container">
+ <el-progress
+ type="dashboard"
+ :percentage="parseFloat(inspectionStats.inspectedRate)"
+ :color="['#409EFF', '#67C23A']"
+ :width="120"
+ />
+ <div class="progress-label">宸插贰鏌ュ簵閾虹巼</div>
+ <div class="progress-value">
+ {{ `${inspectionStats.inspectedShops}/${inspectionStats.totalShops}` }}
+ </div>
+ </div>
+ </div>
+ <div class="stats-grid m-t-16">
+ <el-statistic
+ class="stat-item"
+ :value="inspectionStats.inspectionPoints"
+ title="宸℃煡鐐规"
+ />
+ <el-statistic
+ class="stat-item"
+ :value="inspectionStats.reviewPoints"
+ title="澶嶆煡鐐规"
+ />
+ </div>
+ </div>
+
+ <!-- 鍙充晶锛氶棶棰樻暟銆侀棶棰樻暣鏀规暟銆侀棶棰樻暣鏀圭巼缁熻鍥� -->
+ <div class="stats-section right-section">
+ <h3>闂鏁存敼姒傚喌</h3>
+ <div class="stats-grid">
+ <el-statistic class="stat-item" :value="inspectionStats.problemCount" title="闂鏁�" />
+ <el-statistic
+ class="stat-item"
+ :value="inspectionStats.rectifiedProblems"
+ title="闂鏁存敼鏁�"
+ />
+ </div>
+ <!-- <div class="chart-item"> -->
+ <div ref="rectificationRateChart" class="chart"></div>
+ <!-- </div> -->
+ </div>
+ </div>
+
+ <!-- 鍏朵粬鍥捐〃灞曠ず -->
+ <div class="chart-container">
+ <div class="chart-item">
+ <h3>宸℃煡瀹屾垚鎯呭喌瓒嬪娍</h3>
+ <div ref="inspectionTrendChart" class="chart"></div>
+ </div>
+ <div class="chart-item">
+ <h3>闂绫诲瀷鍒嗗竷</h3>
+ <div ref="problemTypeChart" class="chart"></div>
+ </div>
+ </div>
+ </el-card>
+
+ <!-- 椁愰ギ搴楅摵琛屾斂澶勭綒鍗$墖 -->
+ <el-card class="mb-4">
+ <template #header>
+ <div class="card-header">
+ <span>椁愰ギ搴楅摵琛屾斂澶勭綒</span>
+ <div class="filter-group">
+ <FYOptionTime
+ class="m-r-8"
+ :initValue="false"
+ type="daterange"
+ v-model:value="punishmentDateRange"
+ style="width: 300px; margin-bottom: 0px"
+ :shortcuts="shortcuts"
+ ></FYOptionTime>
+ <el-button type="success" icon="Plus" @click="addPunishment">鏂板澶勭綒</el-button>
+ <el-button type="info" icon="Upload" @click="importPunishment">鎵归噺瀵煎叆</el-button>
+ </div>
+ </div>
+ </template>
+
+ <!-- 鍥捐〃灞曠ず -->
+ <div class="chart-container">
+ <div class="chart-item">
+ <div class="chart-header">
+ <h3>澶勭綒鏁拌秼鍔�</h3>
+ <div class="chart-summary">澶勭綒鎬绘暟: {{ punishmentStats.totalCount }}</div>
+ </div>
+ <div ref="dailyPunishmentChart" class="chart"></div>
+ </div>
+ <div class="chart-item">
+ <h3>搴楅摵绫诲瀷澶勭綒鍒嗗竷</h3>
+ <div ref="shopTypePunishmentChart" class="chart"></div>
+ </div>
+ </div>
+
+ <!-- 澶勭綒璁板綍琛ㄦ牸 -->
+ <el-table
+ :data="filteredPunishmentData"
+ table-layout="fixed"
+ :show-overflow-tooltip="true"
+ height="400px"
+ border
+ >
+ <el-table-column prop="shopName" label="澶勭綒搴楅摵" />
+ <el-table-column prop="punishmentItem" label="澶勭綒浜嬮」" width="180" />
+ <el-table-column prop="punishmentTime" label="澶勭綒鏃堕棿" width="180" />
+ <el-table-column prop="punishmentReason" label="澶勭綒鐞嗙敱" width="200" />
+ <el-table-column prop="punishmentResult" label="澶勭綒缁撴灉" width="150" />
+ <el-table-column prop="punishmentDepartment" label="澶勭綒閮ㄩ棬" width="150" />
+ <el-table-column width="250">
+ <template #header>
+ <el-input v-model="punishmentKeyword" placeholder="鍏抽敭瀛楁悳绱�" style="width: 120px" />
+ </template>
+ <template #default="scope">
+ <el-button size="small" type="primary" @click="editPunishment(scope.row)"
+ >缂栬緫</el-button
+ >
+ <el-button size="small" type="danger" @click="deletePunishment(scope.row.id)"
+ >鍒犻櫎</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 鍒嗛〉 -->
+ <div class="pagination-container">
+ <el-pagination
+ v-model:current-page="punishmentPagination.currentPage"
+ v-model:page-size="punishmentPagination.pageSize"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ :total="punishmentPagination.total"
+ @size-change="handlePunishmentSizeChange"
+ @current-change="handlePunishmentCurrentChange"
+ />
+ </div>
+ </el-card>
+
+ <!-- 椁愰ギ搴楅摵淇¤鎶曡瘔鍗$墖 -->
+ <el-card class="mb-4">
+ <template #header>
+ <div class="card-header">
+ <span>椁愰ギ搴楅摵淇¤鎶曡瘔</span>
+ <div class="filter-group">
+ <FYOptionTime
+ class="m-r-8"
+ :initValue="false"
+ type="daterange"
+ v-model:value="complaintDateRange"
+ style="width: 300px; margin-bottom: 0px"
+ :shortcuts="shortcuts"
+ ></FYOptionTime>
+ <el-button type="success" icon="Plus" @click="addComplaint">鏂板鎶曡瘔</el-button>
+ <el-button type="info" icon="Upload" @click="importComplaint">鎵归噺瀵煎叆</el-button>
+ </div>
+ </div>
+ </template>
+
+ <!-- 鍥捐〃灞曠ず -->
+ <div class="chart-container">
+ <div class="chart-item">
+ <div class="chart-header">
+ <h3>鎶曡瘔鏁拌秼鍔�</h3>
+ <div class="chart-summary">鎶曡瘔鎬绘暟: {{ complaintStats.totalCount }}</div>
+ </div>
+ <div ref="dailyComplaintChart" class="chart"></div>
+ </div>
+ <div class="chart-item">
+ <h3>鎶曡瘔鏉ユ簮鍒嗗竷</h3>
+ <div ref="sourceComplaintChart" class="chart"></div>
+ </div>
+ </div>
+
+ <!-- 鎶曡瘔璁板綍琛ㄦ牸 -->
+ <el-table
+ :data="filteredComplaintData"
+ table-layout="fixed"
+ :show-overflow-tooltip="true"
+ height="400px"
+ border
+ >
+ <el-table-column prop="shopName" label="鎶曡瘔搴楅摵" />
+ <el-table-column prop="complaintReason" label="鎶曡瘔鍘熷洜" width="180" />
+ <el-table-column prop="complaintRequest" label="鎶曡瘔璇夋眰" width="180" />
+ <el-table-column prop="complaintTime" label="鎶曡瘔鏃堕棿" width="180" />
+ <el-table-column prop="complaintSource" label="鎶曡瘔鏉ユ簮" width="150" />
+ <el-table-column prop="handlingDepartment" label="澶勭悊閮ㄩ棬" width="150" />
+ <el-table-column prop="complaintResult" label="鎶曡瘔缁撴灉" width="150" />
+ <el-table-column width="250">
+ <template #header>
+ <el-input v-model="complaintKeyword" placeholder="鍏抽敭瀛楁悳绱�" style="width: 120px" />
+ </template>
+ <template #default="scope">
+ <el-button size="small" type="primary" @click="editComplaint(scope.row)"
+ >缂栬緫</el-button
+ >
+ <el-button size="small" type="danger" @click="deleteComplaint(scope.row.id)"
+ >鍒犻櫎</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 鍒嗛〉 -->
+ <div class="pagination-container">
+ <el-pagination
+ v-model:current-page="complaintPagination.currentPage"
+ v-model:page-size="complaintPagination.pageSize"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ :total="complaintPagination.total"
+ @size-change="handleComplaintSizeChange"
+ @current-change="handleComplaintCurrentChange"
+ />
+ </div>
+ </el-card>
+
+ <!-- 鏂板/缂栬緫澶勭綒瀵硅瘽妗� -->
+ <el-dialog v-model="punishmentDialogVisible" title="澶勭綒淇℃伅" width="600px">
+ <el-form :model="punishmentForm" label-width="100px">
+ <el-form-item label="澶勭綒搴楅摵">
+ <el-input v-model="punishmentForm.shopName" />
+ </el-form-item>
+ <el-form-item label="澶勭綒浜嬮」">
+ <el-input v-model="punishmentForm.punishmentItem" />
+ </el-form-item>
+ <el-form-item label="澶勭綒鏃堕棿">
+ <el-date-picker v-model="punishmentForm.punishmentTime" type="datetime" />
+ </el-form-item>
+ <el-form-item label="澶勭綒鐞嗙敱">
+ <el-input v-model="punishmentForm.punishmentReason" type="textarea" />
+ </el-form-item>
+ <el-form-item label="澶勭綒缁撴灉">
+ <el-input v-model="punishmentForm.punishmentResult" />
+ </el-form-item>
+ <el-form-item label="澶勭綒閮ㄩ棬">
+ <el-input v-model="punishmentForm.punishmentDepartment" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="punishmentDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="savePunishment">淇濆瓨</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鏂板/缂栬緫鎶曡瘔瀵硅瘽妗� -->
+ <el-dialog v-model="complaintDialogVisible" title="鎶曡瘔淇℃伅" width="600px">
+ <el-form :model="complaintForm" label-width="100px">
+ <el-form-item label="鎶曡瘔搴楅摵">
+ <el-input v-model="complaintForm.shopName" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔鍘熷洜">
+ <el-input v-model="complaintForm.complaintReason" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔璇夋眰">
+ <el-input v-model="complaintForm.complaintRequest" type="textarea" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔鏃堕棿">
+ <el-date-picker v-model="complaintForm.complaintTime" type="datetime" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔鏉ユ簮">
+ <el-input v-model="complaintForm.complaintSource" />
+ </el-form-item>
+ <el-form-item label="澶勭悊閮ㄩ棬">
+ <el-input v-model="complaintForm.handlingDepartment" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔缁撴灉">
+ <el-input v-model="complaintForm.complaintResult" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="complaintDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="saveComplaint">淇濆瓨</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 澶勭綒鎵归噺瀵煎叆瀵硅瘽妗� -->
+ <el-dialog v-model="punishmentImportDialogVisible" title="澶勭綒鎵归噺瀵煎叆" width="600px">
+ <div class="import-container">
+ <p class="import-tip">璇烽�夋嫨瑕佸鍏ョ殑Excel鏂囦欢</p>
+ <el-upload
+ class="upload-demo"
+ action="#"
+ :auto-upload="false"
+ :on-change="handlePunishmentFileChange"
+ :file-list="punishmentImportFileList"
+ accept=".xlsx,.xls"
+ :limit="1"
+ :on-exceed="handleExceed"
+ >
+ <el-button type="primary">閫夋嫨鏂囦欢</el-button>
+ <template #tip>
+ <div class="el-upload__tip">鍙兘涓婁紶Excel鏂囦欢锛屼笖涓嶈秴杩�5MB</div>
+ </template>
+ </el-upload>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="punishmentImportDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="confirmPunishmentImport">瀵煎叆</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鎶曡瘔鎵归噺瀵煎叆瀵硅瘽妗� -->
+ <el-dialog v-model="complaintImportDialogVisible" title="鎶曡瘔鎵归噺瀵煎叆" width="600px">
+ <div class="import-container">
+ <p class="import-tip">璇烽�夋嫨瑕佸鍏ョ殑Excel鏂囦欢</p>
+ <el-upload
+ class="upload-demo"
+ action="#"
+ :auto-upload="false"
+ :on-change="handleComplaintFileChange"
+ :file-list="complaintImportFileList"
+ accept=".xlsx,.xls"
+ :limit="1"
+ :on-exceed="handleExceed"
+ >
+ <el-button type="primary">閫夋嫨鏂囦欢</el-button>
+ <template #tip>
+ <div class="el-upload__tip">鍙兘涓婁紶Excel鏂囦欢锛屼笖涓嶈秴杩�5MB</div>
+ </template>
+ </el-upload>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="complaintImportDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="confirmComplaintImport">瀵煎叆</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, watch, computed } from 'vue'
+import * as echarts from 'echarts'
+import { Icon } from '@iconify/vue'
+import dayjs from 'dayjs'
+import { ElMessage } from 'element-plus'
+
+// 鎬昏鐜板満宸℃煡鏁版嵁
+const dayStart = dayjs('2023-08-01').startOf('date')
+const dayEnd = dayStart.endOf('date')
+const shortcuts = [
+ {
+ text: '浠婂ぉ',
+ value: [dayStart.toDate(), dayEnd.toDate()],
+ },
+ {
+ text: '鏈懆',
+ value: [dayStart.startOf('week').toDate(), dayEnd.endOf('week').toDate()],
+ },
+ {
+ text: '涓婂懆',
+ value: [dayStart.day(-7).toDate(), dayEnd.day(-1).toDate()],
+ },
+ {
+ text: '鏈湀',
+ value: [dayStart.startOf('month').toDate(), dayEnd.endOf('month').toDate()],
+ },
+ {
+ text: '涓婃湀',
+ value: [
+ dayStart.subtract(1, 'month').startOf('month').toDate(),
+ dayEnd.subtract(1, 'month').endOf('month').toDate(),
+ ],
+ },
+ {
+ text: '鏈搴�',
+ value: [dayStart.startOf('quarter').toDate(), dayEnd.endOf('quarter').toDate()],
+ },
+ {
+ text: '涓婂搴�',
+ value: [
+ dayStart.subtract(1, 'quarter').startOf('quarter').toDate(),
+ dayEnd.subtract(1, 'quarter').endOf('quarter').toDate(),
+ ],
+ },
+ {
+ text: '鍘诲勾',
+ value: [
+ dayStart.subtract(1, 'year').startOf('year').toDate(),
+ dayEnd.subtract(1, 'year').endOf('year').toDate(),
+ ],
+ },
+ {
+ text: '浠婂勾',
+ value: [dayStart.startOf('year').toDate(), dayEnd.endOf('year').toDate()],
+ },
+]
+const params = ref({
+ prodBaseTypes: [],
+ prodCheck: '',
+ scenetype: '',
+ topTask: '',
+ locations: {
+ aCode: null,
+ aName: null,
+ cCode: '3100',
+ cName: '涓婃捣甯�',
+ dCode: '310104',
+ dName: '寰愭眹鍖�',
+ mCode: null,
+ mName: null,
+ pCode: '31',
+ pName: '涓婃捣甯�',
+ tCode: null,
+ tName: null,
+ },
+ timeRange: [dayStart.startOf('month').toDate(), dayEnd.endOf('month').toDate()],
+})
+const inspectionStats = ref({
+ // totalShops: 1250,
+ // inspectedShops: 980,
+ // inspectedRate: '78.4%',
+ // inspectionPoints: 2350,
+ // reviewPoints: 450,
+ // problemCount: 320,
+ // rectifiedProblems: 280,
+ // sameDayRectificationRate: '65.2%',
+ // effectiveRectificationRate: '78.5%',
+ // comprehensiveRectificationRate: '82.3%',
+ // auditPassRate: '87.5%',
+})
+
+// 鍥捐〃寮曠敤
+const inspectionTrendChart = ref(null)
+const problemTypeChart = ref(null)
+const rectificationRateChart = ref(null)
+const dailyPunishmentChart = ref(null)
+const shopTypePunishmentChart = ref(null)
+const dailyComplaintChart = ref(null)
+const sourceComplaintChart = ref(null)
+
+// 琛屾斂澶勭綒鏁版嵁
+const punishmentDateRange = ref([
+ dayStart.startOf('month').toDate(),
+ dayEnd.endOf('month').toDate(),
+])
+const punishmentKeyword = ref('')
+const punishmentStats = ref({
+ totalCount: 120,
+})
+const punishmentTableData = ref([
+ // {
+ // id: 1,
+ // shopName: '鍛崇編椁愬巺',
+ // punishmentItem: '娌圭儫瓒呮爣鎺掓斁',
+ // punishmentTime: '2026-03-10 14:30',
+ // punishmentReason: '鏈畨瑁呮补鐑熷噣鍖栬澶�',
+ // punishmentResult: '缃氭5000鍏�',
+ // punishmentDepartment: '寰愭眹鍖虹幆淇濆眬',
+ // },
+ // {
+ // id: 2,
+ // shopName: '棣欒荆灏忛緳铏�',
+ // punishmentItem: '娌圭儫瓒呮爣鎺掓斁',
+ // punishmentTime: '2026-03-08 10:15',
+ // punishmentReason: '娌圭儫鍑�鍖栬澶囨湭姝e父杩愯',
+ // punishmentResult: '缃氭3000鍏�',
+ // punishmentDepartment: '寰愭眹鍖虹幆淇濆眬',
+ // },
+])
+const punishmentPagination = ref({
+ currentPage: 1,
+ pageSize: 10,
+ total: 2,
+})
+
+// 杩囨护鍚庣殑澶勭綒鏁版嵁
+const filteredPunishmentData = computed(() => {
+ if (!punishmentKeyword.value) {
+ return punishmentTableData.value
+ }
+ const keyword = punishmentKeyword.value.toLowerCase()
+ return punishmentTableData.value.filter((item) => {
+ return Object.values(item).some((value) => {
+ return String(value).toLowerCase().includes(keyword)
+ })
+ })
+})
+
+// 淇¤鎶曡瘔鏁版嵁
+const complaintDateRange = ref([dayStart.startOf('month').toDate(), dayEnd.endOf('month').toDate()])
+const complaintKeyword = ref('')
+const complaintStats = ref({
+ totalCount: 85,
+})
+const complaintTableData = ref([
+ // {
+ // id: 1,
+ // shopName: '椴滃懗棣�',
+ // complaintReason: '娌圭儫鎵版皯',
+ // complaintRequest: '瑕佹眰瀹夎娌圭儫鍑�鍖栬澶�',
+ // complaintTime: '2026-03-12 09:20',
+ // complaintSource: '12345鐑嚎',
+ // handlingDepartment: '寰愭眹鍖虹幆淇濆眬',
+ // complaintResult: '宸插鐞�',
+ // },
+ // {
+ // id: 2,
+ // shopName: '鐑х儰杈句汉',
+ // complaintReason: '澶滈棿娌圭儫姹℃煋',
+ // complaintRequest: '瑕佹眰鏁存敼',
+ // complaintTime: '2026-03-10 22:30',
+ // complaintSource: '灞呮皯鎶曡瘔',
+ // handlingDepartment: '寰愭眹鍖虹幆淇濆眬',
+ // complaintResult: '澶勭悊涓�',
+ // },
+])
+const complaintPagination = ref({
+ currentPage: 1,
+ pageSize: 10,
+ total: 2,
+})
+
+// 杩囨护鍚庣殑鎶曡瘔鏁版嵁
+const filteredComplaintData = computed(() => {
+ if (!complaintKeyword.value) {
+ return complaintTableData.value
+ }
+ const keyword = complaintKeyword.value.toLowerCase()
+ return complaintTableData.value.filter((item) => {
+ return Object.values(item).some((value) => {
+ return String(value).toLowerCase().includes(keyword)
+ })
+ })
+})
+
+// 瀵硅瘽妗嗙姸鎬�
+const punishmentDialogVisible = ref(false)
+const complaintDialogVisible = ref(false)
+const punishmentImportDialogVisible = ref(false)
+const complaintImportDialogVisible = ref(false)
+
+// 瀵煎叆鏂囦欢鍒楄〃
+const punishmentImportFileList = ref([])
+const complaintImportFileList = ref([])
+
+// 琛ㄥ崟鏁版嵁
+const punishmentForm = ref({
+ id: '',
+ shopName: '',
+ punishmentItem: '',
+ punishmentTime: '',
+ punishmentReason: '',
+ punishmentResult: '',
+ punishmentDepartment: '',
+})
+
+const complaintForm = ref({
+ id: '',
+ shopName: '',
+ complaintReason: '',
+ complaintRequest: '',
+ complaintTime: '',
+ complaintSource: '',
+ handlingDepartment: '',
+ complaintResult: '',
+})
+
+const refreshInspectionData = () => {
+ // 妯℃嫙鍒锋柊鏁版嵁
+ console.log('鍒锋柊宸℃煡鏁版嵁', params.value)
+ // 鐢熸垚鏂扮殑妯℃嫙鏁版嵁
+ const totalShops = 90 + Math.floor(Math.random() * 10)
+ const inspectedShops = 70 + Math.floor(Math.random() * 10)
+ const inspectedRate = ((inspectedShops / totalShops) * 100).toFixed(1) + '%'
+
+ // 璁$畻鏃堕棿鑼冨洿
+ const startTime = params.value.timeRange[0]
+ const endTime = params.value.timeRange[1]
+ const startDate = dayjs(startTime)
+ const endDate = dayjs(endTime)
+ const daysDiff = endDate.diff(startDate, 'day')
+ const months = daysDiff / 30
+
+ // 鏍规嵁鏃堕棿鑼冨洿璋冩暣鏁版嵁閲忕骇
+ const inspectionPoints = Math.floor(100 * months) + Math.floor(Math.random() * 20)
+ const problemCount = Math.floor(200 * months) + Math.floor(Math.random() * 30)
+ const reviewPoints = Math.floor(inspectionPoints * 0.2) + Math.floor(Math.random() * 10)
+ const rectifiedProblems = Math.floor(problemCount * 0.8) + Math.floor(Math.random() * 20)
+
+ inspectionStats.value = {
+ totalShops,
+ inspectedShops,
+ inspectedRate,
+ inspectionPoints,
+ reviewPoints,
+ problemCount,
+ rectifiedProblems,
+ sameDayRectificationRate: (60 + Math.random() * 20).toFixed(1) + '%',
+ effectiveRectificationRate: (70 + Math.random() * 20).toFixed(1) + '%',
+ comprehensiveRectificationRate: (75 + Math.random() * 15).toFixed(1) + '%',
+ auditPassRate: (80 + Math.random() * 15).toFixed(1) + '%',
+ }
+ // 閲嶆柊鍒濆鍖栧浘琛ㄤ互鏇存柊鏁版嵁
+ initCharts()
+}
+
+const searchPunishment = () => {
+ // 妯℃嫙鎼滅储澶勭綒鏁版嵁
+ console.log('鎼滅储澶勭綒鏁版嵁', {
+ dateRange: punishmentDateRange.value,
+ keyword: punishmentKeyword.value,
+ })
+
+ // 璁$畻鏃堕棿鑼冨洿
+ const startTime = punishmentDateRange.value[0]
+ const endTime = punishmentDateRange.value[1]
+ const startDate = dayjs(startTime)
+ const endDate = dayjs(endTime)
+ const daysDiff = endDate.diff(startDate, 'day')
+ const months = daysDiff / 30
+
+ // 鐢熸垚鏂扮殑妯℃嫙鏁版嵁
+ const totalCount = Math.floor(10 * months) + Math.floor(Math.random() * 3)
+ punishmentStats.value = {
+ totalCount,
+ }
+
+ // 鐢熸垚鏂扮殑澶勭綒璁板綍
+ const newData = []
+ const shopNames = [
+ '鍛崇編椁愬巺',
+ '棣欒荆灏忛緳铏�',
+ '椴滃懗棣�',
+ '鐑х儰杈句汉',
+ '宸濊彍棣�',
+ '瑗块鍘�',
+ '鏃ユ枡搴�',
+ '鐏攨搴�',
+ ]
+ const punishmentItems = ['娌圭儫瓒呮爣鎺掓斁', '鏈畨瑁呮补鐑熷噣鍖栬澶�', '璁惧鏈甯歌繍琛�', '鍣0姹℃煋']
+ const departments = ['寰愭眹鍖虹幆淇濆眬', '闀垮畞鍖虹幆淇濆眬', '闈欏畨鍖虹幆淇濆眬', '鏅檧鍖虹幆淇濆眬']
+
+ for (let i = 0; i < totalCount; i++) {
+ // 鐢熸垚鍦ㄦ椂闂磋寖鍥村唴鐨勯殢鏈烘椂闂�
+ const randomDays = Math.floor(Math.random() * (daysDiff + 1))
+ const randomTime = startDate
+ .add(randomDays, 'day')
+ .add(Math.floor(Math.random() * 24), 'hour')
+ .add(Math.floor(Math.random() * 60), 'minute')
+
+ newData.push({
+ id: i + 1,
+ shopName: shopNames[Math.floor(Math.random() * shopNames.length)],
+ punishmentItem: punishmentItems[Math.floor(Math.random() * punishmentItems.length)],
+ punishmentTime: randomTime.format('YYYY-MM-DD HH:mm'),
+ punishmentReason:
+ punishmentItems[Math.floor(Math.random() * punishmentItems.length)] + '鐨勮繚瑙勮涓�',
+ punishmentResult: '缃氭' + (Math.floor(Math.random() * 5) + 1) * 1000 + '鍏�',
+ punishmentDepartment: departments[Math.floor(Math.random() * departments.length)],
+ })
+ }
+
+ punishmentTableData.value = newData
+ punishmentPagination.value.total = newData.length
+ // 閲嶆柊鍒濆鍖栧浘琛ㄤ互鏇存柊鏁版嵁
+ initCharts()
+}
+
+const searchComplaint = () => {
+ // 妯℃嫙鎼滅储鎶曡瘔鏁版嵁
+ console.log('鎼滅储鎶曡瘔鏁版嵁', {
+ dateRange: complaintDateRange.value,
+ keyword: complaintKeyword.value,
+ })
+
+ // 璁$畻鏃堕棿鑼冨洿
+ const startTime = complaintDateRange.value[0]
+ const endTime = complaintDateRange.value[1]
+ const startDate = dayjs(startTime)
+ const endDate = dayjs(endTime)
+ const daysDiff = endDate.diff(startDate, 'day')
+ const months = daysDiff / 30
+
+ // 鐢熸垚鏂扮殑妯℃嫙鏁版嵁
+ const totalCount = Math.floor(20 * months) + Math.floor(Math.random() * 5)
+ complaintStats.value = {
+ totalCount,
+ }
+
+ // 鐢熸垚鏂扮殑鎶曡瘔璁板綍
+ const newData = []
+ const shopNames = [
+ '椴滃懗棣�',
+ '鐑х儰杈句汉',
+ '鍛崇編椁愬巺',
+ '棣欒荆灏忛緳铏�',
+ '宸濊彍棣�',
+ '瑗块鍘�',
+ '鏃ユ枡搴�',
+ '鐏攨搴�',
+ ]
+ const complaintReasons = ['娌圭儫鎵版皯', '澶滈棿鍣0', '寮傚懗姹℃煋', '鍗敓闂']
+ const sources = ['12345鐑嚎', '灞呮皯鎶曡瘔', '缃戠粶骞冲彴', '鍏朵粬']
+ const departments = ['寰愭眹鍖虹幆淇濆眬', '闀垮畞鍖虹幆淇濆眬', '闈欏畨鍖虹幆淇濆眬', '鏅檧鍖虹幆淇濆眬']
+ const results = ['宸插鐞�', '澶勭悊涓�', '鏈鐞�']
+
+ for (let i = 0; i < totalCount; i++) {
+ // 鐢熸垚鍦ㄦ椂闂磋寖鍥村唴鐨勯殢鏈烘椂闂�
+ const randomDays = Math.floor(Math.random() * (daysDiff + 1))
+ const randomTime = startDate
+ .add(randomDays, 'day')
+ .add(Math.floor(Math.random() * 24), 'hour')
+ .add(Math.floor(Math.random() * 60), 'minute')
+
+ newData.push({
+ id: i + 1,
+ shopName: shopNames[Math.floor(Math.random() * shopNames.length)],
+ complaintReason: complaintReasons[Math.floor(Math.random() * complaintReasons.length)],
+ complaintRequest:
+ '瑕佹眰鏁存敼' + complaintReasons[Math.floor(Math.random() * complaintReasons.length)],
+ complaintTime: randomTime.format('YYYY-MM-DD HH:mm'),
+ complaintSource: sources[Math.floor(Math.random() * sources.length)],
+ handlingDepartment: departments[Math.floor(Math.random() * departments.length)],
+ complaintResult: results[Math.floor(Math.random() * results.length)],
+ })
+ }
+
+ complaintTableData.value = newData
+ complaintPagination.value.total = newData.length
+ // 閲嶆柊鍒濆鍖栧浘琛ㄤ互鏇存柊鏁版嵁
+ initCharts()
+}
+
+// 鐩戝惉澶勭綒鏃ユ湡鑼冨洿鍙樺寲
+watch(
+ () => punishmentDateRange.value,
+ () => {
+ searchPunishment()
+ },
+ { deep: true },
+)
+
+// 鐩戝惉鎶曡瘔鏃ユ湡鑼冨洿鍙樺寲
+watch(
+ () => complaintDateRange.value,
+ () => {
+ searchComplaint()
+ },
+ { deep: true },
+)
+
+const addPunishment = () => {
+ // 閲嶇疆琛ㄥ崟
+ punishmentForm.value = {
+ id: '',
+ shopName: '',
+ punishmentItem: '',
+ punishmentTime: '',
+ punishmentReason: '',
+ punishmentResult: '',
+ punishmentDepartment: '',
+ }
+ punishmentDialogVisible.value = true
+}
+
+const editPunishment = (row) => {
+ // 濉厖琛ㄥ崟
+ punishmentForm.value = { ...row }
+ punishmentDialogVisible.value = true
+}
+
+const savePunishment = () => {
+ // 妯℃嫙淇濆瓨鏁版嵁
+ console.log('淇濆瓨澶勭綒鏁版嵁', punishmentForm.value)
+ punishmentDialogVisible.value = false
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勬暟鎹繚瀛橀�昏緫
+}
+
+const deletePunishment = (id) => {
+ // 妯℃嫙鍒犻櫎鏁版嵁
+ console.log('鍒犻櫎澶勭綒鏁版嵁', id)
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勬暟鎹垹闄ら�昏緫
+}
+
+const importPunishment = () => {
+ // 鎵撳紑瀵煎叆瀵硅瘽妗�
+ punishmentImportFileList.value = []
+ punishmentImportDialogVisible.value = true
+}
+
+const handlePunishmentFileChange = (file, fileList) => {
+ punishmentImportFileList.value = fileList
+ console.log('閫夋嫨鐨勫缃氭枃浠�:', file)
+}
+
+const confirmPunishmentImport = () => {
+ if (punishmentImportFileList.value.length === 0) {
+ ElMessage.warning('璇烽�夋嫨瑕佸鍏ョ殑鏂囦欢')
+ return
+ }
+
+ const file = punishmentImportFileList.value[0]
+ console.log('寮�濮嬪鍏ュ缃氭暟鎹�:', file.name)
+
+ // 棰勭暀瀵煎叆閫昏緫
+ // 杩欓噷灏嗗疄鐜板疄闄呯殑鏂囦欢瑙f瀽鍜屾暟鎹鍏�
+
+ punishmentImportDialogVisible.value = false
+ ElMessage.success('瀵煎叆鎿嶄綔宸茶Е鍙戯紝棰勭暀瀵煎叆閫昏緫')
+}
+
+const addComplaint = () => {
+ // 閲嶇疆琛ㄥ崟
+ complaintForm.value = {
+ id: '',
+ shopName: '',
+ complaintReason: '',
+ complaintRequest: '',
+ complaintTime: '',
+ complaintSource: '',
+ handlingDepartment: '',
+ complaintResult: '',
+ }
+ complaintDialogVisible.value = true
+}
+
+const editComplaint = (row) => {
+ // 濉厖琛ㄥ崟
+ complaintForm.value = { ...row }
+ complaintDialogVisible.value = true
+}
+
+const saveComplaint = () => {
+ // 妯℃嫙淇濆瓨鏁版嵁
+ console.log('淇濆瓨鎶曡瘔鏁版嵁', complaintForm.value)
+ complaintDialogVisible.value = false
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勬暟鎹繚瀛橀�昏緫
+}
+
+const deleteComplaint = (id) => {
+ // 妯℃嫙鍒犻櫎鏁版嵁
+ console.log('鍒犻櫎鎶曡瘔鏁版嵁', id)
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勬暟鎹垹闄ら�昏緫
+}
+
+const importComplaint = () => {
+ // 鎵撳紑瀵煎叆瀵硅瘽妗�
+ complaintImportFileList.value = []
+ complaintImportDialogVisible.value = true
+}
+
+const handleComplaintFileChange = (file, fileList) => {
+ complaintImportFileList.value = fileList
+ console.log('閫夋嫨鐨勬姇璇夋枃浠�:', file)
+}
+
+const confirmComplaintImport = () => {
+ if (complaintImportFileList.value.length === 0) {
+ ElMessage.warning('璇烽�夋嫨瑕佸鍏ョ殑鏂囦欢')
+ return
+ }
+
+ const file = complaintImportFileList.value[0]
+ console.log('寮�濮嬪鍏ユ姇璇夋暟鎹�:', file.name)
+
+ // 棰勭暀瀵煎叆閫昏緫
+ // 杩欓噷灏嗗疄鐜板疄闄呯殑鏂囦欢瑙f瀽鍜屾暟鎹鍏�
+
+ complaintImportDialogVisible.value = false
+ ElMessage.success('瀵煎叆鎿嶄綔宸茶Е鍙戯紝棰勭暀瀵煎叆閫昏緫')
+}
+
+const handleExceed = (files, fileList) => {
+ ElMessage.warning('鍙兘涓婁紶涓�涓枃浠�')
+}
+
+const handlePunishmentSizeChange = (size) => {
+ punishmentPagination.value.pageSize = size
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勫垎椤甸�昏緫
+}
+
+const handlePunishmentCurrentChange = (current) => {
+ punishmentPagination.value.currentPage = current
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勫垎椤甸�昏緫
+}
+
+const handleComplaintSizeChange = (size) => {
+ complaintPagination.value.pageSize = size
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勫垎椤甸�昏緫
+}
+
+const handleComplaintCurrentChange = (current) => {
+ complaintPagination.value.currentPage = current
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勫垎椤甸�昏緫
+}
+
+// 鍒濆鍖栧浘琛�
+const initCharts = () => {
+ // 宸℃煡瀹屾垚鎯呭喌瓒嬪娍鍥�
+ if (inspectionTrendChart.value) {
+ const chart = echarts.init(inspectionTrendChart.value)
+
+ // 璁$畻鏃堕棿鑼冨洿骞剁敓鎴恱杞存暟鎹�
+ const startTime = params.value.timeRange[0]
+ const endTime = params.value.timeRange[1]
+ const startDate = dayjs(startTime)
+ const endDate = dayjs(endTime)
+ const daysDiff = endDate.diff(startDate, 'day')
+
+ let xAxisData = []
+ let seriesData = []
+
+ if (daysDiff <= 30) {
+ // 鍚屼竴涓湀鍐咃紝鎸夋棩鏄剧ず
+ for (let i = 0; i <= daysDiff; i++) {
+ const date = startDate.add(i, 'day')
+ xAxisData.push(date.format('MM/DD'))
+ seriesData.push(60 + Math.floor(Math.random() * 30)) // 鐢熸垚闅忔満鏁版嵁
+ }
+ } else {
+ // 瓒呰繃涓�涓湀锛屾寜鏈堟樉绀�
+ const startMonth = startDate.startOf('month')
+ const endMonth = endDate.endOf('month')
+ const monthsDiff = endMonth.diff(startMonth, 'month')
+
+ for (let i = 0; i <= monthsDiff; i++) {
+ const date = startMonth.add(i, 'month')
+ xAxisData.push(date.format('YYYY/MM'))
+ seriesData.push(60 + Math.floor(Math.random() * 30)) // 鐢熸垚闅忔満鏁版嵁
+ }
+ }
+
+ chart.setOption({
+ xAxis: {
+ type: 'category',
+ data: xAxisData,
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ formatter: '{value}%',
+ },
+ },
+ series: [
+ {
+ data: seriesData,
+ type: 'bar',
+ },
+ ],
+ })
+ }
+
+ // 闂绫诲瀷鍒嗗竷鍥�
+ if (problemTypeChart.value) {
+ const chart = echarts.init(problemTypeChart.value)
+ chart.setOption({
+ series: [
+ {
+ type: 'pie',
+ data: [
+ { value: 30, name: '娌圭儫鍦ㄧ嚎鐩戞祴璁惧' },
+ { value: 25, name: '娌圭儫鍑�鍖栬鏂借澶�' },
+ { value: 20, name: '娌圭儫鍦ㄧ嚎鐩戞祴璁惧缁存姢' },
+ { value: 15, name: '娌圭儫鍑�鍖栬鏂借澶囩淮鎶�' },
+ { value: 10, name: '娌圭儫鍦ㄧ嚎鐩戞祴鏁版嵁閲忕骇' },
+ { value: 20, name: '绌鸿皟鍜岄鏈哄櫔澹�' },
+ { value: 18, name: '鍙拌处绠$悊' },
+ { value: 22, name: '淇$敤鎵胯鑷瘎' },
+ ],
+ label: {
+ show: true,
+ formatter: '{b}: {d}%',
+ },
+ },
+ ],
+ })
+ }
+
+ // 姣忔棩澶勭綒鏁伴噺鍥�
+ if (dailyPunishmentChart.value && punishmentDateRange.value.length > 0) {
+ const chart = echarts.init(dailyPunishmentChart.value)
+
+ // 璁$畻鏃堕棿鑼冨洿骞剁敓鎴恱杞存暟鎹�
+ const startTime = punishmentDateRange.value[0]
+ const endTime = punishmentDateRange.value[1]
+ const startDate = dayjs(startTime)
+ const endDate = dayjs(endTime)
+ const daysDiff = endDate.diff(startDate, 'day')
+
+ let xAxisData = []
+ let seriesData = []
+
+ // 澶勭悊澶勭綒鏁版嵁
+ const punishmentData = punishmentTableData.value
+ const dateFormat = daysDiff <= 30 ? 'MM/DD' : 'YYYY/MM'
+
+ // 鐢熸垚鏃ユ湡鑼冨洿
+ if (daysDiff <= 30) {
+ // 鍚屼竴涓湀鍐咃紝鎸夋棩鏄剧ず
+ for (let i = 0; i <= daysDiff; i++) {
+ const date = startDate.add(i, 'day')
+ xAxisData.push(date.format(dateFormat))
+ // 璁$畻璇ユ棩鏈熺殑澶勭綒鏁伴噺
+ const count = punishmentData.filter((item) => {
+ const itemDate = dayjs(item.punishmentTime)
+ return itemDate.format(dateFormat) === date.format(dateFormat)
+ }).length
+ seriesData.push(count)
+ }
+ } else {
+ // 瓒呰繃涓�涓湀锛屾寜鏈堟樉绀�
+ const startMonth = startDate.startOf('month')
+ const endMonth = endDate.endOf('month')
+ const monthsDiff = endMonth.diff(startMonth, 'month')
+
+ for (let i = 0; i <= monthsDiff; i++) {
+ const date = startMonth.add(i, 'month')
+ xAxisData.push(date.format(dateFormat))
+ // 璁$畻璇ユ湀浠界殑澶勭綒鏁伴噺
+ const count = punishmentData.filter((item) => {
+ const itemDate = dayjs(item.punishmentTime)
+ return itemDate.format(dateFormat) === date.format(dateFormat)
+ }).length
+ seriesData.push(count)
+ }
+ }
+
+ chart.setOption({
+ xAxis: {
+ type: 'category',
+ data: xAxisData,
+ },
+ yAxis: {
+ type: 'value',
+ },
+ series: [
+ {
+ data: seriesData,
+ type: 'bar',
+ },
+ ],
+ })
+ }
+
+ // 搴楅摵绫诲瀷澶勭綒鍒嗗竷鍥�
+ if (shopTypePunishmentChart.value) {
+ const chart = echarts.init(shopTypePunishmentChart.value)
+ chart.setOption({
+ series: [
+ {
+ type: 'pie',
+ data: [
+ { value: 50, name: '涓' },
+ { value: 30, name: '鐑х儰' },
+ { value: 20, name: '瑗块' },
+ { value: 15, name: '鍏朵粬' },
+ ],
+ label: {
+ show: true,
+ formatter: '{b}: {d}%',
+ },
+ },
+ ],
+ })
+ }
+
+ // 姣忔棩鎶曡瘔鏁伴噺鍥�
+ if (dailyComplaintChart.value && complaintDateRange.value.length > 0) {
+ const chart = echarts.init(dailyComplaintChart.value)
+
+ // 璁$畻鏃堕棿鑼冨洿骞剁敓鎴恱杞存暟鎹�
+ const startTime = complaintDateRange.value[0]
+ const endTime = complaintDateRange.value[1]
+ const startDate = dayjs(startTime)
+ const endDate = dayjs(endTime)
+ const daysDiff = endDate.diff(startDate, 'day')
+
+ let xAxisData = []
+ let seriesData = []
+
+ // 澶勭悊鎶曡瘔鏁版嵁
+ const complaintData = complaintTableData.value
+ const dateFormat = daysDiff <= 30 ? 'MM/DD' : 'YYYY/MM'
+
+ // 鐢熸垚鏃ユ湡鑼冨洿
+ if (daysDiff <= 30) {
+ // 鍚屼竴涓湀鍐咃紝鎸夋棩鏄剧ず
+ for (let i = 0; i <= daysDiff; i++) {
+ const date = startDate.add(i, 'day')
+ xAxisData.push(date.format(dateFormat))
+ // 璁$畻璇ユ棩鏈熺殑鎶曡瘔鏁伴噺
+ const count = complaintData.filter((item) => {
+ const itemDate = dayjs(item.complaintTime)
+ return itemDate.format(dateFormat) === date.format(dateFormat)
+ }).length
+ seriesData.push(count)
+ }
+ } else {
+ // 瓒呰繃涓�涓湀锛屾寜鏈堟樉绀�
+ const startMonth = startDate.startOf('month')
+ const endMonth = endDate.endOf('month')
+ const monthsDiff = endMonth.diff(startMonth, 'month')
+
+ for (let i = 0; i <= monthsDiff; i++) {
+ const date = startMonth.add(i, 'month')
+ xAxisData.push(date.format(dateFormat))
+ // 璁$畻璇ユ湀浠界殑鎶曡瘔鏁伴噺
+ const count = complaintData.filter((item) => {
+ const itemDate = dayjs(item.complaintTime)
+ return itemDate.format(dateFormat) === date.format(dateFormat)
+ }).length
+ seriesData.push(count)
+ }
+ }
+
+ chart.setOption({
+ xAxis: {
+ type: 'category',
+ data: xAxisData,
+ },
+ yAxis: {
+ type: 'value',
+ },
+ series: [
+ {
+ data: seriesData,
+ type: 'bar',
+ },
+ ],
+ })
+ }
+
+ // 鎶曡瘔鏉ユ簮鍒嗗竷鍥�
+ if (sourceComplaintChart.value) {
+ const chart = echarts.init(sourceComplaintChart.value)
+ chart.setOption({
+ series: [
+ {
+ type: 'pie',
+ data: [
+ { value: 40, name: '12345鐑嚎' },
+ { value: 25, name: '灞呮皯鎶曡瘔' },
+ { value: 15, name: '缃戠粶骞冲彴' },
+ { value: 5, name: '鍏朵粬' },
+ ],
+ label: {
+ show: true,
+ formatter: '{b}: {d}%',
+ },
+ },
+ ],
+ })
+ }
+
+ // 闂鏁存敼鐜囩粺璁″浘
+ if (rectificationRateChart.value) {
+ const chart = echarts.init(rectificationRateChart.value)
+ chart.setOption({
+ xAxis: {
+ type: 'category',
+ data: ['褰撴棩鏁存敼鐜�', '48灏忔椂鍐呮暣鏀圭巼', '缁煎悎鏁存敼鐜�', '瀹℃牳閫氳繃鐜�'],
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ formatter: '{value}%',
+ },
+ },
+ series: [
+ {
+ data: [
+ parseFloat(inspectionStats.value.sameDayRectificationRate),
+ parseFloat(inspectionStats.value.effectiveRectificationRate),
+ parseFloat(inspectionStats.value.comprehensiveRectificationRate),
+ parseFloat(inspectionStats.value.auditPassRate),
+ ],
+ type: 'bar',
+ itemStyle: {
+ color: function (params) {
+ const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C']
+ return colors[params.dataIndex]
+ },
+ },
+ },
+ ],
+ })
+ }
+}
+
+// 鐩戝惉绐楀彛澶у皬鍙樺寲
+const handleResize = () => {
+ // 閲嶆柊璋冩暣鍥捐〃澶у皬
+ if (inspectionTrendChart.value) {
+ echarts.init(inspectionTrendChart.value).resize()
+ }
+ if (problemTypeChart.value) {
+ echarts.init(problemTypeChart.value).resize()
+ }
+ if (rectificationRateChart.value) {
+ echarts.init(rectificationRateChart.value).resize()
+ }
+ if (dailyPunishmentChart.value) {
+ echarts.init(dailyPunishmentChart.value).resize()
+ }
+ if (shopTypePunishmentChart.value) {
+ echarts.init(shopTypePunishmentChart.value).resize()
+ }
+ if (dailyComplaintChart.value) {
+ echarts.init(dailyComplaintChart.value).resize()
+ }
+ if (sourceComplaintChart.value) {
+ echarts.init(sourceComplaintChart.value).resize()
+ }
+}
+
+// 鐩戝惉params鍙樺寲
+watch(
+ () => params.value,
+ () => {
+ refreshInspectionData()
+ },
+ { deep: true },
+)
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+ refreshInspectionData()
+ searchPunishment()
+ searchComplaint()
+ initCharts()
+ window.addEventListener('resize', handleResize)
+})
+
+// 缁勪欢鍗歌浇鏃舵竻鐞嗕簨浠剁洃鍚�
+onUnmounted(() => {
+ cleanup()
+})
+
+// 娓呯悊
+const cleanup = () => {
+ window.removeEventListener('resize', handleResize)
+}
+</script>
+
+<style scoped>
+.monitor-control {
+ padding: 20px;
+ background-color: #f5f7fa;
+ min-height: 100vh;
+}
+
+.card-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.filter-group {
+ display: flex;
+ align-items: center;
+}
+
+.mr-2 {
+ margin-right: 10px;
+}
+
+.stats-sections {
+ display: flex;
+ gap: 20px;
+ margin-bottom: 30px;
+}
+
+.stats-section {
+ flex: 1;
+ background-color: #fff;
+ padding: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.stats-section h3 {
+ margin-bottom: 15px;
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+}
+
+.stats-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 20px;
+ margin-bottom: 20px;
+}
+
+.stat-item {
+ background-color: #fff;
+ padding: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.progress-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+}
+
+.progress-label {
+ margin-top: 10px;
+ font-size: 14px;
+ font-weight: 500;
+ color: #606266;
+}
+
+.progress-value {
+ margin-top: 5px;
+ font-size: 18px;
+ font-weight: 600;
+ color: #409eff;
+}
+
+.chart-container {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
+ gap: 20px;
+ margin-bottom: 30px;
+}
+
+.chart-item {
+ background-color: #fff;
+ padding: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.chart-item h3 {
+ margin-bottom: 15px;
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.chart-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+}
+
+.chart-summary {
+ font-size: 14px;
+ color: #606266;
+ font-weight: 500;
+}
+
+.chart {
+ width: 100%;
+ height: 300px;
+}
+
+.pagination-container {
+ margin-top: 20px;
+ display: flex;
+ justify-content: flex-end;
+}
+
+.dialog-footer {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.import-container {
+ padding: 20px 0;
+}
+
+.import-tip {
+ margin-bottom: 20px;
+ font-size: 14px;
+ color: #606266;
+}
+
+.upload-demo {
+ margin-bottom: 20px;
+}
+</style>
--
Gitblit v1.9.3