Commit 3a5c93fa by jason

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

parent 2c11228f
...@@ -50,6 +50,7 @@ import CopyTaskNode from './nodes/CopyTaskNode.vue' ...@@ -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<{ ...@@ -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)
......
...@@ -138,6 +138,7 @@ const zoomIn = () => { ...@@ -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 {
......
// @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 { ...@@ -46,68 +48,37 @@ export enum NodeType {
*/ */
INCLUSIVE_NODE_JOIN = 8 INCLUSIVE_NODE_JOIN = 8
} }
// 时间单位枚举 /**
export enum TimeUnitType { * 节点结构定义
/** */
* 分钟 export interface SimpleFlowNode {
*/ id: string
MINUTE = 1, type: NodeType
/** name: string
* 小时 showText?: string
*/ attributes?: any
HOUR = 2, // 孩子节点
/** childNode?: SimpleFlowNode
* 天 // 条件节点
*/ conditionNodes?: SimpleFlowNode[]
DAY = 3 // 候选人策略
} candidateStrategy?: number
// 候选人参数
export enum RejectHandlerType { candidateParam?: string
/** // 多人审批方式
* 结束流程 approveMethod?: ApproveMethodType
*/ //通过比例
FINISH_PROCESS = 1, approveRatio?: number
/** // 审批按钮设置
* 驳回到指定节点 buttonsSetting?: any[]
*/ // 表单权限
RETURN_USER_TASK = 2 fieldsPermission?: Array<Record<string, string>>
} // 审批任务超时处理
timeoutHandler?: TimeoutHandler
// 条件配置类型 ( 用于条件节点配置 ) // 审批任务拒绝处理
export enum ConditionConfigType { rejectHandler?: RejectHandler
/**
* 条件表达式
*/
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 { ...@@ -147,12 +118,41 @@ export enum CandidateStrategy {
EXPRESSION = 60 EXPRESSION = 60
} }
// 多人审批方式类型枚举 ( 用于审批节点 )
export enum ApproveMethodType {
/**
* 随机挑选一人审批
*/
RRANDOM_SELECT_ONE_APPROVE = 1,
/**
* 多人会签(按通过比例)
*/
APPROVE_BY_RATIO = 2,
/**
* 多人或签(通过只需一人,拒绝只需一人)
*/
ANY_APPROVE = 3,
/**
* 多人依次审批
*/
SEQUENTIAL_APPROVE = 4
}
/**
* 审批拒绝结构定义
*/
export type RejectHandler = { export type RejectHandler = {
// 审批拒绝类型
type: RejectHandlerType type: RejectHandlerType
// 回退节点 Id
returnNodeId?: string returnNodeId?: string
} }
/**
* 审批超时结构定义
*/
export type TimeoutHandler = { export type TimeoutHandler = {
//是否开启超时处理 //是否开启超时处理
enable: boolean enable: boolean
...@@ -163,60 +163,57 @@ export type TimeoutHandler = { ...@@ -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 { ...@@ -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>()
......
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
}
}
...@@ -14,14 +14,12 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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,53 +220,45 @@ const props = defineProps({ ...@@ -221,53 +220,45 @@ 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,
(newValue) => {
currentNode.value = newValue
}
)
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 copyUserStrategies = computed(() => {
return getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY).filter(
(item) =>
item.value !== CandidateStrategy.START_USER_SELECT &&
item.value !== CandidateStrategy.START_USER
)
})
// 激活的 Tab 标签页 // 激活的 Tab 标签页
const activeTabName = ref('user') const activeTabName = ref('user')
// 表单字段权限配置
const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission()
// 抄送人表单配置
const formRef = ref() // 表单 Ref const formRef = ref() // 表单 Ref
const configForm = ref<any>({
name: NODE_DEFAULT_NAME.get(NodeType.COPY_TASK_NODE),
candidateParamArray: [],
candidateStrategy: CandidateStrategy.USER,
fieldsPermission: []
})
// 表单校验规则 // 表单校验规则
const formRules = reactive({ const formRules = reactive({
candidateStrategy: [{ required: true, message: '抄送人设置不能为空', trigger: 'change' }], candidateStrategy: [{ required: true, message: '抄送人设置不能为空', trigger: 'change' }],
candidateParamArray: [{ required: true, message: '选项不能为空', trigger: 'blur' }] candidateParamArray: [{ required: true, message: '选项不能为空', trigger: 'blur' }]
}) })
// 关闭 const {
const closeDrawer = () => { configForm: tempConfigForm,
settingVisible.value = false roleOptions,
postOptions,
userOptions,
userGroupOptions,
deptTreeOptions,
getShowText
} = useNodeForm(NodeType.COPY_TASK_NODE)
const configForm = tempConfigForm as Ref<CopyTaskFormType>
// 抄送人策略, 去掉发起人自选 和 发起人自己
const copyUserStrategies = computed(() => {
return getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY).filter(
(item) =>
item.value !== CandidateStrategy.START_USER_SELECT &&
item.value !== CandidateStrategy.START_USER
)
})
// 改变抄送人设置策略
const changeCandidateStrategy = () => {
configForm.value.candidateParamArray = []
} }
// 保存配置 // 保存配置
const saveConfig = async () => { const saveConfig = async () => {
...@@ -277,23 +268,19 @@ 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) => { ...@@ -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>
...@@ -43,7 +43,6 @@ ...@@ -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 = () => { ...@@ -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()
} }
// 删除节点。更新当前节点为孩子节点 // 删除节点。更新当前节点为孩子节点
......
...@@ -45,6 +45,7 @@ ...@@ -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<{ ...@@ -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)
// 节点名称输入框失去焦点 // 节点名称输入框失去焦点
......
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) ...@@ -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) => { if (strTimeUnit === 'H') {
const { field, title } = JSON.parse(fieldStr) return TimeUnitType.HOUR
defaultFieldsPermission.push({ }
field, if (strTimeUnit === 'D') {
title, return TimeUnitType.DAY
permission: '1' // 只读
})
})
} }
return defaultFieldsPermission return TimeUnitType.HOUR
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment