流程优化

hc_zhufu
刘妍 2024-05-29 14:03:41 +08:00
parent 0136e88c7b
commit 337b0c5e39
5 changed files with 337 additions and 9 deletions

View File

@ -6,7 +6,11 @@ VITE_PUBLIC_PATH = /
# Basic interface address SPA # Basic interface address SPA
#VITE_GLOB_API_URL=/basic-api #VITE_GLOB_API_URL=/basic-api
#财源
VITE_GLOB_API_URL=http://192.168.10.102:9500 VITE_GLOB_API_URL=http://192.168.10.102:9500
#基础框架
#VITE_GLOB_API_URL=http://192.168.10.102:9023
# File upload address optional # File upload address optional

View File

@ -11,7 +11,10 @@ VITE_BUILD_COMPRESS = 'none'
# Basic interface address SPA # Basic interface address SPA
#财源
VITE_GLOB_API_URL=http://192.168.10.102:9500 VITE_GLOB_API_URL=http://192.168.10.102:9500
#基础框架
#VITE_GLOB_API_URL=http://192.168.10.102:9023
# File upload address optional # File upload address optional
# It can be forwarded by nginx or write the actual address directly # It can be forwarded by nginx or write the actual address directly

View File

@ -165,7 +165,120 @@
</template> </template>
</a-table> </a-table>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel key="4" header="按钮设置"> <a-collapse-panel key="4" header="表单设置" v-if="!node.isInherit">
<a-tabs
v-model:activeKey="node.formType"
type="card"
size="small"
centered="true"
@change="tabsChange"
>
<a-tab-pane key="1" tab="自定义表单">
<a-space direction="vertical" size="middle" class="site-space-compact-wrapper">
<a-space-compact block>
<a-input v-model:value="data.formName" placeholder="请选择表单" readonly />
<a-button @click="handleShow"></a-button>
</a-space-compact>
<a-space-compact block>
<a-select
v-model:value="node.formVerison"
placeholder="请选择表单版本"
@change="custmerformVerisonChange"
:options="data.formVerisons"
:fieldNames="{ value: 'id', label: 'createDate' }"
/>
</a-space-compact>
<a-space-compact block>
<a-select
v-model:value="node.formRelationId"
placeholder="请选择流程关联字段"
@change="updateWfData('formRelationId')"
:options="data.formRelations"
/>
</a-space-compact>
</a-space>
</a-tab-pane>
<a-tab-pane key="2" tab="系统表单">
<a-space direction="vertical" size="middle" class="site-space-compact-wrapper">
<a-space-compact block>
<a-input
v-model:value="node.formUrl"
placeholder="请输入PC端表单地址"
@change="updateWfData('formUrl')"
/>
</a-space-compact>
<a-space-compact block>
<a-input
v-model:value="node.formAppUrl"
placeholder="请输入APP端表单地址"
@change="updateWfData('formAppUrl')"
/>
</a-space-compact>
</a-space>
</a-tab-pane>
</a-tabs>
<a-divider plain="true">表单字段权限</a-divider>
<a-table
:columns="data.formColumns"
:data-source="node.authFields"
bordered
:pagination="false"
v-if="node.formType == 1"
>
<template #bodyCell="{ column, text, record }">
<template v-if="['label', 'field'].includes(column.dataIndex)">
<div>
{{ text }}
</div>
</template>
<template v-else-if="['required', 'disabled', 'ifShow'].includes(column.dataIndex)">
<div>
<a-switch v-model:checked="record[column.dataIndex]" size="small" />
</div>
</template>
</template>
</a-table>
<a-table
:columns="data.columns"
:data-source="node.authFields"
bordered
:pagination="false"
v-else
>
<template #bodyCell="{ column, record }">
<template v-if="['label', 'field'].includes(column.dataIndex)">
<div>
<a-input v-model:value="record[column.dataIndex]" placeholder="请输入" />
</div>
</template>
<template v-else-if="['required', 'disabled', 'ifShow'].includes(column.dataIndex)">
<div>
<a-switch v-model:checked="record[column.dataIndex]" size="small" />
</div>
</template>
<template v-else-if="column.dataIndex === 'operation'">
<delete-outlined
two-tone-color="#eb2f96"
@click="handleDeleteAuthField(record.field)"
/>
</template>
</template>
</a-table>
<a-divider plain="true" />
<a-space v-if="node.formType != 1">
<a-button
@click="handleAddAuthField"
width="100%"
type="dashed"
danger
:icon="h(PlusOutlined)"
>添加字段</a-button
>
</a-space>
</a-collapse-panel>
<a-collapse-panel key="5" header="按钮设置">
<a-table <a-table
size="small" size="small"
:columns="data.columns" :columns="data.columns"
@ -211,7 +324,7 @@
> >
</a-space> </a-space>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel key="5" header="会签设置"> <a-collapse-panel key="6" header="会签设置">
<a-form-item label="是否会签"> <a-form-item label="是否会签">
<a-switch <a-switch
v-model:checked="node.isCountersign" v-model:checked="node.isCountersign"
@ -260,7 +373,7 @@
</a-form-item> </a-form-item>
</template> </template>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel key="6" header="超时设置"> <a-collapse-panel key="7" header="超时设置">
<a-form-item label="超时通知"> <a-form-item label="超时通知">
<a-switch v-model:checked="node.isOvertimeMessage" /> <a-switch v-model:checked="node.isOvertimeMessage" />
</a-form-item> </a-form-item>
@ -363,6 +476,16 @@
> >
<AuditorSql ref="sqlRef" /> <AuditorSql ref="sqlRef" />
</a-modal> </a-modal>
<a-modal
width="60%"
wrap-class-name="full-modal"
v-model:open="data.formOpen"
title="选择表单"
@ok="formHandleOk"
:destroyOnClose="true"
>
<SelectForm ref="formRef" />
</a-modal>
</div> </div>
</template> </template>
@ -374,6 +497,8 @@
import { AuditorLevel, AuditorSql, AuditorNode } from './page'; import { AuditorLevel, AuditorSql, AuditorNode } from './page';
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue'; import { DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { flowStore } from '@/store/modules/flow'; import { flowStore } from '@/store/modules/flow';
import { SelectForm } from '@/components/SelectForm/index';
import { functionGetSchemePageList, functionLoadFormPage } from '@/api/demo/formScheme';
const flowWfDataStore = flowStore(); const flowWfDataStore = flowStore();
const labelCol = { span: 7 }; const labelCol = { span: 7 };
@ -442,6 +567,28 @@
dataIndex: 'operation', dataIndex: 'operation',
}, },
], ],
formColumns: [
{
title: '名称',
dataIndex: 'label',
},
{
title: '字段',
dataIndex: 'field',
},
{
title: '必填',
dataIndex: 'required',
},
{
title: '编辑',
dataIndex: 'disabled',
},
{
title: '查看',
dataIndex: 'ifShow',
},
],
isLooker: false, isLooker: false,
conditionOptions: [ conditionOptions: [
{ value: '1', label: '同一个部门' }, { value: '1', label: '同一个部门' },
@ -450,6 +597,10 @@
{ value: '4', label: '发起人下级' }, { value: '4', label: '发起人下级' },
], ],
componentDisabled: props.pageType == 'detail' ? true : false, componentDisabled: props.pageType == 'detail' ? true : false,
formRelations: [],
formOpen: false,
formVerisons: [],
formName: '',
}); });
watch( watch(
@ -465,6 +616,15 @@
} }
}, },
); );
watch(
() => node.value.formCode,
(newVal) => {
if (newVal) {
getFormList();
getVersions(false);
}
},
);
function updateWfData(key) { function updateWfData(key) {
flowWfDataStore.updataWfDataNode(node.value.id, key, node.value[key]); flowWfDataStore.updataWfDataNode(node.value.id, key, node.value[key]);
} }
@ -629,7 +789,112 @@
node.value.btnlist = node.value.btnlist.filter((item) => item.code !== key); node.value.btnlist = node.value.btnlist.filter((item) => item.code !== key);
updateWfData('btnlist'); updateWfData('btnlist');
} }
//
//
async function getFormList() {
const list = await functionLoadFormPage({
page: 1,
limit: 1000,
});
list.items.forEach((element) => {
if (element.id == node.value.formCode) {
data.formName = element.name;
}
});
}
//
function tabsChange() {
data.formName = '';
node.value.formCode = '';
node.value.formVerison = '';
node.value.formRelationId = '';
node.value.formUrl = '';
node.value.formAppUrl = '';
node.value.authFields = [];
node.value.formRelations = [];
}
//
function handleShow() {
data.formOpen = true;
}
//
const formRef = ref<any>();
async function formHandleOk() {
let obj = formRef.value.getRow();
node.value.formCode = obj[0].id;
data.formName = obj[0].name;
node.value.formVerison = '';
node.value.formRelationId = '';
node.value.formUrl = '';
node.value.formAppUrl = '';
node.value.authFields = [];
node.value.formRelations = [];
getVersions(true);
data.formOpen = false;
}
async function getVersions(isChange) {
const list = await functionGetSchemePageList({
schemeInfoId: node.value.formCode,
});
data.formVerisons = list.items;
if (node.value.formVerison) {
custmerformVerisonChange(node.value.formVerison, isChange);
}
}
//
async function custmerformVerisonChange(val, isChange) {
let obj;
data.formVerisons.forEach((element) => {
if (element.id == val) {
obj = element;
}
});
loadFormScheme(obj.scheme, isChange);
}
function loadFormScheme(strScheme, isChange) {
const scheme = JSON.parse(strScheme);
const fields: any[] = [];
const rfields: {
label?: string;
value?: string;
}[] = [];
scheme.formInfo.schemas.forEach(
(element: { label?: string; field?: string; component: any; itemProps: any }) => {
if (['InputGuid'].includes(element.component)) {
rfields.push({
label: element.label,
// value:element.prop
value: element.field,
});
}
if (!['Divider'].includes(element.component) && !element.itemProps.hidden) {
let obj: any = element;
obj.required = element.itemProps.required;
obj.componentProps.disabled = true;
obj.disabled = true;
obj.ifShow = true;
fields.push(obj);
}
},
);
data.formRelations = rfields;
if (isChange) {
node.value.authFields = fields;
}
}
function handleAddAuthField() {
node.value.authFields.push({
field: '',
label: '',
required: true,
disabled: true,
ifShow: true,
});
}
function handleDeleteAuthField(key) {
node.value.authFields = node.value.authFields.filter((item) => item.field !== key);
}
defineExpose({}); defineExpose({});
</script> </script>
@ -694,3 +959,20 @@
} }
} }
</style> </style>
<style lang="scss" scoped>
::v-deep .ant-space {
width: 90%;
margin-left: 5%;
.ant-space-item {
width: 100%;
button {
width: 20%;
}
.ant-btn-dangerous {
width: 100%;
}
}
}
</style>

