feat: [bpm] 减签任务
This commit is contained in:
@@ -30,6 +30,7 @@ export interface Task {
|
||||
processInstance: ProcessInstance
|
||||
reasonRequire?: boolean // 是否填写审批意见
|
||||
buttonsSetting?: Record<number, OperationButtonSetting> // 按钮设置
|
||||
children?: Task[] // 由加签生成,包含多层子任务
|
||||
}
|
||||
|
||||
/** 查询待办任务分页列表 */
|
||||
@@ -86,3 +87,8 @@ export function getTaskListByReturn(taskId: string) {
|
||||
export function signCreateTask(data: { id: string, type: string, userIds: number[], reason: string }) {
|
||||
return http.put<boolean>('/bpm/task/create-sign', data)
|
||||
}
|
||||
|
||||
/** 减签任务 */
|
||||
export function signDeleteTask(data: { id: string, reason: string }) {
|
||||
return http.delete<boolean>('/bpm/task/delete-sign', data)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,9 @@ import type { Action } from 'wot-design-uni/components/wd-action-sheet/types'
|
||||
import type { ButtonType } from 'wot-design-uni/components/wd-button/types'
|
||||
import type { Task } from '@/api/bpm/task'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { useUserStore } from '@/store'
|
||||
import {
|
||||
BpmProcessInstanceStatus,
|
||||
BpmTaskOperationButtonTypeEnum,
|
||||
BpmTaskStatusEnum,
|
||||
OPERATION_BUTTON_NAME,
|
||||
@@ -71,7 +73,10 @@ const operationIconsMap: Record<number, string> = {
|
||||
[BpmTaskOperationButtonTypeEnum.DELEGATE]: 'share',
|
||||
[BpmTaskOperationButtonTypeEnum.RETURN]: 'arrow-left',
|
||||
[BpmTaskOperationButtonTypeEnum.COPY]: 'copy',
|
||||
[BpmTaskOperationButtonTypeEnum.DELETE_SIGN]: 'remove',
|
||||
}
|
||||
|
||||
const userStore = useUserStore()
|
||||
/** 左侧操作按钮 【最多两个】{转办, 委派, 退回, 加签, 抄送等} */
|
||||
const leftOperations = ref<LeftOperationType[]>([])
|
||||
|
||||
@@ -90,7 +95,7 @@ function loadTodoTask(task: Task) {
|
||||
if (task) {
|
||||
reasonRequire.value = task.reasonRequire ?? false
|
||||
// 右侧按钮
|
||||
if (isHandleTaskStatus() && task.buttonsSetting && task.buttonsSetting[BpmTaskOperationButtonTypeEnum.REJECT]?.enable) {
|
||||
if (isHandleTaskStatus() && isShowButton(BpmTaskOperationButtonTypeEnum.REJECT)) {
|
||||
rightOperationTypes.push(BpmTaskOperationButtonTypeEnum.REJECT)
|
||||
rightOperations.value.push({
|
||||
operationType: BpmTaskOperationButtonTypeEnum.REJECT,
|
||||
@@ -99,7 +104,7 @@ function loadTodoTask(task: Task) {
|
||||
plain: true,
|
||||
})
|
||||
}
|
||||
if (isHandleTaskStatus() && task.buttonsSetting && task.buttonsSetting[BpmTaskOperationButtonTypeEnum.APPROVE]?.enable) {
|
||||
if (isHandleTaskStatus() && isShowButton(BpmTaskOperationButtonTypeEnum.APPROVE)) {
|
||||
rightOperationTypes.push(BpmTaskOperationButtonTypeEnum.APPROVE)
|
||||
rightOperations.value.push({
|
||||
operationType: BpmTaskOperationButtonTypeEnum.APPROVE,
|
||||
@@ -108,7 +113,7 @@ function loadTodoTask(task: Task) {
|
||||
plain: false,
|
||||
})
|
||||
}
|
||||
// TODO 减签
|
||||
|
||||
// 左侧操作,和更多操作
|
||||
Object.keys(task.buttonsSetting || {}).forEach((key) => {
|
||||
const operationType = Number(key)
|
||||
@@ -128,6 +133,21 @@ function loadTodoTask(task: Task) {
|
||||
}
|
||||
}
|
||||
})
|
||||
/** 减签操作的显示 */
|
||||
if (isShowDeleteSign()) {
|
||||
if (leftOperations.value.length >= 2) {
|
||||
moreOperations.value.push({
|
||||
name: getButtonDisplayName(BpmTaskOperationButtonTypeEnum.DELETE_SIGN),
|
||||
operationType: BpmTaskOperationButtonTypeEnum.DELETE_SIGN,
|
||||
})
|
||||
} else {
|
||||
leftOperations.value.push({
|
||||
operationType: BpmTaskOperationButtonTypeEnum.DELETE_SIGN,
|
||||
iconName: operationIconsMap[BpmTaskOperationButtonTypeEnum.DELETE_SIGN],
|
||||
displayName: getButtonDisplayName(BpmTaskOperationButtonTypeEnum.DELETE_SIGN),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 跳转到相应的操作页面 */
|
||||
@@ -162,6 +182,11 @@ function handleOperation(operationType: number) {
|
||||
url: `/pages-bpm/processInstance/detail/return/index?processInstanceId=${runningTask.value.processInstanceId}&taskId=${runningTask.value.id}`,
|
||||
})
|
||||
break
|
||||
case BpmTaskOperationButtonTypeEnum.DELETE_SIGN:
|
||||
uni.navigateTo({
|
||||
url: `/pages-bpm/processInstance/detail/delete-sign/index?processInstanceId=${runningTask.value.processInstanceId}&taskId=${runningTask.value.id}&children=${encodeURIComponent(JSON.stringify(runningTask.value.children || []))}`,
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +234,38 @@ function isHandleTaskStatus() {
|
||||
return canHandle
|
||||
}
|
||||
|
||||
/** 流程状态是否为结束状态 */
|
||||
function isEndProcessStatus(status: number) {
|
||||
let isEndStatus = false
|
||||
if (
|
||||
BpmProcessInstanceStatus.APPROVE === status
|
||||
|| BpmProcessInstanceStatus.REJECT === status
|
||||
|| BpmProcessInstanceStatus.CANCEL === status
|
||||
) {
|
||||
isEndStatus = true
|
||||
}
|
||||
return isEndStatus
|
||||
}
|
||||
|
||||
/** 流程发起人是否为当前用户 */
|
||||
function isProcessStartUser() {
|
||||
let isStartUser = false
|
||||
if (userStore.userInfo?.userId === runningTask.value?.processInstance?.startUser?.id) {
|
||||
isStartUser = true
|
||||
}
|
||||
return isStartUser
|
||||
}
|
||||
|
||||
/** 是否显示减签 */
|
||||
function isShowDeleteSign() {
|
||||
return runningTask.value?.children?.length > 0
|
||||
}
|
||||
|
||||
/** 是否显示流程发起人取消 */
|
||||
function isShowProcessStartCancel() {
|
||||
return isProcessStartUser
|
||||
}
|
||||
|
||||
/** 暴露方法 */
|
||||
defineExpose({ loadTodoTask })
|
||||
</script>
|
||||
|
||||
181
src/pages-bpm/processInstance/detail/delete-sign/index.vue
Normal file
181
src/pages-bpm/processInstance/detail/delete-sign/index.vue
Normal file
@@ -0,0 +1,181 @@
|
||||
<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.deleteSignTaskId"
|
||||
:columns="taskOptions"
|
||||
value-key="id"
|
||||
label-key="label"
|
||||
label="减签人员:"
|
||||
label-width="180rpx"
|
||||
placeholder="请选择减签人员"
|
||||
prop="deleteSignTaskId"
|
||||
/>
|
||||
|
||||
<!-- 审批意见 -->
|
||||
<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 { signDeleteTask } from '@/api/bpm/task'
|
||||
import { navigateBackPlus } from '@/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
processInstanceId: string
|
||||
taskId: string
|
||||
children?: string // JSON 字符串格式的子任务数据
|
||||
}>()
|
||||
|
||||
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 taskOptions = ref<any[]>([])
|
||||
|
||||
const formData = reactive({
|
||||
deleteSignTaskId: '',
|
||||
reason: '',
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
deleteSignTaskId: [
|
||||
{ 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('参数错误')
|
||||
}
|
||||
|
||||
/** 获取减签人员标签 */
|
||||
function getDeleteSignUserLabel(task: any): string {
|
||||
const deptName = task?.assigneeUser?.deptName || task?.ownerUser?.deptName
|
||||
const nickname = task?.assigneeUser?.nickname || task?.ownerUser?.nickname
|
||||
return `${nickname} ( 所属部门:${deptName} )`
|
||||
}
|
||||
|
||||
/** 获取可减签的任务列表 */
|
||||
async function loadDeleteSignTaskList() {
|
||||
try {
|
||||
let childTasks = []
|
||||
|
||||
// 从 URL 参数中获取子任务数据
|
||||
if (props.children) {
|
||||
try {
|
||||
childTasks = JSON.parse(decodeURIComponent(props.children))
|
||||
} catch (parseError) {
|
||||
console.error('[delete-sign] 解析子任务数据失败:', parseError)
|
||||
}
|
||||
}
|
||||
|
||||
// 提示没有子任务数据
|
||||
if (childTasks.length === 0) {
|
||||
toast.show('没有可减签的任务')
|
||||
return
|
||||
}
|
||||
|
||||
taskOptions.value = childTasks.map(task => ({
|
||||
id: task.id,
|
||||
label: getDeleteSignUserLabel(task),
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error('[delete-sign] 获取可减签任务失败:', 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 signDeleteTask({
|
||||
id: formData.deleteSignTaskId,
|
||||
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('[delete-sign] 减签失败:', error)
|
||||
toast.error('减签失败')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 页面加载时获取可减签任务列表 */
|
||||
onMounted(() => {
|
||||
loadDeleteSignTaskList()
|
||||
})
|
||||
</script>
|
||||
@@ -147,6 +147,10 @@ export enum BpmTaskOperationButtonTypeEnum {
|
||||
* 委派
|
||||
*/
|
||||
DELEGATE = 4,
|
||||
/**
|
||||
* 减签
|
||||
*/
|
||||
DELETE_SIGN = 8,
|
||||
/**
|
||||
* 拒绝
|
||||
*/
|
||||
@@ -159,6 +163,7 @@ export enum BpmTaskOperationButtonTypeEnum {
|
||||
* 转办
|
||||
*/
|
||||
TRANSFER = 3,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,6 +291,7 @@ OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.DELEGATE, '委派')
|
||||
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.ADD_SIGN, '加签')
|
||||
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.RETURN, '退回')
|
||||
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.COPY, '抄送')
|
||||
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.DELETE_SIGN, '减签')
|
||||
|
||||
/**
|
||||
* 流程实例的变量枚举
|
||||
|
||||
Reference in New Issue
Block a user