1
zj
2025-05-07 ad35d23bdd072d7179eb4bfcb588975f37a68f53
1
8 files modified
5 files added
223 ■■■■■ changed files
src/main/java/com/nq/controller/protol/UserController.java 12 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/dao/TransactionLogMapper.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/enums/EUserAssets.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/enums/TradeType.java 46 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/pojo/StockDz.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/pojo/TransactionLog.java 25 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/TransactionLogService.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/StockDzServiceImpl.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/TransactionLogServiceImpl.java 59 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserAssetsServices.java 30 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserPositionServiceImpl.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserRechargeServiceImpl.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/controller/protol/UserController.java
@@ -79,6 +79,9 @@
    @Autowired
    UserPositionMapper userPositionMapper;
    @Autowired
    TransactionLogService transactionLogService;
    private static final ThreadLocal<Boolean> orderCreated = ThreadLocal.withInitial(() -> false);
    private final Lock lock = new ReentrantLock();
@@ -291,7 +294,7 @@
                userPendingorderService.updateById(userPendingorder);
                iUserAssetsServices.availablebalanceChange(userPendingorder.getStockGid().equals("ST") ? userPendingorder.getStockGid() : "USD",
                        userPendingorder.getUserId(),
                        EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
                        EUserAssets.THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED,
                        userPendingorder.getOrderTotalPrice(), "", "");
                return ServerResponse.createBySuccess("撤销挂单成功",request);
            }
@@ -513,5 +516,10 @@
        return iApplyLeverServices.applyLever(applyLever,request);
    }
    @RequestMapping({"flowLog.do"})
    @ResponseBody
    public ServerResponse flowLog(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                  @RequestParam(value = "pageSize", defaultValue = "100") int pageSize,HttpServletRequest request) {
        return transactionLogService.flowLog(pageNum,pageSize,request);
    }
}
src/main/java/com/nq/dao/TransactionLogMapper.java
New file
@@ -0,0 +1,10 @@
package com.nq.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nq.pojo.TradingHour;
import com.nq.pojo.TransactionLog;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TransactionLogMapper extends BaseMapper<TransactionLog> {
}
src/main/java/com/nq/enums/EUserAssets.java
@@ -11,6 +11,7 @@
    CALCULATE_PROFIT_AND_LOSS("CALCULATE_PROFIT_AND_LOSS","计算盈亏"),
    CLOSE_POSITION_RETURN_SECURITY_DEPOSIT("CLOSE_POSITION_RETURN_SECURITY","平仓返回保证金"),
    THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED("THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED","挂单撤销返回保证金"),
    CLOSE_POSITION("CLOSE_POSITION","平仓"),
    CONSTRAINT_CLOSE_POSITION("CONSTRAINT_CLOSE_POSITION","强制平仓"),
    BUY("BUY","购买"),
