package com.dsh.competition.service.impl; import com.alibaba.nacos.common.utils.UuidUtils; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.dsh.competition.entity.Competition; import com.dsh.competition.entity.Participant; import com.dsh.competition.entity.PaymentCompetition; import com.dsh.competition.entity.UserCompetition; 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.feignclient.account.model.Student; import com.dsh.competition.feignclient.course.CoursePackagePaymentClient; import com.dsh.competition.feignclient.course.model.PaymentDeductionClassHour; import com.dsh.competition.feignclient.other.StoreClient; import com.dsh.competition.feignclient.other.model.Store; import com.dsh.competition.mapper.CompetitionMapper; import com.dsh.competition.model.CompetitionInfo; import com.dsh.competition.model.CompetitionListVo; import com.dsh.competition.model.ParticipantVo; import com.dsh.competition.model.PaymentCompetitionVo; import com.dsh.competition.service.CompetitionService; import com.dsh.competition.service.IParticipantService; import com.dsh.competition.service.IPaymentCompetitionService; import com.dsh.competition.service.UserCompetitionService; import com.dsh.competition.util.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** *

* 服务实现类 *

* * @author jqs * @since 2023-06-26 */ @Service public class CompetitionServiceImpl extends ServiceImpl implements CompetitionService { @Resource private StoreClient storeClient; @Autowired private IPaymentCompetitionService paymentCompetitionService; @Autowired private UserCompetitionService userCompetitionService; @Autowired private IParticipantService participantService; @Resource private AppUserClient appUserClient; @Resource private StudentClient studentClient; @Resource private CoursePackagePaymentClient coursePackagePaymentClient; @Autowired private PayMoneyUtil payMoneyUtil; /** * 获取赛事列表 * @param content * @param registerCondition * @param heat * @return */ @Override public List queryCompetitionList(String cityCode, String content, Integer registerCondition, String heat) throws Exception { return this.baseMapper.queryCompetitionList(cityCode, content, registerCondition, heat); } /** * 获取赛事详情 * @param uid * @param id * @return * @throws Exception */ @Override public CompetitionInfo queryCompetitionInfo(Integer uid, Integer id, String lon, String lat) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); Competition competition = this.getById(id); CompetitionInfo competitionInfo = new CompetitionInfo(); competitionInfo.setId(competition.getId().longValue()); competitionInfo.setImgs(competition.getImgs()); competitionInfo.setName(competition.getName()); competitionInfo.setRegisterCondition(competition.getRegisterCondition()); if(null != competition.getStoreId()){ Store store = storeClient.queryStoreById(competition.getStoreId()); competitionInfo.setStoreName(store.getName()); competitionInfo.setStoreAddress(store.getAddress()); competitionInfo.setStoreLon(store.getLon()); competitionInfo.setStoreLat(store.getLat()); competitionInfo.setStoreCoverDrawing(store.getCoverDrawing()); if(ToolUtil.isNotEmpty(lon) && ToolUtil.isNotEmpty(lat)){ Map distance = GeodesyUtil.getDistance(lon + "," + lat, store.getLon() + "," + store.getLat()); double wgs84 = new BigDecimal(distance.get("WGS84")).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_EVEN).doubleValue(); competitionInfo.setDistance(wgs84); } } competitionInfo.setRegisterEndTime(sdf.format(competition.getRegisterEndTime())); competitionInfo.setStartTime(sdf.format(competition.getStartTime())); competitionInfo.setEndTime(sdf.format(competition.getEndTime())); competitionInfo.setAge(competition.getStartAge() + "-" + competition.getEndAge()); competitionInfo.setProvince(competition.getEntryProvince()); competitionInfo.setCity(competition.getEntryCity()); competitionInfo.setAddress(competition.getEntryAddress()); competitionInfo.setCashPrice(competition.getCashPrice()); competitionInfo.setPlayPaiCoin(competition.getPlayPaiCoin()); competitionInfo.setClassPrice(competition.getClassPrice()); competitionInfo.setIntroduction(competition.getIntroduction()); competitionInfo.setRegistrationNotes(competition.getRegistrationNotes()); competitionInfo.setApply(0); competitionInfo.setStatus(competition.getStatus()); PaymentCompetition one = paymentCompetitionService.getOne(new QueryWrapper().eq("competitionId", id).eq("appUserId", uid).ne("payStatus", 1).orderByDesc("insertTime").last(" limit 1")); if(null != one){ competitionInfo.setApply(1); List participant = new ArrayList<>(); List list = userCompetitionService.list(new QueryWrapper().eq("paymentCompetitionId", one.getId())); List collect = list.stream().map(UserCompetition::getParticipantId).collect(Collectors.toList()); List participants = participantService.listByIds(collect); SimpleDateFormat sdf_year = new SimpleDateFormat("yyyy"); for (Participant participant1 : participants) { ParticipantVo participantVo = new ParticipantVo(); participantVo.setId(participant1.getId()); participantVo.setName(participant1.getName()); participantVo.setIdcard(participant1.getIdcard()); Integer age = Integer.valueOf(sdf_year.format(new Date())) - Integer.valueOf(sdf_year.format(participant1.getBirthday())); participantVo.setAge(age); participant.add(participantVo); } competitionInfo.setParticipant(participant); if(one.getPayStatus() == 3){ competitionInfo.setStatus(4); } } return competitionInfo; } /** * 赛事报名 * @param uid * @param paymentCompetitionVo * @return * @throws Exception */ @Override public ResultUtil paymentCompetition(Integer uid, PaymentCompetitionVo paymentCompetitionVo) throws Exception { AppUser appUser = appUserClient.queryAppUser(uid); String[] split = paymentCompetitionVo.getIds().split(";"); Competition competition = this.getById(paymentCompetitionVo.getId()); BigDecimal money = null; if(paymentCompetitionVo.getPayType() == 1 || paymentCompetitionVo.getPayType() == 2){ money = new BigDecimal(competition.getCashPrice()).multiply(new BigDecimal(split.length)).setScale(2, RoundingMode.HALF_EVEN); } if(paymentCompetitionVo.getPayType() == 3){//玩湃币 money = new BigDecimal(competition.getPlayPaiCoin()).multiply(new BigDecimal(split.length)).setScale(2, RoundingMode.HALF_EVEN); if(money.compareTo(new BigDecimal(appUser.getPlayPaiCoins())) > 0){ return ResultUtil.error("报名失败,玩湃币不足,请充值"); } } if(paymentCompetitionVo.getPayType() == 4){//课程 money = new BigDecimal(competition.getClassPrice()).multiply(new BigDecimal(split.length)).setScale(2, RoundingMode.HALF_EVEN); for (String s : split) { Participant participant = participantService.getById(s); Student student = studentClient.queryStudentByPhone(participant.getPhone()); if(null == student){ return ResultUtil.error(participant.getName() + "不是学员,无法使用课时支付。"); } Integer integer = coursePackagePaymentClient.queryResidueClassHour(student.getId()); if(new BigDecimal(integer).compareTo(new BigDecimal(competition.getClassPrice())) < 0){ return ResultUtil.error(participant.getName() + "剩余课时不足,无法完成支付。"); } } } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); PaymentCompetition paymentCompetition = new PaymentCompetition(); String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); paymentCompetition.setCode(code); paymentCompetition.setCompetitionId(paymentCompetitionVo.getId()); paymentCompetition.setAppUserId(uid); paymentCompetition.setPayType(paymentCompetitionVo.getPayType()); paymentCompetition.setAmount(money.doubleValue()); paymentCompetition.setPayStatus(1); paymentCompetition.setState(1); paymentCompetition.setInsertTime(new Date()); paymentCompetitionService.save(paymentCompetition); for (String s : split) { UserCompetition userCompetition = new UserCompetition(); userCompetition.setAppUserId(uid); userCompetition.setCompetitionId(paymentCompetitionVo.getId()); userCompetition.setParticipantId(Integer.valueOf(s)); userCompetition.setPaymentCompetitionId(paymentCompetition.getId()); userCompetition.setInsertTime(new Date()); userCompetitionService.save(userCompetition); } if(paymentCompetitionVo.getPayType() == 1){//微信 return weChatPaymentCompetition(code, money); } if(paymentCompetitionVo.getPayType() == 2){//支付宝 return aliPaymentCompetition(code, money); } if(paymentCompetitionVo.getPayType() == 3){//玩湃币 appUser.setPlayPaiCoins(appUser.getPlayPaiCoins() - money.intValue()); appUserClient.updateAppUser(appUser); paymentCompetition = paymentCompetitionService.getById(paymentCompetition.getId()); paymentCompetition.setAppUserId(null); paymentCompetition.setPayStatus(2); paymentCompetition.setPayTime(new Date()); paymentCompetition.setPayOrderNo(""); paymentCompetitionService.updateById(paymentCompetition); competition.setApplicantsNumber(competition.getApplicantsNumber() + 1); this.updateById(competition); } if(paymentCompetitionVo.getPayType() == 4){//课程 for (String s : split) { Participant participant = participantService.getById(s); Student student = studentClient.queryStudentByPhone(participant.getPhone()); PaymentDeductionClassHour paymentDeductionClassHour = new PaymentDeductionClassHour(); paymentDeductionClassHour.setId(student.getId()); paymentDeductionClassHour.setClassHour(competition.getClassPrice()); paymentDeductionClassHour.setCode(code); coursePackagePaymentClient.paymentDeductionClassHour(paymentDeductionClassHour); } paymentCompetition = paymentCompetitionService.getById(paymentCompetition.getId()); paymentCompetition.setAppUserId(null); paymentCompetition.setPayStatus(2); paymentCompetition.setPayTime(new Date()); paymentCompetition.setPayOrderNo(""); paymentCompetitionService.updateById(paymentCompetition); competition.setApplicantsNumber(competition.getApplicantsNumber() + 1); this.updateById(competition); } return ResultUtil.success(); } /** * 赛事微信支付 * @param code * @param money * @return * @throws Exception */ public ResultUtil weChatPaymentCompetition(String code, BigDecimal money) throws Exception{ ResultUtil weixinpay = payMoneyUtil.weixinpay("报名赛事", "", code, money.toString(), "/base/competition/weChatPaymentCompetitionCallback", "APP", ""); if(weixinpay.getCode() == 200){ new Thread(new Runnable() { @Override public void run() { try { int num = 1; int wait = 0; while (num <= 10){ int min = 5000; wait += (min * num); Thread.sleep(wait); PaymentCompetition paymentCompetition = paymentCompetitionService.getOne(new QueryWrapper().eq("code", code).eq("payType", 1)); if(paymentCompetition.getPayStatus() == 2){ break; } ResultUtil> resultUtil = payMoneyUtil.queryWXOrder(code, ""); if(resultUtil.getCode() == 200 && paymentCompetition.getPayStatus() == 1){ /** * SUCCESS—支付成功, * REFUND—转入退款, * NOTPAY—未支付, * CLOSED—已关闭, * REVOKED—已撤销(刷卡支付), * USERPAYING--用户支付中, * PAYERROR--支付失败(其他原因,如银行返回失败) */ Map data1 = resultUtil.getData(); String s = data1.get("trade_state"); String transaction_id = data1.get("transaction_id"); if("REFUND".equals(s) || "NOTPAY".equals(s) || "CLOSED".equals(s) || "REVOKED".equals(s) || "PAYERROR".equals(s) || num == 10){ paymentCompetition.setAppUserId(null); paymentCompetition.setState(3); userCompetitionService.remove(new QueryWrapper().eq("paymentCompetitionId", paymentCompetition.getId())); break; } if("SUCCESS".equals(s)){ paymentCompetition.setAppUserId(null); paymentCompetition.setPayStatus(2); paymentCompetition.setPayTime(new Date()); paymentCompetition.setPayOrderNo(transaction_id); paymentCompetitionService.updateById(paymentCompetition); break; } if("USERPAYING".equals(s)){ num++; } } } }catch (Exception e){ e.printStackTrace(); } } }).start(); } return weixinpay; } /** * 赛事支付宝支付 * @param code * @param money * @return * @throws Exception */ public ResultUtil aliPaymentCompetition(String code, BigDecimal money) throws Exception{ ResultUtil alipay = payMoneyUtil.alipay("报名赛事", "", "", code, money.toString(), "/base/competition/aliPaymentCompetitionCallback"); if(alipay.getCode() == 200){ new Thread(new Runnable() { @Override public void run() { try { int num = 1; int wait = 0; while (num <= 10){ int min = 5000; wait += (min * num); Thread.sleep(wait); PaymentCompetition paymentCompetition = paymentCompetitionService.getOne(new QueryWrapper().eq("code", code).eq("payType", 2)); if(paymentCompetition.getPayStatus() == 2){ break; } ResultUtil> resultUtil = payMoneyUtil.queryALIOrder(code); if(resultUtil.getCode() == 200 && paymentCompetition.getPayStatus() == 1){ /** * WAIT_BUYER_PAY(交易创建,等待买家付款)、 * TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、 * TRADE_SUCCESS(交易支付成功)、 * TRADE_FINISHED(交易结束,不可退款) */ Map data1 = resultUtil.getData(); String s = data1.get("tradeStatus"); String tradeNo = data1.get("tradeNo"); if("TRADE_CLOSED".equals(s) || "TRADE_FINISHED".equals(s) || num == 10){ paymentCompetition.setAppUserId(null); paymentCompetition.setState(3); userCompetitionService.remove(new QueryWrapper().eq("paymentCompetitionId", paymentCompetition.getId())); break; } if("TRADE_SUCCESS".equals(s)){ paymentCompetition.setAppUserId(null); paymentCompetition.setPayStatus(2); paymentCompetition.setPayTime(new Date()); paymentCompetition.setPayOrderNo(tradeNo); paymentCompetitionService.updateById(paymentCompetition); break; } if("WAIT_BUYER_PAY".equals(s)){ num++; } } } }catch (Exception e){ e.printStackTrace(); } } }).start(); } return alipay; } /** * 定时任务修改赛事状态 */ @Override public void taskSetStatus() { this.baseMapper.taskSetStatusStart(); this.baseMapper.taskSetStatusEnd(); } }