ソースを参照

feat: 优化部门树功能并修复多个页面问题

refactor(部门树): 重构部门树选项构建函数,支持包含完整节点数据
fix(违禁品上报): 修复图片上传和显示问题
feat(考勤统计): 添加图表更新前清空功能
style(工作概况): 调整筛选选择器宽度
fix(违禁品统计): 根据用户角色调整部门筛选逻辑
feat(违禁品上报): 添加折叠面板状态控制
huoyi 3 ヶ月 前
コミット
c3fdd020ec

+ 4 - 3
src/api/seizureRecord/seizureRecord.js

@@ -55,9 +55,10 @@ export function categoryInfo (type) {
55 55
  * @name 对违禁品类进行模糊搜索
56 56
  * @param {*} name 查询字符串
57 57
 */
58
-export function categoryList (name) {
58
+export function categoryList (params) {
59 59
   return request({
60
-    url: `/system/category/list?name=${name}`,
61
-    method: 'get'
60
+    url: `/system/category/list`,
61
+    method: 'get',
62
+    params
62 63
   });
63 64
 }

+ 2 - 1
src/api/system/dept/dept.js

@@ -1,13 +1,14 @@
1 1
 import request from '@/utils/request'
2 2
 
3 3
 // 获取组织树形结构
4
-export function getDeptList() {
4
+export function getDeptList(params) {
5 5
   return request({
6 6
     url: '/system/user/deptTree',
7 7
     // headers: {
8 8
     //   isToken: false
9 9
     // },
10 10
     method: 'get',
11
+    params: params
11 12
     // params: {deptType: "TEAMS"}
12 13
   })
13 14
 }

+ 4 - 0
src/pages/attendance/components/MaintainAreaOrMemberModal.vue

@@ -331,6 +331,10 @@ export default {
331 331
             }
332 332
         },
333 333
         close() {
334
+            if(this.searchViewShow){
335
+                this.searchViewShow = false;
336
+                return;
337
+            }
334 338
 
335 339
             this.show = false
336 340
         },

+ 26 - 2
src/pages/attendanceStatistics/index.vue

@@ -168,6 +168,10 @@ export default {
168 168
             });
169 169
         },
