| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | |
| | | @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 |
| | |
| | | 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()); |