9 İşlemeler 67f2cc3e71 ... 1f5d33b1b1

Yazar SHA1 Mesaj Tarih
  simonlll 1f5d33b1b1 feat: 员工画像页面样式按设计稿全面调整 1 ay önce
  simonlll be194775d4 feat: 卡片样式按设计稿实现 1 ay önce
  simonlll 1a90cd3dbb feat: 员工姓名按设计稿字体属性实现 1 ay önce
  simonlll 8ae31ad425 feat: 右侧边栏底色按原型图实现 1 ay önce
  simonlll 66928eb3a0 feat: 员工画像底色按原型图实现 1 ay önce
  simonlll e103832100 feat: 员工画像页面按原型图重新布局 1 ay önce
  simonlll a91844314a fix: 雷达大屏跳转画像改用动态路由查找 1 ay önce
  simonlll e813f40365 feat: 雷达大屏成员卡片点击跳转员工画像 1 ay önce
  simonlll 7ecf4aa06e feat: 员工画像页面接入真实数据 1 ay önce

+ 8 - 0
src/api/score/index.js

@@ -87,6 +87,14 @@ export function syncLedgerByType(type) {
87
   return request({ url: `/ledger/sync/${type}`, method: 'post' })
87
   return request({ url: `/ledger/sync/${type}`, method: 'post' })
88
 }
88
 }
89
 
89
 
90
+// ===== 员工画像 =====
91
+export function searchPortraitUsers(keyword) {
92
+  return request({ url: '/score/portrait/searchUsers', method: 'get', params: { keyword } })
93
+}
94
+export function getEmployeePortrait(params) {
95
+  return request({ url: '/score/portrait/employee', method: 'get', params })
96
+}
97
+
90
 // ===== 推送配置 =====
98
 // ===== 推送配置 =====
91
 export function listPushConfig(params) {
99
 export function listPushConfig(params) {
92
   return request({ url: '/score/pushConfig/list', method: 'get', params })
100
   return request({ url: '/score/pushConfig/list', method: 'get', params })

+ 9 - 1
src/assets/styles/index.scss

@@ -5,13 +5,21 @@
5
 @use './btn.scss';
5
 @use './btn.scss';
6
 @use './ruoyi.scss';
6
 @use './ruoyi.scss';
7
 
7
 
8
+@font-face {
9
+  font-family: 'AlibabaPuHuiTi';
10
+  src: url('/fonts/AlibabaPuHuiTi-Regular.ttf') format('truetype');
11
+  font-weight: 100 900;
12
+  font-style: normal;
13
+  font-display: swap;
14
+}
15
+
8
 body {
16
 body {
9
   height: 100%;
17
   height: 100%;
10
   margin: 0;
18
   margin: 0;
11
   -moz-osx-font-smoothing: grayscale;
19
   -moz-osx-font-smoothing: grayscale;
12
   -webkit-font-smoothing: antialiased;
20
   -webkit-font-smoothing: antialiased;
13
   text-rendering: optimizeLegibility;
21
   text-rendering: optimizeLegibility;
14
-  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
22
+  font-family: 'AlibabaPuHuiTi', Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
15
 }
23
 }
16
 
24
 
17
 label {
25
 label {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 877 - 388
src/views/portraitManagement/employeeProfile/index.vue


+ 24 - 2
src/views/score/radar/index.vue

@@ -64,8 +64,9 @@
64
         <!-- 成员卡片 -->
64
         <!-- 成员卡片 -->
65
         <div
65
         <div
66
           v-for="member in memberList" :key="member.personName"
66
           v-for="member in memberList" :key="member.personName"
67
-          class="member-card"
68
-          :class="getMemberBorderClass(member.totalScore)">
67
+          class="member-card clickable-card"
68
+          :class="getMemberBorderClass(member.totalScore)"
69
+          @click="goToPortrait(member.personName)">
69
           <div class="card-name" :class="getNameClass(member.totalScore)">
70
           <div class="card-name" :class="getNameClass(member.totalScore)">
70
             {{ member.personName }}({{ member.totalScore }}分)
71
             {{ member.personName }}({{ member.totalScore }}分)
71
           </div>
72
           </div>
@@ -81,10 +82,22 @@
81
 import { ref, reactive, onMounted, onBeforeUnmount, nextTick, computed, watch } from 'vue'
82
 import { ref, reactive, onMounted, onBeforeUnmount, nextTick, computed, watch } from 'vue'
82
 import { ElMessage } from 'element-plus'
83
 import { ElMessage } from 'element-plus'
83
 import * as echarts from 'echarts'
84
 import * as echarts from 'echarts'
85
+import { useRouter } from 'vue-router'
84
 import { radarTeamList, radarMemberScores, syncLedgerAll } from '@/api/score/index'
86
 import { radarTeamList, radarMemberScores, syncLedgerAll } from '@/api/score/index'
85
 
87
 
86
 defineOptions({ name: 'ScoreRadar' })
88
 defineOptions({ name: 'ScoreRadar' })
87
 
89
 
90
+const router = useRouter()
91
+
92
+function goToPortrait(personName) {
93
+  const target = router.getRoutes().find(r => /[/]employeeProfile$/.test(r.path))
94
+  if (target) {
95
+    router.push({ path: target.path, query: { personName } })
96
+  } else {
97
+    ElMessage.warning('未找到员工画像页面,请确认菜单中已配置该页面')
98
+  }
99
+}
100
+
88
 // ── 状态 ──────────────────────────────────────────────
101
 // ── 状态 ──────────────────────────────────────────────
89
 const loading = ref(false)
102
 const loading = ref(false)
90
 const syncing = ref(false)
103
 const syncing = ref(false)
@@ -430,4 +443,13 @@ watch(compareNames, () => nextTick(renderCompareChart), { deep: true })
430
 .compare-table .col-person { min-width: 48px; }
443
 .compare-table .col-person { min-width: 48px; }
431
 .score-green { color: #67C23A; font-weight: bold; }
444
 .score-green { color: #67C23A; font-weight: bold; }
432
 .score-red   { color: #F56C6C; font-weight: bold; }
445
 .score-red   { color: #F56C6C; font-weight: bold; }
446
+
447
+.clickable-card {
448
+  cursor: pointer;
449
+  transition: box-shadow 0.2s, transform 0.2s;
450
+}
451
+.clickable-card:hover {
452
+  box-shadow: 0 0 12px rgba(26, 106, 255, 0.6);
453
+  transform: translateY(-2px);
454
+}
433
 </style>
455
 </style>