!247 Merge remote-tracking branch 'yudao/dev' into dev

Merge pull request !247 from Jason/dev
This commit is contained in:
xingyu
2025-11-03 01:39:01 +00:00
committed by Gitee
3 changed files with 87 additions and 24 deletions

View File

@@ -24,6 +24,7 @@ import {
} from '#/api/bpm/processInstance'; } from '#/api/bpm/processInstance';
import { decodeFields, setConfAndFields2 } from '#/components/form-create'; import { decodeFields, setConfAndFields2 } from '#/components/form-create';
import { router } from '#/router'; import { router } from '#/router';
import ProcessInstanceBpmnViewer from '#/views/bpm/processInstance/detail/modules/bpm-viewer.vue';
import ProcessInstanceSimpleViewer from '#/views/bpm/processInstance/detail/modules/simple-bpm-viewer.vue'; import ProcessInstanceSimpleViewer from '#/views/bpm/processInstance/detail/modules/simple-bpm-viewer.vue';
import ProcessInstanceTimeline from '#/views/bpm/processInstance/detail/modules/time-line.vue'; import ProcessInstanceTimeline from '#/views/bpm/processInstance/detail/modules/time-line.vue';
@@ -51,7 +52,6 @@ const props = defineProps({
const emit = defineEmits(['cancel']); const emit = defineEmits(['cancel']);
const { closeCurrentTab } = useTabs(); const { closeCurrentTab } = useTabs();
const isFormReady = ref(false); // 表单就绪状态变量:表单就绪后再渲染 form-create
const getTitle = computed(() => { const getTitle = computed(() => {
return `流程表单 - ${props.selectProcessDefinition.name}`; return `流程表单 - ${props.selectProcessDefinition.name}`;
}); });
@@ -122,21 +122,32 @@ async function initProcessInfo(row: any, formVariables?: any) {
// 注意:需要从 formVariables 中,移除不在 row.formFields 的值。 // 注意:需要从 formVariables 中,移除不在 row.formFields 的值。
// 原因是:后端返回的 formVariables 里面,会有一些非表单的信息。例如说,某个流程节点的审批人。 // 原因是:后端返回的 formVariables 里面,会有一些非表单的信息。例如说,某个流程节点的审批人。
// 这样,就可能导致一个流程被审批不通过后,重新发起时,会直接后端报错!!! // 这样,就可能导致一个流程被审批不通过后,重新发起时,会直接后端报错!!!
const formApi = formCreate.create(decodeFields(row.formFields));
const allowedFields = formApi.fields(); // 解析表单字段列表(不创建实例,避免重复渲染)
for (const key in formVariables) { const decodedFields = decodeFields(row.formFields);
if (!allowedFields.includes(key)) { const allowedFields = new Set(
delete formVariables[key]; decodedFields.map((field: any) => field.field).filter(Boolean),
);
// 过滤掉不允许的字段
if (formVariables) {
for (const key in formVariables) {
if (!allowedFields.has(key)) {
delete formVariables[key];
}
} }
} }
setConfAndFields2(detailForm, row.formConf, row.formFields, formVariables); setConfAndFields2(detailForm, row.formConf, row.formFields, formVariables);
// 设置表单就绪状态 // 在配置中禁用 form-create 自带的提交和重置按钮
// TODO @jason这个变量是必须的有没可能简化掉 detailForm.value.option = {
isFormReady.value = true; ...detailForm.value.option,
submitBtn: false,
resetBtn: false,
};
await nextTick(); await nextTick();
fApi.value?.btn.show(false); // 隐藏提交按钮
// 获取流程审批信息,当再次发起时,流程审批节点要根据原始表单参数预测出来 // 获取流程审批信息,当再次发起时,流程审批节点要根据原始表单参数预测出来
await getApprovalDetail({ await getApprovalDetail({
@@ -153,30 +164,32 @@ async function initProcessInfo(row: any, formVariables?: any) {
} }
// 情况二:业务表单 // 情况二:业务表单
} else if (row.formCustomCreatePath) { } else if (row.formCustomCreatePath) {
// 这里暂时无需加载流程图,因为跳出到另外个 Tab
await router.push({ await router.push({
path: row.formCustomCreatePath, path: row.formCustomCreatePath,
}); });
// 这里暂时无需加载流程图,因为跳出到另外个 Tab // 返回选择流程
emit('cancel');
} }
} }
/** 预测流程节点会因为输入的参数值而产生新的预测结果值,所以需重新预测一次 */ /** 预测流程节点会因为输入的参数值而产生新的预测结果值,所以需重新预测一次 */
watch( watch(
detailForm.value, () => detailForm.value.value,
(newValue) => { (newValue) => {
if (newValue && Object.keys(newValue.value).length > 0) { if (newValue && Object.keys(newValue).length > 0) {
// 记录之前的节点审批人 // 记录之前的节点审批人
tempStartUserSelectAssignees.value = startUserSelectAssignees.value; tempStartUserSelectAssignees.value = startUserSelectAssignees.value;
startUserSelectAssignees.value = {}; startUserSelectAssignees.value = {};
// 加载最新的审批详情 // 加载最新的审批详情
getApprovalDetail({ getApprovalDetail({
id: props.selectProcessDefinition.id, id: props.selectProcessDefinition.id,
processVariablesStr: JSON.stringify(newValue.value), // 解决 GET 无法传递对象的问题,后端 String 再转 JSON processVariablesStr: JSON.stringify(newValue), // 解决 GET 无法传递对象的问题,后端 String 再转 JSON
}); });
} }
}, },
{ {
immediate: true, deep: true,
}, },
); );
@@ -283,7 +296,6 @@ defineExpose({ initProcessInfo });
class="flex-1 overflow-auto" class="flex-1 overflow-auto"
> >
<form-create <form-create
v-if="isFormReady"
:rule="detailForm.rule" :rule="detailForm.rule"
v-model:api="fApi" v-model:api="fApi"
v-model="detailForm.value" v-model="detailForm.value"
@@ -307,10 +319,15 @@ defineExpose({ initProcessInfo });
class="flex flex-1 overflow-hidden" class="flex flex-1 overflow-hidden"
:force-render="true" :force-render="true"
> >
<div class="w-full"> <div class="h-full w-full">
<!-- BPMN 流程图预览 -->
<ProcessInstanceBpmnViewer
:bpmn-xml="bpmnXML"
v-if="BpmModelType.BPMN === selectProcessDefinition.modelType"
/>
<ProcessInstanceSimpleViewer <ProcessInstanceSimpleViewer
:simple-json="simpleJson" :simple-json="simpleJson"
v-if="selectProcessDefinition.modelType === BpmModelType.SIMPLE" v-if="BpmModelType.SIMPLE === selectProcessDefinition.modelType"
/> />
</div> </div>
</Tabs.TabPane> </Tabs.TabPane>

View File

@@ -1,10 +1,59 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue';
import { MyProcessViewer } from '#/views/bpm/components/bpmn-process-designer/package';
defineOptions({ name: 'ProcessInstanceBpmnViewer' }); defineOptions({ name: 'ProcessInstanceBpmnViewer' });
const props = withDefaults(
defineProps<{
bpmnXml?: string;
loading?: boolean; // 是否加载中
modelView?: Object;
}>(),
{
loading: false,
modelView: () => ({}),
bpmnXml: '',
},
);
// BPMN 流程图数据
const view = ref({
bpmnXml: '',
});
/** 监控 modelView 更新 */
watch(
() => props.modelView,
async (newModelView) => {
// 加载最新
if (newModelView) {
// @ts-ignore
view.value = newModelView;
}
},
);
/** 监听 bpmnXml */
watch(
() => props.bpmnXml,
(value) => {
view.value.bpmnXml = value;
},
);
</script> </script>
<template> <template>
<!-- TODO @jason这里 BPMN 图的接入 --> <div
<div> v-loading="loading"
<h1>BPMN Viewer</h1> class="h-full w-full overflow-auto rounded-lg border border-gray-200 bg-white p-4"
>
<MyProcessViewer
key="processViewer"
:xml="view.bpmnXml"
:view="view"
class="h-full min-h-[500px] w-full"
/>
</div> </div>
</template> </template>

View File

@@ -268,9 +268,6 @@ async function openPopover(type: string) {
Object.keys(popOverVisible.value).forEach((item) => { Object.keys(popOverVisible.value).forEach((item) => {
if (popOverVisible.value[item]) popOverVisible.value[item] = item === type; if (popOverVisible.value[item]) popOverVisible.value[item] = item === type;
}); });
// TODO @jason下面这 2 行,要删除么?
// await nextTick()
// formRef.value.resetFields()
} }
/** 关闭气泡卡 */ /** 关闭气泡卡 */