Selaa lähdekoodia

feat: 个人画像

lixiangrui 1 kuukausi sitten
vanhempi
commit
d9ec2796d4

+ 142 - 108
src/views/portraitManagement/employeeProfile/index.vue

@@ -1,7 +1,7 @@
1
 <template>
1
 <template>
2
   <div class="ep-root">
2
   <div class="ep-root">
3
     <!-- 顶部工具栏 -->
3
     <!-- 顶部工具栏 -->
4
-    <div class="ep-topbar">
4
+    <div class="ep-topbar" @click="visible = false">
5
       <div class="time-btns">
5
       <div class="time-btns">
6
         <el-button size="small" :type="currentTime==='week'?'primary':'default'" @click="selectTime('week')">近一周</el-button>
6
         <el-button size="small" :type="currentTime==='week'?'primary':'default'" @click="selectTime('week')">近一周</el-button>
7
         <el-button size="small" :type="currentTime==='month'?'primary':'default'" @click="selectTime('month')">近一月</el-button>
7
         <el-button size="small" :type="currentTime==='month'?'primary':'default'" @click="selectTime('month')">近一月</el-button>
@@ -20,31 +20,55 @@
20
           @change="loadPortrait"
20
           @change="loadPortrait"
21
         />
21
         />
22
       </div>
22
       </div>
23
-      <el-autocomplete
24
-        v-model="personName"
25
-        :fetch-suggestions="queryUsers"
26
-        placeholder="搜索员工/团队画像"
27
-        size="small"
28
-        style="width:220px"
29
-        @select="handlePersonSelect"
30
-        @clear="portrait=null"
31
-        clearable
23
+      <el-popover
24
+        title=""
25
+        :visible="visible"
26
+        placement="bottom-end"
27
+        trigger="click"
28
+        width="60vw"
32
       >
29
       >
33
-        <template #suffix><el-icon><Search /></el-icon></template>
34
-        <template #default="{ item }">
35
-          <span>{{ item.nickName }}</span>
36
-          <span v-if="item.deptName" style="font-size:12px;color:#999;margin-left:8px">{{ item.deptName }}</span>
30
+        <template #reference>
31
+          <el-button type="primary" @click.stop="visible = !visible">组织架构/模糊搜索</el-button>
37
         </template>
32
         </template>
38
-      </el-autocomplete>
33
+        <div style="width:100%; padding: 15px;">
34
+          <div>
35
+            <el-autocomplete
36
+              v-model="personName"
37
+              :fetch-suggestions="queryUsers"
38
+              placeholder="搜索员工/团队画像"
39
+              style="width:320px"
40
+              @clear="portrait=null"
41
+              clearable
42
+            >
43
+              <template #suffix><el-icon><Search /></el-icon></template>
44
+              <template #default="{ item }">
45
+                <span>{{ item.nickName }}</span>
46
+                <span v-if="item.deptName" style="font-size:12px;color:#999;margin-left:8px">{{ item.deptName }}</span>
47
+              </template>
48
+            </el-autocomplete>
49
+            <el-button type="primary" style="margin-left: 30px;" @click="handlePersonSelect({nickName: personName})">模糊搜索</el-button>
50
+          </div>
51
+          <div style="margin-top: 20px;">
52
+            <el-tree
53
+              :data="departments"
54
+              :props="{ value: 'id', showPrefix: false }"
55
+              accordion
56
+              @node-click="handleNodeClick"
57
+            />
58
+          </div>
59
+
60
+        </div>
61
+      </el-popover>
62
+      
39
     </div>
63
     </div>
40
 
64
 
41
     <!-- 空状态 -->
65
     <!-- 空状态 -->
42
-    <div v-if="!portrait" class="ep-empty">
66
+    <div v-if="!portrait" class="ep-empty"  @click="visible = false">
43
       <el-empty description="请在右上角搜索员工姓名以查看画像" />
67
       <el-empty description="请在右上角搜索员工姓名以查看画像" />
44
     </div>
68
     </div>
45
 
69
 
46
     <!-- 主内容 -->
70
     <!-- 主内容 -->
47
-    <div v-else v-loading="loading" class="ep-body" ref="content">
71
+    <div v-else v-loading="loading" class="ep-body" ref="content"  @click="visible = false">
48
       <!-- 左侧主区 -->
72
       <!-- 左侧主区 -->
49
       <div class="ep-left">
73
       <div class="ep-left">
50
 
74
 
@@ -82,7 +106,7 @@
82
               <div class="basic-detail-row">
106
               <div class="basic-detail-row">
