
上述页面的开发,需要对数据进行处理。如果接口返回的是一维数组,需要将之处理为二维数组,原因是为了控制一行展示多少条数据,处理好数据后,直接对其进行遍历即可。
<template>
<!-- 订单签审流程图展示 -->
<view class="components-task-flow">
<view v-for="(item, index) in flowList" :key="index" class="task-flow__row" :class="{ 'row-reverse': (index + 1) % 2 == 0 }">
<!-- row-reverse 样式 当为偶数行时,将数据进行翻转 -->
<!-- 线条 -->
<!-- 奇数行 -->
<template v-if="(index + 1) % 2 != 0">
<view v-if="item.length >= 1 && index != 0" class="line line-a"></view>
<view v-if="item.length >= 2" class="line line-b"></view>
<view v-if="item.length == 3" class="line line-c"></view>
<view v-if="item.length == 3 && index + 1 != flowList.length" class="line line-d"></view>
</template>
<!-- 偶数行 -->
<template v-if="(index + 1) % 2 == 0">
<view v-if="item.length >= 1 && index != 0" class="line line-d"></view>
<view v-if="item.length >= 2" class="line line-c"></view>
<view v-if="item.length == 3" class="line line-b"></view>
<view v-if="item.length == 3 && index + 1 != flowList.length" class="line line-a"></view>
</template>
<view v-if="index + 1 != flowList.length && (index + 1) % 2 != 0" class="line-column-right"></view>
<view v-if="index + 1 != flowList.length && (index + 1) % 2 == 0" class="line-column-left"></view>
<!-- 流程节点 -->
<view v-for="(sonItem, sonIndex) in item" :key="sonItem.id" class="flow__item" :class="{ 'center-node': sonIndex == 1 }">
<view v-if="sonItem.node == '完成'" class="success-icon" :class="{ done__node: sonItem.hasDone, current__node: sonItem.currentFlag }">
<image class="success-icon-img" src="@/static/success__icon.png"></image>
</view>
<view v-else class="default__node" :class="{ done__node: sonItem.hasDone, current__node: sonItem.currentFlag }">
<view class="user-icon"></view>
</view>
<view v-if="sonItem.hasDone && sonItem.node != '完成'" class="complete-icon"></view>
<view class="detail__info">
<view class="user-name">{{ sonItem.processor }}</view>
<view class="node-name">[{{ sonItem.node }}]</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'components-task-flow',
props: {
/**
* 流程图数据
*/
//接口请求到的,流程图一维数据
taskFlowList: {
type: Array,
default: () => [],
},
},
computed: {
flowList() {
let taskFlowList = this.taskFlowList
let list = this.sliceIntoChunks(taskFlowList, 3)
console.log('flowList', list)
return list
},
},
methods: {
/**
* 把数组分割成指定大小的二维数组
*/
sliceIntoChunks(arr, chunkSize) {
const res = []
// let num = 3 // 需要翻转的数组标识
for (let i = 0; i < arr.length; i += chunkSize) {
let chunk = arr.slice(i, i + chunkSize)
// if (i == num) {
// chunk = chunk.reverse()
// num += 6
// }
res.push(chunk)
}
return res
},
},
}
</script>
<style lang="less" scoped>
.components-task-flow {
width: 646rpx;
position: relative;
display: flex;
flex-direction: column;
box-sizing: border-box;
.user-icon {
width: 28rpx;
height: 28rpx;
background: url('~@/static/user-icon.png') center/28rpx 28rpx no-repeat;
}
.complete-icon {
width: 29rpx;
height: 29rpx;
background: url('~@/static/complete-icon.png') center/29rpx 29rpx no-repeat;
}
.task-flow__row {
position: relative;
display: flex;
height: 172rpx;
box-sizing: border-box;
padding: 0 62rpx;
.line {
position: absolute;
top: 32rpx;
height: 2rpx;
background: #dadada;
transform: translateY(-50%);
}
.line-a {
left: 0;
width: 62rpx;
}
.line-b {
left: 124rpx;
width: 168rpx;
}
.line-c {
right: 124rpx;
width: 172rpx;
}
.line-d {
right: 0;
width: 64rpx;
}
.line-column-right {
position: absolute;
top: 32rpx;
right: 0;
width: 2rpx;
height: 172rpx;
background: #dadada;
}
.line-column-left {
position: absolute;
top: 32rpx;
left: 0;
width: 2rpx;
height: 172rpx;
background: #dadada;
}
.flow__item {
position: relative;
width: 66rpx;
height: 66rpx;
.success-icon {
display: flex;
justify-content: center;
align-items: center;
width: 66rpx;
height: 66rpx;
background: #c7c9ce;
overflow: hidden;
border-radius: 50%;
.success-icon-img {
width: 46rpx;
height: 46rpx;
}
}
.default__node {
display: flex;
justify-content: center;
align-items: center;
width: 66rpx;
height: 66rpx;
background: #c7c9ce;
border-radius: 50%;
}
.done__node {
background: #5f95eb;
}
.current__node {
background: #18bc37;
}
.complete-icon {
position: absolute;
left: 45rpx;
top: 41rpx;
}
.detail__info {
width: 168rpx;
position: absolute;
left: 50%;
bottom: -13rpx;
transform: translate(-50%, 100%);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.user-name {
width: 100%;
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 500;
color: #000000;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.node-name {
width: 100%;
margin-top: 10rpx;
font-size: 22rpx;
font-family: PingFang SC;
font-weight: 400;
color: #979797;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.center-node {
margin: 0 164rpx;
}
}
.row-reverse {
flex-direction: row-reverse;
}
}
</style>