From e365192a36d6d9432fbd00ea9d577a38f8679707 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期五, 13 三月 2026 11:21:33 +0800
Subject: [PATCH] 2026.3.13
---
src/views/inspection/scenenew/UserEdit.vue | 33
src/views/inspection/scenenew/components/CompPunishment.vue | 298 ++++++++++++
src/views/monitor/DataException.vue | 2
src/views/inspection/scenenew/components/CompLaint.vue | 310 +++++++++++++
src/constants/menu.js | 10
src/sfc/TimeSelect.vue | 6
src/views/analysis/huanxincode/HuanxinCodeManage.vue | 707 ++++++++++++++++++++++++++++++
7 files changed, 1,341 insertions(+), 25 deletions(-)
diff --git a/src/constants/menu.js b/src/constants/menu.js
index ce7a257..742e0c1 100644
--- a/src/constants/menu.js
+++ b/src/constants/menu.js
@@ -81,11 +81,6 @@
icon: 'solar:checklist-minimalistic-line-duotone',
name: '闂鏁存敼',
},
- {
- path: '/index/inspection/report-manage',
- icon: 'solar:folder-favourite-bookmark-line-duotone',
- name: '璇勪及鎶ュ憡',
- },
],
},
{
@@ -102,6 +97,11 @@
icon: 'solar:archive-down-minimlistic-line-duotone',
name: '鐜俊鐮佺鐞�',
},
+ {
+ path: '/index/inspection/report-manage',
+ icon: 'solar:folder-favourite-bookmark-line-duotone',
+ name: '璇勪及鎶ュ憡',
+ },
// {
// path: '/index/analysis/data-product',
// icon: 'solar:document-add-line-duotone',
diff --git a/src/sfc/TimeSelect.vue b/src/sfc/TimeSelect.vue
index c6783a8..0cd5e1a 100644
--- a/src/sfc/TimeSelect.vue
+++ b/src/sfc/TimeSelect.vue
@@ -61,8 +61,10 @@
methods: {
initOneWeekAgoTime() {
// 缁欐椂闂撮�夋嫨鍣ㄨ缃粯璁ゆ椂闂翠负涓�鍛ㄥ墠
- this.time[0] = dayjs().subtract(4, 'week').format('YYYY-MM-DD HH:mm:ss')
- this.time[1] = dayjs().format('YYYY-MM-DD HH:mm:ss')
+ // this.time[0] = dayjs().subtract(4, 'week').format('YYYY-MM-DD HH:mm:ss')
+ // this.time[1] = dayjs().format('YYYY-MM-DD HH:mm:ss')
+ // 2026.3.13 demo 涓浐瀹氬垵濮嬫椂闂�
+ this.time = ['2023-08-01 00:00:00', '2023-08-31 23:59:59']
},
// 蹇嵎鏃舵閫夋嫨
diff --git a/src/views/analysis/huanxincode/HuanxinCodeManage.vue b/src/views/analysis/huanxincode/HuanxinCodeManage.vue
index 0389851..9a75b38 100644
--- a/src/views/analysis/huanxincode/HuanxinCodeManage.vue
+++ b/src/views/analysis/huanxincode/HuanxinCodeManage.vue
@@ -1 +1,706 @@
-<template>鐜俊鐮佺鐞�</template>
+<template>
+ <div class="huanxin-code-manage">
+ <!-- 椤堕儴瀹忚鐪嬫澘鍖� -->
+ <el-row :gutter="20" class="dashboard">
+ <el-col :span="8">
+ <el-card shadow="hover" class="dashboard-card green-card" @click="filterByCode('green')">
+ <div class="card-content">
+ <div class="card-title">缁跨爜搴楅摵鏁�</div>
+ <div class="card-value">{{ statistics.greenCount }}</div>
+ <div class="card-percentage">{{ statistics.greenPercentage }}%</div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="8">
+ <el-card shadow="hover" class="dashboard-card yellow-card" @click="filterByCode('yellow')">
+ <div class="card-content">
+ <div class="card-title">榛勭爜搴楅摵鏁�</div>
+ <div class="card-value">{{ statistics.yellowCount }}</div>
+ <div class="card-percentage">{{ statistics.yellowPercentage }}%</div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="8">
+ <el-card shadow="hover" class="dashboard-card red-card" @click="filterByCode('red')">
+ <div class="card-content">
+ <div class="card-title">绾㈢爜搴楅摵鏁�</div>
+ <div class="card-value">{{ statistics.redCount }}</div>
+ <div class="card-percentage">{{ statistics.redPercentage }}%</div>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+
+ <!-- 璇勫垎妯″瀷閰嶇疆鎸夐挳 -->
+ <!-- <div class="model-config" v-if="isAdmin">
+ <el-button type="primary" @click="openModelConfig">
+ <el-icon><Setting /></el-icon>
+ <span>璇勫垎妯″瀷閰嶇疆</span>
+ </el-button>
+ </div> -->
+
+ <!-- 涓儴瑙嗗浘鍒囨崲鍖� -->
+ <el-tabs v-model="activeView" class="view-tabs">
+ <!-- 鍒楄〃瑙嗗浘 -->
+ <el-tab-pane label="鍒楄〃瑙嗗浘" name="list">
+ <el-table :data="filteredShopList" style="width: 100%">
+ <el-table-column prop="shopName" label="搴楅摵鍚嶇О" />
+ <el-table-column prop="district" label="鎵�鍦ㄥ尯鍘�" width="120" />
+ <el-table-column prop="town" label="鎵�鍦ㄨ闀�" width="150" />
+ <el-table-column label="鐜俊鐮�" width="100">
+ <template #default="scope">
+ <el-tag :type="getCodeType(scope.row.code)">{{ getCodeText(scope.row.code) }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="score" label="褰撳墠璇勫垎" width="120" sortable />
+ <el-table-column label="璇勫垎鍙樺寲瓒嬪娍" width="150">
+ <template #default="scope">
+ <div class="trend">
+ <el-icon :class="['trend-icon', scope.row.trend > 0 ? 'up' : 'down']">
+ <ArrowUp v-if="scope.row.trend > 0" />
+ <ArrowDown v-else />
+ </el-icon>
+ <span :class="scope.row.trend > 0 ? 'up' : 'down'">
+ {{ scope.row.trend > 0 ? '+' : '' }}{{ scope.row.trend }}鍒�
+ </span>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column prop="lastUpdate" label="涓婃鏇存柊鏃堕棿" width="180" />
+ <el-table-column label="鎿嶄綔" width="200" fixed="right">
+ <template #default="scope">
+ <el-button size="small" @click="viewDetails(scope.row)">鏌ョ湅璇︽儏</el-button>
+ <!-- <el-button size="small" type="warning" @click="viewRiskWarnings(scope.row)"
+ >椋庨櫓棰勮璁板綍</el-button
+ > -->
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-tab-pane>
+
+ <!-- 鍦板浘瑙嗗浘 -->
+ <el-tab-pane label="鍦板浘瑙嗗浘" name="map">
+ <div class="map-container">
+ <div class="map-placeholder">
+ <el-empty description="鍦板浘鍔犺浇涓�..." />
+ <!-- 杩欓噷搴旇闆嗘垚鐪熷疄鐨勫湴鍥剧粍浠� -->
+ </div>
+ <div class="map-legend">
+ <div class="legend-item">
+ <div class="legend-dot green"></div>
+ <span>缁跨爜</span>
+ </div>
+ <div class="legend-item">
+ <div class="legend-dot yellow"></div>
+ <span>榛勭爜</span>
+ </div>
+ <div class="legend-item">
+ <div class="legend-dot red"></div>
+ <span>绾㈢爜</span>
+ </div>
+ </div>
+ </div>
+ </el-tab-pane>
+ </el-tabs>
+
+ <!-- 璇︽儏鎶藉眽 -->
+ <el-drawer v-model="drawerVisible" title="搴楅摵璇︽儏" direction="rtl" size="70%">
+ <div v-if="selectedShop" class="shop-details">
+ <!-- 鐜俊鐮佸ぇ鍥炬爣鍙婂綋鍓嶈瘎鍒� -->
+ <div class="code-header">
+ <div class="code-icon" :class="selectedShop.code">
+ {{ getCodeText(selectedShop.code) }}
+ </div>
+ <div class="score-info">
+ <div class="score-label">褰撳墠璇勫垎</div>
+ <div class="score-value">{{ selectedShop.score }}</div>
+ </div>
+ </div>
+
+ <!-- 璇勫垎缁村害闆疯揪鍥� -->
+ <div class="chart-section">
+ <h3>璇勫垎缁村害鍒嗘瀽</h3>
+ <div class="radar-chart">
+ <!-- 杩欓噷搴旇闆嗘垚鐪熷疄鐨勯浄杈惧浘缁勪欢 -->
+ <el-empty description="闆疯揪鍥惧姞杞戒腑..." />
+ </div>
+ </div>
+
+ <!-- 璇勫垎鍘嗗彶瓒嬪娍鍥� -->
+ <div class="chart-section">
+ <h3>璇勫垎鍘嗗彶瓒嬪娍</h3>
+ <div class="trend-chart">
+ <!-- 杩欓噷搴旇闆嗘垚鐪熷疄鐨勮秼鍔垮浘缁勪欢 -->
+ <el-empty description="瓒嬪娍鍥惧姞杞戒腑..." />
+ </div>
+ </div>
+
+ <!-- 椋庨櫓棰勮璁板綍 -->
+ <div class="warning-section">
+ <h3>椋庨櫓棰勮璁板綍</h3>
+ <el-table :data="selectedShop.warnings" style="width: 100%">
+ <el-table-column prop="time" label="棰勮鏃堕棿" width="180" />
+ <el-table-column prop="content" label="棰勮鍐呭" />
+ <el-table-column prop="score" label="褰撴椂璇勫垎" width="120" />
+ <el-table-column label="澶勭悊鐘舵��" width="120">
+ <template #default="scope">
+ <el-tag :type="scope.row.handled ? 'success' : 'danger'">
+ {{ scope.row.handled ? '宸插鐞�' : '鏈鐞�' }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </div>
+ </el-drawer>
+
+ <!-- 璇勫垎妯″瀷閰嶇疆寮圭獥 -->
+ <el-dialog v-model="modelConfigVisible" title="璇勫垎妯″瀷閰嶇疆" width="80%">
+ <div class="model-config-content">
+ <!-- 杩欓噷搴旇闆嗘垚鐪熷疄鐨勯厤缃〃鍗� -->
+ <el-empty description="閰嶇疆琛ㄥ崟鍔犺浇涓�..." />
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="modelConfigVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="saveModelConfig">淇濆瓨閰嶇疆</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, onMounted } from 'vue'
+import { Setting, ArrowUp, ArrowDown } from '@element-plus/icons-vue'
+
+// 鐘舵��
+const activeView = ref('list')
+const drawerVisible = ref(false)
+const modelConfigVisible = ref(false)
+const selectedShop = ref(null)
+const isAdmin = ref(true) // 妯℃嫙绠$悊鍛樻潈闄�
+const filterCode = ref('all')
+
+// 缁熻鏁版嵁
+const statistics = reactive({
+ greenCount: 125,
+ greenPercentage: 65.8,
+ yellowCount: 45,
+ yellowPercentage: 23.7,
+ redCount: 20,
+ redPercentage: 10.5,
+})
+
+// 搴楅摵鍚嶇О鍒楄〃
+const shopNames = [
+ '浠樺皬濮愬湪鎴愰兘',
+ '鍚夊埢鑱旂洘',
+ '瀹跺湪濉斿暒',
+ '鐙兼潵浜�',
+ '涔愬嚡鎾掓槦娓稿簵',
+ '棣ㄨ繙缇庨灏忛晣锛堝搱灏肩編椋熷箍鍦猴級',
+ '妫掔害缈�',
+ '寮勫爞鍜亾',
+ '鏉ㄨ榻愰綈鍝堝皵鐑よ倝',
+ '涓婃捣绋斾紶椁愰ギ绠$悊鏈夐檺鍏徃锛堜汉鐢熶竴涓诧級',
+ '缂樺',
+ '娉夌洓椁愰ギ锛堜笂娴凤級鏈夐檺鍏徃锛堥鍏跺锛�',
+ '涓拌寕鐑や覆',
+ '涓婃捣娉扮厡椁愰ギ绠$悊鏈夐檺鍏徃锛堟嘲鐓岄浮锛�',
+ '寰愭眹鍖鸿景鐔欓棣�(灏忛搧鍚涗覆鐑у眳閰掑眿)',
+]
+
+// 寰愭眹鍖鸿闀囧垪琛�
+const xuhuiTowns = [
+ '澶╁钩璺閬�',
+ '婀栧崡璺閬�',
+ '鏂滃湡璺閬�',
+ '鏋灄璺閬�',
+ '闀挎ˉ琛楅亾',
+ '鐢版灄琛楅亾',
+ '铏规璺閬�',
+ '搴峰仴鏂版潙琛楅亾',
+ '寰愬姹囪閬�',
+ '鍑屼簯璺閬�',
+ '榫欏崕琛楅亾',
+ '婕曟渤娉捐閬�',
+ '鍗庢尘闀�',
+]
+
+// 鐢熸垚2023骞�8鏈堝唴鐨勯殢鏈烘椂闂�
+function generateRandomDate() {
+ const year = 2023
+ const month = 7 // 0-11锛�8鏈堟槸7
+ const day = Math.floor(Math.random() * 31) + 1 // 1-31
+ const hour = Math.floor(Math.random() * 24) // 0-23
+ const minute = Math.floor(Math.random() * 60) // 0-59
+
+ const date = new Date(year, month, day, hour, minute)
+ return date.toISOString().slice(0, 16).replace('T', ' ')
+}
+
+// 闅忔満閫夋嫨鏁扮粍鍏冪礌
+function getRandomElement(array) {
+ return array[Math.floor(Math.random() * array.length)]
+}
+
+// 鐢熸垚闅忔満璇勫垎瓒嬪娍
+function generateRandomTrend() {
+ return Math.floor(Math.random() * 11) - 5 // -5 鍒� 5
+}
+
+// 搴楅摵鏁版嵁
+const shopList = ref([
+ {
+ id: 1,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'green',
+ score: 95,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [
+ {
+ time: generateRandomDate(),
+ content: '鍑�鍖栧櫒杩愯鏃堕暱涓嶈冻',
+ score: 90,
+ handled: true,
+ },
+ ],
+ },
+ {
+ id: 2,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'yellow',
+ score: 75,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [
+ {
+ time: generateRandomDate(),
+ content: '鎶曡瘔娆℃暟杈冨',
+ score: 80,
+ handled: false,
+ },
+ ],
+ },
+ {
+ id: 3,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'red',
+ score: 60,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [
+ {
+ time: generateRandomDate(),
+ content: '鎺掓斁娴撳害瓒呮爣',
+ score: 65,
+ handled: false,
+ },
+ {
+ time: generateRandomDate(),
+ content: '娓呮礂棰戞涓嶈冻',
+ score: 62,
+ handled: false,
+ },
+ ],
+ },
+ {
+ id: 4,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'green',
+ score: 92,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [],
+ },
+ {
+ id: 5,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'yellow',
+ score: 78,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [
+ {
+ time: generateRandomDate(),
+ content: '椋庢満鑱斿姩鐜囦綆',
+ score: 75,
+ handled: true,
+ },
+ ],
+ },
+ {
+ id: 6,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'green',
+ score: 90,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [],
+ },
+ {
+ id: 7,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'red',
+ score: 55,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [
+ {
+ time: generateRandomDate(),
+ content: '鏈畨瑁呮补鐑熷噣鍖栬澶�',
+ score: 60,
+ handled: false,
+ },
+ ],
+ },
+ {
+ id: 8,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'yellow',
+ score: 72,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [
+ {
+ time: generateRandomDate(),
+ content: '鍑�鍖栧櫒娓呮礂涓嶅強鏃�',
+ score: 75,
+ handled: true,
+ },
+ ],
+ },
+ {
+ id: 9,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'green',
+ score: 93,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [],
+ },
+ {
+ id: 10,
+ shopName: getRandomElement(shopNames),
+ district: '寰愭眹鍖�',
+ town: getRandomElement(xuhuiTowns),
+ code: 'yellow',
+ score: 76,
+ trend: generateRandomTrend(),
+ lastUpdate: generateRandomDate(),
+ warnings: [
+ {
+ time: generateRandomDate(),
+ content: '鎺掓斁娴撳害鎺ヨ繎鏍囧噯闄愬��',
+ score: 78,
+ handled: true,
+ },
+ ],
+ },
+])
+
+// 杩囨护鍚庣殑搴楅摵鍒楄〃
+const filteredShopList = computed(() => {
+ if (filterCode.value === 'all') {
+ return shopList.value
+ }
+ return shopList.value.filter((shop) => shop.code === filterCode.value)
+})
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+ // 杩欓噷鍙互浠嶢PI鑾峰彇鏁版嵁
+ console.log('鐜俊鐮佺鐞嗛〉闈㈠姞杞�')
+})
+
+// 鏂规硶
+function onBack() {
+ // 鍥為��閫昏緫
+ console.log('鍥為��')
+}
+
+function filterByCode(code) {
+ filterCode.value = code === filterCode.value ? 'all' : code
+ activeView.value = 'list' // 鍒囨崲鍒板垪琛ㄨ鍥�
+}
+
+function getCodeType(code) {
+ switch (code) {
+ case 'green':
+ return 'success'
+ case 'yellow':
+ return 'warning'
+ case 'red':
+ return 'danger'
+ default:
+ return ''
+ }
+}
+
+function getCodeText(code) {
+ switch (code) {
+ case 'green':
+ return '缁跨爜'
+ case 'yellow':
+ return '榛勭爜'
+ case 'red':
+ return '绾㈢爜'
+ default:
+ return ''
+ }
+}
+
+function viewDetails(shop) {
+ selectedShop.value = shop
+ drawerVisible.value = true
+}
+
+function viewRiskWarnings(shop) {
+ selectedShop.value = shop
+ drawerVisible.value = true
+ // 杩欓噷鍙互婊氬姩鍒伴闄╅璀﹂儴鍒�
+}
+
+function openModelConfig() {
+ modelConfigVisible.value = true
+}
+
+function saveModelConfig() {
+ // 淇濆瓨閰嶇疆閫昏緫
+ modelConfigVisible.value = false
+ console.log('淇濆瓨璇勫垎妯″瀷閰嶇疆')
+}
+</script>
+
+<style scoped>
+.huanxin-code-manage {
+ padding: 20px;
+}
+
+.dashboard {
+ margin-bottom: 30px;
+}
+
+.dashboard-card {
+ cursor: pointer;
+ transition: all 0.3s ease;
+}
+
+.dashboard-card:hover {
+ transform: translateY(-5px);
+}
+
+.card-content {
+ text-align: center;
+ padding: 20px 0;
+}
+
+.card-title {
+ font-size: 16px;
+ margin-bottom: 10px;
+}
+
+.card-value {
+ font-size: 32px;
+ font-weight: bold;
+ margin-bottom: 5px;
+}
+
+.card-percentage {
+ font-size: 14px;
+ opacity: 0.8;
+}
+
+.green-card .card-value {
+ color: #67c23a;
+}
+
+.yellow-card .card-value {
+ color: #e6a23c;
+}
+
+.red-card .card-value {
+ color: #f56c6c;
+}
+
+.model-config {
+ text-align: right;
+ margin-bottom: 20px;
+}
+
+.view-tabs {
+ margin-bottom: 20px;
+}
+
+.trend {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.trend-icon {
+ margin-right: 5px;
+}
+
+.trend-icon.up {
+ color: #67c23a;
+}
+
+.trend-icon.down {
+ color: #f56c6c;
+}
+
+.trend .up {
+ color: #67c23a;
+}
+
+.trend .down {
+ color: #f56c6c;
+}
+
+.map-container {
+ position: relative;
+ height: 600px;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+}
+
+.map-placeholder {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.map-legend {
+ position: absolute;
+ bottom: 20px;
+ right: 20px;
+ background: white;
+ padding: 10px;
+ border-radius: 4px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.legend-item {
+ display: flex;
+ align-items: center;
+ margin-bottom: 5px;
+}
+
+.legend-dot {
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ margin-right: 8px;
+}
+
+.legend-dot.green {
+ background-color: #67c23a;
+}
+
+.legend-dot.yellow {
+ background-color: #e6a23c;
+}
+
+.legend-dot.red {
+ background-color: #f56c6c;
+}
+
+.shop-details {
+ padding: 20px;
+}
+
+.code-header {
+ display: flex;
+ align-items: center;
+ margin-bottom: 30px;
+}
+
+.code-icon {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 24px;
+ font-weight: bold;
+ color: white;
+ margin-right: 30px;
+}
+
+.code-icon.green {
+ background-color: #67c23a;
+}
+
+.code-icon.yellow {
+ background-color: #e6a23c;
+}
+
+.code-icon.red {
+ background-color: #f56c6c;
+}
+
+.score-info {
+ flex: 1;
+}
+
+.score-label {
+ font-size: 16px;
+ margin-bottom: 5px;
+}
+
+.score-value {
+ font-size: 48px;
+ font-weight: bold;
+}
+
+.chart-section {
+ margin-bottom: 30px;
+}
+
+.chart-section h3 {
+ margin-bottom: 15px;
+ font-size: 18px;
+}
+
+.radar-chart,
+.trend-chart {
+ height: 300px;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.warning-section {
+ margin-top: 30px;
+}
+
+.warning-section h3 {
+ margin-bottom: 15px;
+ font-size: 18px;
+}
+</style>
diff --git a/src/views/inspection/scenenew/UserEdit.vue b/src/views/inspection/scenenew/UserEdit.vue
index 1db19c5..9785e22 100644
--- a/src/views/inspection/scenenew/UserEdit.vue
+++ b/src/views/inspection/scenenew/UserEdit.vue
@@ -49,7 +49,7 @@
</FormCol>
</el-tab-pane>
- <el-tab-pane label="鍗卞簾鎺掓薄" name="third">
+ <!-- <el-tab-pane label="鍗卞簾鎺掓薄" name="third">
<FormCol>
<div class="sub-title">鍗卞簾鎺掓薄娓呭崟</div>
<CompHazardousWasteFile :form-info="formHazardousWasteFile" />
@@ -58,28 +58,26 @@
<div class="sub-title">鍗卞簾鎺掓薄璁板綍</div>
<CompHazardousWasteRecord :form-info="formHazardousWasteRecord" />
</FormCol>
- </el-tab-pane>
+ </el-tab-pane> -->
<el-tab-pane label="琛屾斂澶勭綒" name="fourth">
- <FormCol>
- <div class="sub-title">琛屾斂澶勭綒琛�</div>
- <!-- <CompPunishment :form-info="formProblem" /> -->
- </FormCol>
+ <!-- <FormCol> -->
+ <CompPunishment />
+ <!-- </FormCol> -->
</el-tab-pane>
<el-tab-pane label="淇¤鎶曡瘔" name="fifth">
- <FormCol>
- <div class="sub-title">淇¤鎶曡瘔</div>
- <!-- <CompLaint :form-info="formLaint" /> -->
- </FormCol>
+ <!-- <FormCol> -->
+ <CompLaint />
+ <!-- </FormCol> -->
</el-tab-pane>
- <el-tab-pane label="宸℃煡闂琛�" name="sixth">
+ <!-- <el-tab-pane label="宸℃煡闂琛�" name="sixth">
<FormCol>
<div class="sub-title">宸℃煡闂琛�</div>
- <!-- <CompProblem :form-info="formProblem" /> -->
+ <CompProblem :form-info="formProblem" />
</FormCol>
- </el-tab-pane>
+ </el-tab-pane> -->
</el-tabs>
<!-- <ComBaseInformation v-model="drawer"></ComBaseInformation> -->
@@ -93,6 +91,8 @@
import CompDeviceInfo from './components/CompDeviceInfo.vue'
import CompHazardousWasteFile from './components/CompHazardousWasteFile.vue'
import CompHazardousWasteRecord from './components/CompHazardousWasteRecord.vue'
+import CompLaint from './components/CompLaint.vue'
+import CompPunishment from './components/CompPunishment.vue'
export default {
components: {
@@ -102,14 +102,15 @@
CompSceneInfo,
CompCompanyInfo,
CompDeviceInfo,
- CompHazardousWasteFile,
- CompHazardousWasteRecord,
+ CompPunishment,
+ CompLaint,
+ // CompHazardousWasteFile,
+ // CompHazardousWasteRecord,
// CompPanyInfo,
// CompFumePurifyDevice,
// CompHazardousWasteFile,
// CompHazardousWasteRecord,
// CompProblem,
- // CompPunishment,
// CompRestaurantBaseInfo,
// CompVehicleBaseInfo,
// CompUserInfos,
diff --git a/src/views/inspection/scenenew/components/CompLaint.vue b/src/views/inspection/scenenew/components/CompLaint.vue
new file mode 100644
index 0000000..11adcfa
--- /dev/null
+++ b/src/views/inspection/scenenew/components/CompLaint.vue
@@ -0,0 +1,310 @@
+<template>
+ <div>
+ <el-row class="sub-title" justify="space-between">
+ <div>淇¤鎶曡瘔璁板綍</div>
+ <el-button-group>
+ <el-button type="primary" @click="handleAdd">
+ <el-icon><Plus /></el-icon>
+ <span>鏂板鎶曡瘔璁板綍</span>
+ </el-button>
+ <el-button type="success" @click="dialogImportVisible = true">
+ <el-icon><Upload /></el-icon>
+ <span>瀵煎叆璁板綍</span>
+ </el-button>
+ </el-button-group>
+ </el-row>
+
+ <!-- 琛ㄦ牸灞曠ず -->
+ <el-table :data="laintList" style="width: 100%" :show-overflow-tooltip="true">
+ <el-table-column prop="reason" label="鎶曡瘔鍘熷洜" />
+ <el-table-column prop="demand" label="鎶曡瘔璇夋眰" />
+ <el-table-column prop="laintTime" label="鎶曡瘔鏃堕棿" width="180" />
+ <el-table-column prop="source" label="鎶曡瘔鏉ユ簮" width="150" />
+ <el-table-column prop="department" label="澶勭悊閮ㄩ棬" width="150" />
+ <el-table-column prop="result" label="鎶曡瘔缁撴灉" width="150" />
+ <el-table-column label="鎿嶄綔" width="150" fixed="right">
+ <template #default="scope">
+ <el-button size="small" @click="handleEdit(scope.row)">淇敼</el-button>
+ <el-button size="small" type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 绌虹姸鎬� -->
+ <div v-if="laintList.length === 0" class="empty-state">
+ <el-empty description="鏆傛棤淇¤鎶曡瘔璁板綍" />
+ </div>
+
+ <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%">
+ <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+ <el-form-item label="鎶曡瘔鍘熷洜" prop="reason">
+ <el-input v-model="form.reason" placeholder="璇疯緭鍏ユ姇璇夊師鍥�" type="textarea" rows="3" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔璇夋眰" prop="demand">
+ <el-input v-model="form.demand" placeholder="璇疯緭鍏ユ姇璇夎瘔姹�" type="textarea" rows="3" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔鏃堕棿" prop="laintTime">
+ <el-date-picker
+ v-model="form.laintTime"
+ type="date"
+ placeholder="璇烽�夋嫨鎶曡瘔鏃堕棿"
+ style="width: 100%"
+ />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔鏉ユ簮" prop="source">
+ <el-input v-model="form.source" placeholder="璇疯緭鍏ユ姇璇夋潵婧�" />
+ </el-form-item>
+ <el-form-item label="澶勭悊閮ㄩ棬" prop="department">
+ <el-input v-model="form.department" placeholder="璇疯緭鍏ュ鐞嗛儴闂�" />
+ </el-form-item>
+ <el-form-item label="鎶曡瘔缁撴灉" prop="result">
+ <el-input v-model="form.result" placeholder="璇疯緭鍏ユ姇璇夌粨鏋�" type="textarea" rows="2" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleSubmit">纭畾</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- Excel瀵煎叆瀵硅瘽妗� -->
+ <el-dialog v-model="dialogImportVisible" title="瀵煎叆鎶曡瘔璁板綍" width="50%">
+ <el-upload
+ class="upload-demo"
+ action="#"
+ :auto-upload="false"
+ :on-change="handleFileChange"
+ :show-file-list="false"
+ accept=".xlsx,.xls"
+ >
+ <el-button type="primary">閫夋嫨Excel鏂囦欢</el-button>
+ <template #tip>
+ <div class="el-upload__tip">璇蜂笂浼�.xlsx鎴�.xls鏍煎紡鐨勬枃浠�</div>
+ </template>
+ </el-upload>
+ <div v-if="uploadedFile" class="uploaded-file">
+ <el-icon><Document /></el-icon>
+ <span>{{ uploadedFile.name }}</span>
+ <el-button type="text" @click="uploadedFile = null">绉婚櫎</el-button>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogImportVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleImport" :loading="importLoading">瀵煎叆</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+import { Plus, Upload, Document } from '@element-plus/icons-vue'
+
+// 琛ㄥ崟鏁版嵁
+const form = reactive({
+ reason: '',
+ demand: '',
+ laintTime: '',
+ source: '',
+ department: '',
+ result: '',
+})
+
+// 楠岃瘉瑙勫垯
+const rules = reactive({
+ reason: [{ required: true, message: '璇疯緭鍏ユ姇璇夊師鍥�', trigger: 'blur' }],
+ demand: [{ required: true, message: '璇疯緭鍏ユ姇璇夎瘔姹�', trigger: 'blur' }],
+ laintTime: [{ required: true, message: '璇疯緭鍏ユ姇璇夋椂闂�', trigger: 'blur' }],
+ source: [{ required: true, message: '璇疯緭鍏ユ姇璇夋潵婧�', trigger: 'blur' }],
+ department: [{ required: true, message: '璇疯緭鍏ュ鐞嗛儴闂�', trigger: 'blur' }],
+ result: [{ required: true, message: '璇疯緭鍏ユ姇璇夌粨鏋�', trigger: 'blur' }],
+})
+
+// 鐘舵��
+const dialogVisible = ref(false)
+const dialogImportVisible = ref(false)
+const dialogTitle = ref('鏂板淇¤鎶曡瘔')
+const formRef = ref(null)
+const laintList = ref([])
+const currentRow = ref(null)
+const uploadedFile = ref(null)
+const importLoading = ref(false)
+
+// 妯℃嫙鏁版嵁
+onMounted(() => {
+ // 杩欓噷鍙互浠嶢PI鑾峰彇鏁版嵁
+ // 鏆傛椂浣跨敤妯℃嫙鏁版嵁
+ laintList.value = [
+ {
+ id: 1,
+ reason: '娌圭儫鎵版皯',
+ demand: '瑕佹眰瀹夎娌圭儫鍑�鍖栬澶�',
+ laintTime: '2026-01-10',
+ source: '甯傛皯鐑嚎',
+ department: '鐜繚灞�',
+ result: '宸茶矗浠ゅ畨瑁呮补鐑熷噣鍖栬澶�',
+ },
+ {
+ id: 2,
+ reason: '鍣煶姹℃煋',
+ demand: '瑕佹眰闄嶄綆璁惧鍣煶',
+ laintTime: '2026-02-15',
+ source: '淇¤鍔�',
+ department: '鐜繚灞�',
+ result: '宸茶姹傛暣鏀瑰櫔闊抽棶棰�',
+ },
+ ]
+})
+
+// 鏂板
+function handleAdd() {
+ form.reason = ''
+ form.demand = ''
+ form.laintTime = ''
+ form.source = ''
+ form.department = ''
+ form.result = ''
+ dialogTitle.value = '鏂板淇¤鎶曡瘔'
+ currentRow.value = null
+ dialogVisible.value = true
+}
+
+// 缂栬緫
+function handleEdit(row) {
+ currentRow.value = row
+ form.reason = row.reason
+ form.demand = row.demand
+ form.laintTime = row.laintTime
+ form.source = row.source
+ form.department = row.department
+ form.result = row.result
+ dialogTitle.value = '淇敼淇¤鎶曡瘔'
+ dialogVisible.value = true
+}
+
+// 鍒犻櫎
+function handleDelete(row) {
+ ElMessage.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ })
+ .then(() => {
+ const index = laintList.value.findIndex((item) => item.id === row.id)
+ if (index !== -1) {
+ laintList.value.splice(index, 1)
+ ElMessage.success('鍒犻櫎鎴愬姛')
+ }
+ })
+ .catch(() => {
+ // 鍙栨秷鍒犻櫎
+ })
+}
+
+// 鎻愪氦
+function handleSubmit() {
+ formRef.value.validate((valid) => {
+ if (valid) {
+ if (currentRow.value) {
+ // 淇敼
+ const index = laintList.value.findIndex((item) => item.id === currentRow.value.id)
+ if (index !== -1) {
+ laintList.value[index] = {
+ ...currentRow.value,
+ ...form,
+ }
+ ElMessage.success('淇敼鎴愬姛')
+ }
+ } else {
+ // 鏂板
+ const newItem = {
+ id: Date.now(),
+ ...form,
+ }
+ laintList.value.push(newItem)
+ ElMessage.success('鏂板鎴愬姛')
+ }
+ dialogVisible.value = false
+ }
+ })
+}
+
+// 澶勭悊鏂囦欢閫夋嫨
+function handleFileChange(file) {
+ uploadedFile.value = file.raw
+}
+
+// 澶勭悊Excel瀵煎叆
+function handleImport() {
+ if (!uploadedFile.value) {
+ ElMessage.warning('璇烽�夋嫨瑕佸鍏ョ殑Excel鏂囦欢')
+ return
+ }
+
+ importLoading.value = true
+
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨凟xcel瑙f瀽鍜屽鍏ラ�昏緫
+ // 鏆傛椂妯℃嫙瀵煎叆杩囩▼
+ setTimeout(() => {
+ // 妯℃嫙瀵煎叆鏁版嵁
+ const importedData = [
+ {
+ id: Date.now() + 1,
+ reason: '搴熸皵鎺掓斁瓒呮爣',
+ demand: '瑕佹眰杈炬爣鎺掓斁',
+ laintTime: '2026-03-01',
+ source: '鐜繚鐑嚎',
+ department: '鐜繚灞�',
+ result: '宸茶姹傛暣鏀�',
+ },
+ {
+ id: Date.now() + 2,
+ reason: '寮傚懗鎵版皯',
+ demand: '娑堥櫎寮傚懗',
+ laintTime: '2026-03-10',
+ source: '甯傛皯鎶曡瘔',
+ department: '鐜繚灞�',
+ result: '宸茬幇鍦烘鏌�',
+ },
+ ]
+
+ // 娣诲姞鍒板垪琛�
+ laintList.value.push(...importedData)
+
+ ElMessage.success('瀵煎叆鎴愬姛锛屽叡瀵煎叆2鏉¤褰�')
+ dialogImportVisible.value = false
+ uploadedFile.value = null
+ importLoading.value = false
+ }, 1500)
+}
+</script>
+
+<style scoped>
+.empty-state {
+ padding: 40px 0;
+ text-align: center;
+}
+.sub-title {
+ margin-bottom: 20px;
+}
+.uploaded-file {
+ margin-top: 20px;
+ padding: 10px;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+}
+.uploaded-file span {
+ margin-left: 10px;
+ flex: 1;
+}
+.uploaded-file .el-button {
+ margin-left: 10px;
+}
+</style>
diff --git a/src/views/inspection/scenenew/components/CompPunishment.vue b/src/views/inspection/scenenew/components/CompPunishment.vue
new file mode 100644
index 0000000..b70fd7e
--- /dev/null
+++ b/src/views/inspection/scenenew/components/CompPunishment.vue
@@ -0,0 +1,298 @@
+<template>
+ <div>
+ <el-row class="sub-title" justify="space-between">
+ <div>琛屾斂澶勭綒璁板綍</div>
+ <el-button-group>
+ <el-button type="primary" @click="handleAdd">
+ <el-icon><Plus /></el-icon>
+ <span>鏂板澶勭綒璁板綍</span>
+ </el-button>
+ <el-button type="success" @click="dialogImportVisible = true">
+ <el-icon><Upload /></el-icon>
+ <span>瀵煎叆璁板綍</span>
+ </el-button>
+ </el-button-group>
+ </el-row>
+
+ <!-- 琛ㄦ牸灞曠ず -->
+ <el-table :data="punishmentList" style="width: 100%">
+ <el-table-column prop="name" label="澶勭綒浜嬮」" width="180" />
+ <el-table-column prop="punishTime" label="澶勭綒鏃堕棿" width="180" />
+ <el-table-column prop="reason" label="澶勭綒鐞嗙敱" />
+ <el-table-column prop="result" label="澶勭綒缁撴灉" width="180" />
+ <el-table-column prop="department" label="澶勭綒閮ㄩ棬" width="180" />
+ <el-table-column label="鎿嶄綔" width="150" fixed="right">
+ <template #default="scope">
+ <el-button size="small" @click="handleEdit(scope.row)">淇敼</el-button>
+ <el-button size="small" type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 绌虹姸鎬� -->
+ <div v-if="punishmentList.length === 0" class="empty-state">
+ <el-empty description="鏆傛棤琛屾斂澶勭綒璁板綍" />
+ </div>
+
+ <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%">
+ <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+ <el-form-item label="琛屾斂澶勭綒鍚嶇О" prop="name">
+ <el-input v-model="form.name" placeholder="璇疯緭鍏ヨ鏀垮缃氬悕绉�" />
+ </el-form-item>
+ <el-form-item label="澶勭綒鏃堕棿" prop="punishTime">
+ <el-date-picker
+ v-model="form.punishTime"
+ type="date"
+ placeholder="璇烽�夋嫨澶勭綒鏃堕棿"
+ style="width: 100%"
+ />
+ </el-form-item>
+ <el-form-item label="澶勭綒鐞嗙敱" prop="reason">
+ <el-input v-model="form.reason" placeholder="璇疯緭鍏ュ缃氱悊鐢�" type="textarea" rows="3" />
+ </el-form-item>
+ <el-form-item label="澶勭綒缁撴灉" prop="result">
+ <el-input v-model="form.result" placeholder="璇疯緭鍏ュ缃氱粨鏋�" />
+ </el-form-item>
+ <el-form-item label="澶勭綒閮ㄩ棬" prop="department">
+ <el-input v-model="form.department" placeholder="璇疯緭鍏ュ缃氶儴闂�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleSubmit">纭畾</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- Excel瀵煎叆瀵硅瘽妗� -->
+ <el-dialog v-model="dialogImportVisible" title="瀵煎叆澶勭綒璁板綍" width="50%">
+ <el-upload
+ class="upload-demo"
+ action="#"
+ :auto-upload="false"
+ :on-change="handleFileChange"
+ :show-file-list="false"
+ accept=".xlsx,.xls"
+ >
+ <el-button type="primary">閫夋嫨Excel鏂囦欢</el-button>
+ <template #tip>
+ <div class="el-upload__tip">璇蜂笂浼�.xlsx鎴�.xls鏍煎紡鐨勬枃浠�</div>
+ </template>
+ </el-upload>
+ <div v-if="uploadedFile" class="uploaded-file">
+ <el-icon><Document /></el-icon>
+ <span>{{ uploadedFile.name }}</span>
+ <el-button type="text" @click="uploadedFile = null">绉婚櫎</el-button>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogImportVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleImport" :loading="importLoading">瀵煎叆</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Plus, Upload, Document } from '@element-plus/icons-vue'
+
+// 琛ㄥ崟鏁版嵁
+const form = reactive({
+ name: '',
+ punishTime: '',
+ reason: '',
+ result: '',
+ department: '',
+})
+
+// 楠岃瘉瑙勫垯
+const rules = reactive({
+ name: [{ required: true, message: '璇疯緭鍏ヨ鏀垮缃氬悕绉�', trigger: 'blur' }],
+ punishTime: [{ required: true, message: '璇疯緭鍏ュ缃氭椂闂�', trigger: 'blur' }],
+ reason: [{ required: true, message: '璇疯緭鍏ュ缃氱悊鐢�', trigger: 'blur' }],
+ result: [{ required: true, message: '璇疯緭鍏ュ缃氱粨鏋�', trigger: 'blur' }],
+ department: [{ required: true, message: '璇疯緭鍏ュ缃氶儴闂�', trigger: 'blur' }],
+})
+
+// 鐘舵��
+const dialogVisible = ref(false)
+const dialogImportVisible = ref(false)
+const dialogTitle = ref('鏂板琛屾斂澶勭綒')
+const formRef = ref(null)
+const punishmentList = ref([])
+const currentRow = ref(null)
+const uploadedFile = ref(null)
+const importLoading = ref(false)
+
+// 妯℃嫙鏁版嵁
+onMounted(() => {
+ // 杩欓噷鍙互浠嶢PI鑾峰彇鏁版嵁
+ // 鏆傛椂浣跨敤妯℃嫙鏁版嵁
+ punishmentList.value = [
+ {
+ id: 1,
+ name: '杩濊鎺掓斁搴熸皵',
+ punishTime: '2026-01-15',
+ reason: '鏈寜瑙勫畾澶勭悊搴熸皵锛岃秴鏍囨帓鏀�',
+ result: '缃氭5000鍏�',
+ department: '鐜繚灞�',
+ },
+ {
+ id: 2,
+ name: '鏈畨瑁呮补鐑熷噣鍖栬澶�',
+ punishTime: '2026-02-20',
+ reason: '椁愬巺鏈畨瑁呮补鐑熷噣鍖栬澶�',
+ result: '璐d护闄愭湡鏁存敼',
+ department: '鐜繚灞�',
+ },
+ ]
+})
+
+// 鏂板
+function handleAdd() {
+ form.name = ''
+ form.punishTime = ''
+ form.reason = ''
+ form.result = ''
+ form.department = ''
+ dialogTitle.value = '鏂板琛屾斂澶勭綒'
+ currentRow.value = null
+ dialogVisible.value = true
+}
+
+// 缂栬緫
+function handleEdit(row) {
+ currentRow.value = row
+ form.name = row.name
+ form.punishTime = row.punishTime
+ form.reason = row.reason
+ form.result = row.result
+ form.department = row.department
+ dialogTitle.value = '淇敼琛屾斂澶勭綒'
+ dialogVisible.value = true
+}
+
+// 鍒犻櫎
+function handleDelete(row) {
+ ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ })
+ .then(() => {
+ const index = punishmentList.value.findIndex((item) => item.id === row.id)
+ if (index !== -1) {
+ punishmentList.value.splice(index, 1)
+ ElMessage.success('鍒犻櫎鎴愬姛')
+ }
+ })
+ .catch(() => {
+ // 鍙栨秷鍒犻櫎
+ })
+}
+
+// 鎻愪氦
+function handleSubmit() {
+ formRef.value.validate((valid) => {
+ if (valid) {
+ if (currentRow.value) {
+ // 淇敼
+ const index = punishmentList.value.findIndex((item) => item.id === currentRow.value.id)
+ if (index !== -1) {
+ punishmentList.value[index] = {
+ ...currentRow.value,
+ ...form,
+ }
+ ElMessage.success('淇敼鎴愬姛')
+ }
+ } else {
+ // 鏂板
+ const newItem = {
+ id: Date.now(),
+ ...form,
+ }
+ punishmentList.value.push(newItem)
+ ElMessage.success('鏂板鎴愬姛')
+ }
+ dialogVisible.value = false
+ }
+ })
+}
+
+// 澶勭悊鏂囦欢閫夋嫨
+function handleFileChange(file) {
+ uploadedFile.value = file.raw
+}
+
+// 澶勭悊Excel瀵煎叆
+function handleImport() {
+ if (!uploadedFile.value) {
+ ElMessage.warning('璇烽�夋嫨瑕佸鍏ョ殑Excel鏂囦欢')
+ return
+ }
+
+ importLoading.value = true
+
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨凟xcel瑙f瀽鍜屽鍏ラ�昏緫
+ // 鏆傛椂妯℃嫙瀵煎叆杩囩▼
+ setTimeout(() => {
+ // 妯℃嫙瀵煎叆鏁版嵁
+ const importedData = [
+ {
+ id: Date.now() + 1,
+ name: '鏈寜瑙勫畾鎺掓斁姹℃按',
+ punishTime: '2026-03-05',
+ reason: '鏈寜瑙勫畾澶勭悊姹℃按锛岃秴鏍囨帓鏀�',
+ result: '缃氭8000鍏�',
+ department: '鐜繚灞�',
+ },
+ {
+ id: Date.now() + 2,
+ name: '杩濊鍊惧�掑浐搴�',
+ punishTime: '2026-03-12',
+ reason: '杩濊鍊惧�掑浐浣撳簾鐗�',
+ result: '缃氭10000鍏�',
+ department: '鐜繚灞�',
+ },
+ ]
+
+ // 娣诲姞鍒板垪琛�
+ punishmentList.value.push(...importedData)
+
+ ElMessage.success('瀵煎叆鎴愬姛锛屽叡瀵煎叆2鏉¤褰�')
+ dialogImportVisible.value = false
+ uploadedFile.value = null
+ importLoading.value = false
+ }, 1500)
+}
+</script>
+
+<style scoped>
+.empty-state {
+ padding: 40px 0;
+ text-align: center;
+}
+.sub-title {
+ margin-bottom: 20px;
+}
+.uploaded-file {
+ margin-top: 20px;
+ padding: 10px;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+}
+.uploaded-file span {
+ margin-left: 10px;
+ flex: 1;
+}
+.uploaded-file .el-button {
+ margin-left: 10px;
+}
+</style>
diff --git a/src/views/monitor/DataException.vue b/src/views/monitor/DataException.vue
index b678d8a..271d46b 100644
--- a/src/views/monitor/DataException.vue
+++ b/src/views/monitor/DataException.vue
@@ -19,7 +19,7 @@
</div>
<div class="form-row">
<div class="form-item full-width">
- <TimeSelect @submit-time="giveTime" :useNewStyle="true"></TimeSelect>
+ <TimeSelect @submit-time="giveTime" :useNewStyle="false"></TimeSelect>
</div>
</div>
</div>
--
Gitblit v1.9.3