170 170
         updateCharts() {
171
+            // 在更新图表前先清空所有图表
172
+            this.pieChart && this.pieChart.clear();
173
+            this.barChart1 && this.barChart1.clear();
174
+            this.barChart2 && this.barChart2.clear();
171 175
 
172 176
             let openRate = 0;
173 177
             let openData = 0;
@@ -267,7 +271,17 @@ export default {
267 271
             // 通道开放情况正负条形图
268 272
             if (this.currentTab === 'all') {
269 273
                 this.barChart1 && this.barChart1.setOption({
270
-                    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
274
+                    tooltip: { 
275
+                        trigger: 'axis', 
276
+                        axisPointer: { type: 'shadow' },
277
+                        formatter: function(params) {
278
+                            let result = params[0].name + '<br/>';
279
+                            params.forEach(function(item) {
280
+                                result += item.marker + ' ' + item.seriesName + ': ' + Math.abs(item.value) + '<br/>';
281
+                            });
282
+                            return result;
283
+                        }
284
+                    },
271 285
                     legend: {
272 286
                         data: ['开放', '未开放'],
273 287
                         top: '15%'
@@ -365,7 +379,17 @@ export default {
365 379
             // 人员情况正负条形图
366 380
             if (this.currentTab === 'all') {
367 381
                 this.barChart2 && this.barChart2.setOption({
368
-                    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
382
+                    tooltip: { 
383
+                        trigger: 'axis', 
384
+                        axisPointer: { type: 'shadow' },
385
+                        formatter: function(params) {
386
+                            let result = params[0].name + '<br/>';
387
+                            params.forEach(function(item) {
388
+                                result += item.marker + ' ' + item.seriesName + ': ' + Math.abs(item.value) + '<br/>';
389
+                            });
390
+                            return result;
391
+                        }
392
+                    },
369 393
                     legend: { data: ['在岗人数', '空闲人数'], top: '15%' },
370 394
                     grid: {
371 395
                         left: '4%',

+ 59 - 52
src/pages/eikonStatistics/components/topInfo.vue

@@ -1,54 +1,58 @@
1 1
 <template>
2 2
     <view class="top-info-wrapper">
3 3
         <view class="top-info-container">
4
-        <view class="info-content">
5
-            <!-- 左侧信息区域 -->
6
-            <view class="left-info">
7
-                <!-- 上面:根据角色显示部门信息 -->
8
-                <view class="department-info">
9
-                    <text class="department-value">{{ currentDepartmentPath }}</text>
4
+            <view class="info-content">
5
+                <!-- 左侧信息区域 -->
6
+                <view class="left-info">
7
+                    <!-- 上面:根据角色显示部门信息 -->
8
+                    <view class="department-info">
9
+                        <text class="department-value">{{ currentDepartmentPath }}</text>
10
+                    </view>
11
+
12
+                    <!-- 下面:根据是否个人显示不同信息 -->
13
+                    <view class="user-info">
14
+                        <text v-if="isPersonal" class="user-name">姓名:{{ currentLevelUserName }}</text>
15
+                        <text v-else class="stat-count">统计人数:{{ currentLevelUserCount }}</text>
16
+                    </view>
10 17
                 </view>
11 18
 
12
-                <!-- 下面:根据是否个人显示不同信息 -->
13
-                <view class="user-info">
14
-                    <text v-if="isPersonal" class="user-name">姓名:{{ currentLevelUserName }}</text>
15
-                    <text v-else class="stat-count">统计人数:{{ currentLevelUserCount }}</text>
19
+                <!-- 右侧切换按钮 -->
20
+                <view v-if="!userRoles.includes('SecurityCheck') && currentTab != 'team'" class="right-switch"
21
+                    @click="openPopup">
22
+                    <image src="/static/images/icon/switch.png" mode="aspectFit" class="switch-image" />
16 23
                 </view>
17 24
             </view>
18 25
 
19
-            <!-- 右侧切换按钮 -->
20
-            <view v-if="!userRoles.includes('SecurityCheck')&&currentTab != 'team'" class="right-switch" @click="openPopup">
21
-                <image src="/static/images/icon/switch.png" mode="aspectFit" class="switch-image" />
22
-            </view>
23
-        </view>
24
-
25
-        <!-- 切换弹窗 -->
26
-        <uni-popup ref="SelectPopup" type="center" :mask-click="false">
27
-            <view class="popup-container">
28
-                <view class="popup-header">
29
-                    <text class="popup-title">选择</text>
30
-                    <view class="popup-close" @click="closePopup">×</view>
31
-                </view>
32
-
33
-                <!-- 搜索框 -->
34
-                <view class="search-section">
35
-                    <uni-easyinput v-model="searchKeyword" :placeholder="userRoles.includes('banzuzhang') ? '请输入姓名搜索' : '请输入部门名称、姓名搜索'" :clearable="true" />
26
+            <!-- 切换弹窗 -->
27
+            <uni-popup ref="SelectPopup" type="center" :mask-click="false">
28
+                <view class="popup-container">
29
+                    <view class="popup-header">
30
+                        <text class="popup-title">选择</text>
31
+                        <view class="popup-close" @click="closePopup">×</view>
32
+                    </view>
33
+
34
+                    <!-- 搜索框 -->
35
+                    <view class="search-section">
36
+                        <uni-easyinput v-model="searchKeyword"
37
+                            :placeholder="userRoles.includes('banzuzhang') ? '请输入姓名搜索' : '请输入部门名称、姓名搜索'"
38
+                            :clearable="true" />
39
+                    </view>
40
+
41
+                    <!-- 部门树 -->
42
+                    <view class="tree-section">
43
+                        <scroll-view scroll-y="true" class="tree-scroll">
44
+                            <mix-tree :list="filteredTreeData" :expandAll="!!searchKeyword"
45
+                                @treeItemClick="handleNodeSelect" />
46
+                        </scroll-view>
47
+                    </view>
48
+
49
+                    <!-- 按钮区域 -->
50
+                    <view class="button-section">
51
+                        <view class="btn-cancel" @click="closePopup">取消</view>
52
+                        <view class="btn-confirm" @click="confirmSelection">确定</view>
53
+                    </view>
36 54
                 </view>
37
-
38
-                <!-- 部门树 -->
39
-                <view class="tree-section">
40
-                    <scroll-view scroll-y="true" class="tree-scroll">
41
-                        <mix-tree :list="filteredTreeData" :expandAll="!!searchKeyword" @treeItemClick="handleNodeSelect" />
42
-                    </scroll-view>
43
-                </view>
44
-
45
-                <!-- 按钮区域 -->
46
-                <view class="button-section">
47
-                    <view class="btn-cancel" @click="closePopup">取消</view>
48
-                    <view class="btn-confirm" @click="confirmSelection">确定</view>
49
-                </view>
50
-            </view>
51
-        </uni-popup>
55
+            </uni-popup>
52 56
         </view>
53 57
     </view>
54 58
 </template>
@@ -56,13 +60,13 @@
56 60
 <script>
57 61
 import { mapState, mapGetters } from 'vuex'
58 62
 import mixTree from '@/uni_modules/mix-tree/components/mix-tree/mix-tree.vue'
59
-import { getDeptUserTree,getUserInfoById } from '@/api/system/user'
63
+import { getDeptUserTree, getUserInfoById } from '@/api/system/user'
60 64
 export default {
61 65
     name: 'TopInfo',
62 66
     components: {
63 67
         mixTree
64 68
     },
65
-    props:{ 
69
+    props: {
66 70
         currentTab: {
67 71
             type: String,
68 72
             default: ''
@@ -95,7 +99,7 @@ export default {
95 99
             if (this.isZhanZhang) return '站'
96 100
             return '部门'
97 101
         },
98
-        
102
+
99 103
         // 过滤后的树数据
100 104
         filteredTreeData() {
101 105
             if (!this.searchKeyword) {
@@ -144,7 +148,7 @@ export default {
144 148
                 this.currentLevelUserName = ''
145 149
             }
146 150
         },
147
-        
151
+
148 152
         // 打开弹窗
149 153
         openPopup() {
150 154
             this.$refs.SelectPopup.open();
@@ -210,12 +214,15 @@ export default {
210 214
             return fullPath || []
211 215
         },
212 216
         async getDeptTree() {
213
-
214
-
217
+            // console.log(this.userInfo, "this.userInfo",this.userRoles)
218
+            
215 219
             let params = {}
216 220
             if (this.userRoles.includes('test')) {
217 221
                 params.deptId = this.userInfo.stationId
218 222
             }
223
+            if (this.userRoles.includes('jingli')) {
224
+                params.deptId = this.userInfo.brigadeId
225
+            }
219 226
             if (this.userRoles.includes('kezhang')) {
220 227
                 params.deptId = this.userInfo.departmentId
221 228
             }
@@ -226,9 +233,9 @@ export default {
226 233
             this.departmentTree = res.data
227 234
         }
228 235
     },
229
-    
230
-   
231
-    
236
+
237
+
238
+
232 239
     // 监听currentLevelId和isPersonal的变化
233 240
     watch: {
234 241
         currentLevelId: {
@@ -237,7 +244,7 @@ export default {
237 244
             },
238 245
             immediate: true
239 246
         },
240
-       
247
+
241 248
     }
242 249
 }
243 250
 </script>

+ 1 - 1
src/pages/myToDoList/index.vue

@@ -487,7 +487,7 @@ export default {
487 487
 
488 488
 
489 489
 .mytodo-list {
490
-    height: calc(100vh - 207rpx);
490
+    height: calc(100vh - 260rpx);
491 491
     // overflow: hidden; /* 防止与scroll-view的滚动冲突 */
492 492
     margin-bottom: 100rpx;
493 493
 

+ 76 - 28
src/pages/seizeStatistics/index.vue

@@ -4,8 +4,10 @@
4 4
       <!-- 筛选区域 -->
5 5
       <view class="filter-section">
6 6
         <view class="filter-row">
7
-          <uni-data-picker class="filter-select" :localdata="departments" :placeholder="'请选择'"
8
-            v-model="formData.inspectDepartmentId" @change="handleinspectDepartmentIdChange" :clear-icon="false" />
7
+          <uni-data-picker
8
+            v-if="curUserRoles.includes('test') || curUserRoles.includes('jingli') || curUserRoles.includes('xingzheng')"
9
+            class="filter-select" :localdata="departments" :placeholder="'请选择'" @change="handleinspectDeptIdChange"
10
+            :clear-icon="false" />
9 11
           <text v-if="dateRange.length > 0" class="days-count">共 {{ totalDays }} 天</text>
10 12
           <!-- 时间范围选择器 -->
11 13
           <uni-datetime-picker v-model="dateRange" type="daterange" rangeSeparator="至" @change="handleDateRangeChange"
@@ -83,7 +85,8 @@
83 85
             <uni-data-picker :localdata="item_category_options1" :map="dataTreeOptionMap" popup-title="请选择一级违禁品类别"
84 86
               v-model="formData.categoryCodeOne" @change="onCategoryChange" v-if="showForbiddenCategory" />
85 87
             <uni-data-picker :localdata="item_category_options2" :map="dataTreeOptionMap" popup-title="请选择二级违禁品类别"
86
-              v-model="formData.categoryCodeTwo" v-if="showForbiddenCategory" @change="onTypeChange" :readonly="!formData.categoryCodeOne" />
88
+              v-model="formData.categoryCodeTwo" v-if="showForbiddenCategory" @change="onTypeChange"
89
+              :readonly="!formData.categoryCodeOne" />
87 90
 
88 91
             <!-- 安检岗位嵌套环形图 -->
89 92
             <!-- <view class="chart-item">
@@ -136,7 +139,7 @@
136 139
 
137 140
 <script>
138 141
 import * as echarts from 'echarts'
139
-import { buildDepartmentOptions } from '@/utils/common'
142
+import { buildManagerOptions, buildBrigadeOptions } from '@/utils/common'
140 143
 import HomeContainer from "@/components/HomeContainer.vue";
141 144
 import SwitchTab from "./components/switch-tab.vue";
142 145
 import { getTotalSome, getPost, getPosition, getRank, getTimeSpan, getCategory } from "@/api/seizeStatistics/seizeStatistics";
@@ -152,7 +155,7 @@ export default {
152 155
   data() {
153 156
     return {
154 157
       departments: [
155
-        { value: null, text: '全站' },
158
+
156 159
       ],
157 160
       showForbiddenCategory: true, // 控制违禁品类别的显示
158 161
       dateRange: [],
@@ -185,7 +188,7 @@ export default {
185 188
       formData: {
186 189
         categoryCodeOne: '', // 违禁品类别
187 190
         categoryCodeTwo: '', // 违禁品类型
188
-        inspectDepartmentId: null // 被检查科ID
191
+        inspectDeptId: null // 被检查科ID
189 192
       },
190 193
       dataTreeOptionMap: { text: 'label', value: 'id' }, // 级联字段映射关系树结构
191 194
       // allPositionData: [],
@@ -193,12 +196,19 @@ export default {
193 196
       forbiddenPieData: [],//违禁品类别数据
194 197
       levelType: 1,
195 198
       secondLevelType: 1,
199
+      getType: ''
196 200
     }
197 201
   },
198 202
   computed: {
203
+    currentUser() {
204
+      return this.$store.state.user;
205
+    },
206
+    curUserRoles() {
207
+      return this.$store.state.user && this.$store.state.user.roles;
208
+    },
199 209
     // 表格列配置
200 210
     rankingColumns() {
201
-      let name = this.defaultActive == 1 ? '科室' : this.defaultActive == 2 ? '班组' : '个人';
211
+      let name = this.defaultActive == 1 ? '主管' : this.defaultActive == 2 ? '班组' : this.defaultActive == 3 ? '个人' : '大队';
202 212
       return [
203 213
         { props: 'rank', title: '排名', slot: true },
204 214
         { props: 'name', title: name },
@@ -208,15 +218,22 @@ export default {
208 218
       ]
209 219
     },
210 220
     tabList() {
211
-      if (!this.formData.inspectDepartmentId) {
212
-        this.defaultActive = 1;
221
+      if (this.getType === null) {
213 222
         return [
214
-          { label: '按科室', value: 1 },
223
+          { label: '按大队', value: 4 },
224
+          { label: '按主管', value: 1 },
215 225
           { label: '按班组', value: 2 },
216 226
           { label: '按个人', value: 3 }
217 227
         ];
218
-      } else {
219
-        this.defaultActive = 2;
228
+      }
229
+      if (this.getType == "BRIGADE") {
230
+        return [
231
+          { label: '按主管', value: 1 },
232
+          { label: '按班组', value: 2 },
233
+          { label: '按个人', value: 3 }
234
+        ];
235
+      }
236
+      if (this.getType == "MANAGER" || this.curUserRoles.includes('kezhang')) {
220 237
         return [
221 238
           { label: '按班组', value: 2 },
222 239
           { label: '按个人', value: 3 }
@@ -227,8 +244,6 @@ export default {
227 244
   mounted() {
228 245
     this.initData()
229 246
     this.$nextTick(() => {
230
-
231
-
232 247
       this.initCharts()
233 248
     })
234 249
   },
@@ -247,13 +262,18 @@ export default {
247 262
     },
248 263
 
249 264
     // 处理部门选择变化
250
-    async handleinspectDepartmentIdChange() {
251
-      // 根据选择的部门调整tabList
252
-      if (!this.formData.inspectDepartmentId) {
253
-        // this.activeTab = 1;
265
+    async handleinspectDeptIdChange(e) {
266
+      console.log(e, 111, this.departments)
267
+      let depart = e.detail && e.detail.value[0];
268
+      this.getType = this.departments.find(item => item.value == depart.value).deptType;
269
+
270
+      if (this.getType == null) {
271
+        this.defaultActive = 4;
272
+      }
273
+      if (this.getType == "BRIGADE") {
254 274
         this.defaultActive = 1;
255
-      } else {
256
-        // this.activeTab = 2;
275
+      }
276
+      if (this.getType == "MANAGER") {
257 277
         this.defaultActive = 2;
258 278
       }
259 279
 
@@ -287,13 +307,26 @@ export default {
287 307
       if (this.curType === 'concealTotal') {
288 308
         obj = { isConceal: 1 }
289 309
       }
310
+      let dept = {};
311
+
312
+      if (this.getType == "BRIGADE") {
313
+        dept = { inspectBrigadeId: this.formData.inspectDeptId || this.currentUser.userInfo.deptId }
314
+      }
315
+      if (this.getType == "MANAGER") {
316
+        dept = { inspectDepartmentId: this.formData.inspectDeptId }
317
+      }
318
+      if (this.curUserRoles.includes('kezhang')) {
319
+        const deptId = this.currentUser.userInfo.deptId;
320
+        dept = { inspectDepartmentId: deptId }
321
+      }
290 322
 
291 323
 
292 324
       let params = {
325
+
293 326
         ...obj,
294 327
         startDate: startDate,
295 328
         endDate: endDate,
296
-        inspectDepartmentId: this.formData.inspectDepartmentId || null
329
+        ...dept
297 330
       }
298 331
 
299 332
       return params
@@ -322,6 +355,9 @@ export default {
322 355
     },
323 356
     // 初始化数据
324 357
     async initData() {
358
+      if (this.curUserRoles.includes('kezhang')) {
359
+        this.defaultActive = 2
360
+      }
325 361
       // 使用data()中设置的默认今天日期,不再重置dateRange
326 362
       this.calculateDays()
327 363
 
@@ -337,10 +373,19 @@ export default {
337 373
     async getEnumOption() {
338 374
       try {
339 375
         const itemCategoryRes = await treeSelectByType("ITEM_CATEGORY", 3);
376
+        //站长先获取所有部门;
340 377
         const deptTree = await getDeptList();
341
-        this.departments = [...this.departments, ...buildDepartmentOptions(deptTree.data || []).map(item => ({
378
+        //经理和行政先获取登陆角色部门下的部门
379
+        const deptId = this.currentUser.userInfo && this.currentUser.userInfo.deptId;
380
+        const subDeptTree = await getDeptList({ parentId: deptId });
381
+        // console.log(subDeptTree, "subDeptTree")
382
+        let firstOption = this.curUserRoles.includes('test') ? [{ value: null, deptType: null, text: '全站' }] : this.curUserRoles.includes('jingli') || this.curUserRoles.includes('xingzheng') ? [{ value: deptId, deptType: 'BRIGADE', text: '本队' }] : [];
383
+        //如果是站长,则获取所有部门的大队,如果是经理或行政,则获取登陆角色部门下的主管
384
+        let otherOption = this.curUserRoles.includes('test') ? buildBrigadeOptions(deptTree.data || [], true) : buildManagerOptions(subDeptTree.data, true);
385
+        console.log(otherOption, "this.departments")
386
+        this.departments = [...firstOption, ...otherOption.map(item => ({
342 387
           ...item,
343
-          text: item.text?.split('/')[1],
388
+          text: this.curUserRoles.includes('test') ? item.text?.split('/')[1] : item.text,
344 389
           value: item.value.toString()
345 390
         }))];
346 391
         console.log(itemCategoryRes.data, "itemCategoryRes.data")
@@ -380,8 +425,8 @@ export default {
380 425
     },
381 426
     // 违禁品类型变化
382 427
     onTypeChange(e) {
383
-    
384
-  
428
+
429
+
385 430
       this.initTimeLineChart()
386 431
       this.loadRankingData();
387 432
     },
@@ -1153,7 +1198,9 @@ export default {
1153 1198
       let query = this.getParams();
1154 1199
       query.categoryCodeOne = this.formData.categoryCodeOne;
1155 1200
       query.categoryCodeTwo = this.formData.categoryCodeTwo;
1156
-      query.type = type || this.defaultActive
1201
+      query.type = type || this.defaultActive;
1202
+      console.log(query, "query")
1203
+
1157 1204
       getRank(query).then(res => {
1158 1205
         const newList = res.data.map(el => {
1159 1206
           return {
@@ -1177,6 +1224,7 @@ export default {
1177 1224
       }
1178 1225
     })
1179 1226
   }
1227
+
1180 1228
 }
1181 1229
 </script>
1182 1230
 
@@ -1199,10 +1247,10 @@ export default {
1199 1247
     .filter-row {
1200 1248
       display: flex;
1201 1249
       align-items: center;
1202
-      gap: 24rpx;
1250
+      //gap: 24rpx;
1203 1251
 
1204 1252
       .filter-select {
1205
-        max-width: 180rpx;
1253
+        max-width: 200rpx;
1206 1254
         position: relative;
1207 1255
         top: 4rpx;
1208 1256
 

+ 146 - 111
src/pages/seizedReported/index.vue

@@ -5,75 +5,76 @@
5 5
       <uni-forms ref="form" :rules="rules" :modelValue="formData" label-position="top" err-show-type="modal">
6 6
         <!-- <scroll-view class="form-scroll" scroll-y> -->
7 7
         <!-- 安检员信息分组 (默认折叠) -->
8
-        <view class="card">
9
-          <uni-collapse class="collapse" :accordion="false" :value="['group1']">
10
-            <uni-collapse-item class="collapse-item" title="安检员信息" name="group1" :show-animation="true">
11
-              <template v-slot:title>
12
-                <view class="header-section collapse-title userInfo">
13
-                  <view class="userName">{{ `${type !== 'add' ? '查获人:' : ''}` }}{{ type !==
14
-                    'add' ? `${formData.inspectUserName}(${formData.createBy})` :
15
-                    `${userInfo.nickName}(${userInfo.userName})`
16
-                  }}
17
-                  </view>
18
-                  <view class="teamInfo" v-if="type !== 'add'">
19
-                    <view>{{ formData.inspectUserRoleName }}</view>
20
-                    <view class="team">
21
-
22
-                      <view v-if="formData.inspectStationName">
23
-                        {{ formData.inspectStationName }}
24
-                      </view>
25
-                      <view v-if="formData.inspectDepartmentName">
26
-                        /{{ formData.inspectDepartmentName }}
27
-                      </view>
28
-                      <view v-if="formData.inspectTeamName">
29
-                        /{{ formData.inspectTeamName }}
30
-                      </view>
8
+        <!-- <view class="card" style="overflow: visible;"> -->
9
+        <uni-collapse class="collapse" :class="firstCollapsed.length > 0 ? 'collapse-card' : 'collapse-card-hidden'"
10
+          :accordion="false" v-model="firstCollapsed" @change="changeCollapse">
11
+          <uni-collapse-item class="collapse-item" title="安检员信息" name="group1" :show-animation="true">
12
+            <template v-slot:title>
13
+              <view class="header-section collapse-title userInfo">
14
+                <view class="userName">{{ `${type !== 'add' ? '查获人:' : ''}` }}{{ type !==
15
+                  'add' ? `${formData.inspectUserName}(${formData.createBy})` :
16
+                  `${userInfo.nickName}(${userInfo.userName})`
17
+                }}
18
+                </view>
19
+                <view class="teamInfo" v-if="type !== 'add'">
20
+                  <view>{{ formData.inspectUserRoleName }}</view>
21
+                  <view class="team">
22
+
23
+                    <view v-if="formData.inspectStationName">
24
+                      {{ formData.inspectStationName }}
31 25
                     </view>
32
-                  </view>
33
-                  <view class="teamInfo" v-else>
34
-                    <view>安检员</view>
35
-                    <view class="team">
36
-
37
-                      <view v-if="userInfo.stationName">
38
-                        {{ userInfo.stationName }}
39
-                      </view>
40
-                      <view v-if="userInfo.departmentName">
41
-                        /{{ userInfo.departmentName }}
42
-                      </view>
43
-                      <view v-if="userInfo.teamsName">
44
-                        /{{ userInfo.teamsName }}
45
-                      </view>
26
+                    <view v-if="formData.inspectDepartmentName">
27
+                      /{{ formData.inspectDepartmentName }}
28
+                    </view>
29
+                    <view v-if="formData.inspectTeamName">
30
+                      /{{ formData.inspectTeamName }}
46 31
                     </view>
47 32
                   </view>
48
-
49 33
                 </view>
50
-              </template>
34
+                <view class="teamInfo" v-else>
35
+                  <view>安检员</view>
36
+                  <view class="team">
51 37
 
52
-              <uni-forms-item label="查获时间" name="seizureTime" required>
53
-                <uni-datetime-picker :disabled="isDetailMode" type="datetime" :start="startDate" :end="endDate"
54
-                  v-model="formData.seizureTime" />
55
-              </uni-forms-item>
56
-
57
-              <uni-forms-item label="安检岗位" name="checkMethodText" required>
58
-                <uni-combox :disabled="isDetailMode" :candidates="checkMethodCandidates" placeholder="请选择安检岗位"
59
-                  v-model="formData.checkMethodText" @input="onCheckMethodComboxChange" />
60
-              </uni-forms-item>
61
-
62
-              <uni-forms-item label="查获位置" name="securityLocation" required>
63
-                <uni-data-picker v-if="!isDetailMode" :readonly="isDetailMode" :localdata="position_options"
64
-                  popup-title="请选择查获位置" v-model="formData.securityLocation" @change="onLocationChange" />
65
-                <uni-easyinput v-else :disabled="true" placeholder="请选择查获班组" :value="formData.securityLocationText" />
66
-              </uni-forms-item>
67
-
68
-              <uni-forms-item label="查获班组" name="reportTeam" required>
69
-                <uni-data-picker v-if="!isDetailMode" :readonly="isDetailMode" :localdata="teams" popup-title="请选择查获班组"
70
-                  v-model="formData.reportTeam" @change="onReportTeamChange" />
38
+                    <view v-if="userInfo.stationName">
39
+                      {{ userInfo.stationName }}
40
+                    </view>
41
+                    <view v-if="userInfo.departmentName">
42
+                      /{{ userInfo.departmentName }}
43
+                    </view>
44
+                    <view v-if="userInfo.teamsName">
45
+                      /{{ userInfo.teamsName }}
46
+                    </view>
47
+                  </view>
48
+                </view>
71 49
 
72
-                <uni-easyinput v-else :disabled="true" placeholder="请选择查获班组" :value="formData.attendanceTeamName" />
73
-              </uni-forms-item>
74
-            </uni-collapse-item>
75
-          </uni-collapse>
76
-        </view>
50
+              </view>
51
+            </template>
52
+
53
+            <uni-forms-item label="查获时间" name="seizureTime" required>
54
+              <uni-datetime-picker :disabled="isDetailMode" type="datetime" :start="startDate" :end="endDate"
55
+                v-model="formData.seizureTime" />
56
+            </uni-forms-item>
57
+
58
+            <uni-forms-item label="安检岗位" name="checkMethodText" required>
59
+              <uni-combox :disabled="isDetailMode" :candidates="checkMethodCandidates" placeholder="请选择安检岗位"
60
+                v-model="formData.checkMethodText" @input="onCheckMethodComboxChange" />
61
+            </uni-forms-item>
62
+
63
+            <uni-forms-item label="查获位置" name="securityLocation" required>
64
+              <uni-data-picker v-if="!isDetailMode" :readonly="isDetailMode" :localdata="position_options"
65
+                popup-title="请选择查获位置" v-model="formData.securityLocation" @change="onLocationChange" />
66
+              <uni-easyinput v-else :disabled="true" placeholder="请选择查获班组" :value="formData.securityLocationText" />
67
+            </uni-forms-item>
68
+
69
+            <uni-forms-item label="查获班组" name="reportTeam" required>
70
+              <uni-data-picker v-if="!isDetailMode" :readonly="isDetailMode" :localdata="teams" popup-title="请选择查获班组"
71
+                v-model="formData.reportTeam" @change="onReportTeamChange" />
72
+
73
+              <uni-easyinput v-else :disabled="true" placeholder="请选择查获班组" :value="formData.attendanceTeamName" />
74
+            </uni-forms-item>
75
+          </uni-collapse-item>
76
+        </uni-collapse>
77
+        <!-- </view> -->
77 78
 
78 79
         <!-- 违禁品信息分组 -->
79 80
         <view class="card">
@@ -164,7 +165,7 @@
164 165
         <view class="card" v-if="!isDetailMode || isDetailMode && formData.images.length > 0">
165 166
           <uni-collapse class="collapse" :accordion="false" :value="['group4']">
166 167
             <uni-collapse-item class="collapse-item" title="违禁品照片 (可选)" name="group4" :show-animation="true">
167
-              <view style="padding: 0 15px 15px 15px;">
168
+              <view style="padding: 0 15px 15px 15px;margin-bottom: 150rpx;">
168 169
                 <uni-file-picker :disabled="isDetailMode" v-model="formData.images" limit="8" title="最多上传8张"
169 170
                   :image-styles="imageStyles" fileMediatype="image" mode="grid" @select="onSelect" />
170 171
               </view>
@@ -429,7 +430,8 @@ export default {
429 430
       nodeCode: '',
430 431
       id: '',
431 432
       type: '',
432
-      approvalHistory: []
433
+      approvalHistory: [],
434
+      firstCollapsed: ["group1"],
433 435
     }
434 436
   },
435 437
   async onLoad(options) {
@@ -446,7 +448,7 @@ export default {
446 448
     this.type = params?.type || 'add';
447 449
     // }
448 450
     await this.initPageData();
449
-     if (this.type == 'add') {
451
+    if (this.type == 'add') {
450 452
       this.invokerGetLocationsbyTime()
451 453
     }
452 454
 
@@ -468,6 +470,9 @@ export default {
468 470
     //   this.formData.comment = rejectReason
469 471
     //   this.handleApproveReject()
470 472
     // },
473
+    changeCollapse(e) {
474
+      this.firstCollapsed = e
475
+    },
471 476
     //审批通过
472 477
     async handleApprovePass() {
473 478
       try {
@@ -549,7 +554,10 @@ export default {
549 554
     // 填充表单数据
550 555
     fillFormData(detailData) {
551 556
       if (!detailData) return;
552
-
557
+      let files = detailData?.itemSeizureItemsList[0].baseAttachmentList.map(file => ({
558
+        ...file,
559
+        url: file.attachmentUrl || file.url,
560
+      }))
553 561
       // 填充基础信息
554 562
       this.formData = {
555 563
         ...this.formData,
@@ -572,13 +580,13 @@ export default {
572 580
         partType: detailData?.itemSeizureItemsList[0].checkPositionCodeTwo,
573 581
         partTypeText: detailData?.itemSeizureItemsList[0].checkPositionNameTwo,
574 582
         forbiddenName: detailData?.itemSeizureItemsList[0].itemName,
575
-        images: detailData?.itemSeizureItemsList[0].baseAttachmentList || [],
583
+        images: files || [],
576 584
         location: detailData?.itemSeizureItemsList[0].location,
577 585
         isActiveConcealment: String(detailData?.itemSeizureItemsList[0].isActiveConcealment),
578 586
         handlingMethodDesc: detailData?.itemSeizureItemsList[0].handlingMethodDesc,
579 587
         handlingMethod: detailData?.itemSeizureItemsList[0].handlingMethod,
580 588
         // reportTeamText:`${detailData?.inspectStationName}/${detailData?.inspectBrigadeName}/${detailData?.inspectDepartmentName}/${detailData?.inspectTeamName}`,
581
-        securityLocationText:`${detailData?.terminlName}/${detailData?.regionalName}/${detailData?.channelName}`
589
+        securityLocationText: `${detailData?.terminlName}/${detailData?.regionalName}/${detailData?.channelName}`
582 590
       };
583 591
 
584 592
       this.$nextTick(() => {
@@ -614,7 +622,7 @@ export default {
614 622
     },
615 623
 
616 624
     searchLoadData(val) {
617
-      return categoryList(val).then(res => {
625
+      return categoryList({ name: val, level: 2 }).then(res => {
618 626
         return res.data
619 627
       })
620 628
     },
@@ -803,35 +811,41 @@ export default {
803 811
 
804 812
     // 选择文件后手动上传
805 813
     async onSelect(event) {
814
+      // 由于限制只能上传1个文件,直接取第一个文件进行上传
815
+      const files = await this.uploadFile(event);
806 816
 
807
-      const file = await this.uploadFile(event)
808
-      console.log("file", file)
809
-      console.log("上传成功====");
810
-      this.formData.images.push({
817
+      console.log("上传成功====", files);
818
+      let fileArr = files.map(file => ({
811 819
         url: file.url,
812 820
         name: file.newFileName,
813 821
         attachmentName: file.newFileName,
814 822
         attachmentUrl: file.url,
815 823
         extname: file.newFileName.split('.').pop()
816
-      });
824
+      }))
825
+      // 直接替换而不是追加,因为限制只能上传1张
826
+      this.formData.images = [
827
+        ...this.formData.images,
828
+        ...fileArr
829
+      ];
817 830
     },
818 831
 
819 832
     // 封装上传
820 833
     uploadFile(event) {
821
-      return new Promise((resolve, reject) => {
822
-        uni.uploadFile({
823
-          url: `${config.baseUrl}/common/upload`,
824
-          filePath: event.tempFilePaths[0], // 取第一个文件
825
-          name: 'file',
826
-          header: { Authorization: 'Bearer ' + getToken() },
827
-          formData: {
828
-            // 可添加其他参数
829
-          },
830
-          success: (res) => resolve(JSON.parse(res.data)),
831
-          fail: reject
834
+      return Promise.all(event.tempFilePaths.map(filePath => {
835
+        return new Promise((resolve, reject) => {
836
+          uni.uploadFile({
837
+            url: `${config.baseUrl}/common/upload`,
838
+            filePath: filePath,
839
+            name: 'file',
840
+            header: { Authorization: 'Bearer ' + getToken() },
841
+            formData: {
842
+              // 可添加其他参数
843
+            },
844
+            success: (res) => resolve(JSON.parse(res.data)),
845
+            fail: reject
846
+          });
832 847
         });
833
-      });
834
-
848
+      }));
835 849
     },
836 850
 
837 851
     formatDateTime(date) {
@@ -850,25 +864,25 @@ export default {
850 864
       this.formData.securityLocation = arr[arr.length - 1]?.value || '';
851 865
       this.formData.securityLocationText = arr.map(item => item.text).join('/');
852 866
       const locationResult = this.getParentLocation(this.formData.securityLocation)
853
-        console.log(locationResult);
854
-
855
-        // 安全地处理可能为null的结果
856
-        if (locationResult) {
857
-          this.formData.terminlName = locationResult.grandParent?.text || '';
858
-          this.formData.terminlCode = locationResult.grandParent?.value || '';
859
-          this.formData.regionalName = locationResult.parent?.text || '';
860
-          this.formData.regionalCode = locationResult.parent?.value || '';
861
-          this.formData.channelName = locationResult.current?.text || '';
862
-          this.formData.channelCode = locationResult.current?.value || '';
863
-        } else {
864
-          // 如果找不到位置信息,清空相关字段
865
-          this.formData.terminlName = '';
866
-          this.formData.terminlCode = '';
867
-          this.formData.regionalName = '';
868
-          this.formData.regionalCode = '';
869
-          this.formData.channelName = '';
870
-          this.formData.channelCode = '';
871
-        }
867
+      console.log(locationResult);
868
+
869
+      // 安全地处理可能为null的结果
870
+      if (locationResult) {
871
+        this.formData.terminlName = locationResult.grandParent?.text || '';
872
+        this.formData.terminlCode = locationResult.grandParent?.value || '';
873
+        this.formData.regionalName = locationResult.parent?.text || '';
874
+        this.formData.regionalCode = locationResult.parent?.value || '';
875
+        this.formData.channelName = locationResult.current?.text || '';
876
+        this.formData.channelCode = locationResult.current?.value || '';
877
+      } else {
878
+        // 如果找不到位置信息,清空相关字段
879
+        this.formData.terminlName = '';
880
+        this.formData.terminlCode = '';
881
+        this.formData.regionalName = '';
882
+        this.formData.regionalCode = '';
883
+        this.formData.channelName = '';
884
+        this.formData.channelCode = '';
885
+      }
872 886
     },
873 887
 
874 888
     // 通用取值:只拿最后一级
@@ -1144,11 +1158,34 @@ export default {
1144 1158
     padding: 15px;
1145 1159
   }
1146 1160
 
1161
+  .collapse-card {
1162
+    border-radius: 12px;
1163
+    margin: 15px 0;
1164
+    box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 3px 1px;
1165
+
1166
+    ::v-deep .uni-collapse-item__wrap {
1167
+      overflow: visible !important;
1168
+      border-radius: 12px;
1169
+    }
1170
+  }
1171
+
1172
+  .collapse-card-hidden {
1173
+    border-radius: 12px;
1174
+    margin: 15px 0;
1175
+    box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 3px 1px;
1176
+
1177
+    ::v-deep .uni-collapse-item__wrap {
1178
+      overflow: hidden !important;
1179
+      border-radius: 12px;
1180
+    }
1181
+  }
1182
+
1183
+
1147 1184
   .card {
1148 1185
     border-radius: 12px;
1149 1186
     overflow: hidden;
1150 1187
     margin: 15px 0;
1151
-    // overflow: visible;
1188
+
1152 1189
     box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 3px 1px;
1153 1190
 
1154 1191
     .gridWrap {
@@ -1162,9 +1199,7 @@ export default {
1162 1199
       border-radius: 16px;
1163 1200
     }
1164 1201
 
1165
-    // ::v-deep .uni-collapse-item__wrap {
1166
-    //   overflow: visible !important;
1167
-    // }
1202
+
1168 1203
   }
1169 1204
 
1170 1205
   .userInfo {

+ 31 - 22
src/pages/seizedReportedVoice/index.vue

@@ -166,7 +166,7 @@
166 166
         <view class="card" v-if="!isDetailMode || isDetailMode && formData.images.length > 0">
167 167
           <uni-collapse class="collapse" :accordion="false" :value="['group4']">
168 168
             <uni-collapse-item class="collapse-item" title="违禁品照片 (可选)" name="group4" :show-animation="true">
169
-              <view style="padding: 0 15px 15px 15px;">
169
+              <view style="padding: 0 15px 15px 15px;margin-bottom: 150rpx;">
170 170
                 <uni-file-picker :disabled="isDetailMode" v-model="formData.images" limit="8" title="最多上传8张"
171 171
                   :image-styles="imageStyles" fileMediatype="image" mode="grid" @select="onSelect" />
172 172
               </view>
@@ -827,7 +827,10 @@ export default {
827 827
     // 填充表单数据
828 828
     fillFormData(detailData) {
829 829
       if (!detailData) return;
830
-
830
+      let files = detailData?.itemSeizureItemsList[0].baseAttachmentList.map(file => ({
831
+        ...file,
832
+        url: file.attachmentUrl || file.url,
833
+      }))
831 834
       // 填充基础信息
832 835
       this.formData = {
833 836
         ...this.formData,
@@ -850,7 +853,7 @@ export default {
850 853
         partType: detailData?.itemSeizureItemsList[0].checkPositionCodeTwo,
851 854
         partTypeText: detailData?.itemSeizureItemsList[0].checkPositionNameTwo,
852 855
         forbiddenName: detailData?.itemSeizureItemsList[0].itemName,
853
-        images: detailData?.itemSeizureItemsList[0].baseAttachmentList || [],
856
+        images: files || [],
854 857
         location: detailData?.itemSeizureItemsList[0].location,
855 858
         isActiveConcealment: String(detailData?.itemSeizureItemsList[0].isActiveConcealment),
856 859
         handlingMethodDesc: detailData?.itemSeizureItemsList[0].handlingMethodDesc,
@@ -892,7 +895,7 @@ export default {
892 895
     },
893 896
 
894 897
     searchLoadData(val) {
895
-      return categoryList(val).then(res => {
898
+      return categoryList({ name: val, level: 2 }).then(res => {
896 899
         return res.data
897 900
       })
898 901
     },
@@ -1082,35 +1085,41 @@ export default {
1082 1085
 
1083 1086
     // 选择文件后手动上传
1084 1087
     async onSelect(event) {
1088
+      // 由于限制只能上传1个文件,直接取第一个文件进行上传
1089
+      const files = await this.uploadFile(event);
1085 1090
 
1086
-      const file = await this.uploadFile(event)
1087
-      console.log("file", file)
1088
-      console.log("上传成功====");
1089
-      this.formData.images.push({
1091
+      console.log("上传成功====", files);
1092
+      let fileArr = files.map(file => ({
1090 1093
         url: file.url,
1091 1094
         name: file.newFileName,
1092 1095
         attachmentName: file.newFileName,
1093 1096
         attachmentUrl: file.url,
1094 1097
         extname: file.newFileName.split('.').pop()
1095
-      });
1098
+      }))
1099
+      // 直接替换而不是追加,因为限制只能上传1张
1100
+      this.formData.images = [
1101
+        ...this.formData.images,
1102
+        ...fileArr
1103
+      ];
1096 1104
     },
1097 1105
 
1098 1106
     // 封装上传
1099 1107
     uploadFile(event) {
1100
-      return new Promise((resolve, reject) => {
1101
-        uni.uploadFile({
1102
-          url: `${config.baseUrl}/common/upload`,
1103
-          filePath: event.tempFilePaths[0], // 取第一个文件
1104
-          name: 'file',
1105
-          header: { Authorization: 'Bearer ' + getToken() },
1106
-          formData: {
1107
-            // 可添加其他参数
1108
-          },
1109
-          success: (res) => resolve(JSON.parse(res.data)),
1110
-          fail: reject
1108
+      return Promise.all(event.tempFilePaths.map(filePath => {
1109
+        return new Promise((resolve, reject) => {
1110
+          uni.uploadFile({
1111
+            url: `${config.baseUrl}/common/upload`,
1112
+            filePath: filePath,
1113
+            name: 'file',
1114
+            header: { Authorization: 'Bearer ' + getToken() },
1115
+            formData: {
1116
+              // 可添加其他参数
1117
+            },
1118
+            success: (res) => resolve(JSON.parse(res.data)),
1119
+            fail: reject
1120
+          });
1111 1121
         });
1112
-      });
1113
-
1122
+      }));
1114 1123
     },
1115 1124
 
1116 1125
     formatDateTime(date) {

+ 53 - 23
src/pages/workProfile/index.vue

@@ -144,11 +144,20 @@ export default {
144 144
             userInfo: state => state.user.userInfo,
145 145
             userRoles: state => state.user.roles || [],
146 146
         }),
147
+        currentUser() {
148
+            return this.$store.state.user.userInfo;
149
+        },
147 150
         isSpecialUser() {
148
-            return this.userRoles.includes('test') || this.userRoles.includes('zhijianke')
151
+            return this.userRoles.includes('test')
152
+        },
153
+        isJingLi() {
154
+            return this.userRoles.includes('jingli')
149 155
         },
150 156
         isKeZhang() {
151 157
             return this.userRoles.includes('kezhang')
158
+        },
159
+        curUserRoles() {
160
+            return this.$store.state.user && this.$store.state.user.roles;
152 161
         }
153 162
     },
154 163
 
@@ -193,31 +202,51 @@ export default {
193 202
                 this.levelRateData = res.data || {};
194 203
             })
195 204
         },
196
-        getDept() {
197
-            return getDeptList().then(res => {
198
-                const { data } = res
199
-                let targetObj = data.find(item => item.id == '100' || item.label == '安检站');
205
+        async getDept() {
206
+            if (this.isSpecialUser) {
207
+                getDeptList().then(res => {
208
+                    const { data } = res
209
+                    let targetObj = data.find(item => item.id == '100' || item.label == '安检站');
210
+                    let arr = [
211
+                        targetObj,
212
+                        ...targetObj.children
213
+                    ]
214
+                    this.levelOptions = arr.map(item => ({
215
+                        ...item,
216
+                        value: item.id,
217
+                        text: item.label
218
+                    }))
219
+                    //如果是站长质检科的就赋值安检站
220
+                    if (this.isSpecialUser) {
221
+                        this.selectedLevel = arr[0].id
222
+                        this.handleLevelChange(arr[0].id)
223
+                    }
224
+                    // if (this.isKeZhang) {
225
+
226
+                    //     this.selectedLevel = this.userInfo.departmentId
227
+                    //     this.handleLevelChange(this.userInfo.departmentId)
228
+                    // }
229
+
230
+                })
231
+            }
232
+            if (this.isJingLi) {
233
+
234
+                const deptId = this.currentUser.deptId;
235
+                const subDeptTree = await getDeptList({ parentId: deptId });
236
+                console.log(subDeptTree, "subDeptTree", this.currentUser)
200 237
                 let arr = [
201
-                    targetObj,
202
-                    ...targetObj.children
238
+                    { id: deptId, label: '本队' },
239
+                    ...subDeptTree.data
203 240
                 ]
204 241
                 this.levelOptions = arr.map(item => ({
205 242
                     ...item,
206 243
                     value: item.id,
207 244
                     text: item.label
208 245
                 }))
209
-                //如果是站长质检科的就赋值安检站
210
-                if (this.isSpecialUser) {
211
-                    this.selectedLevel = arr[0].id
212
-                    this.handleLevelChange(arr[0].id)
213
-                }
214
-                if (this.isKeZhang) {
215
-
216
-                    this.selectedLevel = this.userInfo.departmentId
217
-                    this.handleLevelChange(this.userInfo.departmentId)
218
-                }
246
+                this.selectedLevel = arr[0].id
247
+                this.handleLevelChange(arr[0].id)
248
+            }
219 249
 
220
-            })
221 250
         },
222 251
         //获取总览
223 252
         getOverviewData() {
@@ -241,7 +270,7 @@ export default {
241 270
             getChannelOpenTrendChart(specialParams).then(res => {
242 271
                 this.channelOpenTrendData = res || [];
243 272
             })
244
-            getSeizureTrendChart(this.selectedLevelType == 'department'?params:{}).then(res => {
273
+            getSeizureTrendChart(this.selectedLevelType == 'department' ? params : {}).then(res => {
245 274
                 this.seizureTrendData = res.data || [];
246 275
             })
247 276
         },
@@ -285,9 +314,10 @@ export default {
285 314
 </script>
286 315
 
287 316
 <style lang="scss" scoped>
288
-.workProfileContainer{
317
+.workProfileContainer {
289 318
     padding: 20rpx;
290 319
 }
320
+
291 321
 .page-header {
292 322
     margin-bottom: 32rpx;
293 323
 
@@ -308,12 +338,12 @@ export default {
308 338
     z-index: 999;
309 339
     width: 95%;
310 340
     padding: 20rpx 20rpx 20rpx 30rpx;
311
-    
341
+
312 342
 
313 343
 
314 344
 
315 345
     .filter-select {
316
-        width: 205rpx !important;
346
+        width: 255rpx !important;
317 347
 
318 348
         ::v-deep .uni-stat-box {
319 349
             background: transparent !important;
@@ -325,7 +355,7 @@ export default {
325 355
 
326 356
             .uni-select__input-text {
327 357
                 font-weight: bold;
328
-                font-size:38rpx;
358
+                font-size: 38rpx;
329 359
             }
330 360
 
331 361
             .uni-select--disabled {

+ 95 - 15
src/utils/common.js

@@ -92,17 +92,29 @@ export function serializeData(obj) {
92 92
 }
93 93
 
94 94
 
95
-export function buildTeamOptions(tree = []) {
95
+export function buildTeamOptions(tree = [], includeFullData = false) {
96 96
   const result = [];
97 97
 
98 98
   function dfs(node, path = []) {
99 99
     const currentPath = [...path, node.label];
100 100
     // 如果是 TEAMS 叶子节点
101 101
     if (node.deptType === 'TEAMS') {
102
-      result.push({
103
-        text: currentPath.join(' / '),
104
-        value: node.id
105
-      });
102
+      if (includeFullData) {
103
+        // 包含完整节点数据
104
+        result.push({
105
+          ...node,
106
+          text: currentPath.join(' / '),
107
+          value: node.id,
108
+          path: currentPath,
109
+          children: null
110
+        });
111
+      } else {
112
+        // 只包含text和value
113
+        result.push({
114
+          text: currentPath.join(' / '),
115
+          value: node.id
116
+        });
117
+      }
106 118
     }
107 119
     // 继续递归子节点
108 120
     if (node.children && Array.isArray(node.children)) {
@@ -117,19 +129,32 @@ export function buildTeamOptions(tree = []) {
117 129
 /**
118 130
  * 找出deptType为DEPARTMENT的节点
119 131
  * @param {Array} tree - 树形结构数据
132
+ * @param {boolean} includeFullData - 是否包含节点的完整数据,默认false
120 133
  * @returns {Array} 包含所有DEPARTMENT节点的数组
121 134
  */
122
-export function buildDepartmentOptions(tree = []) {
135
+export function buildDepartmentOptions(tree = [], includeFullData = false) {
123 136
   const result = [];
124 137
 
125 138
   function dfs(node, path = []) {
126 139
     const currentPath = [...path, node.label];
127 140
     // 如果是 DEPARTMENT 节点
128 141
     if (node.deptType === 'DEPARTMENT') {
129
-      result.push({
130
-        text: currentPath.join(' / '),
131
-        value: node.id
132
-      });
142
+      if (includeFullData) {
143
+        // 包含完整节点数据
144
+        result.push({
145
+          ...node,
146
+          text: currentPath.join(' / '),
147
+          value: node.id,
148
+          path: currentPath,
149
+          children: null
150
+        });
151
+      } else {
152
+        // 只包含text和value
153
+        result.push({
154
+          text: currentPath.join(' / '),
155
+          value: node.id
156
+        });
157
+      }
133 158
     }
134 159
     // 继续递归子节点
135 160
     if (node.children && Array.isArray(node.children)) {
@@ -144,19 +169,72 @@ export function buildDepartmentOptions(tree = []) {
144 169
 /**
145 170
  * 找出deptType为BRIGADE的节点
146 171
  * @param {Array} tree - 树形结构数据
172
+ * @param {boolean} includeFullData - 是否包含节点的完整数据,默认false
147 173
  * @returns {Array} 包含所有BRIGADE节点的数组
148 174
  */
149
-export function buildBrigadeOptions(tree = []) {
175
+export function buildBrigadeOptions(tree = [], includeFullData = false) {
150 176
   const result = [];
151 177
 
152 178
   function dfs(node, path = []) {
153 179
     const currentPath = [...path, node.label];
154 180
     // 如果是 DEPARTMENT 节点
155 181
     if (node.deptType === 'BRIGADE') {
156
-      result.push({
157
-        text: currentPath.join(' / '),
158
-        value: node.id
159
-      });
182
+      if (includeFullData) {
183
+        // 包含完整节点数据
184
+        result.push({
185
+          ...node,
186
+          text: currentPath.join(' / '),
187
+          value: node.id,
188
+          path: currentPath,
189
+          children: null
190
+        });
191
+      } else {
192
+        // 只包含text和value
193
+        result.push({
194
+          text: currentPath.join(' / '),
195
+          value: node.id
196
+        });
197
+      }
198
+    }
199
+    // 继续递归子节点
200
+    if (node.children && Array.isArray(node.children)) {
201
+      node.children.forEach(child => dfs(child, currentPath));
202
+    }
203
+  }
204
+
205
+  tree.forEach(root => dfs(root));
206
+  return result;
207
+}
208
+
209
+/**
210
+ * 找出deptType为BRIGADE的节点
211
+ * @param {Array} tree - 树形结构数据
212
+ * @param {boolean} includeFullData - 是否包含节点的完整数据,默认false
213
+ * @returns {Array} 包含所有BRIGADE节点的数组
214
+ */
215
+export function buildManagerOptions(tree = [], includeFullData = false) {
216
+  const result = [];
217
+
218
+  function dfs(node, path = []) {
219
+    const currentPath = [...path, node.label];
220
+    // 如果是 DEPARTMENT 节点
221
+    if (node.deptType === 'MANAGER') {
222
+      if (includeFullData) {
223
+        // 包含完整节点数据
224
+        result.push({
225
+          ...node,
226
+          text: currentPath.join(' / '),
227
+          value: node.id,
228
+          path: currentPath,
229
+          children: null
230
+        });
231
+      } else {
232
+        // 只包含text和value
233
+        result.push({
234
+          text: currentPath.join(' / '),
235
+          value: node.id
236
+        });
237
+      }
160 238
     }
161 239
     // 继续递归子节点
162 240
     if (node.children && Array.isArray(node.children)) {
@@ -444,3 +522,5 @@ export function checkRolePermission(role, path) {
444 522
   return rolePermissions[role].includes(path);
445 523
 }
446 524
 
525
+
526
+