You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
5.4 KiB
227 lines
5.4 KiB
|
2 weeks ago
|
<template>
|
||
|
|
<div class="approval-timeline">
|
||
|
|
<!-- 循环渲染每一个节点 -->
|
||
|
|
<div
|
||
|
|
v-for="(item, index) in timelineData"
|
||
|
|
:key="index"
|
||
|
|
class="timeline-item"
|
||
|
|
>
|
||
|
|
<!-- 左侧图标与线条区域 -->
|
||
|
|
<div class="timeline-node">
|
||
|
|
<!-- 垂直连接线 (CSS 处理上下连接) -->
|
||
|
|
<div class="line" v-if="timelineData.length > 1">
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 状态圆点 -->
|
||
|
|
<div
|
||
|
|
class="dot"
|
||
|
|
:class="{
|
||
|
|
'is-blue': item.type === 'submit',
|
||
|
|
'is-green': item.type !== 'submit' && item.status === 'success',
|
||
|
|
'is-red': item.status === 'false' || item.remark,
|
||
|
|
'is-empty': item.status === 'pending'
|
||
|
|
}"
|
||
|
|
>
|
||
|
|
<!-- 如果是实心点,这里可以放Icon,如果是空心,保持空白即可 -->
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 右侧内容区域 -->
|
||
|
|
<div class="timeline-content">
|
||
|
|
<div class="content-header">
|
||
|
|
<span class="label">{{ item.label }}</span>
|
||
|
|
<span class="value">{{ item.value }}</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="content-body">
|
||
|
|
<div class="time">审核时间:{{ item.time }}</div>
|
||
|
|
<!-- 只有审核意见存在时才显示 -->
|
||
|
|
<div v-if="item.remark" class="comment">
|
||
|
|
审核意见:{{ item.remark }}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
export default {
|
||
|
|
name: 'ApprovalTimeline',
|
||
|
|
props:{
|
||
|
|
data:{
|
||
|
|
type: Array,
|
||
|
|
default: []
|
||
|
|
}
|
||
|
|
},
|
||
|
|
data() {
|
||
|
|
return {
|
||
|
|
// 模拟数据:对应图片中的两条流程
|
||
|
|
timelineData: [
|
||
|
|
// {
|
||
|
|
// type: 'audit',
|
||
|
|
// label: '审核人:',
|
||
|
|
// value: '',
|
||
|
|
// time: '2015-09-01 11:13:21',
|
||
|
|
// status: 'pending' // 对应顶部绿色空心点(表示流程结束或当前节点)
|
||
|
|
// },
|
||
|
|
// {
|
||
|
|
// type: 'audit',
|
||
|
|
// label: '审核人:',
|
||
|
|
// value: '',
|
||
|
|
// time: '2015-09-01 11:13:21',
|
||
|
|
// status: 'pending' // 对应顶部绿色空心点(表示流程结束或当前节点)
|
||
|
|
// },
|
||
|
|
// {
|
||
|
|
// type: 'audit',
|
||
|
|
// label: '审核人:',
|
||
|
|
// value: '',
|
||
|
|
// time: '2015-09-01 11:13:21',
|
||
|
|
// status: 'pending' // 对应顶部绿色空心点(表示流程结束或当前节点)
|
||
|
|
// },
|
||
|
|
// {
|
||
|
|
// type: 'audit',
|
||
|
|
// label: '审核人:',
|
||
|
|
// value: '',
|
||
|
|
// time: '2015-09-01 11:10:21',
|
||
|
|
// status: 'success' // 对应绿色实心点
|
||
|
|
// },
|
||
|
|
// {
|
||
|
|
// type: 'submit',
|
||
|
|
// label: '提交人:',
|
||
|
|
// value: '张三',
|
||
|
|
// time: '2015-09-01 10:10:21',
|
||
|
|
// status: 'success' // 对应蓝色实心点
|
||
|
|
// },
|
||
|
|
]
|
||
|
|
};
|
||
|
|
},
|
||
|
|
created(){
|
||
|
|
this.timelineData = this.data
|
||
|
|
}
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
/* 整体容器 */
|
||
|
|
.approval-timeline {
|
||
|
|
width: 100%;
|
||
|
|
margin: 20px auto;
|
||
|
|
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
|
||
|
|
font-size: 14px;
|
||
|
|
color: #333;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 单个条目容器 */
|
||
|
|
.timeline-item {
|
||
|
|
display: flex;
|
||
|
|
position: relative;
|
||
|
|
margin-bottom: 20px; /* 节点间距 */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* --- 左侧节点区域 --- */
|
||
|
|
.timeline-node {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: center;
|
||
|
|
margin-right: 15px;
|
||
|
|
position: relative;
|
||
|
|
width: 20px; /* 固定宽度以对齐 */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 垂直连接线 */
|
||
|
|
.timeline-node .line {
|
||
|
|
position: absolute;
|
||
|
|
top: 0;
|
||
|
|
left: 50%;
|
||
|
|
transform: translateX(-50%);
|
||
|
|
width: 1px;
|
||
|
|
height: calc(100% + 20px);
|
||
|
|
background-color: #ccc;
|
||
|
|
z-index: 0;
|
||
|
|
margin-top: 5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 针对第一个元素,线条通常从圆点下方开始,或者上方留白 */
|
||
|
|
.timeline-item:first-child .timeline-node .line {
|
||
|
|
/* top: 12px; 线条从圆点中心开始向下 */
|
||
|
|
/* height: 100%; */
|
||
|
|
height: calc(100% + 20px);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 针对最后一个元素,线条在圆点上方结束 */
|
||
|
|
.timeline-item:last-child .timeline-node .line {
|
||
|
|
height: 0; /* 线条只在圆点上方 */
|
||
|
|
top: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 如果最后一个节点是“进行中”,上方线条可以是虚线,下方无 */
|
||
|
|
/* 这里为了简化,统一处理,具体根据业务逻辑调整 */
|
||
|
|
|
||
|
|
/* 圆点样式 */
|
||
|
|
.dot {
|
||
|
|
width: 10px;
|
||
|
|
height: 10px;
|
||
|
|
border-radius: 50%;
|
||
|
|
z-index: 1; /* 确保圆点盖住线条 */
|
||
|
|
background-color: #fff;
|
||
|
|
border: 3px solid #ccc;
|
||
|
|
margin-top: 4px; /* 微调垂直位置 */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 状态类:蓝色(提交) */
|
||
|
|
.dot.is-blue {
|
||
|
|
border-color: #1890ff;
|
||
|
|
/* background-color: #1890ff; */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 状态类:绿色(审核通过) */
|
||
|
|
.dot.is-green {
|
||
|
|
border-color: #52c41a;
|
||
|
|
/* background-color: #52c41a; */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 状态类:红色(审核驳回) */
|
||
|
|
.dot.is-red {
|
||
|
|
border-color: #ff4d4f;
|
||
|
|
/* background-color: #ff4d4f; */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 状态类:空心(待处理/结束) */
|
||
|
|
.dot.is-empty {
|
||
|
|
border-color: #52c41a; /* 图片中最后一个点是绿色的圈 */
|
||
|
|
background-color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* --- 右侧内容区域 --- */
|
||
|
|
.timeline-content {
|
||
|
|
flex: 1;
|
||
|
|
padding-top: 2px; /* 与圆点垂直居中对齐 */
|
||
|
|
}
|
||
|
|
|
||
|
|
.content-header {
|
||
|
|
margin-bottom: 4px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.label {
|
||
|
|
color: #333;
|
||
|
|
font-weight: 500;
|
||
|
|
}
|
||
|
|
|
||
|
|
.value {
|
||
|
|
color: #333;
|
||
|
|
margin-left: 8px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.content-body {
|
||
|
|
color: #333;
|
||
|
|
/* font-size: 12px; */
|
||
|
|
line-height: 1.6;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 审核意见特殊样式 */
|
||
|
|
.comment {
|
||
|
|
margin-top: 4px;
|
||
|
|
color: #333; /* 图片中意见颜色较深 */
|
||
|
|
}
|
||
|
|
</style>
|