增加线条、并行网关、包含网关节点及对应属性面板。流程发起列表页,流程发起页面
parent
3a1aa488bb
commit
52f1233354
|
|
@ -0,0 +1,16 @@
|
||||||
|
// WFDelegate 流程模版基本信息
|
||||||
|
import { defHttp } from '@/utils/http/axios';
|
||||||
|
import {DetailParams} from './model/wfSchemeInfoModel'
|
||||||
|
|
||||||
|
enum Api {
|
||||||
|
// 创建流程
|
||||||
|
LoadMyUserList = '/api/WFDelegate/LoadMyUserList',
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: getLoadMyUserList
|
||||||
|
*/
|
||||||
|
export function getLoadMyUserList(params?: DetailParams) {
|
||||||
|
return defHttp.get({ url: Api.LoadMyUserList, params });
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
// WFProcess 流程模版基本信息
|
||||||
|
import { defHttp } from '@/utils/http/axios';
|
||||||
|
import {CreateParams} from './model/WFProcessModel'
|
||||||
|
|
||||||
|
enum Api {
|
||||||
|
// 创建流程
|
||||||
|
Create = '/api/WFProcess/Create',
|
||||||
|
SaveDraft='/api/WFProcess/SaveDraft'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 创建流程
|
||||||
|
*/
|
||||||
|
export function create( params?:CreateParams) {
|
||||||
|
return defHttp.post(
|
||||||
|
{
|
||||||
|
url: Api.Create,
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description: 保存草稿
|
||||||
|
*/
|
||||||
|
export function saveDraft( params?:CreateParams) {
|
||||||
|
return defHttp.post(
|
||||||
|
{
|
||||||
|
url: Api.SaveDraft,
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,8 @@ import {SchemeListParams,GetSchemeModel,AddParams,
|
||||||
// 流程模板详细信息
|
// 流程模板详细信息
|
||||||
LoadHistoryPage= '/api/WFScheme/LoadPage',
|
LoadHistoryPage= '/api/WFScheme/LoadPage',
|
||||||
UpdateScheme='/api/WFSchemeInfo/UpdateScheme',
|
UpdateScheme='/api/WFSchemeInfo/UpdateScheme',
|
||||||
|
// 获取自定义流程列表(流程发起页)
|
||||||
|
GetInfoList='/api/WFSchemeInfo/GetInfoList'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,3 +61,10 @@ export function updateScheme(params:SchemeParams){
|
||||||
return defHttp.post({ url: Api.UpdateScheme + "?id=" + params.id +"&schemeId="+params.schemeId});
|
return defHttp.post({ url: Api.UpdateScheme + "?id=" + params.id +"&schemeId="+params.schemeId});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: getInfoList 获取流程自定义列表
|
||||||
|
*/
|
||||||
|
export function getInfoList(params) {
|
||||||
|
return defHttp.get({ url: Api.GetInfoList, params });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @description: 创建流程参数
|
||||||
|
*/
|
||||||
|
export interface CreateParams {
|
||||||
|
processId: string,
|
||||||
|
schemeCode: string,
|
||||||
|
title: string,
|
||||||
|
userId: string,
|
||||||
|
toUserId: string,
|
||||||
|
nextUsers: {
|
||||||
|
additionalProp1: string,
|
||||||
|
additionalProp2: string,
|
||||||
|
additionalProp3: string
|
||||||
|
},
|
||||||
|
des: string,
|
||||||
|
code: string,
|
||||||
|
name: string,
|
||||||
|
stampImg: string,
|
||||||
|
stampPassWord: string,
|
||||||
|
nextId: string
|
||||||
|
}
|
||||||
|
|
@ -2,22 +2,39 @@
|
||||||
<div :class="prefixCls" :style="{ width: `${props.width}px` }">
|
<div :class="prefixCls" :style="{ width: `${props.width}px` }">
|
||||||
<a-tabs v-model:activeKey="configActiveName">
|
<a-tabs v-model:activeKey="configActiveName">
|
||||||
<a-tab-pane :tab="data.wfNodeName" key="1">
|
<a-tab-pane :tab="data.wfNodeName" key="1">
|
||||||
|
<!-- 开始节点 -->
|
||||||
<start-event-option ref="startRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
<start-event-option ref="startRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
:pageView="props.pageView" :pageType="props.pageType"
|
:pageView="props.pageView" :pageType="props.pageType"
|
||||||
:class="data.currentWfNode.type=='bpmn:StartEvent' ? '' : 'hidden'"></start-event-option>
|
:class="data.currentWfNode.type=='bpmn:StartEvent' ? '' : 'hidden'"></start-event-option>
|
||||||
|
<!-- 审核节点 -->
|
||||||
<user-task-option ref="taskRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
<user-task-option ref="taskRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
:pageView="props.pageView" :pageType="props.pageType"
|
:pageView="props.pageView" :pageType="props.pageType"
|
||||||
:class="data.currentWfNode.type=='bpmn:Task' ? '' : 'hidden'">
|
:class="data.currentWfNode.type=='bpmn:Task' ? '' : 'hidden'">
|
||||||
</user-task-option>
|
</user-task-option>
|
||||||
|
<!-- 结束节点 -->
|
||||||
<end-event-option ref="endRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
<end-event-option ref="endRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
:class="data.currentWfNode.type=='bpmn:EndEvent' ? '' : 'hidden'"></end-event-option>
|
:class="data.currentWfNode.type=='bpmn:EndEvent' ? '' : 'hidden'"></end-event-option>
|
||||||
|
<!-- 子流程 -->
|
||||||
<subprocess-option ref="subprocessRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
<subprocess-option ref="subprocessRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
:pageView="props.pageView" :pageType="props.pageType"
|
:pageView="props.pageView" :pageType="props.pageType"
|
||||||
:class="data.currentWfNode.type=='bpmn:SubProcess' ? '' : 'hidden'"></subprocess-option>
|
:class="data.currentWfNode.type=='bpmn:SubProcess' ? '' : 'hidden'"></subprocess-option>
|
||||||
|
<!-- 排他网关 -->
|
||||||
<exclusive-gateway-option ref="exclusiveGatewayRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
<exclusive-gateway-option ref="exclusiveGatewayRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
:pageView="props.pageView" :pageType="props.pageType"
|
:pageView="props.pageView" :pageType="props.pageType"
|
||||||
:class="data.currentWfNode.type=='bpmn:ExclusiveGateway' ? '' : 'hidden'">
|
:class="data.currentWfNode.type=='bpmn:ExclusiveGateway' ? '' : 'hidden'">
|
||||||
</exclusive-gateway-option>
|
</exclusive-gateway-option>
|
||||||
|
<!-- 并行网关 -->
|
||||||
|
<parallel-gateway-option ref="parallelGatewayRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
|
:pageView="props.pageView" :pageType="props.pageType"
|
||||||
|
:class="data.currentWfNode.type=='bpmn:ParallelGateway' ? '' : 'hidden'">
|
||||||
|
</parallel-gateway-option>
|
||||||
|
<!-- 包容网关 -->
|
||||||
|
<!-- "bpmn:InclusiveGateway" -->
|
||||||
|
<inclusive-gateway-option ref="inclusiveGatewayRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
|
:pageView="props.pageView" :pageType="props.pageType"
|
||||||
|
:class="data.currentWfNode.type=='bpmn:InclusiveGateway' ? '' : 'hidden'">
|
||||||
|
</inclusive-gateway-option>
|
||||||
|
<!-- 线条 -->
|
||||||
<myline-option ref="mylineRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
<myline-option ref="mylineRef" :element="data.currentWfNode" :schemeCode="props.schemeCode"
|
||||||
:pageView="props.pageView" :pageType="props.pageType" :wfData="data.wfData" :flowRef="data.flowRef"
|
:pageView="props.pageView" :pageType="props.pageType" :wfData="data.wfData" :flowRef="data.flowRef"
|
||||||
:class="data.currentWfNode.type=='bpmn:SequenceFlow' ? '' : 'hidden'">
|
:class="data.currentWfNode.type=='bpmn:SequenceFlow' ? '' : 'hidden'">
|
||||||
|
|
@ -55,10 +72,12 @@
|
||||||
import userTaskOption from './userTask/index.vue'
|
import userTaskOption from './userTask/index.vue'
|
||||||
// 结束节点
|
// 结束节点
|
||||||
import endEventOption from './endEvent/index.vue'
|
import endEventOption from './endEvent/index.vue'
|
||||||
// 网关和
|
// 并行网关
|
||||||
import gatewayAndOption from './config/gatewayAnd.vue'
|
import parallelGatewayOption from './parallelGateway/index.vue'
|
||||||
// 排他网关
|
// 排他网关
|
||||||
import exclusiveGatewayOption from './exclusiveGateway/index.vue'
|
import exclusiveGatewayOption from './exclusiveGateway/index.vue'
|
||||||
|
// 包容网关
|
||||||
|
import inclusiveGatewayOption from './inclusiveGateway/index.vue'
|
||||||
// 网关Xor
|
// 网关Xor
|
||||||
import gatewayXorOption from './config/gatewayXor.vue'
|
import gatewayXorOption from './config/gatewayXor.vue'
|
||||||
// 脚本任务
|
// 脚本任务
|
||||||
|
|
@ -96,13 +115,15 @@
|
||||||
const taskRef = ref < any > ()
|
const taskRef = ref < any > ()
|
||||||
const endRef = ref < any > ()
|
const endRef = ref < any > ()
|
||||||
const subprocessRef = ref < any > ()
|
const subprocessRef = ref < any > ()
|
||||||
const exclusiveGatewayRef = ref < any > ()
|
const exclusiveGatewayRef = ref < any > ()
|
||||||
|
const parallelGatewayRef = ref < any > ()
|
||||||
|
const inclusiveGatewayRef = ref < any > ()
|
||||||
const configActiveName = ref('2')
|
const configActiveName = ref('2')
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
currentWfNode: undefined,
|
currentWfNode: undefined,
|
||||||
wfNodeName: "",
|
wfNodeName: "",
|
||||||
wfData:[],
|
wfData: [],
|
||||||
flowRef:{}
|
flowRef: {}
|
||||||
})
|
})
|
||||||
watch(
|
watch(
|
||||||
() => props.element,
|
() => props.element,
|
||||||
|
|
@ -153,6 +174,20 @@
|
||||||
type: newVal.type
|
type: newVal.type
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'ParallelGateway':
|
||||||
|
data.wfNodeName = "并行网关"
|
||||||
|
data.currentWfNode = {
|
||||||
|
id: newVal.id,
|
||||||
|
type: newVal.type
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'InclusiveGateway':
|
||||||
|
data.wfNodeName = "包含网关"
|
||||||
|
data.currentWfNode = {
|
||||||
|
id: newVal.id,
|
||||||
|
type: newVal.type
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'SequenceFlow':
|
case 'SequenceFlow':
|
||||||
data.wfNodeName = "线条"
|
data.wfNodeName = "线条"
|
||||||
data.currentWfNode = {
|
data.currentWfNode = {
|
||||||
|
|
@ -160,9 +195,9 @@
|
||||||
type: newVal.type
|
type: newVal.type
|
||||||
}
|
}
|
||||||
// 获取线条两头的节点id
|
// 获取线条两头的节点id
|
||||||
data.flowRef={
|
data.flowRef = {
|
||||||
from:newVal.businessObject.sourceRef.id,
|
from: newVal.businessObject.sourceRef.id,
|
||||||
to:newVal.businessObject.targetRef.id,
|
to: newVal.businessObject.targetRef.id,
|
||||||
}
|
}
|
||||||
// 获取排他网关和审核节点的数据,为选择流转条件使用
|
// 获取排他网关和审核节点的数据,为选择流转条件使用
|
||||||
getWfData()
|
getWfData()
|
||||||
|
|
@ -279,8 +314,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
data.wfData = wfData
|
data.wfData = wfData
|
||||||
|
|
||||||
}
|
}
|
||||||
async function validatePanel() {
|
async function validatePanel() {
|
||||||
let res = await shcemeinfoRef.value.validateForm();
|
let res = await shcemeinfoRef.value.validateForm();
|
||||||
|
|
@ -320,6 +355,16 @@
|
||||||
if (gatewayInclusiveFrom != undefined) {
|
if (gatewayInclusiveFrom != undefined) {
|
||||||
wfData.push(gatewayInclusiveFrom)
|
wfData.push(gatewayInclusiveFrom)
|
||||||
}
|
}
|
||||||
|
// 并排网关
|
||||||
|
let parallelGatewayFrom = await !(parallelGatewayRef.value) ? {} : parallelGatewayRef.value.getForm();
|
||||||
|
if (parallelGatewayFrom != undefined) {
|
||||||
|
wfData.push(parallelGatewayFrom)
|
||||||
|
}
|
||||||
|
// 包含网关
|
||||||
|
let inclusiveGatewayFrom = await !(inclusiveGatewayRef.value) ? {} : inclusiveGatewayRef.value.getForm();
|
||||||
|
if (inclusiveGatewayFrom != undefined) {
|
||||||
|
wfData.push(inclusiveGatewayFrom)
|
||||||
|
}
|
||||||
// 3.流程节点信息
|
// 3.流程节点信息
|
||||||
wfData.forEach(node => {
|
wfData.forEach(node => {
|
||||||
if (node.type == 'myline' && !node.isInit) {
|
if (node.type == 'myline' && !node.isInit) {
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
<!-- 开始节点配置 -->
|
|
||||||
<template>
|
|
||||||
<el-form
|
|
||||||
class="l-form-config"
|
|
||||||
label-width="88px"
|
|
||||||
label-position="left"
|
|
||||||
size="mini"
|
|
||||||
>
|
|
||||||
<el-form-item label="节点标识">
|
|
||||||
<el-input v-model="node.id" readonly ></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<div style="padding:0 16px;">
|
|
||||||
<el-alert
|
|
||||||
title="并行网关说明"
|
|
||||||
type="info"
|
|
||||||
description="并行网关会等待所有分支汇入才往下执行,所有出口分支都会被执行"
|
|
||||||
show-icon
|
|
||||||
:closable="false"
|
|
||||||
>
|
|
||||||
</el-alert>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name:'gateway-and-option',
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
node(){
|
|
||||||
return this.wfdesign.currentWfNode;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inject: ["wfdesign"]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import conditionFormula from './src/conditionFormula.vue'
|
import conditionFormula from './src/conditionFormula.vue'
|
||||||
import conditionSql from './src/conditionSql.vue'
|
import conditionSql from './src/conditionSql.vue'
|
||||||
|
import { getDetail } from '@/api/sys/WFSchemeInfo'
|
||||||
import { reactive, ref, onMounted, nextTick, unref, h, watch, defineProps } from 'vue';
|
import { reactive, ref, onMounted, nextTick, unref, h, watch, defineProps } from 'vue';
|
||||||
const labelCol = { span: 7 };
|
const labelCol = { span: 7 };
|
||||||
const wrapperCol = { span: 17 };
|
const wrapperCol = { span: 17 };
|
||||||
|
|
@ -72,7 +73,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
tableBtns: [
|
tableBtns: [
|
||||||
{ prop: 'Edit', label: '编辑' },
|
{ prop: 'Edit', label: '编辑' },
|
||||||
|
|
@ -89,6 +90,8 @@
|
||||||
|
|
||||||
editRow: null,
|
editRow: null,
|
||||||
rowIndex: 0,
|
rowIndex: 0,
|
||||||
|
componentDisabled: props.pageType == 'detail' ? true : false
|
||||||
|
|
||||||
})
|
})
|
||||||
function getNode() {
|
function getNode() {
|
||||||
var content = JSON.parse(props.pageView)
|
var content = JSON.parse(props.pageView)
|
||||||
|
|
@ -104,7 +107,6 @@
|
||||||
let wfData = scheme.wfData
|
let wfData = scheme.wfData
|
||||||
wfData.forEach(element => {
|
wfData.forEach(element => {
|
||||||
if (element.id == node.value.id) {
|
if (element.id == node.value.id) {
|
||||||
console.log(node)
|
|
||||||
node.value = element
|
node.value = element
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -139,8 +141,9 @@
|
||||||
async function handleFormulaOk() {
|
async function handleFormulaOk() {
|
||||||
conditionFormulaRef.value.validateForm()
|
conditionFormulaRef.value.validateForm()
|
||||||
let obj = conditionFormulaRef.value.getForm()
|
let obj = conditionFormulaRef.value.getForm()
|
||||||
console.log(obj.name)
|
if (obj.name == '' || obj.dbCode == '' || obj.sql == '') {
|
||||||
if (obj.name != '') {
|
data.formulaVisible = true;
|
||||||
|
}else{
|
||||||
data.formulaVisible = false;
|
data.formulaVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,6 +151,13 @@
|
||||||
function handleSqlOk() {
|
function handleSqlOk() {
|
||||||
console.log(conditionSqlRef.value.getForm())
|
console.log(conditionSqlRef.value.getForm())
|
||||||
// this.sqlVisible = false;
|
// this.sqlVisible = false;
|
||||||
|
conditionSqlRef.value.validateForm()
|
||||||
|
let obj = conditionSqlRef.value.getForm()
|
||||||
|
if (obj.name == '' || obj.table == '' || obj.value == '' || obj.rfield == '' || obj.cfield == '' || obj.compareType == '') {
|
||||||
|
data.formulaVisible = true;
|
||||||
|
}else{
|
||||||
|
data.formulaVisible = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function getForm() {
|
function getForm() {
|
||||||
return node.value
|
return node.value
|
||||||
|
|
|
||||||
|
|
@ -124,12 +124,11 @@
|
||||||
function validateForm() {
|
function validateForm() {
|
||||||
formRef.value
|
formRef.value
|
||||||
.validate()
|
.validate()
|
||||||
.then((values) => {
|
.then(async (values) => {
|
||||||
return formData.value
|
return true
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(async (error) => {
|
||||||
console.log(error)
|
return false
|
||||||
return {}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function setForm(data) {
|
function setForm(data) {
|
||||||
|
|
|
||||||
|
|
@ -43,23 +43,27 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
async function getForm() {
|
// 校验表单
|
||||||
let res = await formRef.value
|
function validateForm() {
|
||||||
|
formRef.value
|
||||||
.validate()
|
.validate()
|
||||||
.then((values) => {
|
.then(async (values) => {
|
||||||
return formData.value
|
return true
|
||||||
})
|
})
|
||||||
.catch((error: ValidateErrorEntity<FormState>) => {
|
.catch(async (error) => {
|
||||||
return {}
|
return false
|
||||||
});
|
});
|
||||||
return res;
|
}
|
||||||
|
function getForm() {
|
||||||
|
return formData.value
|
||||||
}
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getForm
|
getForm,
|
||||||
|
validateForm
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.l-from-body{
|
.l-from-body {
|
||||||
padding: 10px 30px;
|
padding: 10px 30px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
<template>
|
||||||
|
<div class="user-task">
|
||||||
|
<a-form ref="formRef" :rules="rules" :model="node" labelAlign="left" :label-col="labelCol"
|
||||||
|
:wrapper-col="wrapperCol" :disabled="data.componentDisabled">
|
||||||
|
<a-form-item label="节点标识">
|
||||||
|
<a-input v-model:value="node.id" placeholder="请输入" readonly />
|
||||||
|
</a-form-item>
|
||||||
|
<a-alert message="包容网关说明"
|
||||||
|
description="包容网关会等待所有分支汇入才往下执行,出口分支能执行多条(条件为true)" type="info"
|
||||||
|
show-icon />
|
||||||
|
<a-space>
|
||||||
|
<a-radio-group>
|
||||||
|
<a-radio-button value="1" @click="handleFormulaClick">公式</a-radio-button>
|
||||||
|
<a-radio-button value="2" @click="handleSQlClick">sql语句</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
<a-button danger :size="size" @click="handleClearClick">清空</a-button>
|
||||||
|
</a-space>
|
||||||
|
<a-table :columns="data.columns" :data-source="node.conditions" bordered :pagination="false">
|
||||||
|
<template #bodyCell="{ column, text, record }">
|
||||||
|
<template v-if="['name', 'type'].includes(column.dataIndex)">
|
||||||
|
<div>
|
||||||
|
{{ text }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.dataIndex === 'operation'">
|
||||||
|
<a-button>编辑</a-button>
|
||||||
|
<a-button danger @click='onDelete(record.name,false)'>删除</a-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-form>
|
||||||
|
<a-modal width="40%" v-model:open="data.formulaVisible" title="添加公式条件" @ok="handleFormulaOk">
|
||||||
|
<conditionFormula ref="conditionFormulaRef"></conditionFormula>
|
||||||
|
</a-modal>
|
||||||
|
<a-modal width="40%" v-model:open="data.sqlVisible" title="添加sql条件" @ok="handleSqlOk">
|
||||||
|
<conditionSql ref="conditionSqlRef"></conditionSql>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import conditionFormula from '../exclusiveGateway/src/conditionFormula.vue'
|
||||||
|
import conditionSql from '../exclusiveGateway/src/conditionSql.vue'
|
||||||
|
import { getDetail } from '@/api/sys/WFSchemeInfo'
|
||||||
|
import { reactive, ref, onMounted, nextTick, unref, h, watch, defineProps } from 'vue';
|
||||||
|
const labelCol = { span: 7 };
|
||||||
|
const wrapperCol = { span: 17 };
|
||||||
|
const conditionFormulaRef = ref < any > ()
|
||||||
|
const conditionSqlRef = ref < any > ()
|
||||||
|
const props = defineProps({
|
||||||
|
element: Object,
|
||||||
|
schemeCode: String,
|
||||||
|
pageType: String,
|
||||||
|
pageView: String,
|
||||||
|
})
|
||||||
|
const node = ref({
|
||||||
|
conditions: [],
|
||||||
|
id: ''
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
() => props.element,
|
||||||
|
(newVal, oldVal) => {
|
||||||
|
console.log(newVal)
|
||||||
|
if (newVal.type == "bpmn:ExclusiveGateway") {
|
||||||
|
node.value.id = newVal.id
|
||||||
|
node.value.type = newVal.type
|
||||||
|
if (props.pageType == 'detail') {
|
||||||
|
getNode()
|
||||||
|
}
|
||||||
|
if (props.schemeCode) {
|
||||||
|
getDetailInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
tableBtns: [
|
||||||
|
{ prop: 'Edit', label: '编辑' },
|
||||||
|
{ prop: 'Delete', label: '删除' }
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
{ title: '类型', dataIndex: 'type' },
|
||||||
|
{ title: '名称', dataIndex: 'name' },
|
||||||
|
],
|
||||||
|
tableData: [],
|
||||||
|
|
||||||
|
formulaVisible: false,
|
||||||
|
sqlVisible: false,
|
||||||
|
|
||||||
|
editRow: null,
|
||||||
|
rowIndex: 0,
|
||||||
|
componentDisabled: props.pageType == 'detail' ? true : false
|
||||||
|
|
||||||
|
})
|
||||||
|
function getNode() {
|
||||||
|
var content = JSON.parse(props.pageView)
|
||||||
|
content.wfData.forEach(element => {
|
||||||
|
if (element.id == node.value.id) {
|
||||||
|
node.value = element
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function getDetailInfo() {
|
||||||
|
let data = await getDetail({ code: props.schemeCode })
|
||||||
|
let scheme = JSON.parse(data.scheme.content);
|
||||||
|
let wfData = scheme.wfData
|
||||||
|
wfData.forEach(element => {
|
||||||
|
if (element.id == node.value.id) {
|
||||||
|
node.value = element
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.schemeCode) {
|
||||||
|
getDetailInfo()
|
||||||
|
}
|
||||||
|
if (props.pageType == 'detail') {
|
||||||
|
getNode()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function typeFormat(type) {
|
||||||
|
switch (type) {
|
||||||
|
case '1':
|
||||||
|
return '表达式'
|
||||||
|
case '2':
|
||||||
|
return 'sql语句'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFormulaClick() {
|
||||||
|
data.formulaVisible = true;
|
||||||
|
}
|
||||||
|
function handleSQlClick() {
|
||||||
|
data.sqlVisible = true;
|
||||||
|
}
|
||||||
|
function handleClearClick() {
|
||||||
|
node.conditions = [];
|
||||||
|
}
|
||||||
|
async function handleFormulaOk() {
|
||||||
|
conditionFormulaRef.value.validateForm()
|
||||||
|
let obj = conditionFormulaRef.value.getForm()
|
||||||
|
if (obj.name == '' || obj.dbCode == '' || obj.sql == '') {
|
||||||
|
data.formulaVisible = true;
|
||||||
|
}else{
|
||||||
|
data.formulaVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function handleSqlOk() {
|
||||||
|
console.log(conditionSqlRef.value.getForm())
|
||||||
|
// this.sqlVisible = false;
|
||||||
|
conditionSqlRef.value.validateForm()
|
||||||
|
let obj = conditionSqlRef.value.getForm()
|
||||||
|
if (obj.name == '' || obj.table == '' || obj.value == '' || obj.rfield == '' || obj.cfield == '' || obj.compareType == '') {
|
||||||
|
data.formulaVisible = true;
|
||||||
|
}else{
|
||||||
|
data.formulaVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getForm() {
|
||||||
|
return node.value
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
getForm
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
::v-deep .ant-alert-info {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ant-table-wrapper {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
<!-- 开始节点配置 -->
|
||||||
|
<template>
|
||||||
|
<div class="user-task">
|
||||||
|
<a-form ref="formRef" :rules="rules" :model="node" labelAlign="left" :label-col="labelCol"
|
||||||
|
:wrapper-col="wrapperCol" :disabled="data.componentDisabled">
|
||||||
|
<a-form-item label="节点标识">
|
||||||
|
<a-input v-model:value="node.id" placeholder="请输入" readonly />
|
||||||
|
</a-form-item>
|
||||||
|
<a-alert message="并行网关说明"
|
||||||
|
description="并行网关会等待所有分支汇入才往下执行,所有出口分支都会被执行" type="info"
|
||||||
|
show-icon />
|
||||||
|
</a-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref, onMounted, nextTick, unref, h, watch, defineProps } from 'vue';
|
||||||
|
import { getDetail } from '@/api/sys/WFSchemeInfo'
|
||||||
|
const labelCol = { span: 7 };
|
||||||
|
const wrapperCol = { span: 17 };
|
||||||
|
const props = defineProps({
|
||||||
|
element: Object,
|
||||||
|
schemeCode: String,
|
||||||
|
pageType: String,
|
||||||
|
pageView: String,
|
||||||
|
})
|
||||||
|
const node = ref({
|
||||||
|
id: ''
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
() => props.element,
|
||||||
|
(newVal, oldVal) => {
|
||||||
|
console.log(newVal)
|
||||||
|
if (newVal.type == "bpmn:ParallelGateway") {
|
||||||
|
node.value.id = newVal.id
|
||||||
|
node.value.type = newVal.type
|
||||||
|
if (props.pageType == 'detail') {
|
||||||
|
getNode()
|
||||||
|
}
|
||||||
|
if (props.schemeCode) {
|
||||||
|
getDetailInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
componentDisabled: props.pageType == 'detail' ? true : false
|
||||||
|
})
|
||||||
|
function getNode() {
|
||||||
|
var content = JSON.parse(props.pageView)
|
||||||
|
content.wfData.forEach(element => {
|
||||||
|
if (element.id == node.value.id) {
|
||||||
|
node.value = element
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function getDetailInfo() {
|
||||||
|
let data = await getDetail({ code: props.schemeCode })
|
||||||
|
let scheme = JSON.parse(data.scheme.content);
|
||||||
|
let wfData = scheme.wfData
|
||||||
|
wfData.forEach(element => {
|
||||||
|
if (element.id == node.value.id) {
|
||||||
|
node.value = element
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.schemeCode) {
|
||||||
|
getDetailInfo()
|
||||||
|
}
|
||||||
|
if (props.pageType == 'detail') {
|
||||||
|
getNode()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function getForm() {
|
||||||
|
return node.value
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
getForm
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
::v-deep .ant-alert-info {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ant-table-wrapper {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -218,6 +218,14 @@
|
||||||
node.value.authFields = node.value.authFields.filter(item => item.field !== key);
|
node.value.authFields = node.value.authFields.filter(item => item.field !== key);
|
||||||
}
|
}
|
||||||
function getForm() {
|
function getForm() {
|
||||||
|
if(node.value.messageType != ""){
|
||||||
|
if(node.value.messageType.length > 1){
|
||||||
|
node.value.messageType = node.value.messageType.join(',')
|
||||||
|
|
||||||
|
}else{
|
||||||
|
node.value.messageType = node.value.messageType[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
return node.value
|
return node.value
|
||||||
}
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
||||||
|
|
@ -334,7 +334,6 @@
|
||||||
let wfData = scheme.wfData
|
let wfData = scheme.wfData
|
||||||
wfData.forEach(element => {
|
wfData.forEach(element => {
|
||||||
if (element.id == node.value.id) {
|
if (element.id == node.value.id) {
|
||||||
console.log(node)
|
|
||||||
node.value = element
|
node.value = element
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -420,6 +419,11 @@
|
||||||
}
|
}
|
||||||
function getForm() {
|
function getForm() {
|
||||||
if (node.value.id != '') {
|
if (node.value.id != '') {
|
||||||
|
if (node.value.overtimeMessageType.length > 1) {
|
||||||
|
node.value.overtimeMessageType = node.value.overtimeMessageType.join(',')
|
||||||
|
} else {
|
||||||
|
node.value.overtimeMessageType = node.value.overtimeMessageType[0]
|
||||||
|
}
|
||||||
return node.value
|
return node.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
<template>
|
||||||
|
<div class="my-process-designer">
|
||||||
|
<div class="my-process-designer__header">
|
||||||
|
<slot name="control-header"></slot>
|
||||||
|
<template v-if="!$slots['control-header']">
|
||||||
|
<div slot="content">
|
||||||
|
<a-space>
|
||||||
|
<a-tooltip placement="bottom" class="ml-2" title="缩小视图">
|
||||||
|
<a-button :disabled="data.defaultZoom <= 0.3" :icon="h(ZoomOutOutlined)" @click="processZoomOut()"></a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-button>{{ Math.floor(data.defaultZoom * 10 * 10) + "%" }}</a-button>
|
||||||
|
<a-tooltip placement="bottom" title="放大视图">
|
||||||
|
<a-button :disabled="data.defaultZoom >= 3.9" :icon="h(ZoomInOutlined)" @click="processZoomIn()"></a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="my-process-designer__container">
|
||||||
|
<div class="my-process-designer__canvas" ref="bpmn-canvas" id="view"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import '@/components/ProcessDesigner/package/theme/index.scss';
|
||||||
|
import { h, ref, provide, reactive, onMounted, defineProps, computed, defineEmits, onBeforeMount, watch } from 'vue';
|
||||||
|
import { SaveOutlined, ZoomOutOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, ClearOutlined } from '@ant-design/icons-vue';
|
||||||
|
import BpmnViewer from 'bpmn-js/lib/Viewer'
|
||||||
|
import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas';
|
||||||
|
const data = reactive({
|
||||||
|
bpmnModeler: null,
|
||||||
|
defaultZoom: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
xml: String
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
() => props.xml,
|
||||||
|
(newVal, oldVal) => {
|
||||||
|
createDiagram(newVal)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
onMounted(() => {
|
||||||
|
initBpmnModeler()
|
||||||
|
createDiagram(props.xml)
|
||||||
|
})
|
||||||
|
function initBpmnModeler() {
|
||||||
|
if (data.bpmnModerler) return
|
||||||
|
const containerEl = document.getElementById('view')
|
||||||
|
data.bpmnModerler && data.bpmnModerler.destroy() // 避免缓存
|
||||||
|
data.bpmnModerler = new BpmnViewer({
|
||||||
|
container: containerEl,
|
||||||
|
additionalModules: [
|
||||||
|
// 移动整个画布
|
||||||
|
MoveCanvasModule
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function createDiagram(xml) {
|
||||||
|
const viewer = data.bpmnModerler
|
||||||
|
try {
|
||||||
|
const result = await data.bpmnModerler.importXML(xml)
|
||||||
|
const { warnings } = result
|
||||||
|
if (warnings && warnings.length) {
|
||||||
|
warnings.forEach(warn => console.warn(warn))
|
||||||
|
}
|
||||||
|
const canvas = viewer.get('canvas')
|
||||||
|
canvas.zoom('fit-viewport')
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err.message, err.warnings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function processZoomIn(zoomStep = 0.1) {
|
||||||
|
let newZoom = Math.floor(data.defaultZoom * 100 + zoomStep * 100) / 100;
|
||||||
|
if (newZoom > 4) {
|
||||||
|
throw new Error("[Process Designer Warn ]: The zoom ratio cannot be greater than 4");
|
||||||
|
}
|
||||||
|
data.defaultZoom = newZoom;
|
||||||
|
data.bpmnModerler.get("canvas").zoom(data.defaultZoom);
|
||||||
|
}
|
||||||
|
function processZoomOut(zoomStep = 0.1) {
|
||||||
|
let newZoom = Math.floor(data.defaultZoom * 100 - zoomStep * 100) / 100;
|
||||||
|
if (newZoom < 0.2) {
|
||||||
|
throw new Error("[Process Designer Warn ]: The zoom ratio cannot be less than 0.2");
|
||||||
|
}
|
||||||
|
data.defaultZoom = newZoom;
|
||||||
|
data.bpmnModerler.get("canvas").zoom(data.defaultZoom);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.my-process-designer{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
::v-deep .bjs-container a {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -178,6 +178,7 @@
|
||||||
"vxeTable": "VxeTable"
|
"vxeTable": "VxeTable"
|
||||||
},
|
},
|
||||||
"workflow":{
|
"workflow":{
|
||||||
"scheme_preview":"流程模板设计"
|
"scheme_preview":"流程模板设计",
|
||||||
|
"create_preview":"流程发起"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const dashboard: AppRouteModule = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'scheme_preview/:id',
|
path: 'scheme_preview/:id',
|
||||||
name: 'AccountDetail',
|
name: 'SchemePreview',
|
||||||
meta: {
|
meta: {
|
||||||
hideMenu: true,
|
hideMenu: true,
|
||||||
title: t('routes.demo.workflow.scheme_preview'),
|
title: t('routes.demo.workflow.scheme_preview'),
|
||||||
|
|
@ -35,6 +35,18 @@ const dashboard: AppRouteModule = {
|
||||||
},
|
},
|
||||||
component: () => import('@/views/demo/workflow/scheme/preview.vue'),
|
component: () => import('@/views/demo/workflow/scheme/preview.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'create_preview/:id',
|
||||||
|
name: 'CreatePreview',
|
||||||
|
meta: {
|
||||||
|
hideMenu: true,
|
||||||
|
title: t('routes.demo.workflow.create_preview'),
|
||||||
|
ignoreKeepAlive: true,
|
||||||
|
showMenu: false,
|
||||||
|
currentActiveMenu: '/workflow/create',
|
||||||
|
},
|
||||||
|
component: () => import('@/views/demo/workflow/create/preview.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,21 @@ const hexList: string[] = [];
|
||||||
for (let i = 0; i <= 15; i++) {
|
for (let i = 0; i <= 15; i++) {
|
||||||
hexList[i] = i.toString(16);
|
hexList[i] = i.toString(16);
|
||||||
}
|
}
|
||||||
|
export function buildGUID(): string {
|
||||||
|
let guid = '';
|
||||||
|
for (let i = 1; i <= 36; i++) {
|
||||||
|
if (i === 9 || i === 14 || i === 19 || i === 24) {
|
||||||
|
guid += '-';
|
||||||
|
} else if (i === 15) {
|
||||||
|
guid += 4;
|
||||||
|
} else if (i === 20) {
|
||||||
|
guid += hexList[(Math.random() * 4) | 8];
|
||||||
|
} else {
|
||||||
|
guid += hexList[(Math.random() * 16) | 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return guid;
|
||||||
|
}
|
||||||
export function buildUUID(): string {
|
export function buildUUID(): string {
|
||||||
let uuid = '';
|
let uuid = '';
|
||||||
for (let i = 1; i <= 36; i++) {
|
for (let i = 1; i <= 36; i++) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,105 @@
|
||||||
<template>
|
<template>
|
||||||
流程发起
|
<PageWrapper :class="prefixCls">
|
||||||
</template>
|
<div :class="`${prefixCls}__content`" v-for="item in cardList">
|
||||||
|
<div :class="`${prefixCls}__list-title`">{{item.category}}【{{item.data.length}}】</div>
|
||||||
|
<List>
|
||||||
|
<Row :gutter="16">
|
||||||
|
<template v-for="itemchild in item.data" :key="item.id">
|
||||||
|
<Col :span="6">
|
||||||
|
<List.Item>
|
||||||
|
<Card :hoverable="true" :class="`${prefixCls}__card`" @click="launch(itemchild.code)">
|
||||||
|
<div :class="`${prefixCls}__card-title`">
|
||||||
|
<Icon class="icon" v-if="itemchild.icon" :icon="itemchild.icon" :color="itemchild.color" />
|
||||||
|
{{ itemchild.name }}
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</List.Item>
|
||||||
|
</Col>
|
||||||
|
</template>
|
||||||
|
</Row>
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
</PageWrapper>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import Icon from '@/components/Icon/Icon.vue';
|
||||||
|
import { PageWrapper } from '@/components/Page';
|
||||||
|
import { Card, Row, Col, List } from 'ant-design-vue';
|
||||||
|
import { getInfoList } from '@/api/sys/WFSchemeInfo.ts'
|
||||||
|
import { useGo } from '@/hooks/web/usePage';
|
||||||
|
const go = useGo();
|
||||||
|
const prefixCls = 'list-card';
|
||||||
|
let cardList = ref()
|
||||||
|
function launch(code){
|
||||||
|
console.log(code)
|
||||||
|
go('/dashboard/create_preview/add?code='+code);
|
||||||
|
}
|
||||||
|
async function getList() {
|
||||||
|
let data = await getInfoList()
|
||||||
|
let newArr = {}
|
||||||
|
data.map(item => {
|
||||||
|
newArr[item.category] = newArr[item.category] || []; //给category(可自行更换字段如name、sex等,根据自己的数据结构和需求)后加一个[]中括号
|
||||||
|
newArr[item.category].push(item); //将所有的item列放入到对应的category中
|
||||||
|
})
|
||||||
|
let list = [];
|
||||||
|
Object.keys(newArr).forEach(v => {
|
||||||
|
let obj = {};
|
||||||
|
obj.category = v;
|
||||||
|
obj.data = newArr[v]
|
||||||
|
list.push(obj);
|
||||||
|
})
|
||||||
|
cardList.value = list
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.list-card {
|
||||||
|
background-color: @component-background;
|
||||||
|
|
||||||
|
&__list-title {
|
||||||
|
cursor: default;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 17px;
|
||||||
|
padding-top: 16px;
|
||||||
|
color: @text-color-base;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__card {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: -8px;
|
||||||
|
|
||||||
|
.ant-card-body {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: @text-color-base;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-top: -5px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 38px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-detail {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 30px;
|
||||||
|
color: @text-color-secondary;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ant-list-item {
|
||||||
|
padding: 12px 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,161 @@
|
||||||
|
<template>
|
||||||
|
<PageWrapper :class="prefixCls">
|
||||||
|
<div class="btn-box">
|
||||||
|
<a-button type="primary" :icon="h(SendOutlined)" @click="handleCreateFlow" class="ml-2">发起流程 </a-button>
|
||||||
|
<a-button type="primary" :icon="h(SaveOutlined)" @click="handleSaveDraft" class="ml-2">保存草稿 </a-button>
|
||||||
|
<a-button type="primary" :icon="h(CloseCircleOutlined)" @click="closePreview" class="ml-2" danger>关闭 </a-button>
|
||||||
|
</div>
|
||||||
|
<a-tabs v-model:activeKey="activeName">
|
||||||
|
<a-tab-pane key="form" tab="表单信息">
|
||||||
|
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="flow" tab="流程信息" force-render>
|
||||||
|
<div class="process-design" :style="'display: flex; height:' + designerData.height">
|
||||||
|
<process-viewer :key="`designer-${code}`" :xml="flowContent" />
|
||||||
|
<div class="form-box"
|
||||||
|
v-if="designerData.isCustmerTitle || (designerData.delegateUsers && designerData.delegateUsers.length >0)">
|
||||||
|
<a-form ref="formRef" :model="formData" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
|
<a-form-item ref="title" label="流程标题" name="title" v-if="designerData.isCustmerTitle">
|
||||||
|
<a-input v-model:value="formData.title" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="流程发起人" name="userId"
|
||||||
|
v-if="designerData.delegateUsers && designerData.delegateUsers.length >0">
|
||||||
|
<a-select v-model:value="formData.userId" placeholder="请选择" :options="delegateUsers"></a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
|
||||||
|
</PageWrapper>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { h, ref, provide, reactive, onMounted, defineProps, computed, defineEmits, onBeforeMount } from 'vue';
|
||||||
|
import ProcessViewer from '@/components/ProcessViewer/index.vue';
|
||||||
|
import { PageWrapper } from '@/components/Page';
|
||||||
|
|
||||||
|
import { SendOutlined, SaveOutlined, CloseCircleOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, ClearOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { getDetail } from '@/api/sys/WFSchemeInfo'
|
||||||
|
import { create ,saveDraft} from '@/api/sys/WFProcess'
|
||||||
|
import { getLoadMyUserList } from '@/api/sys/WFDelegate'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useMultipleTabStore } from '@/store/modules/multipleTab';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
import { buildGUID } from '@/utils/uuid';
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
console.log()
|
||||||
|
const userInfo = userStore.getUserInfo
|
||||||
|
const prefixCls = 'preview-box'
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
const router = useRouter();
|
||||||
|
const content = ref('')
|
||||||
|
const flowContent = ref('')
|
||||||
|
const route = useRoute()
|
||||||
|
const code = route.query.code
|
||||||
|
const designerOpen = ref(false)
|
||||||
|
const formRef = ref();
|
||||||
|
const labelCol = { span: 7 };
|
||||||
|
const wrapperCol = { span: 13 };
|
||||||
|
|
||||||
|
const designerData = reactive({
|
||||||
|
loading: false,
|
||||||
|
xmlString: '',
|
||||||
|
controlForm: {
|
||||||
|
prefix: 'flowable',
|
||||||
|
},
|
||||||
|
height: document.documentElement.clientHeight - 230.5 + "px;",
|
||||||
|
midVisible: false,
|
||||||
|
isCustmerTitle: false,
|
||||||
|
nodeUsers: [],
|
||||||
|
selectUsersVisible: false,
|
||||||
|
|
||||||
|
isDraft: false,
|
||||||
|
delegateUsers: []
|
||||||
|
})
|
||||||
|
const activeName = ref('flow')
|
||||||
|
const modelDesigner = ref < any > ()
|
||||||
|
|
||||||
|
const formData = reactive({
|
||||||
|
userId: '',
|
||||||
|
title: ''
|
||||||
|
})
|
||||||
|
const rules = reactive({
|
||||||
|
title: [
|
||||||
|
{ required: true, message: '请选择流程标题', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
userId: [
|
||||||
|
{ required: true, message: '请选择流程发起人', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
})
|
||||||
|
async function getDetailInfo() {
|
||||||
|
let data = await getDetail({ code: code })
|
||||||
|
flowContent.value = data.scheme.flowContent
|
||||||
|
formData.userId = userInfo.account
|
||||||
|
let content = JSON.parse(data.scheme.content)
|
||||||
|
let wfData = content.wfData
|
||||||
|
const currentNode = wfData.find(t => t.type == "bpmn:StartEvent")
|
||||||
|
console.log(currentNode)
|
||||||
|
designerData.isCustmerTitle = currentNode.isCustmerTitle
|
||||||
|
}
|
||||||
|
async function getDelegateUsers() {
|
||||||
|
const data = await getLoadMyUserList({
|
||||||
|
code: code
|
||||||
|
})
|
||||||
|
console.log(data)
|
||||||
|
designerData.delegateUsers = data
|
||||||
|
}
|
||||||
|
async function handleSaveDraft() {
|
||||||
|
|
||||||
|
}
|
||||||
|
async function handleCreateFlow() {
|
||||||
|
var querys = {
|
||||||
|
schemeCode: designerData.isDraft ? '' : code,
|
||||||
|
userId: formData.userId,
|
||||||
|
title: formData.title,
|
||||||
|
processId: buildGUID()
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!designerData.isDraft) {
|
||||||
|
await saveDraft(querys)
|
||||||
|
querys.schemeCode = ''
|
||||||
|
designerData.isDraft = true
|
||||||
|
}
|
||||||
|
console.log(querys)
|
||||||
|
const data = await create(querys)
|
||||||
|
closePreview()
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePreview() {
|
||||||
|
if (!code) {
|
||||||
|
tabStore.closeTabByKey('/dashboard/create_preview/add', router);
|
||||||
|
} else {
|
||||||
|
// /dashboard/create_preview/add?code=测试1
|
||||||
|
tabStore.closeTabByKey('/dashboard/create_preview/add?code=' + code, router);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onBeforeMount(() => {
|
||||||
|
getDetailInfo()
|
||||||
|
getDelegateUsers()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.preview-box {
|
||||||
|
background-color: @component-background;
|
||||||
|
|
||||||
|
.btn-box {
|
||||||
|
padding: 10px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-box {
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
</BasicDrawer>
|
</BasicDrawer>
|
||||||
<a-modal width="90%" height="80%" v-model:open="postOpen" title="流程模板预览" @ok="postHandleOk">
|
<a-modal width="90%" height="80%" v-model:open="postOpen" title="流程模板预览" @ok="postHandleOk">
|
||||||
<process-designer :key="designerOpen" style="border:1px solid rgba(0, 0, 0, 0.1);" ref="modelDesigner"
|
<process-designer :key="designerOpen" style="border:1px solid rgba(0, 0, 0, 0.1);" ref="modelDesigner"
|
||||||
v-loading="designerData.loading" :schemeCode="schemeCode" :pageFlow="flowContent" :pageView="content" :pageType="'detail'"
|
v-loading="designerData.loading" :pageFlow="flowContent" :pageView="content" :pageType="'detail'"
|
||||||
@save="onSaveDesigner" />
|
@save="onSaveDesigner" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue