刘帅
2026-09-08 572df690f72ed4a077d934823f261dec39b3cc7d
cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
@@ -15,9 +15,11 @@
import com.alipay.api.response.AlipayTradeOrderSettleResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRoyaltyRelationBindResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsh.competition.entity.*;
import com.dsh.competition.enums.CompetitionStatusEnum;
import com.dsh.competition.feignclient.account.AppUserClient;
import com.dsh.competition.feignclient.account.StudentClient;
import com.dsh.competition.feignclient.account.model.AppUser;
@@ -36,9 +38,11 @@
import com.dsh.competition.service.UserCompetitionService;
import com.dsh.competition.util.*;
import com.dsh.competition.util.wx.WxV3PayConfig;
import cn.mb.cloud.common.core.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -85,6 +89,104 @@
    @Autowired
    private CompetitionService cttService;
    /**
     * 修改活动,并确保修改不会破坏既有报名记录。
     *
     * @param competition 管理端提交的活动信息
     * @throws BusinessException 活动不存在、时间范围非法或人数容量不足时抛出
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCompetition(Competition competition) throws BusinessException {
        validateUpdateRequest(competition);
        // STEP 1: 读取原活动,避免前端传入部分字段时覆盖既有数据。
        Competition originalCompetition = getById(competition.getId());
        if (originalCompetition == null) {
            throw new BusinessException("活动不存在或已删除");
        }
        // STEP 2: 校验人数容量,保证已报名记录始终处于有效的活动容量内。
        validateApplicantsNumber(competition);
        // STEP 3: 仅更新活动配置;支付订单金额为快照,价格调整不会修改既有订单。
        competition.setStatus(resolveCompetitionStatus(originalCompetition, competition));
        updateById(competition);
    }
    /**
     * 校验编辑请求中必填字段和基础数值范围。
     *
     * @param competition 待校验的活动信息
     */
    private void validateUpdateRequest(Competition competition) throws BusinessException {
        if (competition == null || competition.getId() == null) {
            throw new BusinessException("活动编号不能为空");
        }
        if (competition.getStartTime() == null || competition.getEndTime() == null
                || competition.getRegisterEndTime() == null) {
            throw new BusinessException("活动时间和截止报名时间不能为空");
        }
        if (competition.getApplicantsNumber() == null || competition.getApplicantsNumber() < 0) {
            throw new BusinessException("报名人数必须为非负整数");
        }
        if (competition.getBaseNumber() != null && competition.getBaseNumber() < 0) {
            throw new BusinessException("基础报名人数必须为非负整数");
        }
        if (competition.getStartAge() != null && competition.getEndAge() != null
                && competition.getStartAge() > competition.getEndAge()) {
            throw new BusinessException("报名最小年龄不能大于最大年龄");
        }
        validatePrices(competition);
    }
    /**
     * 校验各支付价格不可为负数。
     *
     * @param competition 待校验的活动信息
     */
    private void validatePrices(Competition competition) throws BusinessException {
        if ((competition.getCashPrice() != null && competition.getCashPrice() < 0)
                || (competition.getPlayPaiCoin() != null && competition.getPlayPaiCoin() < 0)
                || (competition.getClassPrice() != null && competition.getClassPrice() < 0)) {
            throw new BusinessException("支付价格不能小于零");
        }
    }
    /**
     * 校验调整后的容量不会小于当前已报名人数。
     *
     * @param competition 待校验的活动信息
     */
    private void validateApplicantsNumber(Competition competition) throws BusinessException {
        int registeredCount = userCompetitionService.count(new LambdaQueryWrapper<UserCompetition>()
                .eq(UserCompetition::getCompetitionId, competition.getId()));
        if (competition.getApplicantsNumber() < registeredCount) {
            throw new BusinessException("报名人数不能小于已报名人数" + registeredCount);
        }
    }
    /**
     * 根据当前时间刷新活动状态,并保持已取消活动的取消状态。
     *
     * @param originalCompetition 数据库中的原活动
     * @param competition 待保存的活动信息
     * @return 计算后的活动状态编码
     */
    private Integer resolveCompetitionStatus(Competition originalCompetition, Competition competition) {
        if (CompetitionStatusEnum.CANCELED.getCode().equals(originalCompetition.getStatus())) {
            return CompetitionStatusEnum.CANCELED.getCode();
        }
        Date currentTime = new Date();
        if (currentTime.before(competition.getStartTime())) {
            return CompetitionStatusEnum.NOT_STARTED.getCode();
        }
        if (currentTime.before(competition.getEndTime())) {
            return CompetitionStatusEnum.IN_PROGRESS.getCode();
        }
        return CompetitionStatusEnum.ENDED.getCode();
    }
    private String aliAppid = "2021004105665036";//支付宝appid
@@ -278,6 +380,7 @@
        String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5);
        paymentCompetition.setCode(code);
        paymentCompetition.setCompetitionId(paymentCompetitionVo.getId());
        paymentCompetition.setCompetitionStoreIds(competition.getStoreId());
        paymentCompetition.setAppUserId(uid);
        paymentCompetition.setPayType(paymentCompetitionVo.getPayType());
        paymentCompetition.setAmount(money.doubleValue());