@@ -25,7 +26,14 @@
    private String desc;
    public static EUserAssets fromString(String value) {
        for (EUserAssets eUserAssets : EUserAssets.values()) {
            if (eUserAssets.getCode().equalsIgnoreCase(value)) {
                return eUserAssets;
            }
        }
        throw new IllegalArgumentException("未知的交易类型: " + value);
    }
    EUserAssets(String code, String desc) {
        this.code = code;
        this.desc = desc;
src/main/java/com/nq/enums/TradeType.java
New file
@@ -0,0 +1,46 @@
package com.nq.enums;
/**
 * 交易类型
 */
public enum  TradeType {
    // 枚举常量
    BUY("买入"),
    SELL("卖出"),
    SERVICE_CHARGE("手续费"),
    TRANSFER("划转"),
    WITHDRAW("提现"),
    WITHDRAW_RETURN("提现返还"),
    DEPOSIT("存款");
    // 枚举常量对应的描述
    private String description;
    // 构造方法
    TradeType(String description) {
        this.description = description;
    }
    // 获取描述
    public String getDescription() {
        return description;
    }
    // 根据字符串获取对应的枚举值
    public static TradeType fromString(String value) {
        for (TradeType tradeType : TradeType.values()) {
            if (tradeType.name().equalsIgnoreCase(value)) {
                return tradeType;
            }
        }
        throw new IllegalArgumentException("未知的交易类型: " + value);
    }
    // 重写toString方法,返回描述
    @Override
    public String toString() {
        return this.description;
    }
}
src/main/java/com/nq/pojo/StockDz.java
@@ -56,7 +56,7 @@
    //价格
    private BigDecimal nowPrice;
    //  差价
    //  折扣价
    @TableField(exist = false)
    private BigDecimal priceSpread;
    //  百分比
src/main/java/com/nq/pojo/TransactionLog.java
New file
@@ -0,0 +1,25 @@
package com.nq.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
 * 用户交易流水
 */
@Data
public class TransactionLog {
    @TableId(type = IdType.AUTO,value = "id")
    private Integer id;                          // 交易日志的唯一标识符
    private Integer userId;                      // 用户 ID
    private String transactionType;          // 交易类型
    private String amount;               // 交易金额
    private String description;              // 交易描述
    private Date transactionTime;       // 交易时间
}
src/main/java/com/nq/service/TransactionLogService.java
New file
@@ -0,0 +1,16 @@
package com.nq.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nq.common.ServerResponse;
import com.nq.pojo.StockDz;
import com.nq.pojo.TransactionLog;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
public interface TransactionLogService extends IService<TransactionLog> {
    void add(Integer userId, String transactionType, String amount,String description);
    ServerResponse flowLog(int pageNum, int pageSize, HttpServletRequest request);
}
src/main/java/com/nq/service/impl/StockDzServiceImpl.java
@@ -63,7 +63,7 @@
        stockTypeDz.forEach(f->{
            String price = iPriceServices.getNowPrice(f.getStockCode()).toString();
            BigDecimal subtract = new BigDecimal(price).subtract(f.getNowPrice());
            f.setPriceSpread(subtract);
            f.setPriceSpread(f.getNowPrice());
            f.setNowPrice(new BigDecimal(price));
            f.setPriceSpreadPercentum(
                    subtract.divide(new BigDecimal(price), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100))
src/main/java/com/nq/service/impl/TransactionLogServiceImpl.java
New file
@@ -0,0 +1,59 @@
package com.nq.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nq.common.ServerResponse;
import com.nq.dao.TradingHourMapper;
import com.nq.dao.TransactionLogMapper;
import com.nq.pojo.TradingHour;
import com.nq.pojo.TransactionLog;
import com.nq.pojo.User;
import com.nq.pojo.UserPositionCheckDz;
import com.nq.service.ITradingHourService;
import com.nq.service.TransactionLogService;
import com.nq.utils.translate.GoogleTranslateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
@Service
public class TransactionLogServiceImpl extends ServiceImpl<TransactionLogMapper, TransactionLog> implements TransactionLogService {
    @Autowired
    UserServiceImpl userService;
    @Override
    public ServerResponse flowLog(int pageNum, int pageSize, HttpServletRequest request) {
        User user = this.userService.getCurrentRefreshUser(request);
        if(ObjectUtil.isEmpty(user)){
            return ServerResponse.createByErrorMsg("登录已失效,请重新登录!",request);
        }
        Page<TransactionLog> page = Page.of(pageNum, pageSize);
        Page<TransactionLog> pageList =  page(page,new LambdaQueryWrapper<TransactionLog>()
                .eq(TransactionLog::getUserId, user.getId())
                .orderByDesc(TransactionLog::getTransactionTime)
        );
        pageList.getRecords().forEach(f->{
           f.setTransactionType(new GoogleTranslateUtil().translate(f.getTransactionType(),request.getHeader("lang")));
           f.setDescription(new GoogleTranslateUtil().translate(f.getDescription(),request.getHeader("lang")));
        });
        return ServerResponse.createBySuccess(pageList);
    }
    @Override
    public void add(Integer userId, String transactionType, String amount, String description) {
        TransactionLog transactionLog = new TransactionLog();
        transactionLog.setUserId(userId);
        transactionLog.setTransactionType(transactionType);
        transactionLog.setAmount(amount);
        transactionLog.setDescription(description);
        transactionLog.setTransactionTime(new Date());
        save(transactionLog);
    }
}
src/main/java/com/nq/service/impl/UserAssetsServices.java
@@ -7,8 +7,10 @@
import com.nq.dao.*;
import com.nq.enums.EStockType;
import com.nq.enums.EUserAssets;
import com.nq.enums.TradeType;
import com.nq.pojo.*;
import com.nq.service.IUserAssetsServices;
import com.nq.service.TransactionLogService;
import com.nq.utils.KeyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,6 +53,8 @@
    @Autowired
    StockConfigMapper stockConfigMapper;
    @Autowired
    TransactionLogService transactionLogService;
    @Override
    public UserAssets assetsByTypeAndUserId(String accetType, Integer userId) {
        if(accetType.equals("SZHB")){
@@ -179,6 +183,22 @@
               userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
           }
            userAssets.setFreezeMoney(userAssets.getFreezeMoney().subtract(amount));
       }else  if(Objects.equals(eUserAssets.getCode(), EUserAssets.THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED.getCode())){
           if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){
               BigDecimal availableBalance = amount.subtract(userAssets.getAmountToBeCovered());
               availableBalance = availableBalance.subtract(userAssets.getHandlingChargeWritten());
               if(availableBalance.compareTo(BigDecimal.ZERO) >= 0){
                   userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(availableBalance));
                   userAssets.setAmountToBeCovered(BigDecimal.ZERO);
                   userAssets.setHandlingChargeWritten(BigDecimal.ZERO);
               }else{
                   BigDecimal amountToBeCovered = userAssets.getAmountToBeCovered().subtract(amount);
                   userAssets.setAmountToBeCovered(amountToBeCovered);
               }
           }else{
               userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
           }
           userAssets.setFreezeMoney(userAssets.getFreezeMoney().subtract(amount));
       }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.CALCULATE_PROFIT_AND_LOSS.getCode())){
           extracted(amount, userAssets);
       }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.TRANSFER.getCode())){
@@ -242,7 +262,15 @@
        moneyLog.setSymbol(EStockType.getEStockTypeByCode(accetType).getSymbol());
        moneyLog.setCreateTime(new Date());
        moneyLogMapper.insert(moneyLog);
        return userAssetsMapper.updateById(userAssets)>1;
        int update = userAssetsMapper.updateById(userAssets);
        if(update > 0){
            if(Objects.equals(eUserAssets.getCode(), EUserAssets.HANDLING_CHARGE.getCode())){
                amount = amount.negate();
            }
            transactionLogService.add(userId, eUserAssets.getDesc(),amount.toString(),eUserAssets.getDesc());
            return true;
        }
        return false;
    }
    @Override
