Browse Source

feat: 完成人像管理模块多页面功能优化与修复

1. 修复SearchBar组件中STATION默认ID配置错误
2. 为 seizedNum 图表添加图例显示
3. 调整运行数据页面接口调用,修正接口名称与注释
4. 优化分数事件页面表单重置逻辑,清空更多关联参数
5. 为雷达图表添加自动配色功能
6. 为多个图表组件添加自定义tooltip与数据缩放组件
7. 重构滚动表格组件,修复滚动逻辑问题
8. 重构部门/小组/队伍画像页面的五角展示数据,从接口动态获取真实数据
huoyi@samsundot.com 3 weeks ago
parent
commit
0f10607a56

+ 24 - 3
src/views/portraitManagement/components/ProfileBasicDistribution.vue

@@ -89,9 +89,16 @@ const updateGenderChart = (data) => {
89 89
   }
90 90
   const chartData = data && data.length > 0 ? getGenderColors(data) : defaultGenderData
91 91
   genderChart.setOption({
92
+    tooltip: {
93
+      trigger: 'item',
94
+      backgroundColor: 'rgba(13,80,122,0.95)',
95
+      borderColor: '#70CFE7',
96
+      textStyle: { color: '#fff' },
97
+      formatter: '{b}: {c} ({d}%)'
98
+    },
92 99
     series: [{
93 100
       type: 'pie',
94
-      radius: ['50%', '70%'],
101
+      radius: ['38%', '55%'],
95 102
       data: chartData,
96 103
       label: { show: true, color: '#fff', fontSize: 11 },
97 104
       labelLine: { show: true }
@@ -106,9 +113,16 @@ const updateNationChart = (data) => {
106 113
   }
107 114
   const chartData = data && data.length > 0 ? getNationColors(data) : defaultNationData
108 115
   nationChart.setOption({
116
+    tooltip: {
117
+      trigger: 'item',
118
+      backgroundColor: 'rgba(13,80,122,0.95)',
119
+      borderColor: '#70CFE7',
120
+      textStyle: { color: '#fff' },
121
+      formatter: '{b}: {c} ({d}%)'
122
+    },
109 123
     series: [{
110 124
       type: 'pie',
111
-      radius: ['50%', '70%'],
125
+      radius: ['38%', '55%'],
112 126
       data: chartData,
113 127
       label: { show: true, color: '#fff', fontSize: 11 },
114 128
       labelLine: { show: true }
@@ -123,9 +137,16 @@ const updatePoliticalChart = (data) => {
123 137
   }
124 138
   const chartData = data && data.length > 0 ? getPoliticalColors(data) : defaultPoliticalData
125 139
   politicalChart.setOption({
140
+    tooltip: {
141
+      trigger: 'item',
142
+      backgroundColor: 'rgba(13,80,122,0.95)',
143
+      borderColor: '#70CFE7',
144
+      textStyle: { color: '#fff' },
145
+      formatter: '{b}: {c} ({d}%)'
146
+    },
126 147
     series: [{
127 148
       type: 'pie',
128
-      radius: ['50%', '70%'],
149
+      radius: ['38%', '55%'],
129 150
       data: chartData,
130 151
       label: { show: true, color: '#fff', fontSize: 11 },
131 152
       labelLine: { show: true }

+ 21 - 0
src/views/portraitManagement/components/ProfilePositionDistribution.vue

@@ -89,6 +89,13 @@ const updateSkillChart = (data) => {
89 89
   const chartData = transformData(data, defaultSkillData)
90 90
  
91 91
   skillChart.setOption({
92
+    tooltip: {
93
+      trigger: 'axis',
94
+      backgroundColor: 'rgba(13,80,122,0.95)',
95
+      borderColor: '#70CFE7',
96
+      textStyle: { color: '#fff' },
97
+      formatter: '{b}: {c}'
98
+    },
92 99
     xAxis: {
93 100
       type: 'category',
94 101
       data: chartData.categories,
@@ -123,6 +130,13 @@ const updateOperateChart = (data) => {
123 130
   const chartData = transformData(data, defaultOperateData)
124 131
   
125 132
   operateChart.setOption({
133
+    tooltip: {
134
+      trigger: 'axis',
135
+      backgroundColor: 'rgba(13,80,122,0.95)',
136
+      borderColor: '#70CFE7',
137
+      textStyle: { color: '#fff' },
138
+      formatter: '{b}: {c}'
139
+    },
126 140
     xAxis: {
127 141
       type: 'category',
128 142
       data: chartData.categories,
@@ -156,6 +170,13 @@ const updatePostChart = (data) => {
156 170
   }
157 171
   const chartData = transformData(data, defaultPostData)
158 172
   postChart.setOption({
173
+    tooltip: {
174
+      trigger: 'axis',
175
+      backgroundColor: 'rgba(13,80,122,0.95)',
176
+      borderColor: '#70CFE7',
177
+      textStyle: { color: '#fff' },
178
+      formatter: '{b}: {c}'
179
+    },
159 180
     xAxis: {
160 181
       type: 'category',
161 182
       data: chartData.categories,

+ 10 - 1
src/views/portraitManagement/components/ProfileRadar.vue

@@ -31,12 +31,21 @@ const props = defineProps({
31 31
   }
32 32
 })
33 33
 
34
+const freshColors = [
35
+  '#00e5ff', '#36d399', '#fbbf24', '#f472b6', '#a78bfa',
36
+  '#34d399', '#f97316', '#2dd4bf', '#e879f9', '#38bdf8'
37
+]
38
+
34 39
 const defaultRadarData = [
35 40
 
36 41
 ]
37 42
 
38 43
 const computedRadarData = computed(() => {
39
-  return props.chartData.length > 0 ? props.chartData : defaultRadarData
44
+  const data = props.chartData.length > 0 ? props.chartData : defaultRadarData
45
+  return data.map((item, index) => ({
46
+    ...item,
47
+    color: item.color || freshColors[index % freshColors.length]
48
+  }))
40 49
 })
41 50
 
42 51
 const computedIndicators = computed(() => {

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

@@ -72,7 +72,7 @@ const currentKey = ref(null)
72 72
 const defaultIdMap = {
73 73
   user: 13,
74 74
   BRIGADE: 103,
75
-  STATION: 103,
75
+  STATION: 100,
76 76
   MANAGER: 104,
77 77
   TEAMS: 110
78 78
 }

+ 18 - 0
src/views/portraitManagement/components/SeizedInfo.vue

@@ -110,6 +110,24 @@ const setChartsOptionsBar = computed(() => {
110 110
         barWidth: '50%'
111 111
       },
112 112
     ],
113
+    dataZoom: [
114
+      {
115
+        type: 'slider',
116
+        show: props.chartsData.itemList.length > 6,
117
+        height: 20,
118
+        bottom: 5,
119
+        borderColor: 'transparent',
120
+        backgroundColor: 'rgba(15,70,250,0.15)',
121
+        fillerColor: 'rgba(15,70,250,0.4)',
122
+        handleStyle: { color: '#4da6ff' },
123
+        textStyle: { color: '#a0c4ff' },
124
+        labelFormatter: ''
125
+      },
126
+      {
127
+        type: 'inside',
128
+        disabled: props.chartsData.itemList.length <= 6
129
+      }
130
+    ],
113 131
     tooltip: {
114 132
       trigger: 'axis',
115 133
       backgroundColor: 'rgba(13,80,122,1)',

+ 3 - 0
src/views/portraitManagement/components/SeizedNum.vue

@@ -65,6 +65,9 @@
65 65
         left: 60,
66 66
         right: 20
67 67
       },
68
+      legend: {
69
+        show: true
70
+      },
68 71
       xAxis: {
69 72
         type: 'category',
70 73
         axisLabel: { show: false },

+ 43 - 37
src/views/portraitManagement/components/rollingTable.vue

@@ -35,6 +35,8 @@ const props = defineProps({
35 35
 
36 36
 const scrollContentRef = ref(null)
37 37
 let animationId = null
38
+let isActive = false
39
+let pendingStart = false
38 40
 
39 41
 const scrollData = computed(() => {
40 42
   if (!props.data || props.data.length === 0) return []
@@ -42,41 +44,48 @@ const scrollData = computed(() => {
42 44
 })
43 45
 
44 46
 const startScroll = () => {
45
-  const content = scrollContentRef.value
46
-  if (!content || props.data.length <= 0) return
47
-
48
-  let lastTime = performance.now()
49
-  let currentScrollY = 0
50
-  content.style.transform = 'translateY(0px)'
51
-
52
-  const scroll = (currentTime) => {
53
-    if (!content) {
54
-      animationId = requestAnimationFrame(scroll)
55
-      return
56
-    }
47
+  stopScroll()
48
+  if (pendingStart) return
49
+  pendingStart = true
50
+  nextTick(() => {
51
+    pendingStart = false
52
+    if (!isActive) return
53
+    const content = scrollContentRef.value
54
+    if (!content || props.data.length <= 0) return
55
+
56
+    let lastTime = performance.now()
57
+    let currentScrollY = 0
58
+    content.style.transform = 'translateY(0px)'
59
+
60
+    const scroll = (currentTime) => {
61
+      if (!isActive || !content) {
62
+        animationId = null
63
+        return
64
+      }
65
+
66
+      const halfHeight = content.scrollHeight / 2
67
+      if (halfHeight <= 0) {
68
+        animationId = requestAnimationFrame(scroll)
69
+        return
70
+      }
71
+
72
+      const step = halfHeight / (props.duration * 60)
73
+      const delta = currentTime - lastTime
74
+      lastTime = currentTime
75
+
76
+      currentScrollY += step * (delta / 16.67)
77
+
78
+      if (currentScrollY >= halfHeight) {
79
+        currentScrollY = 0
80
+      }
81
+
82
+      content.style.transform = `translateY(${-currentScrollY}px)`
57 83
 
58
-    const halfHeight = content.scrollHeight / 2
59
-    if (halfHeight <= 0) {
60 84
       animationId = requestAnimationFrame(scroll)
61
-      return
62 85
     }
63 86
 
64
-    const step = halfHeight / (props.duration * 60)
65
-    const delta = currentTime - lastTime
66
-    lastTime = currentTime
67
-
68
-    currentScrollY += step * (delta / 16.67)
69
-
70
-    if (currentScrollY >= halfHeight) {
71
-      currentScrollY = 0
72
-    }
73
-
74
-    content.style.transform = `translateY(${-currentScrollY}px)`
75
-
76 87
     animationId = requestAnimationFrame(scroll)
77
-  }
78
-
79
-  animationId = requestAnimationFrame(scroll)
88
+  })
80 89
 }
81 90
 
82 91
 const stopScroll = () => {
@@ -87,23 +96,20 @@ const stopScroll = () => {
87 96
 }
88 97
 
89 98
 onMounted(() => {
99
+  isActive = true
90 100
   if (props.data.length > 0) {
91
-    nextTick(() => {
92
-      startScroll()
93
-    })
101
+    startScroll()
94 102
   }
95 103
 })
96 104
 
97 105
 watch(() => props.data, (val) => {
98
-  stopScroll()
99 106
   if (val && val.length > 0) {
100
-    nextTick(() => {
101
-      startScroll()
102
-    })
107
+    startScroll()
103 108
   }
104 109
 })
105 110
 
106 111
 onUnmounted(() => {
112
+  isActive = false
107 113
   stopScroll()
108 114
 })
109 115
 </script>

+ 16 - 13
src/views/portraitManagement/deptProfile/index.vue

@@ -1,7 +1,8 @@
1 1
 <template>
2 2
   <div class="group-profile-page">
3 3
     <Page title="安检人事管理可视化大屏" :tabs="['能力画像', '运行数据']" @tab-change="handleTabChange">
4
-      <SearchBar v-model:visible="searchVisible" ref="searchBar" @search="handleSearch" @init-done="handleInitDone" :deptType="'BRIGADE'" />
4
+      <SearchBar v-model:visible="searchVisible" ref="searchBar" @search="handleSearch" @init-done="handleInitDone"
5
+        :deptType="'BRIGADE'" />
5 6
       <PentagonGroup :items="pentagonItems" />
6 7
       <Profile v-if="activeTab === 0" :query-params="queryParams" />
7 8
       <RunData v-else :query-params="queryParams" />
@@ -28,14 +29,18 @@ const activeTab = ref(0)
28 29
 const searchVisible = ref(false)
29 30
 const queryParams = ref({})
30 31
 
31
-const teamStatsData = ref(null)
32
+const pentagonItems = ref([])
32 33
 const invokerCountDeptTeamStats = (params) => {
33
-  countDeptTeamStats(params).then(res => {
34
+  const copyParams = {
35
+    deptId: params.deptId,
36
+
37
+  }
38
+  countDeptTeamStats(copyParams).then(res => {
34 39
     if (res.code === 200 && res.data) {
35
-      console.log(res.data)
36
-      teamStatsData.value = [
40
+      const result = res.data
41
+      pentagonItems.value = [
37 42
         {
38
-          value: '88',
43
+          value: result.totalScore,
39 44
           label: '综合得分',
40 45
           iconPath: zongheIcon,
41 46
           cornerRadius: 20,
@@ -58,7 +63,7 @@ const invokerCountDeptTeamStats = (params) => {
58 63
           bgGradientEnd: 'rgba(15,70,250,0.2)'
59 64
         },
60 65
         {
61
-          value: '10',
66
+          value: result.employeeCount,
62 67
           label: '人员数量',
63 68
           iconPath: renyuanIcon,
64 69
           cornerRadius: 20,
@@ -80,7 +85,7 @@ const invokerCountDeptTeamStats = (params) => {
80 85
           bgGradientEnd: 'rgba(15,70,250,0.2)'
81 86
         },
82 87
         {
83
-          value: '周游波小组',
88
+          value: result.deptName,
84 89
           label: '',
85 90
           iconPath: zu02Icon,
86 91
           iconStyle: {
@@ -115,7 +120,7 @@ const invokerCountDeptTeamStats = (params) => {
115 120
           bgGradientEnd: 'rgba(15,70,250,0.2)'
116 121
         },
117 122
         {
118
-          value: '28',
123
+          value: result.avgAge,
119 124
           label: '平均年龄',
120 125
           iconPath: nianlingIcon,
121 126
           cornerRadius: 20,
@@ -138,7 +143,7 @@ const invokerCountDeptTeamStats = (params) => {
138 143
           bgGradientEnd: 'rgba(15,70,250,0.2)'
139 144
         },
140 145
         {
141
-          value: '3.5',
146
+          value: result.avgWorkYears,
142 147
           label: '平均司龄',
143 148
           iconPath: silingIcon,
144 149
           cornerRadius: 20,
@@ -167,9 +172,7 @@ const invokerCountDeptTeamStats = (params) => {
167 172
 
168 173
 
169 174
 
170
-const pentagonItems = ref([
171 175
 
172
-])
173 176
 
174 177
 const handleSearch = (params) => {
175 178
   queryParams.value = params
@@ -185,7 +188,7 @@ onMounted(() => {
185 188
 
186 189
   const defParams = Object.assign({ deptId: '' }, searchBar.value.getDefQuery())
187 190
   queryParams.value = defParams
188
- 
191
+
189 192
 })
190 193
 
191 194
 </script>

+ 1 - 1
src/views/portraitManagement/groupProfile/component/runData.vue

@@ -245,7 +245,7 @@ const fetchData = () => {
245 245
   invokerCountSeizeSubjectCategoryQuantity(params)
246 246
   invokerCountSeizureTotalQuantity(params)
247 247
   invokerCountSeizureSingleQuantity(params)
248
-  invokerCountSeizureAreaQuantity(params)
248
+  // invokerCountSeizureAreaQuantity(params)
249 249
   invokerCountSeizureStatsItem(params)
250 250
   invokerCountSeizureStatsType(params)
251 251
   invokerCountSeizureStatsPost(params)

+ 142 - 134
src/views/portraitManagement/groupProfile/index.vue

@@ -13,12 +13,13 @@
13 13
 </template>
14 14
 
15 15
 <script setup>
16
-import { ref, computed, onMounted } from 'vue'
16
+import { ref, onMounted } from 'vue'
17 17
 import Page from '../components/page.vue'
18 18
 import SearchBar from '../components/SearchBar.vue'
19 19
 import Profile from './component/profile.vue'
20 20
 import RunData from './component/runData.vue'
21 21
 import PentagonGroup from '../components/PentagonGroup.vue'
22
+import { countDeptTeamStats } from '@/api/portraitManagement/portraitManagement'
22 23
 import zongheIcon from '@/assets/icons/portrait/zonghe_icon.png'
23 24
 import renyuanIcon from '@/assets/icons/portrait/renyuan_icon.png'
24 25
 import zu02Icon from '@/assets/icons/portrait/zu02_icon.png'
@@ -29,142 +30,149 @@ const activeTab = ref(0)
29 30
 const searchVisible = ref(false)
30 31
 const queryParams = ref({})
31 32
 
32
-const pentagonItems = computed(() => [
33
-  {
34
-    value: '88',
35
-    label: '综合得分',
36
-    iconPath: zongheIcon,
37
-    cornerRadius: 20,
38
-    vertices: {
39
-      topLeft: { x: 0, y: 0 },
40
-      topRight: { x: 300, y: 0 },
41
-      bottomRight: { x: 260, y: 200 },
42
-      bottomLeft: { x: 0, y: 200 }
43
-    },
44
-    cardContentStyle: {
45
-      gap: '100px'
46
-    },
47
-    edgeGradients: {
48
-      top: { start: '#0f46fa', end: 'transparent' },
49
-      right: { start: 'transparent', end: '#9903C1' },
50
-      bottom: { start: '#9903C1', end: 'transparent' },
51
-      left: { start: 'transparent', end: '#0f46fa' }
52
-    },
53
-    bgGradientStart: 'rgba(33,33,58,0.95)',
54
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
55
-  },
56
-  {
57
-    value: '10',
58
-    label: '人员数量',
59
-    iconPath: renyuanIcon,
60
-    cornerRadius: 20,
61
-    vertices: {
62
-      topLeft: { x: 10, y: 0 },
63
-      topRight: { x: 300, y: 0 },
64
-      bottomRight: { x: 260, y: 200 },
65
-      bottomLeft: { x: -30, y: 200 }
66
-    }, cardContentStyle: {
67
-      gap: '100px'
68
-    },
69
-    edgeGradients: {
70
-      top: { start: '#0f46fa', end: 'transparent' },
71
-      right: { start: 'transparent', end: '#9903C1' },
72
-      bottom: { start: '#9903C1', end: 'transparent' },
73
-      left: { start: 'transparent', end: '#0f46fa' }
74
-    },
75
-    bgGradientStart: 'rgba(33,33,58,0.95)',
76
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
77
-  },
78
-  {
79
-    value: groupName.value,
80
-    label: '陈行小组',
81
-    iconPath: zu02Icon,
82
-    iconStyle: {
83
-      width: '250px',
84
-      height: '250px'
85
-    },
86
-    labelStyle: {
87
-      fontSize: '48px',
88
-      bottom: '26px',
89
-      position: 'relative'
90
-    },
91
-    valueStyle: {
92
-      fontSize: '48px',
93
-      bottom: '26px',
94
-      position: 'relative'
95
-    },
96
-    vertical: true,
97
-    cornerRadius: 20,
98
-    vertices: {
99
-      topLeft: { x: 10, y: 0 },
100
-      topRight: { x: 280, y: 0 },
101
-      bottomRight: { x: 320, y: 200 },
102
-      bottomLeft: { x: -30, y: 200 }
103
-    },
104
-    cardContentStyle: {
105
-      gap: '0px',
106
-      position: 'relative',
107
-      bottom: '65px'
108
-    },
109
-    edgeGradients: {
110
-      top: { start: '#0f46fa', end: 'transparent' },
111
-      right: { start: 'transparent', end: '#9903C1' },
112
-      bottom: { start: '#9903C1', end: 'transparent' },
113
-      left: { start: 'transparent', end: '#0f46fa' }
114
-    },
115
-    bgGradientStart: 'rgba(33,33,58,0.95)',
116
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
117
-  },
118
-  {
119
-    value: '28',
120
-    label: '平均年龄',
121
-    iconPath: nianlingIcon,
122
-    cornerRadius: 20,
123
-    vertices: {
124
-      topLeft: { x: -10, y: 0 },
125
-      topRight: { x: 290, y: 0 },
126
-      bottomRight: { x: 330, y: 200 },
127
-      bottomLeft: { x: 30, y: 200 }
128
-    },
129
-    cardContentStyle: {
130
-      gap: '100px'
131
-    },
132
-    edgeGradients: {
133
-      top: { start: '#0f46fa', end: 'transparent' },
134
-      right: { start: 'transparent', end: '#9903C1' },
135
-      bottom: { start: '#9903C1', end: 'transparent' },
136
-      left: { start: 'transparent', end: '#0f46fa' }
137
-    },
138
-    bgGradientStart: 'rgba(33,33,58,0.95)',
139
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
140
-  },
141
-  {
142
-    value: '3.5',
143
-    label: '平均司龄',
144
-    iconPath: silingIcon,
145
-    cornerRadius: 20,
146
-    vertices: {
147
-      topLeft: { x: 0, y: 0 },
148
-      topRight: { x: 300, y: 0 },
149
-      bottomRight: { x: 300, y: 200 },
150
-      bottomLeft: { x: 40, y: 200 }
151
-    },
152
-    cardContentStyle: {
153
-      gap: '100px'
154
-    },
155
-    edgeGradients: {
156
-      top: { start: '#0f46fa', end: 'transparent' },
157
-      right: { start: 'transparent', end: '#9903C1' },
158
-      bottom: { start: '#9903C1', end: 'transparent' },
159
-      left: { start: 'transparent', end: '#0f46fa' }
160
-    },
161
-    bgGradientStart: 'rgba(33,33,58,0.95)',
162
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
33
+const pentagonItems = ref([])
34
+const invokerCountDeptTeamStats = (params) => {
35
+  const copyParams = {
36
+    deptId: params.groupId
163 37
   }
164
-])
165
-const groupName = ref('')
38
+  countDeptTeamStats(copyParams).then(res => {
39
+    if (res.code === 200 && res.data) {
40
+      const result = res.data
41
+      pentagonItems.value = [
42
+        {
43
+          value: result.totalScore,
44
+          label: '综合得分',
45
+          iconPath: zongheIcon,
46
+          cornerRadius: 20,
47
+          vertices: {
48
+            topLeft: { x: 0, y: 0 },
49
+            topRight: { x: 300, y: 0 },
50
+            bottomRight: { x: 260, y: 200 },
51
+            bottomLeft: { x: 0, y: 200 }
52
+          },
53
+          cardContentStyle: {
54
+            gap: '100px'
55
+          },
56
+          edgeGradients: {
57
+            top: { start: '#0f46fa', end: 'transparent' },
58
+            right: { start: 'transparent', end: '#9903C1' },
59
+            bottom: { start: '#9903C1', end: 'transparent' },
60
+            left: { start: 'transparent', end: '#0f46fa' }
61
+          },
62
+          bgGradientStart: 'rgba(33,33,58,0.95)',
63
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
64
+        },
65
+        {
66
+          value: result.employeeCount,
67
+          label: '人员数量',
68
+          iconPath: renyuanIcon,
69
+          cornerRadius: 20,
70
+          vertices: {
71
+            topLeft: { x: 10, y: 0 },
72
+            topRight: { x: 300, y: 0 },
73
+            bottomRight: { x: 260, y: 200 },
74
+            bottomLeft: { x: -30, y: 200 }
75
+          }, cardContentStyle: {
76
+            gap: '100px'
77
+          },
78
+          edgeGradients: {
79
+            top: { start: '#0f46fa', end: 'transparent' },
80
+            right: { start: 'transparent', end: '#9903C1' },
81
+            bottom: { start: '#9903C1', end: 'transparent' },
82
+            left: { start: 'transparent', end: '#0f46fa' }
83
+          },
84
+          bgGradientStart: 'rgba(33,33,58,0.95)',
85
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
86
+        },
87
+        {
88
+          value: result.deptName,
89
+          label: '',
90
+          iconPath: zu02Icon,
91
+          iconStyle: {
92
+            width: '250px',
93
+            height: '250px'
94
+          },
95
+          valueStyle: {
96
+            fontSize: '48px',
97
+            bottom: '26px',
98
+            position: 'relative'
99
+          },
100
+          vertical: true,
101
+          cornerRadius: 20,
102
+          vertices: {
103
+            topLeft: { x: 10, y: 0 },
104
+            topRight: { x: 280, y: 0 },
105
+            bottomRight: { x: 320, y: 200 },
106
+            bottomLeft: { x: -30, y: 200 }
107
+          },
108
+          cardContentStyle: {
109
+            gap: '0px',
110
+            position: 'relative',
111
+            bottom: '65px'
112
+          },
113
+          edgeGradients: {
114
+            top: { start: '#0f46fa', end: 'transparent' },
115
+            right: { start: 'transparent', end: '#9903C1' },
116
+            bottom: { start: '#9903C1', end: 'transparent' },
117
+            left: { start: 'transparent', end: '#0f46fa' }
118
+          },
119
+          bgGradientStart: 'rgba(33,33,58,0.95)',
120
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
121
+        },
122
+        {
123
+          value: result.avgAge,
124
+          label: '平均年龄',
125
+          iconPath: nianlingIcon,
126
+          cornerRadius: 20,
127
+          vertices: {
128
+            topLeft: { x: -10, y: 0 },
129
+            topRight: { x: 290, y: 0 },
130
+            bottomRight: { x: 330, y: 200 },
131
+            bottomLeft: { x: 30, y: 200 }
132
+          },
133
+          cardContentStyle: {
134
+            gap: '100px'
135
+          },
136
+          edgeGradients: {
137
+            top: { start: '#0f46fa', end: 'transparent' },
138
+            right: { start: 'transparent', end: '#9903C1' },
139
+            bottom: { start: '#9903C1', end: 'transparent' },
140
+            left: { start: 'transparent', end: '#0f46fa' }
141
+          },
142
+          bgGradientStart: 'rgba(33,33,58,0.95)',
143
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
144
+        },
145
+        {
146
+          value: result.avgWorkYears,
147
+          label: '平均司龄',
148
+          iconPath: silingIcon,
149
+          cornerRadius: 20,
150
+          vertices: {
151
+            topLeft: { x: 0, y: 0 },
152
+            topRight: { x: 300, y: 0 },
153
+            bottomRight: { x: 300, y: 200 },
154
+            bottomLeft: { x: 40, y: 200 }
155
+          },
156
+          cardContentStyle: {
157
+            gap: '100px'
158
+          },
159
+          edgeGradients: {
160
+            top: { start: '#0f46fa', end: 'transparent' },
161
+            right: { start: 'transparent', end: '#9903C1' },
162
+            bottom: { start: '#9903C1', end: 'transparent' },
163
+            left: { start: 'transparent', end: '#0f46fa' }
164
+          },
165
+          bgGradientStart: 'rgba(33,33,58,0.95)',
166
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
167
+        }
168
+      ]
169
+    }
170
+  })
171
+}
172
+
166 173
 const handleSearch = (params) => {
167 174
   queryParams.value = params
175
+  invokerCountDeptTeamStats(params)
168 176
 }
169 177
 
170 178
 const handleTabChange = (index) => {

+ 2 - 1
src/views/portraitManagement/teamProfile/component/runData.vue

@@ -243,7 +243,8 @@ const fetchData = () => {
243 243
   invokerCountSeizeSubjectCategoryQuantity(params)
244 244
   invokerCountSeizureTotalQuantity(params)
245 245
   invokerCountSeizureSingleQuantity(params)
246
-  invokerCountSeizureAreaQuantity(params)
246
+  invokerCountSeizeAreaQuantity(params)
247
+  // invokerCountSeizureAreaQuantity(params)
247 248
   invokerCountSeizureStatsItem(params)
248 249
   invokerCountSeizureStatsType(params)
249 250
   invokerCountSeizureStatsPost(params)

+ 141 - 128
src/views/portraitManagement/teamProfile/index.vue

@@ -11,12 +11,13 @@
11 11
 </template>
12 12
 
13 13
 <script setup>
14
-import { ref } from 'vue'
14
+import { ref, onMounted } from 'vue'
15 15
 import Page from '../components/page.vue'
16 16
 import SearchBar from '../components/SearchBar.vue'
17 17
 import Profile from './component/profile.vue'
18 18
 import RunData from './component/runData.vue'
19 19
 import PentagonGroup from '../components/PentagonGroup.vue'
20
+import { countDeptTeamStats } from '@/api/portraitManagement/portraitManagement'
20 21
 import zongheIcon from '@/assets/icons/portrait/zonghe_icon.png'
21 22
 import renyuanIcon from '@/assets/icons/portrait/renyuan_icon.png'
22 23
 import zu02Icon from '@/assets/icons/portrait/zu02_icon.png'
@@ -27,137 +28,149 @@ const activeTab = ref(0)
27 28
 const searchVisible = ref(false)
28 29
 const queryParams = ref({})
29 30
 
30
-const pentagonItems = ref([
31
-  {
32
-    value: '88',
33
-    label: '综合得分',
34
-    iconPath: zongheIcon,
35
-    cornerRadius: 20,
36
-    vertices: {
37
-      topLeft: { x: 0, y: 0 },
38
-      topRight: { x: 300, y: 0 },
39
-      bottomRight: { x: 260, y: 200 },
40
-      bottomLeft: { x: 0, y: 200 }
41
-    },
42
-    cardContentStyle: {
43
-      gap: '100px'
44
-    },
45
-    edgeGradients: {
46
-      top: { start: '#0f46fa', end: 'transparent' },
47
-      right: { start: 'transparent', end: '#9903C1' },
48
-      bottom: { start: '#9903C1', end: 'transparent' },
49
-      left: { start: 'transparent', end: '#0f46fa' }
50
-    },
51
-    bgGradientStart: 'rgba(33,33,58,0.95)',
52
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
53
-  },
54
-  {
55
-    value: '10',
56
-    label: '人员数量',
57
-    iconPath: renyuanIcon,
58
-    cornerRadius: 20,
59
-    vertices: {
60
-      topLeft: { x: 10, y: 0 },
61
-      topRight: { x: 300, y: 0 },
62
-      bottomRight: { x: 260, y: 200 },
63
-      bottomLeft: { x: -30, y: 200 }
64
-    }, cardContentStyle: {
65
-      gap: '100px'
66
-    },
67
-    edgeGradients: {
68
-      top: { start: '#0f46fa', end: 'transparent' },
69
-      right: { start: 'transparent', end: '#9903C1' },
70
-      bottom: { start: '#9903C1', end: 'transparent' },
71
-      left: { start: 'transparent', end: '#0f46fa' }
72
-    },
73
-    bgGradientStart: 'rgba(33,33,58,0.95)',
74
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
75
-  },
76
-  {
77
-    value: '周游波小组',
78
-    label: '',
79
-    iconPath: zu02Icon,
80
-    iconStyle: {
81
-      width: '250px',
82
-      height: '250px'
83
-    },
84
-    valueStyle: {
85
-      fontSize: '48px',
86
-      bottom: '26px',
87
-      position: 'relative'
88
-    },
89
-    vertical: true,
90
-    cornerRadius: 20,
91
-    vertices: {
92
-      topLeft: { x: 10, y: 0 },
93
-      topRight: { x: 280, y: 0 },
94
-      bottomRight: { x: 320, y: 200 },
95
-      bottomLeft: { x: -30, y: 200 }
96
-    },
97
-    cardContentStyle: {
98
-      gap: '0px',
99
-      position: 'relative',
100
-      bottom: '65px'
101
-    },
102
-    edgeGradients: {
103
-      top: { start: '#0f46fa', end: 'transparent' },
104
-      right: { start: 'transparent', end: '#9903C1' },
105
-      bottom: { start: '#9903C1', end: 'transparent' },
106
-      left: { start: 'transparent', end: '#0f46fa' }
107
-    },
108
-    bgGradientStart: 'rgba(33,33,58,0.95)',
109
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
110
-  },
111
-  {
112
-    value: '28',
113
-    label: '平均年龄',
114
-    iconPath: nianlingIcon,
115
-    cornerRadius: 20,
116
-    vertices: {
117
-      topLeft: { x: -10, y: 0 },
118
-      topRight: { x: 290, y: 0 },
119
-      bottomRight: { x: 330, y: 200 },
120
-      bottomLeft: { x: 30, y: 200 }
121
-    },
122
-    cardContentStyle: {
123
-      gap: '100px'
124
-    },
125
-    edgeGradients: {
126
-      top: { start: '#0f46fa', end: 'transparent' },
127
-      right: { start: 'transparent', end: '#9903C1' },
128
-      bottom: { start: '#9903C1', end: 'transparent' },
129
-      left: { start: 'transparent', end: '#0f46fa' }
130
-    },
131
-    bgGradientStart: 'rgba(33,33,58,0.95)',
132
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
133
-  },
134
-  {
135
-    value: '3.5',
136
-    label: '平均司龄',
137
-    iconPath: silingIcon,
138
-    cornerRadius: 20,
139
-    vertices: {
140
-      topLeft: { x: 0, y: 0 },
141
-      topRight: { x: 300, y: 0 },
142
-      bottomRight: { x: 300, y: 200 },
143
-      bottomLeft: { x: 40, y: 200 }
144
-    },
145
-    cardContentStyle: {
146
-      gap: '100px'
147
-    },
148
-    edgeGradients: {
149
-      top: { start: '#0f46fa', end: 'transparent' },
150
-      right: { start: 'transparent', end: '#9903C1' },
151
-      bottom: { start: '#9903C1', end: 'transparent' },
152
-      left: { start: 'transparent', end: '#0f46fa' }
153
-    },
154
-    bgGradientStart: 'rgba(33,33,58,0.95)',
155
-    bgGradientEnd: 'rgba(15,70,250,0.2)'
31
+const pentagonItems = ref([])
32
+const invokerCountDeptTeamStats = (params) => {
33
+  const copyParams = {
34
+    deptId: params.teamId
156 35
   }
157
-])
36
+  countDeptTeamStats(copyParams).then(res => {
37
+    if (res.code === 200 && res.data) {
38
+      const result = res.data
39
+      pentagonItems.value = [
40
+        {
41
+          value: result.totalScore,
42
+          label: '综合得分',
43
+          iconPath: zongheIcon,
44
+          cornerRadius: 20,
45
+          vertices: {
46
+            topLeft: { x: 0, y: 0 },
47
+            topRight: { x: 300, y: 0 },
48
+            bottomRight: { x: 260, y: 200 },
49
+            bottomLeft: { x: 0, y: 200 }
50
+          },
51
+          cardContentStyle: {
52
+            gap: '100px'
53
+          },
54
+          edgeGradients: {
55
+            top: { start: '#0f46fa', end: 'transparent' },
56
+            right: { start: 'transparent', end: '#9903C1' },
57
+            bottom: { start: '#9903C1', end: 'transparent' },
58
+            left: { start: 'transparent', end: '#0f46fa' }
59
+          },
60
+          bgGradientStart: 'rgba(33,33,58,0.95)',
61
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
62
+        },
63
+        {
64
+          value: result.employeeCount,
65
+          label: '人员数量',
66
+          iconPath: renyuanIcon,
67
+          cornerRadius: 20,
68
+          vertices: {
69
+            topLeft: { x: 10, y: 0 },
70
+            topRight: { x: 300, y: 0 },
71
+            bottomRight: { x: 260, y: 200 },
72
+            bottomLeft: { x: -30, y: 200 }
73
+          }, cardContentStyle: {
74
+            gap: '100px'
75
+          },
76
+          edgeGradients: {
77
+            top: { start: '#0f46fa', end: 'transparent' },
78
+            right: { start: 'transparent', end: '#9903C1' },
79
+            bottom: { start: '#9903C1', end: 'transparent' },
80
+            left: { start: 'transparent', end: '#0f46fa' }
81
+          },
82
+          bgGradientStart: 'rgba(33,33,58,0.95)',
83
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
84
+        },
85
+        {
86
+          value: result.deptName,
87
+          label: '',
88
+          iconPath: zu02Icon,
89
+          iconStyle: {
90
+            width: '250px',
91
+            height: '250px'
92
+          },
93
+          valueStyle: {
94
+            fontSize: '48px',
95
+            bottom: '26px',
96
+            position: 'relative'
97
+          },
98
+          vertical: true,
99
+          cornerRadius: 20,
100
+          vertices: {
101
+            topLeft: { x: 10, y: 0 },
102
+            topRight: { x: 280, y: 0 },
103
+            bottomRight: { x: 320, y: 200 },
104
+            bottomLeft: { x: -30, y: 200 }
105
+          },
106
+          cardContentStyle: {
107
+            gap: '0px',
108
+            position: 'relative',
109
+            bottom: '65px'
110
+          },
111
+          edgeGradients: {
112
+            top: { start: '#0f46fa', end: 'transparent' },
113
+            right: { start: 'transparent', end: '#9903C1' },
114
+            bottom: { start: '#9903C1', end: 'transparent' },
115
+            left: { start: 'transparent', end: '#0f46fa' }
116
+          },
117
+          bgGradientStart: 'rgba(33,33,58,0.95)',
118
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
119
+        },
120
+        {
121
+          value: result.avgAge,
122
+          label: '平均年龄',
123
+          iconPath: nianlingIcon,
124
+          cornerRadius: 20,
125
+          vertices: {
126
+            topLeft: { x: -10, y: 0 },
127
+            topRight: { x: 290, y: 0 },
128
+            bottomRight: { x: 330, y: 200 },
129
+            bottomLeft: { x: 30, y: 200 }
130
+          },
131
+          cardContentStyle: {
132
+            gap: '100px'
133
+          },
134
+          edgeGradients: {
135
+            top: { start: '#0f46fa', end: 'transparent' },
136
+            right: { start: 'transparent', end: '#9903C1' },
137
+            bottom: { start: '#9903C1', end: 'transparent' },
138
+            left: { start: 'transparent', end: '#0f46fa' }
139
+          },
140
+          bgGradientStart: 'rgba(33,33,58,0.95)',
141
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
142
+        },
143
+        {
144
+          value: result.avgWorkYears,
145
+          label: '平均司龄',
146
+          iconPath: silingIcon,
147
+          cornerRadius: 20,
148
+          vertices: {
149
+            topLeft: { x: 0, y: 0 },
150
+            topRight: { x: 300, y: 0 },
151
+            bottomRight: { x: 300, y: 200 },
152
+            bottomLeft: { x: 40, y: 200 }
153
+          },
154
+          cardContentStyle: {
155
+            gap: '100px'
156
+          },
157
+          edgeGradients: {
158
+            top: { start: '#0f46fa', end: 'transparent' },
159
+            right: { start: 'transparent', end: '#9903C1' },
160
+            bottom: { start: '#9903C1', end: 'transparent' },
161
+            left: { start: 'transparent', end: '#0f46fa' }
162
+          },
163
+          bgGradientStart: 'rgba(33,33,58,0.95)',
164
+          bgGradientEnd: 'rgba(15,70,250,0.2)'
165
+        }
166
+      ]
167
+    }
168
+  })
169
+}
158 170
 
159 171
 const handleSearch = (params) => {
160 172
   queryParams.value = params
173
+  invokerCountDeptTeamStats(params)
161 174
 }
162 175
 
163 176
 const handleTabChange = (index) => {

+ 2 - 0
src/views/score/event/index.vue

@@ -310,8 +310,10 @@ async function handleLevelChange() {
310 310
 async function handleFormLevelChange() {
311 311
   form.dimensionId = null
312 312
   form.level2Id = null; form.level2Name = ''; form.level3Id = null; form.level3Name = ''; form.level4Id = null; form.level4Name = ''
313
+  form.deptId = null; form.teamId = null; form.groupId = null; form.personId = null
313 314
   indicatorTree.value = []
314 315
   level2Options.value = []; level3Options.value = []; level4Options.value = []
316
+  teamOptions.value = []; groupOptions.value = []; personOptions.value = []
315 317
   const r = await getDimensionAll({ pageNum: 1, pageSize: 100, org: form.org })
316 318
   dimensionOptions.value = r.data || []
317 319
 }