blob: 43009110f03763f18e48f88d03008833ed4d5a79 [file] [log] [blame]
崔向南03d21b92025-06-05 17:42:23 +08001package bounty.service;
2
3import bounty.domain.Bounty;
4import bounty.domain.BountySubmission;
5import bounty.mapper.BountyMapper;
6import bounty.mapper.BountySubmissionMapper;
7import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
8import com.baomidou.mybatisplus.core.metadata.IPage;
9import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
10import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
11import com.ruoyi.common.utils.SecurityUtils;
12import org.mybatis.spring.MyBatisSystemException;
13import org.springframework.beans.factory.annotation.Autowired;
14import org.springframework.stereotype.Service;
15import org.springframework.util.StringUtils;
16
17import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
19
20import java.util.Date;
21
22@Service
23public class BountySubmissionServiceImpl extends ServiceImpl<BountySubmissionMapper, BountySubmission> implements BountySubmissionService {
24
25 @Autowired
26 private BountyMapper bountyMapper; // 注入 BountyMapper 校验悬赏存在性
27
28 @Override
29 public boolean saveBountySubmission(BountySubmission bountySubmission) {
30 // 校验 1:悬赏 ID 不能为空
31 Long bountyId = bountySubmission.getBountyId();
32 if (bountyId == null) {
33 throw new IllegalArgumentException("悬赏 ID 不能为空");
34 }
35
36 // 校验 2:目标悬赏是否存在
37 Bounty targetBounty = bountyMapper.selectById(bountyId);
38 if (targetBounty == null) {
39 throw new IllegalArgumentException("无效的悬赏 ID,未找到对应悬赏");
40 }
41
42 // 校验 3:提交内容不能为空
43 String content = bountySubmission.getContent();
44 if (!StringUtils.hasText(content)) {
45 throw new IllegalArgumentException("提交内容不能为空");
46 }
47
48 // 自动填充当前用户 ID(需用户已登录)
49 Long currentUserId = SecurityUtils.getUserId();
50 bountySubmission.setUserId(currentUserId);
51
52
53 // 调用 MyBatis-Plus 保存方法
54 boolean saveResult = this.save(bountySubmission);
55
56 // 新增:保存成功后,更新对应悬赏的状态为1(已回复)
57 if (saveResult) {
58 targetBounty.setStatus(1); // 将悬赏状态改为1
59 bountyMapper.updateById(targetBounty); // 执行更新
60 }
61
62 return saveResult;
63 }
64
65 @Override
66 public IPage<BountySubmission> getBountySubmissionsByPage(Page<BountySubmission> page, Long bountyId) {
67 QueryWrapper<BountySubmission> wrapper = new QueryWrapper<>();
68 wrapper.eq("bounty_id", bountyId);
69 return this.page(page, wrapper);
70 }
71
72 private static final Logger log = LoggerFactory.getLogger(BountySubmissionServiceImpl.class);
73
74 @Override
75 public boolean adoptSubmission(Long submissionId) {
76 log.info("【采纳流程开始】submissionId={}, 当前时间={}", submissionId, new Date());
77
78 try {
79 // 参数校验
80 if (submissionId == null || submissionId <= 0) {
81 log.warn("【参数校验失败】submissionId为空或无效");
82 throw new IllegalArgumentException("无效的回复ID");
83 }
84
85 // 获取回复详情
86 BountySubmission submission = this.getById(submissionId);
87 if (submission == null) {
88 log.warn("【回复不存在】submissionId={}", submissionId);
89 throw new IllegalArgumentException("无效的回复ID");
90 }
91
92 if (submission.getId() == null || submission.getBountyId() == null) {
93 log.warn("【无效提交数据】submissionId={}", submissionId);
94 throw new IllegalArgumentException("提交数据不完整");
95 }
96
97
98 log.debug("【原始回复数据】{}", submission);
99
100 // 获取关联悬赏
101 Bounty bounty = bountyMapper.selectById(submission.getBountyId());
102
103 if (bounty == null) {
104 log.warn("【关联悬赏不存在】bountyId={}", submission.getBountyId());
105 throw new IllegalArgumentException("关联悬赏不存在");
106 }
107
108 // 用户权限校验
109 Long currentUserId = SecurityUtils.getUserId();
110 if (currentUserId == null) {
111 log.warn("【用户未登录】");
112 throw new IllegalArgumentException("用户未登录");
113 }
114
115
116 if (!bounty.getCreator_id().equals(currentUserId)) {
117 log.warn("【权限不足】用户ID={} 试图访问悬赏ID={}", currentUserId, bounty.getId());
118 throw new IllegalArgumentException("无权操作");
119 }
120
121 // 状态校验
122 if (submission.getStatus() == 1) {
123 log.warn("【重复采纳】submissionId={}", submissionId);
124 throw new IllegalArgumentException("该回复已被采纳");
125 }
126
127 log.info("【更新前对象】{}", submission);
128
129 // 执行更新
130 submission.setStatus(1);
131 boolean submissionResult = this.updateById(submission);
132 log.info("【更新后对象】{}", this.getById(submissionId));
133
134
135 log.info("【操作结果】submissionResult={}, 新状态={}", submissionResult, submission.getStatus());
136
137 return submissionResult;
138 } catch (MyBatisSystemException e) {
139 // 显式捕获 MyBatis 异常
140 log.error("【MyBatis 异常】submissionId={}, rootCause={}", submissionId, e.getRootCause());
141 log.error("【异常详情】", e); // 打印完整堆栈
142 throw new RuntimeException("MyBatis 错误: " + e.getRootCause(), e);
143
144 } catch (IllegalArgumentException e) {
145 log.warn("【参数异常】submissionId={}, message={}", submissionId, e.getMessage());
146 throw e;
147 } catch (Exception e) {
148 log.error("【采纳异常】submissionId={}, 错误={}", submissionId, e.getMessage(), e);
149 log.error("【未分类异常】submissionId={}, exceptionClass={}", submissionId, e.getClass().getName());
150 log.error("【异常详情】", e); // 打印完整堆栈
151 throw e;
152 }
153 }
154}