横向和纵向流程图新增

<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>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容