From ffe06be91f95ffd2459ebdb2f9130d1e38d53ea7 Mon Sep 17 00:00:00 2001
From: zzw <228544128@qq.com>
Date: 星期二, 06 十月 2026 18:32:34 +0800
Subject: [PATCH] fix: preserve manually edited menu names

---
 emergency-repair-web/src/views/system/ErrorLogManage.vue |  152 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 152 insertions(+), 0 deletions(-)

diff --git a/emergency-repair-web/src/views/system/ErrorLogManage.vue b/emergency-repair-web/src/views/system/ErrorLogManage.vue
new file mode 100644
index 0000000..162d9c7
--- /dev/null
+++ b/emergency-repair-web/src/views/system/ErrorLogManage.vue
@@ -0,0 +1,152 @@
+<template>
+  <div class="page">
+    <div class="page-title">
+      <div><h2>閿欒鏃ュ織</h2><p>璁板綍绋嬪簭杩愯涓殑鏈鐞嗗紓甯革紝渚夸簬瀹氫綅鍜屼慨澶嶇己闄�</p></div>
+    </div>
+    <div class="table-panel">
+      <div class="toolbar">
+        <el-input v-model="filters.keyword" clearable placeholder="璐︽埛鍚� / 濮撳悕 / 璇锋眰鍦板潃 / 寮傚父淇℃伅" style="width:280px" @keyup.enter.native="search"></el-input>
+        <el-select v-model="filters.module" clearable placeholder="妯″潡" style="width:150px">
+          <el-option v-for="item in modules" :key="item" :label="item" :value="item"></el-option>
+        </el-select>
+        <el-input v-model="filters.exceptionType" clearable placeholder="寮傚父绫诲瀷" style="width:220px" @keyup.enter.native="search"></el-input>
+        <el-date-picker
+          v-model="filters.dates"
+          type="daterange"
+          value-format="yyyy-MM-dd"
+          range-separator="鑷�"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+          style="width:260px"
+        ></el-date-picker>
+        <el-button type="primary" icon="el-icon-search" v-permission="'system:error-logs:query'" @click="search">鏌ヨ</el-button>
+        <el-button icon="el-icon-refresh-left" @click="reset">閲嶇疆</el-button>
+      </div>
+      <el-table v-loading="loading" :data="rows" border stripe height="calc(100vh - 250px)">
+        <el-table-column prop="errorTime" label="鍙戠敓鏃堕棿" width="180"></el-table-column>
+        <el-table-column prop="userName" label="璐︽埛鍚�" width="120"></el-table-column>
+        <el-table-column prop="nickName" label="濮撳悕" width="110"></el-table-column>
+        <el-table-column prop="module" label="妯″潡" width="120"></el-table-column>
+        <el-table-column prop="requestMethod" label="鏂瑰紡" width="75" align="center"></el-table-column>
+        <el-table-column prop="requestUri" label="璇锋眰鍦板潃" min-width="230" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="exceptionType" label="寮傚父绫诲瀷" min-width="220" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="message" label="寮傚父淇℃伅" min-width="280" show-overflow-tooltip></el-table-column>
+        <el-table-column label="鎿嶄綔" width="80" fixed="right">
+          <template slot-scope="{ row }">
+            <el-button type="text" v-permission="'system:error-logs:detail'" @click="openDetail(row)">璇︽儏</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        class="pager"
+        background
+        layout="total, sizes, prev, pager, next"
+        :total="total"
+        :current-page="current"
+        :page-size="size"
+        :page-sizes="[20, 50, 100]"
+        @current-change="handleCurrentChange"
+        @size-change="handleSizeChange"
+      ></el-pagination>
+    </div>
+
+    <el-dialog title="閿欒璇︽儏" :visible.sync="detailVisible" width="900px" append-to-body>
+      <div v-loading="detailLoading">
+        <div class="detail-meta">
+          <span><b>鍙戠敓鏃堕棿锛�</b>{{ detail.errorTime }}</span>
+          <span><b>鎿嶄綔浜猴細</b>{{ detail.userName || '-' }}{{ detail.nickName ? ' / ' + detail.nickName : '' }}</span>
+          <span><b>妯″潡锛�</b>{{ detail.module || '-' }}</span>
+        </div>
+        <div class="detail-meta">
+          <span><b>璇锋眰锛�</b>{{ (detail.requestMethod || '') + ' ' + (detail.requestUri || '') }}</span>
+        </div>
+        <div class="detail-meta">
+          <span><b>寮傚父绫诲瀷锛�</b>{{ detail.exceptionType }}</span>
+        </div>
+        <div class="detail-meta">
+          <span><b>寮傚父淇℃伅锛�</b>{{ detail.message }}</span>
+        </div>
+        <pre class="stack-trace">{{ detail.stackTrace || '鏃犲爢鏍堜俊鎭�' }}</pre>
+      </div>
+      <template slot="footer"><el-button @click="detailVisible = false">鍏抽棴</el-button></template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import api from '@/api'
+export default {
+  name: 'ErrorLogManage',
+  data() {
+    return {
+      rows: [],
+      total: 0,
+      current: 1,
+      size: 20,
+      loading: false,
+      detailVisible: false,
+      detailLoading: false,
+      detail: {},
+      modules: ['鏁呴殰绠$悊', '瀹屽伐绠$悊', '瀹屽伐楠屾敹', '缁熻鎶ヨ〃', '鐢ㄦ埛绠$悊', '瑙掕壊绠$悊', '鑿滃崟绠$悊', '鎵夸慨鍗曚綅绠$悊', '绯荤粺绠$悊', '鍏朵粬'],
+      filters: { keyword: '', module: '', exceptionType: '', dates: [] }
+    }
+  },
+  created() { this.load() },
+  methods: {
+    load() {
+      this.loading = true
+      const dates = this.filters.dates || []
+      api.get('/system/error-logs', {
+        params: {
+          keyword: this.filters.keyword || undefined,
+          module: this.filters.module || undefined,
+          exceptionType: this.filters.exceptionType || undefined,
+          startDate: dates[0] || undefined,
+          endDate: dates[1] || undefined,
+          current: this.current,
+          size: this.size
+        }
+      }).then(res => {
+        const data = res.data || {}
+        this.rows = data.records || []
+        this.total = data.total || 0
+      }).finally(() => { this.loading = false })
+    },
+    search() { this.current = 1; this.load() },
+    reset() { this.filters = { keyword: '', module: '', exceptionType: '', dates: [] }; this.search() },
+    openDetail(row) {
+      this.detailLoading = true
+      this.detail = {}
+      this.detailVisible = true
+      api.get('/system/error-logs/' + row.id).then(res => {
+        this.detail = res.data || {}
+      }).finally(() => { this.detailLoading = false })
+    },
+    handleCurrentChange(page) { this.current = page; this.load() },
+    handleSizeChange(size) { this.size = size; this.current = 1; this.load() }
+  }
+}
+</script>
+
+<style scoped>
+.toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
+.toolbar ::v-deep .el-range-separator { flex: 0 0 18px; min-width: 18px; text-align: center; }
+.pager { margin-top: 12px; text-align: right; }
+.detail-meta { margin-bottom: 8px; color: #42566b; line-height: 22px; word-break: break-all; }
+.detail-meta b { color: #26394d; }
+.stack-trace {
+  max-height: 520px;
+  margin: 12px 0 0;
+  padding: 12px;
+  border: 1px solid #dce4ec;
+  border-radius: 4px;
+  color: #30445a;
+  background: #f7f9fb;
+  font-family: Consolas, "Courier New", monospace;
+  font-size: 12px;
+  line-height: 18px;
+  white-space: pre-wrap;
+  word-break: break-all;
+  overflow: auto;
+}
+</style>

--
Gitblit v1.9.1