View File

@ -164,7 +164,8 @@
} else if (currentNode.formUrl) { } else if (currentNode.formUrl) {
// PC // PC
formUrlVisble.value = true; formUrlVisble.value = true;
let url = '../../..' + currentNode.formUrl + '.vue'; let url = '../../' + currentNode.formUrl + '.vue';
console.log(url)
// AsyncComponent.value = defineAsyncComponent(() => import(url)); // AsyncComponent.value = defineAsyncComponent(() => import(url));
AsyncComponent.value = defineAsyncComponent({ AsyncComponent.value = defineAsyncComponent({
// //
@ -264,9 +265,9 @@
}); });
} else if (formUrlVisble.value) { } else if (formUrlVisble.value) {
// //
const funName = 'handleSubmit'; // const funName = 'handleSubmit';
pcForm.value[funName](); // pcForm.value[funName]();
// handleCreateFlow(processId); handleCreateFlow(processId);
} else { } else {
handleCreateFlow(processId); handleCreateFlow(processId);
} }

View File

@ -21,6 +21,9 @@
v-if="formVisble" v-if="formVisble"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="form" tab="系统表单信息" v-if="formUrlVisble">
<AsyncComponent ref="pcForm" />
</a-tab-pane>
<a-tab-pane key="flow" tab="流程信息" force-render> <a-tab-pane key="flow" tab="流程信息" force-render>
<div class="process-design" :style="'display: flex; height:' + designerData.height"> <div class="process-design" :style="'display: flex; height:' + designerData.height">
<process-viewer <process-viewer
@ -128,7 +131,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, onBeforeMount } from 'vue'; import { ref, reactive, onBeforeMount, defineAsyncComponent } from 'vue';
import { ProcessViewer } from '@/components/ProcessViewer'; import { ProcessViewer } from '@/components/ProcessViewer';
import { PageWrapper } from '@/components/Page'; import { PageWrapper } from '@/components/Page';
import { createAgain, signAudit, audit, ReadFlow } from '@/api/sys/WFProcess'; import { createAgain, signAudit, audit, ReadFlow } from '@/api/sys/WFProcess';
@ -162,7 +165,10 @@
const wrapperCol = { span: 24 }; const wrapperCol = { span: 24 };
const infoOpen = ref(true); const infoOpen = ref(true);
const formVisble = ref(false); const formVisble = ref(false);
const formUrlVisble = ref(false);
const processVisble = ref(false); const processVisble = ref(false);
const AsyncComponent = ref();
const pcForm = ref();
const props = defineProps({ const props = defineProps({
processId: String, processId: String,
taskId: String, taskId: String,
@ -252,10 +258,36 @@
designerData.task = data.task; designerData.task = data.task;
let content = JSON.parse(data.scheme.content); let content = JSON.parse(data.scheme.content);
let wfData = content.wfData; let wfData = content.wfData;
const currentNode = wfData.find((t) => t.type == 'bpmn:StartEvent'); console.log(wfData);
const auditNode = wfData.find((t) => t.id == data.task.unitId);
console.log(auditNode);
let currentNode;
if (auditNode.isInherit) {
currentNode = wfData.find((t) => t.type == 'bpmn:StartEvent');
} else {
currentNode = auditNode;
}
console.log(currentNode); console.log(currentNode);
if (currentNode.authFields.length > 0) { if (currentNode.authFields.length > 0) {
formVisble.value = true; formVisble.value = true;
} else if (currentNode.formUrl) {
// PC
formUrlVisble.value = true;
let url = '../../../' + currentNode.formUrl + '.vue';
console.log(url);
// AsyncComponent.value = defineAsyncComponent(() => import(url));
AsyncComponent.value = defineAsyncComponent({
//
loader: () => import(url),
// 200ms,
delay: 200,
// timeout
// 3000
timeout: 3000,
onError: function () {
createMessage.error('无法加载系统表单,请查看流程配置是否正确!');
},
});
} else { } else {
activeName.value = 'flow'; activeName.value = 'flow';
processVisble.value = true; processVisble.value = true;
@ -494,6 +526,12 @@
activeName.value = 'form'; activeName.value = 'form';
return; return;
}); });
} else if (formUrlVisble.value) {
//
const funName = btn.code;
const res = await pcForm.value[funName]();
console.log(res);
// handleCreateFlow(processId);
} else { } else {
handleSubmit(btn); handleSubmit(btn);
} }