Parcourir la source

feat(portraitManagement): 新增部门人员画像相关功能

1.  新增部门人员相关API接口,包括成员列表、分布数据等接口
2.  改造维度列表加载逻辑,增加org参数筛选
3.  重构搜索栏时间参数格式适配不同场景
4.  完善岗位画像页面,实现动态获取并展示部门人员数据
5.  优化饼图/柱状图组件,增加响应式更新和默认配色
6.  改造班组画像页面,适配新的字段名并接入所有画像数据接口
huoyi il y a 3 semaines
Parent
commit
21231e38c4

+ 20 - 0
src/api/portraitManagement/portraitManagement.js

@@ -23,4 +23,24 @@ export function realtimeInterceptionItem(data) {
23
 // 各岗位监察问题分布
23
 // 各岗位监察问题分布
24
 export function supervisionProblemPosition(data) {
24
 export function supervisionProblemPosition(data) {
25
     return request({ url: '/ledger/supervisionProblem/supervisionProblemPosition', method: 'post', data })
25
     return request({ url: '/ledger/supervisionProblem/supervisionProblemPosition', method: 'post', data })
26
+}
27
+
28
+// 获取部门内所有成员列表
29
+export function getDeptMembers(data) {
30
+    return request({ url: '/score/dept-portrait/members', method: 'post', data })
31
+}
32
+
33
+// 获取部门成员基本情况分布
34
+export function getDeptMemberDistribution(data) {
35
+    return request({ url: '/score/dept-portrait/distribution', method: 'post', data })
36
+}
37
+
38
+// 获取部门成员职位情况分布
39
+export function getDeptPositionDistribution(data) {
40
+    return request({ url: '/score/dept-portrait/position-distribution', method: 'post', data })
41
+}
42
+
43
+// 维度得分一览
44
+export function getDimensionScoreOverview(data) {
45
+    return request({ url: '/score/dept-portrait/group-portrait', method: 'post', data })
26
 }
46
 }

+ 84 - 15
src/views/portraitManagement/components/ProfileBasicDistribution.vue

@@ -18,7 +18,7 @@
18
 </template>
18
 </template>
19
 
19
 
20
 <script setup>
20
 <script setup>
21
-import { ref, onMounted, onUnmounted, nextTick } from 'vue'
21
+import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
22
 import * as echarts from 'echarts'
22
 import * as echarts from 'echarts'
23
 import InfoCard from './card.vue'
23
 import InfoCard from './card.vue'
24
 
24
 
@@ -55,6 +55,7 @@ const defaultPoliticalData = [
55
   { value: 6, name: '其他', itemStyle: { color: '#4d96ff' } }
55
   { value: 6, name: '其他', itemStyle: { color: '#4d96ff' } }
56
 ]
56
 ]
57
 
57
 
58
+
58
 const genderChartRef = ref(null)
59
 const genderChartRef = ref(null)
59
 let genderChart = null
60
 let genderChart = null
60
 const nationChartRef = ref(null)
61
 const nationChartRef = ref(null)
@@ -62,30 +63,98 @@ let nationChart = null
62
 const politicalChartRef = ref(null)
63
 const politicalChartRef = ref(null)
63
 let politicalChart = null
64
 let politicalChart = null
64
 
65
 
