221 lines
4.6 KiB
Vue
221 lines
4.6 KiB
Vue
|
|
<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>
|