xiaoyi
2 天以前 b5e1bceabb36fe1d1e5e88397280d12e7044c6dd
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package cn.iocoder.yudao.module.mes.service.safety;
 
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.document.SafetyDocumentApprovalReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.document.SafetyDocumentSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.safety.SafetyDocumentDO;
import cn.iocoder.yudao.module.mes.dal.mysql.safety.SafetyDocumentMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.safety.SafetyDocumentApprovalMapper;
import cn.iocoder.yudao.module.mes.dal.dataobject.safety.SafetyDocumentApprovalDO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.LocalDate;
import java.util.Objects;
import java.util.UUID;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
@Service
public class SafetyDocumentService {
    @Resource private SafetyDocumentMapper mapper;
    @Resource private SafetyDocumentApprovalMapper approvalMapper;
 
    @Transactional(rollbackFor = Exception.class)
    public Long create(SafetyDocumentSaveReqVO req) {
        var document = new SafetyDocumentDO();
        document.setDocumentKey(UUID.randomUUID().toString());
        document.setRevision(1);
        document.setStatus("DRAFT");
        document.setOwnerUserId(currentUser());
        apply(document, req);
        mapper.insert(document);
        return document.getId();
    }
 
    @Transactional(rollbackFor = Exception.class)
    public void update(SafetyDocumentSaveReqVO req) {
        if (req.getId() == null) throw invalidParamException("请选择制度档案");
        var document = requireLocked(req.getId());
        if (!"DRAFT".equals(document.getStatus()) && !"REJECTED".equals(document.getStatus())) {
            throw invalidParamException("只有草稿或驳回的制度可以修改");
        }
        if (!Objects.equals(document.getOwnerUserId(), currentUser())) throw invalidParamException("只有创建人可以修改制度草稿");
        apply(document, req);
        document.setStatus("DRAFT");
        mapper.updateById(document);
    }
 
    @Transactional(rollbackFor = Exception.class)
    public void submit(Long id) {
        var document = requireLocked(id);
        if (!"DRAFT".equals(document.getStatus())) throw invalidParamException("只有草稿可以提交审批");
        if (!Objects.equals(document.getOwnerUserId(), currentUser())) throw invalidParamException("只有创建人可以提交制度");
        document.setStatus("PENDING");
        document.setSubmitterUserId(currentUser());
        document.setSubmitTime(LocalDateTime.now());
        mapper.updateById(document);
    }
 
    @Transactional(rollbackFor = Exception.class)
    public void approve(SafetyDocumentApprovalReqVO req) {
        var document = requireLocked(req.getId());
        SafetyDocumentPolicy.checkApproval(document.getStatus(), document.getSubmitterUserId(), currentUser());
        if (!req.getApproved() && (req.getComment() == null || req.getComment().isBlank())) throw invalidParamException("驳回时请填写审批意见");
        if (req.getApproved()) {
            if (document.getEffectiveDate() != null && document.getEffectiveDate().isAfter(LocalDate.now())) {
                throw invalidParamException("暂不支持未来日期自动生效,请在生效日期当天审批或修改生效日期");
            }
            mapper.update(null, new LambdaUpdateWrapper<SafetyDocumentDO>()
                    .eq(SafetyDocumentDO::getDocumentKey, document.getDocumentKey())
                    .eq(SafetyDocumentDO::getStatus, "APPROVED")
                    .ne(SafetyDocumentDO::getId, document.getId())
                    .set(SafetyDocumentDO::getStatus, "SUPERSEDED"));
        }
        document.setStatus(req.getApproved() ? "APPROVED" : "REJECTED");
        document.setApproverUserId(currentUser());
        document.setApprovalTime(LocalDateTime.now());
        document.setApprovalComment(req.getComment());
        mapper.updateById(document);
        var log = new SafetyDocumentApprovalDO();
        log.setDocumentId(document.getId()); log.setApproverUserId(currentUser());
        log.setDecision(document.getStatus()); log.setComment(req.getComment()); log.setDecisionTime(document.getApprovalTime());
        log.setSubmitterUserId(document.getSubmitterUserId()); log.setTitleSnapshot(document.getTitle());
        log.setCategorySnapshot(document.getCategory()); log.setAttachmentUrlSnapshot(document.getAttachmentUrl());
        log.setDescriptionSnapshot(document.getDescription());
        log.setEffectiveDateSnapshot(document.getEffectiveDate());
        approvalMapper.insert(log);
    }
 
    @Transactional(rollbackFor = Exception.class)
    public Long createRevision(Long id) {
        var previous = requireLocked(id);
        if (!"APPROVED".equals(previous.getStatus())) throw invalidParamException("只有已批准的制度可以创建新版本");
        var latest = mapper.latest(previous.getDocumentKey());
        if (latest == null || !Objects.equals(latest.getId(), previous.getId())) throw invalidParamException("请基于最新版本创建修订,已有后续版本");
        var next = new SafetyDocumentDO();
        next.setDocumentKey(previous.getDocumentKey());
        next.setRevision(previous.getRevision() + 1);
        next.setTitle(previous.getTitle()); next.setCategory(previous.getCategory());
        next.setAttachmentUrl(previous.getAttachmentUrl()); next.setDescription(previous.getDescription());
        next.setEffectiveDate(previous.getEffectiveDate());
        next.setStatus("DRAFT"); next.setOwnerUserId(currentUser());
        mapper.insert(next);
        return next.getId();
    }
 
    public PageResult<SafetyDocumentDO> page(PageParam page, String title, String status) {
        return mapper.selectPage(page, new LambdaQueryWrapperX<SafetyDocumentDO>()
                .likeIfPresent(SafetyDocumentDO::getTitle, title).eqIfPresent(SafetyDocumentDO::getStatus, status)
                .orderByDesc(SafetyDocumentDO::getId));
    }
 
    public java.util.List<SafetyDocumentApprovalDO> approvals(Long id) {
        if (id == null || mapper.selectById(id) == null) throw invalidParamException("制度档案不存在");
        return approvalMapper.selectList(new LambdaQueryWrapperX<SafetyDocumentApprovalDO>()
                .eq(SafetyDocumentApprovalDO::getDocumentId, id).orderByDesc(SafetyDocumentApprovalDO::getId));
    }
 
    private SafetyDocumentDO requireLocked(Long id) {
        if (id == null) throw invalidParamException("请选择制度档案");
        var result = mapper.lockById(id);
        if (result == null) throw invalidParamException("制度档案不存在");
        return result;
    }
    private Long currentUser() {
        Long userId = getLoginUserId();
        if (userId == null) throw invalidParamException("登录状态已失效");
        return userId;
    }
    private void apply(SafetyDocumentDO doc, SafetyDocumentSaveReqVO req) {
        doc.setTitle(req.getTitle().trim()); doc.setCategory(req.getCategory().trim());
        doc.setAttachmentUrl(req.getAttachmentUrl().trim()); doc.setDescription(req.getDescription());
        doc.setEffectiveDate(req.getEffectiveDate());
    }
}