From ad35d23bdd072d7179eb4bfcb588975f37a68f53 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Wed, 07 May 2025 00:32:57 +0800
Subject: [PATCH] 1

---
 src/main/java/com/nq/service/impl/UserAssetsServices.java        |   30 +++++++
 src/main/java/com/nq/controller/protol/UserController.java       |   12 ++
 src/main/java/com/nq/pojo/TransactionLog.java                    |   25 ++++++
 src/main/java/com/nq/service/TransactionLogService.java          |   16 ++++
 src/main/java/com/nq/service/impl/UserPositionServiceImpl.java   |    2 
 src/main/java/com/nq/pojo/StockDz.java                           |    2 
 src/main/java/com/nq/dao/TransactionLogMapper.java               |   10 ++
 src/main/java/com/nq/service/impl/UserRechargeServiceImpl.java   |    4 
 src/main/java/com/nq/service/impl/StockDzServiceImpl.java        |    2 
 src/main/java/com/nq/service/impl/TransactionLogServiceImpl.java |   59 ++++++++++++++
 src/main/java/com/nq/enums/EUserAssets.java                      |   10 ++
 src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java   |    5 +
 src/main/java/com/nq/enums/TradeType.java                        |   46 +++++++++++
 13 files changed, 214 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/nq/controller/protol/UserController.java b/src/main/java/com/nq/controller/protol/UserController.java
index 8fcee31..50f1ea1 100644
--- a/src/main/java/com/nq/controller/protol/UserController.java
+++ b/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);
+    }
 }
diff --git a/src/main/java/com/nq/dao/TransactionLogMapper.java b/src/main/java/com/nq/dao/TransactionLogMapper.java
new file mode 100644
index 0000000..fb8f6d2
--- /dev/null
+++ b/src/main/java/com/nq/dao/TransactionLogMapper.java
@@ -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> {
+}
diff --git a/src/main/java/com/nq/enums/EUserAssets.java b/src/main/java/com/nq/enums/EUserAssets.java
index 25837d3..7406f56 100644
--- a/src/main/java/com/nq/enums/EUserAssets.java
+++ b/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;
diff --git a/src/main/java/com/nq/enums/TradeType.java b/src/main/java/com/nq/enums/TradeType.java
new file mode 100644
index 0000000..b79e73c
--- /dev/null
+++ b/src/main/java/com/nq/enums/TradeType.java
@@ -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;
+    }
+
+}
diff --git a/src/main/java/com/nq/pojo/StockDz.java b/src/main/java/com/nq/pojo/StockDz.java
index 49e519a..db370b8 100644
--- a/src/main/java/com/nq/pojo/StockDz.java
+++ b/src/main/java/com/nq/pojo/StockDz.java
@@ -56,7 +56,7 @@
     //价格
     private BigDecimal nowPrice;
 
-    //  差价
+    //  折扣价
     @TableField(exist = false)
     private BigDecimal priceSpread;
     //  百分比
diff --git a/src/main/java/com/nq/pojo/TransactionLog.java b/src/main/java/com/nq/pojo/TransactionLog.java
new file mode 100644
index 0000000..657691c
--- /dev/null
+++ b/src/main/java/com/nq/pojo/TransactionLog.java
@@ -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;       // 交易时间
+
+}
diff --git a/src/main/java/com/nq/service/TransactionLogService.java b/src/main/java/com/nq/service/TransactionLogService.java
new file mode 100644
index 0000000..f797386
--- /dev/null
+++ b/src/main/java/com/nq/service/TransactionLogService.java
@@ -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);
+}
diff --git a/src/main/java/com/nq/service/impl/StockDzServiceImpl.java b/src/main/java/com/nq/service/impl/StockDzServiceImpl.java
index 0188646..4e8067c 100644
--- a/src/main/java/com/nq/service/impl/StockDzServiceImpl.java
+++ b/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))
diff --git a/src/main/java/com/nq/service/impl/TransactionLogServiceImpl.java b/src/main/java/com/nq/service/impl/TransactionLogServiceImpl.java
new file mode 100644
index 0000000..e37c9a0
--- /dev/null
+++ b/src/main/java/com/nq/service/impl/TransactionLogServiceImpl.java
@@ -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);
+    }
+}
diff --git a/src/main/java/com/nq/service/impl/UserAssetsServices.java b/src/main/java/com/nq/service/impl/UserAssetsServices.java
index 20cc581..cad5d50 100644
--- a/src/main/java/com/nq/service/impl/UserAssetsServices.java
+++ b/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
diff --git a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
index 04a75f6..e1d8539 100644
--- a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
+++ b/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) {
diff --git a/src/main/java/com/nq/service/impl/UserRechargeServiceImpl.java b/src/main/java/com/nq/service/impl/UserRechargeServiceImpl.java
index 55a30d1..0567f1a 100644
--- a/src/main/java/com/nq/service/impl/UserRechargeServiceImpl.java
+++ b/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());
diff --git a/src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java b/src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java
index ce1f6ee..9337ee0 100644
--- a/src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java
+++ b/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("返还用户资金出错,抛出异常");

--
Gitblit v1.9.3