|
|
@@ -0,0 +1,170 @@
|
|
|
+<template>
|
|
|
+ <div class="steps-progress-container">
|
|
|
+ <div v-for="(step, index) in steps" :key="index" class="step-item">
|
|
|
+ <div class="step-item-part" @click="handleClickNode(step)">
|
|
|
+ <!-- 步骤圆圈及勾选/数字状态 -->
|
|
|
+ <div
|
|
|
+ :class="[
|
|
|
+ 'step-circle',
|
|
|
+ {
|
|
|
+ completed: step.status === 'completed',
|
|
|
+ current: step.status === 'current',
|
|
|
+ },
|
|
|
+ ]"
|
|
|
+ >
|
|
|
+ <span v-if="step.status === 'completed'">✔</span>
|
|
|
+ <span v-else-if="step.status === 'current'">{{ step.number }}</span>
|
|
|
+ <span v-else>{{ step.number }}</span>
|
|
|
+ </div>
|
|
|
+ <!-- 步骤文字及时间 -->
|
|
|
+ <div class="step-text">
|
|
|
+ <div :class="`step-title ${step.status === 'completed' ? 'step-title_completed' : ''}`">{{ step.title }}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="step-time" v-if="step.time">{{ step.time }}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 连接线条,最后一个步骤不需要线条 -->
|
|
|
+ <div
|
|
|
+ class="step-line"
|
|
|
+ v-if="index < steps.length - 1"
|
|
|
+ :style="{
|
|
|
+ width: '100%',
|
|
|
+ background: step.status === 'completed' ? lineColor_complete : lineColor_un_complete,
|
|
|
+ }"
|
|
|
+ ></div>
|
|
|
+
|
|
|
+ <div class="line-top" v-if="index < steps.length - 1">{{ step.lineTopNum }}天</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+ import { onMounted, ref, watch } from 'vue';
|
|
|
+
|
|
|
+ const props = defineProps({
|
|
|
+ doingNodeIndex: {
|
|
|
+ required: false,
|
|
|
+ default: 0,
|
|
|
+ },
|
|
|
+ steps: {
|
|
|
+ required: false,
|
|
|
+ default: [],
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ const doingIndex = ref(0);
|
|
|
+
|
|
|
+ // 可根据需求动态调整线条宽度和颜色等样式
|
|
|
+ const lineColor_complete = '#1677ff';
|
|
|
+ const lineColor_un_complete = '#e5e6eb';
|
|
|
+
|
|
|
+ const emits = defineEmits(['clickNode', 'changeDoingNodeIndex']);
|
|
|
+
|
|
|
+ const handleClickNode = (currentNode) => {
|
|
|
+ emits('clickNode', { node: currentNode });
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ doingIndex.value = props.doingNodeIndex;
|
|
|
+ // TODO 动态来处理steps中的complete和current,todo的状态
|
|
|
+ });
|
|
|
+
|
|
|
+ watch(doingIndex, (val) => {
|
|
|
+ emits('changeDoingNodeIndex', val);
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ .steps-progress-container {
|
|
|
+ min-width: 1250px;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ padding: 10px 0;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ position: relative;
|
|
|
+ flex: 1;
|
|
|
+ //width: 150px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-circle {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: 2px solid #ccc;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #fff;
|
|
|
+ background-color: #ccc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-circle.completed {
|
|
|
+ background-color: #fff;
|
|
|
+ border-color: var(--vxe-ui-font-primary-color);
|
|
|
+ color: var(--vxe-ui-font-primary-color);
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-circle.current {
|
|
|
+ background-color: var(--vxe-ui-font-primary-color);
|
|
|
+ border-color: var(--vxe-ui-font-primary-color);
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-text {
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 5px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #86909c;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-time {
|
|
|
+ margin-top: 2px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #86909c;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ padding-left: 40px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-line {
|
|
|
+ width: 100%;
|
|
|
+ height: 2px;
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ margin-left: 50px;
|
|
|
+ color: var(--vxe-ui-font-primary-color);
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-item-part {
|
|
|
+ display: flex;
|
|
|
+ z-index: 100;
|
|
|
+ background: #fff;
|
|
|
+ gap: 10px;
|
|
|
+ padding: 20px;
|
|
|
+ align-items: center;
|
|
|
+ cursor: pointer;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .line-top {
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 10px;
|
|
|
+ transform: translateX(50%);
|
|
|
+ z-index: 100;
|
|
|
+ color: var(--vxe-ui-font-primary-color);
|
|
|
+ }
|
|
|
+
|
|
|
+ .step-title_completed {
|
|
|
+ color: #1d2129;
|
|
|
+ }
|
|
|
+</style>
|