| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- <template>
- <div class="mod-menu">
- <div class="my-menu">
- <div class="menu-head">流程类别</div>
- <div v-for="(item, index) in menuList" :key="item.id" @click="choseOne(index, item.id)" :class="{'menu-item': true, 'menu-active': active === index}">{{ item.name }}</div>
- </div>
- <div class="my-process">
- <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" @change='steptypeChange' :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">
- <user-components v-model="stepForm.step_func" :userIds="stepForm.step_func" @change='featureChange' :disabled="templateAddDisable" style="width:100%;"/>
- </el-form-item>
- </el-form>
- </div>
- </div>
- <div class='confirmBox'>
- <el-button :disabled="list.length == 0" type='success' size='medium' style='padding:8px 18px; margin-left:20px; font-size:14px;' @click="deploy">部署</el-button>
- <el-button :disabled="list.length == 0" type='primary' size='medium' style='padding:8px 18px; margin-left:20px; font-size:14px;' @click="replace">重置</el-button>
- <el-button :disabled="list.length == 0" 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> -->
- </div>
- <!-- 弹窗, 新增 / 修改 -->
- <!-- <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update> -->
- </div>
- </template>
- <script>
- // import AddOrUpdate from './menu-add-or-update'
- import draggable from 'vuedraggable'
- import { workflowUpdate, workflowList, workflowInfot, workflowDeploy } from '@/api/workflow'
- import UserComponents from '../common/user-components'
- export default {
- data () {
- return {
- id: 0,
- showEndSteps: true,
- dragging: false,
- active: 0,
- menuList: [],
- 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: 'change' }]
- },
- index: '',
- selectValue: '',
- addOrUpdateVisible: false,
- item: {}
- }
- },
- components: {
- draggable,
- UserComponents
- },
- activated () {
- this.getDataList()
- },
- methods: {
- // 获取数据列表
- getDataList () {
- workflowList({ current: 1, size: 100 }).then(({ data }) => {
- if (data.code === '200') {
- this.menuList = data.data.records
- this.workflowInfot(this.menuList[0].id)
- } else {
- this.$message.error(data.msg)
- }
- })
- },
- workflowInfot (id) {
- this.list = []
- workflowInfot(id).then(({ data }) => {
- if (data.code === '200') {
- this.item = data.data
- if (this.item.workFlowStepVOs) {
- this.item.workFlowStepVOs.forEach((v, index) => {
- this.list.push({
- id: index + 1,
- new_or_edit: 'new',
- step_name: v.name,
- step_type: v.type,
- step_func: v.assigneeIds
- })
- if (index === 0) {
- this.stepForm.step_name = v.name
- this.stepForm.step_type = v.type
- this.stepForm.step_func = v.assigneeIds
- this.templateAddDisable = false
- }
- })
- this.id = this.item.workFlowStepVOs.length - 1
- this.$nextTick(() => {
- let stepsArrey = document.querySelectorAll('textarea')
- this.index = 0
- 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'
- })
- }
- } else {
- this.$message.error(data.msg || '未获取到数据')
- }
- })
- },
- choseOne (index, id) {
- this.active = index
- this.workflowInfot(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: []
- })
- },
- 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
- this.stepForm.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.length === 0) 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'
- };
- }
- return this.$message({type: 'error', message: '请填写完整的流程'})
- }
- }
- const myList = []
- this.list.forEach((v, index) => {
- myList.push({
- assigneeIds: v.step_func,
- assigneeType: 1,
- name: v.step_name,
- type: v.step_type,
- sort: index + 1
- })
- })
- let params = {
- name: this.item.name,
- content: this.item.content,
- id: this.item.id,
- code: this.item.code,
- workFlowStepVOs: myList
- }
- workflowUpdate(params).then(({ data }) => {
- if (data.code === '200') {
- this.$message({
- message: '操作成功',
- type: 'success',
- duration: 1500,
- onClose: () => {
- }
- })
- } else {
- this.$message.error(data.msg)
- }
- })
- },
- replace () {
- this.list = []
- this.stepForm = { new_or_edit: 'new', step_name: '', step_type: '', step_func: '' }
- this.templateAddDisable = true
- this.showEndSteps = true
- },
- deploy () {
- this.$confirm(`确定对[流程“${this.item.name}”]进行[部署]操作?`, '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- workflowDeploy({modelId: this.item.modelId}).then(({ data }) => {
- if (data.code === '200') {
- this.$message({
- message: '操作成功',
- type: 'success',
- duration: 1500,
- onClose: () => {
- }
- })
- } else {
- this.$message.error(data.msg)
- }
- })
- }).catch(() => {})
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .my-menu{
- width: 200px;
- position: absolute;
- top: 20px;
- bottom: 30px;
- background: #efefef;
- .menu-head{
- background-color: #17B3A3;
- color: #fff;
- font-size: 20px;
- line-height: 40px;
- padding-left: 10px;
- margin-bottom: 10px;
- }
- .menu-item{
- padding-left: 10px;
- line-height: 30px;
- font-size: 14px;
- &:hover{
- cursor: pointer;
- }
- }
- .menu-active{
- color: #fff;
- background-color: #17B3A3;
- }
- }
- .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>
|