Преглед изворни кода

feat(employeeDimension): 优化员工维度评分明细数据加载与筛选

- 调整接口地址为 /ledger/warning/employeeDimensionScores
- 添加页面加载状态显示(v-loading)
- 使用接口获取维度列表替代静态维度选项
- 更新维度选择绑定数据及表格字段映射
- 从接口获取员工维度评分明细数据,替换本地假数据
- 优化筛选逻辑,支持服务器请求参数传递多种筛选条件
- 实现排序后端适配,前端对数据排序进行控制
- 重构搜索和重置操作,改为调用数据拉取方法
- 删除无效的路由监听代码,简化逻辑
- 增加错误捕获并打印请求失败信息
huoyi пре 15 часа
родитељ
комит
f751bc56bd

+ 1 - 1
src/api/warningManage/employeeDimensionDetails.js

@@ -2,5 +2,5 @@ import request from '@/utils/request'
2 2
 
3 3
 // 员工维度评分明细
4 4
 export function getEmployeeDimensionPageData(data) {
5
-    return request({ url: '/ledger/warning/employeeDimensionDetail', method: 'post', data })
5
+    return request({ url: '/ledger/warning/employeeDimensionScores', method: 'post', data })
6 6
 }

+ 70 - 97
src/views/warningManage/employeeDimensionDetails/index.vue

@@ -1,5 +1,5 @@
1 1
 <template>
2
-    <div class="page-container">
2
+    <div class="page-container" v-loading="pageLoading">
3 3
         <h1 class="page-title">员工维度评分明细</h1>
4 4
 
5 5
         <div class="filter-bar">
@@ -19,8 +19,8 @@
19 19
                     :props="{ label: 'label', value: 'value', children: 'children' }" node-key="value"
20 20
                     placeholder="组织架构/员工" clearable filterable check-strictly style="width: 200px;" />
21 21
                 <el-select v-model="selectedDimension" placeholder="维度" clearable style="width: 150px;">
22
-                    <el-option v-for="item in dimensionOptions" :key="item.value" :label="item.label"
23
-                        :value="item.value" />
22
+                    <el-option v-for="item in dimensionList" :key="item.id" :label="item.name"
23
+                        :value="item.id" />
24 24
                 </el-select>
25 25
             </div>
26 26
             <div class="filter-right">
@@ -36,12 +36,12 @@
36 36
             </div>
37 37
             <el-table :data="displayData" style="width: 100%;" border stripe @sort-change="handleSortChange">
38 38
                 <el-table-column prop="userId" label="员工ID" />
39
-                <el-table-column prop="nickName" label="姓名" />
39
+                <el-table-column prop="personName" label="姓名" />
40 40
                 <el-table-column prop="deptName" label="部门" />
41 41
                 <el-table-column prop="teamName" label="班组" />
42 42
                 <el-table-column prop="groupName" label="小组" />
43
-                <el-table-column prop="dimName" label="维度名称" />
44
-                <el-table-column prop="dimScore" label="维度分值" sortable="custom" />
43
+                <el-table-column prop="dimensionName" label="维度名称" />
44
+                <el-table-column prop="dimensionScore" label="维度分值"  />
45 45
             </el-table>
46 46
             <el-pagination v-show="total > 0" :total="total" v-model:current-page="queryParams.pageNum"
47 47
                 v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]"
@@ -52,11 +52,10 @@
52 52
 </template>
53 53
 
54 54
 <script setup>
55
-import { ref, reactive, computed, onMounted, watch } from 'vue'
56
-import { useRoute } from 'vue-router'
55
+import { ref, reactive, computed, onMounted } from 'vue'
57 56
 import { getDeptUserTree } from '@/api/item/items'
58
-
59
-const route = useRoute()
57
+import { getEmployeeDimensionPageData } from '@/api/warningManage/employeeDimensionDetails'
58
+import { getDimensionAll } from '@/api/score/index'
60 59
 
