刘帅
2026-09-21 3f45e8fdfa31d7b764d60a7c0cb5dd11944ed418
cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java
@@ -12,8 +12,11 @@
import com.alipay.api.response.AlipayTradeOrderSettleResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRoyaltyRelationBindResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsh.account.dto.*;
import com.dsh.account.entity.*;
@@ -42,10 +45,7 @@
import com.dsh.account.model.vo.classDetails.RegisteredCourse;
import com.dsh.account.model.vo.classDetails.classInsVo.ClassInfoVo;
import com.dsh.account.model.vo.userBenefitDetail.*;
import com.dsh.account.service.IRefereeService;
import com.dsh.account.service.TAppGiftService;
import com.dsh.account.service.TAppUserService;
import com.dsh.account.service.UserIntegralChangesService;
import com.dsh.account.service.*;
import com.dsh.account.util.*;
import com.dsh.account.util.akeylogin.Md5Util;
import com.dsh.account.util.wx.WxV3PayConfig;
@@ -56,6 +56,7 @@
import com.dsh.account.vo.entity.YearData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
@@ -86,6 +87,10 @@
@Service
public class TAppUserServiceImpl extends ServiceImpl<TAppUserMapper, TAppUser> implements TAppUserService {
    private static final String SMS_COOLDOWN_KEY_PREFIX = "security:sms:cooldown:";
    private static final String SMS_PHONE_QUOTA_KEY_PREFIX = "security:sms:phone-quota:";
    private static final String SMS_IP_QUOTA_KEY_PREFIX = "security:sms:ip-quota:";
    @Resource
    private TStudentMapper tsmapper;
@@ -98,6 +103,15 @@
    @Autowired
    private RedisUtil redisUtil;
    @Value("${security.sms.cooldown-seconds:60}")
    private int smsCooldownSeconds;
    @Value("${security.sms.phone-max-per-day:5}")
    private int smsPhoneMaxPerDay;
    @Value("${security.sms.ip-max-per-day:10}")
    private int smsIpMaxPerDay;
    @Autowired
    private GDMapGeocodingUtil gdMapGeocodingUtil;
@@ -153,6 +167,8 @@
    @Resource
    private TAppUserMapper appUserMapper;
    @Autowired
    private UserAuditService userAuditService;
    @Autowired
    private TAppGiftService appGiftService;
@@ -162,6 +178,8 @@
    private String aliAppid = "2021004105665036";//支付宝appid
    // 默认头像
    private String headImg = "https://we-park-life.oss-cn-beijing.aliyuncs.com/img/f7fbeaed277a45ab9591b70dc5699cab.jpg";
    private String appPrivateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==";//支付宝开发者应用私钥
@@ -413,13 +431,31 @@
     * @throws Exception
     */
    @Override
    public ResultUtil getSMSCode(Integer type, String phone) throws Exception {
    public ResultUtil getSMSCode(Integer type, String phone, String clientIp) throws Exception {
        if (type == 2) {
            TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", phone).ne("state", 3));
            if (null != tAppUser) {
                return ResultUtil.error("账号已存在");
            }
        }
        String cooldownKey = SMS_COOLDOWN_KEY_PREFIX + phone;
        if (!redisUtil.setIfAbsent(cooldownKey, "1", smsCooldownSeconds)) {
            return ResultUtil.error("短信发送过于频繁,请稍后重试");
        }
        String phoneQuotaKey = SMS_PHONE_QUOTA_KEY_PREFIX + phone;
        if (!redisUtil.tryAcquireFixedWindow(phoneQuotaKey, smsPhoneMaxPerDay, 24 * 60 * 60)) {
            redisUtil.remove(cooldownKey);
            return ResultUtil.error("该手机号24小时内短信发送次数已达上限");
        }
        String ipQuotaKey = SMS_IP_QUOTA_KEY_PREFIX + clientIp;
        if (!redisUtil.tryAcquireFixedWindow(ipQuotaKey, smsIpMaxPerDay, 24 * 60 * 60)) {
            redisUtil.remove(cooldownKey);
            redisUtil.releaseFixedWindow(phoneQuotaKey);
            return ResultUtil.error("当前网络24小时内短信发送次数已达上限");
        }
        String numberRandom = UUIDUtil.getNumberRandom(6);
        String templateCode = "";
        if (type == 1 || type == 2) {
@@ -428,9 +464,29 @@
        if (type == 3 || type == 4) {
            templateCode = "SMS_160960014";
        }
        aLiSendSms.sendSms(phone, templateCode, "{\"code\":\"" + numberRandom + "\"}");
        redisUtil.setStrValue(phone, numberRandom, 300);
        return ResultUtil.success();
        boolean providerAccepted = false;
        try {
            String sendResult = aLiSendSms.sendSms(phone, templateCode, "{\"code\":\"" + numberRandom + "\"}");
            com.alibaba.fastjson.JSONObject response = com.alibaba.fastjson.JSONObject.parseObject(sendResult);
            if (response == null || !"OK".equalsIgnoreCase(response.getString("Code"))) {
                releaseSmsLimit(cooldownKey, phoneQuotaKey, ipQuotaKey);
                return ResultUtil.error("短信发送失败,请稍后重试");
            }
            providerAccepted = true;
            redisUtil.setStrValue(phone, numberRandom, 300);
            return ResultUtil.success();
        } catch (Exception e) {
            if (!providerAccepted) {
                releaseSmsLimit(cooldownKey, phoneQuotaKey, ipQuotaKey);
            }
            throw e;
        }
    }
    private void releaseSmsLimit(String cooldownKey, String phoneQuotaKey, String ipQuotaKey) {
        redisUtil.remove(cooldownKey);
        redisUtil.releaseFixedWindow(phoneQuotaKey);
        redisUtil.releaseFixedWindow(ipQuotaKey);
    }
    /**
@@ -463,8 +519,12 @@
        tAppUser.setProvinceCode("");
        tAppUser.setCity("");
        tAppUser.setCityCode("");
        tAppUser.setHeadImg(headImg);
        // 注册用户
        int insert = this.baseMapper.insert(tAppUser);
        String s = generateNickname(tAppUser.getId());
        tAppUser.setName(s);
        this.baseMapper.updateById(tAppUser);
        // 介绍有礼
        if (addAppUserVo.getReferralUserId() != null || ToolUtil.isNotEmpty(addAppUserVo.getInvitePhone())) {
            if (ToolUtil.isEmpty(addAppUserVo.getLat()) || ToolUtil.isEmpty(addAppUserVo.getLon())) {
@@ -552,6 +612,7 @@
            return ResultUtil.error("验证码无效", "");
        }
        TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", loginSMSCodeVo.getPhone()).ne("state", 3));
//        System.out.println(tAppUser.getId()+"!!!!!!!!");
        if (null == tAppUser) {
            tAppUser = new TAppUser();
            tAppUser.setCode(UUIDUtil.getNumberRandom(16));
@@ -559,13 +620,19 @@
            tAppUser.setPassword(Md5Util.MD5Encode("111111", null));
            tAppUser.setIsVip(0);
            tAppUser.setState(1);
            tAppUser.setHeadImg(headImg);
            tAppUser.setInsertTime(new Date());
            this.baseMapper.insert(tAppUser);
            String s = generateNickname(tAppUser.getId());
            tAppUser.setName(s);
            this.baseMapper.updateById(tAppUser);
        }
        if (tAppUser.getState() == 2) {
            return ResultUtil.error("您的账号已被冻结", "");
        }
        String token = getToken(tAppUser);
        System.out.println("token"+token);
        return ResultUtil.success(token);
    }
@@ -589,8 +656,7 @@
                tAppUser.setPassword(Md5Util.MD5Encode("111111", null));
                tAppUser.setIsVip(0);
//                tAppUser.setName(loginWechatVo.getNickname());
                tAppUser.setName("用户"+loginWechatVo.getPhone().substring(loginWechatVo.getPhone().length() - 4));
                tAppUser.setHeadImg(loginWechatVo.getHeadimgurl());
                tAppUser.setHeadImg(headImg);
                tAppUser.setGender(loginWechatVo.getSex());
                tAppUser.setState(1);
                tAppUser.setInsertTime(new Date());
@@ -599,6 +665,11 @@
                tAppUser.setCity("");
                tAppUser.setCityCode("");
                this.baseMapper.insert(tAppUser);
                // 设置用户昵称为用户+id 保留6位小数 补0
                String s = generateNickname(tAppUser.getId());
                tAppUser.setName(s);
                this.baseMapper.updateById(tAppUser);
            }
        }
        if (tAppUser.getState() == 2) {
@@ -624,6 +695,26 @@
        }
        return ResultUtil.success(map);
    }
    /**
     * 根据用户ID生成固定格式的昵称
     * @param userId 用户ID
     * @return 格式化的昵称
     */
    public static String generateNickname(Integer userId) {
        if (userId == null) {
            return null;
        }
        // 将用户ID转换为字符串
        String userIdStr = String.valueOf(userId);
        // 使用String.format确保总长度为6位,不足的前面补0
        String formattedId = String.format("%06d", Long.parseLong(userIdStr));
        // 返回"用户" + 格式化后的ID
        return "用户" + formattedId;
    }
    /**
     * 获取JWT token和存储个人信息
@@ -740,6 +831,9 @@
            Store s = null;
            Double d = 0D;
            for (Store store : stores) {
                if (store == null || !isValidCoordinate(store.getLon(), store.getLat())) {
                    continue;
                }
                Map<String, Double> distance = GeodesyUtil.getDistance(lon + "," + lat, store.getLon() + "," + store.getLat());
                Double wgs84 = distance.get("WGS84");
                if (s == null || d > wgs84) {
@@ -747,17 +841,34 @@
                    d = wgs84;
                }
            }
            joinPlayPaiVo.setName(s.getName());
            joinPlayPaiVo.setLon(s.getLon());
            joinPlayPaiVo.setLat(s.getLat());
            joinPlayPaiVo.setStoreId(s.getId());
            joinPlayPaiVo.setPhone(s.getPhone());
            joinPlayPaiVo.setProvince(s.getProvince());
            joinPlayPaiVo.setProvinceCode(s.getProvinceCode());
            joinPlayPaiVo.setCity(s.getCity());
            joinPlayPaiVo.setCityCode(s.getCityCode());
            if (s != null) {
                joinPlayPaiVo.setName(s.getName());
                joinPlayPaiVo.setLon(s.getLon());
                joinPlayPaiVo.setLat(s.getLat());
                joinPlayPaiVo.setStoreId(s.getId());
                joinPlayPaiVo.setPhone(s.getPhone());
                joinPlayPaiVo.setProvince(s.getProvince());
                joinPlayPaiVo.setProvinceCode(s.getProvinceCode());
                joinPlayPaiVo.setCity(s.getCity());
                joinPlayPaiVo.setCityCode(s.getCityCode());
            }
        }
        return joinPlayPaiVo;
    }
    private boolean isValidCoordinate(String lon, String lat) {
        if (ToolUtil.isEmpty(lon) || ToolUtil.isEmpty(lat)) {
            return false;
        }
        try {
            double longitude = Double.parseDouble(lon.trim());
            double latitude = Double.parseDouble(lat.trim());
            return Double.isFinite(longitude) && Double.isFinite(latitude)
                    && longitude >= -180 && longitude <= 180
                    && latitude >= -90 && latitude <= 90;
        } catch (NumberFormatException e) {
            return false;
        }
    }
    @Override
@@ -1277,6 +1388,34 @@
    @Override
    public ResultUtil<String> updateInfo(UpdateInfoDto dto, Integer uid) {
        TAppUser tAppUser = appUserMapper.selectById(uid);
        if (StringUtils.hasLength(dto.getName())){
            if (!tAppUser.getName().equals(dto.getName())){
                TUserAudit userAudit = userAuditService
                        .lambdaQuery().eq(TUserAudit::getType, 1)
                        .eq(TUserAudit::getAppUserId, tAppUser.getId())
                        .ne(TUserAudit::getState, 2).last("limit 1").one();
                if (userAudit!=null){
                    userAudit.setState(1);
                    userAudit.setName(dto.getName());
                    UpdateWrapper<TUserAudit> tUserAuditUpdateWrapper = new UpdateWrapper<>();
                    tUserAuditUpdateWrapper.eq("id",userAudit.getId());
                    tUserAuditUpdateWrapper.set("state",1);
                    tUserAuditUpdateWrapper.set("name",dto.getName());
                    tUserAuditUpdateWrapper.set("remarks",null);
                    tUserAuditUpdateWrapper.set("auditId",null);
                    tUserAuditUpdateWrapper.set("auditTime",null);
                    userAuditService.update(tUserAuditUpdateWrapper);
                }else{
                    TUserAudit tUserAudit = new TUserAudit();
                    tUserAudit.setAppUserId(tAppUser.getId());
                    tUserAudit.setName(dto.getName());
                    tUserAudit.setType(1);
                    tUserAudit.setInsertTime(new Date());
                    userAuditService.save(tUserAudit);
                }
            }
        }
        if (ToolUtil.isNotEmpty(dto.getName())) {
            tAppUser.setName(dto.getName());
        }
@@ -1293,6 +1432,7 @@
        if (ToolUtil.isNotEmpty(dto.getGender())) {
            tAppUser.setGender(dto.getGender());
        }
        tAppUser.setName(null);
        appUserMapper.updateById(tAppUser);
        return ResultUtil.success();
    }
@@ -1341,6 +1481,10 @@
    @Override
    @Transactional
    public synchronized ResultUtil productRedemptionOperation(Integer userIdFormRedis, GoodsExchangeVo exchangeType) {
        // 兼容前端历史参数 chooseCouponId,内部统一使用 couponId。
        if (exchangeType.getCouponId() == null && exchangeType.getChooseCouponId() != null) {
            exchangeType.setCouponId(exchangeType.getChooseCouponId());
        }
        ReturnModel returnModel = new ReturnModel();
        Long returnId = null;
        //如果是兑换优惠卷
@@ -1434,6 +1578,51 @@
                return ResultUtil.error("商品不存在");
            }
            BigDecimal cashAmount = merchandise.getCash() == null ? BigDecimal.ZERO : merchandise.getCash();
            // 门票优惠后的订单现金应付总额;支付参数必须使用该金额,不能再使用商品原价。
            BigDecimal ticketPayableCashAmount = null;
            UserCoupon usedCoupon = null;
            if (exchangeType.getGoodsType() == 3 && exchangeType.getCouponId() != null && exchangeType.getCouponId() != 0) {
                if (exchangeType.getExchangeType() == 1) {
                    return ResultUtil.error("积分兑换不能使用优惠券");
                }
                usedCoupon = userConponClient.queryUserCouponById(
                        new QueryUserCouponByIdAndUserId(exchangeType.getCouponId(), userIdFormRedis));
                if (usedCoupon == null || !Integer.valueOf(1).equals(usedCoupon.getStatus())) {
                    return ResultUtil.error("优惠券不可用");
                }
                Coupon coupon = userConponClient.queryCouponById(usedCoupon.getCouponId());
                if (coupon == null || coupon.getEndTime() == null || !coupon.getEndTime().after(new Date())) {
                    return ResultUtil.error("优惠券已过期");
                }
                if (Integer.valueOf(3).equals(coupon.getUseScope())
                        && (exchangeType.getStoreId() == null || !userConponClient.getCouponStoreIds(coupon.getId()).contains(exchangeType.getStoreId()))) {
                    return ResultUtil.error("该优惠券不适用于所选门店");
                }
                BigDecimal orderCash = cashAmount.multiply(BigDecimal.valueOf(exchangeType.getNums() == null ? 1 : exchangeType.getNums()));
                JSONObject rule = JSON.parseObject(coupon.getContent());
                if (Integer.valueOf(1).equals(coupon.getType())) {
                    BigDecimal condition = rule.getBigDecimal("conditionalAmount");
                    BigDecimal deduction = rule.getBigDecimal("deductionAmount");
                    if (condition == null || deduction == null || orderCash.compareTo(condition) < 0) {
                        return ResultUtil.error("该优惠券无法使用");
                    }
                    cashAmount = orderCash.subtract(deduction).max(BigDecimal.ZERO)
                            .divide(BigDecimal.valueOf(exchangeType.getNums() == null ? 1 : exchangeType.getNums()), 2, java.math.RoundingMode.HALF_UP);
                } else if (Integer.valueOf(2).equals(coupon.getType())) {
                    BigDecimal deduction = rule.getBigDecimal("conditionalAmount");
                    if (deduction == null || deduction.compareTo(BigDecimal.ZERO) <= 0) {
                        return ResultUtil.error("该优惠券无法使用");
                    }
                    // 代金券可覆盖全部订单金额,超出订单金额的部分不找零。
                    ticketPayableCashAmount = orderCash.subtract(deduction).max(BigDecimal.ZERO);
                    cashAmount = ticketPayableCashAmount
                            .divide(BigDecimal.valueOf(exchangeType.getNums() == null ? 1 : exchangeType.getNums()), 2, java.math.RoundingMode.HALF_UP);
                } else {
                    return ResultUtil.error("该优惠券不支持购买门票");
                }
            }
            TAppUser tAppUser = this.baseMapper.selectById(userIdFormRedis);
            if (merchandise.getUserPopulation() == 2) {
@@ -1458,6 +1647,9 @@
            } else {
                goodsNums = exchangeType.getNums();
            }
            BigDecimal cashPaymentAmount = ticketPayableCashAmount == null
                    ? cashAmount.multiply(BigDecimal.valueOf(goodsNums))
                    : ticketPayableCashAmount;
            TAppUser user = appUserService.getById(userIdFormRedis);
            if (merchandise.getIntegral() != null) {
@@ -1494,6 +1686,10 @@
            if (exchangeType.getExchangeType() == 1) {
                pointsMerchandise.setPayStatus(2);
                pointsMerchandise.setPaymentTime(new Date());
            } else if (cashPaymentAmount.compareTo(BigDecimal.ZERO) == 0) {
                // 优惠券将现金部分完全抵扣时,不能向第三方支付发起 0 元或原价支付。
                pointsMerchandise.setPayStatus(2);
                pointsMerchandise.setPaymentTime(new Date());
            } else {
                pointsMerchandise.setPayStatus(1);
            }
@@ -1508,26 +1704,37 @@
            pointsMerchandise.setCode(code);
            pointsMerchandise.setInsertTime(new Date());
            pointsMerchandise.setPayType(exchangeType.getExchangeType());
            pointsMerchandise.setUserCouponId(exchangeType.getGoodsType() == 3 ? exchangeType.getCouponId() : null);
            if (null != merchandise.getIntegral()) {
                pointsMerchandise.setIntegral(merchandise.getIntegral() * goodsNums);
            }
            if (exchangeType.getExchangeType() == 2 || exchangeType.getExchangeType() == 3) {
                pointsMerchandise.setCash(merchandise.getCash());
                pointsMerchandise.setCash(exchangeType.getGoodsType() == 3 ? cashPaymentAmount : cashAmount);
                pointsMerchandise.setCashPayType(exchangeType.getPayType());
            }
            Double m = new BigDecimal((merchandise.getIntegral() == null ? 0 : merchandise.getIntegral())).add((merchandise.getCash() == null ? BigDecimal.ZERO : merchandise.getCash())).doubleValue();
            Double m = new BigDecimal((merchandise.getIntegral() == null ? 0 : merchandise.getIntegral())).add(cashAmount).doubleValue();
            if ((m * goodsNums) == 0) {
                pointsMerchandise.setPayStatus(2);
                pointsMerchandise.setPaymentTime(new Date());
            }
            returnId = mcClient.saveDetailsUserPointMercase(pointsMerchandise);
            if (usedCoupon != null) {
                usedCoupon.setStatus(2);
                userConponClient.updateUserCoupon(usedCoupon);
            }
            if(goodsNums>1){
                System.err.println("购买商品数量"+goodsNums);
                List<UserPointsMerchandise> userPointsMerchandises = new ArrayList<>();
                for (int i = 1; i < goodsNums; i++) {
                    UserPointsMerchandise userPointsMerchandise = new UserPointsMerchandise();
                    BeanUtils.copyProperties(pointsMerchandise, userPointsMerchandise);
                    // 一笔订单只能关联一次优惠券,避免拆分门票后重复计入优惠金额。
                    userPointsMerchandise.setUserCouponId(null);
                    if (exchangeType.getGoodsType() == 3) {
                        // 门票拆单后仅首条保留订单总实付金额,避免支付/收入统计重复累加。
                        userPointsMerchandise.setCash(BigDecimal.ZERO);
                    }
                    userPointsMerchandises.add(userPointsMerchandise);
                }
                System.err.println("新增额外购买记录"+userPointsMerchandises);
@@ -1539,8 +1746,16 @@
                }
            }
            if ((m * goodsNums) == 0 && pointsMerchandise.getPayStatus() == 2) {
            if (pointsMerchandise.getPayStatus() == 2 && exchangeType.getExchangeType() != 1
                    && cashPaymentAmount.compareTo(BigDecimal.ZERO) == 0) {
                // 积分+现金商品被优惠券抵扣为零元时,仍需扣除积分;不等待支付回调。
                if (exchangeType.getExchangeType() == 2 && merchandise.getIntegral() != null
                        && merchandise.getIntegral() > 0
                        && !dealAppUserIntegral(userIdFormRedis, tAppUser, merchandise.getIntegral() * goodsNums)) {
                    return ResultUtil.error("用户积分不足!");
                }
                returnModel.setReturnId(returnId);
                returnModel.setPaySuccess(true);
                return ResultUtil.success(returnModel);
            }
@@ -1628,7 +1843,7 @@
                                            break;
                                        }
                                    }
                                    coursePackageOrder.setCashPayment(merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())));
                                    coursePackageOrder.setCashPayment(cashAmount.multiply(new BigDecimal(exchangeType.getStuIds().size())));
                                    coursePackageOrder.setPlayPaiCoin(merchandise.getIntegral() * exchangeType.getStuIds().size());
                                    coursePackageOrder.setPayUserType(1);
                                    coursePackageOrder.setPayStatus(1);
@@ -1638,20 +1853,22 @@
                                    coursePackageOrder.setInsertTime(new Date());
                                    coursePackageOrder.setOrderType(2);
                                    paymentClient.savePaymentCoursePackage(coursePackageOrder);
                                    return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                                    return WechatPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                                } else if (merchandise.getType() == 1) {
                                    return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                                    return WechatPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                                } else if (merchandise.getType() == 3) {
                                    return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                                    return WechatPayment(merchandise.getType(), cashPaymentAmount, code, merchandise.getId());
                                }
                            } catch (Exception e) {
                                return ResultUtil.runErr();
                            }
                        case 2:
                            if (merchandise.getType() == 2) {
                                return AlipayPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                                return AlipayPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                            } else if (merchandise.getType() == 3) {
                                return AlipayPayment(merchandise.getType(), cashPaymentAmount, code, merchandise.getId());
                            } else {
                                return AlipayPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                                return AlipayPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                            }
                        default:
                            break;
@@ -1662,18 +1879,22 @@
                        case 1:
                            try {
                                if (merchandise.getType() == 2) {
                                    return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                                    return WechatPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                                } else if (merchandise.getType() == 3) {
                                    return WechatPayment(merchandise.getType(), cashPaymentAmount, code, merchandise.getId());
                                } else {
                                    return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                                    return WechatPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                                }
                            } catch (Exception e) {
                                return ResultUtil.runErr();
                            }
                        case 2:
                            if (merchandise.getType() == 2) {
                                return AlipayPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                                return AlipayPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(exchangeType.getStuIds().size())), code, merchandise.getId());
                            } else if (merchandise.getType() == 3) {
                                return AlipayPayment(merchandise.getType(), cashPaymentAmount, code, merchandise.getId());
                            } else {
                                return AlipayPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                                return AlipayPayment(merchandise.getType(), cashAmount.multiply(new BigDecimal(goodsNums)), code, merchandise.getId());
                            }
                        default:
                            break;
@@ -1684,6 +1905,7 @@
            }
            returnModel.setReturnId(returnId);
            returnModel.setPaySuccess(pointsMerchandise.getPayStatus() == 2);
            return ResultUtil.success(returnModel);
        } catch (Exception e) {
            e.printStackTrace();
@@ -2038,7 +2260,20 @@
                }
            }).start();
        }
        return alipay;
        return appendPaySuccess(alipay);
    }
    /**
     * 支付宝、微信的成功响应仅表示已生成支付单,客户端仍需拉起第三方支付。
     */
    private ResultUtil appendPaySuccess(ResultUtil paymentResult) {
        JSONObject data = paymentResult.getData() == null ? new JSONObject()
                : JSON.parseObject(JSON.toJSONString(paymentResult.getData()));
        if (data == null) {
            data = new JSONObject();
        }
        data.put("paySuccess", false);
        return ResultUtil.getResult(paymentResult.getCode(), paymentResult.getMsg(), data);
    }
@@ -2060,7 +2295,7 @@
                        // 平台门票
                        ResultUtil weixinpay = payMoneyUtil.weixinpay(name, "", code, cash.toString(),
                                "/base/pointMer/exchangeGoodPaymentWeChatCallback", "APP", "");
                        return weixinpay;
                        return appendPaySuccess(weixinpay);
                    } else {
                        String s2 = storeClient.getmerchantNumberByOperatorId(store1.getOperatorId());
                        System.err.println("微信商户号" + s2);
@@ -2071,7 +2306,7 @@
                        ResultUtil weixinpay = payMoneyUtil.weixinpayV3(s2, name, code,
                                "/base/pointMer/exchangeGoodPaymentWeChatCallback1",
                                cash.toString());
                        return weixinpay;
                        return appendPaySuccess(weixinpay);
                    }
                }
                break;
@@ -2083,7 +2318,7 @@
                    // 平台课包
                    ResultUtil weixinpay = payMoneyUtil.weixinpay(name, "", code, cash.toString(),
                            "/base/pointMer/exchangeGoodPaymentWeChatCallback", "APP", "");
                    return weixinpay;
                    return appendPaySuccess(weixinpay);
                } else {
                    String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId());
                    System.err.println("微信商户号" + s2);
