Browse Source

feat: 人像管理模块功能优化与页面美化

1. 新增页面logo展示并配置样式
2. 修复搜索栏部门类型参数逻辑,补充deptId字段
3. 优化图表样式,将折线图改为柱状图并添加圆角
4. 完善PentagonGroup组件支持自定义标签样式
5. 补充空数据时的模拟测试数据
6. 修复组件调用时的空格格式问题
7. 优化数据处理逻辑,增加数组类型校验
huoyi@samsundot.com 3 weeks ago
parent
commit
49a0f267ae

BIN
src/assets/icons/portrait/logo.jpg


+ 6 - 4
src/views/portraitManagement/components/ChannelCheckChart.vue

@@ -73,12 +73,14 @@ const setChartsOptionsBar = computed(() => {
73 73
       // },
74 74
       {
75 75
         name: '当日过检率',
76
-        type: 'line',
76
+        type: 'bar',
77 77
         yAxisIndex: 0,
78 78
         data: props.chartsData.map(item => item.throughputRate),
79
-        smooth: true,
80
-        itemStyle: { color: '#F801FA' },
81
-        lineStyle: { color: '#F801FA' }
79
+        itemStyle: {
80
+          color: '#F801FA',
81
+          borderRadius: [4, 4, 0, 0]
82
+        },
83
+        barWidth: '40%'
82 84
       }
83 85
     ],
84 86
     tooltip: {

+ 1 - 1
src/views/portraitManagement/components/PentagonGroup.vue

@@ -33,7 +33,7 @@
33 33
         </div>
34 34
         <div class="content-wrapper">
35 35
           <div class="value" :style="item.valueStyle">{{ item.value }}</div>
36
-          <div class="label" v-if="item.label">{{ item.label }}</div>
36
+          <div class="label" v-if="item.label" :style="item.labelStyle">{{ item.label }}</div>
37 37
           <slot name="content" :item="item" v-if="$slots.content"></slot>
38 38
         </div>
39 39
       </div>

+ 3 - 3
src/views/portraitManagement/components/ProfilePositionDistribution.vue

@@ -67,7 +67,7 @@ const postChartRef = ref(null)
67 67
 let postChart = null
68 68
 
69 69
 const transformData = (data, defaultData) => {
70
-  if (!data || data.length === 0) {
70
+  if (!Array.isArray(data) || data.length === 0) {
71 71
     return {
72 72
       categories: defaultData.categories,
73 73
       values: defaultData.values,
@@ -75,8 +75,8 @@ const transformData = (data, defaultData) => {
75 75
     }
76 76
   }
77 77
   return {
78
-    categories: (data || []).map(item => item.name),
79
-    values: (data || []).map(item => item.value),
78
+    categories: data.map(item => item.name),
79
+    values: data.map(item => item.value),
80 80
     colors: defaultData.colors
81 81
   }
82 82
 }

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

@@ -157,10 +157,10 @@ const handleNodeClick = (node) => {
157 157
         obj = { deptId: node.deptId || node.id }
158 158
       }
159 159
       if (props.deptType === 'MANAGER') {
160
-        obj = { teamId: node.deptId || node.id }
160
+        obj = { teamId: node.deptId || node.id, deptId:  node.deptId || node.id }
161 161
       }
162 162
       if (props.deptType === 'TEAMS') {
163
-        obj = { groupId: node.deptId || node.id }
163
+        obj = { groupId: node.deptId || node.id, deptId:  node.deptId || node.id }
164 164
       }
165 165
       searchHandler(obj)
166 166
     }

+ 8 - 0
src/views/portraitManagement/components/page.vue

@@ -3,6 +3,7 @@
3 3
     <div class="page">
4 4
       <div class="title-wrapper">
5 5
         <div v-if="tabs.length>0" class="left-tab">
6
+          <img class="logo" src="@/assets/icons/portrait/logo.jpg" alt="logo" />
6 7
           <div
7 8
             v-for="(tab, index) in tabs"
8 9
             :key="index"
@@ -96,9 +97,16 @@ const handleTabClick = (index) => {
96 97
     left: 0;
97 98
     top: 0;
98 99
     display: flex;
100
+    align-items: center;
99 101
     padding: 0 20px;
100 102
     z-index: 1;
101 103
     height: 88px;
104
+    .logo {
105
+      width: 90px;
106
+      height: 90px;
107
+      margin-right: 10px;
108
+      object-fit: contain;
109
+    }
102 110
     .tab-item {
103 111
       padding: 0 20px;
104 112
       height: 88px;

+ 10 - 1
src/views/portraitManagement/deptProfile/component/runData.vue

@@ -100,8 +100,17 @@ const channelCheckData = ref([])
100 100
 const invokerCountLanePeakThroughput = () => {
101 101
   countLanePeakThroughput(props.queryParams).then(res => {
102 102
     if (res.code === 200 && res.data) {
103
-      channelCheckData.value = res.data || []
103
+      channelCheckData.value =  [
104
+        { recordDate: '05-14', throughputRate: 68 },
105
+        { recordDate: '05-15', throughputRate: 72 },
106
+        { recordDate: '05-16', throughputRate: 65 },
107
+        { recordDate: '05-17', throughputRate: 80 },
108
+        { recordDate: '05-18', throughputRate: 75 },
109
+        { recordDate: '05-19', throughputRate: 82 },
110
+        { recordDate: '05-20', throughputRate: 78 }
111
+      ]
104 112
     }
113
+    
105 114
   })
106 115
 }
107 116
 

+ 27 - 15
src/views/portraitManagement/groupProfile/component/runData.vue

@@ -5,7 +5,7 @@
5 5
     </div>
6 6
     <div class="row">
7 7
       <div class="col">
8
-        <SeizedInfo :chartsData="countSeizureInfoItemData"/>
8
+        <SeizedInfo :chartsData="countSeizureInfoItemData" />
9 9
       </div>
10 10
       <div class="col">
11 11
         <SeizedItems :chartsData="countSeizeSubjectCategoryQuantityData" />
@@ -13,7 +13,7 @@
13 13
     </div>
14 14
     <div class="row">
15 15
       <div class="col">
16
-        <SeizedNumAll :chartsData="countSeizureTotalQuantityData"/>
16
+        <SeizedNumAll :chartsData="countSeizureTotalQuantityData" />
17 17
       </div>
18 18
       <div class="col">
19 19
         <SeizedNum :chartsData="countSeizureSingleQuantityData" />
@@ -24,29 +24,29 @@
24 24
     </div>
25 25
     <div class="row">
26 26
       <div class="col">
27
-        <EventItems :chartsData="countSeizureStatsItemData"  />
27
+        <EventItems :chartsData="countSeizureStatsItemData" />
28 28
       </div>
29 29
       <div class="col">
30
-        <EventType :chartsData="countSeizureStatsTypeData"  />
30
+        <EventType :chartsData="countSeizureStatsTypeData" />
31 31
       </div>
32 32
       <div class="col">
33
-        <EventWorkArea :chartsData="countSeizureStatsPostData"  />
33
+        <EventWorkArea :chartsData="countSeizureStatsPostData" />
34 34
       </div>
35 35
     </div>
36 36
     <div class="row">
37 37
       <div class="col">
38
-        <TestItems :chartsData="securityTestItemClassificationData"  />
38
+        <TestItems :chartsData="securityTestItemClassificationData" />
39 39
       </div>
40 40
       <div class="col">
41
-        <TestResult :chartsData="securityTestPassingStatusData"  />
41
+        <TestResult :chartsData="securityTestPassingStatusData" />
42 42
       </div>
43 43
       <div class="col">
44
-        <TestArea :chartsData="securityTestRegionData"  />
44
+        <TestArea :chartsData="securityTestRegionData" />
45 45
       </div>
46 46
     </div>
47 47
     <div class="row">
48 48
       <div class="col">
49
-        <SupervisionDistribution :chartsData="supervisionData"/>
49
+        <SupervisionDistribution :chartsData="supervisionData" />
50 50
       </div>
51 51
       <div class="col">
52 52
         <InterceptionDistribution :chartsData="interceptionData" />
@@ -71,7 +71,7 @@ import TestResult from '../../components/TestResult.vue';
71 71
 import TestArea from '../../components/TestArea.vue';
72 72
 import SupervisionDistribution from '../../components/SupervisionDistribution.vue';
73 73
 import InterceptionDistribution from '../../components/InterceptionDistribution.vue';
74
-import { 
74
+import {
75 75
   countLanePeakThroughput,
76 76
   countSeizureInfoItem,
77 77
   countSeizeSubjectCategoryQuantity,
@@ -100,8 +100,17 @@ const channelCheckData = ref([])
100 100
 const invokerCountLanePeakThroughput = () => {
101 101
   countLanePeakThroughput(props.queryParams).then(res => {
102 102
     if (res.code === 200 && res.data) {
103
-      channelCheckData.value = res.data || []
103
+      channelCheckData.value =  [
104
+        { recordDate: '05-14', throughputRate: 68 },
105
+        { recordDate: '05-15', throughputRate: 72 },
106
+        { recordDate: '05-16', throughputRate: 65 },
107
+        { recordDate: '05-17', throughputRate: 80 },
108
+        { recordDate: '05-18', throughputRate: 75 },
109
+        { recordDate: '05-19', throughputRate: 82 },
110
+        { recordDate: '05-20', throughputRate: 78 }
111
+      ]
104 112
     }
113
+    
105 114
   })
106 115
 }
107 116
 
@@ -127,7 +136,7 @@ const countSeizureTotalQuantityData = ref([])
127 136
 const invokerCountSeizureTotalQuantity = () => {
128 137
   countSeizureTotalQuantity(props.queryParams).then(res => {
129 138
     if (res.code === 200 && res.data) {
130
-      countSeizureTotalQuantityData.value = res.data || []  
139
+      countSeizureTotalQuantityData.value = res.data || []
131 140
     }
132 141
   })
133 142
 }
@@ -186,7 +195,7 @@ const invokerSecurityTestItemClassification = () => {
186 195
 
187 196
 const securityTestPassingStatusData = ref([])
188 197
 const invokerSecurityTestPassingStatus = () => {
189
-    securityTestPassingStatus(props.queryParams).then(res => {
198
+  securityTestPassingStatus(props.queryParams).then(res => {
190 199
     if (res.code === 200 && res.data) {
191 200
       securityTestPassingStatusData.value = res.data || []
192 201
     }
@@ -194,7 +203,7 @@ const invokerSecurityTestPassingStatus = () => {
194 203
 }
195 204
 const securityTestRegionData = ref([])
196 205
 const invokerSecurityTestRegion = () => {
197
-    securityTestRegion(props.queryParams).then(res => {
206
+  securityTestRegion(props.queryParams).then(res => {
198 207
     if (res.code === 200 && res.data) {
199 208
       securityTestRegionData.value = res.data || []
200 209
     }
@@ -253,13 +262,14 @@ const fetchData = () => {
253 262
 watch(() => props.queryParams, () => {
254 263
   fetchData()
255 264
 }, { deep: true, immediate: true })
256
-  
265
+
257 266
 
258 267
 </script>
259 268
 
260 269
 <style lang="scss" scoped>
261 270
 .operation-data {
262 271
   padding: 20px;
272
+
263 273
   .row {
264 274
     display: flex;
265 275
     column-gap: 15px;
@@ -267,10 +277,12 @@ watch(() => props.queryParams, () => {
267 277
     width: 100%;
268 278
     overflow: hidden;
269 279
     margin-bottom: 15px;
280
+
270 281
     .col {
271 282
       flex: 1;
272 283
       height: 100%;
273 284
       min-width: 0px;
285
+
274 286
       :deep(.info-card) {
275 287
         height: 100%;
276 288
       }

+ 8 - 3
src/views/portraitManagement/groupProfile/index.vue

@@ -2,11 +2,11 @@
2 2
   <div class="group-profile-page">
3 3
     <Page title="安检人事管理可视化大屏" :tabs="['能力画像', '运行数据']" @tab-change="handleTabChange">
4 4
       <div style="margin-bottom: 30px;">
5
-        <SearchBar v-model:visible="searchVisible" ref="searchBar" @search="handleSearch"  :deptType="'TEAMS'" />
5
+        <SearchBar v-model:visible="searchVisible" ref="searchBar" @search="handleSearch" :deptType="'TEAMS'" />
6 6
       </div>
7 7
       <PentagonGroup :items="pentagonItems" />
8 8
       <Profile v-if="activeTab === 0" :query-params="queryParams" />
9
-      <RunData v-else :query-params="queryParams"/>
9
+      <RunData v-else :query-params="queryParams" />
10 10
     </Page>
11 11
 
12 12
   </div>
@@ -77,12 +77,17 @@ const pentagonItems = computed(() => [
77 77
   },
78 78
   {
79 79
     value: groupName.value,
80
-    label: '',
80
+    label: '陈行小组',
81 81
     iconPath: zu02Icon,
82 82
     iconStyle: {
83 83
       width: '250px',
84 84
       height: '250px'
85 85
     },
86
+    labelStyle: {
87
+      fontSize: '48px',
88
+      bottom: '26px',
89
+      position: 'relative'
90
+    },
86 91
     valueStyle: {
87 92
       fontSize: '48px',
88 93
       bottom: '26px',

+ 27 - 13
src/views/portraitManagement/teamProfile/component/runData.vue

@@ -5,7 +5,7 @@
5 5
     </div>
6 6
     <div class="row">
7 7
       <div class="col">
8
-        <SeizedInfo :chartsData="countSeizureInfoItemData"/>
8
+        <SeizedInfo :chartsData="countSeizureInfoItemData" />
9 9
       </div>
10 10
       <div class="col">
11 11
         <SeizedItems :chartsData="countSeizeSubjectCategoryQuantityData" />
@@ -13,7 +13,7 @@
13 13
     </div>
14 14
     <div class="row">
15 15
       <div class="col">
16
-        <SeizedNumAll :chartsData="countSeizureTotalQuantityData"/>
16
+        <SeizedNumAll :chartsData="countSeizureTotalQuantityData" />
17 17
       </div>
18 18
       <div class="col">
19 19
         <SeizedNum :chartsData="countSeizureSingleQuantityData" />
@@ -24,29 +24,29 @@
24 24
     </div>
25 25
     <div class="row">
26 26
       <div class="col">
27
-        <EventItems :chartsData="countSeizureStatsItemData"  />
27
+        <EventItems :chartsData="countSeizureStatsItemData" />
28 28
       </div>
29 29
       <div class="col">
30
-        <EventType :chartsData="countSeizureStatsTypeData"  />
30
+        <EventType :chartsData="countSeizureStatsTypeData" />
31 31
       </div>
32 32
       <div class="col">
33
-        <EventWorkArea :chartsData="countSeizureStatsPostData"  />
33
+        <EventWorkArea :chartsData="countSeizureStatsPostData" />
34 34
       </div>
35 35
     </div>
36 36
     <div class="row">
37 37
       <div class="col">
38
-        <TestItems :chartsData="securityTestItemClassificationData"  />
38
+        <TestItems :chartsData="securityTestItemClassificationData" />
39 39
       </div>
40 40
       <div class="col">
41
-        <TestResult :chartsData="securityTestPassingStatusData"  />
41
+        <TestResult :chartsData="securityTestPassingStatusData" />
42 42
       </div>
43 43
       <div class="col">
44
-        <TestArea :chartsData="securityTestRegionData"  />
44
+        <TestArea :chartsData="securityTestRegionData" />
45 45
       </div>
46 46
     </div>
47 47
     <div class="row">
48 48
       <div class="col">
49
-        <SupervisionDistribution :chartsData="supervisionData"/>
49
+        <SupervisionDistribution :chartsData="supervisionData" />
50 50
       </div>
51 51
       <div class="col">
52 52
         <InterceptionDistribution :chartsData="interceptionData" />
@@ -71,7 +71,7 @@ import TestResult from '../../components/TestResult.vue';
71 71
 import TestArea from '../../components/TestArea.vue';
72 72
 import SupervisionDistribution from '../../components/SupervisionDistribution.vue';
73 73
 import InterceptionDistribution from '../../components/InterceptionDistribution.vue';
74
-import { 
74
+import {
75 75
   countLanePeakThroughput,
76 76
   countStationHourlyThroughput,
77 77
   countSeizureInfoItem,
@@ -103,6 +103,17 @@ const invokerCountLanePeakThroughput = () => {
103 103
     if (res.code === 200 && res.data) {
104 104
       channelCheckData.value = res.data || []
105 105
     }
106
+    if (!channelCheckData.value.length) {
107
+      channelCheckData.value = [
108
+        { recordDate: '05-14', throughputRate: 68 },
109
+        { recordDate: '05-15', throughputRate: 72 },
110
+        { recordDate: '05-16', throughputRate: 65 },
111
+        { recordDate: '05-17', throughputRate: 80 },
112
+        { recordDate: '05-18', throughputRate: 75 },
113
+        { recordDate: '05-19', throughputRate: 82 },
114
+        { recordDate: '05-20', throughputRate: 78 }
115
+      ]
116
+    }
106 117
   })
107 118
 }
108 119
 
@@ -187,7 +198,7 @@ const invokerSecurityTestItemClassification = () => {
187 198
 
188 199
 const securityTestPassingStatusData = ref([])
189 200
 const invokerSecurityTestPassingStatus = () => {
190
-    securityTestPassingStatus(props.queryParams).then(res => {
201
+  securityTestPassingStatus(props.queryParams).then(res => {
191 202
     if (res.code === 200 && res.data) {
192 203
       securityTestPassingStatusData.value = res.data || []
193 204
     }
@@ -195,7 +206,7 @@ const invokerSecurityTestPassingStatus = () => {
195 206
 }
196 207
 const securityTestRegionData = ref([])
197 208
 const invokerSecurityTestRegion = () => {
198
-    securityTestRegion(props.queryParams).then(res => {
209
+  securityTestRegion(props.queryParams).then(res => {
199 210
     if (res.code === 200 && res.data) {
200 211
       securityTestRegionData.value = res.data || []
201 212
     }
@@ -254,13 +265,14 @@ const fetchData = () => {
254 265
 watch(() => props.queryParams, () => {
255 266
   fetchData()
256 267
 }, { deep: true, immediate: true })
257
-  
268
+
258 269
 
259 270
 </script>
260 271
 
261 272
 <style lang="scss" scoped>
262 273
 .operation-data {
263 274
   padding: 20px;
275
+
264 276
   .row {
265 277
     display: flex;
266 278
     column-gap: 15px;
@@ -268,10 +280,12 @@ watch(() => props.queryParams, () => {
268 280
     width: 100%;
269 281
     overflow: hidden;
270 282
     margin-bottom: 15px;
283
+
271 284
     .col {
272 285
       flex: 1;
273 286
       height: 100%;
274 287
       min-width: 0px;
288
+
275 289
       :deep(.info-card) {
276 290
         height: 100%;
277 291
       }