116 lines
3.1 KiB
Vue
116 lines
3.1 KiB
Vue
<script setup lang="ts">
|
||
interface Props {
|
||
/** 总体进度百分比(后端 `projectStage.developmentProgress`;未立项为 0) */
|
||
progress: number
|
||
startTime?: string
|
||
endTime?: string
|
||
}
|
||
|
||
const props = defineProps<Props>()
|
||
|
||
/** 进度条填充宽度(夹到 0~100,避免脏数据把条撑出容器) */
|
||
function clampPercent(value: number): number {
|
||
if (!Number.isFinite(value)) return 0
|
||
return Math.min(100, Math.max(0, Math.round(value)))
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<section class="project-progress">
|
||
<h2 class="project-progress__title">
|
||
开发进度
|
||
</h2>
|
||
|
||
<div class="project-progress__head">
|
||
<span class="project-progress__label text-secondary">总体进度</span>
|
||
<span class="project-progress__percent">{{ clampPercent(props.progress) }}%</span>
|
||
</div>
|
||
|
||
<!-- 设计稿:轨道通栏,蓝色填充,末端一个白底蓝环圆点(进度为 0 时不画圆点) -->
|
||
<div class="project-progress__track">
|
||
<div class="project-progress__fill" :style="{ width: `${clampPercent(props.progress)}%` }" />
|
||
<span
|
||
v-if="clampPercent(props.progress) > 0"
|
||
class="project-progress__knob"
|
||
:style="{ left: `${clampPercent(props.progress)}%` }"
|
||
/>
|
||
</div>
|
||
|
||
<div class="project-progress__range">
|
||
<span>开始时间:{{ props.startTime || '—' }}</span>
|
||
<span>结束时间:{{ props.endTime || '—' }}</span>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
|
||
<style lang="less" scoped>
|
||
// 设计稿实测(1920,1:1;5865c6d9 为 −14 基准,此处统一到主流基准 ⇒ 全部 +14):
|
||
// 「开发进度」ink 324 15/700;「总体进度」ink 372 12/400 #6B7280;「65%」ink 364 20/700 #024FFF;
|
||
// 进度条 (70,402) 1780×6、填充 1157 #024FFF、轨道 #EDEFF2;起止时间 ink 420 11/400 #9CA3AF。
|
||
.project-progress {
|
||
.flex(column, flex-start, stretch);
|
||
padding: 0;
|
||
|
||
// 分割线 317 → 标题 box 321
|
||
&__title {
|
||
.section-title();
|
||
margin-top: 4px;
|
||
padding-left: 12px; // 文字落 x82 = 内容区 x70 + 12
|
||
font-size: 15px;
|
||
font-weight: 700;
|
||
line-height: 20px;
|
||
|
||
&::before {
|
||
width: 4px;
|
||
height: 20px;
|
||
}
|
||
}
|
||
|
||
// 标题盒 321..341 → 「总体进度」盒 370(12/16)
|
||
&__head {
|
||
.flex(row, space-between, baseline);
|
||
margin-top: 29px;
|
||
}
|
||
|
||
&__label {
|
||
font-size: 12px;
|
||
line-height: 16px;
|
||
color: @project-label;
|
||
}
|
||
|
||
// 「65%」20/700:ink 364 → 行盒 361,相对 head 行顶 370 上移 9
|
||
&__percent {
|
||
margin-top: -9px;
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
line-height: 26px;
|
||
color: @project-accent;
|
||
}
|
||
|
||
// 说明盒 370..386 → 轨道顶 402
|
||
&__track {
|
||
position: relative;
|
||
height: 6px;
|
||
margin: 14px 0 0;
|
||
border-radius: @radius-round;
|
||
background: @project-track;
|
||
}
|
||
|
||
&__fill {
|
||
height: 100%;
|
||
border-radius: @radius-round;
|
||
background: @project-accent;
|
||
transition: width 0.3s;
|
||
}
|
||
|
||
// 轨道底 408 → 起止时间盒 418(11/15,ink 420)
|
||
&__range {
|
||
.flex(row, space-between, center);
|
||
margin-top: 10px;
|
||
font-size: 11px;
|
||
line-height: 15px;
|
||
color: @project-muted;
|
||
}
|
||
}
|
||
</style>
|