65
-const initPieChart = (ref, data) => {
66
-  if (!ref) return
67
-  const chart = echarts.init(ref)
68
-  const option = {
66
+const genderColors = ['#ff6b9d', '#4da6ff']
67
+const nationColors = ['#ff9f43', '#4da6ff', '#a55eea']
68
+const politicalColors = ['#ff6b6b', '#ffd93d', '#6bcb77', '#4d96ff']
69
+
70
+const getGenderColors = (data) => {
71
+  return data.map((item, index) => ({
72
+    ...item,
73
+    itemStyle: { color: item.itemStyle?.color || genderColors[index % genderColors.length] }
74
+  }))
75
+}
76
+
77
+const getNationColors = (data) => {
78
+  return data.map((item, index) => ({
79
+    ...item,
80
+    itemStyle: { color: item.itemStyle?.color || nationColors[index % nationColors.length] }
81
+  }))
82
+}
83
+
84
+const getPoliticalColors = (data) => {
85
+  return data.map((item, index) => ({
86
+    ...item,
87
+    itemStyle: { color: item.itemStyle?.color || politicalColors[index % politicalColors.length] }
88
+  }))
89
+}
90
+
91
+const updateGenderChart = (data) => {
92
+  if (!genderChartRef.value) return
93
+  if (!genderChart) {
94
+    genderChart = echarts.init(genderChartRef.value)
95
+  }
96
+  const chartData = data && data.length > 0 ? getGenderColors(data) : defaultGenderData
97
+  genderChart.setOption({
69
     series: [{
98
     series: [{
70
       type: 'pie',
99
       type: 'pie',
71
       radius: ['50%', '70%'],
100
       radius: ['50%', '70%'],
72
-      data: data,
101
+      data: chartData,
73
       label: { show: true, color: '#fff', fontSize: 11 },
102
       label: { show: true, color: '#fff', fontSize: 11 },
74
       labelLine: { show: true }
103
       labelLine: { show: true }
75
     }]
104
     }]
105
+  })
106
+}
107
+
108
+const updateNationChart = (data) => {
109
+  if (!nationChartRef.value) return
110
+  if (!nationChart) {
111
+    nationChart = echarts.init(nationChartRef.value)
76
   }
112
   }
77
-  chart.setOption(option)
78
-  return chart
113
+  const chartData = data && data.length > 0 ? getNationColors(data) : defaultNationData
114
+  nationChart.setOption({
115
+    series: [{
116
+      type: 'pie',
117
+      radius: ['50%', '70%'],
118
+      data: chartData,
119
+      label: { show: true, color: '#fff', fontSize: 11 },
120
+      labelLine: { show: true }
121
+    }]
122
+  })
79
 }
123
 }
80
 
124
 
81
-const initCharts = () => {
82
-  const genderData = props.chartData1.length > 0 ? props.chartData1 : defaultGenderData
83
-  const nationData = props.chartData2.length > 0 ? props.chartData2 : defaultNationData
84
-  const politicalData = props.chartData3.length > 0 ? props.chartData3 : defaultPoliticalData
125
+const updatePoliticalChart = (data) => {
126
+  if (!politicalChartRef.value) return
127
+  if (!politicalChart) {
128
+    politicalChart = echarts.init(politicalChartRef.value)
129
+  }
130
+  const chartData = data && data.length > 0 ? getPoliticalColors(data) : defaultPoliticalData
131
+  politicalChart.setOption({
132
+    series: [{
133
+      type: 'pie',
134
+      radius: ['50%', '70%'],
135
+      data: chartData,
136
+      label: { show: true, color: '#fff', fontSize: 11 },
137
+      labelLine: { show: true }
138
+    }]
139
+  })
140
+}
85
 
141
 
86
-  genderChart = initPieChart(genderChartRef.value, genderData)
87
-  nationChart = initPieChart(nationChartRef.value, nationData)
88
-  politicalChart = initPieChart(politicalChartRef.value, politicalData)
142
+watch(() => props.chartData1, (val) => {
143
+  updateGenderChart(val)
144
+}, { deep: true })
145
+
146
+watch(() => props.chartData2, (val) => {
147
+  updateNationChart(val)
148
+}, { deep: true })
149
+
150
+watch(() => props.chartData3, (val) => {
151
+  updatePoliticalChart(val)
152
+}, { deep: true })
153
+
154
+const initCharts = () => {
155
+  updateGenderChart(props.chartData1)
156
+  updateNationChart(props.chartData2)
157
+  updatePoliticalChart(props.chartData3)
89
 }
158
 }
90
 
159
 
91
 const handleResize = () => {
160
 const handleResize = () => {

+ 116 - 20
src/views/portraitManagement/components/ProfilePositionDistribution.vue

@@ -18,7 +18,7 @@
18
 </template>
18
 </template>
19
 
19
 
20
 <script setup>
20
 <script setup>
21
-import { ref, onMounted, onUnmounted, nextTick } from 'vue'
21
+import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
22
 import * as echarts from 'echarts'
22
 import * as echarts from 'echarts'
23
 import InfoCard from './card.vue'
23
 import InfoCard from './card.vue'
24
 
24
 
@@ -38,23 +38,27 @@ const props = defineProps({
38
 })
38
 })
