25个文件已删除
17个文件已修改
17个文件已添加
| | |
| | | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", |
| | | "dev": true |
| | | }, |
| | | "ansi-styles": { |
| | | "version": "4.3.0", |
| | | "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", |
| | | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "color-convert": "^2.0.1" |
| | | } |
| | | }, |
| | | "chalk": { |
| | | "version": "4.1.2", |
| | | "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", |
| | | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "ansi-styles": "^4.1.0", |
| | | "supports-color": "^7.1.0" |
| | | } |
| | | }, |
| | | "color-convert": { |
| | | "version": "2.0.1", |
| | | "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", |
| | | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "color-name": "~1.1.4" |
| | | } |
| | | }, |
| | | "color-name": { |
| | | "version": "1.1.4", |
| | | "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", |
| | | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", |
| | | "dev": true, |
| | | "optional": true |
| | | }, |
| | | "has-flag": { |
| | | "version": "4.0.0", |
| | | "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", |
| | | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", |
| | | "dev": true, |
| | | "optional": true |
| | | }, |
| | | "ssri": { |
| | | "version": "8.0.1", |
| | | "resolved": "https://registry.npmmirror.com/ssri/-/ssri-8.0.1.tgz", |
| | |
| | | "dev": true, |
| | | "requires": { |
| | | "minipass": "^3.1.1" |
| | | } |
| | | }, |
| | | "supports-color": { |
| | | "version": "7.2.0", |
| | | "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", |
| | | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "has-flag": "^4.0.0" |
| | | } |
| | | }, |
| | | "vue-loader-v16": { |
| | | "version": "npm:vue-loader@16.8.3", |
| | | "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz", |
| | | "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "chalk": "^4.1.0", |
| | | "hash-sum": "^2.0.0", |
| | | "loader-utils": "^2.0.0" |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | }, |
| | | "vue-loader-v16": { |
| | | "version": "npm:vue-loader@16.8.3", |
| | | "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz", |
| | | "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "chalk": "^4.1.0", |
| | | "hash-sum": "^2.0.0", |
| | | "loader-utils": "^2.0.0" |
| | | }, |
| | | "dependencies": { |
| | | "ansi-styles": { |
| | | "version": "4.3.0", |
| | | "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", |
| | | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "color-convert": "^2.0.1" |
| | | } |
| | | }, |
| | | "chalk": { |
| | | "version": "4.1.2", |
| | | "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", |
| | | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "ansi-styles": "^4.1.0", |
| | | "supports-color": "^7.1.0" |
| | | } |
| | | }, |
| | | "color-convert": { |
| | | "version": "2.0.1", |
| | | "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", |
| | | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "color-name": "~1.1.4" |
| | | } |
| | | }, |
| | | "color-name": { |
| | | "version": "1.1.4", |
| | | "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", |
| | | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", |
| | | "dev": true, |
| | | "optional": true |
| | | }, |
| | | "has-flag": { |
| | | "version": "4.0.0", |
| | | "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", |
| | | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", |
| | | "dev": true, |
| | | "optional": true |
| | | }, |
| | | "supports-color": { |
| | | "version": "7.2.0", |
| | | "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", |
| | | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", |
| | | "dev": true, |
| | | "optional": true, |
| | | "requires": { |
| | | "has-flag": "^4.0.0" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "vue-router": { |
| | | "version": "3.6.5", |
| | | "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-3.6.5.tgz", |
| | |
| | | body { |
| | | margin: 0; |
| | | min-width: 500px; |
| | | background-color: #f5f6f6; |
| | | //background-color: #f5f6f6; |
| | | } |
| | | body,html {margin:0; height:100%;} |
| | | ul { |
| | |
| | | import request from '@/api/request.js'; |
| | | |
| | | // 查询表单组 |
| | | export function getFormGroups(param) { |
| | | return request({ |
| | | url: 'admin/form/group', |
| | | method: 'get', |
| | | params: param, |
| | | }); |
| | | } |
| | | |
| | | export function getEntitySet(param) { |
| | | param.token="admin"; |
| | | return request({ |
| | |
| | | }); |
| | | } |
| | | |
| | | // 更新表单组 |
| | | export function updateGroup(param, method) { |
| | | return request({ |
| | | url: 'admin/form/group', |
| | | method: method, |
| | | params: param, |
| | | }); |
| | | } |
| | | |
| | | // 获取表单分组 |
| | | export function getGroup() { |
| | | return request({ |
| | | url: 'admin/form/group/list', |
| | | method: 'get', |
| | | }); |
| | | } |
| | | |
| | | // 更新表单 |
| | | export function updateForm(param) { |
| | | return request({ |
| | | url: 'admin/form', |
| | | method: 'put', |
| | | params: param, |
| | | }); |
| | | } |
| | | |
| | | export function createForm(param) { |
| | | return request({ |
| | | url: 'admin/form', |
| | | method: 'post', |
| | | data: param, |
| | | }); |
| | | } |
| | | export function createFlow(param) { |
| | | param.token="admin"; |
| | | return request({ |
| | |
| | | data:param |
| | | }); |
| | | } |
| | | export function getFormDetailV2(templateId) { |
| | | // 查询审批流详情 |
| | | export function getWorkSetpsByBusinessId(param) { |
| | | param.token="admin" |
| | | param.dataname="md_position" |
| | | return request({ |
| | | url: 'workspace/process/detail', |
| | | method: 'get', |
| | | params: { |
| | | templateId, |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | // 更新表单详情 |
| | | export function updateFormDetail(param) { |
| | | return request({ |
| | | url: 'admin/form/detail', |
| | | method: 'put', |
| | | data: param, |
| | | }); |
| | | } |
| | | |
| | | // 发起流程 |
| | | export function startProcess(param) { |
| | | return request({ |
| | | url: 'workspace/process/start', |
| | | method: 'POST', |
| | | data: param, |
| | | }); |
| | | } |
| | | |
| | | // 查询我发起的 |
| | | export function applyList(data) { |
| | | return request({ |
| | | url: 'workspace/process/applyList', |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // 查看我的待办 |
| | | export function todoList(data) { |
| | | return request({ |
| | | url: 'workspace/process/toDoList', |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | } |
| | | export function ccList(data) { |
| | | return request({ |
| | | url: 'workspace/process/ccList', |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | export function submitedTaskList(data) { |
| | | return request({ |
| | | url: 'workspace/process/submitedTaskList', |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | export function deleteProcessInstance(data) { |
| | | return request({ |
| | | url: 'workspace/process/deleteProcessInstance', |
| | | method: 'POST', |
| | | data : { data} |
| | | }); |
| | | } |
| | | |
| | | // 查看我的已办 |
| | | export function doneList(data) { |
| | | return request({ |
| | | url: 'workspace/process/doneList', |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | } |
| | | // 查询流程详情 |
| | | export function getProcessInstanceInfo(processInstanceId, taskId) { |
| | | return request({ |
| | | url: 'workspace/process/instanceInfo', |
| | | method: 'POST', |
| | | data: { processInstanceId, taskId }, |
| | | }); |
| | | } |
| | | |
| | | // 同意 |
| | | export function agree(data) { |
| | | return request({ |
| | | url: 'workspace/agree', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | // 委派人 |
| | | export function delegateTask(data) { |
| | | return request({ |
| | | url: 'workspace/delegateTask', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | // 委派人完成的按钮 |
| | | export function resolveTask(data) { |
| | | return request({ |
| | | url: 'workspace/resolveTask', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 拒绝,驳回 |
| | | export function refuse(data) { |
| | | return request({ |
| | | url: 'workspace/refuse', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 撤回 |
| | | export function revoke(data) { |
| | | return request({ |
| | | url: 'workspace/revoke', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 转办 |
| | | export function assignee(data) { |
| | | return request({ |
| | | url: 'workspace/assignee', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 回退 |
| | | export function rollback(data) { |
| | | return request({ |
| | | url: 'workspace/rollback', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 加签 |
| | | export function addMulti(data) { |
| | | return request({ |
| | | url: 'workspace/addMulti', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 查询加签人信息 |
| | | export function queryMultiUsersInfo(data) { |
| | | return request({ |
| | | url: 'workspace/queryMultiUsersInfo', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | // 减签 |
| | | export function deleteMulti(data) { |
| | | return request({ |
| | | url: 'workspace/deleteMulti', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | // 评论 |
| | | export function comments(data) { |
| | | return request({ |
| | | url: 'workspace/comments', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 获取历史任务信息列表 |
| | | export function historyTaskList(param) { |
| | | return request({ |
| | | url: 'workspace/process/historyTaskList', |
| | | method: 'GET', |
| | | params: param, |
| | | }); |
| | | } |
| | | |
| | | // 上传文件 |
| | | export function upLoadFileApi(data) { |
| | | return request({ |
| | | url: 'workspace/upLoadFile', |
| | | method: 'POST', |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 下载文件 |
| | | export function downLoadFileApi(data) { |
| | | return request({ |
| | | url: 'workspace/downLoadFile', |
| | | method: 'POST', |
| | | data: data, |
| | | responseType: 'blob', //必须加,否则可能出现乱码或者文件错误,导致文件无法打开 |
| | | }); |
| | | } |
| | | |
| | | // 查询可退回的节点 |
| | | export function getRollbackNodes(data) { |
| | | return request({ |
| | | url: 'workspace/rollbackNodes', |
| | | method: 'POST', |
| | | data, |
| | | url: 'root/approve/getWorkSetps', |
| | | method: 'post', |
| | | data:param |
| | | }); |
| | | } |
| | |
| | | import Vue from "vue"; |
| | | import axios from "axios"; |
| | | import application from '@/config/application'; |
| | | |
| | | import { Notification, MessageBox, Message } from "element-ui"; |
| | | |
| | |
| | | // 字体图标 |
| | | |
| | | const service = axios.create({ |
| | | baseURL: Vue.prototype.BASE_URL+":88/api" , |
| | | baseURL:`${application.baseURL}` , |
| | | //baseURL: Vue.prototype.BASE_URL + ":8090/admin", |
| | | timeout: 50000 |
| | | }); |
| | |
| | | |
| | | service.interceptors.response.use( |
| | | rsp => { |
| | | // console.log("aaaaaaa》》》rps",rsp.data.data) |
| | | // var a =this.$Utils.decode(rsp.data.data) |
| | | // console.log("解码后的rsp》》》rps",a) |
| | | return rsp; |
| | | }, |
| | | // 拦截异常的响应 |
New file |
| | |
| | | export default { |
| | | baseURL: 'http://grand-dev.highdatas.com', |
| | | |
| | | } |
New file |
| | |
| | | export default { |
| | | baseURL: 'http://localhost:88/api', |
| | | |
| | | } |
New file |
| | |
| | | export default { |
| | | baseURL: '', |
| | | /* |
| | | 钉钉配置 |
| | | */ |
| | | dd: { |
| | | corpid: 'ding6b6a824032ecd975bc961a6cb783455b' |
| | | } |
| | | } |
New file |
| | |
| | | export default { |
| | | baseURL: 'https://csec.jemincare.com', |
| | | |
| | | } |
New file |
| | |
| | | import local from './application-local'; |
| | | import prod from './application-prod'; |
| | | import dev from './application-dev'; |
| | | import uat from './application-uat'; |
| | | |
| | | export default { |
| | | ...dev, |
| | | }; |
| | |
| | | Vue.use(WDialog); |
| | | Vue.use(Tip); |
| | | Vue.use(vueEsign) |
| | | Vue.prototype.$cssSrc=require('@/assets/flowDesignVertical.scss'); |
| | | Vue.prototype.$isVertical=true; |
| | | Vue.config.productionTip = false |
| | | Vue.prototype.$Utils = Utils |
| | | |
| | |
| | | |
| | | <script> |
| | | import LayoutHeader from './LayoutHeader' |
| | | import {getFormDetail, createForm, updateFormDetail, createFlow, getFlowDetail} from '@/api/design' |
| | | import {createFlow, getFlowDetail} from '@/api/design' |
| | | |
| | | import ProcessDesign from '@/views/admin/layout/ProcessDesign' |
| | | |
| | |
| | | }, |
| | | loadFormInfo(formId) { |
| | | let param = {"id": formId} |
| | | |
| | | //获取流程详情 |
| | | getFlowDetail(param).then(rsp => { |
| | | let form = rsp.data.data; |
| | |
| | | <div style="float: right"> |
| | | <el-button type="text" icon="el-icon-edit-outline" size="mini" @click="editFrom(item, groups)">编辑 |
| | | </el-button> |
| | | <el-button type="text" :icon="item.isStop ? 'el-icon-check':'el-icon-close'" size="mini" |
| | | @click="stopFrom(item)"> |
| | | {{ item.isStop ? '启用' : '停用' }} |
| | | </el-button> |
| | | |
| | | <el-button type="text" size="mini" @click="viewGroup(item,groups)">查看流程</el-button> |
| | | <el-button type="text" icon="el-icon-delete" size="mini" @click="moveFrom(item)" v-if="item.isStop">删除 |
| | | </el-button> |
| | | |
| | | <el-popover placement="left" trigger="click" width="400" style="margin-left: 10px" |
| | | @show="moveSelect === null" v-else> |
| | | @show="moveSelect === null" > |
| | | <el-radio-group v-model="moveSelect" size="mini"> |
| | | <el-radio :label="g.id" border v-for="g in groups" :key="g.id" v-show="g.id > 1" |
| | | :disabled="g.id === groups.id" style="margin: 10px;">{{ g.name }} |
| | |
| | | <script> |
| | | import draggable from "vuedraggable"; |
| | | import { |
| | | groupItemsSort, updateForm, getEntitySet |
| | | groupItemsSort, getEntitySet |
| | | } from '@/api/design' |
| | | |
| | | export default { |
| | |
| | | }).catch(err => this.$message.error('获取审批流程异常')) |
| | | }, |
| | | newProcess(groupId) { |
| | | this.$store.commit("setTemplate", this.getTemplateData()); |
| | | this.$store.commit("setIsEdit", false); |
| | | // this.$store.commit("setTemplate", this.getTemplateData()); |
| | | // this.$store.commit("setIsEdit", false); |
| | | this.$router.push("/admin/design?groupId=" + groupId); |
| | | }, |
| | | groupSort() { |
| | |
| | | ); |
| | | }, |
| | | |
| | | updateForm(item, type) { |
| | | updateForm({templateId: item.templateId, type: type}).then(rsp => { |
| | | this.$message.success(rsp.data) |
| | | this.getGroups() |
| | | }).catch(err => this.$message.error(err.response.data)) |
| | | }, |
| | | getTemplateData(data, group) { |
| | | return data |
| | | }, |
| | | |
| | | editFrom(item, group) { |
| | | console.log("item",item) |
| | | this.$router.push("/admin/design?code=" + item.id); |
| | | }, |
| | | stopFrom(item) { |
| | | console.log(item) |
| | | let tip = '是否删除此流程?'; |
| | | this.$confirm(`<span style="font-weight: bold">${item.name}</span>` + tip, '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | dangerouslyUseHTMLString: true, |
| | | }).then(() => { |
| | | this.updateForm(item, (item.isStop ? 'using' : 'stop')); |
| | | }) |
| | | }, |
| | | moveFrom(item) { |
| | | if (item.isStop) { |
| | | this.$confirm(`您确定要删除表单 <span style="font-weight: bold">${item.name}</span>> 吗,删除后无法恢复,是否继续?`, '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | dangerouslyUseHTMLString: true, |
| | | }).then(() => { |
| | | this.updateForm(item, 'delete'); |
| | | }) |
| | | } else { |
| | | if (this.moveSelect === null || this.moveSelect === '') { |
| | | this.$message.error('请选择分组') |
| | | return; |
| | | } |
| | | updateForm({templateId: item.templateId, type: 'move', groupId: this.moveSelect}).then(rsp => { |
| | | this.$message.success(rsp.data) |
| | | this.getGroups() |
| | | this.moveSelect = null |
| | | }).catch(err => this.$message.error(err.response.data)) |
| | | } |
| | | }, |
| | | |
| | | |
| | | } |
| | | } |
| | | </script> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <el-dialog title="请使用手机扫码预览" :visible.sync="viewCode" width="300px" :close-on-click-modal="false" center> |
| | | <img src="../../assets/image/code.png" width="250" height="250"> |
| | | </el-dialog> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | <template> |
| | | <el-main> |
| | | <div class="switchStyle"> |
| | | <el-button size="small" @click="switchCss" >切换</el-button> |
| | | <!-- <div class="switchStyle">--> |
| | | <!-- <el-button size="small" @click="switchCss" >切换</el-button>--> |
| | | |
| | | </div> |
| | | <!-- </div>--> |
| | | <div class="scale"> |
| | | <el-button icon="el-icon-plus" size="small" @click="scale += 10" :disabled="scale >= 150" circle></el-button> |
| | | <span>{{ scale }}%</span> |
| | |
| | | |
| | | }, |
| | | methods: { |
| | | switchCss(){ |
| | | |
| | | console.log(this.$cssSrc) |
| | | console.log(this.$isVertical) |
| | | |
| | | if(this.$isVertical){ |
| | | this.$cssSrc=require('@/assets/flowDesign.scss') |
| | | this.$isVertical=false; |
| | | }else{ |
| | | this.$cssSrc=require('@/assets/flowDesignVertical.scss') |
| | | this.$isVertical=true; |
| | | } |
| | | this.$forceUpdate() |
| | | |
| | | }, |
| | | // switchCss(){ |
| | | // |
| | | // console.log(this.$cssSrc) |
| | | // console.log(this.$isVertical) |
| | | // |
| | | // if(this.$isVertical){ |
| | | // this.$cssSrc=require('@/assets/flowDesign.scss') |
| | | // this.$isVertical=false; |
| | | // }else{ |
| | | // this.$cssSrc=require('@/assets/flowDesignVertical.scss') |
| | | // this.$isVertical=true; |
| | | // } |
| | | // this.$forceUpdate() |
| | | // |
| | | // }, |
| | | validate(){ |
| | | return this.$refs["process-tree"].validateProcess() |
| | | }, |
| | |
| | | <template> |
| | | <el-main> |
| | | <el-main style="overflow:auto;padding: 0px;height: 90vh"> |
| | | <div class="scale"> |
| | | <el-button icon="el-icon-plus" size="small" @click="scale += 10" :disabled="scale >= 150" circle></el-button> |
| | | <span>{{ scale }}%</span> |
| | | <el-button icon="el-icon-minus" size="small" @click="scale -= 10" :disabled="scale <= 40" circle></el-button> |
| | | </div> |
| | | <div class="design" :style="'transform: scale('+ scale / 100 +');'"> |
| | | <div class="design" :style="'transform: scale('+ scale / 100 +');transform-origin:left top'"> |
| | | <process-tree-viewer ref="process-tree" @selectedNode="nodeSelected"/> |
| | | </div> |
| | | <el-drawer :title="selectedNode.name" :visible.sync="showConfig" |
| | |
| | | components: { ProcessTreeViewer,NodeConfig }, |
| | | data() { |
| | | return { |
| | | scale: 100, |
| | | scale: 90, |
| | | selected: {}, |
| | | showInput: false, |
| | | showConfig: false |
| | |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" :src="$cssSrc" > |
| | | |
| | | <style lang="less" scoped> |
| | | ._root{ |
| | | margin: 0 auto; |
| | | } |
| | | .process-end{ |
| | | width: 60px; |
| | | margin: 0 auto; |
| | | margin-bottom: 20px; |
| | | border-radius: 15px; |
| | | padding: 5px 10px; |
| | | font-size: small; |
| | | color: #747474; |
| | | background-color: #f2f2f2; |
| | | box-shadow: 0 0 10px 0 #bcbcbc; |
| | | } |
| | | .primary-node{ |
| | | display: flex; |
| | | align-items: center; |
| | | flex-direction: column; |
| | | } |
| | | .branch-node{ |
| | | display: flex; |
| | | justify-content: center; |
| | | /*border-top: 2px solid #cccccc; |
| | | border-bottom: 2px solid #cccccc;*/ |
| | | } |
| | | .branch-node-item{ |
| | | position: relative; |
| | | display: flex; |
| | | background: #f5f6f6; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | border-top: 2px solid #cccccc; |
| | | border-bottom: 2px solid #cccccc; |
| | | &:before{ |
| | | content: ""; |
| | | position: absolute; |
| | | top: 0; |
| | | left: calc(50% - 1px); |
| | | margin: auto; |
| | | width: 2px; |
| | | height: 100%; |
| | | background-color: #CACACA; |
| | | } |
| | | .line-top-left, .line-top-right, .line-bot-left, .line-bot-right{ |
| | | position: absolute; |
| | | width: 50%; |
| | | height: 4px; |
| | | background-color: #f5f6f6; |
| | | } |
| | | .line-top-left{ |
| | | top: -2px; |
| | | left: -1px; |
| | | } |
| | | .line-top-right{ |
| | | top: -2px; |
| | | right: -1px; |
| | | } |
| | | .line-bot-left{ |
| | | bottom: -2px; |
| | | left: -1px; |
| | | } |
| | | .line-bot-right{ |
| | | bottom: -2px; |
| | | right: -1px; |
| | | } |
| | | } |
| | | .add-branch-btn{ |
| | | position: absolute; |
| | | width: 80px; |
| | | .add-branch-btn-el{ |
| | | z-index: 999; |
| | | position: absolute; |
| | | top: -15px; |
| | | } |
| | | } |
| | | |
| | | .empty-node{ |
| | | display: flex; |
| | | justify-content: center; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | </style> |
| | | |
| | |
| | | <script> |
| | | //导入所有节点组件 |
| | | import Approval from '@/views/common/process/nodes/ApprovalNode.vue' |
| | | import Task from '@/views/common/process/nodes/TaskNode.vue' |
| | | import Cc from '@/views/common/process/nodes/CcNode.vue' |
| | | import Concurrent from '@/views/common/process/nodes/ConcurrentNode.vue' |
| | | import Condition from '@/views/common/process/nodes/ConditionNode.vue' |
| | | import Inclusive from '@/views/common/process/nodes/InclusiveNode.vue' |
| | | import Trigger from '@/views/common/process/nodes/TriggerNode.vue' |
| | | import Delay from '@/views/common/process/nodes/DelayNode.vue' |
| | | import Empty from '@/views/common/process/nodes/EmptyNode.vue' |
| | | import Root from '@/views/common/process/nodes/RootNode.vue' |
| | | import Node from '@/views/common/process/nodes/Node.vue' |
| | | import Approval from '@/views/common/process/viewNodes/ApprovalNode.vue' |
| | | import Task from '@/views/common/process/viewNodes/TaskNode.vue' |
| | | import Cc from '@/views/common/process/viewNodes/CcNode.vue' |
| | | import Concurrent from '@/views/common/process/viewNodes/ConcurrentNode.vue' |
| | | import Condition from '@/views/common/process/viewNodes/ConditionNode.vue' |
| | | import Inclusive from '@/views/common/process/viewNodes/InclusiveNode.vue' |
| | | import Trigger from '@/views/common/process/viewNodes/TriggerNode.vue' |
| | | import Delay from '@/views/common/process/viewNodes/DelayNode.vue' |
| | | import Empty from '@/views/common/process/viewNodes/EmptyNode.vue' |
| | | import Root from '@/views/common/process/viewNodes/RootNode.vue' |
| | | import Node from '@/views/common/process/viewNodes/Node.vue' |
| | | |
| | | import DefaultProps from "./DefaultNodeProps" |
| | | |
| | |
| | | this.nodeMap.clear() |
| | | let processTrees = this.getDomTree(h, this.dom) |
| | | //插入末端节点 |
| | | processTrees.push(h('div', {style:{'text-align': 'center'}}, [ |
| | | processTrees.push(h('div', {class:{'end-class': true}}, [ |
| | | h('div', {class:{'process-end': true}, domProps: {innerHTML:'流程结束'}}) |
| | | ])) |
| | | return h('div', {class:{'_root': true}, ref:'_root'}, processTrees) |
| | |
| | | |
| | | //普通业务节点 |
| | | let childDoms = this.getDomTree(h, node.children) |
| | | |
| | | let headerBgc = '#ff943e' |
| | | let headerBgc = '#909399' |
| | | if (this.$store.state.runningList.includes(node.id)) { |
| | | headerBgc = '#1e90ff' |
| | | } |
| | |
| | | |
| | | <style lang="less" scoped> |
| | | ._root{ |
| | | margin: 0 auto; |
| | | display: flex; |
| | | align-items:center; |
| | | margin: 0 auto; |
| | | |
| | | } |
| | | .end-class { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | &:before { |
| | | content: ''; |
| | | top: 50%; |
| | | left: 100%; |
| | | display: block; |
| | | width: 0; |
| | | height: 0; |
| | | |
| | | border-style: solid; |
| | | border-color: #CACACA transparent transparent; |
| | | background: #F5F5F7; |
| | | border-top: 5px solid transparent; |
| | | border-bottom: 5px solid transparent; |
| | | border-left: 10px solid #CACACA; /* 左边界 */ |
| | | } |
| | | } |
| | | .process-end{ |
| | | width: 60px; |
| | | width: 100px; |
| | | height: 40px; |
| | | margin: 0 auto; |
| | | margin-bottom: 20px; |
| | | // margin-bottom: 20px; |
| | | border-radius: 15px; |
| | | padding: 5px 10px; |
| | | font-size: small; |
| | | //font-size: small; |
| | | color: #747474; |
| | | background-color: #f2f2f2; |
| | | box-shadow: 0 0 10px 0 #bcbcbc; |
| | | } |
| | | display: flex; |
| | | justify-content:center; |
| | | align-items: center; |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | .primary-node{ |
| | | display: flex; |
| | | align-items: center; |
| | | flex-direction: column; |
| | | flex-direction: row |
| | | } |
| | | .branch-node{ |
| | | display: flex; |
| | | justify-content: center; |
| | | /*border-top: 2px solid #cccccc; |
| | | border-bottom: 2px solid #cccccc;*/ |
| | | } |
| | | .branch-node-item{ |
| | | position: relative; |
| | |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | </style> |
| | |
| | | <div> |
| | | <el-form label-position="top" label-width="90px"> |
| | | <el-form-item label="⚙ 选择审批组或审批架构" prop="text" class="user-type"> |
| | | <el-select @change="selected(this,'group')" value-key="id" style="width: 80%;" size="small" v-model="nodeProps.approvalGroup" placeholder="请选择审批组"> |
| | | <el-option v-for="approvals in approvalGroups" :label="approvals.name" :value="approvals" :key="approvals.id"></el-option> |
| | | </el-select> |
| | | <el-select @change="selected(this,'group')" value-key="id" style="width: 80%;" size="small" |
| | | v-model="nodeProps.approvalGroup" placeholder="请选择审批组"> |
| | | <el-option v-for="approvals in approvalGroups" :label="approvals.name" :value="approvals" |
| | | :key="approvals.id"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="⚙ 选择审批组或审批架构" prop="text" class="user-type"> |
| | | <el-select @change="selected(this,'staff')" value-key="id" style="width: 80%;" size="small" v-model="nodeProps.staffGroup" placeholder="请选择审批架构"> |
| | | <el-option v-for="staffApprovals in staffGroups" :label="staffApprovals.name" :value="staffApprovals" :key="staffApprovals.id"></el-option> |
| | | <el-select @change="selected(this,'staff')" value-key="id" style="width: 80%;" size="small" |
| | | v-model="nodeProps.staffGroup" placeholder="请选择审批架构"> |
| | | <el-option v-for="staffApprovals in staffGroups" :label="staffApprovals.name" :value="staffApprovals" |
| | | :key="staffApprovals.id"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-divider></el-divider> |
| | | <el-form-item label="参数名"> |
| | | <el-input style="width: 80%;" placeholder="参数名" v-model="nodeProps.params" size="small" clearable /> |
| | | <el-input style="width: 80%;" placeholder="参数名" v-model="nodeProps.params" size="small" clearable/> |
| | | </el-form-item> |
| | | |
| | | <el-divider></el-divider> |
| | | <el-form-item label="触发事件"> |
| | | <div> |
| | | <el-button type="primary" size="mini" icon="el-icon-plus" style="margin: 0 15px 15px 0" round @click="addConditionGroup"> |
| | | <el-button type="primary" size="mini" icon="el-icon-plus" style="margin: 0 15px 15px 0" round |
| | | @click="addConditionGroup"> |
| | | 添加审批触发事件 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <div style="width: 100%" v-for="(group, index) in selectedNode.props.groups" :key="index + '_g'" class="group"> |
| | | <div class="group-header"> |
| | | <span class="group-name">触发事件{{index+1}}</span> |
| | | <span class="group-name">触发事件{{ index + 1 }}</span> |
| | | <i class="el-icon-delete" @click="delGroup(index)"></i> |
| | | |
| | | </div> |
| | | <el-row :gutter="10" > |
| | | <el-col :span="12"><el-select @change="selected(this)" size="small" v-model="group.action" placeholder="请选择审批组"> |
| | | <el-option v-for="actionItem in actions" :label="actionItem.label" :value="actionItem" :key="actionItem.value"></el-option> |
| | | </el-select> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="12"> |
| | | <el-select @change="selected(this)" size="small" v-model="group.action" placeholder="请选择审批组"> |
| | | <el-option v-for="actionItem in actions" :label="actionItem.label" :value="actionItem" |
| | | :key="actionItem.value"></el-option> |
| | | </el-select> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-input placeholder="排序" v-model="group.sort" size="small" clearable></el-input> |
| | | <el-input placeholder="排序" v-model="group.sort" size="small" clearable></el-input> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <span>java方法:</span> |
| | | </el-col> |
| | | <el-col :span="20"> |
| | | <el-input placeholder="java方法" v-model="group.method" size="small" clearable></el-input> |
| | | <el-input placeholder="java方法" v-model="group.method" size="small" clearable></el-input> |
| | | </el-col> |
| | | |
| | | |
| | | </el-row> |
| | | </div> |
| | | |
| | | </el-form-item> |
| | | <el-form-item label="🙅 如果办理被驳回 👇"> |
| | | <el-radio-group @input="setValue" v-model="nodeProps.refuse.type"> |
| | |
| | | </el-radio-group> |
| | | <div v-if="nodeProps.refuse.type === 'TO_NODE'"> |
| | | <span>指定节点:</span> |
| | | <el-select style="margin-left: 10px; width: 150px;" placeholder="选择跳转节点" size="small" v-model="nodeProps.refuse.target"> |
| | | <el-select style="margin-left: 10px; width: 150px;" placeholder="选择跳转节点" size="small" |
| | | v-model="nodeProps.refuse.target"> |
| | | <el-option v-for="(node, i) in nodeOptions" :key="i" :label="node.name" :value="node.id"></el-option> |
| | | </el-select> |
| | | </div> |
| | | |
| | | </el-form-item> |
| | | </el-form> |
| | | <org-picker :title="pickerTitle" multiple :type="orgPickerType" ref="orgPicker" :selected="orgPickerSelected" |
| | | @ok="selected"/> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import OrgPicker from "@/components/common/OrgPicker"; |
| | | import {getDict, getEntitySet} from "@/api/design"; |
| | | |
| | | |
| | | export default { |
| | | name: "ApprovalNodeConfig", |
| | | components: {OrgPicker}, |
| | |
| | | orgPickerSelected: [], |
| | | orgPickerType: 'user', |
| | | groupNames: ['1', '2', '3', '4', '6', 'F', 'G', 'H', 'I', 'J'], |
| | | approvalGroups:[ |
| | | // {"value":'first',"label":'地区经理审批'}, |
| | | // {"value":'secound',"label":'大区经理审批'}, |
| | | // {"value":'third',"label":'商务经理审批'}, |
| | | // {"value":'four',"label":'财务经理审批'}, |
| | | // {"value":'five',"label":'总经理审批'}, |
| | | approvalGroups: [ |
| | | ], |
| | | staffGroups:[], |
| | | actions:[ |
| | | {"value":'before',"label":'审批前'}, |
| | | {"value":'after',"label":'审批后'}, |
| | | staffGroups: [], |
| | | actions: [ |
| | | {"value": 'before', "label": '审批前'}, |
| | | {"value": 'after', "label": '审批后'}, |
| | | ], |
| | | approvalTypes: [ |
| | | {name: '指定人员', type: 'ASSIGN_USER'}, |
| | |
| | | }, |
| | | nodeProps() { |
| | | |
| | | // this.$store.state.selectedNode.props.staffGroup=this.$store.state.selectedNode.props.assignedUser[0] |
| | | // //this.$store.state.selectedNode.props.staffGroup.code="SalesDirector" |
| | | // //this.$store.state.selectedNode.props.staffGroup.id="position_sales_1" |
| | | // console.log("this.$store.state.selectedNode.props",this.$store.state.selectedNode.props) |
| | | return this.$store.state.selectedNode.props |
| | | }, |
| | | select() { |
| | | console.log("this.config--select",this.config) |
| | | console.log("this.config--select", this.config) |
| | | return this.config.assignedUser |
| | | }, |
| | | |
| | |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.getApprovalGroup(); |
| | | this.getStaffGroup(); |
| | | console.log("this.$store.state.selectedNode.props.staffGroup",this.$store.state.selectedNode.props.staffGroup) |
| | | this.getApprovalGroup(); |
| | | this.getStaffGroup(); |
| | | }, |
| | | methods: { |
| | | getApprovalGroup(){ |
| | | let template = {"dataname": "sys_state_board","attachMeta":true} |
| | | getApprovalGroup() { |
| | | let template = {"dataname": "sys_state_board", "attachMeta": true} |
| | | getEntitySet(template).then(rsp => { |
| | | console.log("getEntitySet", rsp.data.data) |
| | | this.approvalGroups = rsp.data.data.entityset |
| | | |
| | | console.log("this.approvalGroups", this.approvalGroups) |
| | | }).catch(err => this.$message.error('获取审批流程异常')) |
| | | }, |
| | | getStaffGroup(){ |
| | | let template = {"code":"position_sales"} |
| | | getStaffGroup() { |
| | | let template = {"code": "position_sales"} |
| | | getDict(template).then(rsp => { |
| | | console.log("getDict", rsp.data.data.dictionary) |
| | | this.staffGroups=this.$Utils.decode(rsp.data.data.dictionary.items) |
| | | this.staffGroups.forEach(item=>item.name=item.value); |
| | | this.staffGroups.forEach(item=>item.id=item.code); |
| | | console.log("getDict", this.staffGroups) |
| | | this.staffGroups = this.$Utils.decode(rsp.data.data.dictionary.items) |
| | | this.staffGroups.forEach(item => item.name = item.value); |
| | | this.staffGroups.forEach(item => item.id = item.code); |
| | | }).catch(err => this.$message.error('获取审批流程异常')) |
| | | }, |
| | | //如果切换选箱不是指定节点 那就把之前选择的指定节点信息 给清除掉 避免提交上去 |
| | | setValue(){ |
| | | if(this.nodeProps.refuse.type!=='TO_NODE'){ |
| | | this.nodeProps.refuse.target=''; |
| | | setValue() { |
| | | if (this.nodeProps.refuse.type !== 'TO_NODE') { |
| | | this.nodeProps.refuse.target = ''; |
| | | |
| | | } |
| | | } |
| | | }, |
| | | delGroup(index) { |
| | | this.selectedNode.props.groups.splice(index, 1) |
| | | }, |
| | | addConditionGroup() { |
| | | console.log("this.config",this.config) |
| | | console.log("this.config", this.config) |
| | | this.config.groups.push({ |
| | | // cids:[], |
| | | // groupType: "OR", |
| | | //conditions:[] |
| | | }) |
| | | }, |
| | | selected(select,type) { |
| | | console.log("输出选中select",this.nodeProps) |
| | | this.nodeProps.assignedUser=[] |
| | | selected(select, type) { |
| | | console.log("输出选中select", this.nodeProps) |
| | | this.nodeProps.assignedUser = [] |
| | | |
| | | if(type==='group'){ |
| | | this.nodeProps.staffGroup={} |
| | | if (type === 'group') { |
| | | this.nodeProps.staffGroup = {} |
| | | this.nodeProps.assignedUser.push({ |
| | | "id":this.nodeProps.approvalGroup.id, |
| | | "name":this.nodeProps.approvalGroup.name, |
| | | "type":"group" |
| | | "id": this.nodeProps.approvalGroup.id, |
| | | "name": this.nodeProps.approvalGroup.name, |
| | | "type": "group" |
| | | }) |
| | | }else{ |
| | | this.nodeProps.approvalGroup={} |
| | | } else { |
| | | this.nodeProps.approvalGroup = {} |
| | | this.nodeProps.assignedUser.push( |
| | | { |
| | | "id":this.nodeProps.staffGroup.code, |
| | | "name":this.nodeProps.staffGroup.value, |
| | | "type":"staff" |
| | | } |
| | | "id": this.nodeProps.staffGroup.code, |
| | | "name": this.nodeProps.staffGroup.value, |
| | | "type": "staff" |
| | | } |
| | | ) |
| | | } |
| | | console.log("assignedUser",this.config) |
| | | console.log("assignedUser", this.config) |
| | | console.log("this.config.props", this.config) |
| | | this.orgPickerSelected.length = 0 |
| | | }, |
| | | removeOrgItem(index) { |
| | |
| | | <style lang="less" scoped> |
| | | .el-row { |
| | | margin-bottom: 20px; |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .el-col { |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .user-type { |
| | | /deep/ .el-radio { |
| | | width: 110px; |
| | |
| | | } |
| | | }, |
| | | mounted(){ |
| | | this.getGroups() |
| | | |
| | | }, |
| | | methods: { |
| | | selectUser() { |
| | |
| | | removeOrgItem(index) { |
| | | this.select.splice(index, 1) |
| | | }, |
| | | getGroups(){ |
| | | // 简便 不使用迭代方法处理 |
| | | getFormGroups().then(rsp => { |
| | | var data = rsp.data |
| | | this.fromGroup = data.map(group => { |
| | | return { |
| | | value: group.id, |
| | | label: group.name, |
| | | children: group.items.map(item => { |
| | | return { |
| | | value: item.formId, |
| | | label: item.formName, |
| | | }; |
| | | }) |
| | | }; |
| | | }); |
| | | }).catch(err => this.$message.error('获取分组异常')) |
| | | }, |
| | | |
| | | handleChange(key){ |
| | | // 对值进行处理 |
| | | } |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | isV:this.$isVertical |
| | | } |
| | | }, |
| | | |
| | | |
| | | created() { |
| | | console.log("this.isV",this.flowText) |
| | | }, |
| | | methods: {} |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" :src="$cssSrc" scoped > |
| | | <style lang="less" scoped> |
| | | |
| | | .root { |
| | | &:before { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .node-error-state { |
| | | .node-body { |
| | | box-shadow: 0px 0px 5px 0px #F56C6C !important; |
| | | } |
| | | } |
| | | |
| | | .node { |
| | | padding: 0 50px; |
| | | width: 220px; |
| | | position: relative; |
| | | |
| | | &:before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: -12px; |
| | | left: 50%; |
| | | -webkit-transform: translateX(-50%); |
| | | transform: translateX(-50%); |
| | | width: 0; |
| | | border-style: solid; |
| | | border-width: 8px 6px 4px; |
| | | border-color: #CACACA transparent transparent; |
| | | background: #F5F5F7; |
| | | } |
| | | |
| | | .node-body { |
| | | cursor: pointer; |
| | | max-height: 120px; |
| | | position: relative; |
| | | border-radius: 5px; |
| | | background-color: white; |
| | | box-shadow: 0px 0px 5px 0px #d8d8d8; |
| | | |
| | | &:hover { |
| | | box-shadow: 0px 0px 3px 0px @theme-primary; |
| | | |
| | | .node-body-header { |
| | | .el-icon-close { |
| | | display: inline; |
| | | font-size: medium; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .node-body-header { |
| | | border-top-left-radius: 5px; |
| | | border-top-right-radius: 5px; |
| | | padding: 5px 15px; |
| | | color: white; |
| | | font-size: xx-small; |
| | | |
| | | .el-icon-close { |
| | | display: none; |
| | | } |
| | | |
| | | .name { |
| | | height: 14px; |
| | | width: 150px; |
| | | display: inline-block |
| | | } |
| | | } |
| | | |
| | | .node-body-content { |
| | | padding: 18px; |
| | | color: #656363; |
| | | font-size: 14px; |
| | | |
| | | i { |
| | | position: absolute; |
| | | top: 55%; |
| | | right: 5px; |
| | | font-size: medium; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #8c8c8c; |
| | | } |
| | | } |
| | | |
| | | .node-error { |
| | | position: absolute; |
| | | right: -40px; |
| | | top: 20px; |
| | | font-size: 25px; |
| | | color: #F56C6C; |
| | | } |
| | | } |
| | | |
| | | .node-footer { |
| | | position: relative; |
| | | |
| | | .btn { |
| | | width: 100%; |
| | | display: flex; |
| | | padding: 20px 0 32px; |
| | | justify-content: center; |
| | | } |
| | | |
| | | /deep/ .el-button { |
| | | height: 32px; |
| | | } |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | z-index: -1; |
| | | margin: auto; |
| | | width: 2px; |
| | | height: 100%; |
| | | background-color: #CACACA; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | |
New file |
| | |
| | | <template> |
| | | <node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo" |
| | | @selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)" |
| | | placeholder="请设置审批人" :header-bgc="headerBgc" header-icon="el-icon-s-check"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "ApprovalNode", |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | components: {Node}, |
| | | data() { |
| | | return { |
| | | showError: false, |
| | | errorInfo: '', |
| | | } |
| | | }, |
| | | computed:{ |
| | | headerBgc() { |
| | | if (this.$store.state.diagramMode === 'viewer') { |
| | | return this.config.props.headerBgc |
| | | } else { |
| | | return '#ff943e' |
| | | } |
| | | }, |
| | | content(){ |
| | | const config = this.config.props |
| | | console.log("content:config.assignedUser",config) |
| | | let texts = [] |
| | | config.assignedUser.forEach(org => texts.push(org.name)) |
| | | return String(texts).replaceAll(',', '、') |
| | | |
| | | }, |
| | | // flowText(){ |
| | | // const config = this.config |
| | | // console.log("flowText-config",config); |
| | | // |
| | | // // return config.approvalArr.filter(ite=>ite.node_id===config.id)[0].approval_time; |
| | | // if(config.approvalArr!==undefined){ |
| | | // return "发起时间:"+config.approvalArr.filter(ite=>ite.node_id===config.id)[0].approval_time; |
| | | // } |
| | | // |
| | | // return '' |
| | | // } |
| | | }, |
| | | created() { |
| | | console.log("加载ApprovalNode.vue") |
| | | }, |
| | | methods: { |
| | | getFormItemById(id){ |
| | | return this.$store.state.design.formItems.find(item => item.id === id) |
| | | }, |
| | | //校验数据配置的合法性 |
| | | validate(err){ |
| | | try { |
| | | this.showError = !this[`validate_${this.config.props.assignedType}`](err) |
| | | |
| | | if (this.config.props.nobody.handler === 'TO_USER' && this.config.props.nobody.assignedUser.length === 0) { |
| | | this.errorInfo = '审批人为空时, 转交给指定人员:【请指定一个具体的人】' |
| | | err.push('审批人为空时, 转交给指定人员:【请指定一个具体的人】') |
| | | this.showError = true |
| | | } |
| | | |
| | | return this.showError |
| | | } catch (e) { |
| | | return true; |
| | | } |
| | | }, |
| | | validate_ASSIGN_USER(err){ |
| | | if(this.config.props.assignedUser.length > 0){ |
| | | return true; |
| | | }else { |
| | | this.errorInfo = '请指定审批人员' |
| | | err.push(`${this.config.name} 未指定审批人员`) |
| | | return false |
| | | } |
| | | }, |
| | | validate_SELF_SELECT(err){ |
| | | return true; |
| | | }, |
| | | validate_LEADER_TOP(err){ |
| | | return true; |
| | | }, |
| | | validate_LEADER(err){ |
| | | return true; |
| | | }, |
| | | validate_ROLE(err){ |
| | | if (this.config.props.assignedUser.length <= 0){ |
| | | this.errorInfo = '请指定负责审批的系统角色' |
| | | err.push(`${this.config.name} 未指定审批角色`) |
| | | return false |
| | | } |
| | | return true; |
| | | }, |
| | | validate_SELF(err){ |
| | | return true; |
| | | }, |
| | | validate_FORM_USER(err){ |
| | | if (this.config.props.formUser === ''){ |
| | | this.errorInfo = '请指定表单中的人员组件' |
| | | err.push(`${this.config.name} 审批人为表单中人员,但未指定`) |
| | | return false |
| | | } |
| | | return true; |
| | | }, |
| | | validate_REFUSE(err){ |
| | | return true; |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo" |
| | | @selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)" |
| | | placeholder="请设置抄送人" header-bgc="#3296fa" header-icon="el-icon-s-promotion"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "CcNode", |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | components: {Node}, |
| | | data() { |
| | | return { |
| | | showError: false, |
| | | errorInfo: '', |
| | | } |
| | | }, |
| | | computed:{ |
| | | content() { |
| | | if (this.config.props.shouldAdd){ |
| | | return '由发起人指定' |
| | | }else if (this.config.props.assignedUser.length > 0) { |
| | | let texts = [] |
| | | this.config.props.assignedUser.forEach(org => texts.push(org.name)) |
| | | return String(texts).replaceAll(',', '、') |
| | | } else { |
| | | return null |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | //校验数据配置的合法性 |
| | | validate(err){ |
| | | this.showError = false |
| | | if(this.config.props.shouldAdd){ |
| | | this.showError = false |
| | | }else if(this.config.props.assignedUser.length === 0){ |
| | | this.showError = true |
| | | this.errorInfo = '请选择需要抄送的人员' |
| | | } |
| | | if (this.showError){ |
| | | err.push(`抄送节点 ${this.config.name} 未设置抄送人`) |
| | | } |
| | | return !this.showError |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="node"> |
| | | <div class="node-body" @click="$emit('selected')"> |
| | | <div class="node-body-left" @click.stop="$emit('leftMove')" v-if="level > 1" v-show="$store.state.diagramMode !== 'viewer'"> |
| | | <i class="el-icon-arrow-left"></i> |
| | | </div> |
| | | <div class="node-body-main"> |
| | | <div class="node-body-main-header"> |
| | | <span class="title"> |
| | | <i class="el-icon-s-operation"></i> |
| | | <ellipsis class="name" hover-tip :content="config.name ? config.name:('并行任务' + level)"/> |
| | | </span> |
| | | <span class="option" v-show="$store.state.diagramMode !== 'viewer'"> |
| | | <el-tooltip effect="dark" content="复制分支" placement="top"> |
| | | <i class="el-icon-copy-document" @click="$emit('copy')"></i> |
| | | </el-tooltip> |
| | | <i class="el-icon-close" @click.stop="$emit('delNode')"></i> |
| | | </span> |
| | | </div> |
| | | <div class="node-body-main-content"> |
| | | <span>并行任务(同时进行)</span> |
| | | </div> |
| | | </div> |
| | | <div class="node-body-right" @click.stop="$emit('rightMove')" v-if="level < size" v-show="$store.state.diagramMode !== 'viewer'"> |
| | | <i class="el-icon-arrow-right"></i> |
| | | </div> |
| | | </div> |
| | | <div class="node-footer"> |
| | | <div class="btn"> |
| | | <insert-button v-show="$store.state.diagramMode !== 'viewer'" @insertNode="type => $emit('insertNode', type)"></insert-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import InsertButton from '@/views/common/InsertButton.vue' |
| | | |
| | | export default { |
| | | name: "ConcurrentNode", |
| | | components: {InsertButton}, |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | }, |
| | | level:{ |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | //条件数 |
| | | size:{ |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | |
| | | } |
| | | }, |
| | | methods: {} |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | |
| | | |
| | | .node{ |
| | | padding: 30px 55px 0; |
| | | width: 220px; |
| | | .node-body{ |
| | | overflow: hidden; |
| | | cursor: pointer; |
| | | min-height: 80px; |
| | | max-height: 120px; |
| | | position: relative; |
| | | border-radius: 5px; |
| | | background-color: white; |
| | | box-shadow: 0px 0px 5px 0px #d8d8d8; |
| | | &:hover{ |
| | | .node-body-left, .node-body-right{ |
| | | i{ |
| | | display: block !important; |
| | | } |
| | | } |
| | | .node-body-main { |
| | | .option{ |
| | | display: inline-block !important; |
| | | } |
| | | } |
| | | box-shadow: 0px 0px 3px 0px @theme-primary; |
| | | } |
| | | .node-body-left, .node-body-right{ |
| | | display: flex; |
| | | align-items: center; |
| | | position: absolute; |
| | | height: 100%; |
| | | i{ |
| | | display: none; |
| | | } |
| | | &:hover{ |
| | | background-color: #ececec; |
| | | } |
| | | } |
| | | .node-body-left{ |
| | | left: 0; |
| | | } |
| | | .node-body-right{ |
| | | right: 0; |
| | | } |
| | | .node-body-main { |
| | | position: absolute; |
| | | width: 188px; |
| | | left: 17px; |
| | | display: inline-block; |
| | | |
| | | .node-body-main-header{ |
| | | padding: 10px 0px 5px; |
| | | font-size: xx-small; |
| | | position: relative; |
| | | .title{ |
| | | color: #718dff; |
| | | .name{ |
| | | display: inline-block; |
| | | height: 14px; |
| | | width: 130px; |
| | | margin-left: 2px; |
| | | } |
| | | } |
| | | .option{ |
| | | position: absolute; |
| | | right: 0; |
| | | display: none; |
| | | font-size: medium; |
| | | i{ |
| | | color: #888888; |
| | | padding: 0 3px; |
| | | } |
| | | } |
| | | } |
| | | .node-body-main-content { |
| | | padding: 6px; |
| | | color: #656363; |
| | | font-size: 14px; |
| | | |
| | | i { |
| | | position: absolute; |
| | | top: 55%; |
| | | right: 10px; |
| | | font-size: medium; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .node-footer{ |
| | | position: relative; |
| | | .btn{ |
| | | width: 100%; |
| | | display: flex; |
| | | height: 70px; |
| | | padding: 20px 0 32px; |
| | | justify-content: center; |
| | | } |
| | | /deep/ .el-button{ |
| | | height: 32px; |
| | | } |
| | | &::before{ |
| | | content: ""; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | z-index: -1; |
| | | margin: auto; |
| | | width: 2px; |
| | | height: 100%; |
| | | background-color: #CACACA; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div :class="{'node': true, 'node-error-state': showError}"> |
| | | <div :class="{'node-body': true, 'error': showError}"> |
| | | <div class="node-body-left" @click="$emit('leftMove')" v-if="level > 1 && $store.state.diagramMode !== 'viewer'"> |
| | | <i class="el-icon-arrow-left"></i> |
| | | </div> |
| | | <div class="node-body-main" @click="$emit('selected')"> |
| | | <div class="node-body-main-header"> |
| | | <ellipsis class="title" hover-tip :content="config.name ? config.name : ('条件' + level)"/> |
| | | <span class="level">优先级{{ level }}</span> |
| | | <span class="option" v-if="$store.state.diagramMode !== 'viewer'"> |
| | | <el-tooltip effect="dark" content="复制条件" placement="top"> |
| | | <i class="el-icon-copy-document" @click.stop="$emit('copy')"></i> |
| | | </el-tooltip> |
| | | <i class="el-icon-close" @click.stop="$emit('delNode')"></i> |
| | | </span> |
| | | </div> |
| | | <div class="node-body-main-content"> |
| | | <span class="placeholder" v-if="(content || '').trim() === ''">{{ |
| | | level == size && size != 0 ? "其他条件进入此流程" : placeholder |
| | | }}</span> |
| | | <ellipsis hoverTip :row="4" :content="content" v-else/> |
| | | </div> |
| | | </div> |
| | | <div class="node-body-right" @click="$emit('rightMove')" |
| | | v-if="level < size && $store.state.diagramMode !== 'viewer'"> |
| | | <i class="el-icon-arrow-right"></i> |
| | | </div> |
| | | <div class="node-error" v-if="showError"> |
| | | <el-tooltip effect="dark" :content="errorInfo" placement="top-start"> |
| | | <i class="el-icon-warning-outline"></i> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | <div class="node-footer"> |
| | | <div class="btn"> |
| | | <insert-button v-if="$store.state.diagramMode !== 'viewer'" |
| | | @insertNode="type => $emit('insertNode', type)"></insert-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import InsertButton from '@/views/common/InsertButton.vue' |
| | | import {ValueType} from '@/views/common/ComponentsConfigExport' |
| | | const groupNames = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']; |
| | | export default { |
| | | name: "ConditionNode", |
| | | components: {InsertButton}, |
| | | props: { |
| | | config: { |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | }, |
| | | //索引位置 |
| | | level: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | //条件数 |
| | | size: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | ValueType, |
| | | groupNames, |
| | | placeholder: '请设置条件', |
| | | errorInfo: '', |
| | | showError: false |
| | | } |
| | | }, |
| | | computed: { |
| | | content() { |
| | | const groups = this.config.props.groups |
| | | let confitions = [] |
| | | groups.forEach(group => { |
| | | let subConditions = [] |
| | | group.conditions.forEach(subCondition => { |
| | | let subConditionStr = '' |
| | | switch (subCondition.valueType) { |
| | | case ValueType.dept: |
| | | case ValueType.user: |
| | | subConditionStr = `${subCondition.title}属于[${String(subCondition.value.map(u => u.name)).replaceAll(',', '. ')}]之一` |
| | | break; |
| | | case ValueType.number: |
| | | case ValueType.string: |
| | | subConditionStr = this.getOrdinaryConditionContent(subCondition) |
| | | break; |
| | | } |
| | | subConditions.push(subConditionStr) |
| | | }) |
| | | //根据子条件关系构建描述 |
| | | let subConditionsStr = String(subConditions) |
| | | .replaceAll(',', subConditions.length > 1 ? |
| | | (group.groupType === 'AND' ? ') 且 (' : ') 或 (') : |
| | | (group.groupType === 'AND' ? ' 且 ' : ' 或 ')) |
| | | confitions.push(subConditions.length > 1 ? `(${subConditionsStr})` : subConditionsStr) |
| | | }) |
| | | //构建最终描述 |
| | | return String(confitions).replaceAll(',', (this.config.props.groupsType === 'AND' ? ' 且 ' : ' 或 ')) |
| | | } |
| | | }, |
| | | methods: { |
| | | getDefault(val, df) { |
| | | return val && val !== '' ? val : df; |
| | | }, |
| | | getOrdinaryConditionContent(subCondition) { |
| | | |
| | | switch (subCondition.compare) { |
| | | case 'IN': |
| | | let items = subCondition.value.map(function (item) { |
| | | return item.label |
| | | }) |
| | | console.log("subCondition",String(items)) |
| | | return `${subCondition.title}为[${String(items).replaceAll(',', '、')}]中之一` |
| | | case 'B': |
| | | return `${subCondition.value[0]} < ${subCondition.title} < ${subCondition.value[1]}` |
| | | case 'AB': |
| | | return `${subCondition.value[0]} ≤ ${subCondition.title} < ${subCondition.value[1]}` |
| | | case 'BA': |
| | | return `${subCondition.value[0]} < ${subCondition.title} ≤ ${subCondition.value[1]}` |
| | | case 'ABA': |
| | | return `${subCondition.value[0]} ≤ ${subCondition.title} ≤ ${subCondition.value[1]}` |
| | | case '<=': |
| | | return `${subCondition.title} ≤ ${this.getDefault(subCondition.value[0], ' ?')}` |
| | | case '>=': |
| | | return `${subCondition.title} ≥ ${this.getDefault(subCondition.value[0], ' ?')}` |
| | | default: |
| | | return `${subCondition.title}${subCondition.compare}${this.getDefault(subCondition.value[0], ' ?')}` |
| | | } |
| | | }, |
| | | //校验数据配置的合法性 |
| | | validate(err) { |
| | | console.log('condition children', this.config.children) |
| | | console.log('this.level', this.level) |
| | | console.log('this.size', this.size) |
| | | if (!(this.level == this.size && this.size != 0) && !this.config.children?.id) { |
| | | this.showError = true |
| | | this.errorInfo = '条件分支后不能为空' |
| | | err.push(`条件分支后不能为空`) |
| | | return !this.showError |
| | | } |
| | | |
| | | const props = this.config.props |
| | | if (props.groups.length <= 0){ |
| | | this.showError = true |
| | | this.errorInfo = '请设置分支条件' |
| | | err.push(`${this.config.name} 未设置条件`) |
| | | }else { |
| | | if (!(this.level == this.size && this.size != 0)) { |
| | | for (let i = 0; i < props.groups.length; i++) { |
| | | if (props.groups[i].cids.length === 0){ |
| | | this.showError = true |
| | | this.errorInfo = `请设置条件组${this.groupNames[i]}内的条件` |
| | | err.push(`条件 ${this.config.name} 条件组${this.groupNames[i]}内未设置条件`) |
| | | break |
| | | }else { |
| | | let conditions = props.groups[i].conditions |
| | | for (let ci = 0; ci < conditions.length; ci++) { |
| | | let subc = conditions[ci] |
| | | if (subc.value.length === 0){ |
| | | this.showError = true |
| | | }else { |
| | | this.showError = false |
| | | } |
| | | if (this.showError){ |
| | | this.errorInfo = `请完善条件组${this.groupNames[i]}内的${subc.title}条件` |
| | | err.push(`条件 ${this.config.name} 条件组${this.groupNames[i]}内${subc.title}条件未完善`) |
| | | return false |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return !this.showError; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | |
| | | |
| | | .node-error-state { |
| | | .node-body { |
| | | box-shadow: 0px 0px 5px 0px #F56C6C !important; |
| | | } |
| | | } |
| | | |
| | | .node { |
| | | padding: 30px 55px 0; |
| | | width: 220px; |
| | | |
| | | .node-body { |
| | | cursor: pointer; |
| | | min-height: 80px; |
| | | max-height: 120px; |
| | | position: relative; |
| | | border-radius: 5px; |
| | | background-color: white; |
| | | box-shadow: 0px 0px 5px 0px #d8d8d8; |
| | | |
| | | &:hover { |
| | | .node-body-left, .node-body-right { |
| | | i { |
| | | display: block !important; |
| | | } |
| | | } |
| | | |
| | | .node-body-main { |
| | | .level { |
| | | display: none !important; |
| | | } |
| | | |
| | | .option { |
| | | display: inline-block !important; |
| | | } |
| | | } |
| | | |
| | | box-shadow: 0px 0px 3px 0px @theme-primary; |
| | | } |
| | | |
| | | .node-body-left, .node-body-right { |
| | | display: flex; |
| | | align-items: center; |
| | | position: absolute; |
| | | height: 100%; |
| | | |
| | | i { |
| | | display: none; |
| | | } |
| | | |
| | | &:hover { |
| | | background-color: #ececec; |
| | | } |
| | | } |
| | | |
| | | .node-body-left { |
| | | left: 0; |
| | | } |
| | | |
| | | .node-body-right { |
| | | right: 0; |
| | | top: 0; |
| | | } |
| | | |
| | | .node-body-main { |
| | | //position: absolute; |
| | | width: 188px; |
| | | margin-left: 17px; |
| | | display: inline-block; |
| | | |
| | | .node-body-main-header { |
| | | padding: 10px 0px 5px; |
| | | font-size: xx-small; |
| | | position: relative; |
| | | |
| | | .title { |
| | | color: #15bca3; |
| | | display: inline-block; |
| | | height: 14px; |
| | | width: 125px; |
| | | } |
| | | |
| | | .level { |
| | | position: absolute; |
| | | right: 15px; |
| | | color: #888888; |
| | | } |
| | | |
| | | .option { |
| | | position: absolute; |
| | | right: 0; |
| | | display: none; |
| | | font-size: medium; |
| | | |
| | | i { |
| | | color: #888888; |
| | | padding: 0 3px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .node-body-main-content { |
| | | padding: 6px; |
| | | color: #656363; |
| | | font-size: 14px; |
| | | |
| | | i { |
| | | position: absolute; |
| | | top: 55%; |
| | | right: 10px; |
| | | font-size: medium; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #8c8c8c; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .node-error { |
| | | position: absolute; |
| | | right: -40px; |
| | | top: 20px; |
| | | font-size: 25px; |
| | | color: #F56C6C; |
| | | } |
| | | } |
| | | |
| | | .node-footer { |
| | | position: relative; |
| | | |
| | | .btn { |
| | | width: 100%; |
| | | display: flex; |
| | | height: 70px; |
| | | padding: 20px 0 32px; |
| | | justify-content: center; |
| | | } |
| | | |
| | | /deep/ .el-button { |
| | | height: 32px; |
| | | } |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | z-index: -1; |
| | | margin: auto; |
| | | width: 2px; |
| | | height: 100%; |
| | | background-color: #CACACA; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo" |
| | | @selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)" |
| | | placeholder="请设置延时时间" header-bgc="#f25643" header-icon="el-icon-time"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "DelayNode", |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | components: {Node}, |
| | | data() { |
| | | return { |
| | | showError: false, |
| | | errorInfo: '', |
| | | } |
| | | }, |
| | | computed:{ |
| | | content(){ |
| | | if (this.config.props.type === 'FIXED'){ |
| | | return `等待 ${this.config.props.time} ${this.getName(this.config.props.unit)}` |
| | | }else if(this.config.props.type === 'AUTO'){ |
| | | return `至当天 ${this.config.props.dateTime}` |
| | | }else { |
| | | return null |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | //校验数据配置的合法性 |
| | | validate(err){ |
| | | this.showError = false |
| | | try { |
| | | if (this.config.props.type === "AUTO") { |
| | | if ((this.config.props.dateTime || "") === ""){ |
| | | this.showError = true |
| | | this.errorInfo = "请选择时间点" |
| | | } |
| | | } else { |
| | | if (this.config.props.time <= 0) { |
| | | this.showError = true |
| | | this.errorInfo = "请设置延时时长" |
| | | } |
| | | } |
| | | } catch (e) { |
| | | this.showError = true |
| | | this.errorInfo = "配置出现问题" |
| | | } |
| | | if (this.showError){ |
| | | err.push(`${this.config.name} 未设置延时规则`) |
| | | } |
| | | return !this.showError |
| | | }, |
| | | getName(unit){ |
| | | switch (unit){ |
| | | case 'D': return '天'; |
| | | case 'H': return '小时'; |
| | | case 'M': return '分钟'; |
| | | default: return '未知'; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <node :show="false" @insertNode="type => $emit('insertNode', type)"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "EmptyNode", |
| | | components: {Node}, |
| | | data() { |
| | | return {} |
| | | }, |
| | | methods: {} |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div :class="{'node': true, 'node-error-state': showError}"> |
| | | <div :class="{'node-body': true, 'error': showError}"> |
| | | <div class="node-body-left" @click="$emit('leftMove')" v-if="level > 1 && $store.state.diagramMode !== 'viewer'"> |
| | | <i class="el-icon-arrow-left"></i> |
| | | </div> |
| | | <div class="node-body-main" @click="$emit('selected')"> |
| | | <div class="node-body-main-header"> |
| | | <ellipsis class="title" hover-tip :content="config.name ? config.name : ('条件' + level)"/> |
| | | <span class="level">优先级{{ level }}</span> |
| | | <span class="option" v-if="$store.state.diagramMode !== 'viewer'"> |
| | | <el-tooltip effect="dark" content="复制条件" placement="top"> |
| | | <i class="el-icon-copy-document" @click.stop="$emit('copy')"></i> |
| | | </el-tooltip> |
| | | <i class="el-icon-close" @click.stop="$emit('delNode')"></i> |
| | | </span> |
| | | </div> |
| | | <div class="node-body-main-content"> |
| | | <span class="placeholder" v-if="(content || '').trim() === ''">{{ |
| | | level == size && size != 0 ? "其他条件进入此流程" : placeholder |
| | | }}</span> |
| | | <ellipsis hoverTip :row="4" :content="content" v-else/> |
| | | </div> |
| | | </div> |
| | | <div class="node-body-right" @click="$emit('rightMove')" |
| | | v-if="level < size && $store.state.diagramMode !== 'viewer'"> |
| | | <i class="el-icon-arrow-right"></i> |
| | | </div> |
| | | <div class="node-error" v-if="showError"> |
| | | <el-tooltip effect="dark" :content="errorInfo" placement="top-start"> |
| | | <i class="el-icon-warning-outline"></i> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | <div class="node-footer"> |
| | | <div class="btn"> |
| | | <insert-button v-if="$store.state.diagramMode !== 'viewer'" |
| | | @insertNode="type => $emit('insertNode', type)"></insert-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import InsertButton from '@/views/common/InsertButton.vue' |
| | | import {ValueType} from '@/views/common/ComponentsConfigExport' |
| | | const groupNames = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']; |
| | | export default { |
| | | name: "InclusiveNode", |
| | | components: {InsertButton}, |
| | | props: { |
| | | config: { |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | }, |
| | | //索引位置 |
| | | level: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | //条件数 |
| | | size: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | ValueType, |
| | | groupNames, |
| | | placeholder: '请设置条件', |
| | | errorInfo: '', |
| | | showError: false |
| | | } |
| | | }, |
| | | computed: { |
| | | content() { |
| | | const groups = this.config.props.groups |
| | | let confitions = [] |
| | | groups.forEach(group => { |
| | | let subConditions = [] |
| | | group.conditions.forEach(subCondition => { |
| | | let subConditionStr = '' |
| | | switch (subCondition.valueType) { |
| | | case ValueType.dept: |
| | | case ValueType.user: |
| | | subConditionStr = `${subCondition.title}属于[${String(subCondition.value.map(u => u.name)).replaceAll(',', '. ')}]之一` |
| | | break; |
| | | case ValueType.number: |
| | | case ValueType.string: |
| | | subConditionStr = this.getOrdinaryConditionContent(subCondition) |
| | | break; |
| | | } |
| | | subConditions.push(subConditionStr) |
| | | }) |
| | | //根据子条件关系构建描述 |
| | | let subConditionsStr = String(subConditions) |
| | | .replaceAll(',', subConditions.length > 1 ? |
| | | (group.groupType === 'AND' ? ') 且 (' : ') 或 (') : |
| | | (group.groupType === 'AND' ? ' 且 ' : ' 或 ')) |
| | | confitions.push(subConditions.length > 1 ? `(${subConditionsStr})` : subConditionsStr) |
| | | }) |
| | | //构建最终描述 |
| | | return String(confitions).replaceAll(',', (this.config.props.groupsType === 'AND' ? ' 且 ' : ' 或 ')) |
| | | } |
| | | }, |
| | | methods: { |
| | | getDefault(val, df) { |
| | | return val && val !== '' ? val : df; |
| | | }, |
| | | getOrdinaryConditionContent(subCondition) { |
| | | switch (subCondition.compare) { |
| | | case 'IN': |
| | | return `${subCondition.title}为[${String(subCondition.value).replaceAll(',', '、')}]中之一` |
| | | case 'B': |
| | | return `${subCondition.value[0]} < ${subCondition.title} < ${subCondition.value[1]}` |
| | | case 'AB': |
| | | return `${subCondition.value[0]} ≤ ${subCondition.title} < ${subCondition.value[1]}` |
| | | case 'BA': |
| | | return `${subCondition.value[0]} < ${subCondition.title} ≤ ${subCondition.value[1]}` |
| | | case 'ABA': |
| | | return `${subCondition.value[0]} ≤ ${subCondition.title} ≤ ${subCondition.value[1]}` |
| | | case '<=': |
| | | return `${subCondition.title} ≤ ${this.getDefault(subCondition.value[0], ' ?')}` |
| | | case '>=': |
| | | return `${subCondition.title} ≥ ${this.getDefault(subCondition.value[0], ' ?')}` |
| | | default: |
| | | return `${subCondition.title}${subCondition.compare}${this.getDefault(subCondition.value[0], ' ?')}` |
| | | } |
| | | }, |
| | | //校验数据配置的合法性 |
| | | validate(err) { |
| | | console.log('inclusive children', this.config.children) |
| | | if (!(this.level == this.size && this.size != 0) && !this.config.children?.id) { |
| | | this.showError = true |
| | | this.errorInfo = '条件分支后不能为空' |
| | | err.push(`条件分支后不能为空`) |
| | | return !this.showError |
| | | } |
| | | |
| | | const props = this.config.props |
| | | if (props.groups.length <= 0){ |
| | | this.showError = true |
| | | this.errorInfo = '请设置分支条件' |
| | | err.push(`${this.config.name} 未设置条件`) |
| | | }else { |
| | | if (!(this.level == this.size && this.size != 0)) { |
| | | for (let i = 0; i < props.groups.length; i++) { |
| | | if (props.groups[i].cids.length === 0){ |
| | | this.showError = true |
| | | this.errorInfo = `请设置条件组${this.groupNames[i]}内的条件` |
| | | err.push(`条件 ${this.config.name} 条件组${this.groupNames[i]}内未设置条件`) |
| | | break |
| | | }else { |
| | | let conditions = props.groups[i].conditions |
| | | for (let ci = 0; ci < conditions.length; ci++) { |
| | | let subc = conditions[ci] |
| | | if (subc.value.length === 0){ |
| | | this.showError = true |
| | | }else { |
| | | this.showError = false |
| | | } |
| | | if (this.showError){ |
| | | this.errorInfo = `请完善条件组${this.groupNames[i]}内的${subc.title}条件` |
| | | err.push(`条件 ${this.config.name} 条件组${this.groupNames[i]}内${subc.title}条件未完善`) |
| | | return false |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return !this.showError; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | |
| | | |
| | | .node-error-state { |
| | | .node-body { |
| | | box-shadow: 0px 0px 5px 0px #F56C6C !important; |
| | | } |
| | | } |
| | | |
| | | .node { |
| | | padding: 30px 55px 0; |
| | | width: 220px; |
| | | |
| | | .node-body { |
| | | cursor: pointer; |
| | | min-height: 80px; |
| | | max-height: 120px; |
| | | position: relative; |
| | | border-radius: 5px; |
| | | background-color: white; |
| | | box-shadow: 0px 0px 5px 0px #d8d8d8; |
| | | |
| | | &:hover { |
| | | .node-body-left, .node-body-right { |
| | | i { |
| | | display: block !important; |
| | | } |
| | | } |
| | | |
| | | .node-body-main { |
| | | .level { |
| | | display: none !important; |
| | | } |
| | | |
| | | .option { |
| | | display: inline-block !important; |
| | | } |
| | | } |
| | | |
| | | box-shadow: 0px 0px 3px 0px @theme-primary; |
| | | } |
| | | |
| | | .node-body-left, .node-body-right { |
| | | display: flex; |
| | | align-items: center; |
| | | position: absolute; |
| | | height: 100%; |
| | | |
| | | i { |
| | | display: none; |
| | | } |
| | | |
| | | &:hover { |
| | | background-color: #ececec; |
| | | } |
| | | } |
| | | |
| | | .node-body-left { |
| | | left: 0; |
| | | } |
| | | |
| | | .node-body-right { |
| | | right: 0; |
| | | top: 0; |
| | | } |
| | | |
| | | .node-body-main { |
| | | //position: absolute; |
| | | width: 188px; |
| | | margin-left: 17px; |
| | | display: inline-block; |
| | | |
| | | .node-body-main-header { |
| | | padding: 10px 0px 5px; |
| | | font-size: xx-small; |
| | | position: relative; |
| | | |
| | | .title { |
| | | color: #425c9d; |
| | | display: inline-block; |
| | | height: 14px; |
| | | width: 125px; |
| | | } |
| | | |
| | | .level { |
| | | position: absolute; |
| | | right: 15px; |
| | | color: #888888; |
| | | } |
| | | |
| | | .option { |
| | | position: absolute; |
| | | right: 0; |
| | | display: none; |
| | | font-size: medium; |
| | | |
| | | i { |
| | | color: #888888; |
| | | padding: 0 3px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .node-body-main-content { |
| | | padding: 6px; |
| | | color: #656363; |
| | | font-size: 14px; |
| | | |
| | | i { |
| | | position: absolute; |
| | | top: 55%; |
| | | right: 10px; |
| | | font-size: medium; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #8c8c8c; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .node-error { |
| | | position: absolute; |
| | | right: -40px; |
| | | top: 20px; |
| | | font-size: 25px; |
| | | color: #F56C6C; |
| | | } |
| | | } |
| | | |
| | | .node-footer { |
| | | position: relative; |
| | | |
| | | .btn { |
| | | width: 100%; |
| | | display: flex; |
| | | height: 70px; |
| | | padding: 20px 0 32px; |
| | | justify-content: center; |
| | | } |
| | | |
| | | /deep/ .el-button { |
| | | height: 32px; |
| | | } |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | z-index: -1; |
| | | margin: auto; |
| | | width: 2px; |
| | | height: 100%; |
| | | background-color: #CACACA; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div :class="{ 'nodeView':true, 'root': isRoot || !show, 'node-error-state': showError}"> |
| | | <div v-if="show" @click="$emit('selected')" :class="{'node-body': true, 'error': showError}" > |
| | | <div> |
| | | <div class="node-body-header" :style="{'background-color': headerBgc}"> |
| | | <i :class="headerIcon" style="margin-right: 5px" v-if="(headerIcon || '') !== ''"></i> |
| | | <ellipsis class="name" hover-tip :content="title"/> |
| | | <i class="el-icon-close" v-if="!isRoot && $store.state.diagramMode !== 'viewer'" style="float:right;" @click="$emit('delNode')"></i> |
| | | </div> |
| | | <div class="node-body-content"> |
| | | <i :class="leftIcon" v-if="leftIcon"></i> |
| | | <span class="placeholder" v-if="(content || '').trim() === ''">{{placeholder}}</span> |
| | | <ellipsis :row="3" :content="content" v-else/> |
| | | <i class="el-icon-arrow-right" v-if="$store.state.diagramMode !== 'viewer'" ></i> |
| | | </div> |
| | | <div class="node-error" v-if="showError"> |
| | | |
| | | <el-tooltip effect="dark" :content="errorInfo" placement="top-start"> |
| | | <i class="el-icon-warning-outline"></i> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="node-footer"> |
| | | <div class="btn"> |
| | | <insert-button v-show="$store.state.diagramMode !== 'viewer'" @insertNode="type => $emit('insertNode', type)"></insert-button> |
| | | |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | import InsertButton from '@/views/common/InsertButton.vue' |
| | | |
| | | |
| | | export default { |
| | | name: "NodeView", |
| | | components: {InsertButton}, |
| | | props:{ |
| | | //是否为根节点 |
| | | isRoot: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | //是否显示节点体 |
| | | show: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | //节点内容区域文字 |
| | | content: { |
| | | type: String, |
| | | default: "" |
| | | }, |
| | | title:{ |
| | | type: String, |
| | | default: "标题" |
| | | }, |
| | | placeholder:{ |
| | | type: String, |
| | | default: "请设置" |
| | | }, |
| | | flowText:{ |
| | | type: String, |
| | | default: "" |
| | | }, |
| | | //节点体左侧图标 |
| | | leftIcon: { |
| | | type: String, |
| | | default: undefined |
| | | }, |
| | | //头部图标 |
| | | headerIcon:{ |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | //头部背景色 |
| | | headerBgc:{ |
| | | type: String, |
| | | default: '#576a95' |
| | | }, |
| | | //是否显示错误状态 |
| | | showError:{ |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | errorInfo:{ |
| | | type: String, |
| | | default: '无信息' |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | } |
| | | }, |
| | | |
| | | |
| | | created() { |
| | | }, |
| | | methods: {} |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .root{ |
| | | &:before{ |
| | | display: none !important; |
| | | } |
| | | } |
| | | .node-error-state{ |
| | | &.node-body{ |
| | | box-shadow: 0px 0px 5px 0px #F56C6C !important; |
| | | } |
| | | } |
| | | .nodeView{ |
| | | display: flex; |
| | | align-items:center; |
| | | width: auto; |
| | | position: relative; |
| | | &:before{ |
| | | content: ''; |
| | | top: 50%; |
| | | left: 100%; |
| | | display: block; |
| | | width: 0; |
| | | height: 0; |
| | | |
| | | border-style: solid; |
| | | border-color: #CACACA transparent transparent; |
| | | background: #F5F5F7; |
| | | border-top: 5px solid transparent; |
| | | border-bottom: 5px solid transparent; |
| | | border-left: 10px solid #CACACA; /* 左边界 */ |
| | | |
| | | } |
| | | .node-body{ |
| | | width: 220px; |
| | | cursor: pointer; |
| | | max-height: 120px; |
| | | position: relative; |
| | | border-radius: 5px; |
| | | background-color: white; |
| | | box-shadow: 0px 0px 5px 0px #d8d8d8; |
| | | &:hover{ |
| | | box-shadow: 0px 0px 3px 0px #1890FF; |
| | | .node-body-header { |
| | | .el-icon-close { |
| | | display: inline; |
| | | font-size: medium; |
| | | } |
| | | } |
| | | } |
| | | .node-body-header{ |
| | | border-top-left-radius: 5px; |
| | | border-top-right-radius: 5px; |
| | | padding: 5px 15px; |
| | | color: white; |
| | | font-size: xx-small; |
| | | .el-icon-close{ |
| | | display: none; |
| | | } |
| | | .name{ |
| | | height: 14px; |
| | | width: 150px; |
| | | display: inline-block |
| | | } |
| | | } |
| | | .node-body-content{ |
| | | padding: 18px; |
| | | color: #656363; |
| | | font-size: 14px; |
| | | i{ |
| | | position: absolute; |
| | | top: 55%; |
| | | right: 5px; |
| | | font-size: medium; |
| | | } |
| | | .placeholder{ |
| | | color: #8c8c8c; |
| | | } |
| | | } |
| | | .node-error{ |
| | | position: absolute; |
| | | right: -40px; |
| | | top: 20px; |
| | | font-size: 25px; |
| | | color: #F56C6C; |
| | | } |
| | | } |
| | | |
| | | .node-footer{ |
| | | position: relative; |
| | | .btn{ |
| | | width: 80px; |
| | | display: flex; |
| | | // padding: 20px 0 32px; |
| | | justify-content: center; |
| | | } |
| | | /deep/ .el-button{ |
| | | height: 32px; |
| | | } |
| | | &::before{ |
| | | content: ""; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | z-index: -1; |
| | | margin: auto; |
| | | width: 100%; |
| | | height: 2px; |
| | | background-color: #CACACA; |
| | | } |
| | | } |
| | | } |
| | | |
| | | </style> |
| | | |
New file |
| | |
| | | <template> |
| | | <node title="发起人" :is-root="true" :content="content" |
| | | @selected="$emit('selected')" @insertNode="type => $emit('insertNode', type)" |
| | | placeholder="所有人" :header-bgc="headerBgc" header-icon="el-icon-user-solid"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "RootNode", |
| | | components: {Node}, |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | computed:{ |
| | | content(){ |
| | | if (this.config.props.assignedUser.length > 0){ |
| | | let texts = [] |
| | | this.config.props.assignedUser.forEach(org => texts.push(org.writer_name)) |
| | | return String(texts).replaceAll(',', '、') |
| | | } else { |
| | | return '所有人' |
| | | } |
| | | }, |
| | | // flowText(){ |
| | | // const config = this.config |
| | | // console.log("flowText-config",config); |
| | | // if(config.approvalArr!==undefined){ |
| | | // return "发起时间:"+config.approvalArr.filter(ite=>ite.node_id===config.id)[0].approval_time; |
| | | // } |
| | | // return '' |
| | | // }, |
| | | headerBgc() { |
| | | if (this.$store.state.diagramMode === 'viewer') { |
| | | return this.config.props.headerBgc |
| | | } else { |
| | | return '#576a95' |
| | | } |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | } |
| | | }, |
| | | methods: {} |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo" |
| | | @selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)" |
| | | placeholder="请设置审批人" :header-bgc="headerBgc" header-icon="el-icon-s-check"/> |
| | | </template> |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "SubprocessNode", |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | components: {Node}, |
| | | data() { |
| | | return { |
| | | showError: false, |
| | | errorInfo: '', |
| | | } |
| | | }, |
| | | computed:{ |
| | | headerBgc() { |
| | | if (this.$store.state.diagramMode === 'viewer') { |
| | | return this.config.props.headerBgc |
| | | } else { |
| | | return '#ff943e' |
| | | } |
| | | }, |
| | | content(){ |
| | | const config = this.config.props |
| | | console.log("role,config.assignedUser",config.assignedUser) |
| | | switch (config.assignedType){ |
| | | case "ASSIGN_USER": |
| | | if (config.assignedUser.length > 0){ |
| | | let texts = [] |
| | | config.assignedUser.forEach(org => texts.push(org.name)) |
| | | return String(texts).replaceAll(',', '、') |
| | | }else { |
| | | return '请指定审批人' |
| | | } |
| | | case "SELF": |
| | | return '发起人自己' |
| | | case "SELF_SELECT": |
| | | return config.selfSelect.multiple ? '发起人自选多人':'发起人自选一人' |
| | | case "LEADER_TOP": |
| | | return '多级主管依次审批' |
| | | case "LEADER": |
| | | return config.leader.level > 1 ? '发起人的第 ' + config.leader.level + ' 级主管' : '发起人的直接主管' |
| | | case "FORM_USER": |
| | | if (!config.formUser || config.formUser === ''){ |
| | | return '表单内联系人(未选择)' |
| | | }else { |
| | | let text = this.getFormItemById(config.formUser) |
| | | if (text && text.title){ |
| | | return `表单(${text.title})内的人员` |
| | | }else { |
| | | return '该表单已被移除😥' |
| | | } |
| | | } |
| | | case "ROLE": |
| | | |
| | | if (config.assignedUser.length > 0){ |
| | | let texts = [] |
| | | config.assignedUser.forEach(org => texts.push(org.name)) |
| | | return String(texts).replaceAll(',', '、') |
| | | }else { |
| | | return '指定角色(未设置)' |
| | | } |
| | | default: return '未知设置项😥' |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | getFormItemById(id){ |
| | | return this.$store.state.design.formItems.find(item => item.id === id) |
| | | }, |
| | | //校验数据配置的合法性 |
| | | validate(err){ |
| | | try { |
| | | this.showError = !this[`validate_${this.config.props.assignedType}`](err) |
| | | |
| | | if (this.config.props.nobody.handler === 'TO_USER' && this.config.props.nobody.assignedUser.length === 0) { |
| | | this.errorInfo = '审批人为空时, 转交给指定人员:【请指定一个具体的人】' |
| | | err.push('审批人为空时, 转交给指定人员:【请指定一个具体的人】') |
| | | this.showError = true |
| | | } |
| | | |
| | | return this.showError |
| | | } catch (e) { |
| | | return true; |
| | | } |
| | | }, |
| | | validate_ASSIGN_USER(err){ |
| | | if(this.config.props.assignedUser.length > 0){ |
| | | return true; |
| | | }else { |
| | | this.errorInfo = '请指定审批人员' |
| | | err.push(`${this.config.name} 未指定审批人员`) |
| | | return false |
| | | } |
| | | }, |
| | | validate_SELF_SELECT(err){ |
| | | return true; |
| | | }, |
| | | validate_LEADER_TOP(err){ |
| | | return true; |
| | | }, |
| | | validate_LEADER(err){ |
| | | return true; |
| | | }, |
| | | validate_ROLE(err){ |
| | | if (this.config.props.role.length <= 0){ |
| | | this.errorInfo = '请指定负责审批的系统角色' |
| | | err.push(`${this.config.name} 未指定审批角色`) |
| | | return false |
| | | } |
| | | return true; |
| | | }, |
| | | validate_SELF(err){ |
| | | return true; |
| | | }, |
| | | validate_FORM_USER(err){ |
| | | if (this.config.props.formUser === ''){ |
| | | this.errorInfo = '请指定表单中的人员组件' |
| | | err.push(`${this.config.name} 审批人为表单中人员,但未指定`) |
| | | return false |
| | | } |
| | | return true; |
| | | }, |
| | | validate_REFUSE(err){ |
| | | return true; |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo" |
| | | @selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)" |
| | | placeholder="请设置办理人" :header-bgc="headerBgc" header-icon="el-icon-s-check"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "TaskNode", |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | components: {Node}, |
| | | data() { |
| | | return { |
| | | showError: false, |
| | | errorInfo: '', |
| | | } |
| | | }, |
| | | computed:{ |
| | | headerBgc() { |
| | | if (this.$store.state.diagramMode === 'viewer') { |
| | | return this.config.props.headerBgc |
| | | } else { |
| | | return '#e6b039' |
| | | } |
| | | }, |
| | | content(){ |
| | | const config = this.config.props |
| | | switch (config.assignedType){ |
| | | case "ASSIGN_USER": |
| | | if (config.assignedUser.length > 0){ |
| | | let texts = [] |
| | | config.assignedUser.forEach(org => texts.push(org.name)) |
| | | return String(texts).replaceAll(',', '、') |
| | | }else { |
| | | return '请指定办理人' |
| | | } |
| | | case "SELF": |
| | | return '发起人自己' |
| | | case "SELF_SELECT": |
| | | return config.selfSelect.multiple ? '发起人自选多人':'发起人自选一人' |
| | | case "LEADER_TOP": |
| | | return '多级主管依次办理' |
| | | case "LEADER": |
| | | return config.leader.level > 1 ? '发起人的第 ' + config.leader.level + ' 级主管' : '发起人的直接主管' |
| | | case "FORM_USER": |
| | | if (!config.formUser || config.formUser === ''){ |
| | | return '表单内联系人(未选择)' |
| | | }else { |
| | | let text = this.getFormItemById(config.formUser) |
| | | if (text && text.title){ |
| | | return `表单(${text.title})内的人员` |
| | | }else { |
| | | return '该表单已被移除😥' |
| | | } |
| | | } |
| | | case "ROLE": |
| | | if (config.assignedUser.length > 0){ |
| | | let texts = [] |
| | | config.assignedUser.forEach(org => texts.push(org.name)) |
| | | return String(texts).replaceAll(',', '、') |
| | | }else { |
| | | return '指定角色(未设置)' |
| | | } |
| | | default: return '未知设置项😥' |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | getFormItemById(id){ |
| | | return this.$store.state.design.formItems.find(item => item.id === id) |
| | | }, |
| | | //校验数据配置的合法性 |
| | | validate(err){ |
| | | try { |
| | | this.showError = !this[`validate_${this.config.props.assignedType}`](err) |
| | | |
| | | if (this.config.props.nobody.handler === 'TO_USER' && this.config.props.nobody.assignedUser.length === 0) { |
| | | this.errorInfo = '办理人为空时, 转交给指定人员:【请指定一个具体的人】' |
| | | err.push('办理人为空时, 转交给指定人员:【请指定一个具体的人】') |
| | | this.showError = true |
| | | } |
| | | |
| | | return this.showError |
| | | } catch (e) { |
| | | return true; |
| | | } |
| | | }, |
| | | validate_ASSIGN_USER(err){ |
| | | if(this.config.props.assignedUser.length > 0){ |
| | | return true; |
| | | }else { |
| | | this.errorInfo = '请指定办理人员' |
| | | err.push(`${this.config.name} 未指定办理人员`) |
| | | return false |
| | | } |
| | | }, |
| | | validate_SELF_SELECT(err){ |
| | | return true; |
| | | }, |
| | | validate_LEADER_TOP(err){ |
| | | return true; |
| | | }, |
| | | validate_LEADER(err){ |
| | | return true; |
| | | }, |
| | | validate_ROLE(err){ |
| | | if (this.config.props.role.length <= 0){ |
| | | this.errorInfo = '请指定负责办理的系统角色' |
| | | err.push(`${this.config.name} 未指定办理角色`) |
| | | return false |
| | | } |
| | | return true; |
| | | }, |
| | | validate_SELF(err){ |
| | | return true; |
| | | }, |
| | | validate_FORM_USER(err){ |
| | | if (this.config.props.formUser === ''){ |
| | | this.errorInfo = '请指定表单中的人员组件' |
| | | err.push(`${this.config.name} 办理人为表单中人员,但未指定`) |
| | | return false |
| | | } |
| | | return true; |
| | | }, |
| | | validate_REFUSE(err){ |
| | | return true; |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo" |
| | | @selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)" |
| | | placeholder="请设置触发器" header-bgc="#47bc82" header-icon="el-icon-set-up"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import Node from './Node.vue' |
| | | |
| | | export default { |
| | | name: "TriggerNode", |
| | | props:{ |
| | | config:{ |
| | | type: Object, |
| | | default: () => { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | components: {Node}, |
| | | data() { |
| | | return { |
| | | showError: false, |
| | | errorInfo: '', |
| | | } |
| | | }, |
| | | computed:{ |
| | | content(){ |
| | | this.config |
| | | } |
| | | }, |
| | | methods: { |
| | | //校验数据配置的合法性 |
| | | validate(err){ |
| | | this.showError = false |
| | | if (this.config.props.type === 'WEBHOOK'){ |
| | | if(this.$isNotEmpty(this.config.props.http.url)){ |
| | | this.showError = false |
| | | }else { |
| | | this.showError = true |
| | | this.errorInfo = '请设置WEBHOOK的URL地址' |
| | | } |
| | | }else if(this.config.props.type === 'EMAIL'){ |
| | | if(!this.$isNotEmpty(this.config.props.email.subject) |
| | | || this.config.props.email.to.length === 0 |
| | | || !this.$isNotEmpty(this.config.props.email.content)){ |
| | | this.showError = true |
| | | this.errorInfo = '请设置邮件发送配置' |
| | | }else { |
| | | this.showError = false |
| | | } |
| | | } |
| | | if (this.showError){ |
| | | err.push(`${this.config.name} 触发动作未设置完善`) |
| | | } |
| | | return !this.showError |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| | |
| | | <div class="workspace__header"> |
| | | <el-button icon="el-icon-back" class="back" type="info" size="mini" plain @click="$router.push('/')">返回主页</el-button> |
| | | </div> |
| | | <div class="workspace__tabs"> |
| | | <route-tab :routes="routes" type="border-card"> |
| | | <router-view></router-view> |
| | | </route-tab> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import RouteTab from '@/components/common/route-tab' |
| | | |
| | | export default { |
| | | name: 'workSpace', |
| | | components: { |
| | | RouteTab |
| | | }, |
| | | data() { |
| | | return { |
| | | routes: [ |
| | | { |
| | | label: '审批列表', |
| | | path: '/workspace/approval' |
| | | }, |
| | | { |
| | | label: '待我处理', |
| | | path: '/workspace/todo' |
| | | }, |
| | | { |
| | | label: '我发起的', |
| | | path: '/workspace/apply' |
| | | }, |
| | | { |
| | | label: '关于我的', |
| | | path: '/workspace/about' |
| | | } |
| | | , |
| | | { |
| | | label: '抄送我的', |
| | | path: '/workspace/cc' |
| | | } |
| | | , |
| | | { |
| | | label: '数据管理', |
| | | path: '/workspace/submit' |
| | | } |
| | | |
| | | ] |
| | | } |
| | | }, |
| | |
| | | <div class="process-view"> |
| | | |
| | | <div class="process-view__tabs" v-loading="loading"> |
| | | <el-tabs type="border-card"> |
| | | <el-tab-pane label="流程图"> |
| | | <process-diagram-viewer /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <process-diagram-viewer /> |
| | | |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getProcessInstanceInfo,getFlowDetail } from "@/api/design"; |
| | | import {getFlowDetail, getWorkSetpsByBusinessId} from "@/api/design"; |
| | | import ProcessDiagramViewer from "@/views/admin/layout/ProcessDiagramViewer"; |
| | | |
| | | export default { |
| | |
| | | getProcessInfo() { |
| | | this.loading = true; |
| | | let param = {"id": this.processInstanceId} |
| | | //let param = {"id": "74d84fb9188f4ce4b93e95f301ebbc1b"} |
| | | //根据业务id获取当前审批流步骤 |
| | | getWorkSetpsByBusinessId(param).then(rsp => { |
| | | let workSetps=rsp.data.data |
| | | console.log("workSetps", workSetps) |
| | | if(workSetps.length>0){ |
| | | let index=-1; |
| | | let resultProcess; |
| | | debugger |
| | | let noApprovalArr=workSetps.filter(item=>item.end_time===null); |
| | | ////如果所有节点都没审批 那么就取index_no=1的id为当前运行的节点 |
| | | if(noApprovalArr.length===workSetps.length){ |
| | | resultProcess=workSetps.find(item=>item.index_no===1) |
| | | }else{ |
| | | //否则就取遍历查询 审批节点不为空 index_no最大的 |
| | | workSetps.forEach(item => { |
| | | console.log("indexno",item.index_no) |
| | | if (item.index_no > index && item.end_time!==null) { |
| | | index = item.index_no; |
| | | resultProcess = item; |
| | | } |
| | | }) |
| | | } |
| | | |
| | | console.log("resultProcess", resultProcess) |
| | | this.$store.state.runningList .push(resultProcess.approve_step_id) |
| | | param.id=resultProcess.approve_id |
| | | this.getFlowDetail(param) |
| | | }else{ |
| | | this.$message.error("未查询到审批流数据!") |
| | | } |
| | | |
| | | console.log("workSetps", workSetps) |
| | | }).catch(err => { |
| | | this.$message.error(err) |
| | | }) |
| | | |
| | | |
| | | }, |
| | | getFlowDetail(param){ |
| | | getFlowDetail(param).then(rsp => { |
| | | |
| | | let form = rsp.data.data; |
| | |
| | | "formPerms": [] |
| | | }, |
| | | },1,form.id) |
| | | this.$store.state.runningList .push(form.id) |
| | | |
| | | |
| | | form.name=this.$Utils.decode(form.name); |
| | | form.templateName = form.name |
| | |
| | | form.notify = ""; |
| | | form.remark = "备注说明"; |
| | | form.isStop = false |
| | | form.whoCommit = "[]" |
| | | form.whoEdit = "[]" |
| | | form.whoExport = "[]" |
| | | form.templateId = "Steps-B-Director" |
| | | form.formId = "Steps-B-Director" |
| | | form.processDefinitionId = null |
| | | this.$store.state.design = form; |
| | | console.log("this.$store.state.design",this.$store.state.design) |
| | |
| | | }).catch(err => { |
| | | this.$message.error(err) |
| | | }) .finally(() => { |
| | | this.loading = false; |
| | | }); |
| | | // getProcessInstanceInfo(this.processInstanceId, this.taskId) |
| | | // .then((rsp) => { |
| | | // console.log("流程详情", rsp.data); |
| | | // const form = { ...rsp.data.result.processTemplates }; |
| | | // const currentNode = { ...rsp.data.result?.currentNode }; |
| | | // |
| | | // form.logo = JSON.parse(form.logo); |
| | | // form.settings = JSON.parse(form.settings); |
| | | // form.process = JSON.parse(form.process); |
| | | // this.$store.state.design = form; |
| | | // this.$store.state.endList = rsp.data.result.endList; |
| | | // this.$store.state.runningList = rsp.data.result.runningList; |
| | | // this.$store.state.noTakeList = rsp.data.result.noTakeList; |
| | | // this.$store.state.detailVOList = rsp.data.result.detailVOList; |
| | | // |
| | | // this.currentNode = currentNode; |
| | | // this.form = form; |
| | | // }) |
| | | // .finally(() => { |
| | | // this.loading = false; |
| | | // }); |
| | | }, |
| | | this.loading = false; |
| | | }); |
| | | } |
| | | }, |
| | | beforeMount() { |
| | | this.processInstanceId = this.$route.query.processInstanceId; |
| | |
| | | .process-view { |
| | | padding: 20px; |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | //display: flex; |
| | | //flex-direction: column; |
| | | box-sizing: border-box; |
| | | |
| | | &__header { |