目前场景是,我们的业务需要对接工作流,每个工作流都需要经过如下几步来完成工作流数据的发起,我们几乎所有涉及到的业务都需要进行工作流审批,我们梳理了下工作流的发起模式(如下图所示)都是先选用户再保存数据,然后保存用户,继而根据有无实例id来实现新工作流的发起或驳回后的重新提交操作。
其实上述步骤非常简便,那么有没有一种方法能够简化这些重复性的工作呢?,在Spring中我们有AOP的概念,在前端我们也可以利用这些思想去处理,尽量地将这些抽取成模板,以模板的方式进行调用。
该函数接收两个参数,分别是kind
和type
kind
标识发起工作流属于哪种业务type
标识使用的工作流种类
返回的参数有 allid
,saveUser
,showUserList
allid
用于接收工作流实例的相关参数saveUser
用于保存所选用户showUserList
用户展示用户列表
ts
export default function useBPMFlow(kind = 1, type = BPM_FLOW_TYPE.rcjt) {
const allid = ref({})
return {
allid,
saveUser,
showUserList
}
}
内部逻辑如下
ts
export default function useBPMFlow(kind = 1, type = BPM_FLOW_TYPE.rcjt) {
const allid = ref({})
const nodeId = ref('')
const { proxy } = getCurrentInstance()
function showUserList() {
const { promise, resolve, reject } = withResolvers()
获取用户({ modelKey: type }).then(res => {
const userList = res.result
proxy.$dialog({ // 用户选择弹框
max: true,
content: {
component: SubmitDialog,
props: {
list: userList,
},
handle: true
},
width: '40%',
height: '30%',
ok: args => {
resolve(args)
return true
},
close: () => {
reject()
return true
}
})
})
return promise
}
/** 保存用户 */
function saveUser(val, id) {
const { promise, resolve, reject } = withResolvers()
val.forEach(node => {
if (node.nodeKey === nodeId.value) {
node.chosen = 1
}
})
const pro = bpmmanage_saveUser({ approveUserList: val })
pro.then(re => {
if (re.code === 200) {
val = val
.filter(function (item) {
return item.nodeKey === nodeId.value
})
.map(function (item) {
return item.userId
})
if (判断是否需要发起工作流) {
// 重新提交
const p = agree(JSON.stringify({ userList: val.join() }))
p.then(() => resolve())
p.catch(() => reject())
} else {
// 发起新工作流
const p = startBpm(JSON.stringify({ userList: val.join() }), id)
p.then(() => resolve())
p.catch(() => reject())
}
}
})
pro.catch(() => {
reject()
})
return promise
}
// 启动流程
function startBpm(val, id) {
const { promise, resolve, reject } = withResolvers()
const pro = bpmmanage_startBpm({
kind,
type,
relationId: id,
formData: val
})
pro.then(rrr => {
if (rrr.code === 200) {
resolve()
} else {
reject()
}
})
pro.catch(() => {
reject()
})
return promise
}
function agree(val) {
const { promise, resolve, reject } = withResolvers()
const pro = 重新提交函数(allid)
pro.then(rrr => {
if (rrr.code === 200) {
resolve()
} else {
reject()
}
})
pro.catch(() => {
reject()
})
return promise
}
return {
allid,
saveUser,
showUserList
}
}
该代码使用使用withResolvers将promise回调转化为扁平化padding,并将结果的成功和失败传递给自定义的处理,
业务侧使用
ts
const { allid, showUserList, saveUser } = useBPMFlow(发起的业务类型)
async handleSubmit(){
const userList = await showUserList() // 选择用户
const result = await saveData() // 保存数据
if (result.code === 200) {
const id = result.result.id
await saveUser(userList, id) // 保存选中审批人
goBack() // 跳转到列表页
}
比起那些重复又复杂的回调,使用这种方式可以简化业务侧的开发工作量
(所有代码均已脱敏)