lanan-repair-app/components/steps/steps.vue
2025-10-31 16:03:53 +08:00

221 lines
4.6 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>
<view class="inspection-progress-card">
<!-- 卡片标题 -->
<view class="card-title">
<text class="title-text">检验项目进度</text>
<text class="progress-text">
{{ completedCount }}/{{ totalCount }} 项已完成
</text>
</view>
<!-- 进度步骤展示 -->
<view class="progress-container">
<!-- 步骤线 - 背景线 -->
<view class="progress-line-bg"></view>
<!-- 步骤线 - 已完成部分 -->
<view class="progress-line-active" :style="{ width: progressPercentage + '%' }"></view>
<!-- 所有步骤点 -->
<view class="steps-wrapper" :style="{ width: 'calc(100% - ' + (stepSize / 2) + 'px)' }">
<view v-for="(step, index) in steps" :key="index" class="step-item"
:style="{ left: (index * (100 / (steps.length - 1))) + '%' }">
<!-- 步骤点 -->
<view class="step-dot" :class="{
'step-dot-completed': step.status === 'completed',
'step-dot-current': step.status === 'current',
'step-dot-pending': step.status === 'pending'
}">
<text v-if="step.status === 'completed'">
<uni-icons type="checkmarkempty" size="16" color="#ffffff"></uni-icons>
</text>
<text v-else>{{ index + 1 }}</text>
</view>
<!-- 步骤名称 -->
<view class="step-name">{{ step.name }}</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'steps',
components: {
// 引入uni-icons组件
},
props: {
// 步骤数据,格式: [{name: '步骤1', status: 'completed'}, ...]
// status可选值: completed(已完成), current(当前), pending(未完成)
steps: {
type: Array,
default: () => [{
name: '外观检查',
status: 'completed'
},
{
name: '性能测试',
status: 'current'
},
{
name: '安全检测',
status: 'current'
},
{
name: '最终确认',
status: 'completed'
},
{
name: '最终确认',
status: 'current'
},
]
},
// 步骤点大小
stepSize: {
type: Number,
default: 36
}
},
computed: {
// 计算总步骤数
totalCount() {
return this.steps.length;
},
// 计算已完成步骤数
completedCount() {
return this.steps.filter(step => step.status === 'completed').length;
},
// 计算进度百分比
progressPercentage() {
// 找到最后一个已完成步骤的索引
let lastCompletedIndex = -1;
this.steps.forEach((step, index) => {
if (step.status === 'completed') {
lastCompletedIndex = index;
}
});
// 如果没有已完成的步骤进度为0%
if (lastCompletedIndex === -1) return 0;
// 计算进度百分比
return (lastCompletedIndex / (this.steps.length - 1)) * 100;
}
}
};
</script>
<style scoped>
.inspection-progress-card {
width: 100%;
background-color: #ffffff;
border-radius: 12px;
padding: 16px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
margin: 10px 0;
}
.card-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.title-text {
font-size: 16px;
font-weight: 600;
color: #333333;
}
.progress-text {
font-size: 14px;
color: #666666;
}
.progress-container {
position: relative;
width: 100%;
padding-top: 10px;
padding-bottom: 20px;
}
/* 进度线 - 背景 */
.progress-line-bg {
position: absolute;
top: 18px;
left: 0;
right: 0;
height: 2px;
background-color: #e5e7eb;
z-index: 1;
}
/* 进度线 - 已完成部分 */
.progress-line-active {
position: absolute;
top: 18px;
left: 0;
height: 2px;
background-color: #3b82f6;
z-index: 2;
transition: width 0.3s ease;
}
.steps-wrapper {
position: relative;
margin: 0 auto;
z-index: 3;
}
.step-item {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
transform: translateX(-50%);
}
.step-dot {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: 500;
margin-bottom: 8px;
}
/* 已完成步骤样式 */
.step-dot-completed {
background-color: #3b82f6;
color: #ffffff;
}
/* 当前步骤样式 */
.step-dot-current {
background-color: #36d399;
color: #ffffff;
border: 2px solid #36d399;
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
}
/* 未完成步骤样式 */
.step-dot-pending {
background-color: #ffffff;
color: #9ca3af;
border: 2px solid #e5e7eb;
}
.step-name {
font-size: 12px;
color: #666666;
white-space: nowrap;
padding: 0 4px;
}
</style>