83
                 <div class="basic-detail-col">
107
                 <div class="basic-detail-col">
84
                   <div class="basic-label">学历:</div>
108
                   <div class="basic-label">学历:</div>
85
-                  <div class="basic-value">{{ portrait.schooling || '-' }}</div>
109
+                  <div class="basic-value">{{ getSchooling(portrait.schooling) }}</div>
86
                 </div>
110
                 </div>
87
                 <div class="basic-detail-col">
111
                 <div class="basic-detail-col">
88
                   <div class="basic-label">专业:</div>
112
                   <div class="basic-label">专业:</div>
@@ -92,8 +116,13 @@
92
               <div class="basic-detail-row">
116
               <div class="basic-detail-row">
93
                 <div class="basic-detail-col">
117
                 <div class="basic-detail-col">
94
                   <div class="basic-label">标签:</div>
118
                   <div class="basic-label">标签:</div>
95
-                  <el-tag size="small" type="primary" style="margin-right:6px" v-if="portrait.roleNames">{{ portrait.roleNames }}</el-tag>
96
-                  <el-tag size="small" type="warning" v-if="portrait.postNames">{{ portrait.postNames }}</el-tag>
119
+                  <div style="display: flex; flex-wrap: wrap; gap: 8px;">
120
+                    <el-tag size="small" type="primary" style="margin-right:6px" v-if="portrait.roleNames">{{ portrait.roleNames }}</el-tag>
121
+                    <template v-if="portrait.postNames">
122
+                      <el-tag size="small" v-for="value in portrait.postNames.split('、')" :key="value" type="warning" >{{ value }}</el-tag>
123
+                    </template>
124
+                  </div>
125
+                  
97
                 </div>
126
                 </div>
98
               </div>
127
               </div>
99
               <!-- 
128
               <!-- 
@@ -108,7 +137,7 @@
108
           <!-- 综合评价 -->
137
           <!-- 综合评价 -->
109
           <div class="card score-card">
138
           <div class="card score-card">
110
             <div class="score-label">综合评价</div>
139
             <div class="score-label">综合评价</div>
111
-            <div class="score-num">{{ portrait.totalScore }}</div>
140
+            <div class="score-num">{{ portrait.totalScore }}+2</div>
112
             <!-- <div class="score-level-tag">{{ scoreLevel }}</div> -->
141
             <!-- <div class="score-level-tag">{{ scoreLevel }}</div> -->
113
           </div>
142
           </div>
114
         </div>
143
         </div>
@@ -132,7 +161,7 @@
132
             <div class="sec-title">获奖记录</div>
161
             <div class="sec-title">获奖记录</div>
133
             <div class="award-table-wrap">
162
             <div class="award-table-wrap">
134
               <div class="award-table" v-if="portrait.awards && portrait.awards.length">
163
               <div class="award-table" v-if="portrait.awards && portrait.awards.length">
135
-                <div class="award-table-row level1" v-for="(aw, i) in portrait.awards" :key="i">
164
+                <div :class="getLevel(aw)" v-for="(aw, i) in portrait.awards" :key="i">
136
                     <div class="award-table-col">{{ aw.level3Name || '-' }}</div>
165
                     <div class="award-table-col">{{ aw.level3Name || '-' }}</div>
137
                     <div class="award-table-col">{{ aw.level2Name || '-' }}</div>
166
                     <div class="award-table-col">{{ aw.level2Name || '-' }}</div>
138
                     <div class="award-table-col">{{ aw.level4Name || '-' }}</div>
167
                     <div class="award-table-col">{{ aw.level4Name || '-' }}</div>
@@ -167,31 +196,6 @@
167
 
196
 
168
               <!-- 雷达图 -->
197
               <!-- 雷达图 -->
169
               <div ref="abilityChart" class="chart-box">
198
               <div ref="abilityChart" class="chart-box">
