<template>
<div class="view-container car-detail-view">
<div class="detail-center">
<div id="stageCanvas" class="stage-content">
<div class="item" v-for="(item,index) in stageData" :key="item.id" :style="getPosition(index,'x')" @mouseover="mouseoverHandle" @mouseout="mouseoutHandle">
<span class="text-x">{{item.name}}</span>
<span><el-icon @click="deleteStage(item,'x')" ><CircleClose /></el-icon></span>
<div class="children" v-for="(child,index) in item.children" :key="child.id" :style="getPosition(index,'y')" @mouseover.stop>
<span class="text-y">{{child.name}}</span>
<span><el-icon @click="deleteStage(child,'y',item)"><CircleClose /></el-icon></span>
</div>
<div class="children add-btn" @click="addStage(item.children,'y')" :style="getPosition(item.children.length,'y')" @mouseover.stop>
<span class="icon iconfont icon-increase"></span> <!-- y新增-->
<span>并行任务 </span>
</div>
</div>
<div class="item add-btn" @click="addStage(stageData,'x')" :style="getPosition(stageData.length,'x')" @mouseover="mouseoverHandle" @mouseout="mouseoutHandle"> <!-- x新增-->
<span class="icon iconfont icon-increase"></span>
<span>{{stageData.length > 0 ?"串行任务":'新增'}}</span>
</div>
</div>
</div>
<el-dialog :model-value="stageAddVisible" title="添加阶段" @close="closeDialog" width="518px" >
<div>
<el-form :rules="stageRules" ref="ruleFormRefStage" label-width="120px" :model="stageDialogData">
<el-form-item label="阶段:" prop="data">
<el-select :multiple="false" v-model="stageDialogData.data" :popper-append-to-body="false" placeholder="请选择">
<el-option v-for="item in stageOptionData" :key="item.id" :label="item.name" :value="item.name" ></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="sureDialog()">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts">
import { type } from "os";
import { defineComponent ,ref} from "vue";
import { ElForm, ElMessage } from "element-plus";
type FormInstance = InstanceType<typeof ElForm>;
export default defineComponent({
data() {
return {
stageOptionData: [
{
id: 1,
name: "编译",
value: "ifBuild",
}, {
id: 2,
name: "静态检查",
value: "ifCodeCheck",
}, {
id: 3,
name: "单元测试",
value: "ifUT",
}, {
id: 4,
name: "冒烟",
value: "ifSmoke",
},
],
stageRules: {
data: [
{
required: true,
trigger: "change",
message: "请选择阶段",
},
],
},
activeNames : ref(['4']),
stageAddVisible: false,
stageDialogData:{
data:''
},
// stageData:[],
stageData: [
{
id:1,
name:'初始化环境',
children:[{
id:2,
'name':'静态检查'
},
{
id:3,
'name':'编译'
},
]
},
{
id:4,
name:'编译',
children:[{
id:5,
'name':'静态检查'
},
{
id:6,
'name':'冒烟'
}
]
},
{
id:7,
name:'编译2',
children:[]
},
{
id:8,
name:'编译3',
children:[]
},
],
curArr:[] as any,//当前操作数组
curType:'x',//当前操作的轴 "x" -x轴 "y" ---y轴
};
},
created() {
},
mounted() {
},
unmounted() {
},
methods: {
addStage(info,type){
this.stageAddVisible = true;
if(this.$refs.ruleFormRefStage){
this.$refs.ruleFormRefStage.clearValidate();
}
console.log('info------',info);
console.log('type------',type);
this.curArr = info;
this.curType = type;
},
deleteStage(info,type,fatherInfo?){
console.log('info-----------------',info);
let conTip = '是否删除当前阶段?';
let $that = this;
this.$layer.confirm(conTip, {
async onSure () {
if(type == 'x'){ //是外层
$that.stageData = $that.stageData.filter(function(item) { return item.id != info.id});//删除
}else{ //是children
if(fatherInfo.children.length > 0){
let yOneDelInfo = fatherInfo.children;
yOneDelInfo = yOneDelInfo.filter(function(item) { return item.id != info.id});
let targetIndex = $that.stageData.findIndex((itemTemp) => {
return itemTemp.id == fatherInfo.id
});
$that.stageData[targetIndex].children = yOneDelInfo;
}
}
},
});
},
closeDialog() {
this.stageAddVisible = false;
// 清除表单验证提示信息
if(this.$refs.ruleFormRefStage){
this.$refs.ruleFormRefStage.clearValidate();
}
this.stageDialogData = {
data: "",
}
},
getPosition(number,type){
let leftVal = 0;
let topVal = 0;
if(type == 'x'){
leftVal = 140*number;
}else if(type == 'y'){
number = number + 1;
topVal = 40*number;
}
let obj = {
left: leftVal+'px',
top: topVal+'px'
}
return obj;
},
mouseoverHandle(event){
if(typeof event.target.className == 'object'){ //是删除图标
return;
}
if(event.target.className.indexOf('item') === -1) {
event.target.parentNode.className = `${event.target.parentNode.className } hover-btn`
return
}
event.target.className = `${event.target.className } hover-btn`
},
mouseoutHandle(event){
if(typeof event.target.className == 'object'){ //是删除图标
return;
}
if(event.target.className.indexOf('item') === -1) {
event.target.parentNode.className =event.target.parentNode.className.replace('hover-btn', '')
return
}
event.target.className = event.target.className.replace('hover-btn', '')
},
sureDialog() {
(this.$refs.ruleFormRefStage as FormInstance).validate((valid) => {
if (valid) {
console.log('this.stageDialogData=====22============---',this.stageDialogData);
let curVal = this.stageOptionData.filter((i)=>{
return i.name == this.stageDialogData.data;
})
if(this.curType =='x'){
this.curArr.push({
id: parseInt(Math.random() * 100000000000),
name: this.stageDialogData.data,
value:curVal[0]?.value,
children:[]
})
}else{
this.curArr.push( {
id: parseInt(Math.random() * 100000000000),
value:curVal[0]?.value,
name: this.stageDialogData.data,
})
}
console.log('this.curArr=====333============---',this.curArr);
this.stageAddVisible = false;
}
});
},
},
});
</script>
<style lang="scss" scoped>
.car-detail-view {
.car-detail-title {
background: #fff;
padding: 0 10px;
height: 50px;
line-height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 4px;
margin-bottom: 10px;
}
.detail-center {
display: flex;
height: calc(100% - 60px);
flex-direction: column;
background: #ffffff;
padding: 10px;
.stage-content{
height: 400px;
width: 100%;
overflow: auto;
position: relative;
.item{
width: 90px;
height: 32px;
background-color: #ededed;
line-height: 32px;
text-align: center;
// border:1px dotted #ededed;
color:#000000a6;
border-radius: 5px;
cursor: pointer;
position: absolute;
span:first-child{
margin-right: 4px;
}
span.icon{
vertical-align: middle;
}
i.el-icon{
vertical-align: middle;
font-size: 16px;
}
span.text-x::before{//水平线
content: '';
width: 50px;
height: 0px;
border-top:1px dotted #aaa;
position: absolute;
left: 90px;
top: 16px;
}
span.text-y::after,
span.text-x::after{//垂直线
content: '';
height: 50px;
width: 0;
border-left:1px dotted #aaa;
position: absolute;
left: 45px;
top: 32px;
}
// &:hover{
// background-color:#1c3dd7;
// color: #ffffff;
// }
.children{
position: relative;
width: 90px;
height: 32px;
line-height: 32px;
text-align: center;
background-color: #ededed;
// border:1px dotted #1c3dd7;
color:#000000a6;
border-radius: 5px;
cursor: pointer;
&:hover{
background-color:#1c3dd7;
color: #ffffff;
}
// &:hover ~ .item{
// background-color: #E8EBFB;
// pointer-events: none;
// border: 1px solid #000;
// }
}
}
.children.add-btn,
.add-btn{
background-color: #E8EBFB ;
border:1px dotted #1c3dd7;
color:#1c3dd7;
}
.hover-btn{
background-color:#1c3dd7;
color: #ffffff;
}
}
}
}
</style>
横向和纵向流程图新增
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 黄坍仪 横向学习·纵向比较 第一次接触思维导图,是在2018年年初大V店蒙台梭利课程,老师要求用思...
- ImageViewer 关于 图片浏览器,支持图片手势缩放、拖拽等操作,自定义View的模式显示,自定义图片加载方...
- 相关依赖库 前往 【阅读原文】[https://mp.weixin.qq.com/s?__biz=MzA3ODk1...
- 哎呀,这个是最简单的,我就直接贴代码了。 import matplotlib matplotlib.use('Ag...