Browse Source

Merge remote-tracking branch 'origin/master'

chris 3 years ago
parent
commit
be87a61370
2 changed files with 430 additions and 38 deletions
  1. 1 0
      package.json
  2. 429 38
      src/views/modules/process/process.vue

+ 1 - 0
package.json

@@ -31,6 +31,7 @@
     "vue": "2.5.16",
     "vue-cookie": "1.1.4",
     "vue-router": "3.0.1",
+    "vuedraggable": "^2.24.3",
     "vuex": "3.0.1"
   },
   "devDependencies": {

+ 429 - 38
src/views/modules/process/process.vue

@@ -2,12 +2,58 @@
   <div class="mod-menu">
     <div class="my-menu">
       <div class="menu-head">流程类别</div>
-      <div v-for="(item, index) in menuList" :key="index" :class="{'menu-item': true, 'menu-active': active === index}">订单流程</div>
+      <div v-for="(item, index) in menuList" :key="index" :class="{'menu-item': true, 'menu-active': active === index}">{{ item }}</div>
     </div>
     <div class="my-process">
-      <el-steps :active="process.length" align-center>
+      <div class="template_box">
+        <div class="template_in">
+          <div class="step_box">
+              <div class='start-steps'>
+                <button class='start-btn'>开始</button>
+              </div>
+              <draggable :list="list" disabled class="list-group" ghost-class="ghost" @start="dragging = true" @end="dragging = false" filter=".undraggable">
+                <div class="step" v-for="(v, i) in list" :key="v.id">
+                  <textarea class="list-group-item" placeholder="请选择流程" maxlength='30' autofocus readonly="readonly" @focus='iptFocus(v, i)' @blur='iptBlur(v, i)' :value='v.step_name' />
+                  <div class='stepsAdd stepsAdd-before' @click='addBefore(i)'>+</div>
+                  <div class='stepsAdd stepsAdd-after' @click='addAfter(i)'>+</div>
+                  <div class='sb-close' @click='deleteStep(i)'>-</div>
+                </div>
+                <div class='end-steps undraggable'>
+                  <button class='end-btn'>结束</button>
+                  <div class='stepsAdd stepsAdd-end' v-if='showEndSteps' @click='addBefore()'>+</div>
+                </div>
+              </draggable>
+          </div>
+          <div class="stepInfo">
+              <p>步骤详情(请点击上方加号添加步骤)</p>
+              <div class="stepDetails">
+                <el-form ref="stepForm" label-width="120px" :model="stepForm" :rules="stepRules">
+                  <el-form-item label="步骤名称:" prop="step_name">
+                    <el-input v-model="stepForm.step_name" @change='stepnameChange' :disabled="templateAddDisable" placeholder='请输入步骤名称' />
+                  </el-form-item>
+                  <el-form-item label="审批类型:" prop="step_type">
+                    <el-radio-group v-model="stepForm.step_type" :disabled="templateAddDisable">
+                      <el-radio label="1">会签</el-radio>
+                      <el-radio label="2">或签</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <el-form-item label="节点审批员:" prop="step_func">
+                    <el-select class='typeBox' v-model='stepForm.step_func' placeholder='节点审批员' @change='featureChange' :disabled="templateAddDisable">
+                      <el-option v-for='i in featureItem' :key='i.id' :label='i.label' :value='i.value' />
+                    </el-select>
+                  </el-form-item>
+                </el-form>
+                </div>
+          </div>
+          <div class='confirmBox'>
+              <el-button type='primary' size='medium' style='padding:8px 18px; margin-left:20px; font-size:14px;' @click="replace">重置</el-button>
+              <el-button type='success' size='medium' style='padding:8px 18px; margin-left:20px; font-size:14px;' @click="confirm">提交</el-button>
+          </div>
+        </div>
+      </div>
+      <!-- <el-steps :active="process.length" align-center>
         <el-step v-for="item in process" :key="item.num" :title="item.name" description="可以写流程备注"></el-step>
-      </el-steps>
+      </el-steps> -->
     </div>
     <!-- 弹窗, 新增 / 修改 -->
     <!-- <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update> -->
@@ -16,19 +62,42 @@
 
 <script>
   // import AddOrUpdate from './menu-add-or-update'
+  import draggable from 'vuedraggable'
   export default {
     data () {
       return {
-        dataForm: {},
+        id: 0,
+        showEndSteps: true,
+        dragging: false,
         active: 0,
         menuList: ['订单流程', '采购流程'],
-        process: [{name: '开始', num: 0}, { name: '发起申请', num: 1 }, { name: '结束', num: 2 }],
+        list: [],
+        templateAddDisable: true,
+        featureItem: [
+          { id: '1', label: 'Jenkins构建', value: 'build' },
+          { id: '2', label: '应用部署', value: 'deploy' },
+          { id: '3', label: '应用验证', value: 'validate' },
+          { id: '4', label: '镜像同步', value: 'sync' }
+        ],
+        stepForm: {
+          new_or_edit: 'new',
+          step_name: '',
+          step_type: '',
+          step_func: ''
+        },
+        stepRules: {
+          step_name: [{ required: true, message: '步骤名不能为空', trigger: 'blur' }],
+          step_type: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
+          step_func: [{ required: true, message: '功能不能为空', trigger: 'blur' }]
+        },
+        index: '',
+        selectValue: '',
         addOrUpdateVisible: false
       }
     },
-    // components: {
-    //   AddOrUpdate
-    // },
+    components: {
+      draggable
+    },
     activated () {
       this.getDataList()
     },
@@ -48,39 +117,129 @@
           this.dataListLoading = false
         })
       },
