puzhibing
2023-07-12 aa43a92c7ec9053dbaef92fe5ccb3011b670442c
cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
@@ -1,26 +1,42 @@
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;
/**
 * <p>
@@ -41,6 +57,21 @@
    @Autowired
    private UserCompetitionService userCompetitionService;
    @Autowired
    private IParticipantService participantService;
    @Resource
    private AppUserClient appUserClient;
    @Resource
    private StudentClient studentClient;
    @Resource
    private CoursePackagePaymentClient coursePackagePaymentClient;
    @Autowired
    private PayMoneyUtil payMoneyUtil;
@@ -65,19 +96,27 @@
     * @throws Exception
     */
    @Override
    public CompetitionInfo queryCompetitionInfo(Integer uid, Integer id) throws Exception {
    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());
        competitionInfo.setId(competition.getId().longValue());
        competitionInfo.setImgs(competition.getImgs());
        competitionInfo.setName(competition.getName());
        competitionInfo.setRegisterCondition(competition.getRegisterCondition());
        Store store = storeClient.queryStoreById(competition.getStoreId());
        competitionInfo.setStoreName(store.getName());
        competitionInfo.setStoreAddress(store.getAddress());
        competitionInfo.setStoreLon(store.getLon());
        competitionInfo.setStoreLat(store.getLat());
        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<String, Double> 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()));
@@ -90,15 +129,260 @@
        competitionInfo.setIntroduction(competition.getIntroduction());
        competitionInfo.setRegistrationNotes(competition.getRegistrationNotes());
        competitionInfo.setApply(0);
        PaymentCompetition one = paymentCompetitionService.getOne(new QueryWrapper<PaymentCompetition>().eq("competitionId", id).eq("appUserId", uid).eq("payStatus", 2));
        competitionInfo.setStatus(competition.getStatus());
        PaymentCompetition one = paymentCompetitionService.getOne(new QueryWrapper<PaymentCompetition>().eq("competitionId", id).eq("appUserId", uid).ne("payStatus", 1).orderByDesc("insertTime").last(" limit 1"));
        if(null != one){
            competitionInfo.setApply(1);
            List<ParticipantVo> participant = new ArrayList<>();
//            userCompetitionService.list(new QueryWrapper<UserCompetition>().eq("competitionId", id).eq(""))
            List<UserCompetition> list = userCompetitionService.list(new QueryWrapper<UserCompetition>().eq("paymentCompetitionId", one.getId()));
            List<Integer> collect = list.stream().map(UserCompetition::getParticipantId).collect(Collectors.toList());
            List<Participant> 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 = competition.getPrice().multiply(new BigDecimal(split.length)).setScale(2, RoundingMode.HALF_EVEN);
        if(paymentCompetitionVo.getPayType() == 3){//玩湃币
            if(money.compareTo(new BigDecimal(appUser.getPlayPaiCoins())) > 0){
                return ResultUtil.error("报名失败,玩湃币不足,请充值");
            }
        }
        if(paymentCompetitionVo.getPayType() == 4){//课程
            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(competition.getPrice()) < 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(competition.getPrice().multiply(new BigDecimal(split.length)).setScale(2, RoundingMode.HALF_EVEN).doubleValue());
        paymentCompetition.setPayStatus(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.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.getPrice().intValue());
                paymentDeductionClassHour.setCode(code);
                coursePackagePaymentClient.paymentDeductionClassHour(paymentDeductionClassHour);
            }
            paymentCompetition.setPayStatus(2);
            paymentCompetition.setPayTime(new Date());
            paymentCompetition.setPayOrderNo("");
            paymentCompetitionService.updateById(paymentCompetition);
            competition.setApplicantsNumber(competition.getApplicantsNumber() + 1);
            this.updateById(competition);
        }
        return ResultUtil.success();
    }
        return null;
    /**
     * 赛事微信支付
     * @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<PaymentCompetition>().eq("code", code).eq("payType", 1));
                            if(paymentCompetition.getPayStatus() == 2){
                                break;
                            }
                            ResultUtil<Map<String, String>> resultUtil = payMoneyUtil.queryWXOrder(code, "");
                            if(resultUtil.getCode() == 200 && paymentCompetition.getPayStatus() == 1){
                                /**
                                 * SUCCESS—支付成功,
                                 * REFUND—转入退款,
                                 * NOTPAY—未支付,
                                 * CLOSED—已关闭,
                                 * REVOKED—已撤销(刷卡支付),
                                 * USERPAYING--用户支付中,
                                 * PAYERROR--支付失败(其他原因,如银行返回失败)
                                 */
                                Map<String, String> 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.setState(3);
                                    userCompetitionService.remove(new QueryWrapper<UserCompetition>().eq("paymentCompetitionId", paymentCompetition.getId()));
                                    break;
                                }
                                if("SUCCESS".equals(s)){
                                    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<PaymentCompetition>().eq("code", code).eq("payType", 2));
                            if(paymentCompetition.getPayStatus() == 2){
                                break;
                            }
                            ResultUtil<Map<String, String>> resultUtil = payMoneyUtil.queryALIOrder(code);
                            if(resultUtil.getCode() == 200 && paymentCompetition.getPayStatus() == 1){
                                /**
                                 * WAIT_BUYER_PAY(交易创建,等待买家付款)、
                                 * TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、
                                 * TRADE_SUCCESS(交易支付成功)、
                                 * TRADE_FINISHED(交易结束,不可退款)
                                 */
                                Map<String, String> 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.setState(3);
                                    userCompetitionService.remove(new QueryWrapper<UserCompetition>().eq("paymentCompetitionId", paymentCompetition.getId()));
                                    break;
                                }
                                if("TRADE_SUCCESS".equals(s)){
                                    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();
    }
}