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