39
 
39
 
40
 const defaultSkillData = {
40
 const defaultSkillData = {
41
-  categories: ['等级1', '等级2', '等级3', '等级4', '等级5'],
42
-  values: [3, 5, 7, 8, 4],
41
+  categories: [],
42
+  values: [],
43
   colors: ['#4da6ff', '#0f46fa']
43
   colors: ['#4da6ff', '#0f46fa']
44
 }
44
 }
45
 
45
 
46
 const defaultOperateData = {
46
 const defaultOperateData = {
47
-  categories: ['0-3', '4-7', '8-11', '12-15', '15-18'],
48
-  values: [4, 2, 3, 5, 8],
47
+  categories: [],
48
+  values: [],
49
   colors: ['#6bcb77', '#2ecc71']
49
   colors: ['#6bcb77', '#2ecc71']
50
 }
50
 }
51
 
51
 
52
 const defaultPostData = {
52
 const defaultPostData = {
53
-  categories: ['前传', '人身', '验证', '开包', '开机'],
54
-  values: [4, 5, 6, 7, 8],
53
+  categories: [],
54
+  values: [],
55
   colors: ['#ff6b6b', '#ee5a24']
55
   colors: ['#ff6b6b', '#ee5a24']
56
 }
56
 }
57
 
57
 
58
+const skillColors = ['#4da6ff', '#0f46fa']
59
+const operateColors = ['#6bcb77', '#2ecc71']
60
+const postColors = ['#ff6b6b', '#ee5a24']
61
+
58
 const skillChartRef = ref(null)
62
 const skillChartRef = ref(null)
59
 let skillChart = null
63
 let skillChart = null
60
 const operateChartRef = ref(null)
64
 const operateChartRef = ref(null)
@@ -62,10 +66,29 @@ let operateChart = null
62
 const postChartRef = ref(null)
66
 const postChartRef = ref(null)
63
 let postChart = null
67
 let postChart = null
64
 
68
 
65
-const initBarChart = (ref, chartData) => {
66
-  if (!ref) return
67
-  const chart = echarts.init(ref)
68
-  const option = {
69
+const transformData = (data, defaultData) => {
70
+  if (!data || data.length === 0) {
71
+    return {
72
+      categories: defaultData.categories,
73
+      values: defaultData.values,
74
+      colors: defaultData.colors
75
+    }
76
+  }
77
+  return {
78
+    categories: (data || []).map(item => item.name),
79
+    values: (data || []).map(item => item.value),
80
+    colors: defaultData.colors
81
+  }
82
+}
83
+
84
+const updateSkillChart = (data) => {
85
+  if (!skillChartRef.value) return
86
+  if (!skillChart) {
87
+    skillChart = echarts.init(skillChartRef.value)
88
+  }
89
+  const chartData = transformData(data, defaultSkillData)
90
+ 
91
+  skillChart.setOption({
69
     xAxis: {
92
     xAxis: {
70
       type: 'category',
93
       type: 'category',
71
       data: chartData.categories,
94
       data: chartData.categories,
@@ -89,19 +112,92 @@ const initBarChart = (ref, chartData) => {
89
       },
112
       },
90
       barWidth: '50%'
113
       barWidth: '50%'
91
     }]
114
     }]
115
+  })
116
+}
117
+
118
+const updateOperateChart = (data) => {
119
+  if (!operateChartRef.value) return
120
+  if (!operateChart) {
121
+    operateChart = echarts.init(operateChartRef.value)
92
   }
122
   }
93
-  chart.setOption(option)
94
-  return chart
123
+  const chartData = transformData(data, defaultOperateData)
124
+  
125
+  operateChart.setOption({
126
+    xAxis: {
127
+      type: 'category',
128
+      data: chartData.categories,
129
+      axisLabel: { color: '#a0c4ff', fontSize: 10 },
130
+      axisLine: { lineStyle: { color: 'rgba(15,70,250,0.3)' } }
131
+    },
132
+    yAxis: {
133
+      type: 'value',
134
+      axisLabel: { color: '#a0c4ff', fontSize: 10 },
135
+      axisLine: { lineStyle: { color: 'rgba(15,70,250,0.3)' } },
136
+      splitLine: { lineStyle: { color: 'rgba(15,70,250,0.2)' } }
137
+    },
138
+    series: [{
139
+      type: 'bar',
140
+      data: chartData.values,
141
+      itemStyle: {
142
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
143
+          { offset: 0, color: chartData.colors[0] },
144
+          { offset: 1, color: chartData.colors[1] }
145
+        ])
146
+      },
147
+      barWidth: '50%'
148
+    }]
149
+  })
95
 }
