From 1e42d705a1f3f040c00e499e1bf42159c601aa40 Mon Sep 17 00:00:00 2001
From: zyy <zyy@email.com>
Date: Fri, 11 Jul 2025 16:21:36 +0800
Subject: [PATCH] AI产品交易

---
 src/main/java/com/nq/dao/StockAiOrderMapper.java           |   10 +
 src/main/java/com/nq/enums/EStockType.java                 |    2 
 src/main/java/com/nq/service/impl/UserAssetsServices.java  |   29 ++
 src/main/java/com/nq/pojo/StockAIOrderPosition.java        |   62 ++++++
 src/main/java/com/nq/controller/StockApiController.java    |    2 
 src/main/java/com/nq/enums/EStockAIStatus.java             |   20 ++
 src/main/java/com/nq/controller/StockInkApiController.java |   78 +++++++
 src/main/java/com/nq/pojo/StockAI.java                     |   57 +++++
 src/main/java/com/nq/enums/EStockAIOrderStatus.java        |   24 ++
 src/main/java/com/nq/service/IStockAiService.java          |   17 +
 src/main/java/com/nq/service/IUserAssetsServices.java      |   15 +
 src/main/java/com/nq/dao/StockAiMapper.java                |   10 +
 src/main/java/com/nq/enums/EUserAssets.java                |    5 
 src/main/java/com/nq/pojo/StockAIOrder.java                |   56 +++++
 src/main/java/com/nq/service/impl/StockAiServiceImpl.java  |  161 ++++++++++++++++
 15 files changed, 544 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/nq/controller/StockApiController.java b/src/main/java/com/nq/controller/StockApiController.java
index 99ecafa..54cb46d 100644
--- a/src/main/java/com/nq/controller/StockApiController.java
+++ b/src/main/java/com/nq/controller/StockApiController.java
@@ -1,7 +1,6 @@
 package com.nq.controller;
 
 import com.nq.common.ServerResponse;
-import com.nq.pojo.SiteSetting;
 import com.nq.service.IStockService;
 import com.nq.service.StockDzService;
 import org.slf4j.Logger;
@@ -152,4 +151,5 @@
                                              @RequestParam(value = "stockType", defaultValue = "US") String stockType) {
         return this.iStockService.getIndicesAndKData(pid, stockType);
     }
+
 }
