Administrator
2025-04-20 c95812b953a54e60c916c8ca375101376f58de57
基础功能的单元测试完成
1 文件已重命名
16个文件已修改
8个文件已添加
681 ■■■■■ 已修改文件
src/main/java/com/taoke/autopay/dao/credit/ExchangeRateMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/credit/UserCreditBalanceMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/credit/CreditExchangeRecord.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/credit/CreditSetting.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/credit/ExchangeRate.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/credit/UserAlipayBinding.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/credit/UserCreditRecord.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/exception/UserCreditException.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/manager/UserCreditExchangeManager.java 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/manager/UserCreditManager.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/WxUserSettingServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/credit/CreditSettingServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/credit/ExchangeRateServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/credit/UserCreditBalanceServiceImpl.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/CreditSettingMapper.xml 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/UserCreditBalanceMapper.xml 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/credit/alipay_account_setting.html 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/credit/index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/credit/AlipayBindTest.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/credit/BalanceTest.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/credit/CreditExchangeTest.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/credit/CreditTest.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/credit/RateTest.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/credit/SettingTest.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/credit/ExchangeRateMapper.java
@@ -22,7 +22,7 @@
    @Builder
    public static class DaoQuery {
        public Long id;
        public ExchangeRate.ExchangeType exchangeType;
        public ExchangeRate.ExchangeRateType exchangeType;
        public Double rate;
        public Date minStartTime;
        public Date maxStartTime;
src/main/java/com/taoke/autopay/dao/credit/UserCreditBalanceMapper.java
@@ -15,6 +15,8 @@
    List<UserCreditBalance> list(@Param("query") DaoQuery query);
    List<UserCreditBalance>  listByIds(@Param("ids") List<Long> ids);
    long count(@Param("query") DaoQuery query);
    public static class DaoQuery {
src/main/java/com/taoke/autopay/entity/credit/CreditExchangeRecord.java
@@ -1,5 +1,6 @@
package com.taoke.autopay.entity.credit;
import lombok.experimental.Tolerate;
import org.springframework.data.annotation.Id;
import org.yeshi.utils.generater.mybatis.Table;
import java.math.BigDecimal;
@@ -58,6 +59,7 @@
    private Date updateTime; // 更新时间
    // 新增默认构造函数
    @Tolerate
    public CreditExchangeRecord() {
    }
src/main/java/com/taoke/autopay/entity/credit/CreditSetting.java
@@ -2,6 +2,7 @@
import lombok.Data;
import lombok.Builder;
import lombok.experimental.Tolerate;
import org.springframework.data.annotation.Id;
import org.yeshi.utils.generater.mybatis.Column;
import java.util.Date;
@@ -14,10 +15,23 @@
    // 枚举类型:积分设置类型
    public enum CreditSettingType {
        MINIMUM_EXCHANGE_AMOUNT, // 最低兑换金额
        DOUYIN_PAYMENT_SUCCESS_CREDITS, // 抖音支付成功积分
        KUAISHOU_PAYMENT_SUCCESS_CREDITS, // 快手支付成功积分
        DAILY_EXCHANGE_LIMIT // 每日兑换次数
        MINIMUM_EXCHANGE_AMOUNT("最低兑换金额"), // 最低兑换金额
        DOUYIN_PAYMENT_SUCCESS_CREDITS("抖音支付成功积分"), // 抖音支付成功积分
        KUAISHOU_PAYMENT_SUCCESS_CREDITS("快手支付成功积分"), // 快手支付成功积分
        DAILY_EXCHANGE_LIMIT("每日兑换次数"); // 每日兑换次数
        public String getDesc() {
            return desc;
        }
        private  String desc;
        private CreditSettingType(String desc){
            this.desc =desc;
        }
    }
    @Id
@@ -46,7 +60,7 @@
    @Column(name = "update_time")
    private Date updateTime; // 更新时间
    @Tolerate
    // 新增默认构造函数
    public CreditSetting() {
    }
src/main/java/com/taoke/autopay/entity/credit/ExchangeRate.java
@@ -1,6 +1,8 @@
package com.taoke.autopay.entity.credit;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;
import org.springframework.data.annotation.Id;
import org.yeshi.utils.generater.mybatis.Column;
import org.yeshi.utils.generater.mybatis.Table;
@@ -8,13 +10,19 @@
import java.math.BigDecimal;
import java.util.Date;
@Builder
@Data
@Table(value = "table_exchange_rate")
public class ExchangeRate {
    public enum ExchangeType {
    public enum ExchangeRateType {
        NEW_USER_EXCHANGE, // 新人兑换
        GENERAL_EXCHANGE   // 一般兑换
    }
    @Tolerate
    public ExchangeRate(){
    }
    @Id
@@ -22,7 +30,7 @@
    private Long id; // 主键ID
    @Column(name = "exchange_type")
    private ExchangeType exchangeType; // 兑换类型
    private ExchangeRateType exchangeType; // 兑换类型
    @Column(name = "rate")
    private BigDecimal rate; // 汇率
src/main/java/com/taoke/autopay/entity/credit/UserAlipayBinding.java
@@ -1,16 +1,24 @@
package com.taoke.autopay.entity.credit;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;
import org.springframework.data.annotation.Id;
import org.yeshi.utils.generater.mybatis.Column;
import org.yeshi.utils.generater.mybatis.Table;
import java.util.Date;
@Builder
@Data
@Table(value = "table_user_alipay_binding")
public class UserAlipayBinding {
    @Tolerate
    public UserAlipayBinding(){
    }
    @Id
    @Column(name = "id")
    private Long id; // 主键ID
src/main/java/com/taoke/autopay/entity/credit/UserCreditRecord.java
@@ -1,5 +1,6 @@
package com.taoke.autopay.entity.credit;
import lombok.experimental.Tolerate;
import org.yeshi.utils.generater.mybatis.Column;
import org.springframework.data.annotation.Id;
import java.math.BigDecimal;
@@ -51,6 +52,7 @@
    @Column(name = "update_time")
    private Date updateTime; // 更新时间
    @Tolerate
    // 新增默认构造函数
    public UserCreditRecord() {
    }
src/main/java/com/taoke/autopay/exception/UserCreditException.java
New file
@@ -0,0 +1,26 @@
package com.taoke.autopay.exception;
/**
 * @author hxh
 * @title: 积分异常
 * @description: 兑换异常
 * @date 2024/6/14 18:46
 */
public class UserCreditException extends  Exception{
    private int code;
    public int getCode() {
        return code;
    }
    public UserCreditException(int code, String msg){
        super(msg);
    }
    public UserCreditException(String msg){
        super(msg);
    }
}
src/main/java/com/taoke/autopay/manager/UserCreditExchangeManager.java
@@ -36,6 +36,9 @@
    @Resource
    private UserCreditRecordService userCreditRecordService;
    @Resource
    private UserCreditManager userCreditManager;
    /**
     * 用户积分兑换
     *
@@ -56,6 +59,8 @@
            throw new UserCreditExchangeException(UserCreditExchangeException.CODE_BALANCE_NOT_ENOUGH, "用户积分不足");
        }
        // 如果是红包兑换,判断用户兑换频率
        if (exchangeType == CreditExchangeRecord.ExchangeType.FUND_EXCHANGE) {
            checkRedPacketExchangeFrequency(userId);
@@ -74,8 +79,7 @@
            BigDecimal exchangeAmount = calculateExchangeAmount(request.getUid(), request.getConsumedCredits());
            exchangeRecord.setExchangeValue(exchangeAmount);
        }
        // 扣减用户积分
        userCreditBalanceService.decreaseCreditBalance(userId, request.getConsumedCredits());
        // 记录兑换记录
        exchangeRecord.setUid(userId);
        exchangeRecord.setExchangeType(exchangeType);
@@ -87,7 +91,18 @@
        exchangeRecord.setExchangeInfo2(alipayBindings.get(0).getAlipayAccount());
        exchangeRecord.setCreateTime(new Date());
        exchangeRecord.setUpdateTime(new Date());
        return userCreditExchangeRecordService.addExchangeRecord(exchangeRecord);
        userCreditExchangeRecordService.addExchangeRecord(exchangeRecord);
        // 扣减用户积分
        userCreditManager.decreaseCredit(UserCreditRecord.builder()
                .creditAmount(request.getConsumedCredits())
                .consumptionMethod(UserCreditRecord.ConsumptionMethod.EXCHANGE_RED_PACKET)
                .direction(UserCreditRecord.DIRECTION_CONSUME)
                .identifierId(exchangeRecord.getId()+"")
                .uid(exchangeRecord.getUid())
                .description("红包兑换")
                .build());
        return exchangeRecord.getId();
    }
    /**
@@ -177,7 +192,7 @@
     * @param credit
     * @return
     */
    private BigDecimal calculateExchangeAmount(Long uid, int credit) throws UserCreditExchangeException{
    public BigDecimal calculateExchangeAmount(Long uid, int credit) throws UserCreditExchangeException{
        long count =  userCreditExchangeRecordService.countExchangeRecords(CreditExchangeRecordMapper.DaoQuery.builder()
                .uid(uid).build());
        Date nowDate =  new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(System.currentTimeMillis(),"yyyyMMddHHmm"),"yyyyMMddHHmm"));
@@ -186,9 +201,10 @@
        if(count<=0){
            // 新人兑换
            List<ExchangeRate>  rates =  exchangeRateService.listExchangeRates(ExchangeRateMapper.DaoQuery.builder()
                            .exchangeType(ExchangeRate.ExchangeType.NEW_USER_EXCHANGE)
                            .minStartTime(nowDate)
                            .maxEndTime(nowDate)
                            .exchangeType(ExchangeRate.ExchangeRateType.NEW_USER_EXCHANGE)
                            .maxStartTime(nowDate)
                            .minEndTime(nowDate)
                            .count(Integer.MAX_VALUE)
                    .build());
            if(rates.isEmpty()) {
                throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON,"新人兑换汇率未设置");
@@ -197,15 +213,21 @@
        }else{
            // 老用户兑换
            List<ExchangeRate>  rates =  exchangeRateService.listExchangeRates(ExchangeRateMapper.DaoQuery.builder()
                    .exchangeType(ExchangeRate.ExchangeType.GENERAL_EXCHANGE)
                    .minStartTime(nowDate)
                    .maxEndTime(nowDate)
                    .exchangeType(ExchangeRate.ExchangeRateType.GENERAL_EXCHANGE)
                    .maxStartTime(nowDate)
                    .minEndTime(nowDate)
                    .count(Integer.MAX_VALUE)
                    .build());
            if(rates.isEmpty()) {
                throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON,"老用户兑换汇率未设置");
            }
            money = new BigDecimal(credit).multiply(rates.get(0).getRate()).setScale(2, RoundingMode.HALF_UP);
        }
        CreditSetting setting =  creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.MINIMUM_EXCHANGE_AMOUNT, nowDate);
        if(setting!=null&& new BigDecimal(setting.getValue()).compareTo(money)>0){
            throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON,String.format("兑换金额不能低于%s元",setting.getValue()));
        }
        return money;
    }
}
src/main/java/com/taoke/autopay/manager/UserCreditManager.java
@@ -1,14 +1,19 @@
package com.taoke.autopay.manager;
import com.taoke.autopay.entity.credit.CreditSetting;
import com.taoke.autopay.entity.credit.UserCreditBalance;
import com.taoke.autopay.entity.credit.UserCreditRecord;
import com.taoke.autopay.exception.UserCreditException;
import com.taoke.autopay.service.credit.CreditSettingService;
import com.taoke.autopay.service.credit.UserCreditBalanceService;
import com.taoke.autopay.service.credit.UserCreditRecordService;
import com.taoke.autopay.utils.TimeUtil;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
@Component
public class UserCreditManager {
@@ -18,6 +23,9 @@
    @Resource
    private UserCreditRecordService userCreditRecordService;
    @Resource
    private CreditSettingService creditSettingService;
    /**
@@ -54,4 +62,50 @@
       // 增加积分记录
        userCreditRecordService.addCreditRecord(creditRecord);
    }
    /**
     * 抖音订单支付记录
     * @param uid
     */
    @Transactional(rollbackFor = Exception.class)
    public void addDYOrderPayRecord(Long uid,String keyId) throws UserCreditException {
        CreditSetting setting =  creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.DOUYIN_PAYMENT_SUCCESS_CREDITS,new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(System.currentTimeMillis(),"yyyyMMddHHmm"),"yyyyMMddHHmm")));
        if(setting==null){
            throw new  UserCreditException("未配置抖音支付成功积分");
        }
        UserCreditRecord record =   UserCreditRecord.builder()
                .creditAmount(Integer.parseInt(setting.getValue()))
                .acquisitionMethod(UserCreditRecord.AcquisitionMethod.COMMAND_PAYMENT)
                .direction(UserCreditRecord.DIRECTION_GAIN)
                .identifierId(keyId)
                .uid(uid)
                .description("抖音代付")
                .build();
        increaseCredit(record);
    }
    /**
     * 快手订单支付成功增加积分
     * @param uid
     * @param keyId
     * @throws UserCreditException
     */
    @Transactional(rollbackFor = Exception.class)
    public void addKSOrderPayRecord(Long uid,String keyId) throws UserCreditException {
        CreditSetting setting =  creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.KUAISHOU_PAYMENT_SUCCESS_CREDITS,new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(System.currentTimeMillis(),"yyyyMMddHHmm"),"yyyyMMddHHmm")));
        if(setting==null){
            throw new  UserCreditException("未配置快手支付成功积分");
        }
        UserCreditRecord record = UserCreditRecord.builder()
                .creditAmount(Integer.parseInt(setting.getValue()))
                .acquisitionMethod(UserCreditRecord.AcquisitionMethod.COMMAND_PAYMENT)
                .direction(UserCreditRecord.DIRECTION_GAIN)
                .identifierId(keyId)
                .uid(uid)
                .description("快手代付")
                .build();
        increaseCredit(record);
    }
}
src/main/java/com/taoke/autopay/service/impl/WxUserSettingServiceImpl.java
@@ -1,6 +1,9 @@
package com.taoke.autopay.service.impl;
import javax.annotation.Resource;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.utils.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -9,6 +12,10 @@
import com.taoke.autopay.service.SystemConfigService;
import com.taoke.autopay.service.WxUserSettingService;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class WxUserSettingServiceImpl implements WxUserSettingService {
src/main/java/com/taoke/autopay/service/impl/credit/CreditSettingServiceImpl.java
@@ -17,6 +17,9 @@
    @Override
    public int addSetting(CreditSetting creditSetting) {
        if(creditSetting.getCreateTime()==null){
            creditSetting.setCreateTime(new Date());
        }
        return creditSettingMapper.insertSelective(creditSetting);
    }
src/main/java/com/taoke/autopay/service/impl/credit/ExchangeRateServiceImpl.java
@@ -6,6 +6,7 @@
import com.taoke.autopay.service.credit.ExchangeRateService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
@@ -16,6 +17,9 @@
    @Override
    public int addExchangeRate(ExchangeRate exchangeRate) {
        if(exchangeRate.getCreateTime()==null){
            exchangeRate.setCreateTime(new Date());
        }
        return exchangeRateMapper.insertSelective(exchangeRate);
    }
src/main/java/com/taoke/autopay/service/impl/credit/UserCreditBalanceServiceImpl.java
@@ -22,9 +22,12 @@
    @Override
    public void initializeCreditBalance(Long userId) {
        if(getCreditBalanceByUserId(userId)!=null){
            return;
        }
        UserCreditBalance userCreditBalance = new UserCreditBalance();
        userCreditBalance.setId(userId);
        userCreditBalance.setCreditBalance(BigDecimal.ZERO);
        userCreditBalance.setCreditBalance(0);
        userCreditBalance.setCreateTime(new Date());
        userCreditBalance.setUpdateTime(new Date());
        userCreditBalanceMapper.insert(userCreditBalance);
@@ -37,7 +40,7 @@
    @Override
    public Map<Long, UserCreditBalance> getCreditBalancesByUserIds(List<Long> userIds) {
        List<UserCreditBalance> userCreditBalances = userCreditBalanceMapper.selectByIds(userIds);
        List<UserCreditBalance> userCreditBalances = userCreditBalanceMapper.listByIds(userIds);
        Map<Long, UserCreditBalance> balanceMap = new HashMap<>();
        for (UserCreditBalance balance : userCreditBalances) {
            balanceMap.put(balance.getId(), balance);
@@ -50,19 +53,23 @@
    public void increaseCreditBalance(Long userId, int amount) {
        UserCreditBalance userCreditBalance = userCreditBalanceMapper.selectByPrimaryKeyForUpdate(userId);
        if (userCreditBalance != null) {
            userCreditBalance.setCreditBalance(userCreditBalance.getCreditBalance().add(amount));
            userCreditBalance.setUpdateTime(new Date());
            userCreditBalanceMapper.updateByPrimaryKeySelective(userCreditBalance);
            userCreditBalanceMapper.updateByPrimaryKeySelective(UserCreditBalance.builder()
                            .id(userCreditBalance.getId())
                            .creditBalance(userCreditBalance.getCreditBalance() + amount)
                            .updateTime(new Date())
                    .build());
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void decreaseCreditBalance(Long userId, int amount) {
        UserCreditBalance userCreditBalance = userCreditBalanceMapper.selectByPrimaryKeyForUpdate(userId);
        if (userCreditBalance != null) {
            userCreditBalance.setCreditBalance(userCreditBalance.getCreditBalance().subtract(amount));
            userCreditBalance.setUpdateTime(new Date());
            userCreditBalanceMapper.updateByPrimaryKeySelective(userCreditBalance);
            userCreditBalanceMapper.updateByPrimaryKeySelective(UserCreditBalance.builder()
                    .id(userCreditBalance.getId())
                    .creditBalance(userCreditBalance.getCreditBalance() - amount)
                    .updateTime(new Date())
                    .build());
        }
    }
}
src/main/resources/application.yml
@@ -1,3 +1,3 @@
spring:
  profiles:
    active: pro
    active: dev
src/main/resources/mapper/CreditSettingMapper.xml
@@ -85,58 +85,52 @@
        where id = #{id,jdbcType=BIGINT}
    </update>
    <select id="selectByType" resultMap="BaseResultMap" parameterType="com.taoke.autopay.entity.credit.CreditSetting.CreditSettingType">
    <select id="selectByType" resultMap="BaseResultMap">
        select 
        <include refid="Base_Column_List" />
        from table_credit_setting
        where type = #{type,jdbcType=VARCHAR}
    </select>
    <select id="list" resultMap="BaseResultMap" parameterType="com.taoke.autopay.dao.credit.CreditSettingMapper.DaoQuery">
    <sql id="listWhereSQL">
        <if test="query.id != null">and id = #{query.id,jdbcType=BIGINT}</if>
        <if test="query.type != null">and type = #{query.type,jdbcType=VARCHAR}</if>
        <if test="query.name != null">and name = #{query.name,jdbcType=VARCHAR}</if>
        <if test="query.value != null">and value = #{query.value,jdbcType=VARCHAR}</if>
        <if test="query.minStartTime != null">and start_time &gt;= #{query.minStartTime,jdbcType=TIMESTAMP}</if>
        <if test="query.maxStartTime != null">and start_time &lt; #{query.maxStartTime,jdbcType=TIMESTAMP}</if>
        <if test="query.minEndTime != null">and end_time &gt;= #{query.minEndTime,jdbcType=TIMESTAMP}</if>
        <if test="query.maxEndTime != null">and end_time &lt; #{query.maxEndTime,jdbcType=TIMESTAMP}</if>
        <if test="query.minCreateTime != null">and create_time &gt;= #{query.minCreateTime,jdbcType=TIMESTAMP}</if>
        <if test="query.maxCreateTime != null">and create_time &lt; #{query.maxCreateTime,jdbcType=TIMESTAMP}</if>
        <if test="query.minUpdateTime != null">and update_time &gt;= #{query.minUpdateTime,jdbcType=TIMESTAMP}</if>
        <if test="query.maxUpdateTime != null">and update_time &lt; #{query.maxUpdateTime,jdbcType=TIMESTAMP}</if>
    </sql>
    <select id="list" resultMap="BaseResultMap">
        select 
        <include refid="Base_Column_List" />
        from table_credit_setting
        <where>
            <if test="id != null">and id = #{id,jdbcType=BIGINT}</if>
            <if test="type != null">and type = #{type,jdbcType=VARCHAR}</if>
            <if test="name != null">and name = #{name,jdbcType=VARCHAR}</if>
            <if test="value != null">and value = #{value,jdbcType=VARCHAR}</if>
            <if test="minStartTime != null">and start_time &gt;= #{minStartTime,jdbcType=TIMESTAMP}</if>
            <if test="maxStartTime != null">and start_time &lt; #{maxStartTime,jdbcType=TIMESTAMP}</if>
            <if test="minEndTime != null">and end_time &gt;= #{minEndTime,jdbcType=TIMESTAMP}</if>
            <if test="maxEndTime != null">and end_time &lt; #{maxEndTime,jdbcType=TIMESTAMP}</if>
            <if test="minCreateTime != null">and create_time &gt;= #{minCreateTime,jdbcType=TIMESTAMP}</if>
            <if test="maxCreateTime != null">and create_time &lt; #{maxCreateTime,jdbcType=TIMESTAMP}</if>
            <if test="minUpdateTime != null">and update_time &gt;= #{minUpdateTime,jdbcType=TIMESTAMP}</if>
            <if test="maxUpdateTime != null">and update_time &lt; #{maxUpdateTime,jdbcType=TIMESTAMP}</if>
         <include refid="listWhereSQL" />
        </where>
        <if test="sortList != null and sortList.size() > 0">
        <if test="query.sortList != null and query.sortList.size() > 0">
            order by
            <foreach collection="sortList" item="sort" separator=",">
            <foreach collection="query.sortList" item="sort" separator=",">
                ${sort}
            </foreach>
        </if>
        <if test="start != null and count != null">
            limit #{start,jdbcType=BIGINT}, #{count,jdbcType=INTEGER}
        <if test="query.start != null and query.count != null">
            limit #{query.start,jdbcType=BIGINT}, #{query.count,jdbcType=INTEGER}
        </if>
    </select>
    <select id="count" resultType="long" parameterType="com.taoke.autopay.dao.credit.CreditSettingMapper.DaoQuery">
    <select id="count" resultType="long" >
        select count(*) 
        from table_credit_setting
        <where>
            <if test="id != null">and id = #{id,jdbcType=BIGINT}</if>
            <if test="type != null">and type = #{type,jdbcType=VARCHAR}</if>
            <if test="name != null">and name = #{name,jdbcType=VARCHAR}</if>
            <if test="value != null">and value = #{value,jdbcType=VARCHAR}</if>
            <if test="minStartTime != null">and start_time &gt;= #{minStartTime,jdbcType=TIMESTAMP}</if>
            <if test="maxStartTime != null">and start_time &lt; #{maxStartTime,jdbcType=TIMESTAMP}</if>
            <if test="minEndTime != null">and end_time &gt;= #{minEndTime,jdbcType=TIMESTAMP}</if>
            <if test="maxEndTime != null">and end_time &lt; #{maxEndTime,jdbcType=TIMESTAMP}</if>
            <if test="minCreateTime != null">and create_time &gt;= #{minCreateTime,jdbcType=TIMESTAMP}</if>
            <if test="maxCreateTime != null">and create_time &lt; #{maxCreateTime,jdbcType=TIMESTAMP}</if>
            <if test="minUpdateTime != null">and update_time &gt;= #{minUpdateTime,jdbcType=TIMESTAMP}</if>
            <if test="maxUpdateTime != null">and update_time &lt; #{maxUpdateTime,jdbcType=TIMESTAMP}</if>
            <include refid="listWhereSQL" />
        </where>
    </select>
src/main/resources/mapper/UserCreditBalanceMapper.xml
@@ -29,12 +29,12 @@
        <if test="query.id!=null">AND id = #{query.id}</if>
        <if test="query.creditBalance!=null">AND credit_balance = #{query.creditBalance}</if>
        <if test="query.minCreateTime!=null">AND create_time >= #{query.minCreateTime}</if>
        <if test="query.maxCreateTime!=null">AND create_time < #{query.maxCreateTime}</if>
        <if test="query.maxCreateTime!=null">AND create_time  <![CDATA[   <  ]]> #{query.maxCreateTime}</if>
        <if test="query.minUpdateTime!=null">AND update_time >= #{query.minUpdateTime}</if>
        <if test="query.maxUpdateTime!=null">AND update_time < #{query.maxUpdateTime}</if>
        <if test="query.maxUpdateTime!=null">AND update_time  <![CDATA[   <  ]]> #{query.maxUpdateTime}</if>
    </sql>
    <select id="list" resultMap="BaseResultMap" parameterType="com.taoke.autopay.dao.credit.UserCreditBalanceMapper.DaoQuery">
    <select id="list" resultMap="BaseResultMap" >
        select 
        <include refid="Base_Column_List" />
        from table_user_credit_balance
@@ -49,7 +49,18 @@
        limit #{query.start},#{query.count}
    </select>
    <select id="count" resultType="java.lang.Long" parameterType="com.taoke.autopay.dao.credit.UserCreditBalanceMapper.DaoQuery">
    <select id="listByIds" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from table_user_credit_balance
       <foreach collection="ids" item="id" open=" where ( "  close=")" separator=" OR ">
            id = #{id}
       </foreach>
    </select>
    <select id="count" resultType="java.lang.Long">
        select count(*) 
        from table_user_credit_balance
        where 1=1
src/main/resources/static/credit/alipay_account_setting.html
New file
@@ -0,0 +1,134 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>支付宝账号设置</title>
        <script>
            window.onresize = function() {
                document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
            };
            window.onresize();
        </script>
        <link rel="stylesheet" type="text/css" href="../layui/css/layui.css" />
        <link rel="stylesheet" type="text/css" href="css/common.css" />
        <script src="../js/jquery.min.js"></script>
        <script src="../js/vue.min.js"></script>
        <script src="../layui/layui.js"></script>
        <script src="js/http.js"></script>
        <style>
            body {
                background-color: #E0E0E0;
            }
            .item {
                margin-bottom: 1px;
                height: 0.89rem;
                display: flex;
                align-items: center;
                background-color: #FFF;
                padding: 0 0.3rem;
            }
            .item .title {
                font-size: 0.30rem;
                color: #000000;
                width: 2rem;
                text-align: left;
            }
            .item input {
                background-color: transparent;
                border: none;
                font-size: 0.30rem;
            }
            .btn {
                width: 6.50rem;
                height: 0.78rem;
                line-height: 0.78rem;
                background: #F6BDD3;
                border-radius: 0.39rem;
                margin: auto 0;
                border: none;
                color: #FFF;
                font-size: 0.36rem;
                margin-top: 1.59rem;
            }
            .active {
                background-color: #FF2B4B;
            }
        </style>
    </head>
    <body>
        <div id="container" style="text-align: center;">
            <div class="top-nav">
                <div @click="goBack"></div>
                <div>支付宝设置</div>
            </div>
            <div style="height: 0.82rem;"></div>
            <div class="item">
                <div class="title">姓&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名</div>
                <input type="text" id="alipayName" placeholder="输入你支付宝绑定的姓名" />
            </div>
            <div class="item">
                <div class="title">支付宝帐号</div>
                <input type="text" id="alipayAccount" placeholder="输入支付宝账号" />
            </div>
            <button class="btn active" @click="save">保存并提交</button>
        </div>
        <script>
            $(function() {
                var app = new Vue({
                    el: "#container",
                    methods: {
                        goBack: function() {
                            if (window.history.length > 1) {
                                window.history.back();
                            }
                        },
                        save: function() {
                            var account = $("#alipayAccount").val();
                            var name = $("#alipayName").val();
                            if (account.length <= 0) {
                                layer.msg("请输入账号");
                                return;
                            }
                            if (name.length <= 0) {
                                layer.msg("请输入名称");
                                return;
                            }
                            var index = layer.load();
                            http_util.post("/agentapi/admin/setAlipayAccount", {
                                alipayAccount: account,
                                alipayName: name
                            }, function(res) {
                                layer.close(index);
                                if (res.code == 0) {
                                    layer.msg("设置成功");
                                    app.goBack();
                                } else {
                                    layer.msg(res.msg);
                                }
                            }, function(res) {
                                layer.close(index);
                                layer.msg(res);
                            });
                        }
                    }
                });
            });
        </script>
    </body>
</html>
src/main/resources/static/credit/index.html
File was renamed from src/main/resources/static/credit.html
@@ -181,7 +181,7 @@
            },
            bindAlipay() {
                // 跳转到支付宝绑定页面
                window.location.href = '/static/agent/alipay_account_setting.html';
                window.location.href = '../agent/alipay_account_setting.html';
            }
        }
    });
src/test/java/com/taoke/autopay/credit/AlipayBindTest.java
New file
@@ -0,0 +1,34 @@
package com.taoke.autopay.credit;
import com.taoke.autopay.dao.credit.ExchangeRateMapper;
import com.taoke.autopay.entity.credit.ExchangeRate;
import com.taoke.autopay.entity.credit.UserAlipayBinding;
import com.taoke.autopay.service.credit.ExchangeRateService;
import com.taoke.autopay.service.credit.UserAlipayBindingService;
import com.taoke.autopay.utils.TimeUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@SpringBootTest
public class AlipayBindTest {
    @Resource
    private UserAlipayBindingService userAlipayBindingService;
    @Test
    public void bind(){
        userAlipayBindingService.addBinding(UserAlipayBinding.builder()
                        .uid(2L)
                        .alipayAccount("xxxxxxxx@qq.com")
                        .alipayName("xxxx")
                .build());
    }
}
src/test/java/com/taoke/autopay/credit/BalanceTest.java
New file
@@ -0,0 +1,37 @@
package com.taoke.autopay.credit;
import com.taoke.autopay.entity.credit.UserCreditBalance;
import com.taoke.autopay.service.credit.UserCreditBalanceService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Map;
@SpringBootTest
public class BalanceTest {
    @Resource
    private UserCreditBalanceService userCreditBalanceService;
    @Test
    public void init(){
        userCreditBalanceService.initializeCreditBalance(2L);
    }
    @Test
    public void test(){
        long uid = 2L;
        UserCreditBalance balance = userCreditBalanceService.getCreditBalanceByUserId(uid);
        System.out.println(balance);
        userCreditBalanceService.increaseCreditBalance(uid, 10);
        balance = userCreditBalanceService.getCreditBalanceByUserId(uid);
        userCreditBalanceService.decreaseCreditBalance(uid, 10);
        balance = userCreditBalanceService.getCreditBalanceByUserId(uid);
        System.out.println(balance);
        Map<Long, UserCreditBalance>  map=userCreditBalanceService.getCreditBalancesByUserIds(Arrays.asList(new Long[]{uid}));
        System.out.println(map);
    }
}
src/test/java/com/taoke/autopay/credit/CreditExchangeTest.java
New file
@@ -0,0 +1,38 @@
package com.taoke.autopay.credit;
import com.taoke.autopay.entity.credit.CreditExchangeRecord;
import com.taoke.autopay.exception.UserCreditException;
import com.taoke.autopay.exception.UserCreditExchangeException;
import com.taoke.autopay.manager.UserCreditExchangeManager;
import com.taoke.autopay.manager.UserCreditManager;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class CreditExchangeTest {
    @Resource
    private UserCreditExchangeManager userCreditExchangeManager;
    @Test
    public void exchangeCredit() throws  UserCreditExchangeException {
        userCreditExchangeManager.exchangeCredit(CreditExchangeRecord.builder()
                        .exchangeType(CreditExchangeRecord.ExchangeType.FUND_EXCHANGE)
                        .consumedCredits(100)
                        .uid(2L)
                .build());
    }
    @Test
    public void pass() throws UserCreditExchangeException {
        userCreditExchangeManager.approveExchange(2L);
    }
    @Test
    public void reject() throws UserCreditExchangeException {
        userCreditExchangeManager.rejectExchange(1L);
    }
}
src/test/java/com/taoke/autopay/credit/CreditTest.java
New file
@@ -0,0 +1,30 @@
package com.taoke.autopay.credit;
import com.taoke.autopay.entity.credit.CreditSetting;
import com.taoke.autopay.exception.UserCreditException;
import com.taoke.autopay.manager.UserCreditManager;
import com.taoke.autopay.service.credit.CreditSettingService;
import com.taoke.autopay.utils.TimeUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.Date;
@SpringBootTest
public class CreditTest {
    @Resource
    private UserCreditManager userCreditManager;
    @Test
    public void addDYOrder() throws UserCreditException {
        userCreditManager.addDYOrderPayRecord(2L,"123123123123");
    }
    @Test
    public void addKSOrder() throws UserCreditException {
        userCreditManager.addKSOrderPayRecord(2L,"12312312234312233");
    }
}
src/test/java/com/taoke/autopay/credit/RateTest.java
New file
@@ -0,0 +1,52 @@
package com.taoke.autopay.credit;
import com.taoke.autopay.dao.credit.ExchangeRateMapper;
import com.taoke.autopay.entity.credit.CreditSetting;
import com.taoke.autopay.entity.credit.ExchangeRate;
import com.taoke.autopay.service.credit.CreditSettingService;
import com.taoke.autopay.service.credit.ExchangeRateService;
import com.taoke.autopay.utils.TimeUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@SpringBootTest
public class RateTest {
    @Resource
    private ExchangeRateService exchangeRateService;
    @Test
    public void setRate(){
        exchangeRateService.addExchangeRate(ExchangeRate.builder()
                        .rate(new BigDecimal("0.03"))
                        .exchangeType(ExchangeRate.ExchangeRateType.NEW_USER_EXCHANGE)
                        .startTime(new Date(TimeUtil.convertToTimeTemp("19700101","yyyyMMdd")))
                        .endTime(new Date(TimeUtil.convertToTimeTemp("29990101","yyyyMMdd")))
                .build());
        exchangeRateService.addExchangeRate(ExchangeRate.builder()
                .rate(new BigDecimal("0.02"))
                .exchangeType(ExchangeRate.ExchangeRateType.GENERAL_EXCHANGE)
                .startTime(new Date(TimeUtil.convertToTimeTemp("19700101","yyyyMMdd")))
                .endTime(new Date(TimeUtil.convertToTimeTemp("29990101","yyyyMMdd")))
                .build());
    }
    @Test
    public void getSetting(){
        long uid = 2L;
        List<ExchangeRate> rateList =   exchangeRateService.listExchangeRates(ExchangeRateMapper.DaoQuery.builder()
                        .exchangeType(ExchangeRate.ExchangeRateType.NEW_USER_EXCHANGE)
                .build());
        System.out.println(rateList);
    }
}
src/test/java/com/taoke/autopay/credit/SettingTest.java
New file
@@ -0,0 +1,64 @@
package com.taoke.autopay.credit;
import com.taoke.autopay.entity.credit.CreditSetting;
import com.taoke.autopay.entity.credit.UserCreditBalance;
import com.taoke.autopay.service.credit.CreditSettingService;
import com.taoke.autopay.service.credit.UserCreditBalanceService;
import com.taoke.autopay.utils.TimeUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
@SpringBootTest
public class SettingTest {
    @Resource
    private CreditSettingService creditSettingService;
    @Test
    public void addSetting(){
//        creditSettingService.addSetting(CreditSetting.builder()
//                        .type(CreditSetting.CreditSettingType.MINIMUM_EXCHANGE_AMOUNT)
//                        .value("100")
//                        .startTime(new Date(TimeUtil.convertToTimeTemp("19700101","yyyyMMdd")))
//                        .endTime(new Date(TimeUtil.convertToTimeTemp("29990101","yyyyMMdd")))
//                        .name(CreditSetting.CreditSettingType.MINIMUM_EXCHANGE_AMOUNT.getDesc())
//                .build());
        creditSettingService.addSetting(CreditSetting.builder()
                .type(CreditSetting.CreditSettingType.DOUYIN_PAYMENT_SUCCESS_CREDITS)
                .value("2")
                .startTime(new Date(TimeUtil.convertToTimeTemp("19700101","yyyyMMdd")))
                .endTime(new Date(TimeUtil.convertToTimeTemp("29990101","yyyyMMdd")))
                .name(CreditSetting.CreditSettingType.DOUYIN_PAYMENT_SUCCESS_CREDITS.getDesc())
                .build());
        creditSettingService.addSetting(CreditSetting.builder()
                .type(CreditSetting.CreditSettingType.KUAISHOU_PAYMENT_SUCCESS_CREDITS)
                .value("3")
                .startTime(new Date(TimeUtil.convertToTimeTemp("19700101","yyyyMMdd")))
                .endTime(new Date(TimeUtil.convertToTimeTemp("29990101","yyyyMMdd")))
                .name(CreditSetting.CreditSettingType.KUAISHOU_PAYMENT_SUCCESS_CREDITS.getDesc())
                .build());
        creditSettingService.addSetting(CreditSetting.builder()
                .type(CreditSetting.CreditSettingType.DAILY_EXCHANGE_LIMIT)
                .value("1")
                .startTime(new Date(TimeUtil.convertToTimeTemp("19700101","yyyyMMdd")))
                .endTime(new Date(TimeUtil.convertToTimeTemp("29990101","yyyyMMdd")))
                .name(CreditSetting.CreditSettingType.DAILY_EXCHANGE_LIMIT.getDesc())
                .build());
    }
    @Test
    public void getSetting(){
        long uid = 2L;
        CreditSetting setting =   creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.MINIMUM_EXCHANGE_AMOUNT, new Date());
        System.out.println(setting);
    }
}