Browse Source

refactor(portrait, ledger): 优化多处业务逻辑与接口配置

1.  为台账导入接口添加自定义超时参数,默认5分钟
2.  重构员工档案加分扣分展示逻辑,按二级分组统计并展示
3.  修复部门路径构建函数的逻辑问题,优化空值与递归处理
huoyi 1 week ago
parent
commit
bb983df94d

+ 2 - 2
src/api/ledger/index.js

@@ -1,8 +1,8 @@
1 1
 import request from '@/utils/request'
2 2
 
3 3
 // ===== 台账一键全量导入(多Sheet合并Excel)=====
4
-export function importCombinedLedger(data) {
5
-  return request({ url: '/ledger/import/combined', method: 'post', data })
4
+export function importCombinedLedger(data, timeout = 300000) {
5
+  return request({ url: '/ledger/import/combined', method: 'post', data, timeout })
6 6
 }
7 7
 
8 8
 // ===== 台账数据清理(按导入时间范围)=====

+ 19 - 19
src/views/portraitManagement/components/SearchBar.vue

@@ -84,26 +84,26 @@ const findFirstNodeByDeptType = (nodes, targetType) => {
84 84
   return null
85 85
 }
86 86
 
87
-const buildPathForNode = (nodes, targetId, path = []) => {
88
-  if (!nodes) return path
87
+const buildPathForNode = (nodes, targetId) => {
88
+  if (!nodes) return null
89 89
   for (const node of nodes) {
90 90
     if (node.id === targetId || node.deptId === targetId) {
91 91
       // 如果是用户节点,不把用户名字加入 path
92 92
       if (node.deptType === 'user' || node.nodeType === 'user') {
93
-        return path
93
+        return []
94 94
       }
95 95
       const name = node.nickName || node.deptName || node.name || node.label
96
-      return [...path, name]
96
+      return [name]
97 97
     }
98
-    
99
-      const name = node.deptName || node.name || node.label
100
-      const found = buildPathForNode(node.children, targetId, [...path, name])
101
-      if (found.length > path.length) {
102
-        return found
98
+    if (node.children && node.children.length > 0) {
99
+      const childPath = buildPathForNode(node.children, targetId)
100
+      if (childPath !== null) {
101
+        const name = node.deptName || node.name || node.label
102
+        return [name, ...childPath]
103 103
       }
104
-    
104
+    }
105 105
   }
106
-  return path
106
+  return null
107 107
 }
108 108
 
109 109
 const queryUsers = async (query, cb) => {
@@ -113,7 +113,7 @@ const queryUsers = async (query, cb) => {
113 113
     const mapped = (res.data || []).map(u => {
114 114
       let path = []
115 115
       if (u.deptId) {
116
-        path = buildPathForNode(departments.value, u.deptId)
116
+        path = buildPathForNode(departments.value, u.deptId) || []
117 117
       }
118 118
       return { ...u, value: u.nickName, path }
119 119
     })
@@ -128,7 +128,7 @@ const queryDept = async (query, cb) => {
128 128
     const mapped = (res.data || []).map(d => {
129 129
       let path = []
130 130
       if (d.id || d.deptId) {
131
-        path = buildPathForNode(departments.value, d.deptId || d.id)
131
+        path = buildPathForNode(departments.value, d.deptId || d.id) || []
132 132
       }
133 133
       return { ...d, value: d.deptName, path }
134 134
     })
@@ -139,14 +139,14 @@ const queryDept = async (query, cb) => {
139 139
 const handleSelect = (item) => {
140 140
   
141 141
   if (props.deptType === 'user') {
142
-    const path = item.path && item.path.length > 0 ? item.path : (item.deptId ? buildPathForNode(departments.value, item.deptId) : [])
142
+    const path = item.path && item.path.length > 0 ? item.path : (item.deptId ? buildPathForNode(departments.value, item.deptId) || [] : [])
143 143
     const name = item.nickName
144 144
 
145 145
     personName.value = path.length > 0 ? `${path.join(' / ')} / ${name}` : name
146 146
     curQuery.value = { personName: item.nickName,id:item.id }
147 147
     searchHandler(curQuery.value)
148 148
   } else {
149
-    const path = item.path && item.path.length > 0 ? item.path : ((item.id || item.deptId) ? buildPathForNode(departments.value, item.deptId || item.id) : [])
149
+    const path = item.path && item.path.length > 0 ? item.path : ((item.id || item.deptId) ? buildPathForNode(departments.value, item.deptId || item.id) || [] : [])
150 150
     const name = item.deptName || item.name || item.label
151 151
     personName.value = path.length > 0 ? path.join(' / ') : name
152 152
     if (props.deptType === 'BRIGADE' || props.deptType === 'STATION') {
@@ -229,7 +229,7 @@ const handleNodeClick = (node) => {
229 229
   if (props.deptType === 'user') {
230 230
     if (node.nodeType === 'user') {
231 231
    
232
-      const path = buildPathForNode(departments.value, node.deptId || node.id)
232
+      const path = buildPathForNode(departments.value, node.deptId || node.id) || []
233 233
       const name = node.label
234 234
       
235 235
       personName.value = path.length > 0 ? `${path.join(' / ')} / ${name}` : name
@@ -238,7 +238,7 @@ const handleNodeClick = (node) => {
238 238
     }
239 239
   } else {
240 240
     if (node.deptType === props.deptType) {
241
-      const path = buildPathForNode(departments.value, node.deptId || node.id)
241
+      const path = buildPathForNode(departments.value, node.deptId || node.id) || []
242 242
       const name = node.deptName || node.name || node.label;
243 243
       personName.value = path.length > 0 ? path.join(' / ') : name
244 244
       if (props.deptType === 'BRIGADE' || props.deptType === 'STATION') {
@@ -270,13 +270,13 @@ onMounted(async () => {
270 270
     const nodeId = defaultNode.deptId || defaultNode.id
271 271
     currentKey.value = nodeId
272 272
     if (props.deptType === 'user') {
273
-      const path = buildPathForNode(departments.value, nodeId)
273
+      const path = buildPathForNode(departments.value, nodeId) || []
274 274
       const name = defaultNode.label
275 275
       personName.value = path.length > 0 ? `${path.join(' / ')} / ${name}` : name
276 276
       curQuery.value = { personName: defaultNode.label, id: defaultNode.id }
277 277
       searchHandler(curQuery.value)
278 278
     } else {
279
-      const path = buildPathForNode(departments.value, nodeId)
279
+      const path = buildPathForNode(departments.value, nodeId) || []
280 280
       const name = defaultNode.deptName || defaultNode.name || defaultNode.label
281 281
       personName.value = path.length > 0 ? path.join(' / ') : name
282 282
       if (props.deptType === 'BRIGADE' || props.deptType === 'STATION') {

+ 25 - 11
src/views/portraitManagement/employeeProfile/index.vue

@@ -186,14 +186,13 @@
186 186
 
187 187
         <!-- 加分区域 -->
188 188
         <div class="tooltip-section">
189
-          <!--<div class="section-list">
190
-            <div v-if="addList.length" class="list-item" v-for="(item, i) in addList" :key="i">
191
-              <span>{{ item.level3Name }}:</span>
192
-              <span class="add-text">{{ item.totalScore }}分</span>
189
+          <div class="section-list">
190
+            <div v-if="addGroupList.length" class="list-item" v-for="(item, i) in addGroupList" :key="i">
191
+              <span>{{ item.name }}:</span>
192
+              <span class="add-text">+{{ item.total }}分</span>
193 193
             </div>
194 194
             <div v-else class="p-empty">暂无加分记录</div>
195 195
           </div>
196
-          -->
197 196
           <div class="section-total add">
198 197
             <span>合计加分:</span>
199 198
             <span>{{ addTotal }}分</span>
@@ -201,14 +200,13 @@
201 200
         </div>
202 201
         <!-- 扣分区域 -->
203 202
         <div class="tooltip-section">
204
-        <!--   <div class="section-list">
205
-            <div v-if="deductList.length" class="list-item" v-for="(item, i) in deductList" :key="i">
206
-              <span>{{ item.level3Name }}:</span>
207
-              <span class="deduct-text">{{ item.totalScore }}分</span>
203
+          <div class="section-list">
204
+            <div v-if="deductGroupList.length" class="list-item" v-for="(item, i) in deductGroupList" :key="i">
205
+              <span>{{ item.name }}:</span>
206
+              <span class="deduct-text">{{ item.total }}分</span>
208 207
             </div>
209
-            <div v-if="!deductList.length" class="p-empty">暂无扣分记录</div>
208
+            <div v-if="!deductGroupList.length" class="p-empty">暂无扣分记录</div>
210 209
           </div>
211
-          -->
212 210
           <div class="section-total deduct">
213 211
             <span>合计扣分:</span>
214 212
             <span>{{ deductTotal }}分</span>
@@ -256,6 +254,22 @@ const deductList = computed(() => {
256 254
   const all = scoreDetails.value.filter(d => d.totalScore != null && Number(d.totalScore) < 0)
257 255
   return activeDimName.value ? all.filter(d => d.dimensionName === activeDimName.value) : all
258 256
 })
257
+const addGroupList = computed(() => {
258
+  const groups = {}
259
+  addList.value.forEach(d => {
260
+    const key = d.level2Name || '其他'
261
+    groups[key] = (groups[key] || 0) + Number(d.totalScore)
262
+  })
263
+  return Object.entries(groups).map(([name, total]) => ({ name, total: total.toFixed(2) }))
264
+})
265
+const deductGroupList = computed(() => {
266
+  const groups = {}
267
+  deductList.value.forEach(d => {
268
+    const key = d.level2Name || '其他'
269
+    groups[key] = (groups[key] || 0) + Number(d.totalScore)
270
+  })
271
+  return Object.entries(groups).map(([name, total]) => ({ name, total: total.toFixed(2) }))
272
+})
259 273
 const addTotal = computed(() => {
260 274
   const s = addList.value.reduce((acc, d) => acc + Number(d.totalScore), 0)
261 275
   return (s > 0 ? '+' : '') + s.toFixed(2)