61 60
 const activeRange = ref('month')
62 61
 const startDate = ref(null)
@@ -65,34 +64,10 @@ const selectedOrg = ref('')
65 64
 const selectedDimension = ref('')
66 65
 const cascadeOptions = ref([])
67 66
 
68
-const dimensionOptions = ref([
69
-    { label: '安全响应能力', value: '安全响应能力' },
70
-    { label: '服务响应能力', value: '服务响应能力' }
71
-])
72
-
73
-// 两页假数据(20条),含事件日期
74
-const allMockData = ref([
75
-    { userId: 397, nickName: '胡婷婷', deptName: '旅检一部', teamName: '安平班组', groupName: '陈行小组', dimName: '安全响应能力', dimScore: 80.5, eventDate: '2026-05-10' },
76
-    { userId: 437, nickName: '李璐', deptName: '旅检一部', teamName: '安平班组', groupName: '陈行小组', dimName: '服务响应能力', dimScore: 79.2, eventDate: '2026-05-15' },
77
-    { userId: 564, nickName: '徐倩', deptName: '旅检一部', teamName: '安平班组', groupName: '陈行小组', dimName: '安全响应能力', dimScore: 81.3, eventDate: '2026-05-20' },
78
-    { userId: 587, nickName: '余杭洋', deptName: '旅检一部', teamName: '安平班组', groupName: '陈行小组', dimName: '服务响应能力', dimScore: 78.6, eventDate: '2026-05-25' },
79
-    { userId: 550, nickName: '肖垚', deptName: '旅检一部', teamName: '安平班组', groupName: '陈行小组', dimName: '安全响应能力', dimScore: 80.1, eventDate: '2026-06-01' },
80
-    { userId: 107, nickName: '刘珊', deptName: '旅检三部', teamName: '安平班组', groupName: '陈行小组', dimName: '服务响应能力', dimScore: 79.8, eventDate: '2026-06-05' },
81
-    { userId: 191, nickName: '王佐朝', deptName: '旅检三部', teamName: '安平班组', groupName: '陈行小组', dimName: '安全响应能力', dimScore: 82.0, eventDate: '2026-06-08' },
82
-    { userId: 250, nickName: '张元媛', deptName: '旅检三部', teamName: '安平班组', groupName: '陈行小组', dimName: '服务响应能力', dimScore: 78.9, eventDate: '2026-06-10' },
83
-    { userId: 293, nickName: '陈凯琳', deptName: '旅检三部', teamName: '安平班组', groupName: '陈行小组', dimName: '安全响应能力', dimScore: 80.7, eventDate: '2026-06-12' },
84
-    { userId: 603, nickName: '张霞', deptName: '旅检一部', teamName: '安平班组', groupName: '陈行小组', dimName: '服务响应能力', dimScore: 79.5, eventDate: '2026-04-15' },
85
-    { userId: 412, nickName: '赵敏', deptName: '旅检一部', teamName: '安行班组', groupName: '拓新小组', dimName: '安全响应能力', dimScore: 83.2, eventDate: '2026-04-20' },
86
-    { userId: 528, nickName: '孙磊', deptName: '旅检一部', teamName: '安行班组', groupName: '拓新小组', dimName: '服务响应能力', dimScore: 77.4, eventDate: '2026-03-10' },
87
-    { userId: 631, nickName: '周杰', deptName: '旅检二部', teamName: '木兰班组', groupName: '飞跃小组', dimName: '安全响应能力', dimScore: 85.1, eventDate: '2026-03-15' },
88
-    { userId: 745, nickName: '吴芳', deptName: '旅检二部', teamName: '木兰班组', groupName: '飞跃小组', dimName: '服务响应能力', dimScore: 76.8, eventDate: '2026-02-20' },
89
-    { userId: 802, nickName: '郑浩', deptName: '旅检二部', teamName: '芮茜班组', groupName: '先锋小组', dimName: '安全响应能力', dimScore: 81.9, eventDate: '2026-01-10' },
90
-    { userId: 156, nickName: '冯婷', deptName: '旅检三部', teamName: '拓新班组', groupName: '锐行小组', dimName: '服务响应能力', dimScore: 78.3, eventDate: '2026-01-25' },
91
-    { userId: 267, nickName: '褚伟', deptName: '旅检三部', teamName: '拓新班组', groupName: '锐行小组', dimName: '安全响应能力', dimScore: 84.6, eventDate: '2025-12-05' },
92
-    { userId: 389, nickName: '卫兰', deptName: '旅检一部', teamName: '屹动班组', groupName: '护航小组', dimName: '服务响应能力', dimScore: 77.1, eventDate: '2025-11-18' },
93
-    { userId: 471, nickName: '蒋涛', deptName: '旅检一部', teamName: '屹动班组', groupName: '护航小组', dimName: '安全响应能力', dimScore: 82.7, eventDate: '2025-10-22' },
94
-    { userId: 598, nickName: '沈琳', deptName: '旅检二部', teamName: '安行班组', groupName: '拓新小组', dimName: '服务响应能力', dimScore: 80.0, eventDate: '2025-09-30' }
95
-])
67
+const dimensionList = ref([])
68
+
69
+const allData = ref([])
70
+const pageLoading = ref(false)
96 71
 
