项目中心

This commit is contained in:
wangzzpeng
2026-09-28 17:47:25 +08:00
parent b014fffacf
commit 6b88c3805f

View File

@@ -0,0 +1,108 @@
<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 class="text-secondary">开始时间:{{ props.startTime || '—' }}</span>
<span class="text-secondary">结束时间:{{ props.endTime || '—' }}</span>
</div>
</section>
</template>
<style lang="less" scoped>
.project-progress {
.flex(column, flex-start, stretch);
padding: @spacing-lg;
border-radius: @radius-lg;
background: @white;
box-shadow: @shadow-base;
&__title {
.section-title();
}
// 设计稿:正文块相对标题再右缩进一级(设计 27 设计px × 0.77 ≈ 21px)
&__head {
.flex(row, space-between, center);
margin-top: @spacing-base;
padding-left: 21px;
}
&__label {
font-size: @font-size-sm;
}
&__percent {
font-size: @font-size-title;
font-weight: 600;
color: @project-accent;
}
&__track {
position: relative;
height: 5px;
margin: @spacing-base 0 0 21px;
border-radius: @radius-round;
background: @project-track;
}
&__fill {
height: 100%;
border-radius: @radius-round;
background: @project-accent;
transition: width 0.3s;
}
&__knob {
position: absolute;
top: 50%;
width: 16px;
height: 16px;
border: 2px solid @project-accent;
border-radius: @radius-round;
background: @white;
transform: translate(-50%, -50%);
box-sizing: border-box;
}
&__range {
.flex(row, space-between, center);
margin-top: @spacing-lg;
font-size: @font-size-sm;
}
}
</style>