150
 }
96
 
151
 
97
-const initCharts = () => {
98
-  const skillData = props.chartData1.length > 0 ? props.chartData1 : defaultSkillData
99
-  const operateData = props.chartData2.length > 0 ? props.chartData2 : defaultOperateData
100
-  const postData = props.chartData3.length > 0 ? props.chartData3 : defaultPostData
152
+const updatePostChart = (data) => {
153
+  if (!postChartRef.value) return
154
+  if (!postChart) {
155
+    postChart = echarts.init(postChartRef.value)
156
+  }
157
+  const chartData = transformData(data, defaultPostData)
158
+  postChart.setOption({
159
+    xAxis: {
160
+      type: 'category',
161
+      data: chartData.categories,
162
+      axisLabel: { color: '#a0c4ff', fontSize: 10 },
163
+      axisLine: { lineStyle: { color: 'rgba(15,70,250,0.3)' } }
164
+    },
165
+    yAxis: {
166
+      type: 'value',
167
+      axisLabel: { color: '#a0c4ff', fontSize: 10 },
168
+      axisLine: { lineStyle: { color: 'rgba(15,70,250,0.3)' } },
169
+      splitLine: { lineStyle: { color: 'rgba(15,70,250,0.2)' } }
170
+    },
171
+    series: [{
172
+      type: 'bar',
173
+      data: chartData.values,
174
+      itemStyle: {
175
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
176
+          { offset: 0, color: chartData.colors[0] },
177
+          { offset: 1, color: chartData.colors[1] }
178
+        ])
179
+      },
180
+      barWidth: '50%'
181
+    }]
182
+  })
183
+}
101
 
184
 
102
-  skillChart = initBarChart(skillChartRef.value, skillData)
103
-  operateChart = initBarChart(operateChartRef.value, operateData)
104
-  postChart = initBarChart(postChartRef.value, postData)
185
+watch(() => props.chartData1, (val) => {
186
+  updateSkillChart(val)
187
+}, { deep: true })
188
+
189
+watch(() => props.chartData2, (val) => {
190
+  updateOperateChart(val)
191
+}, { deep: true })
192
+
193
+watch(() => props.chartData3, (val) => {
194
+  updatePostChart(val)
195
+}, { deep: true })
196
+
197
+const initCharts = () => {
198
+  updateSkillChart(props.chartData1)
199
+  updateOperateChart(props.chartData2)
200
+  updatePostChart(props.chartData3)
105
 }
201
 }
106
 
202
 