-      // 新增 / 修改
-      addOrUpdateHandle (id) {
-        this.addOrUpdateVisible = true
-        this.$nextTick(() => {
-          this.$refs.addOrUpdate.init(id)
+      // 添加
+      addBefore (i) {
+        this.templateAddDisable = false
+        this.stepForm.step_name = ''
+        this.stepForm.step_type = ''
+        this.stepForm.step_func = ''
+        this.list.splice(i, 0, {
+          id: this.id++,
+          new_or_edit: 'new',
+          step_name: '',
+          step_type: '',
+          step_func: ''
+        })
+        if (this.list.length !== 0) {
+          this.showEndSteps = false
+        }
+        this.selectValue = ''
+        let stepsArrey = document.getElementsByTagName('textarea')
+        if (i) {
+          window.setTimeout(() => {
+            stepsArrey[i].focus()
+          }, 0)
+        } else {
+          window.setTimeout(() => {
+            stepsArrey[0].focus()
+          }, 0)
+        }
+      },
+      addAfter (i) {
+        this.stepForm.step_name = ''
+        this.stepForm.step_type = ''
+        this.stepForm.step_func = ''
+        let stepsArrey = document.getElementsByTagName('textarea')
+        if (i === 0) {
+          i = i + 1
+          window.setTimeout(() => { stepsArrey[1].focus() }, 0)
+        } else if (i > 0) {
+          i = i + 1
+          window.setTimeout(() => { stepsArrey[i].focus() }, 0)
+        }
+        this.list.splice(i, 0, {
+          id: this.id++,
+          new_or_edit: 'new',
+          step_name: '',
+          step_type: '',
+          step_func: ''
         })
       },
-      // 删除
-      deleteHandle (id) {
-        this.$confirm(`确定对[id=${id}]进行[删除]操作?`, '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(() => {
-          this.$http({
-            url: this.$http.adornUrl(`/user-service/menu/delete?menuId=${id}`),
-            method: 'DELETE',
-            data: this.$http.adornData()
-          }).then(({data}) => {
-            if (data && data.code === '200') {
-              this.$message({
-                message: '操作成功',
-                type: 'success',
-                duration: 1500,
-                onClose: () => {
-                  this.getDataList()
-                }
-              })
-            } else {
-              this.$message.error(data.msg)
+      deleteStep (i) {
+        this.list.splice(i, 1)
+        if (this.list.length === 0) {
+          this.showEndSteps = true
+          this.templateAddDisable = true
+          this.stepForm = { new_or_edit: 'new', step_name: '', step_type: '', step_func: '' }
+        }
+        let stepsArrey = document.querySelectorAll('textarea')
+        for (let i = 0; i < stepsArrey.length; i++) {
+          stepsArrey[i].style.backgroundColor = '#ecf5ff'
+          stepsArrey[i].style.color = '#409eff'
+        }
+      },
+      iptFocus (v, i) {
+        this.stepForm.step_name = v.step_name
+        this.stepForm.step_type = v.step_type
+        this.stepForm.step_func = v.step_func
+        let stepsArrey = document.querySelectorAll('textarea')
+        this.index = i
+        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'
+      },
+      iptBlur (v, i) {
+        this.index = i
+      },
+      stepnameChange (selVal) {
+        this.list[this.index].step_name = selVal
+        this.stepForm.step_name = selVal
+      },
+      steptypeChange (selVal) {
+        this.list[this.index].step_type = selVal
+      },
+      featureChange (selVal) {
+        this.list[this.index].step_func = selVal
+      },
+      confirm () {
+        if (this.stepForm.step_name === '') return this.$message.error('步骤名称不能为空')
+        if (this.stepForm.step_type === '') return this.$message.error('审批类型不能为空')
+        if (this.stepForm.step_func === '') return this.$message.error('节点审批员不能为空')
+        let stepsMessage = []
+        let stepsArrey = document.querySelectorAll('textarea')
+        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; i++) {
+          if (stepsArrey[i].value !== '') {
+            stepsMessage.push(stepsArrey[i].value)
+          } else {
+            for (let i = 0; i < stepsArrey.length; i++) {
+              if (stepsArrey[i].value === '') {
+                stepsArrey[i].style.backgroundColor = '#EE1111'
+                stepsArrey[i].style.color = '#fff'
+              };
             }
-          })
-        }).catch(() => {})
+            return this.$message({type: 'error', message: '请填写完整的流程'})
+          }
+        }
+        let params = {
+          id: 0,
+          name: this.templateForm.name,
+          msg: this.templateForm.msg,
+          steps: this.list
+        }
+        console.log(params)
+      },
+      replace () {
+        this.list = []
+        this.stepForm = { new_or_edit: 'new', step_name: '', step_type: '', step_func: '' }
+        this.templateAddDisable = true
+        this.showEndSteps = true
       }
     }
   }
@@ -89,6 +248,9 @@
 .my-menu{
   width: 200px;
   position: absolute;
+      top: 20px;
+    bottom: 30px;
+    background: #efefef;
   .menu-head{
     background-color: #17B3A3;
     color: #fff;
@@ -114,4 +276,233 @@
 .my-process{
   padding-left: 210px;
 }
+.template_box {
+  background-color: #fff;
+  .template_in {
+    padding: 15px 0;
+    width: 100%;
+    letter-spacing: 1px;
+  }
+}
+/deep/ .el-form-item--small.el-form-item {
+    margin-bottom: 12px;
+}
+/deep/ .el-input--small .el-input__inner, .el-input--small .el-textarea__inner {
+    font-size: 12px;
+}
+/deep/ .el-input--small .el-textarea__inner {
+    font-size: 12px;
+}
+/deep/ .el-input--small .el-input__inner {
+    height: 28px;
+    line-height: 28px;
+}
+/deep/ textarea {
+  font: 400 13.3333px Arial;
+  resize: none;
+}
+/deep/ .step_box textarea {
+  outline: 0;
+  caret-color: transparent;
+}
+ .step_box textarea::-webkit-input-placeholder {
+  color: #ccc;
+}
+.templateInfo {
+  padding: 0 30px 2px 50px;
+  margin: 0 auto;
+  margin-top: 10px;
+  width: 600px;
+}
+.stepInfo {
+  background-image: linear-gradient(to right, #ccc 0%, #ccc 50%, transparent 50%);
+  background-size: 14px 2px;
+  background-repeat: repeat-x;
+  padding: 10px;
+  margin: 10px auto 25px;
+  width: 600px;
+  p {
+    font-size: 14px;
+    color: grey;
+    margin: 5px 0 15px -10px;
+  }
+}
+.confirmBox {
+  text-align: center;
+}
+button {
+    outline: 0;
+  }
+.step_box {
+  min-height: 72px;
+  width: 100%;
+  text-align: center;
+  display: flex;
+  justify-content:center;
+  .start-steps{
+    width: 120px;
+    position: relative;
+    padding: 15px 30px 15px 0;
+  }
+  .end-steps {
+    width: 90px;
+    position: relative;
+    padding: 15px 30px 15px 0;
+  }
+  .end-steps {
+    box-sizing: border-box;
+    position: relative;
+    padding: 15px 0 15px 15px;
+    .stepsAdd {
+      left: -19px;
+    }
+  }
+  .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;
+  }
+}
+.end-steps::before {
+  content: '';
+  position: absolute;
+  top: 50%;
+  left: -30px;
+  width: 40px;
+  height: 1px;
+  background: #c0c4cc;
+}
+.end-steps::after {
+  position: absolute;
+  content: '';
+  width: 0;
+  height: 0;
+  border-width: 5px;
+  border-style: dashed solid;
+  top: 50%;
+  left: 10px;
+  margin-top: -4px;
+  border-color: transparent transparent transparent #c0c4cc;
+}
+.stepsAdd-before {
+  display: none;
+  left: -19px;
+  z-index: 2;
+}
+.stepsAdd {
+  font-size: 14px;
+  text-align: center;
+  position: absolute;
+  top: 50%;
+  border-radius: 100%;
+  width: 20px;
+  height: 20px;
+  line-height: 18px;
+  margin-top: -10px;
+  background-color: #409eff;
+  color: #fff;
+  z-index: 1;
+  cursor: pointer;
+}
+.stepsAdd-end {
+  display: block;
+}
+.stepsAdd-after {
+  display: none;
+  right: -1px;
+  z-index: 2;
+}
+.end-steps:hover {
+.stepsAdd-after {
+  display: block;
+  }
+}
+.step:hover {
+  .stepsAdd-before {
+    display: block;
+  }
+  .stepsAdd-after {
+    display: block;
+  }
+  .sb-close {
+    display: block;
+  }
+}
+.sb-close {
+  cursor: default;
+  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;
+}
+.buttons {
+  margin-top: 35px;
+}
+.ghost {
+  opacity: 0.5;
+  background: #c8ebfb;
+}
+.list-group {
+  display: flex;
+  flex-wrap: wrap;
+}
+.step::before {
+  content: '';
+  position: absolute;
+  top: 50%;
+  left: -30px;
+  width: 40px;
+  height: 1px;
+  background: #c0c4cc;
+}
+.step {
+  position: relative;
+  padding: 10px 30px 10px 15px;
+}
+.step::after {
+  position: absolute;
+  content: '';
+  width: 0;
+  height: 0;
+  border-width: 5px;
+  border-style: dashed solid;
+  top: 50%;
+  left: 10px;
+  margin-top: -4px;
+  border-color: transparent transparent transparent #c0c4cc;
+}
+.list-group-item {
+  position: relative;
+  width: 90px;
+  box-sizing: border-box;
+  border-radius: 4px;
+  border: 1px solid #409eff;
+  height: 48px;
+  overflow: hidden;
+  cursor: pointer;
+  text-align: center;
+  padding: 0 5px;
+  font-size: 12px;
+  line-height: 48px;
+  background: #ecf5ff;
+  color: #409eff;
+}
 </style>