97 72
 const queryParams = reactive({
98 73
     pageNum: 1,
@@ -165,7 +140,7 @@ const setActiveRange = (range) => {
165 140
 }
166 141
 
167 142
 // 筛选后的数据(点击搜索才更新)
168
-const filteredData = ref([...allMockData.value])
143
+const filteredData = ref([])
169 144
 
170 145
 const displayData = computed(() => {
171 146
     const start = (queryParams.pageNum - 1) * queryParams.pageSize
@@ -177,36 +152,8 @@ const total = computed(() => filteredData.value.length)
177 152
 
178 153
 // 执行筛选(点击搜索时调用)
179 154
 const doFilter = () => {
180
-    let data = [...allMockData.value]
181
-
182
-    // 日期范围筛选
183
-    let rangeStart = null
184
-    let rangeEnd = null
185
-    if (startDate.value && endDate.value) {
186
-        rangeStart = formatDate(startDate.value)
187
-        rangeEnd = formatDate(endDate.value)
188
-    } else {
189
-        const range = getDateRangeFromActive()
190
-        rangeStart = range.startDate
191
-        rangeEnd = range.endDate
192
-    }
193
-    if (rangeStart && rangeEnd) {
194
-        data = data.filter(item => item.eventDate >= rangeStart && item.eventDate <= rangeEnd)
195
-    }
196
-
197
-    // 维度筛选
198
-    if (selectedDimension.value) {
199
-        data = data.filter(item => item.dimName === selectedDimension.value)
200
-    }
201
-
202
-    // 组织架构/员工筛选
203
-    const selectedInfo = getSelectedInfo(selectedOrg.value)
204
-    if (selectedInfo) {
205
-        if (selectedInfo.deptType === 'user') {
206
-            const rawId = Number(selectedInfo.value.split('_')[1])
207
-            data = data.filter(item => item.userId === rawId)
208
-        }
209
-    }
155
+    // 前端维度筛选(接口返回后再次过滤)
156
+    let data = [...allData.value]
210 157
 
211 158
     // 排序(基于全量过滤后数据)
212 159
     if (sortState.value.prop && sortState.value.order) {
@@ -224,6 +171,50 @@ const doFilter = () => {
224 171
     filteredData.value = data
225 172
 }
226 173
 
174
+// 请求接口数据
175
+const fetchData = async () => {
176
+    let params = {}
177
+
178
+    // 日期范围
179
+    if (startDate.value && endDate.value) {
180
+        params.startDate = formatDate(startDate.value)
181
+        params.endDate = formatDate(endDate.value)
182
+    } else {
183
+        const range = getDateRangeFromActive()
184
+        params.startDate = range.startDate
185
+        params.endDate = range.endDate
186
+    }
187
+
188
+    // 维度
189
+    if (selectedDimension.value) {
190
+        params.dimensionId = selectedDimension.value
191
+    }
192
+
193
+    // 组织架构/员工:选哪个层级传哪个参数
194
+    if (selectedOrg.value) {
195
+        const selectedInfo = getSelectedInfo(selectedOrg.value)
196
+        if (selectedInfo) {
197
+            const rawId = Number(selectedInfo.value.split('_')[1])
198
+            if (selectedInfo.deptType === 'BRIGADE') params.deptId = rawId
199
+            else if (selectedInfo.deptType === 'MANAGER') params.teamId = rawId
200
+            else if (selectedInfo.deptType === 'TEAMS') params.groupId = rawId
201
+            else if (selectedInfo.deptType === 'user') params.userId = rawId
202
+        }
203
+    }
204
+
205
+    pageLoading.value = true
206
+    try {
207
+        const res = await getEmployeeDimensionPageData(params)
208
+        if (res.data) {
209
+            allData.value = res.data
210
+        }
211
+    } catch (error) {
212
+        console.error('获取员工维度评分明细失败:', error)
213
+    }
214
+    doFilter()
215
+    pageLoading.value = false
216
+}
217
+
227 218
 const handleSortChange = ({ prop, order }) => {
228 219
     sortState.value = { prop, order }
229 220
     queryParams.pageNum = 1
@@ -233,7 +224,7 @@ const handleSortChange = ({ prop, order }) => {
233 224
 const handleSearch = () => {
234 225
     queryParams.pageNum = 1
235 226
     sortState.value = { prop: '', order: '' }
236
-    doFilter()
227
+    fetchData()
237 228
 }
238 229
 
239 230
 const handleReset = () => {
@@ -244,7 +235,7 @@ const handleReset = () => {
244 235
     selectedDimension.value = ''
245 236
     queryParams.pageNum = 1
246 237
     sortState.value = { prop: '', order: '' }
247
-    doFilter()
238
+    fetchData()
248 239
 }
249 240
 
250 241
 const handlePageChange = (newPage) => {
@@ -265,33 +256,15 @@ onMounted(async () => {
265 256
     } catch (error) {
266 257
         console.error('获取组织架构数据失败:', error)
267 258
     }
268
-    doFilter()
259
+    // 获取维度选项(org=4)
260
+    try {
261
+        const r = await getDimensionAll({ pageNum: 1, pageSize: 100, org: 4 })
262
+        dimensionList.value = r.data || []
263
+    } catch (error) {
264
+        console.error('获取维度列表失败:', error)
265
+    }
266
+    fetchData()
269 267
 })
270
-
271
-// watch(() => route.query, (query) => {
272
-//     const { id, org, startDate: sd, endDate: ed, activeRange: ar, dimension } = query
273
-//     if (id) {
274
-//         selectedOrg.value = `user_${id}`
275
-//     } else if (org) {
276
-//         selectedOrg.value = org
277
-//     } else {
278
-//         selectedOrg.value = ''
279
-//     }
280
-//     if (sd && ed) {
281
-//         startDate.value = sd
282
-//         endDate.value = ed
283
-//         activeRange.value = 'custom'
284
-//     } else {
285
-//         startDate.value = null
286
-//         endDate.value = null
287
-//         activeRange.value = ar || 'month'
288
-//     }
289
-//     if (dimension) {
290
-//         selectedDimension.value = dimension
291
-//     }
292
-//     queryParams.pageNum = 1
293
-//     sortState.value = { prop: '', order: '' }
294
-// }, { immediate: true })
295 268
 </script>
296 269
 
297 270
 <style scoped>