107
 const handleResize = () => {
203
 const handleResize = () => {

+ 15 - 5
src/views/portraitManagement/components/SearchBar.vue

@@ -97,7 +97,12 @@ const filterDeptTree = (data, targetType) => {
97
 const getTimeRange = () => {
97
 const getTimeRange = () => {
98
   if (currentTime.value === 'custom') {
98
   if (currentTime.value === 'custom') {
99
     if (dateRange.value?.length === 2) {
99
     if (dateRange.value?.length === 2) {
100
-      return { beginTime: formatDate(dateRange.value[0]), endTime: formatDate(dateRange.value[1]) }
100
+      if(props.deptType === 'user'){
101
+        return { beginTime: formatDate(dateRange.value[0]), endTime: formatDate(dateRange.value[1]) }
102
+      }else{
103
+        return { startDate: formatDate(dateRange.value[0]), endDate: formatDate(dateRange.value[1]) }
104
+      }
105
+     
101
     }
106
     }
102
     return {}
107
     return {}
103
   }
108
   }
@@ -106,7 +111,11 @@ const getTimeRange = () => {
106
   else if (currentTime.value === 'month') begin.setMonth(end.getMonth() - 1)
111
   else if (currentTime.value === 'month') begin.setMonth(end.getMonth() - 1)
107
   else if (currentTime.value === 'quarter') begin.setMonth(end.getMonth() - 3)
112
   else if (currentTime.value === 'quarter') begin.setMonth(end.getMonth() - 3)
108
   else begin.setFullYear(end.getFullYear() - 1)
113
   else begin.setFullYear(end.getFullYear() - 1)
109
-  return { beginTime: formatDate(begin), endTime: formatDate(end) }
114
+  if(props.deptType === 'user'){
115
+    return { beginTime: formatDate(begin), endTime: formatDate(end) }
116
+  }else{
117
+    return { startDate: formatDate(begin), endDate: formatDate(end) }
118
+  }
110
 }
119
 }
111
 
120
 
112
 const formatDate = (d) => {
121
 const formatDate = (d) => {
@@ -140,14 +149,15 @@ const handleNodeClick = (node) => {
140
     if (node.deptType === props.deptType) {
149
     if (node.deptType === props.deptType) {
141
       personName.value = node.deptName || node.name || node.label;
150
       personName.value = node.deptName || node.name || node.label;
142
       let obj = {}
151
       let obj = {}
143
-      if (props.deptType === 'BRIGADE') {
152
+      
153
+      if (props.deptType === 'BRIGADE'||props.deptType === 'STATION') {
144
         obj = { deptId: node.deptId || node.id }
154
         obj = { deptId: node.deptId || node.id }
145
       }
155
       }
146
       if (props.deptType === 'MANAGER') {
156
       if (props.deptType === 'MANAGER') {
147
-        obj = { teamId: node.deptId || node.id }
157
+        obj = { teamId: node.deptId || node.id,deptId: node.deptId || node.id }
148
       }
158
       }
149
       if (props.deptType === 'TEAMS') {
159
       if (props.deptType === 'TEAMS') {
150
-        obj = { groupId: node.deptId || node.id }
160
+        obj = { groupId: node.deptId || node.id,deptId: node.deptIdId || node.id }
151
       }
161
       }
152
       searchHandler(obj)
162
       searchHandler(obj)
153
     }
163
     }

+ 81 - 30
src/views/portraitManagement/groupProfile/component/profile.vue

@@ -36,6 +36,7 @@ import ProfileRadar from '../../components/ProfileRadar.vue'
36
 import ProfileMembers from '../../components/ProfileMembers.vue'
36
 import ProfileMembers from '../../components/ProfileMembers.vue'
37
 import ProfileBasicDistribution from '../../components/ProfileBasicDistribution.vue'
37
 import ProfileBasicDistribution from '../../components/ProfileBasicDistribution.vue'
38
 import ProfilePositionDistribution from '../../components/ProfilePositionDistribution.vue'
38
 import ProfilePositionDistribution from '../../components/ProfilePositionDistribution.vue'
39
+import { getDeptMembers, getDeptMemberDistribution, getDeptPositionDistribution, getDimensionScoreOverview } from '@/api/portraitManagement/portraitManagement'
39
 
40
 
40
 const props = defineProps({
41
 const props = defineProps({
41
   queryParams: {
42
   queryParams: {
@@ -76,63 +77,113 @@ const teamMembers = ref([
76
 ])
77
 ])
77
 
78
 
78
 const memberColumns = ref([
79
 const memberColumns = ref([
79
-  { label: '姓名', prop: 'name' },
80
+  { label: '姓名', prop: 'personName' },
80
   { label: '年龄', prop: 'age' },
81
   { label: '年龄', prop: 'age' },
81
-  { label: '司龄', prop: 'seniority' },
82
-  { label: '性别', prop: 'gender' },
82
+  { label: '司龄', prop: 'workYears' },
83
+  { label: '性别', prop: 'sex' },
83
   { label: '民族', prop: 'nation' },
84
   { label: '民族', prop: 'nation' },
84
-  { label: '政治面貌', prop: 'political' },
85
-  { label: '职务', prop: 'position' },
85
+  { label: '政治面貌', prop: 'politicalStatus' },
86
+  { label: '职务', prop: 'roleNames' },
86
   { label: '岗位资质', prop: 'qualification' },
87
   { label: '岗位资质', prop: 'qualification' },
87
-  { label: '职业技能等级', prop: 'skillLevel' },
88
-  { label: '开机年限', prop: 'operateYears' },
88
+  { label: '职业技能等级', prop: 'qualificationLevel' },
89
+  { label: '开机年限', prop: 'xrayOperatorYears' },
89
   { label: '平均年限', prop: 'avgYears' },
90
   { label: '平均年限', prop: 'avgYears' },
90
   { label: '综合得分', prop: 'totalScore' }
91
   { label: '综合得分', prop: 'totalScore' }
91
 ])
92
 ])
92
 
93
 
93
 const genderData = ref([
94
 const genderData = ref([
94
-  { value: 6, name: '女', itemStyle: { color: '#ff6b9d' } },
95
-  { value: 8, name: '男', itemStyle: { color: '#4da6ff' } }
95
+  
96
 ])
96
 ])
97
 
97
 
98
 const nationData = ref([
98
 const nationData = ref([
99
-  { value: 1, name: '回族', itemStyle: { color: '#ff9f43' } },
100
-  { value: 8, name: '汉族', itemStyle: { color: '#4da6ff' } },
101
-  { value: 5, name: '其他', itemStyle: { color: '#a55eea' } }
99
+ 
102
 ])
100
 ])
103
 
101
 
104
 const politicalData = ref([
102
 const politicalData = ref([
105
-  { value: 1, name: '党员', itemStyle: { color: '#ff6b6b' } },
106
-  { value: 2, name: '共青团员', itemStyle: { color: '#ffd93d' } },
107
-  { value: 5, name: '群众', itemStyle: { color: '#6bcb77' } },
108
-  { value: 6, name: '其他', itemStyle: { color: '#4d96ff' } }
103
+  
109
 ])
104
 ])
110
 
105
 
111
-const skillData = ref({
112
-  categories: ['等级1', '等级2', '等级3', '等级4', '等级5'],
113
-  values: [3, 5, 7, 8, 4],
114
-  colors: ['#4da6ff', '#0f46fa']
115
-})
106
+const skillData = ref([])
116
 
107
 
117
-const operateData = ref({
118
-  categories: ['0-3', '4-7', '8-11', '12-15', '15-18'],
119
-  values: [4, 2, 3, 5, 8],
120
-  colors: ['#6bcb77', '#2ecc71']
121
-})
108
+const operateData = ref([])
122
 
109
 
123
 const postData = ref({
110
 const postData = ref({
124
   categories: ['前传', '人身', '验证', '开包', '开机'],
111
   categories: ['前传', '人身', '验证', '开包', '开机'],
125
   values: [4, 5, 6, 7, 8],
112
   values: [4, 5, 6, 7, 8],
126
   colors: ['#ff6b6b', '#ee5a24']
113
   colors: ['#ff6b6b', '#ee5a24']
127
 })
114
 })
115
+const fetchTeamMembers = async (params) => {
116
+  try {
117
+    const res = await getDeptMembers(params)
118
+    if (res.code === 200 && res.data) {
119
+      teamMembers.value = res.data
120
+    }
121
+  } catch (error) {
122
+    console.error('获取部门成员列表失败', error)
123
+  }
124
+}
128
 
125
 
129
-watch(() => props.queryParams, (newParams) => {
130
-  fetchData(newParams)
131
-}, { deep: true })
126
+const fetchMemberDistribution = async (params) => {
127
+  try {
128
+    const res = await getDeptMemberDistribution(params)
129
+    if (res.code === 200 && res.data) {
130
+      
131
+      genderData.value = res.data.sexDistribution.map(item => ({ value: item.count, name: item.name })) || []
132
+      nationData.value = res.data.nationDistribution.map(item => ({ value: item.count, name: item.name })) || []
133
+      politicalData.value = res.data.politicalDistribution.map(item => ({ value: item.count, name: item.name })) || []
134
+      console.log('genderData', genderData.value)
135
+      console.log('nationData', nationData.value)
136
+      console.log('politicalData', politicalData.value)
137
+    }
138
+  } catch (error) {
139
+    console.error('获取部门成员基本情况分布失败', error)
140
+  }
141
+}
142
+
143
+const fetchPositionDistribution = async (params) => {
144
+  try {
145
+    const res = await getDeptPositionDistribution(params)
146
+    if (res.code === 200 && res.data) {
147
+      skillData.value = res.data.qualificationDistribution.map(item => ({ value: item.count, name: item.name })) || []
148
+      operateData.value = res.data.xrayYearDistribution.map(item => ({ value: item.count, name: item.name })) || []
149
+      postData.value = res.data.positionDistribution.map(item => ({ value: item.count, name: item.name })) || []
150
+    }
151
+  } catch (error) {
152
+    console.error('获取部门成员职位情况分布失败', error)
153
+  }
154
+}
132
 
155
 
156
+const fetchRadarData = async (params) => {
157
+  try {
158
+    const res = await getDimensionScoreOverview(params)
159
+    if (res.code === 200 && res.data) {
160
+      radarData.value = res.data.radarData || []
161
+      radarIndicators.value = res.data.radarIndicators || []
162
+      radarSeries1.value = res.data.radarSeries1 || []
163
+      radarSeries2.value = res.data.radarSeries2 || []
164
+    }
165
+  } catch (error) {
166
+    console.error('获取维度得分一览失败', error)
167
+  }
168
+}
133
 const fetchData = (params) => {
169
 const fetchData = (params) => {
134
-  console.log('查询参数:', params)
170
+  if (!params.deptId && !params.groupId && !params.teamId ) {
171
+    return
172
+  }
173
+  //  console.log('params', params)
174
+  // debugger
175
+  fetchTeamMembers(params)
176
+  fetchMemberDistribution(params)
177
+  fetchPositionDistribution(params)
178
+  fetchRadarData(params)
135
 }
179
 }
180
+watch(() => props.queryParams, (newParams) => {
181
+  fetchData(newParams)
182
+}, { deep: true, immediate: true })
183
+
184
+
185
+
186
+
136
 </script>
187
 </script>
137
 
188
 
138
 <style lang="scss" scoped>
189
 <style lang="scss" scoped>

+ 56 - 24
src/views/portraitManagement/stationProfile/component/profile.vue

@@ -23,10 +23,11 @@
23
 </template>
23
 </template>
24
 
24
 
25
 <script setup>
25
 <script setup>
26
-import { ref } from 'vue'
26
+import { ref, watch } from 'vue'
27
 import ProfileMembers from '../../components/ProfileMembers.vue'
27
 import ProfileMembers from '../../components/ProfileMembers.vue'
28
 import ProfileBasicDistribution from '../../components/ProfileBasicDistribution.vue'
28
 import ProfileBasicDistribution from '../../components/ProfileBasicDistribution.vue'
29
 import ProfilePositionDistribution from '../../components/ProfilePositionDistribution.vue'
29
 import ProfilePositionDistribution from '../../components/ProfilePositionDistribution.vue'
30
+import { getDeptMembers, getDeptMemberDistribution, getDeptPositionDistribution } from '@/api/portraitManagement/portraitManagement'
30
 
31
 
31
 
32
 
32
 
33
 
@@ -48,35 +49,66 @@ const teamColumns = [
48
   { label: '综合得分', prop: 'totalScore' }
49
   { label: '综合得分', prop: 'totalScore' }
49
 ]
50
 ]
50
 
51
 
51
-const teamData = ref([
52
-  { dept: '旅检一部', empCount: '800', partyCount: '7', avgAge: '25', avgWorkYears: '3', certLevel: '16', avgUpgradeAge: '3', totalScore: '90' },
53
-  { dept: '旅检二部', empCount: '756', partyCount: '2', avgAge: '28', avgWorkYears: '8', certLevel: '18', avgUpgradeAge: '5', totalScore: '88' },
54
-  { dept: '旅检三部', empCount: '708', partyCount: '7', avgAge: '25', avgWorkYears: '3', certLevel: '23', avgUpgradeAge: '3', totalScore: '86' }
55
-])
52
+const teamData = ref([])
56
 
53
 
57
-const genderData = [
58
-  { value: 650, name: '女', itemStyle: { color: '#ff9f9f' } },
59
-  { value: 750, name: '男', itemStyle: { color: '#7effc4' } }
60
-]
54
+const genderData = ref([])
55
+const nationData = ref([])
56
+const politicalData = ref([])
61
 
57
 
62
-const nationData = [
63
-  { value: 615, name: '汉族', itemStyle: { color: '#7effc4' } },
64
-  { value: 484, name: '回族', itemStyle: { color: '#4da6ff' } },
65
-  { value: 156, name: '其他', itemStyle: { color: '#ffd93d' } }
66
-]
58
+const skillData = ref([])
59
+const operateData = ref([])
60
+const postData = ref([])
67
 
61
 
68
-const politicalData = [
69
-  { value: 410, name: '群众', itemStyle: { color: '#ffd93d' } },
70
-  { value: 540, name: '共青团员', itemStyle: { color: '#4da6ff' } },
71
-  { value: 270, name: '中共党员', itemStyle: { color: '#ff6b6b' } },
72
-  { value: 138, name: '预备党员', itemStyle: { color: '#7effc4' } }
73
-]
62
+const fetchTeamData = async (params) => {
63
+  try {
64
+    const res = await getDeptMembers(params)
65
+    if (res.code === 200 && res.data) {
66
+      teamData.value = res.data
67
+    }
68
+  } catch (error) {
69
+    console.error('获取部门成员列表失败', error)
70
+  }
71
+}
72
+
73
+const fetchMemberDistribution = async (params) => {
74
+  try {
75
+    const res = await getDeptMemberDistribution(params)
76
+    if (res.code === 200 && res.data) {
77
+      genderData.value = res.data.sexDistribution?.map(item => ({ value: item.count, name: item.name })) || []
78
+      nationData.value = res.data.nationDistribution?.map(item => ({ value: item.count, name: item.name })) || []
79
+      politicalData.value = res.data.politicalDistribution?.map(item => ({ value: item.count, name: item.name })) || []
80
+    }
81
+  } catch (error) {
82
+    console.error('获取部门成员基本情况分布失败', error)
83
+  }
84
+}
74
 
85
 
75
-const skillData = []
86
+const fetchPositionDistribution = async (params) => {
87
+  try {
88
+    const res = await getDeptPositionDistribution(params)
89
+    if (res.code === 200 && res.data) {
90
+      skillData.value = res.data.qualificationDistribution?.map(item => ({ value: item.count, name: item.name })) || []
91
+      operateData.value = res.data.xrayYearDistribution?.map(item => ({ value: item.count, name: item.name })) || []
92
+      postData.value = res.data.positionDistribution?.map(item => ({ value: item.count, name: item.name })) || []
93
+    }
94
+  } catch (error) {
95
+    console.error('获取部门成员职位情况分布失败', error)
96
+  }
97
+}
76
 
98
 
77
-const operateData = []
99
+const fetchData = (params) => {
100
+  if (!params.deptId && !params.groupId && !params.teamId) {
101
+    return
102
+  }
103
+  fetchTeamData(params)
104
+  fetchMemberDistribution(params)
105
+  fetchPositionDistribution(params)
106
+}
78
 
107
 
79
-const postData = []
108
+watch(() => props.queryParams, (newParams) => {
109
+  
110
+  fetchData(newParams)
111
+}, { deep: true, immediate: true })
80
 
112
 
81
 </script>
113
 </script>
82
 
114
 

+ 1 - 1
src/views/score/dimension/index.vue

@@ -226,7 +226,7 @@ const totalWeight = computed(() => {
226
 
226
 
227
 async function loadDimensions() {
227
 async function loadDimensions() {
228
   dimLoading.value = true
228
   dimLoading.value = true
229
-  const r = await getDimensionAll({ pageNum: 1, pageSize: 100 }).finally(() => dimLoading.value = false)
229
+  const r = await getDimensionAll({ pageNum: 1, pageSize: 100, org: scoreLevel.value }).finally(() => dimLoading.value = false)
230
   dimList.value = r.data || []
230
   dimList.value = r.data || []
231
   if (!selectedDim.value && dimList.value.length) selectDimension(dimList.value[0])
231
   if (!selectedDim.value && dimList.value.length) selectDimension(dimList.value[0])
232
 }
232
 }