初始化版本,引入智慧食堂模块,第三方模块
No files matched your search
@@ -0,0 +1,74 @@
|
||||
/* color palette from <https://github.com/vuejs/theme> */
|
||||
:root {
|
||||
--vt-c-white: #ffffff;
|
||||
--vt-c-white-soft: #f8f8f8;
|
||||
--vt-c-white-mute: #f2f2f2;
|
||||
|
||||
--vt-c-black: #181818;
|
||||
--vt-c-black-soft: #222222;
|
||||
--vt-c-black-mute: #282828;
|
||||
|
||||
--vt-c-indigo: #2c3e50;
|
||||
|
||||
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
||||
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
||||
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
||||
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
||||
|
||||
--vt-c-text-light-1: var(--vt-c-indigo);
|
||||
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
||||
--vt-c-text-dark-1: var(--vt-c-white);
|
||||
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
||||
}
|
||||
|
||||
/* semantic color variables for this project */
|
||||
:root {
|
||||
--color-background: var(--vt-c-white);
|
||||
--color-background-soft: var(--vt-c-white-soft);
|
||||
--color-background-mute: var(--vt-c-white-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-light-2);
|
||||
--color-border-hover: var(--vt-c-divider-light-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-light-1);
|
||||
--color-text: var(--vt-c-text-light-1);
|
||||
|
||||
--section-gap: 160px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-background: var(--vt-c-black);
|
||||
--color-background-soft: var(--vt-c-black-soft);
|
||||
--color-background-mute: var(--vt-c-black-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-dark-2);
|
||||
--color-border-hover: var(--vt-c-divider-dark-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-dark-1);
|
||||
--color-text: var(--vt-c-text-dark-2);
|
||||
}
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
color: var(--color-text);
|
||||
background: var(--color-background);
|
||||
transition: color 0.5s, background-color 0.5s;
|
||||
line-height: 1.6;
|
||||
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
font-size: 15px;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
After Width: | Height: | Size: 466 B |
|
After Width: | Height: | Size: 223 B |
|
After Width: | Height: | Size: 549 B |
|
After Width: | Height: | Size: 325 B |
|
After Width: | Height: | Size: 209 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 266 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69" xmlns:v="https://vecta.io/nano"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
||||
|
After Width: | Height: | Size: 308 B |
@@ -0,0 +1,35 @@
|
||||
@import './base.css';
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
a,
|
||||
.green {
|
||||
text-decoration: none;
|
||||
color: hsla(160, 100%, 37%, 1);
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
a:hover {
|
||||
background-color: hsla(160, 100%, 37%, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
body {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div class="add-node-btn-box">
|
||||
<div class="add-node-btn">
|
||||
<el-popover placement="right-start" v-model="visible" width="250px">
|
||||
<div class="add-node-popover-body">
|
||||
<a class="add-node-popover-item approver" @click="addType(1)">
|
||||
<div class="item-wrapper">
|
||||
<span class="iconfont"></span>
|
||||
</div>
|
||||
<p>{{ $t('flow.approver') }}</p>
|
||||
</a>
|
||||
<a class="add-node-popover-item notifier" @click="addType(2)">
|
||||
<div class="item-wrapper">
|
||||
<span class="iconfont"></span>
|
||||
</div>
|
||||
<p>{{ $t('flow.carbonCopyRecipient') }}</p>
|
||||
</a>
|
||||
|
||||
<a class="add-node-popover-item condition" @click="addType(4)">
|
||||
<div class="item-wrapper">
|
||||
<span class="iconfont"></span>
|
||||
</div>
|
||||
<p>{{ $t('flow.conditionalBranching') }}</p>
|
||||
</a>
|
||||
|
||||
<a class="add-node-popover-item ParallelGateway" @click="addType(5)">
|
||||
<div class="item-wrapper">
|
||||
<span class="iconfont"></span>
|
||||
</div>
|
||||
<p>{{ $t('flow.parallelBranch') }}</p>
|
||||
</a>
|
||||
</div>
|
||||
<template #reference>
|
||||
<button class="btn" type="button">
|
||||
<span class="iconfont"></span>
|
||||
</button>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import other from '/@/utils/other';
|
||||
|
||||
let props = defineProps({
|
||||
childNodeP: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
currentNode: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
let emits = defineEmits(['update:childNodeP']);
|
||||
let visible = ref(false);
|
||||
const addType = (type) => {
|
||||
visible.value = false;
|
||||
if (type !== 4 && type !== 5) {
|
||||
var data;
|
||||
if (type === 1) {
|
||||
data = {
|
||||
id: other.getNonDuplicateID(),
|
||||
nodeName: '审批人',
|
||||
error: true,
|
||||
type: 1,
|
||||
parentId: props.currentNode.id,
|
||||
//人员方式
|
||||
assignedType: 1,
|
||||
//单选还是多选
|
||||
multiple: false,
|
||||
//多人审批的选项
|
||||
multipleMode: 1,
|
||||
//第几级部门负责人
|
||||
deptLeaderLevel: 1,
|
||||
//人员选择
|
||||
formUserId: '',
|
||||
formUserName: '',
|
||||
//表单权限
|
||||
formPerms: {},
|
||||
//审批人为空
|
||||
nobody: {
|
||||
handler: 'TO_PASS',
|
||||
assignedUser: [],
|
||||
},
|
||||
//审批人拒绝
|
||||
refuse: {
|
||||
handler: "TO_END",
|
||||
nodeId:''
|
||||
},
|
||||
childNode: props.childNodeP,
|
||||
nodeUserList: [],
|
||||
};
|
||||
} else if (type === 2) {
|
||||
data = {
|
||||
id: other.getNonDuplicateID(),
|
||||
parentId: props.currentNode.id,
|
||||
|
||||
nodeName: '抄送人',
|
||||
type: 2,
|
||||
error: true,
|
||||
childNode: props.childNodeP,
|
||||
nodeUserList: [],
|
||||
//表单权限
|
||||
formPerms: {},
|
||||
};
|
||||
}
|
||||
emits('update:childNodeP', data);
|
||||
} else if (type === 4) {
|
||||
let id = other.getNonDuplicateID();
|
||||
emits('update:childNodeP', {
|
||||
nodeName: '条件分支',
|
||||
type: 4,
|
||||
id: id,
|
||||
parentId: props.currentNode.id,
|
||||
|
||||
childNode: props.childNodeP,
|
||||
conditionNodes: [
|
||||
{
|
||||
id: other.getNonDuplicateID(),
|
||||
nodeName: '条件1',
|
||||
groupMode: true,
|
||||
error: true,
|
||||
type: 3,
|
||||
parentId: id,
|
||||
|
||||
priorityLevel: 1,
|
||||
conditionList: [
|
||||
{
|
||||
mode: true,
|
||||
conditionList: [
|
||||
{
|
||||
key: '',
|
||||
expression: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
nodeUserList: [],
|
||||
childNode: null,
|
||||
},
|
||||
{
|
||||
nodeName: '条件2',
|
||||
type: 3,
|
||||
id: other.getNonDuplicateID(),
|
||||
groupMode: true,
|
||||
error: false,
|
||||
parentId: id,
|
||||
priorityLevel: 2,
|
||||
conditionList: [
|
||||
{
|
||||
mode: true,
|
||||
conditionList: [
|
||||
{
|
||||
key: '',
|
||||
expression: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
nodeUserList: [],
|
||||
childNode: null,
|
||||
},
|
||||
],
|
||||
});
|
||||
} else if (type === 5) {
|
||||
let id = other.getNonDuplicateID();
|
||||
emits('update:childNodeP', {
|
||||
nodeName: '并行分支',
|
||||
type: 5,
|
||||
id: id,
|
||||
parentId: props.currentNode.id,
|
||||
|
||||
childNode: props.childNodeP,
|
||||
conditionNodes: [
|
||||
{
|
||||
id: other.getNonDuplicateID(),
|
||||
nodeName: '分支1',
|
||||
placeHolder: '满足条件',
|
||||
parentId: id,
|
||||
|
||||
error: false,
|
||||
type: 3,
|
||||
priorityLevel: 1,
|
||||
conditionList: [],
|
||||
nodeUserList: [],
|
||||
childNode: null,
|
||||
},
|
||||
{
|
||||
nodeName: '分支2',
|
||||
type: 3,
|
||||
id: other.getNonDuplicateID(),
|
||||
parentId: id,
|
||||
|
||||
error: false,
|
||||
placeHolder: '满足条件',
|
||||
|
||||
priorityLevel: 2,
|
||||
conditionList: [],
|
||||
nodeUserList: [],
|
||||
childNode: null,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="css">
|
||||
.add-node-btn-box {
|
||||
width: 240px;
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.add-node-btn-box::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
margin: auto;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
background-color: #cacaca;
|
||||
}
|
||||
|
||||
.add-node-btn {
|
||||
user-select: none;
|
||||
width: 240px;
|
||||
padding: 20px 0 32px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.add-node-btn .btn {
|
||||
outline: none;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: #3296fa;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
border: none;
|
||||
line-height: 30px;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
|
||||
.add-node-btn .btn .iconfont {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.add-node-btn .btn:hover {
|
||||
transform: scale(1.3);
|
||||
box-shadow: 0 13px 27px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.add-node-btn .btn:active {
|
||||
transform: none;
|
||||
background: #1e83e9;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
@import '/@/views/flow/workflow/css/workflow.css';
|
||||
|
||||
.add-node-popover-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.add-node-popover-item {
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
|
||||
.item-wrapper {
|
||||
user-select: none;
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-bottom: 5px;
|
||||
background: #fff;
|
||||
border: 1px solid #e2e2e2;
|
||||
border-radius: 50%;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
.iconfont {
|
||||
font-size: 35px;
|
||||
line-height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
&.approver {
|
||||
.item-wrapper {
|
||||
color: #ff943e;
|
||||
}
|
||||
}
|
||||
|
||||
&.notifier {
|
||||
.item-wrapper {
|
||||
//color: #3296fa
|
||||
}
|
||||
}
|
||||
|
||||
&.condition {
|
||||
.item-wrapper {
|
||||
color: #15bc83;
|
||||
}
|
||||
}
|
||||
|
||||
&.ParallelGateway {
|
||||
.item-wrapper {
|
||||
color: rgb(255, 69, 0);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.item-wrapper {
|
||||
background: #3296fa;
|
||||
box-shadow: 0 10px 20px 0 rgba(50, 150, 250, 0.4);
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
.item-wrapper {
|
||||
box-shadow: none;
|
||||
background: #eaeaea;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
//color: inherit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,323 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
v-model="visible"
|
||||
:append-to-body="true"
|
||||
title="审批人设置"
|
||||
:show-close="false"
|
||||
:size="550"
|
||||
:before-close="saveApprover"
|
||||
@open="openEvent"
|
||||
>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="设置审批人">
|
||||
<el-radio-group v-model="approverConfig.assignedType" class="ml-4" @change="assignedTypeChangeEvent">
|
||||
<el-row>
|
||||
<el-col v-for="{ value, label } in setTypes" :key="value" :span="8">
|
||||
<el-radio :label="value">{{ label }}</el-radio>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-radio-group>
|
||||
|
||||
<el-divider/>
|
||||
<template v-if="approverConfig.assignedType === 2">
|
||||
<h4>选择部门</h4>
|
||||
<select-show v-model:orgList="approverConfig.nodeUserList" type="dept"></select-show>
|
||||
</template>
|
||||
<template v-if="approverConfig.assignedType === 3">
|
||||
<h4>选择角色</h4>
|
||||
|
||||
<select-show v-model:orgList="approverConfig.nodeUserList" type="role" :multiple="true"></select-show>
|
||||
</template>
|
||||
<template v-if="approverConfig.assignedType === 1">
|
||||
<h4>选择成员</h4>
|
||||
|
||||
<select-show v-model:orgList="approverConfig.nodeUserList" type="user" :multiple="true"></select-show>
|
||||
</template>
|
||||
<template v-if="approverConfig.assignedType === 8">
|
||||
<h4>人员控件</h4>
|
||||
<el-select v-model="approverConfig.formUserId" clearable class="m-2" placeholder="请选择审批表单"
|
||||
size="large">
|
||||
<el-option v-for="item in step2FormUserList" :key="item.id" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-if="approverConfig.assignedType === 7">
|
||||
<h4>审批终点</h4>
|
||||
<span style="margin-right: 5px; font-size: 14px">到第</span>
|
||||
<el-input-number v-model="approverConfig.deptLeaderLevel" :step="1" :min="1" :max="20" step-strictly
|
||||
size="small"/>
|
||||
<span style="margin-left: 5px; font-size: 14px">级部门主管终止</span>
|
||||
</template>
|
||||
<template v-if="approverConfig.assignedType === 4">
|
||||
<h4>选择方式</h4>
|
||||
<el-radio-group v-model="approverConfig.multiple" class="ml-4">
|
||||
<el-radio :label="false" size="large">单选</el-radio>
|
||||
<el-radio :label="true" size="large">多选</el-radio>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
<template
|
||||
v-if="
|
||||
((approverConfig.multiple === true && approverConfig.assignedType === 4) ||
|
||||
(approverConfig.assignedType === 1 && approverConfig.nodeUserList.length > 1) ||
|
||||
approverConfig.assignedType === 2 ||
|
||||
approverConfig.assignedType === 3 ||
|
||||
(approverConfig.assignedType === 7 && approverConfig.deptLeaderLevel > 1) ||
|
||||
(approverConfig.assignedType === 8 && isMultiUserForm(approverConfig.formUserId))) &&
|
||||
approverConfig.assignedType !== 5
|
||||
"
|
||||
>
|
||||
<h4>多人审批时采用的审批方式</h4>
|
||||
<el-radio-group v-model="approverConfig.multipleMode" class="ml-4">
|
||||
<p style="display: block; width: 100%">
|
||||
<el-radio :label="1" size="large">会签(需要所有审批人同意)</el-radio>
|
||||
</p>
|
||||
<p style="display: block; width: 100%">
|
||||
<el-radio :label="2" size="large">或签(一名审批人同意即可)</el-radio>
|
||||
</p>
|
||||
<p style="display: block; width: 100%">
|
||||
<el-radio :label="3" size="large">依次审批(按顺序依次审批)</el-radio>
|
||||
</p>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
<el-divider/>
|
||||
|
||||
<h4>审批人为空时</h4>
|
||||
<el-radio-group v-model="approverConfig.nobody.handler" class="ml-4">
|
||||
<el-radio label="TO_PASS" size="large">自动通过</el-radio>
|
||||
<el-radio label="TO_REFUSE" size="large">自动拒绝</el-radio>
|
||||
<el-radio label="TO_END" size="large">自动结束</el-radio>
|
||||
<el-radio label="TO_ADMIN" size="large">转交给管理员</el-radio>
|
||||
<el-radio label="TO_USER" size="large">指定人员</el-radio>
|
||||
</el-radio-group>
|
||||
<select-show
|
||||
v-if="approverConfig?.nobody.handler === 'TO_USER'"
|
||||
v-model:orgList="approverConfig.nobody.assignedUser"
|
||||
type="user"
|
||||
:multiple="false"
|
||||
></select-show>
|
||||
|
||||
<el-divider/>
|
||||
|
||||
<template v-if="approverConfig.refuse?.handler">
|
||||
<h4>审批被拒绝</h4>
|
||||
<el-radio-group v-model="approverConfig.refuse.handler" class="ml-4">
|
||||
<el-radio label="TO_END" size="large">直接结束流程</el-radio>
|
||||
<el-radio label="TO_NODE" size="large" v-if="rejectNodeList.length > 0">驳回到指定节点</el-radio>
|
||||
</el-radio-group>
|
||||
<el-select v-if="approverConfig.refuse.handler==='TO_NODE' && rejectNodeList.length > 0" v-model="approverConfig.refuse.nodeId"
|
||||
placeholder="驳回节点" class="w-1/2 mb-2">
|
||||
<el-option
|
||||
v-for="item in rejectNodeList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="表单权限">
|
||||
<form-perm :form-perm="approverConfig.formPerms"></form-perm>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="事件通知">
|
||||
<event-config v-model="approverConfig.eventConfig"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-drawer>
|
||||
</template>
|
||||
<script setup type="ts">
|
||||
import {setTypes} from '../../utils/const'
|
||||
import {useStore} from '../../stores/index'
|
||||
import {useFlowStore} from '../../stores/flow'
|
||||
import FormPerm from './components/formPerm.vue'
|
||||
import EventConfig from './components/eventConfig.vue'
|
||||
import selectShow from "/@/components/OrgSelector/index.vue";
|
||||
import {validateNull} from "/@/utils/validate";
|
||||
import other from "/@/utils/other";
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
|
||||
//驳回节点列表
|
||||
const rejectNodeList = computed(() => {
|
||||
let values = []
|
||||
const excType = [1]
|
||||
const arr = {};
|
||||
const obj = {};
|
||||
|
||||
produceSerialNodeList(undefined, flowStore.step3, arr, obj, true)
|
||||
|
||||
const k = arr[approverConfig.value.id];
|
||||
|
||||
if (k == undefined) {
|
||||
return []
|
||||
}
|
||||
|
||||
for (const item of k) {
|
||||
const type = obj[item].type;
|
||||
if (excType.indexOf(type) > -1 && obj[item].id != approverConfig.value.id) {
|
||||
values.push({id: obj[item].id, name: obj[item].nodeName})
|
||||
}
|
||||
}
|
||||
return values
|
||||
});
|
||||
|
||||
function produceSerialNodeList(parentId, process, nodeArr, nodeObj, noBranch) {
|
||||
if (validateNull(process?.id)) {
|
||||
return;
|
||||
}
|
||||
const nodeId = process.id;
|
||||
nodeObj[nodeId] = process;
|
||||
|
||||
if (validateNull(parentId)) {
|
||||
const arr = [];
|
||||
arr.push(nodeId)
|
||||
nodeArr[nodeId] = arr;
|
||||
} else {
|
||||
const p = nodeArr[parentId];
|
||||
let parentType = nodeObj[parentId].type;
|
||||
|
||||
if ((parentType == 5 || parentType == 8) && !noBranch) {
|
||||
nodeArr[nodeId] = [];
|
||||
} else {
|
||||
const arr1 = other.deepClone(p);
|
||||
arr1.push(nodeId)
|
||||
nodeArr[nodeId] = arr1;
|
||||
}
|
||||
}
|
||||
|
||||
const type = process.type;
|
||||
const children = process.childNode;
|
||||
|
||||
if (type === 5 || type === 8 || type === 4) {
|
||||
const branchs = process.conditionNodes;
|
||||
for (const item of branchs) {
|
||||
produceSerialNodeList(nodeId, item, nodeArr, nodeObj, false)
|
||||
}
|
||||
|
||||
if (!validateNull(children?.id)) {
|
||||
produceSerialNodeList(nodeId, children, nodeArr, nodeObj, true)
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!validateNull(children?.id)) {
|
||||
produceSerialNodeList(nodeId, children, nodeArr, nodeObj, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const step2FormList = computed(() => {
|
||||
return flowStore.step2;
|
||||
})
|
||||
|
||||
const step2FormUserList = computed(() => {
|
||||
return step2FormList.value.filter(res => res.type === 'SelectUser');
|
||||
})
|
||||
|
||||
const openEvent = () => {
|
||||
let value = step2FormList.value;
|
||||
var arr = {};
|
||||
let formPerms = approverConfig.value.formPerms;
|
||||
|
||||
for (var item of value) {
|
||||
arr[item.id] = "R"
|
||||
if (item.type === 'Layout') {
|
||||
arr[item.id] = "E"
|
||||
}
|
||||
if (formPerms[item.id]) {
|
||||
arr[item.id] = formPerms[item.id]
|
||||
}
|
||||
if (item.type === 'Layout') {
|
||||
let value1 = item.props.value;
|
||||
for (var it of value1) {
|
||||
arr[it.id] = "R"
|
||||
if (formPerms[it.id]) {
|
||||
arr[it.id] = formPerms[it.id]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
approverConfig.value.formPerms = arr;
|
||||
}
|
||||
|
||||
|
||||
let approverConfig = ref({})
|
||||
|
||||
|
||||
let store = useStore()
|
||||
let {setApproverConfig, setApprover} = store
|
||||
let approverConfigData = computed(() => store.approverConfigData)
|
||||
let approverDrawer = computed(() => store.approverDrawer)
|
||||
let visible = computed({
|
||||
get() {
|
||||
return approverDrawer.value
|
||||
},
|
||||
set() {
|
||||
closeDrawer()
|
||||
}
|
||||
})
|
||||
watch(approverConfigData, (val) => {
|
||||
approverConfig.value = val.value
|
||||
})
|
||||
//用户表单是否是多选
|
||||
const isMultiUserForm = (id) => {
|
||||
if (!(id)) {
|
||||
return false
|
||||
}
|
||||
let t = step2FormUserList.value.filter(res => res.id === id)[0].props.multi;
|
||||
return t;
|
||||
}
|
||||
//监听用户选择表单值变化
|
||||
watch(() => approverConfig.value.formUserId, (val) => {
|
||||
if (val) {
|
||||
approverConfig.value.formUserName = step2FormUserList.value.filter(res => res.id === val)[0].name
|
||||
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
||||
//审批人类型变化
|
||||
const assignedTypeChangeEvent = (e) => {
|
||||
approverConfig.value.nodeUserList = [];
|
||||
}
|
||||
|
||||
const saveApprover = () => {
|
||||
approverConfig.value.error = !checkApproval(approverConfig.value);
|
||||
setApproverConfig({
|
||||
value: approverConfig.value,
|
||||
flag: true,
|
||||
id: approverConfigData.value.id
|
||||
})
|
||||
closeDrawer()
|
||||
}
|
||||
const closeDrawer = () => {
|
||||
setApprover(false)
|
||||
}
|
||||
|
||||
const checkApproval = (nodeConfig) => {
|
||||
if (nodeConfig.assignedType == 1 || nodeConfig.assignedType == 3) {
|
||||
|
||||
//指定成员
|
||||
if (nodeConfig.nodeUserList.length == 0) {
|
||||
return false;
|
||||
|
||||
}
|
||||
} else if (nodeConfig.assignedType == 8 && nodeConfig.formUserId.length == 0) {
|
||||
//表单
|
||||
return false;
|
||||
}
|
||||
|
||||
//审批人为空
|
||||
if (nodeConfig?.nobody?.handler === 'TO_USER' && nodeConfig.nobody.assignedUser.length === 0) {
|
||||
return false;
|
||||
}
|
||||
//操作权限
|
||||
let operList = nodeConfig.operList;
|
||||
let length = operList?.filter(res => res.checked).length;
|
||||
if (length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,365 @@
|
||||
<script setup lang="ts">
|
||||
import { useFlowStore } from '../../../stores/flow';
|
||||
import { getCurrentInstance } from 'vue';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
|
||||
const step2FormList = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
return step2;
|
||||
})
|
||||
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
|
||||
//表单
|
||||
const formList = computed(() => {
|
||||
let value = step2FormList.value;
|
||||
|
||||
let $deepCopy = other.deepClone(value.filter(res =>
|
||||
res.type != 'MultiSelect' &&
|
||||
res.type != 'Description' &&
|
||||
res.type != 'SelectMultiUser' &&
|
||||
res.type != 'SelectMultiDept' &&
|
||||
res.type != 'Layout' &&
|
||||
res.type != 'UploadImage' &&
|
||||
res.type != 'UploadFile'
|
||||
));
|
||||
|
||||
|
||||
$deepCopy.push({
|
||||
id: 'root',
|
||||
name: '发起人',
|
||||
type: "SelectUser",
|
||||
typeName: "用户"
|
||||
})
|
||||
|
||||
return $deepCopy;
|
||||
})
|
||||
let props = defineProps({
|
||||
condition: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const formIdObj = computed(() => {
|
||||
var obj = {}
|
||||
for (var item of formList.value) {
|
||||
obj[item.id] = item;
|
||||
}
|
||||
return obj
|
||||
})
|
||||
|
||||
const conditionSelectVal = computed(
|
||||
{
|
||||
get(){
|
||||
|
||||
let value = props.condition.value;
|
||||
return (value&&value.length>0)?(value.map(res=>res.key)):undefined;
|
||||
|
||||
},
|
||||
set(t){
|
||||
|
||||
let options = (formIdObj.value)[props.condition.key].props.options;
|
||||
|
||||
|
||||
let filterElement = options.filter(res=>t.indexOf(res.key)>=0);
|
||||
props.condition.value = filterElement
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
//表达式
|
||||
let expression = ref(
|
||||
{
|
||||
"SelectDept": [
|
||||
{
|
||||
key: "in",
|
||||
name: "属于"
|
||||
}, {
|
||||
key: "notin",
|
||||
name: "不属于"
|
||||
}
|
||||
],
|
||||
|
||||
"SelectUser": [
|
||||
{
|
||||
key: "in",
|
||||
name: "属于"
|
||||
}, {
|
||||
key: "notin",
|
||||
name: "不属于"
|
||||
}
|
||||
],
|
||||
|
||||
"Input": [
|
||||
{
|
||||
key: "==",
|
||||
name: "等于"
|
||||
}, {
|
||||
key: "!=",
|
||||
name: "不等于"
|
||||
}, {
|
||||
key: "contain",
|
||||
name: "包含"
|
||||
}, {
|
||||
key: "notcontain",
|
||||
name: "不包含"
|
||||
}
|
||||
],
|
||||
|
||||
"Textarea": [
|
||||
{
|
||||
key: "==",
|
||||
name: "等于"
|
||||
}, {
|
||||
key: "!=",
|
||||
name: "不等于"
|
||||
},{
|
||||
key: "contain",
|
||||
name: "包含"
|
||||
}, {
|
||||
key: "notcontain",
|
||||
name: "不包含"
|
||||
}
|
||||
],
|
||||
"Number": [
|
||||
{
|
||||
key: "==",
|
||||
name: "等于"
|
||||
}, {
|
||||
key: "!=",
|
||||
name: "不等于"
|
||||
}, {
|
||||
key: ">",
|
||||
name: "大于"
|
||||
}, {
|
||||
key: ">=",
|
||||
name: "大于等于"
|
||||
}, {
|
||||
key: "<",
|
||||
name: "小于"
|
||||
}, {
|
||||
key: "<=",
|
||||
name: "小于等于"
|
||||
}
|
||||
],
|
||||
"Date": [
|
||||
{
|
||||
key: "==",
|
||||
name: "等于"
|
||||
}, {
|
||||
key: "!=",
|
||||
name: "不等于"
|
||||
}, {
|
||||
key: ">",
|
||||
name: "大于"
|
||||
}, {
|
||||
key: ">=",
|
||||
name: "大于等于"
|
||||
}, {
|
||||
key: "<",
|
||||
name: "小于"
|
||||
}, {
|
||||
key: "<=",
|
||||
name: "小于等于"
|
||||
}
|
||||
],
|
||||
"DateTime": [
|
||||
{
|
||||
key: "==",
|
||||
name: "等于"
|
||||
}, {
|
||||
key: "!=",
|
||||
name: "不等于"
|
||||
}, {
|
||||
key: ">",
|
||||
name: "大于"
|
||||
}, {
|
||||
key: ">=",
|
||||
name: "大于等于"
|
||||
}, {
|
||||
key: "<",
|
||||
name: "小于"
|
||||
}, {
|
||||
key: "<=",
|
||||
name: "小于等于"
|
||||
}
|
||||
],
|
||||
"Time": [
|
||||
{
|
||||
key: "==",
|
||||
name: "等于"
|
||||
}, {
|
||||
key: "!=",
|
||||
name: "不等于"
|
||||
}, {
|
||||
key: ">",
|
||||
name: "大于"
|
||||
}, {
|
||||
key: ">=",
|
||||
name: "大于等于"
|
||||
}, {
|
||||
key: "<",
|
||||
name: "小于"
|
||||
}, {
|
||||
key: "<=",
|
||||
name: "小于等于"
|
||||
}
|
||||
],
|
||||
"Money": [
|
||||
{
|
||||
key: "==",
|
||||
name: "等于"
|
||||
}, {
|
||||
key: "!=",
|
||||
name: "不等于"
|
||||
}, {
|
||||
key: ">",
|
||||
name: "大于"
|
||||
}, {
|
||||
key: ">=",
|
||||
name: "大于等于"
|
||||
}, {
|
||||
key: "<",
|
||||
name: "小于"
|
||||
}, {
|
||||
key: "<=",
|
||||
name: "小于等于"
|
||||
}
|
||||
],
|
||||
"SingleSelect": [
|
||||
{
|
||||
key: "in",
|
||||
name: "属于"
|
||||
}, {
|
||||
key: "notin",
|
||||
name: "不属于"
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
import selectShow from '/@/components/OrgSelector/index.vue';
|
||||
import other from '/@/utils/other';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-select v-model="condition.key" placeholder="选择表单" style="width: 100%;">
|
||||
<el-option
|
||||
v-for="f in formList"
|
||||
:key="f.id"
|
||||
:label="f.name"
|
||||
:value="f.id"
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
<el-select v-model="condition.expression" placeholder="选择关系" style="width: 100%;margin-top: 20px">
|
||||
|
||||
<el-option
|
||||
v-for="f in expression[formIdObj[condition.key]?.type]"
|
||||
:key="f.key"
|
||||
:label="f.name"
|
||||
:value="f.key"
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
<el-input v-model="condition.value" v-if="formIdObj[condition.key]?.type==='Input'||
|
||||
formIdObj[condition.key]?.type==='Textarea'
|
||||
" style="margin-top: 20px;" placeholder="条件值"></el-input>
|
||||
|
||||
|
||||
<el-input-number v-model="condition.value"
|
||||
v-if="formIdObj[condition.key]?.type==='Money'||
|
||||
formIdObj[condition.key]?.type==='Number'
|
||||
"
|
||||
placeholder="条件值"
|
||||
style="width: 100%;margin-top: 20px"
|
||||
controls-position="right"
|
||||
/>
|
||||
|
||||
|
||||
<el-date-picker
|
||||
value-format="YYYY-MM-DD"
|
||||
type="date"
|
||||
class="formDate"
|
||||
|
||||
v-model="condition.value"
|
||||
v-if="formIdObj[condition.key]?.type==='Date'
|
||||
"
|
||||
placeholder="条件值"
|
||||
style="width: 100%;margin-top: 20px"
|
||||
|
||||
/>
|
||||
<el-time-picker
|
||||
arrow-control
|
||||
value-format="HH:mm:ss"
|
||||
|
||||
|
||||
class="formDate"
|
||||
|
||||
v-model="condition.value"
|
||||
v-if="formIdObj[condition.key]?.type==='Time'
|
||||
"
|
||||
placeholder="条件值"
|
||||
style="width: 100%;margin-top: 20px"
|
||||
|
||||
/>
|
||||
|
||||
<el-date-picker
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="datetime"
|
||||
class="formDate"
|
||||
|
||||
v-model="condition.value"
|
||||
v-if="formIdObj[condition.key]?.type==='DateTime'
|
||||
"
|
||||
placeholder="条件值"
|
||||
style="width: 100%;margin-top: 20px"
|
||||
|
||||
/>
|
||||
|
||||
<el-select v-model="conditionSelectVal"
|
||||
v-if="formIdObj[condition.key]?.type==='SingleSelect'
|
||||
"
|
||||
style="width: 100%;margin-top: 20px"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
|
||||
placeholder="请选择值">
|
||||
<el-option
|
||||
v-for="item in formIdObj[condition.key].props.options"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
<div style="margin-top: 20px">
|
||||
<select-show v-if="formIdObj[condition.key]?.type==='SelectUser'
|
||||
" v-model:orgList="condition.value" type="org" :multiple="true"></select-show>
|
||||
</div>
|
||||
<div style="margin-top: 20px">
|
||||
|
||||
<select-show v-if="formIdObj[condition.key]?.type==='SelectDept'
|
||||
" v-model:orgList="condition.value" type="dept" :multiple="true"></select-show>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.formDate div.el-input__wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:deep(.formDate) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="mb-4">节点任务完成推送接口:</div>
|
||||
<el-input type="textarea" show-word-limit maxlength="200" rows="5" :model-value="props.modelValue"
|
||||
@input="emit('update:modelValue',$event)"
|
||||
placeholder="此节点任务完成后,会往目标接口推送事件通知"/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,101 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useFlowStore } from '/@/views/flow/workflow/stores/flow';
|
||||
|
||||
defineProps({
|
||||
formPerm: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
hideKey: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
const step2FormList = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
return step2;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: row; background-color: var(--el-fill-color-light)" effect="dark">
|
||||
<div class="f1">表单字段</div>
|
||||
<div class="f2">只读</div>
|
||||
<div class="f3">编辑</div>
|
||||
<div class="f4">隐藏</div>
|
||||
</div>
|
||||
|
||||
<div v-if="step2FormList.length == 0">
|
||||
<el-empty description="暂无表单" />
|
||||
</div>
|
||||
<div v-for="item in step2FormList" :key="item.id">
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<div class="f1">
|
||||
<span>{{ item.name }}</span>
|
||||
<span v-if="item.required" style="color: #c75450"> * </span>
|
||||
</div>
|
||||
|
||||
<el-radio-group v-model="formPerm[item.id]" size="large">
|
||||
<div class="f2">
|
||||
<el-radio size="large" label="R"><span></span></el-radio>
|
||||
</div>
|
||||
<div class="f3">
|
||||
<el-radio :disabled="!(hideKey.length == 0 || hideKey.indexOf('E') < 0)" size="large" label="E"><span></span> </el-radio>
|
||||
</div>
|
||||
<div class="f4">
|
||||
<el-radio size="large" label="H"><span></span></el-radio>
|
||||
</div>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div v-if="item.type === 'Layout'">
|
||||
<div v-for="item1 in item.props.value" :key="item1.id">
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<div class="f1">
|
||||
<span> {{ '\u00A0\u00A0\u00A0\u00A0-' + item1.name }}</span>
|
||||
<span v-if="item1.required" style="color: #c75450"> * </span>
|
||||
</div>
|
||||
|
||||
<el-radio-group v-model="formPerm[item1.id]" size="large">
|
||||
<div class="f2">
|
||||
<el-radio size="large" label="R"><span></span></el-radio>
|
||||
</div>
|
||||
<div class="f3">
|
||||
<el-radio :disabled="!(hideKey.length == 0 || hideKey.indexOf('E') < 0)" size="large" label="E"><span></span> </el-radio>
|
||||
</div>
|
||||
<div class="f4">
|
||||
<el-radio size="large" label="H"><span></span></el-radio>
|
||||
</div>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.f1 {
|
||||
width: calc(100% - 80px - 80px - 80px);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.f2 {
|
||||
width: 80px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.f3 {
|
||||
width: 80px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.f4 {
|
||||
width: 80px;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
:append-to-body="true"
|
||||
title="条件设置"
|
||||
v-model="visible"
|
||||
:show-close="false"
|
||||
:size="550"
|
||||
@open="openEvent"
|
||||
:before-close="saveCondition"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h3 :id="titleId" :class="titleClass">条件设置</h3>
|
||||
</template>
|
||||
<el-form label-width="120px">
|
||||
<el-form-item label="条件组关系">
|
||||
<el-switch v-model="conditionConfig.groupMode" active-text="且" inactive-text="或" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-card class="box-card" v-for="(item, index) in conditionConfig.conditionList" :key="index" style="margin-bottom: 20px">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>条件组{{ index + 1 }}</span>
|
||||
<el-switch v-model="item.mode" active-text="且" inactive-text="或" />
|
||||
|
||||
<el-button text v-if="conditionConfig.conditionList.length > 1" @click="deleteGroup(index)" icon="Delete"></el-button>
|
||||
</div>
|
||||
</template>
|
||||
<div v-for="(item1, index1) in item.conditionList" :key="index1">
|
||||
<div style="display: flex; flex-direction: row; justify-content: space-between">
|
||||
<div>
|
||||
{{ index1 == 0 ? '当' : item.mode ? '且' : '或' }}
|
||||
</div>
|
||||
<div>
|
||||
<el-button text @click="deleteCondition(index, index1)" v-if="item.conditionList.length > 1" icon="Delete"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<condition :condition="item1"></condition>
|
||||
</div>
|
||||
<el-button dark type="success" style="margin-top: 20px" @click="addOneCondition(item, index)">添加条件</el-button>
|
||||
</el-card>
|
||||
<el-button dark type="primary" @click="addOneConditionGroup">添加条件组</el-button>
|
||||
</el-drawer>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, watch, computed, getCurrentInstance } from 'vue';
|
||||
import $func from '../../utils/index';
|
||||
import { useStore } from '../../stores/index';
|
||||
|
||||
let conditionsConfig = ref({
|
||||
conditionNodes: [],
|
||||
});
|
||||
let conditionConfig = ref({});
|
||||
let PriorityLevel = ref('');
|
||||
|
||||
let store = useStore();
|
||||
let { setCondition, setConditionsConfig } = store;
|
||||
let conditionsConfig1 = computed(() => store.conditionsConfig1);
|
||||
let conditionDrawer = computed(() => store.conditionDrawer);
|
||||
let visible = computed({
|
||||
get() {
|
||||
return conditionDrawer.value;
|
||||
},
|
||||
set() {
|
||||
closeDrawer();
|
||||
},
|
||||
});
|
||||
//删除条件组
|
||||
const deleteGroup = (index) => {
|
||||
conditionConfig.value?.conditionList.splice(index, 1);
|
||||
};
|
||||
//刪除单个条件
|
||||
const deleteCondition = (index, index1) => {
|
||||
conditionConfig.value?.conditionList[index].conditionList.splice(index1, 1);
|
||||
};
|
||||
|
||||
//添加一个条件组
|
||||
const addOneConditionGroup = () => {
|
||||
conditionConfig.value?.conditionList.push({
|
||||
mode: true,
|
||||
conditionList: [{}],
|
||||
});
|
||||
};
|
||||
//添加组内一个条件
|
||||
const addOneCondition = (item, index) => {
|
||||
let conditionList = item.conditionList;
|
||||
if (!conditionList) {
|
||||
conditionList = [];
|
||||
}
|
||||
conditionList.push({});
|
||||
item.conditionList = conditionList;
|
||||
};
|
||||
|
||||
import Condition from './components/condition.vue';
|
||||
import { useFlowStore } from '../../stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
const step2FormList = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
return step2;
|
||||
});
|
||||
|
||||
const openEvent = () => {};
|
||||
|
||||
watch(conditionsConfig1, (val) => {
|
||||
let conditionNodes = val.value.conditionNodes;
|
||||
|
||||
for (var item of conditionNodes) {
|
||||
let groupList = item.conditionList;
|
||||
for (var group of groupList) {
|
||||
let conditionList = group.conditionList;
|
||||
for (var con of conditionList) {
|
||||
let key = con.key;
|
||||
if (key === 'root') {
|
||||
con.keyType = 'SelectUser';
|
||||
} else {
|
||||
let ele = step2FormList.value.filter((res) => res.id === key);
|
||||
if (ele.length > 0) {
|
||||
con.keyType = ele[0].type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conditionsConfig.value = val.value;
|
||||
PriorityLevel.value = val.priorityLevel;
|
||||
conditionConfig.value = val.priorityLevel ? conditionsConfig.value.conditionNodes[val.priorityLevel - 1] : { nodeUserList: [], conditionList: [] };
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const saveCondition = () => {
|
||||
closeDrawer();
|
||||
var a = conditionsConfig.value.conditionNodes.splice(PriorityLevel.value - 1, 1); //截取旧下标
|
||||
conditionsConfig.value.conditionNodes.splice(conditionConfig.value.priorityLevel - 1, 0, a[0]); //填充新下标
|
||||
conditionsConfig.value.conditionNodes.map((item, index) => {
|
||||
item.priorityLevel = index + 1;
|
||||
});
|
||||
|
||||
for (var i = 0; i < conditionsConfig.value.conditionNodes.length; i++) {
|
||||
let conditionNode = conditionsConfig.value.conditionNodes[i];
|
||||
|
||||
conditionNode.error = false;
|
||||
let conditionList = conditionNode.conditionList;
|
||||
if (i != conditionsConfig.value.conditionNodes.length - 1) {
|
||||
var error = conditionList.length == 0;
|
||||
|
||||
for (var it of conditionList) {
|
||||
error = it.conditionList.length == 0;
|
||||
for (var ite of it.conditionList) {
|
||||
if (!ite.key || !ite.expression || !ite.value) {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
conditionNode.error = error;
|
||||
}
|
||||
|
||||
conditionNode.placeHolder = $func.conditionStr(conditionsConfig.value, i);
|
||||
}
|
||||
setConditionsConfig({
|
||||
value: conditionsConfig.value,
|
||||
flag: true,
|
||||
id: conditionsConfig1.value.id,
|
||||
});
|
||||
};
|
||||
|
||||
const closeDrawer = (val) => {
|
||||
setCondition(false);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
:append-to-body="true"
|
||||
title="抄送人设置"
|
||||
v-model="visible"
|
||||
@open="openEvent"
|
||||
class="set_copyer"
|
||||
:show-close="false"
|
||||
:size="550"
|
||||
:before-close="saveCopyer"
|
||||
>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="设置抄送人">
|
||||
<select-show v-model:orgList="copyerConfig.nodeUserList" type="org" :multiple="true"></select-show>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="表单权限">
|
||||
<form-perm :hide-key="['E']" :form-perm="copyerConfig.formPerms"></form-perm>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-drawer>
|
||||
</template>
|
||||
<script setup>
|
||||
import selectShow from '/@/components/OrgSelector/index.vue';
|
||||
|
||||
import $func from '../../utils/index';
|
||||
import { useStore } from '../../stores/index';
|
||||
import { ref, watch, computed } from 'vue';
|
||||
let copyerConfig = ref({});
|
||||
|
||||
import { useFlowStore } from '../../stores/flow';
|
||||
import { ElTable } from 'element-plus';
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
import FormPerm from './components/formPerm.vue';
|
||||
|
||||
const step2FormList = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
return step2;
|
||||
});
|
||||
|
||||
let store = useStore();
|
||||
let { setCopyerConfig, setCopyer } = store;
|
||||
let copyerDrawer = computed(() => store.copyerDrawer);
|
||||
let copyerConfig1 = computed(() => store.copyerConfig1);
|
||||
let visible = computed({
|
||||
get() {
|
||||
return copyerDrawer.value;
|
||||
},
|
||||
set() {
|
||||
closeDrawer();
|
||||
},
|
||||
});
|
||||
watch(copyerConfig1, (val) => {
|
||||
copyerConfig.value = val.value;
|
||||
});
|
||||
|
||||
const openEvent = () => {
|
||||
let value = step2FormList.value;
|
||||
var arr = {};
|
||||
let formPerms = copyerConfig.value.formPerms;
|
||||
|
||||
for (var item of value) {
|
||||
arr[item.id] = 'R';
|
||||
// if (item.type === 'Layout') {
|
||||
// arr[item.id] = "R"
|
||||
// }
|
||||
if (formPerms[item.id]) {
|
||||
arr[item.id] = formPerms[item.id];
|
||||
}
|
||||
if (item.type === 'Layout') {
|
||||
let value1 = item.props.value;
|
||||
for (var it of value1) {
|
||||
arr[it.id] = 'R';
|
||||
if (formPerms[it.id]) {
|
||||
arr[it.id] = formPerms[it.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
copyerConfig.value.formPerms = arr;
|
||||
};
|
||||
|
||||
const saveCopyer = () => {
|
||||
copyerConfig.value.error = !$func.copyerStr(copyerConfig.value);
|
||||
setCopyerConfig({
|
||||
value: copyerConfig.value,
|
||||
flag: true,
|
||||
id: copyerConfig1.value.id,
|
||||
});
|
||||
closeDrawer();
|
||||
};
|
||||
const closeDrawer = () => {
|
||||
setCopyer(false);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
:append-to-body="true"
|
||||
:title="$t('flow.initiator')"
|
||||
v-model="visible"
|
||||
class="set_promoter"
|
||||
:show-close="false"
|
||||
@open="openEvent"
|
||||
:size="550"
|
||||
:before-close="savePromoter"
|
||||
>
|
||||
<div class="demo-drawer__content">
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="设置发起人">
|
||||
<select-show v-model:orgList="starterConfig.nodeUserList" type="org" :multiple="true"></select-show>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="表单权限">
|
||||
<form-perm :form-perm="starterConfig.formPerms"></form-perm>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
<script setup>
|
||||
import selectShow from '/@/components/OrgSelector/index.vue';
|
||||
import { useFlowStore } from '../../stores/flow';
|
||||
import { useStore } from '../../stores/index';
|
||||
import FormPerm from './components/formPerm.vue';
|
||||
|
||||
let store = useStore();
|
||||
|
||||
let starterConfig = ref({});
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
let starterConfigData = computed(() => store.starterConfigData);
|
||||
watch(starterConfigData, (val) => {
|
||||
starterConfig.value = val.value;
|
||||
});
|
||||
const step2FormList = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
return step2;
|
||||
});
|
||||
|
||||
const openEvent = () => {
|
||||
let value = step2FormList.value;
|
||||
var arr = {};
|
||||
let formPerms = starterConfig.value.formPerms;
|
||||
for (var item of value) {
|
||||
arr[item.id] = 'E';
|
||||
|
||||
if (formPerms[item.id]) {
|
||||
arr[item.id] = formPerms[item.id];
|
||||
}
|
||||
if (item.type === 'Layout') {
|
||||
let value1 = item.props.value;
|
||||
for (var it of value1) {
|
||||
arr[it.id] = 'E';
|
||||
if (formPerms[it.id]) {
|
||||
arr[it.id] = formPerms[it.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
starterConfig.value.formPerms = arr;
|
||||
};
|
||||
|
||||
let { setPromoter, setStarterConfig } = store;
|
||||
let promoterDrawer = computed(() => store.promoterDrawer);
|
||||
let visible = computed({
|
||||
get() {
|
||||
return promoterDrawer.value;
|
||||
},
|
||||
set() {
|
||||
closeDrawer();
|
||||
},
|
||||
});
|
||||
|
||||
const savePromoter = () => {
|
||||
setStarterConfig({
|
||||
value: starterConfig.value,
|
||||
flag: true,
|
||||
id: starterConfigData.value.id,
|
||||
});
|
||||
closeDrawer();
|
||||
};
|
||||
const closeDrawer = () => {
|
||||
setPromoter(false);
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,131 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
let isInput = ref(false);
|
||||
|
||||
let props = defineProps({
|
||||
nodeConfig: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const blurEvent = (index) => {
|
||||
if (index || index === 0) {
|
||||
isInputList.value[index] = false;
|
||||
props.nodeConfig.conditionNodes[index].nodeName = props.nodeConfig.conditionNodes[index].nodeName || '条件';
|
||||
} else {
|
||||
isInput.value = false;
|
||||
props.nodeConfig.nodeName = props.nodeConfig.nodeName || defaultText;
|
||||
}
|
||||
};
|
||||
import { bgColors, placeholderList } from '/@/views/flow/workflow/utils/const';
|
||||
import { computed } from 'vue';
|
||||
import addNode from '../addNode.vue';
|
||||
|
||||
import $func from '/@/views/flow/workflow/utils';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
let defaultText = computed(() => {
|
||||
return placeholderList[props.nodeConfig.type];
|
||||
});
|
||||
|
||||
const { t } = useI18n;
|
||||
var placeHolder = computed(() => {
|
||||
if (props.nodeConfig.type == 0) {
|
||||
return $func.arrToStr(props.nodeConfig.nodeUserList) || t('flow.allUser');
|
||||
}
|
||||
if (props.nodeConfig.type == 1) {
|
||||
return $func.setApproverStr(props.nodeConfig);
|
||||
}
|
||||
if (props.nodeConfig.type == 2) {
|
||||
return $func.copyerStr(props.nodeConfig);
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
const clickEvent = (index) => {
|
||||
if (index || index === 0) {
|
||||
isInputList.value[index] = true;
|
||||
} else {
|
||||
isInput.value = true;
|
||||
}
|
||||
};
|
||||
let isInputList = ref([]);
|
||||
|
||||
const delNode = () => {
|
||||
emits('update:nodeConfig', props.nodeConfig.childNode);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="node-wrap">
|
||||
<div class="node-wrap-box" :class="(nodeConfig.type == 0 ? 'start-node ' : '') + (nodeConfig.error ? 'active error' : '')">
|
||||
<div class="title" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
|
||||
<span v-if="nodeConfig.type == 0">{{ nodeConfig.nodeName }}</span>
|
||||
<template v-else>
|
||||
<span class="iconfont">{{ '' }}</span>
|
||||
<input
|
||||
v-if="isInput"
|
||||
type="text"
|
||||
class="ant-input editable-title-input"
|
||||
@blur="blurEvent()"
|
||||
@focus="$event.currentTarget.select()"
|
||||
v-focus
|
||||
v-model="nodeConfig.nodeName"
|
||||
:placeholder="defaultText"
|
||||
/>
|
||||
<span v-else class="editable-title" @click="clickEvent()">{{ nodeConfig.nodeName }}</span>
|
||||
<i class="anticon anticon-close close" @click="delNode"></i>
|
||||
</template>
|
||||
</div>
|
||||
<div class="content" @click="openConfigDrawer">
|
||||
<div class="text">
|
||||
{{ placeHolder?.length > 0 ? placeHolder : '请选择' + defaultText }}
|
||||
</div>
|
||||
<i class="anticon anticon-right arrow"></i>
|
||||
</div>
|
||||
|
||||
<div class="error_tip" v-if="nodeConfig.error">
|
||||
<i class="anticon anticon-exclamation-circle"></i>
|
||||
</div>
|
||||
</div>
|
||||
<addNode :current-node="nodeConfig" v-model:childNodeP="nodeConfig.childNode" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@import '/@/views/flow/workflow/css/workflow.css';
|
||||
|
||||
.error_tip {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
transform: translate(150%, 0px);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.promoter_person .el-dialog__body {
|
||||
padding: 10px 20px 14px 20px;
|
||||
}
|
||||
|
||||
.selected_list {
|
||||
margin-bottom: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.selected_list span {
|
||||
margin-right: 10px;
|
||||
padding: 3px 6px 3px 9px;
|
||||
line-height: 12px;
|
||||
white-space: nowrap;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgba(220, 220, 220, 1);
|
||||
}
|
||||
|
||||
.selected_list img {
|
||||
margin-left: 5px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,481 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <approval :node-config="nodeConfig" v-if="nodeConfig.type==1"></approval>-->
|
||||
<div class="node-wrap" v-if="nodeConfig.type < 3">
|
||||
<div class="node-wrap-box" :class="(nodeConfig.type == 0 ? 'start-node ' : '') + (nodeConfig.error ? 'active error' : '')">
|
||||
<div class="title" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
|
||||
<span v-if="nodeConfig.type == 0">{{ nodeConfig.nodeName }}</span>
|
||||
<template v-else>
|
||||
<span class="iconfont">{{ nodeConfig.type == 1 ? '' : '' }}</span>
|
||||
<input
|
||||
v-if="isInput"
|
||||
type="text"
|
||||
class="ant-input editable-title-input"
|
||||
@blur="blurEvent()"
|
||||
@focus="$event.currentTarget.select()"
|
||||
v-focus
|
||||
v-model="nodeConfig.nodeName"
|
||||
:placeholder="defaultText"
|
||||
/>
|
||||
<span v-else class="editable-title" @click="clickEvent()">{{ nodeConfig.nodeName }}</span>
|
||||
<i class="anticon anticon-close close" @click="delNode"></i>
|
||||
</template>
|
||||
</div>
|
||||
<div class="content" @click="openConfigDrawer">
|
||||
<div class="text">
|
||||
{{ placeHolder?.length > 0 ? placeHolder : '请选择' + defaultText }}
|
||||
</div>
|
||||
<i class="anticon anticon-right arrow"></i>
|
||||
</div>
|
||||
|
||||
<div class="error_tip" v-if="nodeConfig.error">
|
||||
<i class="anticon anticon-exclamation-circle"></i>
|
||||
</div>
|
||||
</div>
|
||||
<addNode :current-node="nodeConfig" v-model:childNodeP="nodeConfig.childNode" />
|
||||
</div>
|
||||
<div class="branch-wrap" v-if="nodeConfig.type == 4">
|
||||
<div class="branch-box-wrap">
|
||||
<div class="branch-box">
|
||||
<button class="add-branch" @click="addTerm">添加条件</button>
|
||||
<div class="col-box" v-for="(item, index) in nodeConfig.conditionNodes" :key="index">
|
||||
<div class="condition-node">
|
||||
<div class="condition-node-box">
|
||||
<div class="auto-judge" :class="item.error ? 'error active' : ''">
|
||||
<div class="sort-left" v-if="index != 0" @click="arrTransfer(index, -1)"><</div>
|
||||
<div class="title-wrapper">
|
||||
<input
|
||||
style="width: 50%"
|
||||
v-if="isInputList[index]"
|
||||
type="text"
|
||||
class="ant-input editable-title-input"
|
||||
@blur="blurEvent(index)"
|
||||
@focus="$event.currentTarget.select()"
|
||||
v-focus
|
||||
v-model="item.nodeName"
|
||||
/>
|
||||
<span v-else class="editable-title" @click="clickEvent(index)">{{ item.nodeName }}</span>
|
||||
<span class="priority-title">优先级{{ item.priorityLevel }}</span>
|
||||
<i class="anticon anticon-close close" @click="delTerm(index)"></i>
|
||||
</div>
|
||||
<div class="sort-right" v-if="index != nodeConfig.conditionNodes.length - 1" @click="arrTransfer(index)">></div>
|
||||
<div class="content" v-if="index < nodeConfig.conditionNodes.length - 1" @click="openConfigDrawer(item.priorityLevel)">
|
||||
{{ $func.conditionStr(nodeConfig, index) }}
|
||||
</div>
|
||||
<div class="content" v-else>{{ $func.conditionStr(nodeConfig, index) }}</div>
|
||||
<div class="error_tip" v-if="item.error">
|
||||
<i class="anticon anticon-exclamation-circle"></i>
|
||||
</div>
|
||||
</div>
|
||||
<addNode v-model:childNodeP="item.childNode" :current-node="item" />
|
||||
</div>
|
||||
</div>
|
||||
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" />
|
||||
<template v-if="index == 0">
|
||||
<div class="top-left-cover-line"></div>
|
||||
<div class="bottom-left-cover-line"></div>
|
||||
</template>
|
||||
<template v-if="index == nodeConfig.conditionNodes.length - 1">
|
||||
<div class="top-right-cover-line"></div>
|
||||
<div class="bottom-right-cover-line"></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<addNode v-model:childNodeP="nodeConfig.childNode" :current-node="nodeConfig" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="branch-wrap" v-if="nodeConfig.type == 5">
|
||||
<div class="branch-box-wrap">
|
||||
<div class="branch-box">
|
||||
<button class="add-branch" @click="addTerm">添加分支</button>
|
||||
<div class="col-box" v-for="(item, index) in nodeConfig.conditionNodes" :key="index">
|
||||
<div class="condition-node">
|
||||
<div class="condition-node-box">
|
||||
<div class="auto-judge" :class="item.error ? 'error active' : ''">
|
||||
<div class="sort-left" v-if="index != 0" @click="arrTransfer(index, -1)"><</div>
|
||||
<div class="title-wrapper">
|
||||
<input
|
||||
style="width: 50%"
|
||||
v-if="isInputList[index]"
|
||||
type="text"
|
||||
class="ant-input editable-title-input"
|
||||
@blur="blurEvent(index)"
|
||||
@focus="$event.currentTarget.select()"
|
||||
v-focus
|
||||
v-model="item.nodeName"
|
||||
/>
|
||||
<span v-else class="editable-title" @click="clickEvent(index)">{{ item.nodeName }}</span>
|
||||
|
||||
<!-- <span class="priority-title" @click="openConfigDrawer(item.priorityLevel)">优先级{{-->
|
||||
<!-- item.priorityLevel-->
|
||||
<!-- }}</span>-->
|
||||
<i class="anticon anticon-close close" @click="delTerm(index)"></i>
|
||||
</div>
|
||||
<div class="sort-right" v-if="index != nodeConfig.conditionNodes.length - 1" @click="arrTransfer(index)">></div>
|
||||
|
||||
<div class="content">{{ item.placeHolder }}</div>
|
||||
<div class="error_tip" v-if="item.error">
|
||||
<i class="anticon anticon-exclamation-circle"></i>
|
||||
</div>
|
||||
</div>
|
||||
<addNode v-model:childNodeP="item.childNode" :current-node="item" />
|
||||
</div>
|
||||
</div>
|
||||
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" />
|
||||
<template v-if="index == 0">
|
||||
<div class="top-left-cover-line"></div>
|
||||
<div class="bottom-left-cover-line"></div>
|
||||
</template>
|
||||
<template v-if="index == nodeConfig.conditionNodes.length - 1">
|
||||
<div class="top-right-cover-line"></div>
|
||||
<div class="bottom-right-cover-line"></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<addNode v-model:childNodeP="nodeConfig.childNode" :current-node="nodeConfig" />
|
||||
</div>
|
||||
</div>
|
||||
<nodeWrap v-if="nodeConfig.childNode" v-model:nodeConfig="nodeConfig.childNode" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import addNode from './addNode.vue';
|
||||
import Approval from './node/approval.vue';
|
||||
|
||||
import { onMounted, ref, watch, getCurrentInstance, computed } from 'vue';
|
||||
import $func from '../utils/index';
|
||||
import { useStore } from '../stores/index';
|
||||
import { bgColors, placeholderList } from '../utils/const';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
let _uid = getCurrentInstance().uid;
|
||||
|
||||
let props = defineProps({
|
||||
nodeConfig: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
let defaultText = computed(() => {
|
||||
return placeholderList[props.nodeConfig.type];
|
||||
});
|
||||
|
||||
const {t} = useI18n()
|
||||
var placeHolder = computed(() => {
|
||||
if (props.nodeConfig.type == 0) {
|
||||
return $func.arrToStr(props.nodeConfig.nodeUserList) || t('flow.allUser');
|
||||
}
|
||||
if (props.nodeConfig.type == 1) {
|
||||
return $func.setApproverStr(props.nodeConfig);
|
||||
}
|
||||
if (props.nodeConfig.type == 2) {
|
||||
return $func.copyerStr(props.nodeConfig);
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
watch(placeHolder, (value, oldValue, onCleanup) => {
|
||||
props.nodeConfig.placeHolder = value;
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../stores/flow';
|
||||
import other from '/@/utils/other';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
const step2FormList = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
return step2;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => step2FormList.value,
|
||||
(val) => {
|
||||
let nodeConfig = props.nodeConfig;
|
||||
|
||||
if (nodeConfig.type == 1) {
|
||||
//审批人
|
||||
|
||||
if (nodeConfig.assignedType == 8) {
|
||||
//表单人员
|
||||
let formUserId = nodeConfig.formUserId;
|
||||
let length = val.filter((res) => res.id === formUserId).length;
|
||||
if (length == 0) {
|
||||
nodeConfig.formUserId = '';
|
||||
nodeConfig.formUserName = '';
|
||||
nodeConfig.error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nodeConfig.type == 4) {
|
||||
//条件分支
|
||||
var index = 0;
|
||||
var len = nodeConfig.conditionNodes.length;
|
||||
for (var node of nodeConfig.conditionNodes) {
|
||||
if (index >= len - 1) {
|
||||
break;
|
||||
}
|
||||
for (var item1 of node.conditionList) {
|
||||
for (var item2 of item1.conditionList) {
|
||||
let length = val.filter((res) => res.id === item2.key).length;
|
||||
if (length == 0) {
|
||||
item2.key = '';
|
||||
item2.expression = '';
|
||||
item2.keyType = '';
|
||||
item2.value = '';
|
||||
node.error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let isInputList = ref([]);
|
||||
let isInput = ref(false);
|
||||
const resetConditionNodesErr = () => {
|
||||
if (props.nodeConfig.type == 5) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < props.nodeConfig.conditionNodes.length; i++) {
|
||||
let conditionNode = props.nodeConfig.conditionNodes[i];
|
||||
|
||||
conditionNode.error = false;
|
||||
let conditionList = conditionNode.conditionList;
|
||||
if (i != props.nodeConfig.conditionNodes.length - 1) {
|
||||
var error = conditionList.length == 0;
|
||||
|
||||
for (var it of conditionList) {
|
||||
error = it.conditionList.length == 0;
|
||||
for (var ite of it.conditionList) {
|
||||
if (!ite.key || !ite.expression || !ite.value) {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
conditionNode.error = error;
|
||||
}
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
if (props.nodeConfig.type == 1) {
|
||||
props.nodeConfig.error = !$func.checkApproval(props.nodeConfig);
|
||||
} else if (props.nodeConfig.type == 2) {
|
||||
props.nodeConfig.error = !$func.copyerStr(props.nodeConfig);
|
||||
} else if (props.nodeConfig.type == 4) {
|
||||
resetConditionNodesErr();
|
||||
}
|
||||
});
|
||||
let emits = defineEmits(['update:nodeConfig']);
|
||||
let store = useStore();
|
||||
let { setPromoter, setApprover, setCopyer, setCondition, setStarterConfig, setApproverConfig, setCopyerConfig, setConditionsConfig } = store;
|
||||
let starterConfigData = computed(() => store.starterConfigData);
|
||||
let approverConfigData = computed(() => store.approverConfigData);
|
||||
let copyerConfig1 = computed(() => store.copyerConfig1);
|
||||
let conditionsConfig1 = computed(() => store.conditionsConfig1);
|
||||
|
||||
watch(starterConfigData, (approver) => {
|
||||
if (approver.flag && approver.id === _uid) {
|
||||
emits('update:nodeConfig', approver.value);
|
||||
}
|
||||
});
|
||||
watch(approverConfigData, (approver) => {
|
||||
if (approver.flag && approver.id === _uid) {
|
||||
emits('update:nodeConfig', approver.value);
|
||||
}
|
||||
});
|
||||
watch(copyerConfig1, (copyer) => {
|
||||
if (copyer.flag && copyer.id === _uid) {
|
||||
emits('update:nodeConfig', copyer.value);
|
||||
}
|
||||
});
|
||||
watch(conditionsConfig1, (condition) => {
|
||||
if (condition.flag && condition.id === _uid) {
|
||||
emits('update:nodeConfig', condition.value);
|
||||
}
|
||||
});
|
||||
|
||||
const clickEvent = (index) => {
|
||||
if (index || index === 0) {
|
||||
isInputList.value[index] = true;
|
||||
} else {
|
||||
isInput.value = true;
|
||||
}
|
||||
};
|
||||
const blurEvent = (index) => {
|
||||
if (index || index === 0) {
|
||||
isInputList.value[index] = false;
|
||||
props.nodeConfig.conditionNodes[index].nodeName = props.nodeConfig.conditionNodes[index].nodeName || '条件';
|
||||
} else {
|
||||
isInput.value = false;
|
||||
props.nodeConfig.nodeName = props.nodeConfig.nodeName || defaultText;
|
||||
}
|
||||
};
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const delNode = () => {
|
||||
emits('update:nodeConfig', props.nodeConfig.childNode);
|
||||
};
|
||||
const addTerm = () => {
|
||||
if (props.nodeConfig.type == 5) {
|
||||
let len = props.nodeConfig.conditionNodes.length + 1;
|
||||
props.nodeConfig.conditionNodes.push({
|
||||
nodeName: '分支' + len,
|
||||
type: 3,
|
||||
id: other.getNonDuplicateID(),
|
||||
placeHolder: '满足条件',
|
||||
parentId: props.nodeConfig.id,
|
||||
|
||||
priorityLevel: len,
|
||||
conditionList: [
|
||||
{
|
||||
conditionList: [],
|
||||
},
|
||||
],
|
||||
nodeUserList: [],
|
||||
childNode: null,
|
||||
});
|
||||
emits('update:nodeConfig', props.nodeConfig);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let len = props.nodeConfig.conditionNodes.length + 1;
|
||||
props.nodeConfig.conditionNodes.push({
|
||||
nodeName: '条件' + len,
|
||||
type: 3,
|
||||
parentId: props.nodeConfig.id,
|
||||
id: other.getNonDuplicateID(),
|
||||
priorityLevel: len,
|
||||
conditionList: [
|
||||
{
|
||||
mode: true,
|
||||
conditionList: [
|
||||
{
|
||||
key: '',
|
||||
expression: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
nodeUserList: [],
|
||||
childNode: null,
|
||||
});
|
||||
resetConditionNodesErr();
|
||||
emits('update:nodeConfig', props.nodeConfig);
|
||||
};
|
||||
const delTerm = (index) => {
|
||||
props.nodeConfig.conditionNodes.splice(index, 1);
|
||||
props.nodeConfig.conditionNodes.map((item, index) => {
|
||||
item.priorityLevel = index + 1;
|
||||
item.nodeName = `条件${index + 1}`;
|
||||
});
|
||||
resetConditionNodesErr();
|
||||
emits('update:nodeConfig', props.nodeConfig);
|
||||
if (props.nodeConfig.conditionNodes.length == 1) {
|
||||
if (props.nodeConfig.childNode) {
|
||||
if (props.nodeConfig.conditionNodes[0].childNode) {
|
||||
reData(props.nodeConfig.conditionNodes[0].childNode, props.nodeConfig.childNode);
|
||||
} else {
|
||||
props.nodeConfig.conditionNodes[0].childNode = props.nodeConfig.childNode;
|
||||
}
|
||||
}
|
||||
emits('update:nodeConfig', props.nodeConfig.conditionNodes[0].childNode);
|
||||
}
|
||||
};
|
||||
const reData = (data, addData) => {
|
||||
if (!data.childNode) {
|
||||
data.childNode = addData;
|
||||
} else {
|
||||
reData(data.childNode, addData);
|
||||
}
|
||||
};
|
||||
const openConfigDrawer = (priorityLevel) => {
|
||||
var { type } = props.nodeConfig;
|
||||
if (type == 0) {
|
||||
setPromoter(true);
|
||||
setStarterConfig({
|
||||
value: JSON.parse(JSON.stringify(props.nodeConfig)),
|
||||
|
||||
flag: false,
|
||||
id: _uid,
|
||||
});
|
||||
} else if (type == 1) {
|
||||
setApprover(true);
|
||||
setApproverConfig({
|
||||
value: {
|
||||
...JSON.parse(JSON.stringify(props.nodeConfig)),
|
||||
...{ assignedType: props.nodeConfig.assignedType || 1 },
|
||||
...{ multiple: props.nodeConfig.multiple || false },
|
||||
},
|
||||
flag: false,
|
||||
id: _uid,
|
||||
});
|
||||
} else if (type == 2) {
|
||||
setCopyer(true);
|
||||
setCopyerConfig({
|
||||
value: JSON.parse(JSON.stringify(props.nodeConfig)),
|
||||
flag: false,
|
||||
id: _uid,
|
||||
});
|
||||
} else {
|
||||
setCondition(true);
|
||||
setConditionsConfig({
|
||||
value: JSON.parse(JSON.stringify(props.nodeConfig)),
|
||||
priorityLevel,
|
||||
flag: false,
|
||||
id: _uid,
|
||||
});
|
||||
}
|
||||
};
|
||||
const arrTransfer = (index, type = 1) => {
|
||||
//向左-1,向右1
|
||||
props.nodeConfig.conditionNodes[index] = props.nodeConfig.conditionNodes.splice(index + type, 1, props.nodeConfig.conditionNodes[index])[0];
|
||||
props.nodeConfig.conditionNodes.map((item, index) => {
|
||||
item.priorityLevel = index + 1;
|
||||
});
|
||||
resetConditionNodesErr();
|
||||
emits('update:nodeConfig', props.nodeConfig);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '/@/views/flow/workflow/css/workflow.css';
|
||||
|
||||
.error_tip {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
transform: translate(150%, 0px);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.promoter_person .el-dialog__body {
|
||||
padding: 10px 20px 14px 20px;
|
||||
}
|
||||
|
||||
.selected_list {
|
||||
margin-bottom: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.selected_list span {
|
||||
margin-right: 10px;
|
||||
padding: 3px 6px 3px 9px;
|
||||
line-height: 12px;
|
||||
white-space: nowrap;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgba(220, 220, 220, 1);
|
||||
}
|
||||
|
||||
.selected_list img {
|
||||
margin-left: 5px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,114 @@
|
||||
.el-drawer__header {
|
||||
margin-bottom: 0 !important;
|
||||
padding: 14px 0 14px 20px !important;
|
||||
/* border-bottom: 1px solid #f2f2f2 !important; */
|
||||
color: #323232 !important;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.el-drawer__header .el-drawer__title{
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.demo-drawer__content {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.drawer_content {
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
.demo-drawer__content>div {
|
||||
border-top: 1px solid #F2F2F2 !important;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
min-width: 79px !important;
|
||||
padding: 8px 12px !important;
|
||||
font-size: 12px !important;
|
||||
border-radius: 2px !important;
|
||||
color: #323232 !important;
|
||||
background: #f2f2f2 !important;
|
||||
height: 30px !important;
|
||||
}
|
||||
|
||||
.el-button.el-button--primary {
|
||||
background: #46A6FE !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.demo-drawer__footer {
|
||||
padding: 10px 30px !important;
|
||||
border-top: 1px solid #F2F2F2 !important;
|
||||
}
|
||||
|
||||
.demo-drawer__footer .el-button {
|
||||
float: right !important;
|
||||
margin-right: 10px !important;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
width: 520px;
|
||||
border: 1px solid #DDE1E5 !important;
|
||||
border-radius: 3px !important;
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
padding: 0 0 0 20px !important;
|
||||
line-height: 50px !important;
|
||||
height: 50px !important;
|
||||
background: #fff !important;
|
||||
border-bottom: 1px solid #F2F2F2 !important;
|
||||
}
|
||||
|
||||
.el-dialog__header .el-dialog__title {
|
||||
font-size: 16px !important;
|
||||
line-height: 50px !important;
|
||||
color: #333333 !important;
|
||||
}
|
||||
|
||||
.el-dialog__header .el-dialog__headerbtn {
|
||||
height: 12px !important;
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.el-dialog__header .el-icon-close {
|
||||
width: 12px !important;
|
||||
height: 12px !important;
|
||||
float: left !important;
|
||||
}
|
||||
|
||||
.el-dialog__header .el-icon-close::before {
|
||||
display: block !important;
|
||||
width: 12px !important;
|
||||
height: 12px !important;
|
||||
background: url(~@/assets/images/add-close.png) no-repeat center !important;
|
||||
background-size: 100% 100% !important;
|
||||
content: "" !important;
|
||||
}
|
||||
.el-drawer__body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.el-dialog__footer {
|
||||
border-top: 1px solid #F2F2F2 !important;
|
||||
padding-bottom: 10px !important;
|
||||
}
|
||||
|
||||
.el-checkbox,
|
||||
.el-checkbox__input.is-checked+.el-checkbox__label,
|
||||
.el-radio,
|
||||
.el-radio__input.is-checked+.el-radio__label,
|
||||
.el-dialog__body,
|
||||
.el-tree {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
.el-radio__label, .el-checkbox__label {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.my-el-custom-spinner {
|
||||
display: inline-block !important;
|
||||
width: 80px !important;
|
||||
height: 80px !important;
|
||||
background: url(~@/assets/images/loading.gif) no-repeat center !important;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* @Date: 2022-08-25 14:13:11
|
||||
* @LastEditors: StavinLi 495727881@qq.com
|
||||
* @LastEditTime: 2023-05-24 15:00:32
|
||||
* @FilePath: /Workflow-Vue3/src/store/index.js
|
||||
*/
|
||||
import { defineStore } from 'pinia';
|
||||
import { FormConfigUserVO, FormVO } from '/@/api/flow/form/types';
|
||||
|
||||
var adminList: FormConfigUserVO[] = reactive([]);
|
||||
|
||||
export const useFlowStore = defineStore('flow', {
|
||||
state: () => {
|
||||
return {
|
||||
step1: {
|
||||
logo: '',
|
||||
name: '',
|
||||
flowId: '',
|
||||
groupId: undefined,
|
||||
adminList: adminList,
|
||||
remark: '',
|
||||
},
|
||||
step2: [] as FormVO[],
|
||||
step3:{}
|
||||
};
|
||||
},
|
||||
actions: {
|
||||
setStep2(p: FormVO[]) {
|
||||
this.step2 = p;
|
||||
},
|
||||
clearStep1() {
|
||||
this.step1 = {
|
||||
logo: '',
|
||||
name: '',
|
||||
flowId: '',
|
||||
groupId: undefined,
|
||||
adminList: adminList,
|
||||
remark: '',
|
||||
};
|
||||
},
|
||||
clearStep2() {
|
||||
this.step2 = [];
|
||||
},
|
||||
setStep3(p: any) {
|
||||
this.step3 = p;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* @Date: 2022-08-25 14:13:11
|
||||
* @LastEditors: StavinLi 495727881@qq.com
|
||||
* @LastEditTime: 2023-05-24 15:00:32
|
||||
* @FilePath: /Workflow-Vue3/src/store/index.js
|
||||
*/
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useStore = defineStore('store', {
|
||||
state: () => ({
|
||||
promoterDrawer: false,
|
||||
|
||||
approverDrawer: false,
|
||||
approverConfigData: {},
|
||||
starterConfigData: {},
|
||||
copyerDrawer: false,
|
||||
copyerConfig1: {},
|
||||
conditionDrawer: false,
|
||||
conditionsConfig1: {
|
||||
conditionNodes: [],
|
||||
},
|
||||
}),
|
||||
actions: {
|
||||
setPromoter(payload) {
|
||||
this.promoterDrawer = payload;
|
||||
},
|
||||
|
||||
setApprover(payload) {
|
||||
this.approverDrawer = payload;
|
||||
},
|
||||
setApproverConfig(payload) {
|
||||
this.approverConfigData = payload;
|
||||
},
|
||||
setStarterConfig(payload) {
|
||||
this.starterConfigData = payload;
|
||||
},
|
||||
setCopyer(payload) {
|
||||
this.copyerDrawer = payload;
|
||||
},
|
||||
setCopyerConfig(payload) {
|
||||
this.copyerConfig1 = payload;
|
||||
},
|
||||
setCondition(payload) {
|
||||
this.conditionDrawer = payload;
|
||||
},
|
||||
setConditionsConfig(payload) {
|
||||
this.conditionsConfig1 = payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @Date: 2023-03-29 15:25:37
|
||||
* @LastEditors: StavinLi 495727881@qq.com
|
||||
* @LastEditTime: 2023-03-29 15:52:38
|
||||
* @FilePath: /Workflow-Vue3/src/utils/const.js
|
||||
*/
|
||||
|
||||
export let bgColors = ['87, 106, 149', '255, 148, 62', '50, 150, 250'];
|
||||
export let placeholderList = ['发起人', '审批人', '抄送人'];
|
||||
|
||||
export let setTypes = [
|
||||
{ value: 1, label: '指定成员' },
|
||||
{ value: 2, label: '部门主管' },
|
||||
{ value: 3, label: '角色' },
|
||||
{ value: 4, label: '发起人自选' },
|
||||
{ value: 5, label: '发起人自己' },
|
||||
//{ value: 7, label: '连续多级主管' },
|
||||
{ value: 8, label: '表单人员' },
|
||||
];
|
||||
|
||||
export let selectModes = [
|
||||
{ value: 1, label: '选一个人' },
|
||||
{ value: 2, label: '选多个人' },
|
||||
];
|
||||
|
||||
export let selectRanges = [
|
||||
{ value: 1, label: '全公司' },
|
||||
{ value: 2, label: '指定成员' },
|
||||
{ value: 3, label: '指定角色' },
|
||||
];
|
||||
|
||||
export let optTypes = [
|
||||
{ value: '1', label: '小于' },
|
||||
{ value: '2', label: '大于' },
|
||||
{ value: '3', label: '小于等于' },
|
||||
{ value: '4', label: '等于' },
|
||||
{ value: '5', label: '大于等于' },
|
||||
{ value: '6', label: '介于两个数之间' },
|
||||
];
|
||||
|
||||
export let opt1s = [
|
||||
{ value: '<', label: '<' },
|
||||
{ value: '≤', label: '≤' },
|
||||
];
|
||||
@@ -0,0 +1,221 @@
|
||||
function All() {}
|
||||
|
||||
import { useFlowStore } from '../stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
const step2FormList = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
return step2;
|
||||
});
|
||||
const formIdObj = computed(() => {
|
||||
var obj = {};
|
||||
for (var item of step2FormList.value) {
|
||||
obj[item.id] = item;
|
||||
}
|
||||
obj['root'] = {
|
||||
name: '发起人',
|
||||
type: 'SelectUser',
|
||||
};
|
||||
return obj;
|
||||
});
|
||||
|
||||
All.prototype = {
|
||||
timer: '',
|
||||
debounce(fn, delay = 500) {
|
||||
var _this = this;
|
||||
return function (arg) {
|
||||
//获取函数的作用域和变量
|
||||
let that = this;
|
||||
let args = arg;
|
||||
clearTimeout(_this.timer); // 清除定时器
|
||||
_this.timer = setTimeout(function () {
|
||||
fn.call(that, args);
|
||||
}, delay);
|
||||
};
|
||||
},
|
||||
setCookie(val) {
|
||||
//cookie设置[{key:value}]、获取key、清除['key1','key2']
|
||||
for (var i = 0, len = val.length; i < len; i++) {
|
||||
for (var key in val[i]) {
|
||||
document.cookie = key + '=' + encodeURIComponent(val[i][key]) + '; path=/';
|
||||
}
|
||||
}
|
||||
},
|
||||
getCookie(name) {
|
||||
var strCookie = document.cookie;
|
||||
var arrCookie = strCookie.split('; ');
|
||||
for (var i = 0, len = arrCookie.length; i < len; i++) {
|
||||
var arr = arrCookie[i].split('=');
|
||||
if (name == arr[0]) {
|
||||
return decodeURIComponent(arr[1]);
|
||||
}
|
||||
}
|
||||
},
|
||||
clearCookie(name) {
|
||||
var myDate = new Date();
|
||||
myDate.setTime(-1000); //设置时间
|
||||
for (var i = 0, len = name.length; i < len; i++) {
|
||||
document.cookie = '' + name[i] + "=''; path=/; expires=" + myDate.toGMTString();
|
||||
}
|
||||
},
|
||||
arrToStr(arr) {
|
||||
if (arr) {
|
||||
return arr
|
||||
.map((item) => {
|
||||
return item.name;
|
||||
})
|
||||
.toString();
|
||||
}
|
||||
},
|
||||
toChecked(arr, elem, key = 'id') {
|
||||
var isIncludes = this.toggleClass(arr, elem, key);
|
||||
!isIncludes ? arr.push(elem) : this.removeEle(arr, elem, key);
|
||||
},
|
||||
checkApproval(nodeConfig) {
|
||||
if (nodeConfig.assignedType == 1) {
|
||||
//指定成员
|
||||
if (nodeConfig.nodeUserList.length == 0) {
|
||||
return false;
|
||||
}
|
||||
} else if (nodeConfig.assignedType == 3) {
|
||||
//指定角色
|
||||
if (nodeConfig.nodeUserList.length == 0) {
|
||||
return false;
|
||||
}
|
||||
} else if (nodeConfig.assignedType == 8 && nodeConfig.formUserId.length == 0) {
|
||||
//表单
|
||||
return false;
|
||||
}
|
||||
|
||||
//审批人为空
|
||||
if (nodeConfig.nobody?.handler === 'TO_USER' && nodeConfig.nobody.assignedUser.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
setApproverStr(nodeConfig) {
|
||||
if (nodeConfig.assignedType == 1) {
|
||||
//指定成员
|
||||
if (nodeConfig.nodeUserList.length >= 1) {
|
||||
return nodeConfig.nodeUserList.map((res) => res.name).join(',');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else if (nodeConfig.assignedType == 3) {
|
||||
//指定角色
|
||||
if (nodeConfig.nodeUserList.length >= 1) {
|
||||
return nodeConfig.nodeUserList.map((res) => res.name).join(',');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else if (nodeConfig.assignedType == 2) {
|
||||
return nodeConfig.deptLeaderLevel == 1 ? '直接部门主管' : '第' + nodeConfig.deptLeaderLevel + '级部门主管';
|
||||
} else if (nodeConfig.assignedType == 4) {
|
||||
//发起人自选
|
||||
return '发起人自选';
|
||||
} else if (nodeConfig.assignedType == 5) {
|
||||
return '发起人自己';
|
||||
} else if (nodeConfig.assignedType == 7) {
|
||||
return '到第' + nodeConfig.deptLeaderLevel + '级部门主管终止';
|
||||
} else if (nodeConfig.assignedType == 8 && nodeConfig.formUserId.length > 0) {
|
||||
//表单
|
||||
return '表单:' + nodeConfig.formUserName;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
dealStr(str, obj) {
|
||||
let arr = [];
|
||||
let list = str.split(',');
|
||||
for (var elem in obj) {
|
||||
list.map((item) => {
|
||||
if (item == elem) {
|
||||
arr.push(obj[elem].value);
|
||||
}
|
||||
});
|
||||
}
|
||||
return arr.join('或');
|
||||
},
|
||||
conditionStr(nodeConfig, index) {
|
||||
var { conditionList, groupMode } = nodeConfig.conditionNodes[index];
|
||||
if (conditionList.length == 0) {
|
||||
return index == nodeConfig.conditionNodes.length - 1 ? '其他条件进入此流程' : '请设置条件';
|
||||
} else {
|
||||
var groupConArr = [];
|
||||
for (var groupCondition of conditionList) {
|
||||
let mode = groupCondition.mode;
|
||||
|
||||
var conArr = [];
|
||||
|
||||
for (var con of groupCondition.conditionList) {
|
||||
const { key, expression, value } = con;
|
||||
if (!key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let valueElement = formIdObj.value[key];
|
||||
var name = valueElement.name;
|
||||
|
||||
var valueShow = value;
|
||||
if (valueElement.type === 'SelectUser' || valueElement.type === 'SelectDept') {
|
||||
valueShow = value.map((res) => res.name).join(',');
|
||||
} else if (valueElement.type === 'SingleSelect') {
|
||||
valueShow = value.map(res=>res.value).join(",")
|
||||
} else {
|
||||
if (!valueShow) {
|
||||
valueShow = '?';
|
||||
}
|
||||
}
|
||||
|
||||
if (expression === '==') {
|
||||
conArr.push(name + ' 等于 ' + valueShow);
|
||||
} else if (expression === 'in') {
|
||||
conArr.push(name + ' 属于 ' + valueShow);
|
||||
} else if (expression === 'notin') {
|
||||
conArr.push(name + ' 不属于 ' + valueShow);
|
||||
} else if (expression === '!=') {
|
||||
conArr.push(name + ' 不等于 ' + valueShow);
|
||||
} else if (expression === '>') {
|
||||
conArr.push(name + ' 大于 ' + valueShow);
|
||||
} else if (expression === '>=') {
|
||||
conArr.push(name + ' 大于等于 ' + valueShow);
|
||||
} else if (expression === '<') {
|
||||
conArr.push(name + ' 小于 ' + valueShow);
|
||||
} else if (expression === '<=') {
|
||||
conArr.push(name + ' 小于等于 ' + valueShow);
|
||||
} else if (expression === 'contain') {
|
||||
conArr.push(name + " 包含 " + valueShow);
|
||||
} else if (expression === 'notcontain') {
|
||||
conArr.push(name + " 不包含 " + valueShow);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode) {
|
||||
let s = conArr.join(' 且 ');
|
||||
if (conArr.length > 0) {
|
||||
groupConArr.push('(' + s + ')');
|
||||
}
|
||||
} else {
|
||||
let s = conArr.join(' 或 ');
|
||||
if (conArr.length > 0) {
|
||||
groupConArr.push('(' + s + ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return groupConArr.length > 0
|
||||
? groupConArr.join(groupMode ? ' 且 ' : ' 或 ')
|
||||
: index == nodeConfig.conditionNodes.length - 1
|
||||
? '默认条件'
|
||||
: '请设置条件';
|
||||
}
|
||||
},
|
||||
copyerStr(nodeConfig) {
|
||||
if (nodeConfig.nodeUserList?.length != 0) {
|
||||
return this.arrToStr(nodeConfig.nodeUserList);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default new All();
|
||||