自定义审批流程
安装
npm install awe-dnd --save
npm i vuedraggable -s
npm i element-ui -S
// main.js
import VueDND from 'awe-dnd'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
Vue.use(VueDND)
vue
<template>
<!-- 审批流程设置 -->
<div class="main">
<div class="stepsBox">
<div class="start-steps">
<button class="start-btn">开始</button>
</div>
<div class="other-steps">
<div class="drap-box">
<draggable v-model="stepsBox" class="draggable">
<div class="steps-box" v-for="(i, v) in stepsBox" :key="i">
<div class="steps-btn">
<input type="text" maxlength="30" placeholder="点击进行选择" value="" @focus="iptFocus(v, i)"
@blur="iptBlur(v, i)" autofocus readonly/>
</div>
<div class="stepsAdd stepsAdd-before" @click="addStepBox1(i, v)">+</div>
<div class="stepsAdd stepsAdd-after" @click="addStepBox2(i, v)">+</div>
<div class="sb-close" @click="subStepBox(i, v)">-</div>
</div>
<div class="end-steps">
<button class="end-btn">结束</button>
<div class="stepsAdd stepsAdd-end" v-if="showEndSteps" @click="addStepBox1()">+</div>
</div>
</draggable>
</div>
</div>
</div>
<div class="select-box" v-if="showSelect" style="margin-top: 150px">
<template>
<el-select class="selectBox" v-model="selectValue" placeholder="请选择" @change="selectChange">
<el-option v-for="i in options" :key="i.label" :label="i.label" :value="i.value"/>
</el-select>
</template>
</div>
<div class="confirm-box" v-if="showConfirm" style="position: absolute;top: 550px;left: 250px">
<el-button type="success" size="medium" style="padding:10px 30px; font-size:14px;" @click="confirm">提交
</el-button>
<el-button type='success' size='medium' style='padding:8px 18px; margin-left:20px; font-size:14px;'
@click="replace">重置
</el-button>
<input style="margin-left:50px; height:28px; text-align:center;" :size="iptWidth" v-model="confirmMessage"
disabled/>
</div>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: [draggable,],
name: 'appr',
data() {
return {
stepsBox: [],
id: 0,
selectId: 0,
drawer: false,
selectValue: '',
showEndSteps: true,
showSelect: false,
showConfirm: false,
index: '',
confirmMessage: "提交的信息",// 最后返回的字符串
options: [
{value: 'DI部署', label: 'DI部署'},
{value: 'DI验证', label: 'DI验证'},
{value: 'ST部署', label: 'ST部署'},
{value: 'ST验证', label: 'ST验证'},
{value: '同步生产', label: '同步生产'},
{value: '生产部署', label: '生产部署'},
{value: '生产验证', label: '生产验证'},
],
selVal: '',
iptWidth: '',
}
},
methods: {
iptFocus(i) {
let stepsArrey = document.querySelectorAll("input");
this.index = i;
this.selectValue = stepsArrey[this.index].value;
for (let i = 0; i < stepsArrey.length; i++) {
stepsArrey[i].style.backgroundColor = '#ecf5ff';
stepsArrey[i].style.color = '#409eff';
}
stepsArrey[this.index].style.backgroundColor = '#409eff';
stepsArrey[this.index].style.color = '#fff';
},
selectChange(selVal) {
let stepsArrey = document.querySelectorAll("input");
stepsArrey[this.index].value = selVal;
this.selVal = selVal;
},
iptBlur(i) {
let stepsArrey = document.querySelectorAll("input");
this.index = i;
},
addStepBox1(v, i) {
let stepsArrey = document.getElementsByTagName("input");
if (i) {
window.setTimeout(() => {
stepsArrey[i].focus()
}, 0);
} else {
window.setTimeout(() => {
stepsArrey[0].focus()
}, 0);
}
this.id++;
this.selectId++;
this.stepsBox.splice(i, 0, this.id);
this.selectValue = '';
if (this.stepsBox.length !== 0) {
this.showSelect = true;
this.showConfirm = true;
this.showEndSteps = false;
}
},
addStepBox2(v, i) {
if (i >= 0) {
let stepsArrey = document.getElementsByTagName("input");
i = i + 1;
window.setTimeout(() => {
stepsArrey[i].focus()
}, 0);
}
this.id++;
this.selectId++;
this.stepsBox.splice(i + 1, 0, this.id);
this.selectValue = '';
},
subStepBox(v, i) {
this.stepsBox.splice(i, 1);
if (this.stepsBox.length === 0) {
this.showConfirm = false;
this.showEndSteps = true;
this.showSelect = false;
}
this.selectValue = '请选择修改模块';
let stepsArrey = document.querySelectorAll("input");
for (let i = 0; i < stepsArrey.length; i++) {
stepsArrey[i].style.backgroundColor = '#ecf5ff';
stepsArrey[i].style.color = '#409eff';
}
},
confirm() {
let stepsMessage = [];
let stepsArrey = document.querySelectorAll('input');
for (let i = 0; i < stepsArrey.length; i++) {
stepsArrey[i].style.backgroundColor = '#ecf5ff';
stepsArrey[i].style.color = '#409eff';
}
for (let i = 0; i < stepsArrey.length - 2; i++) {
if (stepsArrey[i].value != '') {
stepsMessage.push(stepsArrey[i].value);
} else {
for (let i = 0; i < stepsArrey.length - 2; i++) {
if (stepsArrey[i].value === '') {
stepsArrey[i].style.backgroundColor = '#EE1111';
stepsArrey[i].style.color = '#fff';
}
}
this.$message({type: 'error', message: '请填写完整的流程'});
return;
}
}
this.confirmMessage = stepsMessage.join('-');
this.iptWidth = 1.8 * this.confirmMessage.length;
},
replace() {
this.stepsBox = [{value: '点击进行选择', label: '点击进行选择'},];
this.selectValue = '';
this.confirmMessage = '提交的信息';
}
},
}
</script>
<style lang="less" scoped>
i {
font-style: normal;
}
div {
box-sizing: border-box;
}
.stepsBox {
position: relative;
display: flex;
z-index: 100;
flex-wrap: nowrap;
top: 100px;
.draggable {
display: flex;
flex-wrap: wrap;
}
.stepsAdd {
text-align: center;
position: absolute;
top: 50%;
border-radius: 100%;
width: 20px;
height: 20px;
line-height: 18px;
margin-top: -9px;
background-color: #409eff;
color: #fff;
z-index: 1;
cursor: pointer;
}
.start-steps,
.end-steps {
height: 70px;
width: 120px;
position: relative;
padding: 15px 30px 15px 0;
}
.end-steps {
box-sizing: border-box;
position: relative;
padding: 15px 0 15px 30px;
.stepsAdd {
left: -10px;
}
}
.end-steps::before {
content: "";
position: absolute;
top: 50%;
left: -30px;
width: 60px;
height: 1px;
background: #c0c4cc;
}
.end-steps::after {
position: absolute;
content: "";
width: 0;
height: 0;
border-width: 5px;
border-style: dashed solid;
top: 50%;
left: 25px;
margin-top: -4px;
border-color: transparent transparent transparent #c0c4cc;
}
.other-steps {
position: relative;
display: flex;
flex-wrap: wrap;
.steps-box {
text-align: center;
color: #333;
font-size: 12px;
cursor: pointer;
padding: 10px 30px;
line-height: 50px;
position: relative;
}
.steps-box::before {
content: "";
position: absolute;
top: 50%;
left: -30px;
width: 60px;
height: 1px;
background: #c0c4cc;
}
.steps-btn {
box-sizing: border-box;
position: relative;
border-radius: 4px;
border: 1px solid #409eff;
background: #409eff;
input {
text-align: center;
width: 100px;
border: none;
outline: 0;
padding: 0 5px;
font-size: 14px;
//font-weight: 500px;
line-height: 48px;
background: #409eff;
color: #fff;
}
}
.steps-btn::before {
position: absolute;
content: "";
width: 0;
height: 0;
border-width: 5px;
border-style: dashed solid;
top: 50%;
left: -5px;
margin-top: -5px;
border-color: transparent transparent transparent #c0c4cc;
}
}
.drap-box {
display: flex;
flex-wrap: wrap;
}
.stepsAdd-before {
// display: none;
left: -10px;
z-index: 2;
}
.stepsAdd-end {
display: block;
}
.stepsAdd-after {
// display: none;
right: -10px;
z-index: 2;
}
.sb-close {
display: none;
width: 16px;
height: 16px;
border-radius: 16px;
color: #fff;
text-align: center;
position: absolute;
color: #fff;
background: #f56c6c;
font-size: 16px;
border-radius: 50%;
top: 3px;
right: 23px;
line-height: 12px;
}
.end-steps:hover {
.stepsAdd-after {
display: block;
}
}
.steps-box:hover {
.stepsAdd-before {
display: block;
}
.stepsAdd-after {
display: block;
}
.sb-close {
display: block;
}
}
.start-btn,
.end-btn {
width: 90px;
height: 40px;
border: 1px solid #b3d8ff;
border-radius: 20px;
text-align: center;
color: #409eff;
line-height: 40px;
font-size: 12px;
cursor: pointer;
background: #ecf5ff;
}
}
</style>
效果展示