src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -847,7 +847,7 @@
                    UserPositionVO userPositionVO = UserPointUtil.assembleUserPositionVO(position, nowPrice);
                    userPositionVO.setOrderTotalPrice(userPositionVO.getOrderTotalPrice().multiply(new BigDecimal(userPositionVO.getOrderLever())));
                    userPositionVO.setBuyOrderPrice(userPositionVO.getBuyOrderPrice().setScale(2, BigDecimal.ROUND_DOWN));
                    StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new LambdaQueryWrapper<StockSubscribe>()
                            .eq(StockSubscribe::getCode, userPositionVO.getStockCode()));
                    if (position.getSellOrderId() == null) {
src/main/java/com/nq/service/impl/UserRechargeServiceImpl.java
@@ -401,11 +401,11 @@
    public ServerResponse saveUserRecharge(Integer id, String amt, HttpServletRequest request){
        User user = this.userMapper.selectById(id);
        if (user == null) {
            return ServerResponse.createBySuccessMsg("请登录后操作",request);
            return ServerResponse.createByErrorMsg("请登录后操作",request);
        }
        List<UserRecharge> userRecharges = userRechargeMapper.selectList(new LambdaQueryWrapper<>(UserRecharge.class).eq(UserRecharge::getUserId, id).eq(UserRecharge::getOrderStatus, 0));
        if(CollectionUtils.isNotEmpty(userRecharges)){
            return ServerResponse.createBySuccessMsg("当前有未处理充值订单,请联系客服完成充值!",request);
            return ServerResponse.createByErrorMsg("当前有未处理充值订单,请联系客服完成充值!",request);
        }
        UserRecharge userRecharge = new UserRecharge();
        userRecharge.setUserId(user.getId());
src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java
@@ -7,6 +7,7 @@
import com.nq.enums.EConfigKey;
import com.nq.enums.EStockType;
import com.nq.enums.EUserAssets;
import com.nq.enums.TradeType;
import com.nq.pay.PayUtil;
import com.nq.pojo.*;
import com.nq.service.*;
@@ -100,6 +101,9 @@
    @Resource
    StockTimeSettingMapper stockTimeSettingMapper;
    @Autowired
    TransactionLogService transactionLogService;
    @Transactional
    public ServerResponse outMoney(String amt, String with_Pwd,String accsetType,String bankName,String bankNo,HttpServletRequest request) throws Exception {
@@ -369,6 +373,7 @@
            }
            int updateCount = userAssetsMapper.updateById(userAssets);
            if (updateCount > 0) {
                transactionLogService.add(user.getId(), TradeType.WITHDRAW_RETURN.getDescription(),userWithdraw.getWithAmt().toString(),EStockType.ST.getSymbol());
                log.info("提现失败,返还用户资金成功!");
            } else {
                log.error("返还用户资金出错,抛出异常");