2026-05-04 00:17:44 +08:00

1135 lines
34 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="step4" ref="rootEl">
<div class="top nav">
<div class="l"></div>
<div class="title">
我的检测报告
</div>
<div class="r" @click="router.replace('/')"><img src="@/assets/close.png" alt=""></div>
</div>
<div class="time"> 检测时间<span>{{ creatTime }}</span></div>
<div class="tabs" ref="tabsEl">
<div :class="['tab', activeTab === value.id ? 'active' : '']" v-for="value in tabs" :key="value.id"
@click="handleTabClick(value.id)">{{ value.name }}</div>
</div>
<div class="content content1" :ref="(el) => setSectionEl(1, el)">
<Item title="综合报告">
<div class="text text1"> 您的健康状况一般{{ numsData.abnormalTotal }}项指标超出正常范围需要引起重视</div>
<div class="indicator">
<div class="chart" ref="chartWrapEl">
<canvas ref="radarCanvasRef"></canvas>
</div>
<div class="r">
<div class="r-item">
<div>
<span>{{ numsData.normalTotal }}</span><br> 正常指标
</div>
</div>
<div class="r-item">
<div>
<span class="red">{{ numsData.abnormalTotal }}</span><br> 异常指标
</div>
</div>
</div>
</div>
<div class="text">
生命体征指标正常心肺功能良好血液指标方面血糖超出正常范围建议调整饮食结构定期复查心理健康方面压力指数焦虑指数偏高建议适当放松保持积极心态皮肤健康方面您的皮肤整体状态良好含水量适中面部有轻度黑眼圈可能与睡眠不足有关T区出油较为明显建议加强控油和清洁面部有少量痤疮需注意饮食清淡和规律作息整体肤质为混合型建议分区护理
</div>
</Item>
</div>
<div class="content content2" :ref="(el) => setSectionEl(2, el)">
<Item title="基础体征分析报告">
<div class="card first">
<div class="top">
<div class="icon"><img src="@/assets/images/icon1.png" alt=""></div>
<div class="title">心率</div>
<div :class="['status', data?.metrics?.vital_signs?.heart_rate?.status == '正常' ? '' : 'error']">{{ data?.metrics?.vital_signs?.heart_rate?.status }}</div>
</div>
<div class="middle">心率 <span>{{ data?.metrics?.vital_signs?.heart_rate?.value }}</span> bpm</div>
<div class="bottom">正常范围60100 bmp</div>
</div>
<div class="card">
<div class="top">
<div class="icon"><img src="@/assets/images/icon2.png" alt=""></div>
<div class="title">呼吸频率</div>
<div :class="['status', data?.metrics?.vital_signs?.respiratory_rate?.status == '正常' ? '' : 'error']">{{ data?.metrics?.vital_signs?.respiratory_rate?.status}}</div>
</div>
<div class="middle">呼吸频率 <span>{{ data?.metrics?.vital_signs?.respiratory_rate?.value }}</span> rpm</div>
<div class="bottom">正常范围1220 rpm</div>
</div>
<div class="card">
<div class="top">
<div class="icon"><img src="@/assets/images/icon3.png" alt=""></div>
<div class="title">舒张压</div>
<div :class="['status', data?.metrics?.vital_signs?.diastolic_bp?.status == '正常' ? '' : 'error']">{{ data?.metrics?.vital_signs?.diastolic_bp?.status }}</div>
</div>
<div class="middle">舒张压 <span>{{ data?.metrics?.vital_signs?.diastolic_bp?.value }}</span> rpm</div>
<div class="bottom">正常范围1220 rpm</div>
</div>
<div class="card">
<div class="top">
<div class="icon"><img src="@/assets/images/icon4.png" alt=""></div>
<div class="title">收缩压</div>
<div :class="['status', data?.metrics?.vital_signs?.systolic_bp?.status == '正常' ? '' : 'error']">{{ data?.metrics?.vital_signs?.systolic_bp?.status }}</div>
</div>
<div class="middle">舒张压 <span>{{ data?.metrics?.vital_signs?.systolic_bp?.value }}</span> mmHg</div>
<div class="bottom">正常范围1220 rpm</div>
</div>
<div class="tips">
<Tips title="健康提示" :text="data?.metrics?.vital_signs?.analysis" />
</div>
</Item>
</div>
<div class="content content3" :ref="(el) => setSectionEl(3, el)">
<Item title="血液健康分析报告">
<div class="card">
<div class="top">
<div class="icon"><img src="@/assets/images/icon4.png" alt=""></div>
<div class="title">血糖</div>
<div :class="['status', data?.metrics?.blood_health?.glucose?.status == '偏低' ? 'status1' : data?.metrics?.blood_health?.glucose?.status == '偏高' ? 'status3' : 'status2']">{{ data?.metrics?.blood_health?.glucose?.status }}</div>
</div>
<div class="middle"> <span>{{ data.metrics?.blood_health?.glucose?.value }}</span> bmp</div>
<div :class="['middle_progress', data?.metrics?.blood_health?.glucose?.status == '偏低' ? 'status1' : data?.metrics?.blood_health?.glucose?.status == '偏高' ? 'status3' : 'status2']"></div>
<div class="bottom">正常范围3.96.1 mmol/L</div>
</div>
<div class="card">
<div class="top">
<div class="icon"><img src="@/assets/images/icon4.png" alt=""></div>
<div class="title">血红蛋白</div>
<div :class="['status', data?.metrics?.blood_health?.hemoglobin?.status == '偏低' ? 'status1' : data?.metrics?.blood_health?.hemoglobin?.status == '偏高' ? 'status3' : 'status2']">{{ data?.metrics?.blood_health?.hemoglobin?.status }}</div>
</div>
<div class="middle"> <span>{{ data.metrics?.blood_health?.hemoglobin?.value }}</span> rmp</div>
<div :class="['middle_progress', data?.metrics?.blood_health?.hemoglobin?.status == '偏低' ? 'status1' : data?.metrics?.blood_health?.hemoglobin?.status == '偏高' ? 'status3' : 'status2']"></div>
<div class="bottom">正常范围:110165 g/L</div>
</div>
<div class="card">
<div class="top">
<div class="icon"><img src="@/assets/images/icon4.png" alt=""></div>
<div class="title">甘油三酯</div>
<div :class="['status', data?.metrics?.blood_health?.triglycerides?.status == '偏低' ? 'status1' : data?.metrics?.blood_health?.triglycerides?.status == '偏高' ? 'status3' : 'status2']">{{ data?.metrics?.blood_health?.triglycerides?.status }}</div>
</div>
<div class="middle"> <span>{{ data?.metrics?.blood_health?.triglycerides?.value }}</span> mmol/L</div>
<div :class="['middle_progress', data?.metrics?.blood_health?.triglycerides?.status == '偏低' ? 'status1' : data?.metrics?.blood_health?.triglycerides?.status == '偏高' ? 'status3' : 'status2']"></div>
<div class="bottom">正常范围:0.565 ~ 1.96 mmol/L</div>
</div>
<div class="tips">
<Tips title="健康提示" :text="data?.metrics?.blood_health?.analysis" />
</div>
</Item>
</div>
<div class="content content4" :ref="(el) => setSectionEl(4, el)">
<Item title="心理健康分析报告">
<div class="card">
<div class="top">
心理健康指数
</div>
<div class="middle"> <span>{{ data?.metrics?.mental_health?.mental_score?.value }}</span> </div>
<div class="middle_progress">
<Progress color="linear-gradient(to right, #F5EBC2, #C8A92E)" :percentage="data?.metrics?.mental_health?.mental_score?.value" :pivot-text="''" />
</div>
<div class="bottom">正常范围70-100</div>
</div>
<div class="indicator">
<div class="indicator_item">
<div>
<div class="title"> <img src="@/assets/images/content4-icon1.png" alt="">压力指数
</div>
<div class="value">
<span :class="['value', data?.metrics?.mental_health?.stress?.status == '正常' ? '' : 'error']">{{ data?.metrics?.mental_health?.stress?.value }}</span>
<div :class="['status', data?.metrics?.mental_health?.stress?.status == '正常' ? '' : 'error']">{{ data?.metrics?.mental_health?.stress?.status=='正常' ? '正常' : '异常' }}</div>
</div>
<div class="desc">正常范围:0~5</div>
</div>
</div>
<div class="indicator_item">
<div>
<div class="title"> <img src="@/assets/images/content4-icon1.png" alt="">抑郁指数
</div>
<div class="value">
<span :class="['value', data?.metrics?.mental_health?.depression?.status == '正常' ? '' : 'error']">{{ data?.metrics?.mental_health?.depression?.value }}</span>
<div :class="['status', data?.metrics?.mental_health?.depression?.status == '正常' ? '' : 'error']">{{ data?.metrics?.mental_health?.depression?.status=='正常' ? '正常' : '异常' }}</div>
</div>
<div class="desc">正常范围:0~3</div>
</div>
</div>
<div class="indicator_item">
<div>
<div class="title"> <img src="@/assets/images/content4-icon1.png" alt="">焦虑指数
</div>
<div class="value">
<span :class="['value', data?.metrics?.mental_health?.anxiety?.status == '正常' ? '' : 'error']">{{ data?.metrics?.mental_health?.anxiety?.value }}</span>
<div :class="['status', data?.metrics?.mental_health?.anxiety?.status == '正常' ? '' : 'error']">{{ data?.metrics?.mental_health?.anxiety?.status=='正常' ? '正常' : '异常' }}</div>
</div>
<div class="desc">正常范围:0~3</div>
</div>
</div>
</div>
<!-- <div class="tips1"></div> -->
<div class="tips2">
<Tips title="健康提示" :text="data?.metrics?.mental_health?.analysis" />
</div>
</Item>
</div>
<div class="content content5" :ref="(el) => setSectionEl(5, el)">
<Item title="皮肤健康分析报告">
<div class="card">
<div class="type"><span>混合型肤质</span></div>
<div class="desc">混合性肌肤T区偏油U区偏干</div>
<div class="line-box">
<div class="dot" :style="{'--left': data?.metrics?.skin_status?.hydration?.value + '%'}">皮肤含水量{{data?.metrics?.skin_status?.hydration?.value}}%</div>
<div class="line"></div>
</div>
<div class="skin-box">
<div class="avatar">
<div class="item">黑眼圈 <img :src="data?.metrics?.skin_status?.dark_circles?.value =='轻度' ? content5Status1 : data?.metrics?.skin_status?.dark_circles?.value =='中度' ? content5Status2 : content5Status3" alt=""></div>
<div class="item item2">出油状态 <img :src="data?.metrics?.skin_status?.oil_control?.value =='轻度' ? content5Status1 : data?.metrics?.skin_status?.oil_control?.value =='中度' ? content5Status2 : content5Status3" alt=""></div>
<div class="item item3">痤疮 <img :src="data?.metrics?.skin_status?.acne?.value =='少量' ? content5Status1 : data?.metrics?.skin_status?.acne?.value =='中度' ? content5Status2 : content5Status3" alt=""></div>
</div>
<div class="legend"></div>
</div>
<div class="text">您的皮肤整体状态良好含水量适中面部有轻度黑眼圈可能与睡眠不足有关T区出油较为明显建议加强控油和清洁面部有少量痤疮需注意饮食清淡和规律作息整体肤质为混合型建议分区护理</div>
</div>
<div class="tips">
<Tips title="护理建议" :text="data?.metrics?.skin_status?.analysis" />
</div>
</Item>
</div>
</div>
</template>
<script setup lang="ts">
import { Progress } from 'vant';
import Tips from '@/components/Tips/index.vue';
import { useRouter } from 'vue-router';
import { onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';
import { format } from 'silly-datetime';
import Item from '@/components/Item/index.vue';
import content5Status1 from '@/assets/images/content5-status1.png';
import content5Status2 from '@/assets/images/content5-status2.png';
import content5Status3 from '@/assets/images/content5-status3.png';
const router = useRouter();
const creatTime = ref(new Date().toLocaleString());
const data = ref<any>({});
const summaryText = ref('');
const numsData = ref<any>({
base:{
normal:0,//正常
abnormal:0,//异常
},
blood:{
normal:0,//正常
abnormal:0,//异常
},
mental:{
normal:0,//正常
abnormal:0,//异常
},
normalTotal:0,//正常总数
abnormalTotal:0,//异常总数
});
const tabs = ref([
{
name: '综合报告',
id: 1,
},
{
name: '基础体征',
id: 2,
},
{
name: '血液健康',
id: 3,
},
{
name: '心理健康',
id: 4,
}, {
name: '皮肤状态',
id: 5,
}
]);
const activeTab = ref(1);
const rootEl = ref<HTMLElement | null>(null);
const tabsEl = ref<HTMLElement | null>(null);
const chartWrapEl = ref<HTMLElement | null>(null);
const radarCanvasRef = ref<HTMLCanvasElement | null>(null);
/** 各维度正常项占比 0100用于雷达轴长 */
const categoryRadarScore = (cat: { normal: number; abnormal: number }) => {
const total = cat.normal + cat.abnormal;
if (total <= 0) return 100;
return (cat.normal / total) * 100;
};
const drawRadarChart = () => {
const wrap = chartWrapEl.value;
const canvas = radarCanvasRef.value;
if (!wrap || !canvas) return;
const dpr = Math.min(window.devicePixelRatio || 1, 2);
const w = wrap.clientWidth;
const h = wrap.clientHeight;
if (w < 2 || h < 2) return;
canvas.width = Math.round(w * dpr);
canvas.height = Math.round(h * dpr);
canvas.style.width = `${w}px`;
canvas.style.height = `${h}px`;
const ctx = canvas.getContext('2d');
if (!ctx) return;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
ctx.clearRect(0, 0, w, h);
const cx = w / 2;
const cy = h / 2;
// 留出标签边距
const labelPad = Math.min(w, h) * 0.12;
const R = Math.min(w, h) / 2 - labelPad;
const angles = [
-Math.PI / 2, // 基础体征 12 点
Math.PI / 6, // 血液 右下
(5 * Math.PI) / 6, // 心理 左下
];
const maxVal = 100;
const base = categoryRadarScore(numsData.value.base);
const blood = categoryRadarScore(numsData.value.blood);
const mental = categoryRadarScore(numsData.value.mental);
const values = [base, blood, mental];
const ax = (i: number) => cx + R * Math.cos(angles[i]!);
const ay = (i: number) => cy + R * Math.sin(angles[i]!);
const px = (i: number) => {
const t = Math.min(Math.max(values[i]! / maxVal, 0), 1);
return cx + R * t * Math.cos(angles[i]!);
};
const py = (i: number) => {
const t = Math.min(Math.max(values[i]! / maxVal, 0), 1);
return cy + R * t * Math.sin(angles[i]!);
};
const gridColor = 'rgba(0, 0, 0, 0.08)';
const goldStroke = '#C8A92E';
const goldFill = 'rgba(200, 169, 46, 0.22)';
const goldDeep = 'rgba(160, 120, 30, 0.35)';
// 网格3 层同心圆 + 轴线
ctx.strokeStyle = gridColor;
ctx.lineWidth = 1;
for (let level = 1; level <= 3; level++) {
const r = (R * level) / 3;
ctx.beginPath();
ctx.arc(cx, cy, r, 0, Math.PI * 2);
ctx.stroke();
}
for (let i = 0; i < 3; i++) {
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(ax(i), ay(i));
ctx.stroke();
}
const p: [number, number][] = [
[px(0), py(0)],
[px(1), py(1)],
[px(2), py(2)],
];
// 分三块扇形填充,心理扇区略深以增加层次
const fillWedge = (i0: number, i1: number, alphaMul: number, useDeep: boolean) => {
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(p[i0]![0], p[i0]![1]);
ctx.lineTo(p[i1]![0], p[i1]![1]);
ctx.closePath();
ctx.fillStyle = useDeep ? goldDeep : goldFill;
ctx.globalAlpha = alphaMul;
ctx.fill();
ctx.globalAlpha = 1;
};
fillWedge(0, 1, 1, false);
fillWedge(1, 2, 1, false);
fillWedge(2, 0, 1, true);
ctx.beginPath();
ctx.moveTo(p[0]![0], p[0]![1]);
ctx.lineTo(p[1]![0], p[1]![1]);
ctx.lineTo(p[2]![0], p[2]![1]);
ctx.closePath();
ctx.strokeStyle = goldStroke;
ctx.lineWidth = 1.5;
ctx.stroke();
ctx.fillStyle = '#555';
ctx.font = `${Math.round(Math.min(w, h) * 0.045)}px sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const labels = ['基础体征', '血液指标', '心理健康'];
const labelR = R + labelPad * 0.55;
for (let i = 0; i < 3; i++) {
const lx = cx + labelR * Math.cos(angles[i]!);
const ly = cy + labelR * Math.sin(angles[i]!);
ctx.fillText(labels[i]!, lx, ly);
}
};
let radarRo: ResizeObserver | null = null;
const scheduleDrawRadar = () => {
nextTick(() => drawRadarChart());
};
const sectionEls = new Map<number, HTMLElement>();
const isProgrammaticScrolling = ref(false);
const scrollContainer = ref<Window | HTMLElement>(window);
let rafId: number | null = null;
let programmaticTimer: number | null = null;
const setSectionEl = (id: number, el: unknown) => {
if (!(el instanceof HTMLElement)) return;
sectionEls.set(id, el);
};
const getScrollParent = (el: HTMLElement | null) => {
let cur: HTMLElement | null = el?.parentElement ?? null;
while (cur) {
const style = window.getComputedStyle(cur);
const overflowY = style.overflowY;
const canScroll =
(overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay') &&
cur.scrollHeight > cur.clientHeight + 1;
if (canScroll) return cur;
cur = cur.parentElement;
}
return window;
};
const getStickyOffset = () => {
// tabs 吸顶后会遮住内容,这里用 tabs 高度做滚动偏移
const tabsHeight = tabsEl.value?.getBoundingClientRect().height ?? 0;
return Math.ceil(tabsHeight + 12); // 额外留一点间距,避免标题被顶得太紧
};
const scrollToSection = (id: number) => {
const el = sectionEls.get(id);
if (!el) return;
const offset = getStickyOffset();
const container = scrollContainer.value;
if (container === window) {
const top = window.scrollY + el.getBoundingClientRect().top - offset;
window.scrollTo({ top: Math.max(0, top), behavior: 'smooth' });
return;
}
if (container instanceof HTMLElement) {
const containerRect = container.getBoundingClientRect();
const top = container.scrollTop + (el.getBoundingClientRect().top - containerRect.top) - offset;
container.scrollTo({ top: Math.max(0, top), behavior: 'smooth' });
}
};
const handleTabClick = (id: number) => {
activeTab.value = id;
isProgrammaticScrolling.value = true;
if (programmaticTimer) window.clearTimeout(programmaticTimer);
programmaticTimer = window.setTimeout(() => {
isProgrammaticScrolling.value = false;
}, 800);
scrollToSection(id);
};
const updateActiveTabByScroll = () => {
if (isProgrammaticScrolling.value) return;
const offset = getStickyOffset();
const ids = tabs.value.map((t) => t.id);
let current = ids[0] ?? 1;
for (const id of ids) {
const el = sectionEls.get(id);
if (!el) continue;
const top = el.getBoundingClientRect().top;
if (top - offset <= 2) current = id;
else break;
}
activeTab.value = current;
};
const onScroll = () => {
if (rafId != null) return;
rafId = window.requestAnimationFrame(() => {
rafId = null;
updateActiveTabByScroll();
});
};
onMounted(() => {
scrollContainer.value = getScrollParent(rootEl.value);
const container = scrollContainer.value;
if (container === window) window.addEventListener('scroll', onScroll, { passive: true });
else container.addEventListener('scroll', onScroll, { passive: true });
// 首次进入时根据当前位置更新一次
updateActiveTabByScroll();
scheduleDrawRadar();
if (typeof ResizeObserver !== 'undefined' && chartWrapEl.value) {
radarRo = new ResizeObserver(() => drawRadarChart());
radarRo.observe(chartWrapEl.value);
}
window.addEventListener('resize', drawRadarChart);
});
watch(
numsData,
() => scheduleDrawRadar(),
{ deep: true },
);
onBeforeUnmount(() => {
const container = scrollContainer.value;
if (container === window) window.removeEventListener('scroll', onScroll);
else container.removeEventListener('scroll', onScroll);
if (rafId != null) window.cancelAnimationFrame(rafId);
if (programmaticTimer) window.clearTimeout(programmaticTimer);
window.removeEventListener('resize', drawRadarChart);
radarRo?.disconnect();
radarRo = null;
});
//真实数据
const arkResult = sessionStorage.getItem('step2_ark_result');
if (arkResult) {
const result = JSON.parse(arkResult);
console.log(result);
summaryText.value = result?.output[0]?.summary[0]?.text;
console.log(summaryText.value); //文本
data.value = JSON.parse(result?.output[1]?.content[0]?.text);
console.log(data.value);
/** 只统计带 status 的指标项,跳过 analysis 等非指标字段 */
const countStatus = (section: Record<string, unknown> | undefined, bucket: { normal: number; abnormal: number }) => {
if (!section || typeof section !== 'object') return;
for (const key of Object.keys(section)) {
const item = section[key];
if (!item || typeof item !== 'object' || !('status' in item)) continue;
if ((item as { status: string }).status === '正常') bucket.normal++;
else bucket.abnormal++;
}
};
countStatus(data.value?.metrics?.vital_signs as Record<string, unknown> | undefined, numsData.value.base);
countStatus(data.value?.metrics?.blood_health as Record<string, unknown> | undefined, numsData.value.blood);
countStatus(data.value?.metrics?.mental_health as Record<string, unknown> | undefined, numsData.value.mental);
numsData.value.normalTotal = numsData.value.base.normal + numsData.value.blood.normal + numsData.value.mental.normal;
numsData.value.abnormalTotal = numsData.value.base.abnormal + numsData.value.blood.abnormal + numsData.value.mental.abnormal;
console.log(numsData.value);
creatTime.value = format(new Date(result.created_at ? result.created_at * 1000 : new Date()), 'YYYY-MM-DD HH:mm:ss')
summaryText.value = data.value?.brief_report?.summary_text;
}
</script>
<style scoped lang="scss">
.step4 {
background: #F3F3F3;
min-height: 100vh;
padding-top: 52px;
box-sizing: border-box;
.top.nav {
padding: 0 30px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 50px;
.l {
width: 60px;
height: 60px;
}
.r {
width: 60px;
height: 60px;
img {
width: 100%;
}
}
.title {
background: url('@/assets/images/indicator-bg.png') no-repeat center center / cover;
}
}
.time {
line-height: 33px;
margin-top: 3px;
text-align: center;
font-size: 24px;
color: #000;
span {
color: #797979;
}
}
.tabs {
margin: 50px auto 0;
width: 956px;
height: 118px;
border-radius: 60px;
border: 2px solid #000;
display: flex;
justify-content: space-around;
align-items: center;
position: sticky;
top: 0;
z-index: 20;
background: #F3F3F3;
.tab {
font-size: 30px;
text-align: center;
position: relative;
&:before {
content: '';
position: absolute;
height: 30px;
width: 4px;
background-color: #D8D8D8;
top: 50%;
transform: translateY(-50%);
left: -34px;
}
&:nth-child(1) {
&:before {
display: none;
}
}
&.active {
font-weight: 900;
&:after {
content: '';
position: absolute;
height: 4px;
width: 46px;
background-color: #000;
left: 50%;
transform: translateX(-50%);
bottom: -12px;
}
}
}
}
.content1 {
margin-top: 40px;
.text {
font-size: 30px;
}
.text1 {
margin-top: 30px;
}
.indicator {
margin: 55px 0;
display: flex;
.chart {
margin-right: 80px;
flex: 1;
height: 325px;
min-width: 0;
canvas {
display: block;
width: 100%;
height: 100%;
}
}
.r {
width: 258px;
display: flex;
flex-direction: column;
justify-content: space-between;
.r-item {
width: 100%;
height: 140px;
background: #F8F8F8;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
color: #000;
span {
font-size: 72px;
font-weight: 900;
color: #000;
&.red {
color: #F36151;
}
}
}
}
}
}
.content2,
.content3,
.content4,
.content5 {
margin-top: 20px;
}
.content2 {
.card {
&.first {
margin-top: 30px;
}
border-radius: 18px;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 30px 50px;
margin-top: 20px;
height: 246px;
background: url('@/assets/images/card-bg.png') no-repeat center center / cover;
.top {
display: flex;
align-items: center;
.icon {
background: #000;
border-radius: 50%;
width: 58px;
height: 58px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 36px;
}
}
.title {
flex: 1;
margin-left: 12px;
font-size: 30px;
}
.status {
width: 89px;
height: 58px;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
background: rgba(37, 203, 171, .1);
color: #25CBAB;
&.error {
background: rgba(243, 93, 81, .1);
color: #F36151;
}
}
}
.middle {
font-size: 30px;
color: #000;
span {
font-size: 53px;
font-weight: 900;
color: #000;
}
}
.bottom {
font-size: 30px;
color: #000;
}
}
.tips {
margin-top: 20px;
}
}
.content3 {
.card {
&.first {
margin-top: 30px;
}
border-radius: 18px;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 30px 50px;
margin-top: 20px;
height: 317px;
background: url('@/assets/images/card-bg.png') no-repeat center center / cover;
.top {
display: flex;
align-items: center;
.icon {
background: #000;
border-radius: 50%;
width: 58px;
height: 58px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 36px;
}
}
.title {
flex: 1;
margin-left: 12px;
font-size: 30px;
}
.status {
width: 89px;
height: 58px;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
background: rgba(37, 203, 171, .1);
color: #25CBAB;
&.status1 {
background: rgba(226, 207, 137, .22);
color: #BBA867;
}
&.status2 {
background: rgba(37, 203, 171, .1);
color: #25CBAB;
}
&.status3 {
background: rgba(243, 93, 81, .1);
color: #F36151;
}
}
}
.middle {
font-size: 30px;
color: #000;
span {
font-size: 53px;
font-weight: 900;
color: #000;
}
}
.middle_progress {
height: 43px;
background: url('@/assets/images/status1.png') no-repeat center center / cover;
&.status2 {
background: url('@/assets/images/status2.png') no-repeat center center / cover;
}
&.status3 {
background: url('@/assets/images/status3.png') no-repeat center center / cover;
}
}
.bottom {
font-size: 30px;
color: #000;
}
}
.tips {
margin-top: 20px;
}
}
.content4 {
.card {
&.first {
margin-top: 30px;
}
border-radius: 18px;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 30px 50px;
margin-top: 20px;
height: 317px;
background: url('@/assets/images/card-bg.png') no-repeat center center / cover;
.top {
font-size: 30px;
}
.middle {
font-size: 30px;
color: #000;
span {
font-size: 53px;
font-weight: 900;
color: #000;
}
}
.bottom {
font-size: 30px;
color: #000;
}
}
.indicator {
margin-top: 20px;
display: flex;
justify-content: space-between;
.indicator_item {
width: 272px;
height: 233px;
background: url('@/assets/images/card-bg.png') no-repeat center center / cover;
display: flex;
justify-content: center;
align-items: center;
.title {
white-space: nowrap;
font-size: 30px;
img {
display: inline-block;
width: 30px;
margin-right: 8px;
}
}
.value {
margin: 10px 0;
display: flex;
align-items: flex-end;
span {
font-size: 60px;
&.error {
color: #F36151;
}
}
.status {
margin-left: 8px;
width: 40px;
height: 24px;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
background: rgba(37, 203, 171, .1);
color: #25CBAB;
&.error {
background: rgba(243, 93, 81, .1);
color: #F36151;
}
}
}
.desc {
font-size: 24px;
}
}
}
// .tips1 {
// margin-top: 20px;
// height: 138px;
// background: url('@/assets/images/content4-tips1.png') no-repeat center center / cover;
// }
.tips2 {
margin-top: 20px;
// height: 254px;
// background: url('@/assets/images/content4-tips2.png') no-repeat center center / cover;
}
}
.content5 {
.card {
margin-top: 30px;
padding: 50px;
border-radius: 18px;
background: linear-gradient(to bottom, #F4F4F4 0%, #fbfbfb 100%);
.type {
font-size: 30px;
font-weight: 850;
color: #000;
position: relative;
span {
z-index: 2;
display: inline;
position: relative;
&::before {
z-index: -1;
border-radius: 10px;
content: '';
position: absolute;
width: 120%;
height: 20px;
background: linear-gradient(to right, #F5EBC2 0%, #C8A92E 100%);
left: 50%;
transform: translateX(-50%);
bottom: -10px;
}
}
}
.desc {
font-size: 24px;
color: #000;
margin-top: 20px;
}
.line-box {
margin-top: 96px;
position: relative;
.dot {
transform: translateX(-50%);
left: var(--left);
top: -64px;
position: absolute;
width: 208px;
height: 54px;
display: inline-block;
font-size: 24px;
color:#fff;
background: url('@/assets/images/dot.png') no-repeat center center / 100% 100%;
display: flex;
justify-content: center;
padding-top: 5px;
}
.line {
height: 20px;
background: url('@/assets/images/content5-line.png') no-repeat center center / cover;
}
}
.skin-box{
margin-top: 50px;
.avatar{
position: relative;
margin: 0 auto;
width: 336px;
height: 336px;
background: url('@/assets/images/avatar.png') no-repeat center center / cover;
.item{
top: 96px;
left: -109px;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
padding: 9px 27px;
height: 50px;
font-size: 24px;
color:rgba(0,0,0,0.65);
background: #fff;
border-radius: 25px 25px 0 25px;
white-space: nowrap;
img{
width: 44px;
height: 20px;
margin-left: 8px;
}
}
.item2{
top: 16px;
left: 244px;
}
.item3{
top: 160px;
left: 293px;
}
}
.legend{
margin: 30px auto 0;
width: 531px;
height: 30px;
background: url('@/assets/images/legend.png') no-repeat center center / cover;
}
}
.text{
margin-top: 36px;
font-size: 30px;
color: #000;
line-height: 48px;
}
}
.tips{
margin-top: 20px;
// height: 254px;
// background: url('@/assets/images/content5-tips.png') no-repeat center center / cover;
}
}
}
</style>