@@ -2094,7 +2329,7 @@
                    ResultUtil weixinpay = payMoneyUtil.weixinpayV3(s2, name, code,
                            "/base/pointMer/exchangeGoodPaymentWeChatCallback1",
                            cash.toString());
                    return weixinpay;
                    return appendPaySuccess(weixinpay);
                }
            case 3:
                if (!integers.isEmpty()) {
@@ -2103,7 +2338,7 @@
                        // 平台门票
                        ResultUtil weixinpay = payMoneyUtil.weixinpay(name, "", code, cash.toString(),
                                "/base/pointMer/exchangeGoodPaymentWeChatCallback", "APP", "");
                        return weixinpay;
                        return appendPaySuccess(weixinpay);
                    } else {
                        String s2 = storeClient.getmerchantNumberByOperatorId(store1.getOperatorId());
                        System.err.println("微信商户号" + s2);
@@ -2114,13 +2349,13 @@
                        ResultUtil weixinpay = payMoneyUtil.weixinpayV3(s2, name, code,
                                "/base/pointMer/exchangeGoodPaymentWeChatCallback1",
                                cash.toString());
                        return weixinpay;
                        return appendPaySuccess(weixinpay);
                    }
                } else {
                    // 平台门票
                    ResultUtil weixinpay = payMoneyUtil.weixinpay(name, "", code, cash.toString(),
                            "/base/pointMer/exchangeGoodPaymentWeChatCallback", "APP", "");
                    return weixinpay;
                    return appendPaySuccess(weixinpay);
                }
        }