package com.ym.mec.biz.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.DegreeRegistrationActivityDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.*;
import com.ym.mec.biz.service.SysUserCashAccountService;
import com.ym.mec.common.constant.CommonConstants;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.entity.HttpResponseResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.ym.mec.biz.dal.dto.PageInfoDegree;
import com.ym.mec.biz.dal.page.DegreeQueryInfo;
import com.ym.mec.biz.service.DegreeRegistrationService;
import com.ym.mec.biz.service.PayService;
import com.ym.mec.biz.service.StudentPaymentOrderService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.service.IdGeneratorService;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.util.collection.MapUtil;
import org.springframework.util.CollectionUtils;

@Service
public class DegreeRegistrationServiceImpl extends BaseServiceImpl<Integer, DegreeRegistration> implements DegreeRegistrationService {

    @Autowired
    private DegreeRegistrationDao degreeRegistrationDao;

    @Autowired
    private SporadicChargeInfoDao sporadicChargeInfoDao;

    @Autowired
    private IdGeneratorService idGeneratorService;

    @Autowired
    private StudentPaymentOrderService studentPaymentOrderService;

    @Autowired
    private StudentPaymentOrderDao studentPaymentOrderDao;

    @Autowired
    private SysConfigDao sysConfigDao;

    @Autowired
    private PayService payService;

    @Autowired
    private PracticeGroupSellPriceDao practiceGroupSellPriceDao;

    @Autowired
    private StudentDao studentDao;

    @Autowired
    private StudentPaymentOrderDetailDao studentPaymentOrderDetailDao;

    @Autowired
    private SysUserCashAccountService sysUserCashAccountService;

    @Override
    public BaseDAO<Integer, DegreeRegistration> getDAO() {
        return degreeRegistrationDao;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public HttpResponseResult pay(DegreeRegistrationActivityDto degreeRegistration) throws Exception {
        Student student = studentDao.getLocked(degreeRegistration.getUserId());

        List<DegreeRegistration> userLevelDegrees = degreeRegistrationDao.getUserLevelDegrees(degreeRegistration.getUserId(), ACTIVITY_TAG);
        long endLevelNum = userLevelDegrees.stream().filter(d -> Objects.nonNull(d.getSporadicId())&&d.getStatus().equals(2)).count();
        long ingLevelNum = userLevelDegrees.stream().filter(d -> Objects.nonNull(d.getSporadicId())&&d.getStatus().equals(1)).count();
        long endTheoryLevelNum = userLevelDegrees.stream().filter(d -> StringUtils.isNotBlank(d.getTheoryLevel())&&d.getStatus().equals(2)).count();
        long ingTheoryLevelNum = userLevelDegrees.stream().filter(d -> StringUtils.isNotBlank(d.getTheoryLevel())&&d.getStatus().equals(1)).count();

        if(Objects.nonNull(degreeRegistration.getSporadicId())&&endLevelNum>0){
            throw new BizException("您已报考过选择的考级项目");
        }
        if(StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())&&endTheoryLevelNum>0){
            throw new BizException("您已报考过选择的考级项目");
        }

        degreeRegistration.setActivityTag(ACTIVITY_TAG);

        Date nowDate = new Date();

        if(ACTIVITY_END_TIME.compareTo(nowDate)<0){
            throw new BizException("活动已截至");
        }

        String orderNo = idGeneratorService.generatorId("payment") + "";

        //获取收费项价格
        SporadicChargeInfo chargeInfo = null;
        if(Objects.nonNull(degreeRegistration.getSporadicId())){
            chargeInfo = sporadicChargeInfoDao.get(degreeRegistration.getSporadicId());
            if (chargeInfo == null || chargeInfo.getDelFlag().equals(1) || chargeInfo.getOpenFlag().equals(1)) {
                throw new BizException("你选的考试级别不存在");
            }

            if (!chargeInfo.getTitle().equals("一级") && !chargeInfo.getTitle().equals("二级") && StringUtils.equals("免考", degreeRegistration.getTheoryLevel())
                    && StringUtils.isBlank(degreeRegistration.getTheoryCert())) {
                throw new BizException("报考级别为“" + chargeInfo.getTitle() + "”且乐理级别是“免考”时,必须上传证书");
            }
            degreeRegistration.setLevel(chargeInfo.getTitle());
            degreeRegistration.setMoney(chargeInfo.getAmount());
        }else{
            degreeRegistration.setMoney(BigDecimal.ZERO);
        }

        List<String> courseInfos = new ArrayList<>();

        if("免考".equals(degreeRegistration.getTheoryLevel())){
            degreeRegistration.setTheoryLevel(null);
        }

        if(StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())){
            degreeRegistration.setOrderNo(orderNo);
            BigDecimal theoryMoney = BigDecimal.ZERO;
            switch (degreeRegistration.getTheoryLevel()) {
                case "一级":
                    theoryMoney = new BigDecimal(200);
                    break;
                case "二级":
                    theoryMoney = new BigDecimal(240);
                    break;
                case "三级":
                    theoryMoney = new BigDecimal(280);
                    break;
                case "四级":
                    theoryMoney = new BigDecimal(320);
                    break;
                case "免考":
                    break;
                default:
                    throw new BizException("您选择的乐理级别不存在，请核对");
            }
            degreeRegistration.setTheoryMoney(theoryMoney);
        }else{
            degreeRegistration.setTheoryMoney(BigDecimal.ZERO);
        }

