4 小时以前 4d15fa8051884869c5b612d0641508874cc71811
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
package cn.iocoder.yudao.module.srm.service.tender;
 
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmBidEvaluationSaveReqVO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmBidEvaluationDO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmBidOpenDO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderProjectDO;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmBidEvaluationMapper;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmBidOpenMapper;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderProjectMapper;
import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
 
/**
 * SRM 评标管理 Service 实现类
 */
@Service
@Validated
public class SrmBidEvaluationServiceImpl implements SrmBidEvaluationService {
 
    @Resource
    private SrmBidEvaluationMapper bidEvaluationMapper;
 
    @Resource
    private SrmBidOpenMapper bidOpenMapper;
 
    @Resource
    private SrmTenderProjectMapper tenderProjectMapper;
 
    // ========== 评标管理 ==========
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createEvaluation(SrmBidEvaluationSaveReqVO createReqVO) {
        SrmBidEvaluationDO evaluation = BeanUtils.toBean(createReqVO, SrmBidEvaluationDO.class);
        // 计算综合评分: 价格*0.4 + 技术*0.3 + 交付*0.2 + 服务*0.1
        BigDecimal price = nvl(evaluation.getPriceScore());
        BigDecimal tech = nvl(evaluation.getTechScore());
        BigDecimal delivery = nvl(evaluation.getDeliveryScore());
        BigDecimal service = nvl(evaluation.getServiceScore());
        BigDecimal composite = price.multiply(new BigDecimal("0.4"))
                .add(tech.multiply(new BigDecimal("0.3")))
                .add(delivery.multiply(new BigDecimal("0.2")))
                .add(service.multiply(new BigDecimal("0.1")))
                .setScale(2, RoundingMode.HALF_UP);
        evaluation.setCompositeScore(composite);
        evaluation.setEvaluationTime(LocalDateTime.now());
        bidEvaluationMapper.insert(evaluation);
        // 首次评标时更新招标项目状态为评标中
        SrmTenderProjectDO project = tenderProjectMapper.selectById(createReqVO.getTenderProjectId());
        if (project != null && TenderStatusEnum.BIDDING.getCode().equals(project.getTenderStatus())) {
            project.setTenderStatus(TenderStatusEnum.EVALUATING.getCode());
            tenderProjectMapper.updateById(project);
        }
        return evaluation.getId();
    }
 
    @Override
    public List<SrmBidEvaluationDO> getEvaluationList(Long tenderProjectId) {
        return bidEvaluationMapper.selectListByTenderProjectId(tenderProjectId);
    }
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void calculateRanking(Long tenderProjectId) {
        List<SrmBidEvaluationDO> list = bidEvaluationMapper.selectListByTenderProjectId(tenderProjectId);
        // 按综合评分降序排名
        list.sort(Comparator.comparing(e -> e.getCompositeScore() != null ? e.getCompositeScore() : BigDecimal.ZERO, Comparator.reverseOrder()));
        for (int i = 0; i < list.size(); i++) {
            SrmBidEvaluationDO evaluation = list.get(i);
            evaluation.setRanking(i + 1);
            bidEvaluationMapper.updateById(evaluation);
        }
    }
 
    // ========== 开标管理 ==========
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createBidOpen(Long tenderProjectId) {
        if (bidOpenMapper.selectByTenderProjectId(tenderProjectId) != null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_PUBLISHED);
        }
        // 开标后自动更新招标项目状态为投标中
        SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId);
        if (project != null && TenderStatusEnum.PUBLISHED.getCode().equals(project.getTenderStatus())) {
            project.setTenderStatus(TenderStatusEnum.BIDDING.getCode());
            tenderProjectMapper.updateById(project);
        }
        SrmBidOpenDO open = new SrmBidOpenDO();
        open.setTenderProjectId(tenderProjectId);
        open.setOpenTime(LocalDateTime.now());
        bidOpenMapper.insert(open);
        return open.getId();
    }
 
    @Override
    public SrmBidOpenDO getBidOpen(Long id) {
        return bidOpenMapper.selectById(id);
    }
 
    private static BigDecimal nvl(BigDecimal value) {
        return value != null ? value : BigDecimal.ZERO;
    }
 
}