diff --git a/src/main/java/com/nq/controller/StockInkApiController.java b/src/main/java/com/nq/controller/StockInkApiController.java
new file mode 100644
index 0000000..42faa99
--- /dev/null
+++ b/src/main/java/com/nq/controller/StockInkApiController.java
@@ -0,0 +1,78 @@
+package com.nq.controller;
+
+import com.nq.common.ServerResponse;
+import com.nq.service.IStockAiService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+@Controller
+@RequestMapping({"/api/lnk/"})
+public class StockInkApiController {
+
+    @Autowired
+    IStockAiService stockAiService;
+
+    private static final ThreadLocal<Boolean> buyOrderCreated = ThreadLocal.withInitial(() -> false);
+    private final Lock buyLock = new ReentrantLock();
+
+    /**
+     * 获取ai交易产品列表
+     * @return
+     */
+    @RequestMapping("getStockAiList.do")
+    @ResponseBody
+    public ServerResponse getStockAiList(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                         @RequestParam(value = "pageSize", defaultValue = "5") int pageSize)   {
+        return stockAiService.getStockAiList(pageNum, pageSize);
+    }
+
+    /**
+     * ai量化交易购买
+     * @param id
+     * @param buyNum  买入金额
+     * @return
+     */
+    @RequestMapping("buyStockAi.do")
+    @ResponseBody
+    public ServerResponse buyStockAi(@RequestParam(value = "id") Long id,
+                                     @RequestParam(value = "buyNum") BigDecimal buyNum, HttpServletRequest request) {
+        if (buyNum.compareTo(BigDecimal.ZERO) <= 0) {
+            return ServerResponse.createByErrorMsg("购买金额不能小于0");
+        }
+        buyLock.lock();
+        try {
+            if (buyOrderCreated.get()) {
+                return ServerResponse.createByErrorMsg("当前下单人数过多,请稍后重试");
+            }
+            buyOrderCreated.set(true);
+            return stockAiService.buyStockAi(id, buyNum, request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ServerResponse.createByErrorMsg("订单异常,请稍后重试");
+        }  finally{
+            buyLock.unlock();
+            buyOrderCreated.set(false);
+        }
+    }
+
+    /**
+     * 获取ai交易产品订单列表
+     * @return
+     */
+    @RequestMapping("getStockAiOrderList.do")
+    @ResponseBody
+    public ServerResponse getStockAiOrderList(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                              @RequestParam(value = "pageSize", defaultValue = "5") int pageSize,
+                                              @RequestParam(value = "status") String status,
+                                              HttpServletRequest request)   {
+        return stockAiService.getStockAiOrderList(pageNum, pageSize, status ,request);
+    }
+}
diff --git a/src/main/java/com/nq/dao/StockAiMapper.java b/src/main/java/com/nq/dao/StockAiMapper.java
new file mode 100644
index 0000000..0d4429c
--- /dev/null
+++ b/src/main/java/com/nq/dao/StockAiMapper.java
@@ -0,0 +1,10 @@
+package com.nq.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nq.pojo.StockAI;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface StockAiMapper extends BaseMapper<StockAI> {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/nq/dao/StockAiOrderMapper.java b/src/main/java/com/nq/dao/StockAiOrderMapper.java
new file mode 100644
index 0000000..8c54e67
--- /dev/null
+++ b/src/main/java/com/nq/dao/StockAiOrderMapper.java
@@ -0,0 +1,10 @@
+package com.nq.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nq.pojo.StockAIOrder;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface StockAiOrderMapper extends BaseMapper<StockAIOrder> {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/nq/enums/EStockAIOrderStatus.java b/src/main/java/com/nq/enums/EStockAIOrderStatus.java
new file mode 100644
index 0000000..a9f0b36
--- /dev/null
+++ b/src/main/java/com/nq/enums/EStockAIOrderStatus.java
@@ -0,0 +1,24 @@
+package com.nq.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum EStockAIOrderStatus {
+
+    //等待审核
+    wait("wait"),
+    //已通过
+    passed("passed"),
+    //不通过
+    notPass("notPass"),
+    //已完成
+    finished("finished"),
+    ;
+
+    private String status;
+
+    EStockAIOrderStatus(String status) {
+        this.status = status;
+    }
+
+}
diff --git a/src/main/java/com/nq/enums/EStockAIStatus.java b/src/main/java/com/nq/enums/EStockAIStatus.java
new file mode 100644
index 0000000..a3fce8e
--- /dev/null
+++ b/src/main/java/com/nq/enums/EStockAIStatus.java
@@ -0,0 +1,20 @@
+package com.nq.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum EStockAIStatus {
+
+    //上线
+    online("online"),
+    //下架
+    out("out"),
+    ;
+
+    private String value;
+
+    EStockAIStatus(String value) {
+        this.value = value;
+    }
+
+}
diff --git a/src/main/java/com/nq/enums/EStockType.java b/src/main/java/com/nq/enums/EStockType.java
index 73dde29..5713795 100644
--- a/src/main/java/com/nq/enums/EStockType.java
+++ b/src/main/java/com/nq/enums/EStockType.java
@@ -17,7 +17,7 @@
 //    MAS("MAS","马来西亚股票","42",PropertiesUtil.getProperty("MAS_HTTP_API"),PropertiesUtil.getProperty("MAS_KEY"),"MYR","RM"),
 //
 //    IN("IN","印度股票","14", PropertiesUtil.getProperty("JS_IN_HTTP_URL"),PropertiesUtil.getProperty("JS_IN_KEY"),"INR","₹"),
-    MX("MEX","墨西哥股票","7",PropertiesUtil.getProperty("MX_HTTP_API"),PropertiesUtil.getProperty("MX_KEY"),"MXN","MXN$");
+    MX("MEX","墨西哥股票","7",PropertiesUtil.getProperty("MX_HTTP_API"),PropertiesUtil.getProperty("MX_KEY"),"MXN","MX$");
 
 //    TH("TH","泰国股票","41",PropertiesUtil.getProperty("TH_HTTP_API"),PropertiesUtil.getProperty("TH_KEY")),
 //    HG("HG","韩国股票","11",PropertiesUtil.getProperty("HG_HTTP_API"),PropertiesUtil.getProperty("HG_KEY")),
diff --git a/src/main/java/com/nq/enums/EUserAssets.java b/src/main/java/com/nq/enums/EUserAssets.java
index 4036884..5341b6a 100644
--- a/src/main/java/com/nq/enums/EUserAssets.java
+++ b/src/main/java/com/nq/enums/EUserAssets.java
@@ -17,8 +17,9 @@
     WITHDRAW("WITHDRAW","提现"),
 
     TRANSFER("TRANSFER","转换"),
-    TOP_UP("TOP_UP","充值");
-
+    TOP_UP("TOP_UP","充值"),
+    BUY_AI("BUY_AI","购买AI产品"),
+    ;
 
     private String  code;
 
diff --git a/src/main/java/com/nq/pojo/StockAI.java b/src/main/java/com/nq/pojo/StockAI.java
new file mode 100644
index 0000000..a31dd5f
--- /dev/null
+++ b/src/main/java/com/nq/pojo/StockAI.java
@@ -0,0 +1,57 @@
+package com.nq.pojo;
+
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * AI产品表
+ */
+@Data
+@TableName("stock_ai")
+@Entity
+public class StockAI {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private String stockType;
+
+    private String stockName;
+
+    /**
+     * 最低买入金额
+     */
+    private BigDecimal minPrice;
+
+    /**
+     * 交易成功率
+     */
+    private BigDecimal successRate;
+
+    /**
+     * 预期收益率
+     */
+    private BigDecimal expectedEarning;
+
+    /**
+     * 周期 天
+     */
+    private Integer cycle;
+
+    /**
+     * 状态 上线 下架
+     */
+    private String status;
+
+    //创建时间
+    private Date createDate;
+}
\ No newline at end of file
diff --git a/src/main/java/com/nq/pojo/StockAIOrder.java b/src/main/java/com/nq/pojo/StockAIOrder.java
new file mode 100644
index 0000000..30206ea
--- /dev/null
+++ b/src/main/java/com/nq/pojo/StockAIOrder.java
@@ -0,0 +1,56 @@
+package com.nq.pojo;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * AI产品订单表
+ */
+@Data
+@TableName("stock_ai_order")
+@Entity
+public class StockAIOrder {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    //用户id
+    private Integer userId;
+
+    //ai交易产品id
+    private Long stockAiId;
+
+    //买入时间
+    private Date buyDate;
+
+    /**
+     * 买入金额
+     */
+    private BigDecimal buyAmount;
+
+    /**
+     * 剩余金额
+     */
+    private BigDecimal remainAmount;
+
+    /**
+     * 实际收益
+     */
+    private BigDecimal realEarning;
+
+    /**
+     * 状态 待审核 申请通过 申请通过 已完成
+     */
+    private String status;
+
+    //审核时间
+    private Date auditDate;
+}
diff --git a/src/main/java/com/nq/pojo/StockAIOrderPosition.java b/src/main/java/com/nq/pojo/StockAIOrderPosition.java
new file mode 100644
index 0000000..dc03b11
--- /dev/null
+++ b/src/main/java/com/nq/pojo/StockAIOrderPosition.java
@@ -0,0 +1,62 @@
+package com.nq.pojo;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * AI产品订单建仓表
+ */
+@Data
+@TableName("stock_ai_order_position")
+@Entity
+public class StockAIOrderPosition {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    //ai交易产品订单id
+    private Long stockAiOrderId;
+
+    //建仓股票id
+    private Integer stockId;
+
+    /**
+     * 建仓股票数量
+     */
+    private Long stockNum;
+
+    /**
+     * 建仓股票单价
+     */
+    private BigDecimal stockPrice;
+
+    /**
+     * 建仓时间
+     */
+    private Date creatDate;
+
+    /**
+     * 平仓单价
+     */
+    private BigDecimal coverPrice;
+
+    /**
+     * 平仓时间
+     */
+    private Date coverDate;
+
+    /**
+     * 收益 (平仓单价-建仓股票单价)*建仓股票数量
+     */
+    private BigDecimal earnings;
+
+
+}
diff --git a/src/main/java/com/nq/service/IStockAiService.java b/src/main/java/com/nq/service/IStockAiService.java
new file mode 100644
index 0000000..ae18d6a
--- /dev/null
+++ b/src/main/java/com/nq/service/IStockAiService.java
@@ -0,0 +1,17 @@
+package com.nq.service;
+
+import com.nq.common.ServerResponse;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+
+public interface IStockAiService {
+
+  ServerResponse getStockAiList(Integer pageNum, Integer pageSize);
+
+  ServerResponse buyStockAi(Long id, BigDecimal buyNum, HttpServletRequest request);
+
+  ServerResponse getStockAiOrderList(Integer pageNum, Integer pageSize, String status, HttpServletRequest request);
+
+}
diff --git a/src/main/java/com/nq/service/IUserAssetsServices.java b/src/main/java/com/nq/service/IUserAssetsServices.java
index ae7475a..ce8bd35 100644
--- a/src/main/java/com/nq/service/IUserAssetsServices.java
+++ b/src/main/java/com/nq/service/IUserAssetsServices.java
@@ -47,5 +47,20 @@
      * */
     Boolean availablebalanceChange(String accetType, Integer userId, EUserAssets eUserAssets, BigDecimal amount, String desc, String descType);
 
+    /**
+     * ai交易
+     * @param userAssets
+     * @param eUserAssets
+     * @param amount
+     * @return
+     */
+    Boolean aiAvailableBalanceChange(UserAssets userAssets, EUserAssets eUserAssets, BigDecimal amount);
 
+    /**
+     * 根据汇率转换金额
+     * @param amount    转换金额
+     * @param rate      转换汇率
+     * @return
+     */
+    BigDecimal exchangeAmountByRate(BigDecimal amount, BigDecimal rate);
 }
diff --git a/src/main/java/com/nq/service/impl/StockAiServiceImpl.java b/src/main/java/com/nq/service/impl/StockAiServiceImpl.java
new file mode 100644
index 0000000..b671859
--- /dev/null
+++ b/src/main/java/com/nq/service/impl/StockAiServiceImpl.java
@@ -0,0 +1,161 @@
+package com.nq.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.nq.Repository.ExchangeRateRepository;
+import com.nq.common.ServerResponse;
+import com.nq.dao.StockAiMapper;
+import com.nq.dao.StockAiOrderMapper;
+import com.nq.enums.*;
+import com.nq.pojo.*;
+import com.nq.service.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+@Service("iStockAiService")
+public class StockAiServiceImpl implements IStockAiService {
+    private static final Logger log = LoggerFactory.getLogger(StockAiServiceImpl.class);
+
+    @Autowired
+    StockAiMapper stockAiMapper;
+    @Autowired
+    StockAiOrderMapper stockAiOrderMapper;
+    @Autowired
+    ISiteProductService iSiteProductService;
+    @Autowired
+    IUserService iUserService;
+    @Autowired
+    IUserAssetsServices iUserAssetsServices;
+    @Autowired
+    ExchangeRateRepository exchangeRateRepository;
+
+    /**
+     * 获取上架ai产品
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ServerResponse getStockAiList(Integer pageNum, Integer pageSize) {
+        try {
+            PageHelper.startPage(pageNum, pageSize);
+            List<StockAI> stockAiList = stockAiMapper.selectList(new QueryWrapper<StockAI>().eq("status", EStockAIStatus.online.getValue()));
+            // 获取分页信息
+            PageInfo<StockAI> pageInfo = new PageInfo<>(stockAiList);
+            return ServerResponse.createBySuccess(pageInfo);
+        } catch (Exception ex) {
+            log.error("StockAiService getStockAiList error", ex);
+        }
+        return ServerResponse.createByError();
+    }
+
+    /**
+     * 购买ai产品
+     * @param id
+     * @param buyNum
+     * @return
+     */
+    @Override
+    @Transactional
+    public ServerResponse buyStockAi(Long id, BigDecimal buyNum, HttpServletRequest request) {
+        try {
+            User user = iUserService.getCurrentUser(request);
+            if (user == null ){
+                return ServerResponse.createBySuccessMsg("請先登錄");
+            }
+            synchronized (user.getId()){
+                SiteProduct siteProduct = iSiteProductService.getProductSetting();
+                if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) {
+                    return ServerResponse.createByErrorMsg("订单失败,请先实名认证", request);
+                }
+
+                if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) {
+                    return ServerResponse.createByErrorMsg("订单失败,帐户已被锁定", request);
+                }
+
+                StockAI stockAI = stockAiMapper.selectById(id);
+                if (stockAI == null) {
+                    return ServerResponse.createByErrorMsg("订单失败,AI股票不存在", request);
+                }
+
+                if(buyNum.compareTo(stockAI.getMinPrice()) < 0){
+                    return ServerResponse.createByErrorMsg("最低购买数量" + stockAI.getMinPrice(), request);
+                }
+                //获取用户账户
+                UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(EStockType.MX.getCode(), user.getId());
+                BigDecimal finalBuyNum = buyNum;    //购买金额
+                //如果不是墨西哥币需要转换金额
+                if (!stockAI.getStockType().equals(EStockType.US.getCode())) {
+                    EStockType stockType = EStockType.getEStockTypeByCode(stockAI.getStockType());
+                    ExchangeRate exchangeRate = exchangeRateRepository.findExchangeRateByCurrencyAndConversionCurrency(stockType.getSymbol(), EStockType.MX.getSymbol())
+                            .orElse(null);
+                    if (exchangeRate == null) {
+                        return ServerResponse.createByErrorMsg("当前货币汇率无法转换");
+                    }
+                    //转换为墨西哥币
+                    buyNum = iUserAssetsServices.exchangeAmountByRate(buyNum, exchangeRate.getRata());
+                }
+                if(buyNum.compareTo(userAssets.getAvailableBalance()) > 0){
+                    return ServerResponse.createByErrorMsg("可用余额不足" + userAssets.getAvailableBalance(), request);
+                }
+
+                if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){
+                    return ServerResponse.createByErrorMsg("请先缴清待补资金", request);
+                }
+
+                StockAIOrder stockAIOrder = new StockAIOrder();
+                stockAIOrder.setUserId(user.getId());
+                stockAIOrder.setStockAiId(id);
+                stockAIOrder.setBuyDate(new Date());
+                stockAIOrder.setBuyAmount(finalBuyNum);
+                stockAIOrder.setRemainAmount(finalBuyNum);
+                stockAIOrder.setRealEarning(BigDecimal.valueOf(0));
+                stockAIOrder.setStatus(EStockAIOrderStatus.wait.getStatus());   //等待审核
+                stockAiOrderMapper.insert(stockAIOrder);
+                iUserAssetsServices.aiAvailableBalanceChange(userAssets, EUserAssets.BUY_AI, buyNum);
+                return ServerResponse.createBySuccessMsg("下单成功", request);
+            }
+        } catch (Exception e) {
+            log.error("StockAiService buyStockAiList error", e);
+        }
+        return ServerResponse.createByError();
+    }
+
+    /**
+     * 获取ai产品订单
+     * @param pageNum
+     * @param pageSize
+     * @param status
+     * @param request
+     * @return
+     */
+    @Override
+    public ServerResponse getStockAiOrderList(Integer pageNum, Integer pageSize, String status, HttpServletRequest request) {
+        try {
+            User user = iUserService.getCurrentUser(request);
+            if (user == null ){
+                return ServerResponse.createBySuccessMsg("請先登錄");
+            }
+
+            PageHelper.startPage(pageNum, pageSize);
+            List<StockAIOrder> stockAIOrders = stockAiOrderMapper.selectList(new QueryWrapper<StockAIOrder>()
+                    .eq("user_id", user.getId())
+                    .eq(status != null && !status.isEmpty(), "status", status));
+            // 获取分页信息
+            PageInfo<StockAIOrder> pageInfo = new PageInfo<>(stockAIOrders);
+            return ServerResponse.createBySuccess(pageInfo);
+        } catch (Exception e) {
+            log.error("StockAiService getStockAiOrderList error", e);
+        }
+        return ServerResponse.createByError();
+    }
+}
diff --git a/src/main/java/com/nq/service/impl/UserAssetsServices.java b/src/main/java/com/nq/service/impl/UserAssetsServices.java
index 3a5b5e1..2f42217 100644
--- a/src/main/java/com/nq/service/impl/UserAssetsServices.java
+++ b/src/main/java/com/nq/service/impl/UserAssetsServices.java
@@ -291,4 +291,33 @@
         }
         extracted(userAssets);
     }
