Merge branch 'feature/bpm' of https://gitee.com/yudaocode/yudao-ui-admin-vue3
commit
42f5223941
|
@ -54,6 +54,15 @@ const props = defineProps({
|
||||||
modelName: {
|
modelName: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false
|
||||||
|
},
|
||||||
|
// 可发起流程的人员编号
|
||||||
|
startUserIds : {
|
||||||
|
type: Array,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Object],
|
||||||
|
required: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -66,6 +75,10 @@ const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
const deptOptions = ref<DeptApi.DeptVO[]>([]) // 部门列表
|
const deptOptions = ref<DeptApi.DeptVO[]>([]) // 部门列表
|
||||||
const deptTreeOptions = ref()
|
const deptTreeOptions = ref()
|
||||||
const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
|
const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
|
||||||
|
|
||||||
|
// 添加当前值的引用
|
||||||
|
const currentValue = ref<SimpleFlowNode | undefined>()
|
||||||
|
|
||||||
provide('formFields', formFields)
|
provide('formFields', formFields)
|
||||||
provide('formType', formType)
|
provide('formType', formType)
|
||||||
provide('roleList', roleOptions)
|
provide('roleList', roleOptions)
|
||||||
|
@ -74,6 +87,7 @@ provide('userList', userOptions)
|
||||||
provide('deptList', deptOptions)
|
provide('deptList', deptOptions)
|
||||||
provide('userGroupList', userGroupOptions)
|
provide('userGroupList', userGroupOptions)
|
||||||
provide('deptTree', deptTreeOptions)
|
provide('deptTree', deptTreeOptions)
|
||||||
|
provide('startUserIds', props.startUserIds)
|
||||||
|
|
||||||
const message = useMessage() // 国际化
|
const message = useMessage() // 国际化
|
||||||
const processNodeTree = ref<SimpleFlowNode | undefined>()
|
const processNodeTree = ref<SimpleFlowNode | undefined>()
|
||||||
|
@ -81,10 +95,10 @@ const errorDialogVisible = ref(false)
|
||||||
let errorNodes: SimpleFlowNode[] = []
|
let errorNodes: SimpleFlowNode[] = []
|
||||||
|
|
||||||
// 添加更新模型的方法
|
// 添加更新模型的方法
|
||||||
const updateModel = (key?: string, name?: string) => {
|
const updateModel = () => {
|
||||||
if (!processNodeTree.value) {
|
if (!processNodeTree.value) {
|
||||||
processNodeTree.value = {
|
processNodeTree.value = {
|
||||||
name: name || '发起人',
|
name: '发起人',
|
||||||
type: NodeType.START_USER_NODE,
|
type: NodeType.START_USER_NODE,
|
||||||
id: NodeId.START_USER_NODE_ID,
|
id: NodeId.START_USER_NODE_ID,
|
||||||
childNode: {
|
childNode: {
|
||||||
|
@ -93,45 +107,78 @@ const updateModel = (key?: string, name?: string) => {
|
||||||
type: NodeType.END_EVENT_NODE
|
type: NodeType.END_EVENT_NODE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (name) {
|
// 初始化时也触发一次保存
|
||||||
// 更新现有模型的名称
|
saveSimpleFlowModel(processNodeTree.value)
|
||||||
processNodeTree.value.name = name
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载流程数据
|
||||||
|
const loadProcessData = async (data: any) => {
|
||||||
|
try {
|
||||||
|
if (data) {
|
||||||
|
const parsedData = typeof data === 'string' ? JSON.parse(data) : data
|
||||||
|
processNodeTree.value = parsedData
|
||||||
|
currentValue.value = parsedData
|
||||||
|
// 确保数据加载后刷新视图
|
||||||
|
await nextTick()
|
||||||
|
if (simpleProcessModelRef.value?.refresh) {
|
||||||
|
await simpleProcessModelRef.value.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载流程数据失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听属性变化
|
// 监听属性变化
|
||||||
watch([() => props.modelKey, () => props.modelName], ([newKey, newName]) => {
|
watch(
|
||||||
if (!props.modelId && newKey && newName) {
|
() => props.value,
|
||||||
updateModel(newKey, newName)
|
async (newValue, oldValue) => {
|
||||||
}
|
if (newValue && newValue !== oldValue) {
|
||||||
}, { immediate: true, deep: true })
|
await loadProcessData(newValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听流程节点树变化,自动保存
|
||||||
|
watch(
|
||||||
|
() => processNodeTree.value,
|
||||||
|
async (newValue, oldValue) => {
|
||||||
|
if (newValue && oldValue && JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
|
||||||
|
await saveSimpleFlowModel(newValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
|
const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
|
||||||
if (!simpleModelNode) {
|
if (!simpleModelNode) {
|
||||||
message.error('模型数据为空')
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 校验节点
|
||||||
|
errorNodes = []
|
||||||
|
validateNode(simpleModelNode, errorNodes)
|
||||||
|
if (errorNodes.length > 0) {
|
||||||
|
errorDialogVisible.value = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
|
||||||
if (props.modelId) {
|
if (props.modelId) {
|
||||||
// 编辑模式
|
// 编辑模式
|
||||||
const data = {
|
const data = {
|
||||||
id: props.modelId,
|
id: props.modelId,
|
||||||
simpleModel: simpleModelNode
|
simpleModel: simpleModelNode
|
||||||
}
|
}
|
||||||
const result = await updateBpmSimpleModel(data)
|
await updateBpmSimpleModel(data)
|
||||||
if (result) {
|
|
||||||
message.success('修改成功')
|
|
||||||
emits('success')
|
|
||||||
} else {
|
|
||||||
message.alert('修改失败')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 新建模式,直接返回数据
|
|
||||||
emits('success', simpleModelNode)
|
|
||||||
}
|
}
|
||||||
} finally {
|
// 无论是编辑还是新建模式,都更新当前值并触发事件
|
||||||
loading.value = false
|
currentValue.value = simpleModelNode
|
||||||
|
emits('success', simpleModelNode)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,31 +243,23 @@ onMounted(async () => {
|
||||||
userOptions.value = await UserApi.getSimpleUserList()
|
userOptions.value = await UserApi.getSimpleUserList()
|
||||||
// 获得部门列表
|
// 获得部门列表
|
||||||
deptOptions.value = await DeptApi.getSimpleDeptList()
|
deptOptions.value = await DeptApi.getSimpleDeptList()
|
||||||
|
|
||||||
deptTreeOptions.value = handleTree(deptOptions.value as DeptApi.DeptVO[], 'id')
|
deptTreeOptions.value = handleTree(deptOptions.value as DeptApi.DeptVO[], 'id')
|
||||||
// 获取用户组列表
|
// 获取用户组列表
|
||||||
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
|
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
|
||||||
|
|
||||||
|
// 加载流程数据
|
||||||
if (props.modelId) {
|
if (props.modelId) {
|
||||||
//获取 SIMPLE 设计器模型
|
// 获取 SIMPLE 设计器模型
|
||||||
const result = await getBpmSimpleModel(props.modelId)
|
const result = await getBpmSimpleModel(props.modelId)
|
||||||
if (result) {
|
if (result) {
|
||||||
processNodeTree.value = result
|
await loadProcessData(result)
|
||||||
}
|
} else {
|
||||||
}
|
updateModel()
|
||||||
|
|
||||||
// 如果没有现有模型,创建初始模型
|
|
||||||
if (!processNodeTree.value) {
|
|
||||||
processNodeTree.value = {
|
|
||||||
name: props.modelName || '发起人',
|
|
||||||
type: NodeType.START_USER_NODE,
|
|
||||||
id: NodeId.START_USER_NODE_ID,
|
|
||||||
childNode: {
|
|
||||||
id: NodeId.END_EVENT_NODE_ID,
|
|
||||||
name: '结束',
|
|
||||||
type: NodeType.END_EVENT_NODE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (props.value) {
|
||||||
|
await loadProcessData(props.value)
|
||||||
|
} else {
|
||||||
|
updateModel()
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
@ -231,14 +270,36 @@ const simpleProcessModelRef = ref()
|
||||||
|
|
||||||
/** 获取当前流程数据 */
|
/** 获取当前流程数据 */
|
||||||
const getCurrentFlowData = async () => {
|
const getCurrentFlowData = async () => {
|
||||||
if (simpleProcessModelRef.value) {
|
try {
|
||||||
return await simpleProcessModelRef.value.getCurrentFlowData()
|
if (simpleProcessModelRef.value) {
|
||||||
|
const data = await simpleProcessModelRef.value.getCurrentFlowData()
|
||||||
|
if (data) {
|
||||||
|
currentValue.value = data
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentValue.value
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取流程数据失败:', error)
|
||||||
|
return currentValue.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新方法
|
||||||
|
const refresh = async () => {
|
||||||
|
try {
|
||||||
|
if (currentValue.value) {
|
||||||
|
await loadProcessData(currentValue.value)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('刷新失败:', error)
|
||||||
}
|
}
|
||||||
return undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getCurrentFlowData,
|
getCurrentFlowData,
|
||||||
updateModel
|
updateModel,
|
||||||
|
loadProcessData,
|
||||||
|
refresh
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
NODE_DEFAULT_NAME,
|
NODE_DEFAULT_NAME,
|
||||||
AssignStartUserHandlerType,
|
AssignStartUserHandlerType,
|
||||||
AssignEmptyHandlerType,
|
AssignEmptyHandlerType,
|
||||||
FieldPermissionType,
|
FieldPermissionType
|
||||||
} from './consts'
|
} from './consts'
|
||||||
import { parseFormFields } from '@/components/FormCreate/src/utils/index'
|
import { parseFormFields } from '@/components/FormCreate/src/utils/index'
|
||||||
export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlowNode> {
|
export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlowNode> {
|
||||||
|
@ -52,9 +52,33 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType)
|
||||||
|
|
||||||
const getNodeConfigFormFields = (nodeFormFields?: Array<Record<string, string>>) => {
|
const getNodeConfigFormFields = (nodeFormFields?: Array<Record<string, string>>) => {
|
||||||
nodeFormFields = toRaw(nodeFormFields)
|
nodeFormFields = toRaw(nodeFormFields)
|
||||||
fieldsPermissionConfig.value =
|
if (!nodeFormFields || nodeFormFields.length === 0) {
|
||||||
cloneDeep(nodeFormFields) || getDefaultFieldsPermission(unref(formFields))
|
fieldsPermissionConfig.value = getDefaultFieldsPermission(unref(formFields))
|
||||||
|
} else {
|
||||||
|
fieldsPermissionConfig.value = mergeFieldsPermission(nodeFormFields, unref(formFields))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// 合并已经设置的表单字段权限,当前流程表单字段 (可能新增,或删除了字段)
|
||||||
|
const mergeFieldsPermission = (
|
||||||
|
formFieldsPermisson: Array<Record<string, string>>,
|
||||||
|
formFields?: string[]
|
||||||
|
) => {
|
||||||
|
let mergedFieldsPermission: Array<Record<string, any>> = []
|
||||||
|
if (formFields) {
|
||||||
|
mergedFieldsPermission = parseFormCreateFields(formFields).map((item) => {
|
||||||
|
const found = formFieldsPermisson.find(
|
||||||
|
(fieldPermission) => fieldPermission.field == item.field
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
field: item.field,
|
||||||
|
title: item.title,
|
||||||
|
permission: found ? found.permission : defaultPermission
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return mergedFieldsPermission
|
||||||
|
}
|
||||||
|
|
||||||
// 默认的表单权限: 获取表单的所有字段,设置字段默认权限为只读
|
// 默认的表单权限: 获取表单的所有字段,设置字段默认权限为只读
|
||||||
const getDefaultFieldsPermission = (formFields?: string[]) => {
|
const getDefaultFieldsPermission = (formFields?: string[]) => {
|
||||||
let defaultFieldsPermission: Array<Record<string, any>> = []
|
let defaultFieldsPermission: Array<Record<string, any>> = []
|
||||||
|
|
|
@ -25,7 +25,20 @@
|
||||||
</template>
|
</template>
|
||||||
<el-tabs type="border-card" v-model="activeTabName">
|
<el-tabs type="border-card" v-model="activeTabName">
|
||||||
<el-tab-pane label="权限" name="user">
|
<el-tab-pane label="权限" name="user">
|
||||||
<div> 待实现 </div>
|
<el-text v-if="!startUserIds || startUserIds.length === 0"> 全部成员可以发起流程 </el-text>
|
||||||
|
<el-text v-else-if="startUserIds.length == 1">
|
||||||
|
{{ getUserNicknames(startUserIds) }} 可发起流程
|
||||||
|
</el-text>
|
||||||
|
<el-text v-else>
|
||||||
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
|
effect="dark"
|
||||||
|
placement="top"
|
||||||
|
:content="getUserNicknames(startUserIds)"
|
||||||
|
>
|
||||||
|
{{ getUserNicknames(startUserIds.slice(0,2)) }} 等 {{ startUserIds.length }} 人可发起流程
|
||||||
|
</el-tooltip>
|
||||||
|
</el-text>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="表单字段权限" name="fields" v-if="formType === 10">
|
<el-tab-pane label="表单字段权限" name="fields" v-if="formType === 10">
|
||||||
<div class="field-setting-pane">
|
<div class="field-setting-pane">
|
||||||
|
@ -86,7 +99,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { SimpleFlowNode, NodeType, FieldPermissionType, START_USER_BUTTON_SETTING } from '../consts'
|
import { SimpleFlowNode, NodeType, FieldPermissionType, START_USER_BUTTON_SETTING } from '../consts'
|
||||||
import { useWatchNode, useDrawer, useNodeName, useFormFieldsPermission } from '../node'
|
import { useWatchNode, useDrawer, useNodeName, useFormFieldsPermission } from '../node'
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'StartUserNodeConfig'
|
name: 'StartUserNodeConfig'
|
||||||
})
|
})
|
||||||
|
@ -96,6 +109,10 @@ const props = defineProps({
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// 可发起流程的用户编号
|
||||||
|
const startUserIds = inject<Ref<any[]>>('startUserIds')
|
||||||
|
// 用户列表
|
||||||
|
const userOptions = inject<Ref<UserApi.UserVO[]>>('userList')
|
||||||
// 抽屉配置
|
// 抽屉配置
|
||||||
const { settingVisible, closeDrawer, openDrawer } = useDrawer()
|
const { settingVisible, closeDrawer, openDrawer } = useDrawer()
|
||||||
// 当前节点
|
// 当前节点
|
||||||
|
@ -108,12 +125,23 @@ const activeTabName = ref('user')
|
||||||
const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission(
|
const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission(
|
||||||
FieldPermissionType.WRITE
|
FieldPermissionType.WRITE
|
||||||
)
|
)
|
||||||
|
const getUserNicknames = (userIds: number[]): string => {
|
||||||
|
if (!userIds || userIds.length === 0) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const nicknames: string[] = []
|
||||||
|
userIds.forEach((userId) => {
|
||||||
|
const found = userOptions?.value.find((item) => item.id === userId)
|
||||||
|
if (found && found.nickname) {
|
||||||
|
nicknames.push(found.nickname)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nicknames.join(',')
|
||||||
|
}
|
||||||
// 保存配置
|
// 保存配置
|
||||||
const saveConfig = async () => {
|
const saveConfig = async () => {
|
||||||
activeTabName.value = 'user'
|
activeTabName.value = 'user'
|
||||||
currentNode.value.name = nodeName.value!
|
currentNode.value.name = nodeName.value!
|
||||||
// TODO 暂时写死。后续可以显示谁有权限可以发起
|
|
||||||
currentNode.value.showText = '已设置'
|
currentNode.value.showText = '已设置'
|
||||||
// 设置表单权限
|
// 设置表单权限
|
||||||
currentNode.value.fieldsPermission = fieldsPermissionConfig.value
|
currentNode.value.fieldsPermission = fieldsPermissionConfig.value
|
||||||
|
|
|
@ -39,9 +39,10 @@ const props = defineProps<{
|
||||||
modelId?: string
|
modelId?: string
|
||||||
modelKey?: string
|
modelKey?: string
|
||||||
modelName?: string
|
modelName?: string
|
||||||
|
value?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits(['success'])
|
const emit = defineEmits(['success', 'init-finished'])
|
||||||
const message = useMessage() // 国际化
|
const message = useMessage() // 国际化
|
||||||
|
|
||||||
// 表单信息
|
// 表单信息
|
||||||
|
@ -98,8 +99,35 @@ const initModeler = async (item) => {
|
||||||
// 确保 modeler 的所有实例都已经准备好
|
// 确保 modeler 的所有实例都已经准备好
|
||||||
if (initBpmnInstances()) {
|
if (initBpmnInstances()) {
|
||||||
isModelerReady.value = true
|
isModelerReady.value = true
|
||||||
if (!props.modelId && props.modelKey && props.modelName) {
|
emit('init-finished')
|
||||||
await updateModelData(props.modelKey, props.modelName)
|
|
||||||
|
// 初始化完成后,设置初始值
|
||||||
|
if (props.modelId) {
|
||||||
|
// 编辑模式
|
||||||
|
const data = await ModelApi.getModel(props.modelId)
|
||||||
|
model.value = {
|
||||||
|
...data,
|
||||||
|
bpmnXml: undefined // 清空 bpmnXml 属性
|
||||||
|
}
|
||||||
|
xmlString.value = data.bpmnXml || getDefaultBpmnXml(data.key, data.name)
|
||||||
|
} else if (props.modelKey && props.modelName) {
|
||||||
|
// 新建模式
|
||||||
|
xmlString.value = props.value || getDefaultBpmnXml(props.modelKey, props.modelName)
|
||||||
|
model.value = {
|
||||||
|
key: props.modelKey,
|
||||||
|
name: props.modelName
|
||||||
|
} as ModelApi.ModelVO
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入XML并刷新视图
|
||||||
|
await nextTick()
|
||||||
|
try {
|
||||||
|
await modeler.value.importXML(xmlString.value)
|
||||||
|
if (processDesigner.value?.refresh) {
|
||||||
|
processDesigner.value.refresh()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('导入XML失败:', error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('modeler 实例未完全初始化')
|
console.error('modeler 实例未完全初始化')
|
||||||
|
@ -123,6 +151,7 @@ const getDefaultBpmnXml = (key: string, name: string) => {
|
||||||
/** 添加/修改模型 */
|
/** 添加/修改模型 */
|
||||||
const save = async (bpmnXml: string) => {
|
const save = async (bpmnXml: string) => {
|
||||||
try {
|
try {
|
||||||
|
xmlString.value = bpmnXml
|
||||||
if (props.modelId) {
|
if (props.modelId) {
|
||||||
// 编辑模式
|
// 编辑模式
|
||||||
const data = {
|
const data = {
|
||||||
|
@ -141,58 +170,44 @@ const save = async (bpmnXml: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 初始化 */
|
// 监听 key、name 和 value 的变化
|
||||||
onMounted(async () => {
|
|
||||||
try {
|
|
||||||
if (props.modelId) {
|
|
||||||
// 编辑模式
|
|
||||||
// 查询模型
|
|
||||||
const data = await ModelApi.getModel(props.modelId)
|
|
||||||
model.value = {
|
|
||||||
...data,
|
|
||||||
bpmnXml: undefined // 清空 bpmnXml 属性
|
|
||||||
}
|
|
||||||
xmlString.value = data.bpmnXml || getDefaultBpmnXml(data.key, data.name)
|
|
||||||
} else if (props.modelKey && props.modelName) {
|
|
||||||
// 新建模式
|
|
||||||
xmlString.value = getDefaultBpmnXml(props.modelKey, props.modelName)
|
|
||||||
model.value = {
|
|
||||||
key: props.modelKey,
|
|
||||||
name: props.modelName
|
|
||||||
} as ModelApi.ModelVO
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('初始化失败:', error)
|
|
||||||
message.error('初始化失败')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 更新模型数据 */
|
|
||||||
const updateModelData = async (key?: string, name?: string) => {
|
|
||||||
if (key && name) {
|
|
||||||
xmlString.value = getDefaultBpmnXml(key, name)
|
|
||||||
model.value = {
|
|
||||||
...model.value,
|
|
||||||
key: key,
|
|
||||||
name: name
|
|
||||||
} as ModelApi.ModelVO
|
|
||||||
// 确保更新后重新渲染
|
|
||||||
await nextTick()
|
|
||||||
if (processDesigner.value?.refresh) {
|
|
||||||
processDesigner.value.refresh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听 key 和 name 的变化
|
|
||||||
watch(
|
watch(
|
||||||
[() => props.modelKey, () => props.modelName],
|
[() => props.modelKey, () => props.modelName, () => props.value],
|
||||||
async ([newKey, newName]) => {
|
async ([newKey, newName, newValue]) => {
|
||||||
if (!props.modelId && newKey && newName && modeler.value) {
|
if (!props.modelId && isModelerReady.value) {
|
||||||
await updateModelData(newKey, newName)
|
let shouldRefresh = false
|
||||||
|
|
||||||
|
if (newKey && newName) {
|
||||||
|
const newXml = newValue || getDefaultBpmnXml(newKey, newName)
|
||||||
|
if (newXml !== xmlString.value) {
|
||||||
|
xmlString.value = newXml
|
||||||
|
shouldRefresh = true
|
||||||
|
}
|
||||||
|
model.value = {
|
||||||
|
...model.value,
|
||||||
|
key: newKey,
|
||||||
|
name: newName
|
||||||
|
} as ModelApi.ModelVO
|
||||||
|
} else if (newValue && newValue !== xmlString.value) {
|
||||||
|
xmlString.value = newValue
|
||||||
|
shouldRefresh = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldRefresh) {
|
||||||
|
// 确保更新后重新渲染
|
||||||
|
await nextTick()
|
||||||
|
if (processDesigner.value?.refresh) {
|
||||||
|
try {
|
||||||
|
await modeler.value?.importXML(xmlString.value)
|
||||||
|
processDesigner.value.refresh()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('导入XML失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 在组件卸载时清理
|
// 在组件卸载时清理
|
||||||
|
@ -209,13 +224,15 @@ onBeforeUnmount(() => {
|
||||||
/** 获取 XML 字符串 */
|
/** 获取 XML 字符串 */
|
||||||
const saveXML = async () => {
|
const saveXML = async () => {
|
||||||
if (!modeler.value) {
|
if (!modeler.value) {
|
||||||
return { xml: undefined }
|
return { xml: xmlString.value }
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return await modeler.value.saveXML({ format: true })
|
const result = await modeler.value.saveXML({ format: true })
|
||||||
|
xmlString.value = result.xml
|
||||||
|
return result
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取XML失败:', error)
|
console.error('获取XML失败:', error)
|
||||||
return { xml: undefined }
|
return { xml: xmlString.value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,9 +250,14 @@ const saveSVG = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 刷新视图 */
|
/** 刷新视图 */
|
||||||
const refresh = () => {
|
const refresh = async () => {
|
||||||
if (processDesigner.value?.refresh) {
|
if (processDesigner.value?.refresh && modeler.value) {
|
||||||
processDesigner.value.refresh()
|
try {
|
||||||
|
await modeler.value.importXML(xmlString.value)
|
||||||
|
processDesigner.value.refresh()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('刷新视图失败:', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
:model-id="modelData.id"
|
:model-id="modelData.id"
|
||||||
:model-key="modelData.key"
|
:model-key="modelData.key"
|
||||||
:model-name="modelData.name"
|
:model-name="modelData.name"
|
||||||
:value="modelData.bpmnXml"
|
:value="currentBpmnXml"
|
||||||
ref="bpmnEditorRef"
|
ref="bpmnEditorRef"
|
||||||
@success="handleDesignSuccess"
|
@success="handleDesignSuccess"
|
||||||
|
@init-finished="handleEditorInit"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -19,9 +20,11 @@
|
||||||
:model-id="modelData.id"
|
:model-id="modelData.id"
|
||||||
:model-key="modelData.key"
|
:model-key="modelData.key"
|
||||||
:model-name="modelData.name"
|
:model-name="modelData.name"
|
||||||
:value="modelData.bpmnXml"
|
:start-user-ids="modelData.startUserIds"
|
||||||
|
:value="currentSimpleModel"
|
||||||
ref="simpleEditorRef"
|
ref="simpleEditorRef"
|
||||||
@success="handleDesignSuccess"
|
@success="handleDesignSuccess"
|
||||||
|
@init-finished="handleEditorInit"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -42,6 +45,7 @@ const emit = defineEmits(['update:modelValue', 'success'])
|
||||||
|
|
||||||
const bpmnEditorRef = ref()
|
const bpmnEditorRef = ref()
|
||||||
const simpleEditorRef = ref()
|
const simpleEditorRef = ref()
|
||||||
|
const isEditorInitialized = ref(false)
|
||||||
|
|
||||||
// 创建本地数据副本
|
// 创建本地数据副本
|
||||||
const modelData = computed({
|
const modelData = computed({
|
||||||
|
@ -49,49 +53,120 @@ const modelData = computed({
|
||||||
set: (val) => emit('update:modelValue', val)
|
set: (val) => emit('update:modelValue', val)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 保存当前的流程XML或数据
|
||||||
|
const currentBpmnXml = ref('')
|
||||||
|
const currentSimpleModel = ref('')
|
||||||
|
|
||||||
|
// 初始化或更新当前的XML数据
|
||||||
|
const initOrUpdateXmlData = () => {
|
||||||
|
if (modelData.value) {
|
||||||
|
if (modelData.value.type === BpmModelType.BPMN) {
|
||||||
|
currentBpmnXml.value = modelData.value.bpmnXml || ''
|
||||||
|
} else {
|
||||||
|
currentSimpleModel.value = modelData.value.simpleModel || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听modelValue的变化,更新数据
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
if (newVal.type === BpmModelType.BPMN) {
|
||||||
|
if (newVal.bpmnXml && newVal.bpmnXml !== currentBpmnXml.value) {
|
||||||
|
currentBpmnXml.value = newVal.bpmnXml
|
||||||
|
// 如果编辑器已经初始化,刷新视图
|
||||||
|
if (isEditorInitialized.value && bpmnEditorRef.value?.refresh) {
|
||||||
|
nextTick(() => {
|
||||||
|
bpmnEditorRef.value.refresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (newVal.simpleModel && newVal.simpleModel !== currentSimpleModel.value) {
|
||||||
|
currentSimpleModel.value = newVal.simpleModel
|
||||||
|
// 如果编辑器已经初始化,刷新视图
|
||||||
|
if (isEditorInitialized.value && simpleEditorRef.value?.refresh) {
|
||||||
|
nextTick(() => {
|
||||||
|
simpleEditorRef.value.refresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
/** 编辑器初始化完成的回调 */
|
||||||
|
const handleEditorInit = async () => {
|
||||||
|
isEditorInitialized.value = true
|
||||||
|
|
||||||
|
// 等待下一个tick,确保编辑器已经准备好
|
||||||
|
await nextTick()
|
||||||
|
|
||||||
|
// 初始化完成后,设置初始值
|
||||||
|
if (modelData.value.type === BpmModelType.BPMN) {
|
||||||
|
if (modelData.value.bpmnXml) {
|
||||||
|
currentBpmnXml.value = modelData.value.bpmnXml
|
||||||
|
if (bpmnEditorRef.value?.refresh) {
|
||||||
|
await nextTick()
|
||||||
|
bpmnEditorRef.value.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (modelData.value.simpleModel) {
|
||||||
|
currentSimpleModel.value = modelData.value.simpleModel
|
||||||
|
if (simpleEditorRef.value?.refresh) {
|
||||||
|
await nextTick()
|
||||||
|
simpleEditorRef.value.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 获取当前流程数据 */
|
/** 获取当前流程数据 */
|
||||||
const getProcessData = async () => {
|
const getProcessData = async () => {
|
||||||
try {
|
try {
|
||||||
if (modelData.value.type === BpmModelType.BPMN) {
|
if (modelData.value.type === BpmModelType.BPMN) {
|
||||||
// BPMN设计器
|
if (!bpmnEditorRef.value || !isEditorInitialized.value) {
|
||||||
if (bpmnEditorRef.value) {
|
return currentBpmnXml.value || undefined
|
||||||
const { xml } = await bpmnEditorRef.value.saveXML()
|
}
|
||||||
if (xml) {
|
const { xml } = await bpmnEditorRef.value.saveXML()
|
||||||
return xml
|
if (xml) {
|
||||||
}
|
currentBpmnXml.value = xml
|
||||||
|
return xml
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Simple设计器
|
if (!simpleEditorRef.value || !isEditorInitialized.value) {
|
||||||
if (simpleEditorRef.value) {
|
return currentSimpleModel.value || undefined
|
||||||
const flowData = await simpleEditorRef.value.getCurrentFlowData()
|
}
|
||||||
if (flowData) {
|
const flowData = await simpleEditorRef.value.getCurrentFlowData()
|
||||||
return flowData // 直接返回流程数据对象,不需要转换为字符串
|
if (flowData) {
|
||||||
}
|
currentSimpleModel.value = flowData
|
||||||
|
return flowData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined
|
return modelData.value.type === BpmModelType.BPMN
|
||||||
|
? currentBpmnXml.value
|
||||||
|
: currentSimpleModel.value
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取流程数据失败:', error)
|
console.error('获取流程数据失败:', error)
|
||||||
return undefined
|
return modelData.value.type === BpmModelType.BPMN
|
||||||
|
? currentBpmnXml.value
|
||||||
|
: currentSimpleModel.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 表单校验 */
|
/** 表单校验 */
|
||||||
const validate = async () => {
|
const validate = async () => {
|
||||||
try {
|
try {
|
||||||
// 根据流程类型获取对应的编辑器引用
|
|
||||||
const editorRef =
|
|
||||||
modelData.value.type === BpmModelType.BPMN ? bpmnEditorRef.value : simpleEditorRef.value
|
|
||||||
if (!editorRef) {
|
|
||||||
throw new Error('流程设计器未初始化')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取最新的流程数据
|
// 获取最新的流程数据
|
||||||
const processData = await getProcessData()
|
const processData = await getProcessData()
|
||||||
if (!processData) {
|
if (!processData) {
|
||||||
throw new Error('请设计流程')
|
throw new Error('请设计流程')
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error
|
throw error
|
||||||
|
@ -99,21 +174,24 @@ const validate = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理设计器保存成功 */
|
/** 处理设计器保存成功 */
|
||||||
const handleDesignSuccess = (data?: any) => {
|
const handleDesignSuccess = async (data?: any) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
if (modelData.value.type === BpmModelType.BPMN) {
|
if (modelData.value.type === BpmModelType.BPMN) {
|
||||||
modelData.value = {
|
currentBpmnXml.value = data
|
||||||
...modelData.value,
|
|
||||||
bpmnXml: data,
|
|
||||||
simpleModel: null
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
modelData.value = {
|
currentSimpleModel.value = data
|
||||||
...modelData.value,
|
|
||||||
bpmnXml: null,
|
|
||||||
simpleModel: data
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建新的对象以触发响应式更新
|
||||||
|
const newModelData = {
|
||||||
|
...modelData.value,
|
||||||
|
bpmnXml: modelData.value.type === BpmModelType.BPMN ? data : null,
|
||||||
|
simpleModel: modelData.value.type === BpmModelType.BPMN ? null : data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用emit更新父组件的数据
|
||||||
|
await nextTick()
|
||||||
|
emit('update:modelValue', newModelData)
|
||||||
emit('success', data)
|
emit('success', data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,6 +201,33 @@ const showDesigner = computed(() => {
|
||||||
return Boolean(modelData.value?.key && modelData.value?.name)
|
return Boolean(modelData.value?.key && modelData.value?.name)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 组件创建时初始化数据
|
||||||
|
onMounted(() => {
|
||||||
|
initOrUpdateXmlData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 组件卸载前保存数据
|
||||||
|
onBeforeUnmount(async () => {
|
||||||
|
try {
|
||||||
|
// 获取并保存最新的流程数据
|
||||||
|
const data = await getProcessData()
|
||||||
|
if (data) {
|
||||||
|
// 创建新的对象以触发响应式更新
|
||||||
|
const newModelData = {
|
||||||
|
...modelData.value,
|
||||||
|
bpmnXml: modelData.value.type === BpmModelType.BPMN ? data : null,
|
||||||
|
simpleModel: modelData.value.type === BpmModelType.BPMN ? null : data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用emit更新父组件的数据
|
||||||
|
await nextTick()
|
||||||
|
emit('update:modelValue', newModelData)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存数据失败:', error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
validate,
|
validate,
|
||||||
getProcessData
|
getProcessData
|
||||||
|
|
|
@ -194,11 +194,32 @@ const validateAllSteps = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 流程设计校验
|
// 流程设计校验
|
||||||
await processDesignRef.value?.validate()
|
// 如果已经有流程数据,则不需要重新校验
|
||||||
const processData = await processDesignRef.value?.getProcessData()
|
if (!formData.value.bpmnXml && !formData.value.simpleModel) {
|
||||||
if (!processData) {
|
// 如果当前不在第三步,需要先保存当前步骤数据
|
||||||
currentStep.value = 2
|
if (currentStep.value !== 2) {
|
||||||
throw new Error('请设计流程')
|
await steps[currentStep.value].validator()
|
||||||
|
// 切换到第三步
|
||||||
|
currentStep.value = 2
|
||||||
|
// 等待组件渲染完成
|
||||||
|
await nextTick()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验流程设计
|
||||||
|
await processDesignRef.value?.validate()
|
||||||
|
const processData = await processDesignRef.value?.getProcessData()
|
||||||
|
if (!processData) {
|
||||||
|
throw new Error('请设计流程')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存流程数据
|
||||||
|
if (formData.value.type === BpmModelType.BPMN) {
|
||||||
|
formData.value.bpmnXml = processData
|
||||||
|
formData.value.simpleModel = null
|
||||||
|
} else {
|
||||||
|
formData.value.bpmnXml = null
|
||||||
|
formData.value.simpleModel = processData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -213,22 +234,23 @@ const handleSave = async () => {
|
||||||
// 保存前校验所有步骤的数据
|
// 保存前校验所有步骤的数据
|
||||||
await validateAllSteps()
|
await validateAllSteps()
|
||||||
|
|
||||||
// 获取最新的流程设计数据
|
|
||||||
const processData = await processDesignRef.value?.getProcessData()
|
|
||||||
if (!processData) {
|
|
||||||
throw new Error('获取流程数据失败')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新表单数据
|
// 更新表单数据
|
||||||
const modelData = {
|
const modelData = {
|
||||||
...formData.value
|
...formData.value
|
||||||
}
|
}
|
||||||
if (formData.value.type === BpmModelType.BPMN) {
|
|
||||||
modelData.bpmnXml = processData
|
// 如果当前在第三步,获取最新的流程设计数据
|
||||||
modelData.simpleModel = null
|
if (currentStep.value === 2) {
|
||||||
} else {
|
const processData = await processDesignRef.value?.getProcessData()
|
||||||
modelData.bpmnXml = null
|
if (processData) {
|
||||||
modelData.simpleModel = processData // 直接使用流程数据对象
|
if (formData.value.type === BpmModelType.BPMN) {
|
||||||
|
modelData.bpmnXml = processData
|
||||||
|
modelData.simpleModel = null
|
||||||
|
} else {
|
||||||
|
modelData.bpmnXml = null
|
||||||
|
modelData.simpleModel = processData
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formData.value.id) {
|
if (formData.value.id) {
|
||||||
|
@ -281,22 +303,23 @@ const handleDeploy = async () => {
|
||||||
// 校验所有步骤
|
// 校验所有步骤
|
||||||
await validateAllSteps()
|
await validateAllSteps()
|
||||||
|
|
||||||
// 获取最新的流程设计数据
|
|
||||||
const processData = await processDesignRef.value?.getProcessData()
|
|
||||||
if (!processData) {
|
|
||||||
throw new Error('获取流程数据失败')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新表单数据
|
// 更新表单数据
|
||||||
const modelData = {
|
const modelData = {
|
||||||
...formData.value
|
...formData.value
|
||||||
}
|
}
|
||||||
if (formData.value.type === BpmModelType.BPMN) {
|
|
||||||
modelData.bpmnXml = processData
|
// 如果当前在第三步,获取最新的流程设计数据
|
||||||
modelData.simpleModel = null
|
if (currentStep.value === 2) {
|
||||||
} else {
|
const processData = await processDesignRef.value?.getProcessData()
|
||||||
modelData.bpmnXml = null
|
if (processData) {
|
||||||
modelData.simpleModel = processData // 直接使用流程数据对象
|
if (formData.value.type === BpmModelType.BPMN) {
|
||||||
|
modelData.bpmnXml = processData
|
||||||
|
modelData.simpleModel = null
|
||||||
|
} else {
|
||||||
|
modelData.bpmnXml = null
|
||||||
|
modelData.simpleModel = processData
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 先保存所有数据
|
// 先保存所有数据
|
||||||
|
@ -320,27 +343,51 @@ const handleDeploy = async () => {
|
||||||
|
|
||||||
/** 步骤切换处理 */
|
/** 步骤切换处理 */
|
||||||
const handleStepClick = async (index: number) => {
|
const handleStepClick = async (index: number) => {
|
||||||
// 如果是切换到第三步(流程设计),需要校验key和name
|
try {
|
||||||
if (index === 2) {
|
// 如果是切换到第三步(流程设计),需要校验key和name
|
||||||
if (!formData.value.key || !formData.value.name) {
|
if (index === 2) {
|
||||||
message.warning('请先填写流程标识和流程名称')
|
if (!formData.value.key || !formData.value.name) {
|
||||||
return
|
message.warning('请先填写流程标识和流程名称')
|
||||||
}
|
return
|
||||||
}
|
|
||||||
|
|
||||||
// 只有在向后切换时才进行校验
|
|
||||||
if (index > currentStep.value) {
|
|
||||||
try {
|
|
||||||
if (typeof steps[currentStep.value].validator === 'function') {
|
|
||||||
await steps[currentStep.value].validator()
|
|
||||||
}
|
}
|
||||||
currentStep.value = index
|
|
||||||
} catch (error) {
|
|
||||||
message.warning('请先完善当前步骤必填信息')
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// 向前切换时直接切换
|
// 保存当前步骤的数据
|
||||||
|
if (currentStep.value === 2) {
|
||||||
|
const processData = await processDesignRef.value?.getProcessData()
|
||||||
|
if (processData) {
|
||||||
|
if (formData.value.type === BpmModelType.BPMN) {
|
||||||
|
formData.value.bpmnXml = processData
|
||||||
|
formData.value.simpleModel = null
|
||||||
|
} else {
|
||||||
|
formData.value.bpmnXml = null
|
||||||
|
formData.value.simpleModel = processData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 只有在向后切换时才进行校验
|
||||||
|
if (index > currentStep.value) {
|
||||||
|
if (typeof steps[currentStep.value].validator === 'function') {
|
||||||
|
await steps[currentStep.value].validator()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换步骤
|
||||||
currentStep.value = index
|
currentStep.value = index
|
||||||
|
|
||||||
|
// 如果切换到流程设计步骤,等待组件渲染完成后刷新设计器
|
||||||
|
if (index === 2) {
|
||||||
|
await nextTick()
|
||||||
|
// 等待更长时间确保组件完全初始化
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 200))
|
||||||
|
if (processDesignRef.value?.refresh) {
|
||||||
|
await processDesignRef.value.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('步骤切换失败:', error)
|
||||||
|
message.warning('请先完善当前步骤必填信息')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
:model-id="modelId"
|
:model-id="modelId"
|
||||||
:model-key="modelKey"
|
:model-key="modelKey"
|
||||||
:model-name="modelName"
|
:model-name="modelName"
|
||||||
|
:value="currentValue"
|
||||||
@success="handleSuccess"
|
@success="handleSuccess"
|
||||||
|
@init-finished="handleInit"
|
||||||
|
:start-user-ids="startUserIds"
|
||||||
ref="designerRef"
|
ref="designerRef"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
@ -20,38 +23,133 @@ const props = defineProps<{
|
||||||
modelId?: string
|
modelId?: string
|
||||||
modelKey?: string
|
modelKey?: string
|
||||||
modelName?: string
|
modelName?: string
|
||||||
|
value?: string
|
||||||
|
startUserIds?: number[]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits(['success'])
|
const emit = defineEmits(['success', 'init-finished'])
|
||||||
const designerRef = ref()
|
const designerRef = ref()
|
||||||
|
const isInitialized = ref(false)
|
||||||
|
const currentValue = ref('')
|
||||||
|
|
||||||
|
// 初始化或更新当前值
|
||||||
|
const initOrUpdateValue = async () => {
|
||||||
|
console.log('initOrUpdateValue', props.value)
|
||||||
|
if (props.value) {
|
||||||
|
currentValue.value = props.value
|
||||||
|
// 如果设计器已经初始化,立即加载数据
|
||||||
|
if (isInitialized.value && designerRef.value) {
|
||||||
|
try {
|
||||||
|
await designerRef.value.loadProcessData(props.value)
|
||||||
|
await nextTick()
|
||||||
|
if (designerRef.value.refresh) {
|
||||||
|
await designerRef.value.refresh()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载流程数据失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 监听属性变化
|
// 监听属性变化
|
||||||
watch([() => props.modelKey, () => props.modelName], ([newKey, newName]) => {
|
watch(
|
||||||
if (designerRef.value && newKey && newName) {
|
[() => props.modelKey, () => props.modelName, () => props.value],
|
||||||
designerRef.value.updateModel(newKey, newName)
|
async ([newKey, newName, newValue], [oldKey, oldName, oldValue]) => {
|
||||||
|
if (designerRef.value && isInitialized.value) {
|
||||||
|
try {
|
||||||
|
if (newKey && newName && (newKey !== oldKey || newName !== oldName)) {
|
||||||
|
await designerRef.value.updateModel(newKey, newName)
|
||||||
|
}
|
||||||
|
if (newValue && newValue !== oldValue) {
|
||||||
|
currentValue.value = newValue
|
||||||
|
await designerRef.value.loadProcessData(newValue)
|
||||||
|
await nextTick()
|
||||||
|
if (designerRef.value.refresh) {
|
||||||
|
await designerRef.value.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('更新流程数据失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 初始化完成回调
|
||||||
|
const handleInit = async () => {
|
||||||
|
try {
|
||||||
|
isInitialized.value = true
|
||||||
|
emit('init-finished')
|
||||||
|
|
||||||
|
// 等待下一个tick,确保设计器已经准备好
|
||||||
|
await nextTick()
|
||||||
|
|
||||||
|
// 初始化完成后,设置初始值
|
||||||
|
if (props.modelKey && props.modelName) {
|
||||||
|
await designerRef.value.updateModel(props.modelKey, props.modelName)
|
||||||
|
}
|
||||||
|
if (props.value) {
|
||||||
|
currentValue.value = props.value
|
||||||
|
await designerRef.value.loadProcessData(props.value)
|
||||||
|
// 再次刷新确保数据正确加载
|
||||||
|
await nextTick()
|
||||||
|
if (designerRef.value.refresh) {
|
||||||
|
await designerRef.value.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('初始化流程数据失败:', error)
|
||||||
}
|
}
|
||||||
}, { immediate: true, deep: true })
|
}
|
||||||
|
|
||||||
// 修改成功回调
|
// 修改成功回调
|
||||||
const handleSuccess = (data?: any) => {
|
const handleSuccess = (data?: any) => {
|
||||||
emit('success', data)
|
console.warn('handleSuccess', data)
|
||||||
|
if (data && data !== currentValue.value) {
|
||||||
|
currentValue.value = data
|
||||||
|
emit('success', data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取当前流程数据 */
|
/** 获取当前流程数据 */
|
||||||
const getCurrentFlowData = async () => {
|
const getCurrentFlowData = async () => {
|
||||||
try {
|
try {
|
||||||
if (designerRef.value) {
|
if (designerRef.value) {
|
||||||
return await designerRef.value.getCurrentFlowData()
|
const data = await designerRef.value.getCurrentFlowData()
|
||||||
|
if (data) {
|
||||||
|
currentValue.value = data
|
||||||
|
}
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
return undefined
|
return currentValue.value || undefined
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取流程数据失败:', error)
|
console.error('获取流程数据失败:', error)
|
||||||
return undefined
|
return currentValue.value || undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 组件创建时初始化数据
|
||||||
|
onMounted(() => {
|
||||||
|
initOrUpdateValue()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 组件卸载前保存数据
|
||||||
|
onBeforeUnmount(async () => {
|
||||||
|
try {
|
||||||
|
const data = await getCurrentFlowData()
|
||||||
|
if (data) {
|
||||||
|
emit('success', data)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存数据失败:', error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getCurrentFlowData
|
getCurrentFlowData,
|
||||||
|
refresh: () => designerRef.value?.refresh?.()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|
Loading…
Reference in New Issue