仿钉钉流程设计器- 代码优化

This commit is contained in:
jason 2024-07-23 22:39:06 +08:00
parent 2c11228f55
commit 3a5c93fa84
9 changed files with 675 additions and 603 deletions

View File

@ -50,6 +50,7 @@ import CopyTaskNode from './nodes/CopyTaskNode.vue'
import ExclusiveNode from './nodes/ExclusiveNode.vue' import ExclusiveNode from './nodes/ExclusiveNode.vue'
import ParallelNode from './nodes/ParallelNode.vue' import ParallelNode from './nodes/ParallelNode.vue'
import { SimpleFlowNode, NodeType } from './consts' import { SimpleFlowNode, NodeType } from './consts'
import { useWatchNode } from './node'
defineOptions({ defineOptions({
name: 'ProcessNodeTree' name: 'ProcessNodeTree'
}) })
@ -72,15 +73,8 @@ const emits = defineEmits<{
] ]
}>() }>()
const currentNode = ref<SimpleFlowNode>(props.flowNode) const currentNode = useWatchNode(props)
// .
watch(
() => props.flowNode,
(newValue) => {
currentNode.value = newValue
}
)
// //
const handleModelValueUpdate = (updateValue) => { const handleModelValueUpdate = (updateValue) => {
emits('update:flowNode', updateValue) emits('update:flowNode', updateValue)

View File

@ -138,6 +138,7 @@ const zoomIn = () => {
onMounted(async () => { onMounted(async () => {
const result = await getBpmSimpleModel(props.modelId) const result = await getBpmSimpleModel(props.modelId)
console.log('the result is :', result)
if (result) { if (result) {
processNodeTree.value = result processNodeTree.value = result
} else { } else {

View File

@ -1,6 +1,8 @@
// @ts-ignore // @ts-ignore
import { DictDataVO } from '@/api/system/dict/types' import { DictDataVO } from '@/api/system/dict/types'
/**
*
*/
export enum NodeType { export enum NodeType {
/** /**
* *
@ -46,68 +48,37 @@ export enum NodeType {
*/ */
INCLUSIVE_NODE_JOIN = 8 INCLUSIVE_NODE_JOIN = 8
} }
// 时间单位枚举 /**
export enum TimeUnitType { *
/**
*
*/ */
MINUTE = 1, export interface SimpleFlowNode {
/** id: string
* type: NodeType
*/ name: string
HOUR = 2, showText?: string
/** attributes?: any
* // 孩子节点
*/ childNode?: SimpleFlowNode
DAY = 3 // 条件节点
conditionNodes?: SimpleFlowNode[]
// 候选人策略
candidateStrategy?: number
// 候选人参数
candidateParam?: string
// 多人审批方式
approveMethod?: ApproveMethodType
//通过比例
approveRatio?: number
// 审批按钮设置
buttonsSetting?: any[]
// 表单权限
fieldsPermission?: Array<Record<string, string>>
// 审批任务超时处理
timeoutHandler?: TimeoutHandler
// 审批任务拒绝处理
rejectHandler?: RejectHandler
} }
// 候选人策略枚举 用于审批节点。抄送节点 )
export enum RejectHandlerType {
/**
*
*/
FINISH_PROCESS = 1,
/**
*
*/
RETURN_USER_TASK = 2
}
// 条件配置类型 用于条件节点配置
export enum ConditionConfigType {
/**
*
*/
EXPRESSION = 1,
/**
*
*/
RULE = 2
}
// 多人审批方式类型 用于审批节点
export enum ApproveMethodType {
/**
*
*/
RRANDOM_SELECT_ONE_APPROVE = 1,
/**
* ()
*/
APPROVE_BY_RATIO = 2,
/**
* ()
*/
ANY_APPROVE = 3,
/**
*
*/
SEQUENTIAL_APPROVE = 4
}
// 候选人策略 用于审批节点。抄送节点 )
export enum CandidateStrategy { export enum CandidateStrategy {
/** /**
* *
@ -147,12 +118,41 @@ export enum CandidateStrategy {
EXPRESSION = 60 EXPRESSION = 60
} }
export type RejectHandler = { // 多人审批方式类型枚举 用于审批节点
type: RejectHandlerType export enum ApproveMethodType {
/**
*
*/
RRANDOM_SELECT_ONE_APPROVE = 1,
/**
* ()
*/
APPROVE_BY_RATIO = 2,
/**
* ()
*/
ANY_APPROVE = 3,
/**
*
*/
SEQUENTIAL_APPROVE = 4
}
/**
*
*/
export type RejectHandler = {
// 审批拒绝类型
type: RejectHandlerType
// 回退节点 Id
returnNodeId?: string returnNodeId?: string
} }
/**
*
*/
export type TimeoutHandler = { export type TimeoutHandler = {
//是否开启超时处理 //是否开启超时处理
enable: boolean enable: boolean
@ -163,60 +163,57 @@ export type TimeoutHandler = {
// 执行动作是自动提醒, 最大提醒次数 // 执行动作是自动提醒, 最大提醒次数
maxRemindCount?: number maxRemindCount?: number
} }
// 审批拒绝类型枚举
export type SimpleFlowNode = { export enum RejectHandlerType {
id: string /**
type: NodeType *
name: string */
showText?: string FINISH_PROCESS = 1,
attributes?: any /**
// 孩子节点 *
childNode?: SimpleFlowNode */
// 条件节点 RETURN_USER_TASK = 2
conditionNodes?: SimpleFlowNode[]
// 候选人策略
candidateStrategy?: number
// 候选人参数
candidateParam?: string
// 多人审批方式
approveMethod?: ApproveMethodType
//通过比例
approveRatio?: number
// 审批按钮设置
buttonsSetting?: any[]
// 表单权限
fieldsPermission?: any[]
// 审批任务超时处理
timeoutHandler?: TimeoutHandler
// 审批任务拒绝处理
rejectHandler?: RejectHandler
} }
// 条件组 // 时间单位枚举
export type ConditionGroup = { export enum TimeUnitType {
// 条件组的逻辑关系是否为且 /**
and: boolean *
// 条件数组 */
conditions: Condition[] MINUTE = 1,
/**
*
*/
HOUR = 2,
/**
*
*/
DAY = 3
} }
// 条件 // 条件配置类型 用于条件节点配置
export type Condition = { export enum ConditionConfigType {
// 条件规则的逻辑关系是否为且 /**
and: boolean *
rules: ConditionRule[] */
EXPRESSION = 1,
/**
*
*/
RULE = 2
} }
// 条件规则 /**
export type ConditionRule = { *
type: number */
opName: string export type ButtonSetting = {
opCode: string id: OpsButtonType
leftSide: string displayName: string
rightSide: string enable: boolean
} }
// 审批操作按钮类型 // 操作按钮类型枚举 (用于审批节点)
export enum OpsButtonType { export enum OpsButtonType {
/** /**
* *
@ -243,11 +240,34 @@ export enum OpsButtonType {
*/ */
RETURN = 6 RETURN = 6
} }
/**
*
*/
export type ConditionRule = {
type: number
opName: string
opCode: string
leftSide: string
rightSide: string
}
export type ButtonSetting = { /**
id: OpsButtonType *
displayName: string */
enable: boolean export type ConditionGroup = {
// 条件组的逻辑关系是否为且
and: boolean
// 条件数组
conditions: Condition[]
}
/**
*
*/
export type Condition = {
// 条件规则的逻辑关系是否为且
and: boolean
rules: ConditionRule[]
} }
export const NODE_DEFAULT_TEXT = new Map<number, string>() export const NODE_DEFAULT_TEXT = new Map<number, string>()

View File

@ -0,0 +1,260 @@
import { cloneDeep } from 'lodash-es'
import * as RoleApi from '@/api/system/role'
import * as DeptApi from '@/api/system/dept'
import * as PostApi from '@/api/system/post'
import * as UserApi from '@/api/system/user'
import * as UserGroupApi from '@/api/bpm/userGroup'
import {
SimpleFlowNode,
CandidateStrategy,
NodeType,
ApproveMethodType,
RejectHandlerType,
NODE_DEFAULT_NAME
} from './consts'
export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlowNode> {
const node = ref<SimpleFlowNode>(props.flowNode)
watch(
() => props.flowNode,
(newValue) => {
node.value = newValue
}
)
return node
}
/**
* @description
*/
export function useFormFieldsPermission() {
// 字段权限配置. 需要有 field, title, permissioin 属性
const fieldsPermissionConfig = ref<Array<Record<string, string>>>([])
const formType = inject<Ref<number>>('formType') // 表单类型
const formFields = inject<Ref<string[]>>('formFields') // 流程表单字段
const getNodeConfigFormFields = (nodeFormFields?: Array<Record<string, string>>) => {
nodeFormFields = toRaw(nodeFormFields)
fieldsPermissionConfig.value =
cloneDeep(nodeFormFields) || getDefaultFieldsPermission(unref(formFields))
}
// 获取默认的表单权限。 所有字段只读
const getDefaultFieldsPermission = (formFields?: string[]) => {
const defaultFieldsPermission: Array<Record<string, string>> = []
if (formFields) {
formFields.forEach((fieldStr: string) => {
const { field, title } = JSON.parse(fieldStr)
defaultFieldsPermission.push({
field,
title,
permission: '1' // 只读
})
})
}
return defaultFieldsPermission
}
return {
formType,
fieldsPermissionConfig,
getNodeConfigFormFields
}
}
export type UserTaskFormType = {
candidateParamArray: any[]
candidateStrategy: CandidateStrategy
approveMethod: ApproveMethodType
approveRatio?: number
rejectHandlerType?: RejectHandlerType
returnNodeId?: string
timeoutHandlerEnable?: boolean
timeoutHandlerAction?: number
timeDuration?: number
maxRemindCount?: number
buttonsSetting: any[]
}
export type CopyTaskFormType = {
candidateParamArray: any[]
candidateStrategy: CandidateStrategy
}
/**
* @description
*/
export function useNodeForm(nodeType: NodeType) {
const roleOptions = inject<Ref<RoleApi.RoleVO[]>>('roleList') // 角色列表
const postOptions = inject<Ref<PostApi.PostVO[]>>('postList') // 岗位列表
const userOptions = inject<Ref<UserApi.UserVO[]>>('userList') // 用户列表
const deptOptions = inject<Ref<DeptApi.DeptVO[]>>('deptList') // 部门列表
const userGroupOptions = inject<Ref<UserGroupApi.UserGroupVO[]>>('userGroupList') // 用户组列表
const deptTreeOptions = inject('deptTree') // 部门树
const configForm = ref<UserTaskFormType | CopyTaskFormType>()
if (nodeType === NodeType.USER_TASK_NODE) {
configForm.value = {
candidateParamArray: [],
candidateStrategy: CandidateStrategy.USER,
approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE,
approveRatio: 100,
rejectHandlerType: RejectHandlerType.FINISH_PROCESS,
returnNodeId: '',
timeoutHandlerEnable: false,
timeoutHandlerAction: 1,
timeDuration: 6, // 默认 6小时
maxRemindCount: 1, // 默认 提醒 1次
buttonsSetting: []
}
} else {
configForm.value = {
candidateParamArray: [],
candidateStrategy: CandidateStrategy.USER
}
}
const getShowText = (): string => {
let showText = ''
// 指定成员
if (configForm.value?.candidateStrategy === CandidateStrategy.USER) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
userOptions?.value.forEach((item) => {
if (configForm.value?.candidateParamArray.includes(item.id)) {
candidateNames.push(item.nickname)
}
})
showText = `指定成员:${candidateNames.join(',')}`
}
}
// 指定角色
if (configForm.value?.candidateStrategy === CandidateStrategy.ROLE) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
roleOptions?.value.forEach((item) => {
if (configForm.value?.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定角色:${candidateNames.join(',')}`
}
}
// 指定部门
if (
configForm.value?.candidateStrategy === CandidateStrategy.DEPT_MEMBER ||
configForm.value?.candidateStrategy === CandidateStrategy.DEPT_LEADER
) {
if (configForm.value?.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
deptOptions?.value.forEach((item) => {
if (configForm.value?.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) {
showText = `部门成员:${candidateNames.join(',')}`
} else {
showText = `部门的负责人:${candidateNames.join(',')}`
}
}
}
// 指定岗位
if (configForm.value?.candidateStrategy === CandidateStrategy.POST) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
postOptions?.value.forEach((item) => {
if (configForm.value?.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定岗位: ${candidateNames.join(',')}`
}
}
// 指定用户组
if (configForm.value?.candidateStrategy === CandidateStrategy.USER_GROUP) {
if (configForm.value?.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
userGroupOptions?.value.forEach((item) => {
if (configForm.value?.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定用户组: ${candidateNames.join(',')}`
}
}
// 发起人自选
if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_SELECT) {
showText = `发起人自选`
}
// 发起人自己
if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER) {
showText = `发起人自己`
}
// 流程表达式
if (configForm.value?.candidateStrategy === CandidateStrategy.EXPRESSION) {
if (configForm.value.candidateParamArray?.length > 0) {
showText = `流程表达式:${configForm.value.candidateParamArray[0]}`
}
}
return showText
}
return {
configForm,
roleOptions,
postOptions,
userOptions,
userGroupOptions,
deptTreeOptions,
getShowText
}
}
/**
* @description
*/
export function useDrawer() {
// 抽屉配置是否可见
const settingVisible = ref(false)
// 关闭配置抽屉
const closeDrawer = () => {
settingVisible.value = false
}
// 打开配置抽屉
const openDrawer = () => {
settingVisible.value = true
}
return {
settingVisible,
closeDrawer,
openDrawer
}
}
/**
* @description
*/
export function useNodeName(nodeType: NodeType) {
// 节点名称
const nodeName = ref<string>()
// 节点名称输入框
const showInput = ref(false)
// 点击节点名称编辑图标
const clickIcon = () => {
showInput.value = true
}
// 节点名称输入框失去焦点
const blurEvent = () => {
showInput.value = false
nodeName.value = nodeName.value || (NODE_DEFAULT_NAME.get(nodeType) as string)
}
return {
nodeName,
showInput,
clickIcon,
blurEvent
}
}

View File

@ -14,14 +14,12 @@
class="config-editable-input" class="config-editable-input"
@blur="blurEvent()" @blur="blurEvent()"
v-mountedFocus v-mountedFocus
v-model="configForm.name" v-model="nodeName"
:placeholder="configForm.name" :placeholder="nodeName"
/> />
<div v-else class="node-name" <div v-else class="node-name">
>{{ configForm.name }} {{ nodeName }} <Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" />
<Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" </div>
/></div>
<div class="divide-line"></div> <div class="divide-line"></div>
</div> </div>
</template> </template>
@ -173,7 +171,7 @@
</div> </div>
<div <div
class="field-setting-item" class="field-setting-item"
v-for="(item, index) in configForm.fieldsPermission" v-for="(item, index) in fieldsPermissionConfig"
:key="index" :key="index"
> >
<div class="field-setting-item-label"> {{ item.title }} </div> <div class="field-setting-item-label"> {{ item.title }} </div>
@ -202,16 +200,17 @@
</el-drawer> </el-drawer>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { SimpleFlowNode, CandidateStrategy, NodeType, NODE_DEFAULT_NAME } from '../consts' import { SimpleFlowNode, CandidateStrategy, NodeType } from '../consts'
import { getDefaultFieldsPermission } from '../utils'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as RoleApi from '@/api/system/role' import {
import * as DeptApi from '@/api/system/dept' useWatchNode,
import * as PostApi from '@/api/system/post' useDrawer,
import * as UserApi from '@/api/system/user' useNodeName,
import * as UserGroupApi from '@/api/bpm/userGroup' useFormFieldsPermission,
useNodeForm,
CopyTaskFormType
} from '../node'
import { defaultProps } from '@/utils/tree' import { defaultProps } from '@/utils/tree'
import { cloneDeep } from 'lodash-es'
defineOptions({ defineOptions({
name: 'CopyTaskNodeConfig' name: 'CopyTaskNodeConfig'
}) })
@ -221,26 +220,34 @@ const props = defineProps({
required: true required: true
} }
}) })
// //
const settingVisible = ref(false) const { settingVisible, closeDrawer, openDrawer } = useDrawer()
// //
const currentNode = ref<SimpleFlowNode>(props.flowNode) const currentNode = useWatchNode(props)
// //
watch( const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.COPY_TASK_NODE)
() => props.flowNode, // Tab
(newValue) => { const activeTabName = ref('user')
currentNode.value = newValue //
} const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission()
) //
const roleOptions = inject<Ref<RoleApi.RoleVO[]>>('roleList') // const formRef = ref() // Ref
const postOptions = inject<Ref<PostApi.PostVO[]>>('postList') // //
const userOptions = inject<Ref<UserApi.UserVO[]>>('userList') // const formRules = reactive({
const deptOptions = inject<Ref<DeptApi.DeptVO[]>>('deptList') // candidateStrategy: [{ required: true, message: '抄送人设置不能为空', trigger: 'change' }],
const userGroupOptions = inject<Ref<UserGroupApi.UserGroupVO[]>>('userGroupList') // candidateParamArray: [{ required: true, message: '选项不能为空', trigger: 'blur' }]
const deptTreeOptions = inject('deptTree') // })
const formType = inject('formType') //
const formFields = inject<Ref<string[]>>('formFields')
const {
configForm: tempConfigForm,
roleOptions,
postOptions,
userOptions,
userGroupOptions,
deptTreeOptions,
getShowText
} = useNodeForm(NodeType.COPY_TASK_NODE)
const configForm = tempConfigForm as Ref<CopyTaskFormType>
// //
const copyUserStrategies = computed(() => { const copyUserStrategies = computed(() => {
return getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY).filter( return getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY).filter(
@ -249,25 +256,9 @@ const copyUserStrategies = computed(() => {
item.value !== CandidateStrategy.START_USER item.value !== CandidateStrategy.START_USER
) )
}) })
// Tab //
const activeTabName = ref('user') const changeCandidateStrategy = () => {
const formRef = ref() // Ref configForm.value.candidateParamArray = []
const configForm = ref<any>({
name: NODE_DEFAULT_NAME.get(NodeType.COPY_TASK_NODE),
candidateParamArray: [],
candidateStrategy: CandidateStrategy.USER,
fieldsPermission: []
})
//
const formRules = reactive({
candidateStrategy: [{ required: true, message: '抄送人设置不能为空', trigger: 'change' }],
candidateParamArray: [{ required: true, message: '选项不能为空', trigger: 'blur' }]
})
//
const closeDrawer = () => {
settingVisible.value = false
} }
// //
const saveConfig = async () => { const saveConfig = async () => {
@ -277,23 +268,19 @@ const saveConfig = async () => {
if (!valid) return false if (!valid) return false
const showText = getShowText() const showText = getShowText()
if (!showText) return false if (!showText) return false
currentNode.value.name = configForm.value.name currentNode.value.name = nodeName.value!
currentNode.value.candidateParam = configForm.value.candidateParamArray?.join(',') currentNode.value.candidateParam = configForm.value.candidateParamArray?.join(',')
currentNode.value.candidateStrategy = configForm.value.candidateStrategy currentNode.value.candidateStrategy = configForm.value.candidateStrategy
currentNode.value.showText = showText currentNode.value.showText = showText
currentNode.value.fieldsPermission = configForm.value.fieldsPermission currentNode.value.fieldsPermission = fieldsPermissionConfig.value
settingVisible.value = false settingVisible.value = false
return true return true
} }
//
const open = () => { const showCopyTaskNodeConfig = (node: SimpleFlowNode) => {
settingVisible.value = true nodeName.value = node.name
}
//
const setCurrentNode = (node: SimpleFlowNode) => {
configForm.value.name = node.name
// //
configForm.value.candidateStrategy = node.candidateStrategy configForm.value.candidateStrategy = node.candidateStrategy!
const strCandidateParam = node?.candidateParam const strCandidateParam = node?.candidateParam
if (node.candidateStrategy === CandidateStrategy.EXPRESSION) { if (node.candidateStrategy === CandidateStrategy.EXPRESSION) {
configForm.value.candidateParamArray[0] = strCandidateParam configForm.value.candidateParamArray[0] = strCandidateParam
@ -303,104 +290,10 @@ const setCurrentNode = (node: SimpleFlowNode) => {
} }
} }
// //
configForm.value.fieldsPermission = getNodeConfigFormFields(node.fieldsPermission)
cloneDeep(node.fieldsPermission) || getDefaultFieldsPermission(formFields?.value)
} }
defineExpose({ open, setCurrentNode }) // defineExpose({ openDrawer, showCopyTaskNodeConfig }) //
const changeCandidateStrategy = () => {
configForm.value.candidateParamArray = []
}
// TODO UserTaskNodeConfig ??
const getShowText = (): string => {
let showText = ''
//
if (configForm.value.candidateStrategy === CandidateStrategy.USER) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
userOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.nickname)
}
})
showText = `指定成员:${candidateNames.join(',')}`
}
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.ROLE) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
roleOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定角色:${candidateNames.join(',')}`
}
}
//
if (
configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER ||
configForm.value.candidateStrategy === CandidateStrategy.DEPT_LEADER
) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
deptOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
if (currentNode.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) {
showText = `部门成员:${candidateNames.join(',')}`
} else {
showText = `部门的负责人:${candidateNames.join(',')}`
}
}
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.POST) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
postOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定岗位: ${candidateNames.join(',')}`
}
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.USER_GROUP) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
userGroupOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定用户组: ${candidateNames.join(',')}`
}
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.EXPRESSION) {
if (configForm.value.candidateParamArray?.length > 0) {
showText = `流程表达式:${configForm.value.candidateParamArray[0]}`
}
}
return showText
}
//
const showInput = ref(false)
const clickIcon = () => {
showInput.value = true
}
//
const blurEvent = () => {
showInput.value = false
configForm.value.name =
configForm.value.name || (NODE_DEFAULT_NAME.get(NodeType.COPY_TASK_NODE) as string)
}
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -15,14 +15,12 @@
class="config-editable-input" class="config-editable-input"
@blur="blurEvent()" @blur="blurEvent()"
v-mountedFocus v-mountedFocus
v-model="configForm.name" v-model="nodeName"
:placeholder="configForm.name" :placeholder="nodeName"
/> />
<div v-else class="node-name" <div v-else class="node-name">
>{{ configForm.name }} {{ nodeName }} <Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" />
<Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" </div>
/></div>
<div class="divide-line"></div> <div class="divide-line"></div>
</div> </div>
</template> </template>
@ -280,7 +278,7 @@
</el-form> </el-form>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="操作按钮设置" name="buttons" v-if="formType === 10"> <el-tab-pane label="操作按钮设置" name="buttons">
<div class="button-setting-pane"> <div class="button-setting-pane">
<div class="button-setting-desc">操作按钮</div> <div class="button-setting-desc">操作按钮</div>
<div class="button-setting-title"> <div class="button-setting-title">
@ -288,11 +286,7 @@
<div class="pl-4 button-title-label">显示名称</div> <div class="pl-4 button-title-label">显示名称</div>
<div class="button-title-label">启用</div> <div class="button-title-label">启用</div>
</div> </div>
<div <div class="button-setting-item" v-for="(item, index) in buttonsSetting" :key="index">
class="button-setting-item"
v-for="(item, index) in configForm.buttonsSetting"
:key="index"
>
<div class="button-setting-item-label"> {{ OPERATION_BUTTON_NAME.get(item.id) }} </div> <div class="button-setting-item-label"> {{ OPERATION_BUTTON_NAME.get(item.id) }} </div>
<div class="button-setting-item-label"> <div class="button-setting-item-label">
<input <input
@ -327,7 +321,7 @@
</div> </div>
<div <div
class="field-setting-item" class="field-setting-item"
v-for="(item, index) in configForm.fieldsPermission" v-for="(item, index) in fieldsPermissionConfig"
:key="index" :key="index"
> >
<div class="field-setting-item-label"> {{ item.title }} </div> <div class="field-setting-item-label"> {{ item.title }} </div>
@ -368,19 +362,22 @@ import {
TIMEOUT_HANDLER_ACTION_TYPES, TIMEOUT_HANDLER_ACTION_TYPES,
TIME_UNIT_TYPES, TIME_UNIT_TYPES,
REJECT_HANDLER_TYPES, REJECT_HANDLER_TYPES,
NODE_DEFAULT_NAME,
DEFAULT_BUTTON_SETTING, DEFAULT_BUTTON_SETTING,
OPERATION_BUTTON_NAME OPERATION_BUTTON_NAME,
ButtonSetting
} from '../consts' } from '../consts'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { getDefaultFieldsPermission } from '../utils' import {
useWatchNode,
useNodeName,
useFormFieldsPermission,
useNodeForm,
UserTaskFormType,
useDrawer
} from '../node'
import { defaultProps } from '@/utils/tree' import { defaultProps } from '@/utils/tree'
import * as RoleApi from '@/api/system/role'
import * as DeptApi from '@/api/system/dept'
import * as PostApi from '@/api/system/post'
import * as UserApi from '@/api/system/user'
import * as UserGroupApi from '@/api/bpm/userGroup'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { convertTimeUnit } from '../utils'
defineOptions({ defineOptions({
name: 'UserTaskNodeConfig' name: 'UserTaskNodeConfig'
}) })
@ -393,44 +390,22 @@ const props = defineProps({
const emits = defineEmits<{ const emits = defineEmits<{
'find:returnTaskNodes': [nodeList: SimpleFlowNode[]] 'find:returnTaskNodes': [nodeList: SimpleFlowNode[]]
}>() }>()
//
const currentNode = useWatchNode(props)
//
const { settingVisible, closeDrawer, openDrawer } = useDrawer()
//
const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.USER_TASK_NODE)
// Tab
const activeTabName = ref('user')
//
const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission()
//
const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } =
useButtonsSetting()
const currentNode = ref<SimpleFlowNode>(props.flowNode) //
//
watch(
() => props.flowNode,
(newValue) => {
currentNode.value = newValue
}
)
const notAllowedMultiApprovers = ref(false)
const settingVisible = ref(false)
const roleOptions = inject<Ref<RoleApi.RoleVO[]>>('roleList') //
const postOptions = inject<Ref<PostApi.PostVO[]>>('postList') //
const userOptions = inject<Ref<UserApi.UserVO[]>>('userList') //
const deptOptions = inject<Ref<DeptApi.DeptVO[]>>('deptList') //
const userGroupOptions = inject<Ref<UserGroupApi.UserGroupVO[]>>('userGroupList') //
const deptTreeOptions = inject('deptTree') //
const formType = inject('formType') //
const formFields = inject<Ref<string[]>>('formFields')
const returnTaskList = ref<SimpleFlowNode[]>([])
const formRef = ref() // Ref const formRef = ref() // Ref
const activeTabName = ref('user') // Tab
const configForm = ref<any>({
name: NODE_DEFAULT_NAME.get(NodeType.USER_TASK_NODE),
candidateParamArray: [],
candidateStrategy: CandidateStrategy.USER,
approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE,
approveRatio: 100,
rejectHandlerType: RejectHandlerType.FINISH_PROCESS,
returnNodeId: '',
timeoutHandlerEnable: false,
timeoutHandlerAction: 1,
timeDuration: 6, // 6
maxRemindCount: 1, // 1
fieldsPermission: [],
buttonsSetting: []
})
// //
const formRules = reactive({ const formRules = reactive({
candidateStrategy: [{ required: true, message: '审批人设置不能为空', trigger: 'change' }], candidateStrategy: [{ required: true, message: '审批人设置不能为空', trigger: 'change' }],
@ -443,10 +418,66 @@ const formRules = reactive({
timeDuration: [{ required: true, message: '超时时间不能为空', trigger: 'blur' }], timeDuration: [{ required: true, message: '超时时间不能为空', trigger: 'blur' }],
maxRemindCount: [{ required: true, message: '提醒次数不能为空', trigger: 'blur' }] maxRemindCount: [{ required: true, message: '提醒次数不能为空', trigger: 'blur' }]
}) })
//
const closeDrawer = () => { const {
settingVisible.value = false configForm: tempConfigForm,
roleOptions,
postOptions,
userOptions,
userGroupOptions,
deptTreeOptions,
getShowText
} = useNodeForm(NodeType.USER_TASK_NODE)
const configForm = tempConfigForm as Ref<UserTaskFormType>
//
const notAllowedMultiApprovers = ref(false)
//
const changeCandidateStrategy = () => {
configForm.value.candidateParamArray = []
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE
if (
configForm.value.candidateStrategy === CandidateStrategy.START_USER ||
configForm.value.candidateStrategy === CandidateStrategy.USER
) {
notAllowedMultiApprovers.value = true
} else {
notAllowedMultiApprovers.value = false
}
} }
//
const changedCandidateUsers = () => {
if (
configForm.value.candidateParamArray?.length <= 1 &&
configForm.value.candidateStrategy === CandidateStrategy.USER
) {
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE
configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS
notAllowedMultiApprovers.value = true
} else {
notAllowedMultiApprovers.value = false
}
}
//
const approveMethodChanged = () => {
configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS
if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
configForm.value.approveRatio = 100
}
formRef.value.clearValidate('approveRatio')
}
// 退
const returnTaskList = ref<SimpleFlowNode[]>([])
//
const {
timeoutHandlerChange,
cTimeoutAction,
timeoutActionChanged,
timeUnit,
timeUnitChange,
isoTimeDuration,
cTimeoutMaxRemindCount
} = useTimeoutHandler()
// //
const saveConfig = async () => { const saveConfig = async () => {
activeTabName.value = 'user' activeTabName.value = 'user'
@ -455,7 +486,7 @@ const saveConfig = async () => {
if (!valid) return false if (!valid) return false
const showText = getShowText() const showText = getShowText()
if (!showText) return false if (!showText) return false
currentNode.value.name = configForm.value.name currentNode.value.name = nodeName.value!
currentNode.value.candidateStrategy = configForm.value.candidateStrategy currentNode.value.candidateStrategy = configForm.value.candidateStrategy
currentNode.value.candidateParam = configForm.value.candidateParamArray?.join(',') currentNode.value.candidateParam = configForm.value.candidateParamArray?.join(',')
// //
@ -465,121 +496,31 @@ const saveConfig = async () => {
} }
// //
currentNode.value.rejectHandler = { currentNode.value.rejectHandler = {
type: configForm.value.rejectHandlerType, type: configForm.value.rejectHandlerType!,
returnNodeId: configForm.value.returnNodeId returnNodeId: configForm.value.returnNodeId
} }
// //
currentNode.value.timeoutHandler = { currentNode.value.timeoutHandler = {
enable: configForm.value.timeoutHandlerEnable, enable: configForm.value.timeoutHandlerEnable!,
action: cTimeoutAction.value, action: cTimeoutAction.value,
timeDuration: isoTimeDuration.value, timeDuration: isoTimeDuration.value,
maxRemindCount: cTimeoutMaxRemindCount.value maxRemindCount: cTimeoutMaxRemindCount.value
} }
// //
currentNode.value.fieldsPermission = configForm.value.fieldsPermission currentNode.value.fieldsPermission = fieldsPermissionConfig.value
// //
currentNode.value.buttonsSetting = configForm.value.buttonsSetting currentNode.value.buttonsSetting = buttonsSetting.value
currentNode.value.showText = getShowText() currentNode.value.showText = showText
settingVisible.value = false settingVisible.value = false
return true return true
} }
const getShowText = (): string => {
let showText = ''
//
if (configForm.value.candidateStrategy === CandidateStrategy.USER) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
userOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.nickname)
}
})
showText = `指定成员:${candidateNames.join(',')}`
}
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.ROLE) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
roleOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定角色:${candidateNames.join(',')}`
}
}
//
if (
configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER ||
configForm.value.candidateStrategy === CandidateStrategy.DEPT_LEADER
) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
deptOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) {
showText = `部门成员:${candidateNames.join(',')}`
} else {
showText = `部门的负责人:${candidateNames.join(',')}`
}
}
}
// //
if (configForm.value.candidateStrategy === CandidateStrategy.POST) { const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
if (configForm.value.candidateParamArray?.length > 0) { nodeName.value = node.name
const candidateNames: string[] = []
postOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定岗位: ${candidateNames.join(',')}`
}
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.USER_GROUP) {
if (configForm.value.candidateParamArray?.length > 0) {
const candidateNames: string[] = []
userGroupOptions?.value.forEach((item) => {
if (configForm.value.candidateParamArray.includes(item.id)) {
candidateNames.push(item.name)
}
})
showText = `指定用户组: ${candidateNames.join(',')}`
}
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.START_USER_SELECT) {
showText = `发起人自选`
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.START_USER) {
showText = `发起人自己`
}
//
if (configForm.value.candidateStrategy === CandidateStrategy.EXPRESSION) {
if (configForm.value.candidateParamArray?.length > 0) {
showText = `流程表达式:${configForm.value.candidateParamArray[0]}`
}
}
return showText
}
const open = () => {
settingVisible.value = true
}
//
const setCurrentNode = (node: SimpleFlowNode) => {
configForm.value.name = node.name
//1.1 //1.1
configForm.value.candidateStrategy = node.candidateStrategy configForm.value.candidateStrategy = node.candidateStrategy!
const strCandidateParam = node?.candidateParam const strCandidateParam = node?.candidateParam
if (node.candidateStrategy === CandidateStrategy.EXPRESSION) { if (node.candidateStrategy === CandidateStrategy.EXPRESSION) {
configForm.value.candidateParamArray[0] = strCandidateParam configForm.value.candidateParamArray[0] = strCandidateParam
@ -598,18 +539,18 @@ const setCurrentNode = (node: SimpleFlowNode) => {
notAllowedMultiApprovers.value = false notAllowedMultiApprovers.value = false
} }
//1.2 //1.2
configForm.value.approveMethod = node.approveMethod configForm.value.approveMethod = node.approveMethod!
if (node.approveMethod == ApproveMethodType.APPROVE_BY_RATIO) { if (node.approveMethod == ApproveMethodType.APPROVE_BY_RATIO) {
configForm.value.approveRatio = node.approveRatio configForm.value.approveRatio = node.approveRatio!
} }
// 1.3 // 1.3
configForm.value.rejectHandlerType = node.rejectHandler?.type configForm.value.rejectHandlerType = node.rejectHandler!.type
configForm.value.returnNodeId = node.rejectHandler?.returnNodeId configForm.value.returnNodeId = node.rejectHandler?.returnNodeId
const matchNodeList = [] const matchNodeList = []
emits('find:returnTaskNodes', matchNodeList) emits('find:returnTaskNodes', matchNodeList)
returnTaskList.value = matchNodeList returnTaskList.value = matchNodeList
// 1.4 // 1.4
configForm.value.timeoutHandlerEnable = node.timeoutHandler?.enable configForm.value.timeoutHandlerEnable = node.timeoutHandler!.enable
if (node.timeoutHandler?.enable && node.timeoutHandler?.timeDuration) { if (node.timeoutHandler?.enable && node.timeoutHandler?.timeDuration) {
const strTimeDuration = node.timeoutHandler.timeDuration const strTimeDuration = node.timeoutHandler.timeDuration
let parseTime = strTimeDuration.slice(2, strTimeDuration.length - 1) let parseTime = strTimeDuration.slice(2, strTimeDuration.length - 1)
@ -620,64 +561,84 @@ const setCurrentNode = (node: SimpleFlowNode) => {
configForm.value.timeoutHandlerAction = node.timeoutHandler?.action configForm.value.timeoutHandlerAction = node.timeoutHandler?.action
configForm.value.maxRemindCount = node.timeoutHandler?.maxRemindCount configForm.value.maxRemindCount = node.timeoutHandler?.maxRemindCount
// 2. // 2.
configForm.value.buttonsSetting = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING buttonsSetting.value = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING
// 3. // 3.
configForm.value.fieldsPermission = getNodeConfigFormFields(node.fieldsPermission)
cloneDeep(node.fieldsPermission) || getDefaultFieldsPermission(formFields?.value)
} }
defineExpose({ open, setCurrentNode }) // defineExpose({ openDrawer, showUserTaskNodeConfig }) //
const changeCandidateStrategy = () => { /**
configForm.value.candidateParamArray = [] * @description 操作按钮设置
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE */
if ( function useButtonsSetting() {
configForm.value.candidateStrategy === CandidateStrategy.START_USER || const buttonsSetting = ref<ButtonSetting[]>()
configForm.value.candidateStrategy === CandidateStrategy.USER //
) { const btnDisplayNameEdit = ref<boolean[]>([])
notAllowedMultiApprovers.value = true const changeBtnDisplayName = (index: number) => {
} else { btnDisplayNameEdit.value[index] = true
notAllowedMultiApprovers.value = false }
const btnDisplayNameBlurEvent = (index: number) => {
btnDisplayNameEdit.value[index] = false
const buttonItem = buttonsSetting.value![index]
buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id)!
}
return {
buttonsSetting,
btnDisplayNameEdit,
changeBtnDisplayName,
btnDisplayNameBlurEvent
} }
} }
const changedCandidateUsers = () => { /**
if ( * @description 审批人超时未处理配置
configForm.value.candidateParamArray?.length <= 1 && */
configForm.value.candidateStrategy === CandidateStrategy.USER function useTimeoutHandler() {
) { //
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE const timeUnit = ref(TimeUnitType.HOUR)
configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS
notAllowedMultiApprovers.value = true //
} else { const timeoutHandlerChange = () => {
notAllowedMultiApprovers.value = false if (configForm.value.timeoutHandlerEnable) {
timeUnit.value = 2
configForm.value.timeDuration = 6
configForm.value.timeoutHandlerAction = 1
configForm.value.maxRemindCount = 1
} }
}
//
const showInput = ref(false)
const clickIcon = () => {
showInput.value = true
}
//
const blurEvent = () => {
showInput.value = false
configForm.value.name =
configForm.value.name || (NODE_DEFAULT_NAME.get(NodeType.USER_TASK_NODE) as string)
}
const approveMethodChanged = () => {
configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS
if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
configForm.value.approveRatio = 100
} }
formRef.value.clearValidate('approveRatio') //
} const cTimeoutAction = computed(() => {
if (!configForm.value.timeoutHandlerEnable) {
return undefined
}
return configForm.value.timeoutHandlerAction
})
const timeUnit = ref(TimeUnitType.HOUR) //
const timeoutActionChanged = () => {
if (configForm.value.timeoutHandlerAction === 1) {
configForm.value.maxRemindCount = 1 // 1
}
}
// ISO //
const isoTimeDuration = computed(() => { const timeUnitChange = () => {
// 60
if (timeUnit.value === TimeUnitType.MINUTE) {
configForm.value.timeDuration = 60
}
// 6
if (timeUnit.value === TimeUnitType.HOUR) {
configForm.value.timeDuration = 6
}
// 1
if (timeUnit.value === TimeUnitType.DAY) {
configForm.value.timeDuration = 1
}
}
// ISO
const isoTimeDuration = computed(() => {
if (!configForm.value.timeoutHandlerEnable) { if (!configForm.value.timeoutHandlerEnable) {
return undefined return undefined
} }
@ -692,16 +653,10 @@ const isoTimeDuration = computed(() => {
strTimeDuration += configForm.value.timeDuration + 'D' strTimeDuration += configForm.value.timeDuration + 'D'
} }
return strTimeDuration return strTimeDuration
}) })
//
const cTimeoutAction = computed(() => { //
if (!configForm.value.timeoutHandlerEnable) { const cTimeoutMaxRemindCount = computed(() => {
return undefined
}
return configForm.value.timeoutHandlerAction
})
//
const cTimeoutMaxRemindCount = computed(() => {
if (!configForm.value.timeoutHandlerEnable) { if (!configForm.value.timeoutHandlerEnable) {
return undefined return undefined
} }
@ -709,63 +664,18 @@ const cTimeoutMaxRemindCount = computed(() => {
return undefined return undefined
} }
return configForm.value.maxRemindCount return configForm.value.maxRemindCount
}) })
// return {
const timeoutHandlerChange = () => { timeoutHandlerChange,
if (configForm.value.timeoutHandlerEnable) { cTimeoutAction,
timeUnit.value = 2 timeoutActionChanged,
configForm.value.timeDuration = 6 timeUnit,
configForm.value.timeoutHandlerAction = 1 timeUnitChange,
configForm.value.maxRemindCount = 1 isoTimeDuration,
cTimeoutMaxRemindCount
} }
} }
//
const timeoutActionChanged = () => {
if (configForm.value.timeoutHandlerAction === 1) {
configForm.value.maxRemindCount = 1 // 1
}
}
//
const timeUnitChange = () => {
// 60
if (timeUnit.value === TimeUnitType.MINUTE) {
configForm.value.timeDuration = 60
}
// 6
if (timeUnit.value === TimeUnitType.HOUR) {
configForm.value.timeDuration = 6
}
// 1
if (timeUnit.value === TimeUnitType.DAY) {
configForm.value.timeDuration = 1
}
}
const convertTimeUnit = (strTimeUnit: string) => {
if (strTimeUnit === 'M') {
return TimeUnitType.MINUTE
}
if (strTimeUnit === 'H') {
return TimeUnitType.HOUR
}
if (strTimeUnit === 'D') {
return TimeUnitType.DAY
}
return TimeUnitType.HOUR
}
//
const btnDisplayNameEdit = ref<boolean[]>([])
const changeBtnDisplayName = (index: number) => {
btnDisplayNameEdit.value[index] = true
}
const btnDisplayNameBlurEvent = (index: number) => {
btnDisplayNameEdit.value[index] = false
const buttonItem = configForm.value.buttonPermission[index]
buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id)
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -43,7 +43,6 @@
import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT, NODE_DEFAULT_NAME } from '../consts' import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT, NODE_DEFAULT_NAME } from '../consts'
import NodeHandler from '../NodeHandler.vue' import NodeHandler from '../NodeHandler.vue'
import CopyTaskNodeConfig from '../nodes-config/CopyTaskNodeConfig.vue' import CopyTaskNodeConfig from '../nodes-config/CopyTaskNodeConfig.vue'
import { generateUUID } from '@/utils'
defineOptions({ defineOptions({
name: 'CopyTaskNode' name: 'CopyTaskNode'
}) })
@ -81,8 +80,8 @@ const clickEvent = () => {
const nodeSetting = ref() const nodeSetting = ref()
// //
const openNodeConfig = () => { const openNodeConfig = () => {
nodeSetting.value.setCurrentNode(currentNode.value) nodeSetting.value.showCopyTaskNodeConfig(currentNode.value)
nodeSetting.value.open() nodeSetting.value.openDrawer()
} }
// //

View File

@ -45,6 +45,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT, NODE_DEFAULT_NAME } from '../consts' import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT, NODE_DEFAULT_NAME } from '../consts'
import { useWatchNode } from '../node'
import NodeHandler from '../NodeHandler.vue' import NodeHandler from '../NodeHandler.vue'
import UserTaskNodeConfig from '../nodes-config/UserTaskNodeConfig.vue' import UserTaskNodeConfig from '../nodes-config/UserTaskNodeConfig.vue'
defineOptions({ defineOptions({
@ -61,21 +62,16 @@ const emits = defineEmits<{
'find:parentNode': [nodeList: SimpleFlowNode[], nodeType: NodeType] 'find:parentNode': [nodeList: SimpleFlowNode[], nodeType: NodeType]
}>() }>()
const currentNode = ref<SimpleFlowNode>(props.flowNode) const currentNode = useWatchNode(props)
const nodeSetting = ref() const nodeSetting = ref()
// //
const openNodeConfig = () => { const openNodeConfig = () => {
// //
nodeSetting.value.setCurrentNode(currentNode.value) nodeSetting.value.showUserTaskNodeConfig(currentNode.value)
nodeSetting.value.open() nodeSetting.value.openDrawer()
} }
//
watch(
() => props.flowNode,
(newValue) => {
currentNode.value = newValue
}
)
// //
const showInput = ref(false) const showInput = ref(false)
// //

View File

@ -1,3 +1,5 @@
import { TimeUnitType } from './consts'
// 获取条件节点默认的名称 // 获取条件节点默认的名称
export const getDefaultConditionNodeName = (index: number, defaultFlow: boolean): string => { export const getDefaultConditionNodeName = (index: number, defaultFlow: boolean): string => {
if (defaultFlow) { if (defaultFlow) {
@ -6,18 +8,15 @@ export const getDefaultConditionNodeName = (index: number, defaultFlow: boolean)
return '条件' + (index + 1) return '条件' + (index + 1)
} }
// 获得默认的表单字段权限. export const convertTimeUnit = (strTimeUnit: string) => {
export const getDefaultFieldsPermission = (formFields: string[] | undefined) => { if (strTimeUnit === 'M') {
const defaultFieldsPermission: any[] = [] return TimeUnitType.MINUTE
if (formFields) {
formFields.forEach((fieldStr: string) => {
const { field, title } = JSON.parse(fieldStr)
defaultFieldsPermission.push({
field,
title,
permission: '1' // 只读
})
})
} }
return defaultFieldsPermission if (strTimeUnit === 'H') {
return TimeUnitType.HOUR
}
if (strTimeUnit === 'D') {
return TimeUnitType.DAY
}
return TimeUnitType.HOUR
} }