        if(Objects.nonNull(degreeRegistration.getSporadicId())||StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())){
            degreeRegistration.setStatus(1);
            degreeRegistration.setCreateTime(nowDate);
            degreeRegistration.setUpdateTime(nowDate);
            degreeRegistrationDao.insert(degreeRegistration);

            List<DegreeRegistration> updateDegrees = new ArrayList<>();
            if(ingLevelNum>0||ingTheoryLevelNum>0){
                for (DegreeRegistration userLevelDegree : userLevelDegrees) {
                    if(Objects.nonNull(userLevelDegree.getSporadicId())&&Objects.nonNull(userLevelDegree.getSporadicId())){
                        userLevelDegree.setStatus(0);
                        updateDegrees.add(userLevelDegree);
                    }
                    if(Objects.nonNull(userLevelDegree.getTheoryLevel())&&StringUtils.isNotBlank(userLevelDegree.getTheoryLevel())){
                        userLevelDegree.setStatus(0);
                        updateDegrees.add(userLevelDegree);
                    }
                }
                if(!CollectionUtils.isEmpty(updateDegrees)){
                    degreeRegistrationDao.batchUpdate(updateDegrees);
                }
            }
        }

        BigDecimal additionCoursePrice = new BigDecimal("0");
        if(Objects.nonNull(degreeRegistration.getAdditionCourseInfo())){
            Map<CourseSchedule.CourseScheduleType, Integer> additionCourseInfo = degreeRegistration.getAdditionCourseInfo();
            PracticeGroupSellPrice practiceGroupSellPrice = practiceGroupSellPriceDao.get(degreeRegistration.getOrganId());
            if(Objects.isNull(practiceGroupSellPrice)){
                throw new BizException("该分部暂未参与此活动");
            }

            List<StudentPaymentOrderDetail> historyOrderDetails = studentPaymentOrderDetailDao.getWithUserAndOrderType(degreeRegistration.getUserId(), OrderTypeEnum.DEGREE_REGISTRATION);
            int historyVipNum = 0, historyPracticeNum = 0, historyHighNum = 0;
            for (StudentPaymentOrderDetail historyOrderDetail : historyOrderDetails) {
                if(StringUtils.isBlank(historyOrderDetail.getGoodsIdList())){
                    continue;
                }
                Map<String, Integer> courseNumMap = JSON.parseObject(historyOrderDetail.getGoodsIdList(), Map.class);
                for (Map.Entry<String, Integer> stringIntegerEntry : courseNumMap.entrySet()) {
                    switch (stringIntegerEntry.getKey()){
                        case "VIP":
                            historyVipNum = historyVipNum + stringIntegerEntry.getValue();
                            break;
                        case "PRACTICE":
                            historyPracticeNum = historyPracticeNum + stringIntegerEntry.getValue();
                            break;
                        case "HIGH":
                            historyHighNum = historyHighNum + stringIntegerEntry.getValue();
                            break;
                    }
                }
            }

            BigDecimal practiceUnitPrice = practiceGroupSellPrice.getOnceOriginalPrice(),
                    vipUnitPrice = practiceGroupSellPrice.getVipOneStudentTwelveCourseActivityPriceWithNewUser(), highUnitPrice;

            if(additionCourseInfo.containsKey(CourseSchedule.CourseScheduleType.HIGH)){
                historyHighNum = historyHighNum + additionCourseInfo.get(CourseSchedule.CourseScheduleType.HIGH);
            }
            if(student.getIsNewUser()){
                highUnitPrice = practiceGroupSellPrice.getHighOnlineTenCourseOriginalPriceWithNewUser();
                if(additionCourseInfo.containsKey(CourseSchedule.CourseScheduleType.VIP)){
                    historyVipNum = historyVipNum + additionCourseInfo.get(CourseSchedule.CourseScheduleType.VIP);
                }
                if(historyVipNum<=0){
                    additionCourseInfo.remove(CourseSchedule.CourseScheduleType.PRACTICE);
                }
                boolean vipMoreThan2 = historyVipNum>=2;
                if(vipMoreThan2){
                    if(FREE_PRICE_LEVEL.contains(degreeRegistration.getLevel())){
                        degreeRegistration.setMoney(BigDecimal.ZERO);
                    }else{
                        degreeRegistration.setMoney(degreeRegistration.getMoney().divide(new BigDecimal(2), CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN));
                    }
                    highUnitPrice = practiceGroupSellPrice.getHighOnlineTenCourseActivityPriceWithNewUser();
                }
                if(vipMoreThan2&&historyHighNum>0){
                    degreeRegistration.setTheoryMoney(BigDecimal.ZERO);
                }
            }else{
                highUnitPrice = practiceGroupSellPrice.getHighOnlineTenCourseActivityPriceWithOldUser();
                if(historyHighNum<=0){
                    additionCourseInfo.remove(CourseSchedule.CourseScheduleType.PRACTICE);
                }
            }
            for (Map.Entry<CourseSchedule.CourseScheduleType, Integer> courseScheduleTypeIntegerEntry : additionCourseInfo.entrySet()) {
                BigDecimal courseTime = new BigDecimal(courseScheduleTypeIntegerEntry.getValue());
                switch (courseScheduleTypeIntegerEntry.getKey()){
                    case VIP:
                        BigDecimal vipPrice = vipUnitPrice.multiply(courseTime);
                        additionCoursePrice = additionCoursePrice.add(vipPrice);
                        courseInfos.add((courseTime.multiply(new BigDecimal(12)))+"节VIP-1V1课程费用：" + vipPrice);
                        break;
                    case PRACTICE:
                        BigDecimal practicePrice = practiceUnitPrice.multiply(courseTime);
                        additionCoursePrice = additionCoursePrice.add(practicePrice);
                        courseInfos.add((courseTime.multiply(new BigDecimal(12)))+"节1V1网管课课程费用：" + practicePrice);
                        break;
                    case HIGH:
                        BigDecimal highPrice = highUnitPrice.multiply(courseTime);
                        additionCoursePrice = additionCoursePrice.add(highPrice);
                        courseInfos.add((courseTime.multiply(new BigDecimal(10)))+"节乐理课程费用：" + highPrice);
                        break;
                }
            }
        }

        BigDecimal amount = degreeRegistration.getMoney();
        amount = amount.add(degreeRegistration.getTheoryMoney());
        amount = amount.add(additionCoursePrice);

        if(amount.compareTo(degreeRegistration.getPrice())!=0){
            throw new BizException("商品价格不符");
        }

        OrderTypeEnum type = OrderTypeEnum.DEGREE_REGISTRATION;

        Integer userId = degreeRegistration.getUserId();
        String channelType = "";
        StudentPaymentOrder studentPaymentOrder = new StudentPaymentOrder();
        studentPaymentOrder.setUserId(userId);
        studentPaymentOrder.setGroupType(GroupType.SPORADIC);
        studentPaymentOrder.setOrderNo(orderNo);
        studentPaymentOrder.setType(type);
        studentPaymentOrder.setExpectAmount(amount);
        studentPaymentOrder.setActualAmount(amount);
        studentPaymentOrder.setStatus(DealStatusEnum.ING);
        studentPaymentOrder.setClassGroupId(degreeRegistration.getId());
        if(Objects.nonNull(degreeRegistration.getSporadicId())){
            studentPaymentOrder.setMusicGroupId(degreeRegistration.getSporadicId().toString());
        }
        studentPaymentOrder.setOrganId(degreeRegistration.getOrganId());
        studentPaymentOrder.setRoutingOrganId(degreeRegistration.getOrganId());
        if(Objects.nonNull(degreeRegistration.getSporadicId())){
            courseInfos.add("乐器" + degreeRegistration.getLevel() + ",费用：" + degreeRegistration.getMoney());
        }
        if (StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())) {
            courseInfos.add("乐理" + degreeRegistration.getTheoryLevel() + ",费用：" + degreeRegistration.getTheoryMoney());
        }
        studentPaymentOrder.setMemo(StringUtils.join(courseInfos, "；"));
        studentPaymentOrderService.insert(studentPaymentOrder);
        studentPaymentOrder.setVersion(0);

        if(BigDecimal.ZERO.compareTo(additionCoursePrice)<0){
            StudentPaymentOrderDetail studentPaymentOrderDetail = new StudentPaymentOrderDetail();
            studentPaymentOrderDetail.setType(OrderDetailTypeEnum.DEGREE_REGISTRATION);
            if(Objects.nonNull(degreeRegistration.getAdditionCourseInfo())){
                studentPaymentOrderDetail.setGoodsIdList(JSON.toJSONString(degreeRegistration.getAdditionCourseInfo()));
            }
            studentPaymentOrderDetail.setPrice(additionCoursePrice);
            studentPaymentOrderDetail.setRemitFee(BigDecimal.ZERO);
            studentPaymentOrderDetail.setPaymentOrderId(studentPaymentOrder.getId());
            studentPaymentOrderDetail.setCreateTime(nowDate);
            studentPaymentOrderDetail.setUpdateTime(nowDate);
            studentPaymentOrderDetailDao.insert(studentPaymentOrderDetail);
        }

        if (amount.compareTo(BigDecimal.ZERO) == 0) {
            Map<String, String> notifyMap = new HashMap<>();
            notifyMap.put("tradeState", "1");
            notifyMap.put("merOrderNo", studentPaymentOrder.getOrderNo());
            notifyMap.put("channelType", channelType);
            notifyMap.put("orderNo", "");
            studentPaymentOrderService.updateOrder(notifyMap);
            return BaseController.failed(HttpStatus.CREATED, "恭喜您,支付成功!");
        }

        String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");

        String receiver = "kjRegister";
        Map payMap = payService.getPayMap(
                amount,
                BigDecimal.ZERO,
                orderNo,
                baseApiUrl + "/api-student/studentOrder/notify",
                baseApiUrl + "/api-student/studentOrder/paymentResult?orderNo=" + orderNo,
                Objects.nonNull(chargeInfo)?chargeInfo.getDetail():"考级报名活动",
                Objects.nonNull(chargeInfo)?chargeInfo.getDetail():"考级报名活动",
                degreeRegistration.getOrganId(),
                receiver
        );

        studentPaymentOrder.setOrganId(degreeRegistration.getOrganId());
        studentPaymentOrder.setMerNos((String) payMap.get("routingMerNos"));
        studentPaymentOrder.setPaymentChannel((String) payMap.get("type"));
        studentPaymentOrder.setUpdateTime(nowDate);
        studentPaymentOrderService.update(studentPaymentOrder);
        return BaseController.succeed(payMap);
    }



    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public HttpResponseResult theoryPay(DegreeRegistrationActivityDto degreeRegistration) throws Exception {
        studentDao.getLocked(degreeRegistration.getUserId());

        List<DegreeRegistration> userLevelDegrees = degreeRegistrationDao.getUserLevelDegrees(degreeRegistration.getUserId(), ACTIVITY_TAG);

        long endTheoryLevelNum = userLevelDegrees.stream().filter(d -> StringUtils.isNotBlank(d.getTheoryLevel())&&d.getStatus().equals(2)).count();
        long ingTheoryLevelNum = userLevelDegrees.stream().filter(d -> StringUtils.isNotBlank(d.getTheoryLevel())&&d.getStatus().equals(1)).count();

        if(StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())&&endTheoryLevelNum>0){
            throw new BizException("您已报考过选择的考级项目");
        }

        degreeRegistration.setActivityTag(ACTIVITY_TAG);

        Date nowDate = new Date();

        if(ACTIVITY_END_TIME.compareTo(nowDate)<0){
            throw new BizException("活动已截至");
        }

        String orderNo = idGeneratorService.generatorId("payment") + "";

        degreeRegistration.setMoney(BigDecimal.ZERO);

        List<String> courseInfos = new ArrayList<>();

        if("免考".equals(degreeRegistration.getTheoryLevel())){
            degreeRegistration.setTheoryLevel(null);
        }

        if(StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())){
            degreeRegistration.setOrderNo(orderNo);
            BigDecimal theoryMoney = BigDecimal.ZERO;
            switch (degreeRegistration.getTheoryLevel()) {
                case "一级":
                    theoryMoney = new BigDecimal(200);
                    break;
                case "二级":
                    theoryMoney = new BigDecimal(240);
                    break;
                case "三级":
                    theoryMoney = new BigDecimal(280);
                    break;
                case "四级":
                    theoryMoney = new BigDecimal(320);
                    break;
                default:
                    throw new BizException("您选择的乐理级别不存在，请核对");
            }
            degreeRegistration.setTheoryMoney(theoryMoney);
        }else{
            degreeRegistration.setTheoryMoney(BigDecimal.ZERO);
        }

        if(Objects.nonNull(degreeRegistration.getSporadicId())||StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())){
            degreeRegistration.setStatus(1);
            degreeRegistration.setCreateTime(nowDate);
            degreeRegistration.setUpdateTime(nowDate);
            degreeRegistrationDao.insert(degreeRegistration);

            List<DegreeRegistration> updateDegrees = new ArrayList<>();
            if(ingTheoryLevelNum>0){
                for (DegreeRegistration userLevelDegree : userLevelDegrees) {
                    if(Objects.nonNull(userLevelDegree.getSporadicId())&&Objects.nonNull(userLevelDegree.getSporadicId())){
                        userLevelDegree.setStatus(0);
                        updateDegrees.add(userLevelDegree);
                    }
                    if(Objects.nonNull(userLevelDegree.getTheoryLevel())&&StringUtils.isNotBlank(userLevelDegree.getTheoryLevel())){
                        userLevelDegree.setStatus(0);
                        updateDegrees.add(userLevelDegree);
                    }
                }
                if(!CollectionUtils.isEmpty(updateDegrees)){
                    degreeRegistrationDao.batchUpdate(updateDegrees);
                }
            }
        }

        BigDecimal additionCoursePrice = new BigDecimal("0");
        if(Objects.nonNull(degreeRegistration.getAdditionCourseInfo())){
            Map<CourseSchedule.CourseScheduleType, Integer> additionCourseInfo = degreeRegistration.getAdditionCourseInfo();
            PracticeGroupSellPrice practiceGroupSellPrice = practiceGroupSellPriceDao.get(degreeRegistration.getOrganId());
            if(Objects.isNull(practiceGroupSellPrice)){
                throw new BizException("该分部暂未参与此活动");
            }

            BigDecimal practiceUnitPrice = practiceGroupSellPrice.getOnceOriginalPrice(),
                    vipUnitPrice = practiceGroupSellPrice.getVipOneStudentTwelveCourseOriginalPriceWithNewUser(),
                    highUnitPrice = practiceGroupSellPrice.getHighOnlineTenCourseOriginalPriceWithNewUser();

            for (Map.Entry<CourseSchedule.CourseScheduleType, Integer> courseScheduleTypeIntegerEntry : additionCourseInfo.entrySet()) {
                BigDecimal courseTime = new BigDecimal(courseScheduleTypeIntegerEntry.getValue());
                switch (courseScheduleTypeIntegerEntry.getKey()){
                    case VIP:
                        BigDecimal vipPrice = vipUnitPrice.multiply(courseTime);
                        additionCoursePrice = additionCoursePrice.add(vipPrice);
                        courseInfos.add((courseTime.multiply(new BigDecimal(12)))+"节VIP-1V1课程费用：" + vipPrice);
                        break;
                    case PRACTICE:
                        BigDecimal practicePrice = practiceUnitPrice.multiply(courseTime);
                        additionCoursePrice = additionCoursePrice.add(practicePrice);
                        courseInfos.add((courseTime.multiply(new BigDecimal(12)))+"节1V1网管课课程费用：" + practicePrice);
                        break;
                    case HIGH:
                        BigDecimal highPrice = highUnitPrice.multiply(courseTime);
                        additionCoursePrice = additionCoursePrice.add(highPrice);
                        courseInfos.add((courseTime.multiply(new BigDecimal(10)))+"节乐理课程费用：" + highPrice);
                        break;
                }
            }
        }

        BigDecimal amount = degreeRegistration.getMoney();
        amount = amount.add(degreeRegistration.getTheoryMoney());
        amount = amount.add(additionCoursePrice);

        if(amount.compareTo(degreeRegistration.getPrice())!=0){
            throw new BizException("商品价格不符");
        }

        OrderTypeEnum type = OrderTypeEnum.DEGREE_REGISTRATION;

        Integer userId = degreeRegistration.getUserId();
        String channelType = "";
        StudentPaymentOrder studentPaymentOrder = new StudentPaymentOrder();
        studentPaymentOrder.setUserId(userId);
        studentPaymentOrder.setGroupType(GroupType.SPORADIC);
        studentPaymentOrder.setOrderNo(orderNo);
        studentPaymentOrder.setType(type);
        studentPaymentOrder.setExpectAmount(amount);
        studentPaymentOrder.setActualAmount(amount);
        studentPaymentOrder.setStatus(DealStatusEnum.ING);
        studentPaymentOrder.setClassGroupId(degreeRegistration.getId());
        if(Objects.nonNull(degreeRegistration.getSporadicId())){
            studentPaymentOrder.setMusicGroupId(degreeRegistration.getSporadicId().toString());
        }
        studentPaymentOrder.setOrganId(degreeRegistration.getOrganId());
        studentPaymentOrder.setRoutingOrganId(degreeRegistration.getOrganId());
        if (StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())) {
            courseInfos.add("乐理" + degreeRegistration.getTheoryLevel() + ",费用：" + degreeRegistration.getTheoryMoney());
        }
        studentPaymentOrder.setMemo(StringUtils.join(courseInfos, "；"));
        studentPaymentOrderService.insert(studentPaymentOrder);
        studentPaymentOrder.setVersion(0);

        if(BigDecimal.ZERO.compareTo(additionCoursePrice)<0){
            StudentPaymentOrderDetail studentPaymentOrderDetail = new StudentPaymentOrderDetail();
            studentPaymentOrderDetail.setType(OrderDetailTypeEnum.DEGREE_REGISTRATION);
            if(Objects.nonNull(degreeRegistration.getAdditionCourseInfo())){
                studentPaymentOrderDetail.setGoodsIdList(JSON.toJSONString(degreeRegistration.getAdditionCourseInfo()));
            }
            studentPaymentOrderDetail.setPrice(additionCoursePrice);
            studentPaymentOrderDetail.setRemitFee(BigDecimal.ZERO);
            studentPaymentOrderDetail.setPaymentOrderId(studentPaymentOrder.getId());
            studentPaymentOrderDetail.setCreateTime(nowDate);
            studentPaymentOrderDetail.setUpdateTime(nowDate);
            studentPaymentOrderDetailDao.insert(studentPaymentOrderDetail);
        }

        if (amount.compareTo(BigDecimal.ZERO) == 0) {
            Map<String, String> notifyMap = new HashMap<>();
            notifyMap.put("tradeState", "1");
            notifyMap.put("merOrderNo", studentPaymentOrder.getOrderNo());
            notifyMap.put("channelType", channelType);
            notifyMap.put("orderNo", "");
            studentPaymentOrderService.updateOrder(notifyMap);
            return BaseController.failed(HttpStatus.CREATED, "恭喜您,支付成功!");
        }

        String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");

        String receiver = "kjRegister";
        Map payMap = payService.getPayMap(
                amount,
                BigDecimal.ZERO,
                orderNo,
                baseApiUrl + "/api-student/studentOrder/notify",
                baseApiUrl + "/api-student/studentOrder/paymentResult?orderNo=" + orderNo,
                "乐理考级报名活动",
                "乐理考级报名活动",
                degreeRegistration.getOrganId(),
                receiver
        );

        studentPaymentOrder.setOrganId(degreeRegistration.getOrganId());
        studentPaymentOrder.setMerNos((String) payMap.get("routingMerNos"));
        studentPaymentOrder.setPaymentChannel((String) payMap.get("type"));
        studentPaymentOrder.setUpdateTime(nowDate);
        studentPaymentOrderService.update(studentPaymentOrder);
        return BaseController.succeed(payMap);
    }

    @Override
    public Boolean updateStatus(StudentPaymentOrder studentPaymentOrder) {
        DegreeRegistration degree = degreeRegistrationDao.getLock(studentPaymentOrder.getClassGroupId());

        int updateCount = studentPaymentOrderService.update(studentPaymentOrder);
        if (updateCount <= 0) {
            throw new BizException("订单更新失败");
        }

        if(DealStatusEnum.SUCCESS.equals(studentPaymentOrder.getStatus())){
            List<StudentPaymentOrderDetail> orderDetails = studentPaymentOrderDetailDao.getOrderDetail(studentPaymentOrder.getId());
            BigDecimal additionCoursePrice = new BigDecimal(0);
            if(!CollectionUtils.isEmpty(orderDetails)){
                additionCoursePrice = orderDetails.stream().map(StudentPaymentOrderDetail::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            if(additionCoursePrice.compareTo(BigDecimal.ZERO)>0){
                sysUserCashAccountService.appendCourseBalance(studentPaymentOrder.getUserId(), additionCoursePrice, PlatformCashAccountDetailTypeEnum.RECHARGE, "2020考级报名");
            }
        }

        if(Objects.isNull(studentPaymentOrder.getClassGroupId())){
            return true;
        }

        if (degree == null || !degree.getStatus().equals(1)) {
            studentPaymentOrder.setMemo("订单状态已变更");
            studentPaymentOrder.setVersion(studentPaymentOrder.getVersion()+1);
            studentPaymentOrderService.update(studentPaymentOrder);
            return true;
        }
        degree.setOrderNo(studentPaymentOrder.getOrderNo());
        degree.setTransNo(studentPaymentOrder.getTransNo());
        switch (studentPaymentOrder.getStatus()){
            case SUCCESS:
                degree.setStatus(2);
                break;
            case FAILED:
            case CLOSE:
                degree.setStatus(0);
                break;
        }
        degree.setUpdateTime(new Date());
        if (degreeRegistrationDao.update(degree) <= 0) {
            throw new BizException("更新支付状态失败");
        }
        return true;
    }

    @Override
    public PageInfoDegree<DegreeRegistration> getPageList(DegreeQueryInfo queryInfo) {
        PageInfoDegree<DegreeRegistration> pageInfo = new PageInfoDegree<>(queryInfo.getPage(), queryInfo.getRows());
        Map<String, Object> params = new HashMap<String, Object>();
        MapUtil.populateMap(params, queryInfo);

        List<DegreeRegistration> dataList = new ArrayList<>();
        int count = this.findCount(params);

        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = degreeRegistrationDao.queryPage(params);
            DegreeRegistration degree = degreeRegistrationDao.getTotalAmount(params);
            BigDecimal subjectLevelAmount = degree.getMoney() == null ? BigDecimal.ZERO : degree.getMoney();
            BigDecimal theoryLevelAmount = degree.getTheoryMoney() == null ? BigDecimal.ZERO : degree.getTheoryMoney();
            BigDecimal totalAmount = subjectLevelAmount.add(theoryLevelAmount);

            pageInfo.setSubjectLevelAmount(subjectLevelAmount);
            pageInfo.setTheoryLevelAmount(theoryLevelAmount);
            pageInfo.setTotalAmount(totalAmount);
        }
        pageInfo.setRows(dataList);
        return pageInfo;
    }
}
