feat: [bpm] 退回任务
This commit is contained in:
@@ -71,3 +71,13 @@ export function delegateTask(data: { id: string, delegateUserId: string, reason:
|
||||
export function transferTask(data: { id: string, assigneeUserId: string, reason: string }) {
|
||||
return http.put<boolean>('/bpm/task/transfer', data)
|
||||
}
|
||||
|
||||
/** 退回任务 */
|
||||
export function returnTask(data: { id: string, targetTaskDefinitionKey: string, reason: string }) {
|
||||
return http.put<boolean>('/bpm/task/return', data)
|
||||
}
|
||||
|
||||
/** 获取可退回的节点列表 */
|
||||
export function getTaskListByReturn(taskId: string) {
|
||||
return http.get<any[]>(`/bpm/task/list-by-return?id=${taskId}`)
|
||||
}
|
||||
|
||||
@@ -1,40 +1,39 @@
|
||||
<!-- 操作按钮 -->
|
||||
<template>
|
||||
<view class="yd-detail-footer">
|
||||
<!-- 有待审批的任务 -->
|
||||
<view v-if="runningTask">
|
||||
<view v-if="leftOperations.length > 0" class="w-full flex items-center">
|
||||
<!-- 左侧操作按钮 -->
|
||||
<view v-for="(action, idx) in leftOperations" :key="idx" class="mr-32rpx w-60rpx flex flex-col items-center" @click="handleOperation(action.operationType)">
|
||||
<wd-icon :name="action.iconName" size="40rpx" color="#1890ff" />
|
||||
<text class="mt-4rpx text-22rpx text-[#333]">{{ action.displayName }}</text>
|
||||
</view>
|
||||
<!-- 更多操作按钮 -->
|
||||
<view v-if="moreOperations.length > 0" class="mr-32rpx w-60rpx flex flex-col items-center" @click="handleShowMore">
|
||||
<wd-icon name="ellipsis" size="40rpx" color="#1890ff" />
|
||||
<text class="mt-4rpx text-22rpx text-[#333]">更多</text>
|
||||
</view>
|
||||
<!-- 右侧按钮,TODO 是否一定要保留两个按钮 -->
|
||||
<view class="flex flex-1 gap-16rpx">
|
||||
<wd-button
|
||||
v-for="(action, idx) in rightOperations"
|
||||
:key="idx"
|
||||
:plain="action.plain"
|
||||
:type="action.btnType"
|
||||
:round="false"
|
||||
class="flex-1"
|
||||
custom-style="min-width: 200rpx; width: 200rpx;"
|
||||
@click="handleOperation(action.operationType)"
|
||||
>
|
||||
{{ action.displayName }}
|
||||
</wd-button>
|
||||
</view>
|
||||
<!-- 有待审批的任务 -->
|
||||
<view v-if="runningTask" class="yd-detail-footer">
|
||||
<view class="w-full flex items-center">
|
||||
<!-- 左侧操作按钮 -->
|
||||
<view v-for="(action, idx) in leftOperations" :key="idx" class="mr-32rpx w-60rpx flex flex-col items-center" @click="handleOperation(action.operationType)">
|
||||
<wd-icon :name="action.iconName" size="40rpx" color="#1890ff" />
|
||||
<text class="mt-4rpx text-22rpx text-[#333]">{{ action.displayName }}</text>
|
||||
</view>
|
||||
<!-- 更多操作按钮 -->
|
||||
<view v-if="moreOperations.length > 0" class="mr-32rpx w-60rpx flex flex-col items-center" @click="handleShowMore">
|
||||
<wd-icon name="ellipsis" size="40rpx" color="#1890ff" />
|
||||
<text class="mt-4rpx text-22rpx text-[#333]">更多</text>
|
||||
</view>
|
||||
<!-- 更多操作 ActionSheet -->
|
||||
<wd-action-sheet v-if="moreOperations.length > 0" v-model="showMoreActions" :actions="moreOperations" title="请选择操作" @select="handleMoreAction" />
|
||||
|
||||
<!-- 右侧按钮,TODO 是否一定要保留两个按钮 -->
|
||||
<view class="flex flex-1 gap-16rpx">
|
||||
<wd-button
|
||||
v-for="(action, idx) in rightOperations"
|
||||
:key="idx"
|
||||
:plain="action.plain"
|
||||
:type="action.btnType"
|
||||
:round="false"
|
||||
class="flex-1"
|
||||
custom-style="min-width: 200rpx; width: 200rpx;"
|
||||
@click="handleOperation(action.operationType)"
|
||||
>
|
||||
{{ action.displayName }}
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- TODO 无待审批的任务 需要显示什么 -->
|
||||
</view>
|
||||
<!-- TODO 无待审批的任务 需要显示什么 -->
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -91,7 +90,7 @@ function loadTodoTask(task: Task) {
|
||||
if (task) {
|
||||
reasonRequire.value = task.reasonRequire ?? false
|
||||
// 右侧按钮
|
||||
if (isHandleTaskStatus() && task.buttonsSetting[BpmTaskOperationButtonTypeEnum.REJECT]?.enable) {
|
||||
if (isHandleTaskStatus() && task.buttonsSetting && task.buttonsSetting[BpmTaskOperationButtonTypeEnum.REJECT]?.enable) {
|
||||
rightOperationTypes.push(BpmTaskOperationButtonTypeEnum.REJECT)
|
||||
rightOperations.value.push({
|
||||
operationType: BpmTaskOperationButtonTypeEnum.REJECT,
|
||||
@@ -100,7 +99,7 @@ function loadTodoTask(task: Task) {
|
||||
plain: true,
|
||||
})
|
||||
}
|
||||
if (isHandleTaskStatus() && task.buttonsSetting[BpmTaskOperationButtonTypeEnum.APPROVE]?.enable) {
|
||||
if (isHandleTaskStatus() && task.buttonsSetting && task.buttonsSetting[BpmTaskOperationButtonTypeEnum.APPROVE]?.enable) {
|
||||
rightOperationTypes.push(BpmTaskOperationButtonTypeEnum.APPROVE)
|
||||
rightOperations.value.push({
|
||||
operationType: BpmTaskOperationButtonTypeEnum.APPROVE,
|
||||
@@ -109,6 +108,7 @@ function loadTodoTask(task: Task) {
|
||||
plain: false,
|
||||
})
|
||||
}
|
||||
console.log('rightOperationTypes====>', rightOperationTypes)
|
||||
// TODO 减签
|
||||
// 左侧操作,和更多操作
|
||||
Object.keys(task.buttonsSetting || {}).forEach((key) => {
|
||||
@@ -157,7 +157,9 @@ function handleOperation(operationType: number) {
|
||||
toast.show('加签功能待实现')
|
||||
break
|
||||
case BpmTaskOperationButtonTypeEnum.RETURN:
|
||||
toast.show('退回功能待实现')
|
||||
uni.navigateTo({
|
||||
url: `/pages-bpm/processInstance/detail/return/index?processInstanceId=${runningTask.value.processInstanceId}&taskId=${runningTask.value.id}`,
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
157
src/pages-bpm/processInstance/detail/return/index.vue
Normal file
157
src/pages-bpm/processInstance/detail/return/index.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<view class="yd-page-container">
|
||||
<!-- 顶部导航栏 -->
|
||||
<wd-navbar
|
||||
title="退回任务"
|
||||
left-arrow placeholder safe-area-inset-top fixed
|
||||
@click-left="handleBack"
|
||||
/>
|
||||
|
||||
<!-- 操作表单 -->
|
||||
<view class="p-24rpx">
|
||||
<wd-form ref="formRef" :model="formData" :rules="formRules">
|
||||
<wd-cell-group border>
|
||||
<!-- 退回节点选择 -->
|
||||
<wd-picker
|
||||
v-model="formData.targetActivityId"
|
||||
label="退回节点:"
|
||||
prop="targetActivityId"
|
||||
:columns="activityOptions"
|
||||
value-key="taskDefinitionKey"
|
||||
label-key="name"
|
||||
placeholder="请选择退回节点"
|
||||
/>
|
||||
|
||||
<!-- 退回原因 -->
|
||||
<wd-textarea
|
||||
v-model="formData.reason"
|
||||
prop="reason"
|
||||
label="退回原因:"
|
||||
label-width="180rpx"
|
||||
placeholder="请输入退回原因"
|
||||
:maxlength="500"
|
||||
show-word-limit
|
||||
clearable
|
||||
/>
|
||||
</wd-cell-group>
|
||||
<!-- 提交按钮 -->
|
||||
<view class="mt-48rpx">
|
||||
<wd-button
|
||||
type="primary"
|
||||
block
|
||||
:loading="submitting"
|
||||
:disabled="submitting"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
退回
|
||||
</wd-button>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'wot-design-uni/components/wd-form/types'
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { getTaskListByReturn, returnTask } from '@/api/bpm/task'
|
||||
import { navigateBackPlus } from '@/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
processInstanceId: string
|
||||
taskId: string
|
||||
}>()
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '',
|
||||
navigationStyle: 'custom',
|
||||
},
|
||||
})
|
||||
|
||||
const taskId = computed(() => props.taskId)
|
||||
const processInstanceId = computed(() => props.processInstanceId)
|
||||
const toast = useToast()
|
||||
const submitting = ref(false)
|
||||
const formRef = ref<FormInstance>()
|
||||
const activityOptions = ref<any[]>([])
|
||||
|
||||
const formData = reactive({
|
||||
targetActivityId: '',
|
||||
reason: '',
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
targetActivityId: [
|
||||
{ required: true, message: '退回节点不能为空' },
|
||||
],
|
||||
reason: [
|
||||
{ required: true, message: '退回原因不能为空' },
|
||||
],
|
||||
}
|
||||
|
||||
/** 返回上一页 */
|
||||
function handleBack() {
|
||||
navigateBackPlus(`/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}&taskId=${taskId.value}`)
|
||||
}
|
||||
|
||||
/** 初始化校验 */
|
||||
if (!props.taskId || !props.processInstanceId) {
|
||||
toast.show('参数错误')
|
||||
}
|
||||
|
||||
/** 获取可退回的节点列表 */
|
||||
async function loadReturnTaskList() {
|
||||
try {
|
||||
const result = await getTaskListByReturn(taskId.value)
|
||||
console.log('[return] 获取可退回节点:', result)
|
||||
if (result && Array.isArray(result)) {
|
||||
activityOptions.value = result
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[return] 获取可退回节点失败:', error)
|
||||
toast.error('获取可退回节点失败')
|
||||
}
|
||||
}
|
||||
|
||||
/** 提交操作 */
|
||||
async function handleSubmit() {
|
||||
if (submitting.value)
|
||||
return
|
||||
|
||||
// 使用 wd-form 的校验方法
|
||||
const { valid } = await formRef.value!.validate()
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
|
||||
submitting.value = true
|
||||
try {
|
||||
const result = await returnTask({
|
||||
id: taskId.value as string,
|
||||
targetTaskDefinitionKey: formData.targetActivityId,
|
||||
reason: formData.reason,
|
||||
})
|
||||
|
||||
if (result) {
|
||||
toast.success('退回成功')
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: `/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}&taskId=${taskId.value}`,
|
||||
})
|
||||
}, 1500)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[return] 退回失败:', error)
|
||||
toast.error('退回失败')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 页面加载时获取可退回节点列表 */
|
||||
onMounted(() => {
|
||||
loadReturnTaskList()
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user