170
-                <!-- <div style="position: absolute;" v-if="activeDimName">
171
-                  <div style="padding: 12px; font-size: 14px; line-height: 1.6;">
172
-                    <div style="font-weight: bold; margin-bottom: 8px; font-size: 16px;">
173
-                      {{ activeDimName }}
174
-                    </div>
175
-                    <div style="margin-bottom: 10px;">
176
-                      <div style="color: #f56c6c; font-weight: bold;">扣分详情 (PENALTIES)</div>
177
-                      <ul style="margin: 6px 0; padding-left: 20px; color: #666;">
178
-                        <li>不安全事件(一类): -10.0分</li>
179
-                        <li>不安全事件(二类): -8.0分</li>
180
-                        <li>三/四/五类事件: -5/-3/-2分</li>
181
-                      </ul>
182
-                      <div style="text-align: right; color: #f56c6c; font-weight: bold;">合计扣分: 30.3分</div>
183
-                    </div>
184
-                    <div>
185
-                      <div style="color: #67c23a; font-weight: bold;">加分详情 (BONUSES)</div>
186
-                      <ul style="margin: 6px 0; padding-left: 20px; color: #666;">
187
-                        <li>一类查获/隐患上报: +1.0分</li>
188
-                        <li>建议采纳/二类查获: +1.0/+0.5分</li>
189
-                        <li>特殊物品查获: +0.15分</li>
190
-                      </ul>
191
-                      <div style="text-align: right; color: #67c23a; font-weight: bold;">合计加分: 4.3分</div>
192
-                    </div>
193
-                  </div>
194
-                </div> -->
195
               </div>
199
               </div>
196
               
200
               
197
               <!-- 加分明细浮窗(点击维度后显示,绝对定位右侧) -->
201
               <!-- 加分明细浮窗(点击维度后显示,绝对定位右侧) -->
@@ -238,15 +242,15 @@
238
               </div>
242
               </div>
239
               <div class="supp-item">
243
               <div class="supp-item">
240
                 <span class="s-lbl">籍贯</span>
244
                 <span class="s-lbl">籍贯</span>
241
-                <span class="s-val">{{ portrait.sexText || '-' }}</span>
245
+                <span class="s-val">{{ portrait.nativePlace || '-' }}</span>
242
               </div>
246
               </div>
243
               <div class="supp-item">
247
               <div class="supp-item">
244
                 <span class="s-lbl">民族</span>
248
                 <span class="s-lbl">民族</span>
245
-                <span class="s-val">{{ portrait.sexText || '-' }}</span>
249
+                <span class="s-val">{{ portrait.nation || '-' }}</span>
246
               </div>
250
               </div>
247
               <div class="supp-item">
251
               <div class="supp-item">
248
                 <span class="s-lbl">年龄</span>
252
                 <span class="s-lbl">年龄</span>
249
-                <span class="s-val">{{ portrait.sexText || '-' }}</span>
253
+                <span class="s-val">{{ getAge(portrait.birthday) }}</span>
250
               </div>
254
               </div>
251
               <div class="supp-item">
255
               <div class="supp-item">
252
                 <span class="s-lbl">司龄</span>
256
                 <span class="s-lbl">司龄</span>
@@ -308,15 +312,15 @@
308
               </div>
312
               </div>
309
               <div class="supp-item">
313
               <div class="supp-item">
310
                 <span class="s-lbl">监察问题记录</span>
314
                 <span class="s-lbl">监察问题记录</span>
311
-                <span class="s-val">{{ portrait.qualityControlCount ?? '-' }}</span>
315
+                <span class="s-val">{{ portrait.d ?? '-' }}</span>
312
               </div>
316
               </div>
313
               <div class="supp-item">
317
               <div class="supp-item">
314
                 <span class="s-lbl">三级质控巡查记录</span>
318
                 <span class="s-lbl">三级质控巡查记录</span>
315
-                <span class="s-val">{{ portrait.qualityControlCount ?? '-' }}</span>
319
+                <span class="s-val">{{ portrait.e ?? '-' }}</span>
316
               </div>
320
               </div>
317
               <div class="supp-item">
321
               <div class="supp-item">
318
                 <span class="s-lbl">实时质控拦截记录</span>
322
                 <span class="s-lbl">实时质控拦截记录</span>
319
-                <span class="s-val">{{ portrait.qualityControlCount ?? '-' }}</span>
323
+                <span class="s-val">{{ portrait.q ?? '-' }}</span>
320
               </div>
324
               </div>
321
             </div>
325
             </div>
322
           </div>
326
           </div>
@@ -373,6 +377,8 @@ import * as echarts from 'echarts'
373
 import { Search } from '@element-plus/icons-vue'
377
 import { Search } from '@element-plus/icons-vue'
374
 import { useRoute } from 'vue-router'
378
 import { useRoute } from 'vue-router'
375
 import { searchPortraitUsers, getEmployeePortrait } from '@/api/score/index'
379
 import { searchPortraitUsers, getEmployeePortrait } from '@/api/score/index'
380
+import { getDeptUserTree } from '@/api/item/items'
381
+import { useDict } from '@/utils/dict'
376
 
382
 
377
 defineOptions({ name: 'EmployeeProfile' })
