123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- <template>
- <div>
- <el-dialog
- class="modify-flow-detail page-dialog"
- :visible.sync="modalIsShow"
- title="流程图编辑"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- :show-close="false"
- append-to-body
- fullscreen
- destroy-on-close
- @open="visibleChange"
- >
- <div class="box-justify" slot="title">
- <h4 class="el-dialog__title">流程图编辑:{{ instance.name }}</h4>
- <div>
- <el-button @click="cancel">取消</el-button>
- <el-button type="primary" :disabled="isSubmit" @click="submit"
- >发布</el-button
- >
- </div>
- </div>
- <div class="flow-box">
- <div class="flow-content">
- <div class="flow-main">
- <!-- nodes -->
- <div
- v-for="node in nodes"
- :key="node.id"
- :id="`node-${node.id}`"
- :class="[
- 'flow-node',
- `node-${node.type.toLowerCase()}`,
- { 'is-active': curNode.id === node.id }
- ]"
- @click="toSelectNode(node)"
- >
- <div v-if="node.type === 'PROCESS'" class="flow-node-title">
- <i
- v-if="node.type === 'PROCESS'"
- :class="nodeIcons['PROCESS']"
- ></i
- >审批人
- </div>
- <div v-if="node.type === 'PROCESS'" class="flow-node-content">
- <template v-if="!IS_APPROVE_SET">
- <div v-if="node.property.approveUserType === 'USER'">
- <p>
- {{
- node.property.approveUsers
- .map(item => item.name)
- .join(",")
- }}
- </p>
- <p v-if="node.property.copyForUsers.length">
- 抄送:{{
- node.property.copyForUsers
- .map(item => item.name)
- .join(",")
- }}
- </p>
- </div>
- <div v-else>
- <p>
- {{
- node.property.approveRoles
- .map(item => item.name)
- .join(",")
- }}
- </p>
- </div>
- </template>
- <template
- v-if="IS_APPROVE_SET && node.property.approveUserCountType"
- >
- <p>
- 方式:{{
- APPROVE_USER_COUNT_TYPE[
- node.property.approveUserCountType
- ]
- }}
- </p>
- <p>
- 范围:{{
- APPROVE_USER_SELECT_RANGE[
- node.property.approveUserSelectRange
- ]
- }}
- </p>
- <p v-if="node.property.approveUserSelectRange === 'ROLE'">
- 角色:{{
- node.property.approveUserSelectRoles
- .map(item => item.name)
- .join(",")
- }}
- </p>
- </template>
- </div>
- <div v-else class="flow-node-content">
- <span><i :class="nodeIcons[node.type]"></i></span>
- <span>{{ node.content }}</span>
- </div>
- <div v-if="node.type !== 'END'" class="flow-link">
- <div class="node-add" @click.stop="toAddNode(node.id)">
- <i class="el-icon-plus"></i>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="flow-property">
- <div v-if="curNode.id" class="flow-property-main" :key="curNode.id">
- <h3 class="flow-property-title">节点属性</h3>
- <!-- 管理员指定审批人 -->
- <div v-if="!IS_APPROVE_SET" class="property-part">
- <h4 class="property-part-title">设置审批人</h4>
- <div class="flow-radio">
- <el-radio-group
- v-model="curNode.property.approveUserType"
- size="small"
- @change="curNodeChange"
- >
- <el-radio
- v-for="(val, key) in APPROVE_USER_TYPE"
- :key="key"
- :label="key"
- >{{ val }}</el-radio
- >
- </el-radio-group>
- </div>
- <!-- 添加成员 -->
- <div
- v-if="curNode.property.approveUserType === 'USER'"
- class="flow-users"
- >
- <el-button
- size="small"
- type="primary"
- @click="toAddUser('approveUsers')"
- >添加成员</el-button
- >
- <span class="tips-info">(最多添加5个)</span>
- <div class="user-list">
- <el-tag
- v-for="user in curNode.property.approveUsers"
- :key="user.id"
- size="small"
- closable
- :disable-transitions="false"
- @close="deleteApproveUser('approveUsers', user)"
- >
- {{ user.name }}
- </el-tag>
- <el-button
- class="user-clear"
- type="danger"
- size="mini"
- plain
- @click="clearApproveUsers('approveUsers')"
- >清空</el-button
- >
- </div>
- </div>
- <!-- 添加角色 -->
- <div v-else class="flow-users">
- <el-button
- size="small"
- type="primary"
- @click="toAddApproveRole('approveRoles')"
- >添加角色</el-button
- >
- <div class="user-list">
- <el-tag
- v-for="role in curNode.property.approveRoles"
- :key="role.id"
- size="small"
- closable
- :disable-transitions="false"
- @close="deleteApproveRole('approveRoles', role)"
- >
- {{ role.name }}
- </el-tag>
- <el-button
- class="user-clear"
- type="danger"
- size="mini"
- plain
- @click="clearApproveRole('approveRoles')"
- >清空</el-button
- >
- </div>
- </div>
- </div>
- <!-- 发起人指定审批人 -->
- <div v-else class="property-part">
- <h4 class="property-part-title">设置审批人</h4>
- <el-form label-width="80px">
- <el-form-item label="选择方式:">
- <el-select
- v-model="curNode.property.approveUserCountType"
- class="width-full"
- placeholder="请选择方式"
- :disabled="curNodeIsLast"
- @change="curNodeChange"
- >
- <el-option
- v-for="(val, key) in APPROVE_USER_COUNT_TYPE"
- :key="key"
- :value="key"
- :label="val"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="选择范围:">
- <el-select
- v-model="curNode.property.approveUserSelectRange"
- class="width-full"
- placeholder="请选择范围"
- :disabled="curNodeIsLast"
- @change="curNodeChange"
- >
- <el-option
- v-for="(val, key) in APPROVE_USER_SELECT_RANGE"
- :key="key"
- :value="key"
- :label="val"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item
- v-if="curNode.property.approveUserSelectRange === 'ROLE'"
- label="指定角色:"
- >
- <el-button
- size="small"
- type="primary"
- @click="toAddApproveRole('approveUserSelectRoles')"
- >添加角色</el-button
- >
- <div class="user-list">
- <el-tag
- v-for="role in curNode.property.approveUserSelectRoles"
- :key="role.id"
- size="small"
- closable
- :disable-transitions="false"
- @close="deleteApproveRole('approveUserSelectRoles', role)"
- >
- {{ role.name }}
- </el-tag>
- <el-button
- class="user-clear"
- type="danger"
- size="mini"
- plain
- @click="clearApproveRole('approveUserSelectRoles')"
- >清空</el-button
- >
- </div>
- </el-form-item>
- </el-form>
- </div>
- <!-- 抄送人 -->
- <div
- v-if="curNode.property.approveUserType === 'USER'"
- class="property-part"
- >
- <h4 class="property-part-title">设置抄送人</h4>
- <div class="flow-users">
- <el-button
- size="small"
- type="primary"
- @click="toAddUser('copyForUsers')"
- >添加成员</el-button
- >
- <span class="tips-info">(最多添加5个)</span>
- <div class="user-list">
- <el-tag
- v-for="user in curNode.property.copyForUsers"
- :key="user.id"
- closable
- size="small"
- :disable-transitions="false"
- @close="deleteApproveUser('copyForUsers', user)"
- >
- {{ user.name }}
- </el-tag>
- <el-button
- class="user-clear"
- type="danger"
- size="mini"
- plain
- @click="clearApproveUsers('copyForUsers')"
- >清空</el-button
- >
- </div>
- </div>
- </div>
- <!-- 高级设置 -->
- <div class="property-part">
- <h4 class="property-part-title">高级设置</h4>
- <p class="property-desc">多人审批时采用的审批方式</p>
- <div class="flow-radio-v">
- <el-radio-group
- v-model="curNode.property.multipleUserApproveType"
- size="small"
- @change="curNodeChange"
- >
- <el-radio
- v-for="(val, key) in MULTIPLE_USER_APPROVE_TYPE"
- :key="key"
- :label="key"
- >{{ val }}</el-radio
- >
- </el-radio-group>
- </div>
- </div>
- <!-- 驳回设置 -->
- <div class="property-part">
- <h4 class="property-part-title">驳回设置</h4>
- <p class="property-desc">允许驳回节点</p>
- <div class="flow-radio-v">
- <el-radio-group
- v-model="curNode.property.rejectType"
- size="small"
- @change="curNodeChange"
- >
- <el-radio
- v-for="(val, key) in REJECT_TYPE"
- :key="key"
- :label="key"
- >{{ val }}</el-radio
- >
- </el-radio-group>
- </div>
- <p class="property-desc">驳回后提交方式</p>
- <div class="flow-radio-v">
- <el-radio-group
- v-model="curNode.property.rejectResubmitType"
- size="small"
- @change="curNodeChange"
- >
- <el-radio
- v-for="(val, key) in REJECT_RESUBMIT_TYPE"
- :key="key"
- :label="key"
- >{{ val }}</el-radio
- >
- </el-radio-group>
- </div>
- </div>
- <el-button size="mini" type="danger" plain @click="toDeleteNode"
- >删除节点</el-button
- >
- </div>
- </div>
- </div>
- </el-dialog>
- <!-- SelectUserDialog -->
- <select-user-dialog
- ref="SelectUserDialog"
- :users="curAddUsers"
- @modified="userModified"
- ></select-user-dialog>
- <!-- SelectRoleDialog -->
- <select-role-dialog
- ref="SelectRoleDialog"
- :data="curAddRoles"
- @modified="roleModified"
- ></select-role-dialog>
- </div>
- </template>
- <script>
- import { deepCopy } from "../../../plugins/utils";
- import { flowDetail, updateFlowDetail } from "../api";
- import SelectUserDialog from "./SelectUserDialog";
- import SelectRoleDialog from "./SelectRoleDialog";
- const initFlowInfo = {
- id: null,
- name: "",
- type: "ELECTRON_FLOW",
- modelType: "USER_FIXED"
- };
- const DEFAULT_NODE = {
- id: "",
- type: "PROCESS", // 节点类型,START:开始节点,PROCESS:过程节点,END:结束节点
- content: "",
- w: 150,
- h: 40,
- x: 0,
- y: 0,
- property: {
- approveUserType: "USER", // 审批用户类型,USER:成员,ROLE:角色
- approveUsers: [], // 审批用户列表
- approveRoles: [], // 审批角色列表
- copyForUsers: [], // 抄送用户列表
- multipleUserApproveType: "ORDER", // 审批用户类别,ORDER:依次审批,ALL:会签(所有人必须审批),SOME:或签(一名审批人同意或拒绝即可)
- rejectType: "PREV", // 驳回类型,PREV:上一节点,START:发起人节点,PREV_ALL:该节点前全部节点
- rejectResubmitType: "NORMAL", // 驳回再提交类型,NORMAL:按正常流程提交,PREV_STEP:提交到驳回节点
- approveUserCountType: "ONE", // 选择方式,ONE:一个,MORE:多个
- approveUserSelectRange: "ALL", // 选择范围,ALL:全单位,ROLE:角色
- approveUserSelectRoles: [] // 指定角色范围
- }
- };
- // 详细参数:https://doc.qmth.com.cn/pages/viewpage.action?pageId=40435764
- export default {
- name: "modify-flow-detail",
- components: { SelectUserDialog, SelectRoleDialog },
- props: {
- instance: {
- type: Object,
- default() {
- return {};
- }
- }
- },
- data() {
- return {
- modalIsShow: false,
- isSubmit: false,
- initNodes: [
- {
- id: "1",
- type: "START",
- content: "开始流程",
- w: 150,
- h: 40,
- x: 0,
- y: 0,
- property: null
- },
- {
- id: "2",
- type: "END",
- content: "结束流程",
- w: 150,
- h: 40,
- x: 0,
- y: 0,
- property: null
- }
- ],
- flowInfo: { ...initFlowInfo },
- nodes: [],
- curNode: {},
- curNodeIsLast: false,
- curAddUsers: [],
- curAddUserType: "",
- curAddRoles: [],
- curAddRoleType: "",
- nodeIcons: {
- START: "el-icon-video-play",
- END: "el-icon-switch-button",
- PROCESS: "el-icon-circle-plus-outline"
- },
- APPROVE_USER_TYPE: {
- USER: "成员",
- ROLE: "角色"
- },
- MULTIPLE_USER_APPROVE_TYPE: {
- ORDER: "依次审批",
- ALL: "会签(所有人必须审批)",
- SOME: "或签(一名审批人同意或拒绝即可)"
- },
- REJECT_TYPE: {
- PREV: "上一节点",
- START: "发起人节点",
- PREV_ALL: "该节点前全部节点"
- },
- REJECT_RESUBMIT_TYPE: {
- NORMAL: "按正常流程提交",
- PREV_STEP: "提交到驳回节点"
- },
- APPROVE_USER_COUNT_TYPE: {
- ONE: "一次选择一个人",
- MORE: "一次选择多个人"
- },
- APPROVE_USER_SELECT_RANGE: {
- ALL: "全单位",
- ROLE: "指定角色"
- }
- };
- },
- computed: {
- IS_APPROVE_SET() {
- return this.flowInfo.modelType === "APPROVE_SET";
- }
- },
- methods: {
- async initData(val) {
- if (val.id) {
- const data = await flowDetail(val.id);
- this.flowInfo = this.$objAssign(initFlowInfo, data);
- this.flowInfo.id = data.customFlowId;
- this.nodes = data.customFlowLists;
- this.toSelectNode(this.nodes[1]);
- } else {
- this.flowInfo = this.$objAssign(initFlowInfo, val);
- this.nodes = deepCopy(this.initNodes);
- // this.toSelectNode(this.nodes[1]);
- this.toAddNode(this.nodes[0].id);
- // 发起人自选模式,默认新增两个节点
- if (this.IS_APPROVE_SET) this.toAddNode(this.nodes[0].id);
- }
- },
- visibleChange() {
- this.initData(this.instance);
- },
- cancel() {
- this.modalIsShow = false;
- },
- open() {
- this.modalIsShow = true;
- },
- getDefaultNode() {
- const nodeId = this.nodes.length
- ? Math.max.apply(
- null,
- this.nodes.map(item => item.id)
- ) + 1
- : 1;
- return { ...deepCopy(DEFAULT_NODE), id: nodeId };
- },
- toAddNode(curNodeId) {
- const newNode = this.getDefaultNode();
- const pos = this.nodes.findIndex(node => node.id === curNodeId);
- this.nodes.splice(pos + 1, 0, newNode);
- this.toSelectNode(newNode);
- },
- toDeleteNode() {
- const pos = this.nodes.findIndex(node => node.id === this.curNode.id);
- this.nodes.splice(pos, 1);
- if (this.nodes[pos] && this.nodes[pos].type === "PROCESS") {
- this.toSelectNode(this.nodes[pos]);
- } else {
- let prevPos = pos - 1;
- prevPos = Math.max(prevPos, 0);
- this.toSelectNode(this.nodes[prevPos]);
- }
- },
- toSelectNode(node) {
- if (node.type === "START" || node.type === "END") {
- this.curNode = {};
- return;
- }
- this.curNode = node ? deepCopy(node) : {};
- if (!this.IS_APPROVE_SET) return;
- // 发起人自选模式,最后一个节点禁止编辑审批人
- const pos = this.nodes.findIndex(item => item.id === node.id);
- this.curNodeIsLast = pos === this.nodes.length - 2;
- if (this.curNodeIsLast) {
- this.curNode.property.approveUserCountType = null;
- this.curNode.property.approveUserSelectRange = null;
- this.curNode.property.approveUserSelectRoles = [];
- this.curNodeChange();
- }
- },
- curNodeChange() {
- const pos = this.nodes.findIndex(node => node.id === this.curNode.id);
- this.nodes.splice(pos, 1, deepCopy(this.curNode));
- },
- // approveUser
- toAddUser(curAddUserType) {
- this.curAddUserType = curAddUserType;
- this.curAddUsers = this.curNode.property[this.curAddUserType];
- this.$refs.SelectUserDialog.open();
- },
- userModified(users) {
- this.curNode.property[this.curAddUserType] = users;
- this.curNodeChange();
- },
- deleteApproveUser(curAddUserType, user) {
- console.log(user);
- const pos = this.curNode.property[curAddUserType].findIndex(
- item => item.id === user.id
- );
- this.curNode.property[curAddUserType].splice(pos, 1);
- this.curNodeChange();
- },
- clearApproveUsers(curAddUserType) {
- this.curNode.property[curAddUserType] = [];
- this.curNodeChange();
- },
- // approveRole
- toAddApproveRole(curAddRoleType) {
- this.curAddRoleType = curAddRoleType;
- this.curAddRoles = this.curNode.property[this.curAddRoleType];
- this.$refs.SelectRoleDialog.open();
- },
- roleModified(roles) {
- this.curNode.property[this.curAddRoleType] = roles;
- this.curNodeChange();
- },
- deleteApproveRole(curAddRoleType, role) {
- const pos = this.curNode.property[curAddRoleType].findIndex(
- item => item.id === role.id
- );
- this.curNode.property[curAddRoleType].splice(pos, 1);
- this.curNodeChange();
- },
- clearApproveRole(curAddRoleType) {
- this.curNode.property[curAddRoleType] = [];
- this.curNodeChange();
- },
- checkData() {
- if (!this.nodes.some(node => node.type === "PROCESS")) {
- this.$message.error("请设置过程节点");
- return;
- }
- if (this.IS_APPROVE_SET) {
- const nodeUserValid = !this.nodes
- .filter(node => node.type === "PROCESS")
- .some(node => {
- if (node.property.approveUserSelectRange === "ROLE") {
- return !node.property.approveUserSelectRoles.length;
- } else {
- return false;
- }
- });
- if (!nodeUserValid) {
- this.$message.error("请完成节点设置");
- return;
- }
- } else {
- const nodeUserValid = !this.nodes
- .filter(node => node.type === "PROCESS")
- .some(node => {
- if (node.property.approveUserType === "USER") {
- return !node.property.approveUsers.length;
- // return !(
- // node.property.approveUsers.length &&
- // node.property.copyForUsers.length
- // );
- } else {
- return !node.property.approveRoles.length;
- }
- });
- if (!nodeUserValid) {
- this.$message.error("请完成节点设置");
- return;
- }
- }
- return true;
- },
- async submit() {
- if (this.isSubmit) return;
- const result = await this.$confirm(
- `确定要发布流程【${this.instance.name}】吗?`,
- "提示",
- {
- type: "warning"
- }
- ).catch(() => {});
- if (result !== "confirm") return;
- if (!this.checkData()) return;
- this.nodes.forEach(node => {
- const dom = document.getElementById(`node-${node.id}`);
- node.w = dom.clientWidth;
- node.h = dom.clientHeight;
- node.x = dom.offsetLeft;
- node.y = dom.offsetTop;
- });
- const nodes = this.nodes.map((node, index) => {
- let nnode = deepCopy(node);
- nnode.id = index + 1;
- if (node.property) {
- if (this.IS_APPROVE_SET) {
- if (node.property.approveUserSelectRange === "ALL") {
- node.property.approveUserSelectRoles = [];
- }
- } else {
- if (node.property.approveUserType === "USER") {
- nnode.approveRoles = [];
- } else {
- nnode.approveUsers = [];
- nnode.copyForUsers = [];
- }
- }
- }
- return nnode;
- });
- this.isSubmit = true;
- const res = await updateFlowDetail({
- customFlowId: this.flowInfo.id,
- name: this.flowInfo.name,
- type: this.flowInfo.type,
- modelType: this.flowInfo.modelType,
- publish: true,
- customFlowLists: nodes
- }).catch(() => {});
- this.isSubmit = false;
- if (!res) return;
- this.$message.success("编辑成功!");
- this.$emit("modified");
- this.cancel();
- }
- }
- };
- </script>
|