+
+
+    public Boolean aiAvailableBalanceChange(UserAssets userAssets, EUserAssets eUserAssets, BigDecimal amount) {
+        String before = userAssets.getAvailableBalance().toString();
+        if (eUserAssets.getCode().equals(EUserAssets.BUY_AI.getCode())) {
+            //冻结金额
+            userAssets.setFreezeMoney(userAssets.getFreezeMoney().add(amount));
+            //扣除可用金额
+            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount.negate()));
+        }
+        String after = userAssets.getAvailableBalance().toString();
+        MoneyLog moneyLog = new MoneyLog();
+        moneyLog.setDescs(eUserAssets.getDesc());
+        moneyLog.setBeFore(before);
+        moneyLog.setAfter(after);
+        moneyLog.setAmount(amount.toString());
+        moneyLog.setAccectType(userAssets.getAccectType());
+        moneyLog.setType(eUserAssets.getCode());
+        moneyLog.setUserId(userAssets.getId()+"");
+        moneyLog.setSymbol(EStockType.getEStockTypeByCode(userAssets.getAccectType()).getSymbol());
+        moneyLog.setCreateTime(new Date());
+        moneyLogMapper.insert(moneyLog);
+        return userAssetsMapper.updateById(userAssets)>1;
+    }
+
+    @Override
+    public BigDecimal exchangeAmountByRate(BigDecimal amount, BigDecimal rate) {
+        return amount.multiply(rate);
+    }
 }

--
Gitblit v1.9.3