longz
2026-04-21 c4db0a4526f61758272c92396aa788d84f098102
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package com.sinata.appointment.service;
 
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sinata.appointment.constants.ApprovalInstanceStatus;
import com.sinata.appointment.constants.ApprovalTaskStatus;
import com.sinata.appointment.constants.BizErrorCode;
import com.sinata.appointment.dto.ApprovalActionRequest;
import com.sinata.appointment.entity.AppointmentOrder;
import com.sinata.appointment.entity.ApprovalInstance;
import com.sinata.appointment.entity.ApprovalTask;
import com.sinata.appointment.exception.BizException;
import com.sinata.appointment.mapper.AppointmentOrderMapper;
import com.sinata.appointment.mapper.ApprovalInstanceMapper;
import com.sinata.appointment.mapper.ApprovalTaskMapper;
import com.sinata.appointment.service.event.AppointmentApprovedEvent;
import com.sinata.appointment.service.event.AppointmentRejectedEvent;
import com.sinata.appointment.util.UuidAssert;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.ApplicationEventPublisher;
 
@Service
@RequiredArgsConstructor
public class ApprovalApplicationService {
 
    private final ApprovalTaskMapper approvalTaskMapper;
    private final ApprovalInstanceMapper approvalInstanceMapper;
    private final AppointmentOrderMapper appointmentOrderMapper;
    private final ApprovalEngineService approvalEngineService;
    private final ApplicationEventPublisher applicationEventPublisher;
 
    public IPage<ApprovalTask> pageMyTodo(long page, long size) {
        Long uid = StpUtil.getLoginIdAsLong();
        return approvalTaskMapper.selectPage(
                new Page<>(page, size),
                new LambdaQueryWrapper<ApprovalTask>()
                        .eq(ApprovalTask::getAssigneeUserId, uid)
                        .eq(ApprovalTask::getTaskStatus, ApprovalTaskStatus.PENDING)
                        .orderByDesc(ApprovalTask::getCreateTime));
    }
 
    @Transactional(rollbackFor = Exception.class)
    public void handleAction(ApprovalActionRequest req) {
        Long uid = StpUtil.getLoginIdAsLong();
        ApprovalTask task = approvalTaskMapper.selectById(req.getTaskId());
        if (task == null || task.getDelFlag() != null && task.getDelFlag() == 1) {
            throw new BizException(BizErrorCode.APPROVAL_TASK_NOT_FOUND, "审批任务不存在");
        }
        UuidAssert.match(task, req.getTaskUuid());
        if (!ApprovalTaskStatus.PENDING.equals(task.getTaskStatus())) {
            throw new BizException(BizErrorCode.APPROVAL_CONFLICT, "任务已处理");
        }
        if (!uid.equals(task.getAssigneeUserId())) {
            throw new BizException(BizErrorCode.AUTH_FORBIDDEN, "无权处理该任务");
        }
 
        ApprovalInstance inst = approvalInstanceMapper.selectById(task.getInstanceId());
        AppointmentOrder order = appointmentOrderMapper.selectById(inst.getOrderId());
 
        if (Boolean.FALSE.equals(req.getApprove())) {
            String reason = req.getComment() != null ? req.getComment() : "拒绝";
            task.setTaskStatus(ApprovalTaskStatus.REJECTED);
            task.setComment(reason);
            approvalTaskMapper.updateById(task);
            approvalEngineService.rejectInstance(inst, reason);
            applicationEventPublisher.publishEvent(new AppointmentRejectedEvent(order.getId(), reason));
            return;
        }
 
        task.setTaskStatus(ApprovalTaskStatus.APPROVED);
        task.setComment(req.getComment());
        approvalTaskMapper.updateById(task);
        approvalEngineService.markGroupSkippedExcept(task);
 
        if (approvalEngineService.isCurrentNodeComplete(inst)) {
            approvalEngineService.advanceOrComplete(inst, order);
            ApprovalInstance latest = approvalInstanceMapper.selectById(inst.getId());
            if (ApprovalInstanceStatus.APPROVED.equals(latest.getStatus())) {
                applicationEventPublisher.publishEvent(new AppointmentApprovedEvent(order.getId()));
            }
        }
    }
}