废话不多说,直接上图
上代码
先封装进度条组件
examin_step.vue
<template>
<div class="d-examineBox cf" v-if="(processList && processList.length > 0) || (review && review.length > 0)">
<h3>审核进度</h3>
<div class="d-steps cf">
<span v-for="(item,index) in processList" :key="index" :status="item.status">
<em>{{ item.username }}</em>
<i>{{ item.user_type_name || '' }}</i>
<template v-if="item.is_reject == 100">
<em text>已驳回 <el-tooltip v-if="item.reject_msg" placement="top" :content="item.reject_msg"><b>{{item.reject_msg }}</b></el-tooltip></em>
<!--时间-->
<em>{{item.reject_date ? $tool.getFormatByCode(item.reject_date , 3) : '-'}}</em>
</template>
<template v-else>
<em v-if="item.status === 0">发起 <el-tooltip v-if="item.service_type_name" placement="top" :content="item.service_type_name"><b>{{item.service_type_name }}</b></el-tooltip></em>
<em v-if="item.status === 100" text>审核中</em>
<em v-if="item.status === 300" text>已通过 <el-tooltip v-if="item.examine_msg" placement="top" :content="item.examine_msg"><b>{{item.examine_msg }}</b></el-tooltip></em>
<em v-if="item.status === 400" text>已拒绝 <el-tooltip v-if="item.examine_msg" placement="top" :content="item.examine_msg"><b>{{item.examine_msg }}</b></el-tooltip></em>
<em v-if="item.status === 500" text>已撤回 {{item.service_type_name}}</em>
<!--时间-->
<em>{{(item.op_date && (item.status === 0 || item.status === 100 || item.status === 300 || item.status === 400 || item.status === 500)) ? $tool.getFormatByCode(item.op_date , 3) : '-'}}</em>
</template>
<!-- 加签 -->
<a href="javascript:;" v-if="addStep && (item.status == 100 || item.status == 200) && !item.isAdd" class="a-addStep" @click="addStepBy(item)" title="添加审核人员">+</a>
<!-- 删除加签 -->
<a href="javascript:;" v-if="item.isAdd" class="a-deleteStep" @click="deleteStepBy(index)" :title="'删除'+item.username">---</a>
</span>
</div>
<div class="d-review cf" v-if="review && review.length > 0">
<strong>抄送人员</strong>
<span>
<em v-for="(item,index) in review" :key="index">{{ item.user_type_name + '-' + item.username }}</em>
</span>
</div>
<!-- 选择人 -->
<dialogChooseUser ref="dialogChooseUser" @callBack="dialogChooseUser_callBack" />
</div>
</template>
<script>
import dialogChooseUser from './dialogChooseUser'
export default {
props: {
//进度
process: {
type: Array,
default: []
},
//抄送人
review: {
type: Array,
default: []
},
//是否有加签
addStep : {
type : Boolean,
default : false
},
},
components : {
dialogChooseUser
},
data() {
return {
processList : [],
}
},
watch: {
process: {
handler(val) {
//检查是否有加签
this.checkIsAdd()
console.log('进度',val)
},
deep: true
},
review: {
handler(val) {
console.log('抄送人',val)
},
deep: true
},
},
methods: {
//删除加签的审核人
deleteStepBy(index){
this.processList.splice(index , 1)
},
//添加审核人
addStepBy(itemNow){
this.previousId = itemNow.id
this.$refs['dialogChooseUser'].selectedUser = this.processList.filter(c=>c.isAdd && c.isAdd == this.previousId)
this.$refs['dialogChooseUser'].isOpenExaminCommonUsers = true
this.$refs['dialogChooseUser'].multiple = true
this.$refs['dialogChooseUser'].dialogVisible = true
},
dialogChooseUser_callBack(data){
var arr = []
//在审核人后面+
var processList = this.processList.filter(c=>!c.isAdd || c.isAdd != this.previousId)
processList.map((item,index)=>{
arr.push(item)
//在操作的这个审核人后面,且它是审核人或者待审核人
if(item.id == this.previousId && (item.status == 100 || item.status == 200)){
data.map((child,childIndex)=>{
//用下审核人的字段
let user = JSON.parse(JSON.stringify(item))
user = Object.assign(user , child)
//是新增的,标识
user.isAdd = this.previousId
user.status = 200
user.status_name = '等待上一个审批'
user.op_date = ''
arr.push(user)
})
}
})
this.processList = arr
},
//检查是否有加签
checkIsAdd(){
this.processList = JSON.parse(JSON.stringify(this.process))
}
},
created() {
},
mounted() {
this.checkIsAdd()
},
}
</script>
<style scoped lang="less">
.d-examineBox {
background: #fff;
position: relative;
border-radius: 2px;
margin-bottom: 10px;
font-style: normal;
h3 {
height: 40px;
line-height: 40px;
color: #06121e;
font-size: 14px;
border-bottom: solid #dbdfe5 1px;
margin: 0 20px;
}
.d-steps {
position: relative;
display: flex;
margin: 0 20px;
overflow: hidden;
overflow-x: auto;
&::-webkit-scrollbar {
height: 8px;
width: 3px;
cursor: pointer;
border-radius: 4px;
}
span {
flex-shrink: 0;
display: block;
position: relative;
padding: 15px 20px 10px 0;
margin-top: 20px;
min-width: 120px;
&:before {
content: "";
width: 8px;
height: 8px;
border-radius: 100%;
overflow: hidden;
background: #fff;
position: absolute;
top: 0;
left: 10px;
border: solid rgba(181, 181, 181, 1) 1px;
z-index: 2;
}
&:after {
content: "";
display: block;
height: 1px;
background: #ececec;
position: absolute;
top: 5px;
left: 0;
right: 0;
z-index: 1;
}
&:nth-of-type(1):after {
left: 14px;
}
&:nth-last-child(1):after {
right: unset;
width: 20px;
}
em {
display: block;
color: #999;
line-height: 20px;
white-space: nowrap;
font-size:12px;
text-overflow: ellipsis;
overflow: hidden;
max-width: 120px;
font-style: normal;
b {
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&:nth-of-type(1){
color:#333;font-size:14px; line-height: 25px;
&:before {
content: "";
width: 6px;
height: 6px;
border-radius: 100%;
overflow: hidden;
background: rgba(181, 181, 181, 1);
position: absolute;
top: 2px;
left: 12px;
z-index: 2;
}
}
}
i{
font-style: normal;
display: inline-block; background: #E7F4FF; font-size:10px; color:#1890FF; border:solid #D9ECFF 1px; border-radius: 2px; height:18px; line-height: 18px; padding:0 5px;
}
.a-addStep{
position: absolute; top:-2px; left:80px; z-index:2; background:rgba(24,144,255,0.5); transition: all 0.3s ease; color:#fff; width:16px; height:16px; font-size:16px; border-radius: 100%; line-height: 14px; text-align: center;
&:before{
content: "";
display: block;
height: 1px;
background: #ececec;
position: absolute;
top: 7px;
left: -60px;
right: 16px;
z-index: 1;
}
&:hover{
background:rgba(24,144,255,1);
}
}
.a-deleteStep{
position: absolute; top:12px; left:50px; background: rgba(255,0,0,0.3); color:#fff; width:16px; height:16px; font-size:9px; border-radius: 100%; line-height: 14px; text-align: center; transition: all 0.3s ease;
&:hover{
background: rgba(255,0,0,1);
}
}
// 审核中
&[status="100"] {
&:before {
border-color: #ff6612;
}
em:nth-of-type(1):before {
background: #ff6612;
}
em[text] {
color: #ff6612;
}
}
// 拒绝
&[status="400"] {
&:before {
border-color: #ff0000;
}
em:nth-of-type(1):before {
background: #ff0000;
}
em[text] {
color: #ff0000;
}
}
// 同意
&[status="300"] {
&:before {
border-color: #33be6f;
}
em:nth-of-type(1):before {
background: #33be6f;
}
em[text] {
color: #33be6f;
}
}
// 撤回
&[status="500"] {
&:before {
border-color: #909399;
}
em:nth-of-type(1):before {
background: #909399;
}
em[text] {
color: #909399;
}
}
}
}
.d-review {
position: relative; margin: 0 20px; border-top:solid #dbdfe5 1px; padding:10px 0; display: flex; align-items: center;
strong{ display: block; flex-shrink: 0; white-space: nowrap; font-weight: 400; }
span{
flex:1; display: flex; flex-wrap: wrap; padding-left:5px;
em{
display: block; height:30px; line-height: 30px; padding:0 20px; border:solid #E6E8EB 1px; margin:5px; border-radius: 2px;
}
}
}
}
</style>
将组件引入到我们自己的项目
import examin_step from '@/components/examin_step.vue'
<examin_step :process="examin_process" :review="examin_review" />
设置一些模拟数据
//审核进度
examin_process: [
{
"id": 26256,
"workflows_id": 112,
"workflows_type_name": "行政",
"workflows_type": 100,
"username": "张三",
"store_4s_name_abbreviation": "德众汽车",
"user_id": 21857,
"op_date": "2024-05-28 17:12:57",
"user_type_name": "测试工程师",
"examine_msg": "",
"service_type": "350100",
"status": 0,
"sort": 0,
"is_lose": 100,
"is_zuofei": 200,
"zuofei_date": null,
"is_reject": 200,
"reject_date": null,
"reject_msg": null,
"is_fan_auth": 200,
"fan_auth_date": null,
"is_entry": 100,
"entry_id": 2213,
"status_name": "撤回审核",
"current_status": 100,
"current_status_name": "待审核",
"is_end": 100,
"is_first": 100,
"extend_field": [],
"service_id": 8,
"store_4s_id": 2,
"service_type_name": "行政物耗采购申请",
"workflows_create_user_id": 10764,
"reject_process_id": null,
"workflows_process_exp_id": 5516,
"service_group": "350100",
"reject_logs": []
},
{
"id": 26256,
"store_4s_name_abbreviation": "怀化远众",
"workflows_id": 112,
"workflows_type_name": "行政",
"workflows_type": 100,
"username": "张三1",
"user_id": 21857,
"op_date": "2024-05-28 17:13:28",
"user_type_name": "测试工程师",
"status": 500,
"service_type": "350100",
"examine_msg": "",
"is_lose": 100,
"sort": 1,
"is_zuofei": 200,
"zuofei_date": null,
"is_reject": 200,
"reject_date": null,
"reject_msg": null,
"is_fan_auth": 200,
"fan_auth_date": null,
"is_entry": 100,
"entry_id": 2213,
"status_name": "已撤回",
"current_status": 100,
"current_status_name": "待审核",
"is_end": 100,
"is_first": 100,
"extend_field": [],
"service_id": 8,
"store_4s_id": 2,
"service_type_name": "行政物耗采购申请",
"workflows_create_user_id": 10764,
"reject_process_id": null,
"workflows_process_exp_id": 5516,
"service_group": "350100",
"reject_logs": []
},
{
"id": 26259,
"workflows_id": 112,
"workflows_type_name": "行政",
"workflows_type": 100,
"username": "张三2",
"store_4s_name_abbreviation": "德众汽车",
"user_id": 21857,
"op_date": "2024-05-28 17:13:40",
"user_type_name": "测试工程师",
"examine_msg": "",
"service_type": "350100",
"status": 0,
"sort": 0,
"is_lose": 200,
"is_zuofei": 200,
"zuofei_date": null,
"is_reject": 200,
"reject_date": null,
"reject_msg": null,
"is_fan_auth": 200,
"fan_auth_date": null,
"is_entry": 100,
"entry_id": 2213,
"status_name": "发起审核",
"current_status": 100,
"current_status_name": "待审核",
"is_end": 100,
"is_first": 100,
"extend_field": [],
"service_id": 8,
"store_4s_id": 2,
"service_type_name": "行政物耗采购申请",
"workflows_create_user_id": 10764,
"reject_process_id": null,
"workflows_process_exp_id": 5517,
"service_group": "350100",
"reject_logs": []
},
{
"id": 26259,
"workflows_id": 112,
"workflows_type_name": "行政",
"workflows_type": 100,
"store_4s_name_abbreviation": "怀化远众",
"username": "张三3",
"user_id": 21695,
"op_date": null,
"user_type_name": "销售主管",
"status": 100,
"service_type": "350100",
"examine_msg": null,
"is_lose": 200,
"sort": 1,
"is_zuofei": 200,
"zuofei_date": null,
"is_reject": 200,
"reject_date": null,
"reject_msg": null,
"is_fan_auth": 200,
"fan_auth_date": null,
"is_entry": 100,
"entry_id": 2087,
"status_name": "待审核",
"current_status": 100,
"current_status_name": "待审核",
"is_end": 100,
"is_first": 100,
"extend_field": [],
"service_id": 8,
"store_4s_id": 2,
"service_type_name": "行政物耗采购申请",
"workflows_create_user_id": 10764,
"reject_process_id": null,
"workflows_process_exp_id": 5517,
"service_group": "350100",
"reject_logs": []
},
{
"id": 26260,
"workflows_id": 112,
"workflows_type_name": "行政",
"workflows_type": 100,
"store_4s_name_abbreviation": "怀化远众",
"username": "张三4",
"user_id": 21857,
"op_date": null,
"user_type_name": "测试工程师",
"status": 200,
"service_type": "350100",
"examine_msg": null,
"is_lose": 200,
"sort": 2,
"is_zuofei": 200,
"zuofei_date": null,
"is_reject": 200,
"reject_date": null,
"reject_msg": null,
"is_fan_auth": 200,
"fan_auth_date": null,
"is_entry": 100,
"entry_id": 2213,
"status_name": "等待上一个审批",
"current_status": 100,
"current_status_name": "待审核",
"is_end": 200,
"is_first": 200,
"extend_field": [],
"service_id": 8,
"store_4s_id": 2,
"service_type_name": "行政物耗采购申请",
"workflows_create_user_id": 10764,
"reject_process_id": null,
"workflows_process_exp_id": 5517,
"service_group": "350100",
"reject_logs": []
},
{
"id": 26261,
"workflows_id": 112,
"workflows_type_name": "行政",
"workflows_type": 100,
"store_4s_name_abbreviation": "怀化远众",
"username": "张三5",
"user_id": 22172,
"op_date": null,
"user_type_name": "后端工程师",
"status": 200,
"service_type": "350100",
"examine_msg": null,
"is_lose": 200,
"sort": 3,
"is_zuofei": 200,
"zuofei_date": null,
"is_reject": 200,
"reject_date": null,
"reject_msg": null,
"is_fan_auth": 200,
"fan_auth_date": null,
"is_entry": 100,
"entry_id": 2191,
"status_name": "等待上一个审批",
"current_status": 100,
"current_status_name": "待审核",
"is_end": 200,
"is_first": 200,
"extend_field": [],
"service_id": 8,
"store_4s_id": 2,
"service_type_name": "行政物耗采购申请",
"workflows_create_user_id": 10764,
"reject_process_id": null,
"workflows_process_exp_id": 5517,
"service_group": "350100",
"reject_logs": []
}
],
以上,完事
遥祝大家一切顺利,发大财