383
 defineOptions({ name: 'EmployeeProfile' })
378
 
384
 
@@ -384,6 +390,34 @@ const portrait = ref(null)
384
 const loading = ref(false)
390
 const loading = ref(false)
385
 const abilityChart = ref(null)
391
 const abilityChart = ref(null)
386
 let chart = null
392
 let chart = null
393
+const { sys_user_schooling } = useDict('sys_user_schooling')
394
+
395
+function getSchooling (schooling) {
396
+  const result = (sys_user_schooling.value || []).find(item => item.value === schooling) || { label: schooling }
397
+  return result.label || '-'
398
+}
399
+
400
+function getAge (birthday) {
401
+  const birthDate = new Date(birthday);
402
+  if (isNaN(birthDate.getTime())) {
403
+    return '-'
404
+  }
405
+  const today = new Date();
406
+  // 计算年份差
407
+  let age = today.getFullYear() - birthDate.getFullYear();
408
+  // 计算月份差
409
+  const monthDiff = today.getMonth() - birthDate.getMonth();
410
+  // 如果还没到今年生日,年龄减1
411
+  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
412
+    age--;
413
+  }
414
+  return `${age}岁`;
415
+}
416
+function getLevel (level) {
417
+  if (level.level3Name === '部门层级') return ['award-table-row', 'level2'] 
418
+  if (level.level3Name === '班组层级') return ['award-table-row', 'level3'] 
419
+  return ['award-table-row', 'level1'] 
420
+}
387
 
421
 
