| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922 |
- <template>
- <Page @click="visible = false" v-loading="loading" element-loading-background="rgba(22, 22, 22, 0.8)">
- <div class="content">
- <div class="content-search">
- <SearchBar v-model:visible="visible" @search="searchHandler" :deptType="'user'" />
- </div>
-
- <div v-show="portrait.personName" class="content-info">
- <Card title="个人基本信息">
- <div class="userInfo">
- <div class="userInfo-name">
- <div class="avatar-area">
- <img v-if="portrait.avatar" :src="portrait.avatar" class="avatar" alt="头像" />
- <div v-else class="avatar">{{ portrait.personName?.charAt(0) }}</div>
- </div>
- <div class="basic-name">
- <div class="basic-label">姓名:</div>
- <div class="basic-value">{{ portrait.personName }}</div>
- </div>
- </div>
- <div class="userInfo-info">
- <div class="info-item">
- <div class="info-item-icon">
- <img src="/src/assets/dataBigScreen/img01.png" alt="" />
- </div>
- <div class="info-item-content">
- <div class="info-item-label">所属部门及队室:</div>
- <div class="info-item-value">{{ portrait.deptPath || '-' }}</div>
- </div>
- </div>
- <div class="info-item">
- <div class="info-item-icon">
- <img src="/src/assets/dataBigScreen/img04.png" alt="" />
- </div>
- <div class="info-item-content">
- <div class="info-item-label">学历:</div>
- <div class="info-item-value">{{ getSchooling(portrait.schooling) }}</div>
- </div>
- </div>
- </div>
- <div class="userInfo-info">
- <div class="info-item">
- <div class="info-item-icon">
- <img src="/src/assets/dataBigScreen/img02.png" alt="" />
- </div>
- <div class="info-item-content">
- <div class="info-item-label">出生日期:</div>
- <div class="info-item-value">{{ portrait.birthday || '-' }}</div>
- </div>
- </div>
- <div class="info-item">
- <div class="info-item-icon">
- <img src="/src/assets/dataBigScreen/img05.png" alt="" />
- </div>
- <div class="info-item-content">
- <div class="info-item-label">专业:</div>
- <div class="info-item-value">{{ portrait.major || '-' }}</div>
- </div>
- </div>
- </div>
- <div class="userInfo-info">
- <div class="info-item">
- <div class="info-item-icon">
- <img src="/src/assets/dataBigScreen/img03.png" alt="" />
- </div>
- <div class="info-item-content">
- <div class="info-item-label">技能等级:</div>
- <div class="info-item-value">
- {{ portrait.qualificationLevelText || '-' }}
- <span class="info-item-tag" style="margin-left: 10px;margin-top: 2px;" v-if="!!portrait.xrayOperatorStarttime">X射线安检仪操作岗位</span>
- </div>
- </div>
- </div>
- <div class="info-item">
- <div class="info-item-icon">
- <img src="/src/assets/dataBigScreen/img06.png" alt="" />
- </div>
- <div class="info-item-content">
- <div class="info-item-label">标签:</div>
- <div class="info-item-value" v-if="portrait.userTags">
- <span class="info-item-tag" v-for="tag in portrait.userTags.split(',')" :key="tag">{{ tag }}</span>
- </div>
- </div>
- </div>
- </div>
- <div class="userInfo-score">
- <div class="score-progress">
- <el-progress type="circle" :width="160" :stroke-width="18" color="#5BE39E" :percentage="(portrait.totalScore || -2) + 2">
- <div class="percentage-content">
- <span class="percentage-value">{{ (portrait.totalScore || 0) }}</span>
- <span class="percentage-text">综合得分</span>
- </div>
- </el-progress>
- </div>
- <div class="score-box">
- <!-- <div class="score-row">
- <span class="score-col">评分:</span>
- <span class="score-col-2">{{ portrait.totalScore || 0 }}</span>
- </div> -->
- <div class="score-row">
- <span class="score-col">附加分:</span>
- <span class="score-col-2">{{ portrait?.userTags?.split(',').length || 0 }}分</span>
- <!-- <span class="score-col-2">{{ tagScoreData != null ? (typeof tagScoreData === 'object' ? (tagScoreData.totalScore ?? tagScoreData.score ?? tagScoreData) : tagScoreData) : 0 }}</span> -->
- </div>
- </div>
- </div>
- </div>
- </Card>
- </div>
- <div v-show="portrait.personName" class="content-bottom">
- <div class="content-bottom-left">
- <Card title="工作履历">
- <div class="work-history">
- <span v-if="portrait.entryDate">
- {{ formatWorkDate(portrait.entryDate) }}入职 | 司龄{{ portrait.companyYears != null ? portrait.companyYears : '-' }}年 | 开机年限{{ portrait.xrayOperatorYears != null ? portrait.xrayOperatorYears : '-'
- }}年 | 现任职{{ portrait.roleNames || '-' }}
- </span>
- <span v-else>暂无数据</span>
- </div>
- </Card>
- <Card title="获奖记录">
- <div class="card-content">
- <div class="honor-item" v-for="(value, index) in portrait.awards" :key="index">
- <div :style="{'--indexBgColor': value.color}">
- <div :data-index="index + 1"></div>
- {{ value.level2Name }} {{ value.level4Name }}
- </div>
- <div>{{ value.score || '-' }}分</div>
- </div>
- </div>
- </Card>
- </div>
- <div class="content-bottom-center">
- <Card title="个人能力">
- <div class="chart-legend">
- <div class="legend-item legend-warning"><span></span>预警线(低于75分)</div>
- <!-- <div class="legend-item legend-normal"><span></span>正常线(75~90分)</div> -->
- <div class="legend-item legend-excellent"><span></span>优秀线(高于90分)</div>
- <div class="legend-item legend-current"><span></span>当前员工分值</div>
- </div>
- <div ref="abilityChart" class="chart-box" @click="goToWarningPage" />
- </Card>
- </div>
- <div class="content-bottom-right">
- <Card title="补充信息">
- <div class="card-content">
- <div class="supp-item">
- <span class="s-lbl">政治面貌:</span>
- <span class="s-val">{{ portrait.politicalStatusText || '-' }}</span>
- </div>
- <div class="supp-item supp-item-2">
- <span class="s-lbl">性别:</span>
- <span class="s-val">{{ portrait.sexText || '-' }}</span>
- </div>
- <div class="supp-item">
- <span class="s-lbl">籍贯:</span>
- <span class="s-val">{{ portrait.nativePlace || '-' }}</span>
- </div>
- <div class="supp-item supp-item-2">
- <span class="s-lbl">民族:</span>
- <span class="s-val">{{ portrait.nation || '-' }}</span>
- </div>
- <div class="supp-item">
- <span class="s-lbl">年龄:</span>
- <span class="s-val">{{ getAge(portrait.birthday) }}</span>
- </div>
- <div class="supp-item supp-item-2">
- <span class="s-lbl">司龄:</span>
- <span class="s-val">{{ portrait.companyYears != null ? portrait.companyYears+'年' : '-' }}</span>
- </div>
- <div class="supp-item">
- <span class="s-lbl">性格特征:</span>
- <span class="s-val">{{ portrait.characterCharacteristics || '-' }}</span>
- </div>
- <div class="supp-item supp-item-2">
- <span class="s-lbl">工作风格:</span>
- <span class="s-val">{{ portrait.workingStyle || '-' }}</span>
- </div>
- <div :class="i % 2 ? 'supp-item' : 'supp-item supp-item-2'" v-for="(p, i) in (portrait.postNames || '').split('、')" :key="i">
- <span class="s-lbl">{{ i === 0 ? '业务岗位:' : ''}}</span>
- <span class="s-val">{{ p }}</span>
- </div>
- </div>
- </Card>
- </div>
- </div>
- <div v-show="!portrait.personName" class="ep-empty">
- <el-empty description="搜索员工姓名以查看画像" />
- </div>
- </div>
- <div class="radar-tooltip" ref="tipRef">
- <Card>
- <!-- 标题 -->
- <div class="tooltip-title">{{ activeDimName }}</div>
- <!-- 加分区域 -->
- <div class="tooltip-section">
- <div class="section-list">
- <div v-if="addGroupList.length" class="list-item" v-for="(item, i) in addGroupList" :key="i">
- <span>{{ item.name }}:</span>
- <span class="add-text">+{{ item.total }}分</span>
- </div>
- <div v-else class="p-empty">暂无加分记录</div>
- </div>
- <div class="section-total add">
- <span>合计加分:</span>
- <span>{{ addTotal }}分</span>
- </div>
- </div>
- <!-- 扣分区域 -->
- <div class="tooltip-section">
- <div class="section-list">
- <div v-if="deductGroupList.length" class="list-item" v-for="(item, i) in deductGroupList" :key="i">
- <span>{{ item.name }}:</span>
- <span class="deduct-text">{{ item.total }}分</span>
- </div>
- <div v-if="!deductGroupList.length" class="p-empty">暂无扣分记录</div>
- </div>
- <div class="section-total deduct">
- <span>合计扣分:</span>
- <span>{{ deductTotal }}分</span>
- </div>
- </div>
- </Card>
- </div>
- </Page>
- </template>
- <script setup>
- import Page from '../components/page.vue'
- import Card from '../components/card.vue'
- import SearchBar from '../components/SearchBar.vue'
- import { getEmployeePortrait } from '@/api/score/index'
- import { countTagScore } from '@/api/portraitManagement/portraitManagement'
- import { onMounted, onUnmounted, reactive, ref, computed, watch } from 'vue'
- import { useDict } from '@/utils/dict'
- import { useECharts } from '@/hooks/useEcharts'
- import useUserStore from '@/store/modules/user'
- import { useRouter } from 'vue-router'
- defineOptions({ name: 'ProfileEmployeeProfile' })
- const router = useRouter()
- let radarChartInstance = null
- const { sys_user_schooling } = useDict('sys_user_schooling')
- const userStore = useUserStore()
- const visible = ref(false)
- const loading = ref(false)
- const portrait = ref({ dimensions: [] })
- const abilityChart = ref(null)
- const activeDimName = ref(null)
- const tagScoreData = ref(null)
- const currentQuery = ref(null)
- const scoreDetails = computed(() => portrait.value?.scoreDetails || [])
- const addList = computed(() => {
- const all = scoreDetails.value.filter(d => d.totalScore != null && Number(d.totalScore) > 0)
- return activeDimName.value ? all.filter(d => d.dimensionName === activeDimName.value) : all
- })
- const deductList = computed(() => {
- const all = scoreDetails.value.filter(d => d.totalScore != null && Number(d.totalScore) < 0)
- return activeDimName.value ? all.filter(d => d.dimensionName === activeDimName.value) : all
- })
- const addGroupList = computed(() => {
- const groups = {}
- addList.value.forEach(d => {
- const key = d.level2Name || '其他'
- groups[key] = (groups[key] || 0) + Number(d.totalScore)
- })
- return Object.entries(groups).map(([name, total]) => ({ name, total: total.toFixed(2) }))
- })
- const deductGroupList = computed(() => {
- const groups = {}
- deductList.value.forEach(d => {
- const key = d.level2Name || '其他'
- groups[key] = (groups[key] || 0) + Number(d.totalScore)
- })
- return Object.entries(groups).map(([name, total]) => ({ name, total: total.toFixed(2) }))
- })
- const addTotal = computed(() => {
- const s = addList.value.reduce((acc, d) => acc + Number(d.totalScore), 0)
- return (s > 0 ? '+' : '') + s.toFixed(2)
- })
- const deductTotal = computed(() => {
- const s = deductList.value.reduce((acc, d) => acc + Number(d.totalScore), 0)
- return s.toFixed(2)
- })
- const getSchooling = (schooling) => {
- const result = (sys_user_schooling.value || []).find(item => item.value === schooling) || { label: schooling }
- return result.label || '-'
- }
- const getAge = (birthday) => {
- const birthDate = new Date(birthday);
- if (isNaN(birthDate.getTime())) {
- return '-'
- }
- const today = new Date();
- // 计算年份差
- let age = today.getFullYear() - birthDate.getFullYear();
- // 计算月份差
- const monthDiff = today.getMonth() - birthDate.getMonth();
- // 如果还没到今年生日,年龄减1
- if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
- age--;
- }
- return `${age}岁`;
- }
- const getRandomHexColor = () => {
- return '#' + Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, '0');
- }
- const formatWorkDate = (d) => {
- if (!d) return '-'
- const str = String(d)
- const parts = str.substring(0, 10).split('-')
- if (parts.length < 3) return str
- return `${parts[0]}.${Number(parts[1])}.${Number(parts[2])}`
- }
- const invokerEmployeePortrait = (query) => {
- loading.value = true
- const userId = query.id
- const queryData = {
- ...query
- }
- delete queryData.id
- const portraitPromise = getEmployeePortrait(queryData).then(res => {
- portrait.value = res.data || { dimensions: [], awards: [] }
- portrait.value.awards.forEach(item => {
- item.color = getRandomHexColor()
- })
- permutationRadarDataHandler(res.data.dimensions)
- })
- const tagPromise = countTagScore(queryData).then(res => {
- const data = res.data
- if (Array.isArray(data)) {
-
-
- const found = data.find(item => (item.userId == userId) )
-
- if (found) {
-
- tagScoreData.value = found.totalScore ?? found.score
- } else {
- tagScoreData.value = null
- }
- } else {
- tagScoreData.value = data
- }
- })
- return Promise.all([portraitPromise, tagPromise]).finally(() => {
- loading.value = false
- })
- }
- const searchHandler = (query) => {
- visible.value = false
- currentQuery.value = query
- invokerEmployeePortrait(query)
- }
- const goToWarningPage = () => {
- if (currentQuery.value) {
- router.push({
- path: '/score/event',
- query: { id: currentQuery.value.id, startDate: currentQuery.value.beginTime, endDate: currentQuery.value.endTime },
- })
- } else {
- router.push('/score/event')
- }
- }
- const radarData = reactive({
- grounp: [],
- data: []
- })
- const permutationRadarDataHandler = (result = []) => {
- radarData.grounp = result.map(d => ({ name: d.name + '\n\n' + d.score, max: 100 })),
- radarData.data = [{
- name: '个人能力',
- value: result.map(attr => attr.score),
- symbolSize: 10,
- areaStyle: {
- show: false,
- opacity: 0,
-
- // color: {
- // type: 'linear',
- // x: 0,
- // y: 0,
- // x2: 0,
- // y2: 1,
- // colorStops: [{
- // offset: 0, color: '#4DC8FE'
- // }, {
- // offset: 1, color: '#6C26F3'
- // }],
- // global: false
- // },
- },
- lineStyle: {
- color: '#4DC8FE',
- width: 2
- },
- // lineStyle: {
- // color: {
- // type: 'linear',
- // x: 0,
- // y: 0,
- // x2: 0,
- // y2: 1,
- // colorStops: [{
- // offset: 0, color: '#4DC8FE'
- // }, {
- // offset: 1, color: '#6C26F3'
- // }],
- // global: false
- // },
- // width: 5
- // },
- itemStyle: { color: '#fff', borderWidth: 1, borderColor: '#00C8DA', borderJoin: 'round' }
- }]
- }
- const setRadarOptions = computed(() => {
- return {
- radar: {
- indicator: radarData.grounp,
- center: ['50%', '52%'],
- radius: '65%',
- splitNumber: 8,
- axisLine: { lineStyle: { color: '#ccc' } },
- splitLine: { lineStyle: { color: ['#ccc', '#ccc', '#ccc', '#ccc', '#ccc', '#ccc', '#fe4322', '#8EC742', '#ccc'], width: 3 } },
- splitArea: { show: false },
- axisName: {
- color: '#fff',
- fontSize: 18
- },
- },
- series: [
- {
- type: 'radar',
- data: radarData.data,
- symbol: 'circle',
- symbolSize: 13,
- label: {
- show: false,
- formatter: (p) => p.value,
- color: '#fff',
- fontSize: 16,
- fontWeight: 'bold'
- }
- }
- ]
- }
- })
- let pisition = {
- x: 0,
- y: 0
- }
- const tipRef = ref(null)
- radarChartInstance = useECharts(abilityChart, setRadarOptions).bindEvent('mousemove', (e) => {
- if (!Array.isArray(portrait.value.dimensions) || !portrait.value.dimensions.length) return
- const rect = abilityChart.value.getBoundingClientRect()
- if (!tipRef.value) return
- const cx = rect.width / 2
- const cy = rect.height / 2
- const dx = e.offsetX - cx
- const dy = e.offsetY - cy
- const distance = Math.sqrt(dx * dx + dy * dy)
- const radarRadius = rect.width * 0.35 // 对应 radius: 65%
- if (distance > radarRadius) {
- tipRef.value.style.display = 'none'
- return
- }
- // 角度计算
- let angle = Math.atan2(dx, -dy) * (180 / Math.PI)
- if (angle < 0) angle += 360
- const count = portrait.value.dimensions.length
- const step = 360 / count
- let idx = Math.abs(Math.round(angle / step) % count - count)
- if (idx < 0) idx += count
- if (idx >= count) idx = 0
- // 显示 tooltip
- tipRef.value.style.display = 'block'
- tipRef.value.style.left = pisition.x + 30 + 'px'
- tipRef.value.style.top = pisition.y + 'px'
- activeDimName.value = portrait.value.dimensions[idx].name
- }).bindEvent('mouseout', () => {
- if (tipRef.value) tipRef.value.style.display = 'none'
- })
- const handleMouseMove = (eve) => {
- pisition.x = eve.pageX
- pisition.y = eve.pageY
- }
- onMounted(() => {
- window.addEventListener('mousemove', handleMouseMove)
- })
- onUnmounted(() => {
- window.removeEventListener('mousemove', handleMouseMove)
- })
- </script>
- <style lang="scss" scoped>
- .content {
- height: calc(100vh - 90px);
- display: flex;
- flex-direction: column;
- row-gap: 15px;
- padding: 15px;
- box-sizing: border-box;
- overflow: hidden;
- .ep-empty {
- background: #fff;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- background: #21213a;
- opacity: 0.8;
- border-radius: 30px;
- }
- .content-search {}
- .content-info {
- & > * {
- height: 100%;
- }
- .userInfo {
- display: flex;
- width: 100%;
- height: 180px;
- box-sizing: border-box;
- column-gap: 5px;
- .userInfo-name {
- flex: 1;
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- column-gap: 30px;
- &::after {
- content: '';
- display: block;
- width: 1px;
- background:linear-gradient(180deg, transparent, #6f6c98, transparent);
- height: 100%;
- position: absolute;
- top: 0;
- right: -2px;
- }
- .avatar-area {
- height: 140px;
- width: 140px;
- background: #fff;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- .avatar {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- color: #6f6c98;
- font-size: 48px;
- font-weight: 900;
- }
- }
- .basic-name {
- display: flex;
- flex-direction: column;
- justify-content: center;
- row-gap: 10px;
- font-weight: 500;
- .basic-label {
- font-size: 18px;
- color: #8675AE;
- }
- .basic-value {
- font-size: 26px;
- color: #fff;
- }
- }
- }
- .userInfo-info {
- flex: 1;
- position: relative;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- padding: 10px 15px;
- padding-right: 0px;
- box-sizing: border-box;
- &::after {
- content: '';
- display: block;
- width: 1px;
- background:linear-gradient(180deg, transparent, #6f6c98, transparent);
- height: 100%;
- position: absolute;
- top: 0;
- right: -2px;
- }
- .info-item {
- display: flex;
- column-gap: 15px;
- .info-item-content {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- font-weight: 500;
- .info-item-label {
- font-size: 18px;
- color: #8675AE;
- }
- .info-item-value {
- font-size: 18px;
- color: #fff;
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- gap: 2px;
- }
- .info-item-tag {
- font-size: 14px;
- display: block;
- padding: 3px 15px;
- background: linear-gradient(125deg, #2AB3E6, #9605FC);
- border-radius: 20px;
- }
- }
- }
- }
- .userInfo-score {
- :deep(.el-progress-circle) {
- width: 160px;
- height: 160px;
- --el-fill-color-light: #004970;
- transform: rotate(0.5turn);
- }
- flex: 1;
- display: flex;
- align-items: center;
- padding-left: 15px;
- column-gap: 25px;
- .score-progress {
- .percentage-content {
- display: flex;
- flex-direction: column;
- align-items: center;
- row-gap: 6px;
- font-weight: 500;
- .percentage-value {
- font-size: 48px;
- color: #02E5CC;
- }
- .percentage-text {
- font-size: 16px;
- color: #fff;
- }
- }
- }
- .score-box {
- display: flex;
- flex-direction: column;
- font-weight: 500;
- row-gap: 15px;
- font-size: 18px;
- .score-col {
- display: inline-block;
- width: 5em;
- }
- .score-col-2 {
- font-size: 24px;
- }
- }
- }
- }
- }
- .content-bottom {
- flex: 1;
- display: flex;
- column-gap: 15px;
- overflow: hidden;
- .content-bottom-left {
- width: 380px;
- display: flex;
- flex-direction: column;
- row-gap: 15px;
- & > *:nth-child(1) {
- height: 160px;
- .work-history {
- font-size: 18px;
- }
- }
- & > *:nth-child(2) {
- flex: 1.6;
- .honor-item {
- height: 48px;
- padding-right: 15px;
- box-sizing: border-box;
- font-weight: 500;
- font-size: 18px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- position: relative;
- & > div:nth-child(1) {
- display: flex;
- align-items: center;
- column-gap: 15px;
- margin-left: 10px;
- & > div {
- width: 26px;
- height: 20px;
- position: relative;
- font-size: 18px;
- text-align: center;
- line-height: 20px;
- color: #222;
- &::before {
- position: absolute;
- inset: 0;
- content: '';
- display: block;
- background: var(--indexBgColor);
- width: 100%;
- height: 100%;
- transform: skew(-25deg);
- }
- &::after {
- position: absolute;
- inset: 0;
- content: attr(data-index);
- display: block;
- width: 100%;
- height: 100%;
- z-index: 100;
- }
- }
- }
- & > div:nth-child(2) {
- color: #02E5CC;
- }
- &::after {
- content: '';
- display: block;
- position: absolute;
- bottom: 0;
- left: 0;
- height: 1px;
- width: 100%;
- background:linear-gradient(45deg, transparent 0%, transparent 30%, #6f6c98 100%);
- }
- }
- }
- }
- .content-bottom-center {
- flex: 1;
- & > * {
- height: 100%;
- }
- .chart-legend {
- display: flex;
- justify-content: center;
- align-items: center;
- flex-wrap: wrap;
- gap: 10px 18px;
- padding-top: 8px;
- color: #fff;
- font-size: 14px;
- }
- .legend-item {
- display: flex;
- align-items: center;
- gap: 6px;
- span {
- width: 24px;
- height: 10px;
- border: 2px solid currentColor;
- border-radius: 2px;
- }
- }
- .legend-warning {
- color: #fe4322;
- span {
- background-color: #fe4322;
- }
- }
- .legend-normal {
- color: #fff;
- span {
- background-color: #fff;
- }
- }
- .legend-excellent {
- color: #8EC742;
- span {
- background-color: #8EC742;
- }
- }
- .legend-current {
- color: #1890ff;
- span {
- background-color: #1890ff;
- }
- }
- .chart-box {
- width: 100%;
- height: calc(100% - 34px);
- overflow: hidden;
- }
- }
- .content-bottom-right {
- width: 380px;
- & > * {
- height: 100%;
- }
- .supp-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- height: 42px;
- padding: 0 15px;
- font-weight: 500;
- font-size: 18px;
- .s-lbl {
- color: #8675AE;
- }
- .s-val {
- color: #fff;
- }
- }
- .supp-item-2 {
- background: #261C48;
- }
- }
- .card-content {
- height: 100%;
- overflow-x: hidden;
- overflow-y: auto;
- &::-webkit-scrollbar-track {
- background: transparent;
- }
- &::-webkit-scrollbar-thumb {
- background: linear-gradient(225deg, #4355cb, #873dc3);
- border-radius: 4px;
- }
- }
- }
- }
- /* Tooltip 样式(全部放这里) */
- .radar-tooltip {
- position: fixed;
- min-width: 300px;
- z-index: 999;
- pointer-events: none;
- transform: translateY(-80%);
- display: none;
- .p-empty {
- text-align: center;
- margin-top: 5px;
- }
- .tooltip-title {
- font-size: 18px;
- font-weight: bold;
- color: #fff;
- padding: 0 10px;
- }
- .tooltip-section {
- padding: 0 10px;
- }
- .list-item {
- margin-top: 4px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- color: #fff;
- .deduct-text {
- color: #ff4d4f;
- }
- .add-text {
- color: #00b42a;
- }
- }
- .section-total {
- margin-top: 4px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-weight: 500;
- font-size: 16px;
- &.deduct {
- color: #ff4d4f;
- }
- &.add {
- color: #00b42a;
- }
- }
- }
- </style>
|