388
 const formatDate = (d) => {
422
 const formatDate = (d) => {
389
   const dt = new Date(d)
423
   const dt = new Date(d)
@@ -421,6 +455,14 @@ const queryUsers = async (query, cb) => {
421
 const handlePersonSelect = (item) => {
455
 const handlePersonSelect = (item) => {
422
   personName.value = item.nickName
456
   personName.value = item.nickName
423
   loadPortrait()
457
   loadPortrait()
458
+  visible.value = false
459
+}
460
+const visible = ref(false)
461
+const handleNodeClick = (node) => {
462
+  if (node.nodeType === 'user') {
463
+    handlePersonSelect({ nickName: node.label })
464
+  }
465
+  
424
 }
466
 }
425
 
467
 
426
 const loadPortrait = async () => {
468
 const loadPortrait = async () => {
@@ -494,10 +536,7 @@ const examScoreStyle = (score) => {
494
 }
536
 }
495
 
537
 
496
 const radarColor = computed(() => {
538
 const radarColor = computed(() => {
497
-  const total = Number(portrait.value?.totalScore ?? 0)
498
-  if (total < 75)  return { line: '#28ABE2', fill: '#5BBCE7', label: '#000' }
499
-  if (total >= 90) return { line: '#28ABE2', fill: '#5BBCE7',  label: '#000' }
500
-  return             { line: '#28ABE2',  fill: '#5BBCE7',    label: '#000' }
539
+  return { line: '#EEBE7C',  fill: 'rgba(246, 238, 202, 0.8)', label: '#000' }
501
 })
540
 })
502
 
541
 
503
 const tipRef = ref(null)
542
 const tipRef = ref(null)
@@ -506,7 +545,6 @@ const initChart = () => {
506
   if (chart) { chart.dispose(); chart = null }
545
   if (chart) { chart.dispose(); chart = null }
507
   chart = echarts.init(abilityChart.value)
546
   chart = echarts.init(abilityChart.value)
508
   const dims = portrait.value.dimensions || []
547
   const dims = portrait.value.dimensions || []
509
-  console.log(dims);
510
   
548
   
511
   const c = radarColor.value
549
   const c = radarColor.value
512
 
550
 
@@ -515,9 +553,9 @@ const initChart = () => {
515
       indicator: dims.map(d => ({ name: d.name + '\n\n' + d.score, max: 100 })),
553
       indicator: dims.map(d => ({ name: d.name + '\n\n' + d.score, max: 100 })),
516
       center: ['50%', '52%'],
554
       center: ['50%', '52%'],
517
       radius: '65%',
555
       radius: '65%',
518
-      splitNumber: 4,
519
-      axisLine: { lineStyle: { color: '#8EC742' } },
520
-      splitLine: { lineStyle: { color: '#8EC742' } },
556
+      splitNumber: 7,
557
+      axisLine: { lineStyle: { color: '#ccc' } },
558
+      splitLine: { lineStyle: { color: ['#fe4322', '#fe4322', '#fe4322', '#fe4322', '#fe4322', '#fe4322', '#28ABE2', '#8EC742'], width: 3  } },
521
       splitArea: { show: false },
559
       splitArea: { show: false },
522
       axisName: {
560
       axisName: {
523
         color: '#000',
561
         color: '#000',
@@ -530,7 +568,7 @@ const initChart = () => {
530
         value: dims.map(d => Number(d.score)),
568
         value: dims.map(d => Number(d.score)),
531
         name: '个人能力',
569
         name: '个人能力',
532
         areaStyle: { color: c.fill },
570
         areaStyle: { color: c.fill },
533
-        lineStyle: { color: c.line, width: 3 },
571
+        lineStyle: { color: c.line, width: 2 },
534
         itemStyle: { color: c.line }
572
         itemStyle: { color: c.line }
535
       }],
573
       }],
536
       symbol: 'circle',
574
       symbol: 'circle',
@@ -573,9 +611,7 @@ const initChart = () => {
573
 
611
 
574
     // 显示 tooltip
612
     // 显示 tooltip
575
     tip.style.display = 'block'
613
     tip.style.display = 'block'
576
-    
577
-    // tip.style.left = rect.x + e.offsetX + 30 + 'px'
578
-    // tip.style.top = rect.y + e.offsetY + 'px'
614
+
579
     tip.style.left = pisition.x + 30 + 'px'
615
     tip.style.left = pisition.x + 30 + 'px'
580
     tip.style.top = pisition.y + 'px'
616
     tip.style.top = pisition.y + 'px'
581
     activeDimName.value = dims[idx].name
617
     activeDimName.value = dims[idx].name
@@ -621,7 +657,10 @@ let pisition = {
621
   x: 0,
657
   x: 0,
622
   y: 0
658
   y: 0
623
 }
659
 }
624
-onMounted(() => {
660
+const departments = ref([])
661
+onMounted(async () => {
662
+  const res = await getDeptUserTree()
663
+  departments.value = res.data
625
   window.addEventListener('resize', handleResize)
664
   window.addEventListener('resize', handleResize)
626
   const n = route.query.personName
665
   const n = route.query.personName
627
   if (n) { personName.value = n; loadPortrait() }
666
   if (n) { personName.value = n; loadPortrait() }
@@ -654,7 +693,7 @@ onBeforeUnmount(() => {
654
 .ep-topbar {
693
 .ep-topbar {
655
   display: flex;
694
   display: flex;
656
   align-items: center;
695
   align-items: center;
657
-  justify-content: space-between;
696
+  justify-content: flex-start;
658
   background: rgba(255, 255, 255, 1);
697
   background: rgba(255, 255, 255, 1);
659
   // border-radius: 20px;
698
   // border-radius: 20px;
660
   padding: 10px 16px;
699
   padding: 10px 16px;
@@ -669,6 +708,7 @@ onBeforeUnmount(() => {
669
     align-items: center;
708
     align-items: center;
670
     gap: 6px;
709
     gap: 6px;
671
     flex-wrap: wrap;
710
     flex-wrap: wrap;
711
+    margin-right: 40px;
672
   }
712
   }
673
 }
713
 }
674
 
714
 
@@ -704,7 +744,7 @@ onBeforeUnmount(() => {
704
   display: flex;
744
   display: flex;
705
   flex-direction: column;
745
   flex-direction: column;
706
   gap: 20px;
746
   gap: 20px;
707
-  font-size: 20px;
747
+  font-size: 18px;
708
   color: rgba(16, 16, 16, 1);
748
   color: rgba(16, 16, 16, 1);
709
   line-height: 28px;
749
   line-height: 28px;
710
 }
750
 }
@@ -715,7 +755,7 @@ onBeforeUnmount(() => {
715
   border-radius: 20px;
755
   border-radius: 20px;
716
   box-sizing: border-box;
756
   box-sizing: border-box;
717
     .sec-title {
757
     .sec-title {
718
-    font-size: 48px;
758
+    font-size: 32px;
719
     font-weight: bold;
759
     font-weight: bold;
720
     line-height: 68px;
760
     line-height: 68px;
721
     color: rgba(31, 135, 232, 1);
761
     color: rgba(31, 135, 232, 1);
@@ -728,8 +768,8 @@ onBeforeUnmount(() => {
728
     &::before {
768
     &::before {
729
       content: '';
769
       content: '';
730
       display: block;
770
       display: block;
731
-      width: 20px;
732
-      height: 20px;
771
+      width: 12px;
772
+      height: 12px;
733
       border-radius: 50%;
773
       border-radius: 50%;
734
       transform: translateX(15px);
774
       transform: translateX(15px);
735
       background: rgba(31, 135, 232, 1);
775
       background: rgba(31, 135, 232, 1);
@@ -792,7 +832,7 @@ onBeforeUnmount(() => {
792
     .basic-detail-row {
832
     .basic-detail-row {
793
       display: flex;
833
       display: flex;
794
       color: rgba(16,16,16,1);
834
       color: rgba(16,16,16,1);
795
-      font-size: 20px;
835
+      font-size: 18px;
796
       text-align: left;
836
       text-align: left;
797
       font-weight: bold;
837
       font-weight: bold;
798
       width: 100%;
838
       width: 100%;
@@ -800,8 +840,8 @@ onBeforeUnmount(() => {
800
         flex: 1;
840
         flex: 1;
801
         display: flex;
841
         display: flex;
802
         align-items: center;
842
         align-items: center;
803
-        line-height: 28px;
804
         .basic-label {
843
         .basic-label {
844
+          white-space: nowrap;
805
         }
845
         }
806
         .basic-value {
846
         .basic-value {
807
           flex: 1;
847
           flex: 1;
@@ -839,7 +879,7 @@ onBeforeUnmount(() => {
839
   flex-direction: column;
879
   flex-direction: column;
840
   align-items: center;
880
   align-items: center;
841
   background: var(--cardBgColor);
881
   background: var(--cardBgColor);
842
-  font-size: 20px;
882
+  font-size: 18px;
843
   text-align: center;
883
   text-align: center;
844
 
884
 
845
   .score-label {
885
   .score-label {
@@ -871,7 +911,7 @@ onBeforeUnmount(() => {
871
 
911
 
872
   .score-level-tag {
912
   .score-level-tag {
873
     margin-top: 12px;
913
     margin-top: 12px;
874
-    font-size: 20px;
914
+    font-size: 18px;
875
     font-weight: 600;
915
     font-weight: 600;
876
     color: rgba(16, 16, 16, 1);
916
     color: rgba(16, 16, 16, 1);
877
     background: #f5f5f5;
917
     background: #f5f5f5;
@@ -884,14 +924,14 @@ onBeforeUnmount(() => {
884
 
924
 
885
 /* ── 工作履历 + 获奖 ── */
925
 /* ── 工作履历 + 获奖 ── */
886
 .left-mid-card {
926
 .left-mid-card {
887
-  width: 604px;
927
+  width: 560px;
888
   flex-shrink: 0;
928
   flex-shrink: 0;
889
   background: var(--cardBgColor);
929
   background: var(--cardBgColor);
890
   color: rgba(16, 16, 16, 1);
930
   color: rgba(16, 16, 16, 1);
891
-  font-size: 20px;
931
+  font-size: 18px;
892
   line-height: 28px;
932
   line-height: 28px;
893
   box-sizing: border-box;
933
   box-sizing: border-box;
894
-  padding: 30px 10px;
934
+  padding: 0 10px 10px;
895
   text-align: center;
935
   text-align: center;
896
   height: 100%;
936
   height: 100%;
897
   overflow: hidden;
937
   overflow: hidden;
@@ -906,7 +946,7 @@ onBeforeUnmount(() => {
906
     padding: 20px;
946
     padding: 20px;
907
 
947
 
908
     .history-item {
948
     .history-item {
909
-      font-size: 20px;
949
+      font-size: 18px;
910
       font-weight: bold;
950
       font-weight: bold;
911
       color: #101010;
951
       color: #101010;
912
       line-height: 28px;
952
       line-height: 28px;
@@ -929,6 +969,10 @@ onBeforeUnmount(() => {
929
       .award-table-row {
969
       .award-table-row {
930
         display: flex;
970
         display: flex;
931
         height: 48px;
971
         height: 48px;
972
+        border-bottom: 1px dashed #fff;
973
+        &:last-child {
974
+          border: none;
975
+        }
932
         .award-table-col {
976
         .award-table-col {
933
           flex: 1;
977
           flex: 1;
934
           text-align: center;
978
           text-align: center;
@@ -948,27 +992,6 @@ onBeforeUnmount(() => {
948
   }
992
   }
949
 }
993
 }
950
 
994
 
951
-.award-section {
952
-  margin-top: 16px;
953
-  background-color: rgba(169, 209, 250, 1);
954
-  border-radius: 20px;
955
-  padding: 12px;
956
-  font-size: 20px;
957
-  font-family: 'AlibabaPuHuiTi', 'PingFang SC', 'Microsoft YaHei', sans-serif;
958
-  font-weight: bold;
959
-
960
-  .sec-title {
961
-    font-size: 48px;
962
-    font-weight: bold;
963
-    line-height: 68px;
964
-    color: rgba(31, 135, 232, 1);
965
-    text-align: left;
966
-    font-family: 'YSBiaoTiHei-bold', 'AlibabaPuHuiTi', 'PingFang SC', 'Microsoft YaHei', sans-serif;
967
-    margin-bottom: 10px;
968
-  }
969
-}
970
-
971
-
972
 /* ── 雷达图卡 ── */
995
 /* ── 雷达图卡 ── */
973
 .radar-card {
996
 .radar-card {
974
   flex: 1;
997
   flex: 1;
@@ -977,7 +1000,7 @@ onBeforeUnmount(() => {
977
   flex-direction: column;
1000
   flex-direction: column;
978
   background: rgb(242, 249, 253);
1001
   background: rgb(242, 249, 253);
979
   color: rgba(16, 16, 16, 1);
1002
   color: rgba(16, 16, 16, 1);
980
-  font-size: 20px;
1003
+  font-size: 18px;
981
   line-height: 28px;
1004
   line-height: 28px;
982
   text-align: center;
1005
   text-align: center;
983
 
1006
 
@@ -1006,13 +1029,24 @@ onBeforeUnmount(() => {
1006
   flex-direction: column;
1029
   flex-direction: column;
1007
   .side-title {
1030
   .side-title {
1008
     font-size: 32px;
1031
     font-size: 32px;
1009
-    font-weight: 900;
1032
+    font-weight: bold;
1010
     line-height: 50px;
1033
     line-height: 50px;
1011
     color: rgba(31, 135, 232, 1);
1034
     color: rgba(31, 135, 232, 1);
1012
     text-indent: 20px;
1035
     text-indent: 20px;
1013
     text-align: left;
1036
     text-align: left;
1014
     font-style: italic;
1037
     font-style: italic;
1015
-    font-family: 'YSBiaoTiHei-bold', 'AlibabaPuHuiTi', 'PingFang SC', 'Microsoft YaHei', sans-serif;
1038
+    text-indent: 25px;
1039
+    display: flex;
1040
+    align-items: center;
1041
+    &::before {
1042
+      content: '';
1043
+      display: block;
1044
+      width: 12px;
1045
+      height: 12px;
1046
+      border-radius: 50%;
1047
+      transform: translateX(15px);
1048
+      background: rgba(31, 135, 232, 1);
1049
+    }
1016
   }
1050
   }
1017
 }
1051
 }
1018
 .pos-section {
1052
 .pos-section {
@@ -1026,14 +1060,14 @@ onBeforeUnmount(() => {
1026
   flex-direction: column;
1060
   flex-direction: column;
1027
   border-radius: 30px;
1061
   border-radius: 30px;
1028
   padding: 5px 20px;
1062
   padding: 5px 20px;
1029
-  font-size: 20px;
1063
+  font-size: 18px;
1030
   font-family: 'AlibabaPuHuiTi', 'PingFang SC', 'Microsoft YaHei', sans-serif;
1064
   font-family: 'AlibabaPuHuiTi', 'PingFang SC', 'Microsoft YaHei', sans-serif;
1031
   
1065
   
1032
   .supp-item {
1066
   .supp-item {
1033
     display: flex;
1067
     display: flex;
1034
     justify-content: space-between;
1068
     justify-content: space-between;
1035
     align-items: center;
1069
     align-items: center;
1036
-    font-size: 20px;
1070
+    font-size: 18px;
1037
     padding: 4px 0;
1071
     padding: 4px 0;
1038
     line-height: 28px;
1072
     line-height: 28px;
1039
     color: rgba(0,0,0,1);
1073
     color: rgba(0,0,0,1);
@@ -1087,7 +1121,7 @@ onBeforeUnmount(() => {
1087
         display: table-cell;
1121
         display: table-cell;
1088
         min-width: 5em;
1122
         min-width: 5em;
1089
         text-align: center;
1123
         text-align: center;
1090
-        font-size: 20px;
1124
+        font-size: 18px;
1091
       }
1125
       }
1092
     }
1126
     }
1093
   }
1127
   }
@@ -1113,7 +1147,7 @@ onBeforeUnmount(() => {
1113
   pointer-events: none;
1147
   pointer-events: none;
1114
   font-size: 14px;
1148
   font-size: 14px;
1115
   line-height: 1.5;
1149
   line-height: 1.5;
1116
-  transform: translateY(-50%);
1150
+  transform: translateY(-80%);
1117
   display: none;
1151
   display: none;
1118
 
1152
 
1119
   .tooltip-title {
1153
   .tooltip-title {
@@ -1269,5 +1303,5 @@ onBeforeUnmount(() => {
1269
 .add-score    { color: #1a9944; }
1303
 .add-score    { color: #1a9944; }
1270
 .p-empty { color: #bbb; font-size: 11px; text-align: center; padding: 12px 0; }
1304
 .p-empty { color: #bbb; font-size: 11px; text-align: center; padding: 12px 0; }
1271
 /* 通用 */
1305
 /* 通用 */
1272
-.empty-text { color: #bbb; font-size: 20px; text-align: center; padding: 8px 0; }
1306
+.empty-text { color: #bbb; font-size: 18px; text-align: center; padding: 8px 0; }
1273
 </style>
1307
 </style>

+ 15 - 0
src/views/system/user/components/UserInfoEdit.vue

@@ -41,6 +41,11 @@
41
             </el-form-item>
41
             </el-form-item>
42
           </el-col>
42
           </el-col>
43
           <el-col :span="12">
43
           <el-col :span="12">
44
+            <el-form-item label="籍贯" prop="nativePlace">
45
+              <el-input v-model="form.nativePlace" placeholder="请输入籍贯" maxlength="128"  />
46
+            </el-form-item>
47
+          </el-col>
48
+          <el-col :span="12">
44
             <el-form-item label="用户性别" prop="sex">
49
             <el-form-item label="用户性别" prop="sex">
45
               <el-select v-model="form.sex" placeholder="请选择用户性别">
50
               <el-select v-model="form.sex" placeholder="请选择用户性别">
46
                 <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label"
51
                 <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label"
@@ -49,6 +54,11 @@
49
             </el-form-item>
54
             </el-form-item>
50
           </el-col>
55
           </el-col>
51
           <el-col :span="12">
56
           <el-col :span="12">
57
+            <el-form-item label="民族" prop="nation">
58
+              <el-input v-model="form.nation" placeholder="请输入民族" maxlength="128"  />
59
+            </el-form-item>
60
+          </el-col>
61
+          <el-col :span="12">
52
             <el-form-item label="生肖" prop="zodiac">
62
             <el-form-item label="生肖" prop="zodiac">
53
               <el-select v-model="form.zodiac" placeholder="请选择生肖">
63
               <el-select v-model="form.zodiac" placeholder="请选择生肖">
54
                 <el-option v-for="item in sys_user_zodiac" :key="item.value" :label="item.label" :value="item.value" />
64
                 <el-option v-for="item in sys_user_zodiac" :key="item.value" :label="item.label" :value="item.value" />
@@ -146,6 +156,11 @@
146
               </el-select>
156
               </el-select>
147
             </el-form-item>
157
             </el-form-item>
148
           </el-col>
158
           </el-col>
159
+          <el-col :span="12">
160
+            <el-form-item label="专业" prop="professional">
161
+              <el-input v-model="form.professional" placeholder="请输入专业" />
162
+            </el-form-item>
163
+          </el-col>
149
           <el-col :span="24">
164
           <el-col :span="24">
150
             <el-form-item label="行政处罚情况" prop="administrativeStatus">
165
             <el-form-item label="行政处罚情况" prop="administrativeStatus">
151
               <el-input v-model="form.administrativeStatus" type="textarea" placeholder="请输入行政处罚情况"></el-input>
166
               <el-input v-model="form.administrativeStatus" type="textarea" placeholder="请输入行政处罚情况"></el-input>

+ 2 - 2
vite.config.js

@@ -2,8 +2,8 @@ import { defineConfig, loadEnv } from 'vite'
2
 import path from 'path'
2
 import path from 'path'
3
 import createVitePlugins from './vite/plugins'
3
 import createVitePlugins from './vite/plugins'
4
 
4
 
5
-const baseUrl = 'http://localhost:8088' // 后端接口
6
-// const baseUrl = 'http://airport.samsundot.com:9035/prod-api'
5
+// const baseUrl = 'http://localhost:8088' // 后端接口
6
+const baseUrl = 'http://airport.samsundot.com:9035/prod-api'
7
 // https://vitejs.dev/config/
7
 // https://vitejs.dev/config/
8
 export default defineConfig(({ mode, command }) => {
8
 export default defineConfig(({ mode, command }) => {
9
   const env = loadEnv(mode, process.cwd())
9
   const env = loadEnv(mode, process.cwd())