From 49770c755aa288c72d6977ff2fd1f55f653b99bf Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Mon, 06 May 2024 22:33:59 +0800
Subject: [PATCH] 1

---
 src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java |   78 ++---
 src/main/java/com/nq/service/impl/ApplyLeverServicesimpl.java        |   90 ++++++
 src/main/java/com/nq/service/impl/UserAssetsServices.java            |   81 ++++
 src/main/java/com/nq/dao/ApplyLeverMapper.java                       |    7 
 src/main/java/com/nq/controller/protol/UserController.java           |    9 
 src/main/java/com/nq/utils/task/stock/StockTask.java                 |  129 ++++++++
 src/main/java/com/nq/pojo/User.java                                  |    2 
 src/main/java/com/nq/service/impl/UserPositionServiceImpl.java       |  292 +++++++++++++++----
 src/main/java/com/nq/service/IUserPositionService.java               |    2 
 src/main/java/com/nq/service/impl/UserServiceImpl.java               |   72 ++++
 src/main/java/com/nq/pojo/reponse/RUserAssets.java                   |    3 
 src/main/java/com/nq/pojo/UserAssets.java                            |    3 
 src/main/java/com/nq/service/IApplyLeverServices.java                |   17 +
 src/main/java/com/nq/controller/backend/AdminController.java         |   22 +
 src/main/java/com/nq/enums/EUserAssets.java                          |    1 
 src/main/java/com/nq/pojo/MoneyLog.java                              |    5 
 src/main/java/com/nq/pojo/ApplyLever.java                            |   37 ++
 17 files changed, 716 insertions(+), 134 deletions(-)

diff --git a/src/main/java/com/nq/controller/backend/AdminController.java b/src/main/java/com/nq/controller/backend/AdminController.java
index 0ea5e18..177950f 100644
--- a/src/main/java/com/nq/controller/backend/AdminController.java
+++ b/src/main/java/com/nq/controller/backend/AdminController.java
@@ -72,6 +72,10 @@
     @Autowired
     IUserAssetsServices iUserAssetsServices;
 
+
+    @Autowired
+    IApplyLeverServices iApplyLeverServices;
+
     //分页查询管理设置 所有管理列表数据及模糊查询
     @RequestMapping({"list.do"})
     @ResponseBody
@@ -343,4 +347,22 @@
         return  iUserAssetsServices.updateUserAssets(id,amt);
     }
 
+    @RequestMapping({"examineApplyLever.do"})
+    @ResponseBody
+    public ServerResponse examineApplyLever(@RequestParam(value = "id", required = true) String id,
+                                            @RequestParam(value = "state", defaultValue = "1") String state,
+                                            HttpServletRequest request) {
+        return this.iApplyLeverServices.examineApplyLever(id,state,request);
+    }
+
+
+    @RequestMapping({"queryApplyLever.do"})
+    @ResponseBody
+    public ServerResponse queryApplyLever(@RequestParam(value = "phone", required = false) String adminName,
+                                          @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                          @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
+                                          HttpServletRequest request
+    ) {
+        return this.iApplyLeverServices.queryApplyLever(adminName,pageNum,pageSize, request);
+    }
 }
diff --git a/src/main/java/com/nq/controller/protol/UserController.java b/src/main/java/com/nq/controller/protol/UserController.java
index b2ac108..aa2e638 100644
--- a/src/main/java/com/nq/controller/protol/UserController.java
+++ b/src/main/java/com/nq/controller/protol/UserController.java
@@ -4,6 +4,7 @@
 import com.google.common.collect.Maps;
 import com.nq.common.ServerResponse;
 import com.nq.enums.EStockType;
+import com.nq.pojo.ApplyLever;
 import com.nq.pojo.StockSubscribe;
 import com.nq.pojo.UserStockSubscribe;
 import com.nq.service.*;
@@ -56,6 +57,9 @@
 
     @Autowired
     IUserRechargeService iUserRechargeService;
+
+    @Autowired
+    IApplyLeverServices iApplyLeverServices;
 
     //添加到自选股
     @RequestMapping({"addOption.do"})
@@ -349,5 +353,10 @@
         return ServerResponse.createBySuccess(rateServices.currencyRate(EStockType.getEStockTypeByCode(stockCode), EStockType.getEStockTypeByCode(toType)));
     }
 
+    @RequestMapping({"applyLever.do"})
+    @ResponseBody
+    public ServerResponse applyLever(ApplyLever applyLever, HttpServletRequest request) {
+        return iApplyLeverServices.applyLever(applyLever,request);
+    }
 
 }
diff --git a/src/main/java/com/nq/dao/ApplyLeverMapper.java b/src/main/java/com/nq/dao/ApplyLeverMapper.java
new file mode 100644
index 0000000..5b9f07e
--- /dev/null
+++ b/src/main/java/com/nq/dao/ApplyLeverMapper.java
@@ -0,0 +1,7 @@
+package com.nq.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nq.pojo.ApplyLever;
+
+public interface ApplyLeverMapper extends BaseMapper<ApplyLever> {
+}
diff --git a/src/main/java/com/nq/enums/EUserAssets.java b/src/main/java/com/nq/enums/EUserAssets.java
index 7384a33..4036884 100644
--- a/src/main/java/com/nq/enums/EUserAssets.java
+++ b/src/main/java/com/nq/enums/EUserAssets.java
@@ -12,6 +12,7 @@
 
     CLOSE_POSITION_RETURN_SECURITY_DEPOSIT("CLOSE_POSITION_RETURN_SECURITY","平仓返回保证金"),
     CLOSE_POSITION("CLOSE_POSITION","平仓"),
+    CONSTRAINT_CLOSE_POSITION("CONSTRAINT_CLOSE_POSITION","强制平仓"),
     BUY("BUY","购买"),
     WITHDRAW("WITHDRAW","提现"),
 
diff --git a/src/main/java/com/nq/pojo/ApplyLever.java b/src/main/java/com/nq/pojo/ApplyLever.java
new file mode 100644
index 0000000..da1a908
--- /dev/null
+++ b/src/main/java/com/nq/pojo/ApplyLever.java
@@ -0,0 +1,37 @@
+package com.nq.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+@Data
+public class ApplyLever {
+
+    @TableId(value = "id",type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     *
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    // 用户id
+    private String userId;
+
+    // 用户手机号码
+    private String phone;
+
+    // 杠杆
+    private String lever;
+
+
+    private String state;
+
+    private String descs;
+
+
+}
diff --git a/src/main/java/com/nq/pojo/MoneyLog.java b/src/main/java/com/nq/pojo/MoneyLog.java
index cb30c05..162a90d 100644
--- a/src/main/java/com/nq/pojo/MoneyLog.java
+++ b/src/main/java/com/nq/pojo/MoneyLog.java
@@ -2,7 +2,10 @@
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
+
+import java.util.Date;
 
 @Data
 public class MoneyLog {
@@ -18,6 +21,8 @@
     private String userId;
 
     private String symbol;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
 
 
 }
diff --git a/src/main/java/com/nq/pojo/User.java b/src/main/java/com/nq/pojo/User.java
index 17b797f..19d5ffb 100644
--- a/src/main/java/com/nq/pojo/User.java
+++ b/src/main/java/com/nq/pojo/User.java
@@ -23,7 +23,7 @@
     private Integer accountType;
 
 
-
+    private String lever;
     private String recomPhone;
     private Integer isLock;
     private Integer isLogin;
diff --git a/src/main/java/com/nq/pojo/UserAssets.java b/src/main/java/com/nq/pojo/UserAssets.java
index 2196a20..2650c0c 100644
--- a/src/main/java/com/nq/pojo/UserAssets.java
+++ b/src/main/java/com/nq/pojo/UserAssets.java
@@ -47,4 +47,7 @@
 
     // 冻结金额
     private BigDecimal freezeMoney;
+
+    // 累计盈亏 0 正 1 负
+    private Integer isZf;
 }
diff --git a/src/main/java/com/nq/pojo/reponse/RUserAssets.java b/src/main/java/com/nq/pojo/reponse/RUserAssets.java
index 777241c..25aba7b 100644
--- a/src/main/java/com/nq/pojo/reponse/RUserAssets.java
+++ b/src/main/java/com/nq/pojo/reponse/RUserAssets.java
@@ -52,4 +52,7 @@
     private String symbol;
 
     private String symbolCode;
+
+    // 累计盈亏 0 正 1 负
+    private Integer isZf;
 }
diff --git a/src/main/java/com/nq/service/IApplyLeverServices.java b/src/main/java/com/nq/service/IApplyLeverServices.java
new file mode 100644
index 0000000..790ef55
--- /dev/null
+++ b/src/main/java/com/nq/service/IApplyLeverServices.java
@@ -0,0 +1,17 @@
+package com.nq.service;
+
+import com.nq.common.ServerResponse;
+import com.nq.pojo.ApplyLever;
+
+import javax.servlet.http.HttpServletRequest;
+
+public interface IApplyLeverServices {
+
+    ServerResponse  applyLever(ApplyLever applyLever, HttpServletRequest request);
+
+
+    ServerResponse  examineApplyLever(String  id,String states, HttpServletRequest request);
+
+
+    ServerResponse  queryApplyLever(String phone, Integer page,Integer pageSize,HttpServletRequest request);
+}
diff --git a/src/main/java/com/nq/service/IUserPositionService.java b/src/main/java/com/nq/service/IUserPositionService.java
index 1a4b1b5..73ccbbb 100644
--- a/src/main/java/com/nq/service/IUserPositionService.java
+++ b/src/main/java/com/nq/service/IUserPositionService.java
@@ -80,4 +80,6 @@
     ServerResponse buyDz(String stockCode, String password, Integer num, HttpServletRequest request) throws Exception;
 
   ServerResponse buyStockDzList(HttpServletRequest request);
+
+  void stockConstraint(List<UserPosition> userPositions);
 }
diff --git a/src/main/java/com/nq/service/impl/ApplyLeverServicesimpl.java b/src/main/java/com/nq/service/impl/ApplyLeverServicesimpl.java
new file mode 100644
index 0000000..486c5e4
--- /dev/null
+++ b/src/main/java/com/nq/service/impl/ApplyLeverServicesimpl.java
@@ -0,0 +1,90 @@
+package com.nq.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nq.common.ServerResponse;
+import com.nq.dao.ApplyLeverMapper;
+import com.nq.dao.UserMapper;
+import com.nq.pojo.ApplyLever;
+import com.nq.pojo.User;
+import com.nq.service.IApplyLeverServices;
+import com.nq.service.IUserService;
+import org.apache.http.util.TextUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+@Service
+public class ApplyLeverServicesimpl implements IApplyLeverServices {
+
+    @Resource
+    ApplyLeverMapper applyLeverMapper;
+
+    @Resource
+    IUserService userService;
+    @Resource
+    UserMapper userMapper;
+
+    @Override
+    public ServerResponse applyLever(ApplyLever applyLever, HttpServletRequest request) {
+
+        QueryWrapper<ApplyLever> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("user_id",userService.getCurrentUser(request).getId());
+        queryWrapper.ne("state",2);
+        if(applyLeverMapper.selectCount(queryWrapper)>0){
+            return ServerResponse.createByErrorMsg("你已经申请杠杆了",request);
+        }
+        User user = userService.getCurrentUser(request);
+        applyLever.setPhone(user.getPhone());
+        applyLever.setUserId(user.getId()+"");
+        applyLever.setState("0");
+        applyLever.setCreateTime(new Date());
+
+        if(applyLeverMapper.insert(applyLever)>0){
+            return ServerResponse.createBySuccess("申请成功,请联系客服",request);
+        }else{
+            return ServerResponse.createByErrorMsg("申请失败",request);
+        }
+    }
+
+    @Transactional
+    @Override
+    public ServerResponse examineApplyLever(String  id,String states, HttpServletRequest request) {
+        ApplyLever applyLever = applyLeverMapper.selectById(id);
+        applyLever.setState(states);
+        applyLeverMapper.updateById(applyLever);
+       User user =  userMapper.selectById(applyLever.getUserId());
+       user.setLever(applyLever.getLever());
+       userMapper.updateById(user);
+       return ServerResponse.createBySuccess();
+    }
+
+    @Override
+    public ServerResponse queryApplyLever(String phone, Integer page, Integer pageSize, HttpServletRequest request) {
+        Integer userId = null;
+        Page<ApplyLever> page1 = new Page<>(page, pageSize);
+        if(!TextUtils.isEmpty(phone)){
+            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("phone",phone);
+            User user = userMapper.selectOne(queryWrapper);
+            if(user != null ){
+                userId = user.getId();
+            }else{
+                QueryWrapper<ApplyLever> queryWrapper1 = new QueryWrapper<>();
+                queryWrapper1.eq("user_id",phone);
+                return ServerResponse.createBySuccess(applyLeverMapper.selectPage(page1,queryWrapper1));
+            }
+        }
+        QueryWrapper<ApplyLever> queryWrapper1 = new QueryWrapper<>();
+        if(userId != null){
+            queryWrapper1.eq("user_id",userId);
+        }
+        queryWrapper1.orderByDesc("create_time");
+
+       return ServerResponse.createBySuccess(applyLeverMapper.selectPage(page1,queryWrapper1));
+    }
+
+}
diff --git a/src/main/java/com/nq/service/impl/UserAssetsServices.java b/src/main/java/com/nq/service/impl/UserAssetsServices.java
index 5e1a4e9..007a702 100644
--- a/src/main/java/com/nq/service/impl/UserAssetsServices.java
+++ b/src/main/java/com/nq/service/impl/UserAssetsServices.java
@@ -13,6 +13,7 @@
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 
@@ -91,28 +92,59 @@
         String type = eUserAssets.getDesc();
         String before = userAssets.getAvailableBalance().toString();
         String accectType = userAssets.getAccectType();
-       if(Objects.equals(eUserAssets.getCode(), EUserAssets.BUY.getCode())){
+        if(Objects.equals(eUserAssets.getCode(), EUserAssets.BUY.getCode())){
             userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
             userAssets.setFreezeMoney(userAssets.getFreezeMoney().add(amount.negate()));
         }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.CLOSE_POSITION.getCode())){
             userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
-            userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().add(amount.abs()));
+            extracted(amount, userAssets);
         }else  if(Objects.equals(eUserAssets.getCode(), EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT.getCode())){
-            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
+            if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){
+                BigDecimal availableBalance = amount.subtract(userAssets.getAmountToBeCovered());
+                if(availableBalance.compareTo(BigDecimal.ZERO) > 0){
+                    userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(availableBalance));
+                    userAssets.setAmountToBeCovered(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())){
-            userAssets.setCumulativeProfitAndLoss(userAssets.getProfitAndLoss().add(amount.abs()));
+            extracted(amount, userAssets);
         }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.TRANSFER.getCode())){
             userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
-           eUserAssets.setDesc(desc);
+            eUserAssets.setDesc(desc);
         }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.TOP_UP.getCode())){
-            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
+            if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){
+                BigDecimal availableBalance = amount.subtract(userAssets.getAmountToBeCovered());
+                if(availableBalance.compareTo(BigDecimal.ZERO) > 0){
+                    userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(availableBalance));
+                    userAssets.setAmountToBeCovered(BigDecimal.ZERO);
+                }else{
+                    BigDecimal amountToBeCovered = userAssets.getAmountToBeCovered().subtract(amount);
+                    userAssets.setAmountToBeCovered(amountToBeCovered);
+                }
+            }else{
+                userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
+            }
         }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.WITHDRAW.getCode())){
             userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
         }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.HANDLING_CHARGE.getCode())){
-           userAssets.setHandlingCharge(userAssets.getHandlingCharge().add(amount.abs()));
-           userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount.negate()));
-       }
+            userAssets.setHandlingCharge(userAssets.getHandlingCharge().add(amount.abs()));
+            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount.negate()));
+            extracted(amount.negate(),userAssets);
+        }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.CONSTRAINT_CLOSE_POSITION.getCode())){
+            userAssets.setFreezeMoney(userAssets.getFreezeMoney().subtract(amount));
+            if(userAssets.getIsZf() == 0){
+                userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().subtract(amount));
+            }else{
+                userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().add(amount));
+            }
+            extracted(userAssets);
+        }
         String  after =  userAssets.getAvailableBalance().toString();
         MoneyLog moneyLog = new MoneyLog();
         moneyLog.setDescs(eUserAssets.getDesc());
@@ -123,7 +155,38 @@
         moneyLog.setType(eUserAssets.getCode());
         moneyLog.setUserId(userId+"");
         moneyLog.setSymbol(EStockType.getEStockTypeByCode(accetType).getSymbol());
+        moneyLog.setCreateTime(new Date());
         moneyLogMapper.insert(moneyLog);
         return userAssetsMapper.updateById(userAssets)>1;
     }
+
+    //只要涉及到cumulativeProfitAndLoss变动重新设置状态
+    private static void extracted(UserAssets userAssets) {
+        if(userAssets.getCumulativeProfitAndLoss().compareTo(BigDecimal.ZERO) >= 0){
+            userAssets.setIsZf(0);
+        }else{
+            userAssets.setIsZf(1);
+            userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().abs());
+        }
+    }
+
+    private static void extracted(BigDecimal amount, UserAssets userAssets) {
+        if(userAssets.getIsZf() == 1){
+            userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().negate());
+        }
+        if(userAssets.getIsZf() == 0){
+            if(amount.compareTo(BigDecimal.ZERO) >= 0){
+                userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().add(amount.abs()));
+            }else{
+                userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().subtract(amount.abs()));
+            }
+        }else{
+            if(amount.compareTo(BigDecimal.ZERO) >= 0){
+                userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().add(amount.abs()));
+            }else{
+                userAssets.setCumulativeProfitAndLoss(userAssets.getCumulativeProfitAndLoss().subtract(amount.abs()));
+            }
+        }
+        extracted(userAssets);
+    }
 }
diff --git a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
index f469776..81c7180 100644
--- a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -1,5 +1,6 @@
 package com.nq.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.nq.dao.*;
 import com.nq.enums.EStockType;
@@ -31,6 +32,9 @@
 
 import java.math.BigDecimal;
 import java.sql.Timestamp;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
 import java.util.*;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
@@ -109,51 +113,53 @@
     @Autowired
     IPriceServices priceServices;
 
+    @Autowired
+    UserAssetsMapper userAssetsMapper;
+
     @Transactional
-    public ServerResponse buy(Integer stockId, Integer buyNum, Integer buyType, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, HttpServletRequest request)  {
+    public ServerResponse buy(Integer stockId, Integer buyNum, Integer buyType, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, HttpServletRequest request) {
 
         SiteProduct siteProduct = iSiteProductService.getProductSetting();
 
         User user = this.iUserService.getCurrentRefreshUser(request);
-        if (siteProduct.getRealNameDisplay() && (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()))) {
-            return ServerResponse.createByErrorMsg("订单失败,请先实名认证",request);
+        if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) {
+            return ServerResponse.createByErrorMsg("订单失败,请先实名认证", request);
         }
-         SiteSetting siteSetting = this.iSiteSettingService.getSiteSetting();
-         // 手续费率
-          BigDecimal siteSettingBuyFee = siteSetting.getBuyFee();
+        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
+        // 手续费率
+        BigDecimal siteSettingBuyFee = siteSetting.getBuyFee();
 
         if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) {
-            return ServerResponse.createByErrorMsg("订单失败,帐户已被锁定",request);
+            return ServerResponse.createByErrorMsg("订单失败,帐户已被锁定", request);
         }
 
         Stock stock = stockMapper.selectByPrimaryKey(stockId);
         if (stock == null) {
-            return ServerResponse.createByErrorMsg("订单失败,股票代码不存在",request);
+            return ServerResponse.createByErrorMsg("订单失败,股票代码不存在", request);
         }
         //判断股票是否在可交易时间段
         Boolean b = tradingHourService.timeCheck(stock.getStockCode());
         if (!b) {
-            return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内",request);
+            return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内", request);
         }
 
-
+        UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(stock.getStockType(), user.getId());
         if (stock.getIsLock() != 0) {
-            return ServerResponse.createByErrorMsg("订单失败,股票被锁定",request);
+            return ServerResponse.createByErrorMsg("订单失败,股票被锁定", request);
         }
 
         //股票类型 现价 数据源的处理
-        BigDecimal  nowPrice = priceServices.getNowPrice(stock.getStockCode());
+        BigDecimal nowPrice = priceServices.getNowPrice(stock.getStockCode());
 
         if (nowPrice.compareTo(new BigDecimal("0")) == 0) {
-            return ServerResponse.createByErrorMsg("报价0,请稍后再试",request);
+            return ServerResponse.createByErrorMsg("报价0,请稍后再试", request);
         }
 
-        BigDecimal buyAmt = nowPrice.multiply(new BigDecimal(buyNum));
-        BigDecimal orderFree =  siteSettingBuyFee.multiply(buyAmt);
+        BigDecimal buyAmt = nowPrice.multiply(new BigDecimal(buyNum)).divide(new BigDecimal(lever));
+        BigDecimal orderFree = siteSettingBuyFee.multiply(buyAmt);
 
-        UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(stock.getStockType(),user.getId());
-        if(userAssets.getAvailableBalance().compareTo(buyAmt.add(orderFree))<0){
-            return ServerResponse.createByErrorMsg("订单失败,余额不足",request);
+        if (userAssets.getAvailableBalance().compareTo(buyAmt.add(orderFree)) < 0) {
+            return ServerResponse.createByErrorMsg("订单失败,配资不足", request);
         }
         UserPosition userPosition = new UserPosition();
         if (profitTarget != null && profitTarget.compareTo(new BigDecimal("0")) > 0) {
@@ -193,9 +199,9 @@
         userPosition.setOrderStayDays(Integer.valueOf(0));
         userPosition.setOrderStayFee(BigDecimal.ZERO);
         userPositionMapper.insert(userPosition);
-        iUserAssetsServices.availablebalanceChange(stock.getStockType(),user.getId(), EUserAssets.BUY,buyAmt.negate(),"","");
-        iUserAssetsServices.availablebalanceChange(stock.getStockType(),user.getId(), EUserAssets.HANDLING_CHARGE,orderFree,"","");
-        return ServerResponse.createBySuccessMsg("下单成功",request);
+        iUserAssetsServices.availablebalanceChange(stock.getStockType(), user.getId(), EUserAssets.BUY, buyAmt.negate(), "", "");
+        iUserAssetsServices.availablebalanceChange(stock.getStockType(), user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
+        return ServerResponse.createBySuccessMsg("下单成功", request);
     }
 
 
@@ -290,30 +296,30 @@
 
 
     @Transactional
-    public ServerResponse sell(String positionSn, int doType,HttpServletRequest request){
+    public ServerResponse sell(String positionSn, int doType, HttpServletRequest request) {
         UserPosition userPosition = this.userPositionMapper.findPositionBySn(positionSn);
-        BigDecimal siitteBuyFee = iSiteSettingService.getSiteSetting().getBuyFee();
-        Boolean b = tradingHourService.timeCheck(userPosition.getStockCode());
-        if (!b) {
-            return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内",request);
-        }
+
+        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
+        // 手续费率
+        BigDecimal siitteBuyFee = siteSetting.getSellFee();
+
         if (userPosition == null) {
-            return ServerResponse.createByErrorMsg("平仓失败,订单不存在",request);
+            return ServerResponse.createByErrorMsg("平仓失败,订单不存在", request);
         }
         User user = this.userMapper.selectById(userPosition.getUserId());
         if (user == null) {
-            return ServerResponse.createByErrorMsg("平仓失败,用户不存在",request);
+            return ServerResponse.createByErrorMsg("平仓失败,用户不存在", request);
         }
         if (userPosition.getSellOrderId() != null) {
-            return ServerResponse.createByErrorMsg("平仓失败, 订单已平仓",request);
+            return ServerResponse.createByErrorMsg("平仓失败, 订单已平仓", request);
         }
         if (1 == userPosition.getIsLock().intValue()) {
             return ServerResponse.createByErrorMsg("this order is closed " + userPosition.getLockMsg());
         }
         Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", userPosition.getStockCode()));
-        BigDecimal  nowPrice = priceServices.getNowPrice(userPosition.getStockCode());
+        BigDecimal nowPrice = priceServices.getNowPrice(userPosition.getStockCode());
         if (nowPrice.compareTo(new BigDecimal("0")) != 1) {
-            return ServerResponse.createByErrorMsg("报价0,平仓失败,请稍后再试",request);
+            return ServerResponse.createByErrorMsg("报价0,平仓失败,请稍后再试", request);
         }
         userPosition.setSellOrderId(GeneratePosition.getPositionId());
         userPosition.setSellOrderPrice(nowPrice);
@@ -323,16 +329,20 @@
         BigDecimal xsPrice = sellOrderTotel.multiply(siitteBuyFee);
         userPositionMapper.updateById(userPosition);
         userAssetsServices.availablebalanceChange(stock.getStockType(),
-                userPosition.getUserId(),EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
-                userPosition.getOrderTotalPrice(),"","");
+                userPosition.getUserId(),
+                EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
+                userPosition.getOrderTotalPrice(), "", "");
         userAssetsServices.availablebalanceChange(stock.getStockType(),
-                userPosition.getUserId(),EUserAssets.HANDLING_CHARGE,
-                xsPrice,"","");
+                userPosition.getUserId(), EUserAssets.HANDLING_CHARGE,
+                xsPrice, "", "");
 
-        PositionProfitVO profitVO =  UserPointUtil.getPositionProfitVO(userPosition,priceServices.getNowPrice(userPosition.getStockCode()));
-        userAssetsServices.availablebalanceChange(stock.getStockType(),userPosition.getUserId(),EUserAssets.CLOSE_POSITION,
-                profitVO.getAllProfitAndLose() ,"","");
-        return ServerResponse.createBySuccessMsg("平仓成功!",request);
+        PositionProfitVO profitVO = UserPointUtil.getPositionProfitVO(userPosition,
+                priceServices.getNowPrice(userPosition.getStockCode()));
+
+        userAssetsServices.availablebalanceChange(stock.getStockType(),
+                userPosition.getUserId(), EUserAssets.CLOSE_POSITION,
+                profitVO.getAllProfitAndLose(), "", "");
+        return ServerResponse.createBySuccessMsg("平仓成功!", request);
     }
 
     @Transactional
@@ -355,7 +365,7 @@
 
         List<UserPosition> userPositionList = userPositionMapper.selectList(queryWrapper);
         for (int i = 0; i < userPositionList.size(); i++) {
-            sell(userPositionList.get(i).getPositionSn(),0);
+            sell(userPositionList.get(i).getPositionSn(),0,request);
         }
         return ServerResponse.createBySuccessMsg("平仓成功!");
     }
@@ -520,7 +530,10 @@
 
         PageHelper.startPage(pageNum, pageSize);
         List<UserPosition> userPositions;
-        userPositions   = userPositionMapper.
+
+
+
+        userPositions = userPositionMapper.
                 findMyPositionByCodeAndSpell(user.getId(),
                         stockCode, stockSpell,
                         state, stockType);
@@ -529,7 +542,9 @@
         List<UserPositionVO> userPositionVOS = Lists.newArrayList();
         if (userPositions.size() > 0) {
             for (UserPosition position : userPositions) {
-                UserPositionVO userPositionVO = UserPointUtil.assembleUserPositionVO(position,priceServices.getNowPrice(position.getStockCode()));
+                UserPositionVO userPositionVO = UserPointUtil.assembleUserPositionVO(position, priceServices.getNowPrice(position.getStockCode()));
+                userPositionVO.setOrderTotalPrice(userPositionVO.getOrderTotalPrice().multiply(new BigDecimal(userPositionVO.getOrderLever())));
+                userPositionVO.setProfitAndLose(userPositionVO.getProfitAndLose().multiply(new BigDecimal(userPositionVO.getOrderLever())));
                 userPositionVOS.add(userPositionVO);
             }
         }
@@ -1127,26 +1142,25 @@
         if (userStockSubscribe == null) {
             return ServerResponse.createByErrorMsg("无该申购记录");
         }
-        StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("code", userStockSubscribe.getNewCode()));
+        StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("code", userStockSubscribe.getNewCode()).eq("type",userStockSubscribe.getType()));
         if (userStockSubscribe == null) {
             return ServerResponse.createByErrorMsg("该新股不存在");
         }
         if (userStockSubscribe.getStatus() == 4 || userStockSubscribe.getStatus() == 3 && stockSubscribe.getType() == 2) {
-
-//                String sinaStock = SinaStockApi.getSinaStock(stockSubscribe.getStockType()+userStockSubscribe.getNewCode());
-//                String[] arrayOfString = sinaStock.split(",");
-//                 if (arrayOfString.length < 10){
-//                 return ServerResponse.createByErrorMsg("数据源无该新股数据,转持仓失败");
-//                 }
+            Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockCode, userStockSubscribe.getNewCode()));
+            if(null == stock){
+                return ServerResponse.createByErrorMsg("该新股不存在");
+            }
             UserPosition userPosition = new UserPosition();
             userPosition.setPositionType(1);
             userPosition.setPositionSn(KeyUtils.getUniqueKey());
             userPosition.setUserId(userStockSubscribe.getUserId());
             userPosition.setNickName(userStockSubscribe.getRealName());
             userPosition.setAgentId(userStockSubscribe.getAgentId());
-            userPosition.setStockCode(userStockSubscribe.getNewCode());
+            userPosition.setStockCode(stock.getStockCode());
+            userPosition.setStockSpell(stock.getStockSpell());
             userPosition.setStockName(userStockSubscribe.getNewName());
-            userPosition.setStockGid(stockSubscribe.getStockType() + userStockSubscribe.getNewCode());
+            userPosition.setStockGid(stock.getStockType());
 
             userPosition.setBuyOrderId(GeneratePosition.getPositionId());
             userPosition.setBuyOrderTime(new Date());
@@ -1159,7 +1173,7 @@
             userPosition.setIsLock(Integer.valueOf(0));
 
 
-            userPosition.setOrderLever(10);
+            userPosition.setOrderLever(1);
 
 
             //递延费特殊处理
@@ -1181,14 +1195,6 @@
             log.info("用户购买印花税(配资后总资金 * 百分比) = {}", buy_yhs_amt);
             userPosition.setOrderSpread(buy_yhs_amt);
 
-            //            SiteSpread siteSpread = iSiteSpreadService.findSpreadRateOne(new BigDecimal(stock_crease), buy_amt, stock.getStockCode(), now_price);
-            //            BigDecimal spread_rate_amt = new BigDecimal("0");
-            //            if(siteSpread != null){
-            //                spread_rate_amt = buy_amt.multiply(siteSpread.getSpreadRate()).setScale(2, 4);
-            //                log.info("用户购买点差费(配资后总资金 * 百分比{}) = {}", siteSpread.getSpreadRate(), spread_rate_amt);
-            //            } else{
-            //                log.info("用户购买点差费(配资后总资金 * 百分比{}) = {}", "设置异常", spread_rate_amt);
-            //            }
             BigDecimal spread_rate_amt = new BigDecimal(0);
             userPosition.setSpreadRatePrice(spread_rate_amt);
 
@@ -1206,13 +1212,17 @@
 
             int ret = 0;
             ret = this.userPositionMapper.insert(userPosition);
-
+            UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(stock.getStockType(), userPosition.getUserId());
+            if(null == userAssets){
+                return ServerResponse.createByErrorMsg("新股转持仓失败");
+            }
+            userAssetsMapper.updateById(userAssets);
             if (ret > 0) {
                 userStockSubscribe.setStatus(5);
                 userStockSubscribeMapper.update1(userStockSubscribe);
                 if (userStockSubscribe.getType() == 1 || userStockSubscribe.getType() == 2) {
                     User user = userMapper.selectById(userStockSubscribe.getUserId());
-                    ret = userMapper.updateByPrimaryKey(user);
+                    ret = userMapper.updateById(user);
                 }
                 if (ret > 0) {
                     return ServerResponse.createBySuccessMsg("新股转持仓成功");
@@ -1758,6 +1768,162 @@
 
     }
 
+
+    @Override
+    @Transactional
+    public void stockConstraint(List<UserPosition> list) {
+        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
+
+        for (UserPosition position : list) {
+            Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockCode, position.getStockCode()));
+            UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<UserAssets>()
+                    .eq(UserAssets::getUserId, position.getUserId())
+                    .eq(UserAssets::getAccectType, stock.getStockType())
+            );
+            if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){
+                continue;
+            }
+            //平仓检查
+            Result result = getResult(position);
+            if (result == null) continue;
+
+            Integer liquidation = 0;
+            liquidation = isLiquidation(position, result.signum, result.profit, liquidation);
+            if(liquidation != 0){
+                extracted(position, result.nowPrice, result.stock,liquidation);
+            }
+        }
+    }
+
+    private Result getResult(UserPosition position) {
+        // 检查订单是否存在
+        if (position == null) {
+            log.info("订单不存在,订单id: {}", position.getId());
+            return null;
+        }
+
+        // 检查用户是否存在
+        User user = this.userMapper.selectById(position.getUserId());
+        if (user == null) {
+            log.info("用户不存在,订单id: {}", position.getId());
+            return null;
+        }
+
+
+        //判断订单
+        if (1 == position.getIsLock().intValue()) {
+            log.info("订单已终止,订单id: {}", position.getId());
+            return null;
+        }
+
+        Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", position.getStockCode()));
+
+
+        BigDecimal nowPrice = priceServices.getNowPrice(position.getStockCode());
+
+
+        //判断订单是否已到强制平仓价格
+        BigDecimal purchaseAmount = position.getBuyOrderPrice().multiply(new BigDecimal(position.getOrderNum()));// 买入价总额
+        BigDecimal nowPriceAmount = nowPrice.multiply(new BigDecimal(position.getOrderNum())); // 现价总额
+
+        BigDecimal profit = nowPriceAmount.subtract(purchaseAmount);//利润
+        int signum = profit.signum();  // -1, 0, 1,分别表示 负数、零、正数
+        Result result = new Result(stock, nowPrice, profit, signum);
+        return result;
+    }
+
+    private static class Result {
+        public final Stock stock;//股票
+        public final BigDecimal nowPrice;//现价
+        public final BigDecimal profit;//利润
+        public final int signum;// -1, 0, 1,分别表示 负数、零、正数
+
+        public Result(Stock stock, BigDecimal nowPrice, BigDecimal profit, int signum) {
+            this.stock = stock;
+            this.nowPrice = nowPrice;
+            this.profit = profit;
+            this.signum = signum;
+        }
+    }
+
+    //判断平仓
+    private Integer isLiquidation(UserPosition position, int signum, BigDecimal profit, Integer liquidation) {
+        //-1强平 0未触发 1止损强平 2止盈强平
+        //最新报价
+        BigDecimal nowPrice = priceServices.getNowPrice(position.getStockCode());
+        if(position.getOrderDirection().equals("买涨")){
+            //判断亏损金额是否达到保证金金额
+            BigDecimal negate = profit.negate();
+            //如果买涨 signum 为-1则表示亏损
+            if(signum == -1){
+                //止损
+                if(null != position.getStopTargetPrice() && nowPrice.compareTo(position.getStopTargetPrice()) <= 0){
+                    //强制平仓
+                    return liquidation = 1;
+                }
+                if (negate.compareTo(position.getOrderTotalPrice()) >= 0){//亏平强平
+                    //强制平仓
+                    return liquidation = -1;
+                }
+            }else{
+                //止盈
+                if(null != position.getProfitTargetPrice() && nowPrice.compareTo(position.getProfitTargetPrice()) >= 0){
+                    //强制平仓
+                    return liquidation = 2;
+                }
+            }
+        }else{
+            //买跌 signum
+            if(signum == 1){
+                //止损
+                if(null != position.getStopTargetPrice() && nowPrice.compareTo(position.getStopTargetPrice()) >= 0){
+                    //强制平仓
+                    return liquidation = 1;
+                }
+                //判断亏损金额是否达到保证金金额
+                if (profit.compareTo(position.getOrderTotalPrice()) >= 0){//亏平强平
+                    //强制平仓
+                    return liquidation = -1;
+                }
+            }else{
+                //止盈
+                if(null != position.getProfitTargetPrice() && nowPrice.compareTo(position.getProfitTargetPrice()) <= 0){
+                    //强制平仓
+                    return liquidation = 2;
+                }
+            }
+        }
+        return liquidation;
+    }
+
+    //平仓
+    private void extracted(UserPosition position, BigDecimal nowPrice, Stock stock,Integer liquidation) {
+        //-1强平 0未触发 1止损强平 2止盈强平
+        BigDecimal sellOrderTotel = nowPrice.multiply(new BigDecimal(position.getOrderNum()));
+        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
+        // 手续费率
+        BigDecimal xsPrice = sellOrderTotel.multiply(siteSetting.getForceStopFee());//手续费
+        // 更新订单信息
+        position.setSellOrderId(GeneratePosition.getPositionId());
+        position.setSellOrderPrice(nowPrice);
+        position.setSellOrderTime(new Date());
+        userPositionMapper.updateById(position);
+        if(liquidation == -1){
+            userAssetsServices.availablebalanceChange(stock.getStockType(),
+                    position.getUserId(),
+                    EUserAssets.CONSTRAINT_CLOSE_POSITION,
+                    position.getOrderTotalPrice(), "", "");
+        }else if(liquidation == 1 || liquidation == 2){
+            userAssetsServices.availablebalanceChange(stock.getStockType(),
+                    position.getUserId(), EUserAssets.HANDLING_CHARGE,
+                    xsPrice, "", "");
+            PositionProfitVO profitVO = UserPointUtil.getPositionProfitVO(position, priceServices.getNowPrice(position.getStockCode()));
+            userAssetsServices.availablebalanceChange(stock.getStockType(), position.getUserId(), EUserAssets.CLOSE_POSITION,
+                    profitVO.getAllProfitAndLose(), "", "");
+        }
+        log.info("强制平仓成功,订单id: {}", position.getId());
+    }
+
 }
 
 
diff --git a/src/main/java/com/nq/service/impl/UserServiceImpl.java b/src/main/java/com/nq/service/impl/UserServiceImpl.java
index b80ea6e..672a312 100644
--- a/src/main/java/com/nq/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserServiceImpl.java
@@ -13,6 +13,7 @@
 import com.nq.pojo.*;
 import com.nq.pojo.reponse.RUserAssets;
 import com.nq.service.*;
+import com.nq.utils.UserPointUtil;
 import com.nq.utils.timeutil.DateTimeUtil;
 import com.nq.utils.PropertiesUtil;
 import com.nq.utils.SymmetricCryptoUtil;
@@ -27,6 +28,7 @@
 import com.nq.vo.indexposition.IndexPositionVO;
 import com.nq.vo.position.PositionProfitVO;
 import com.nq.vo.position.PositionVO;
+import com.nq.vo.position.UserPositionVO;
 import com.nq.vo.stock.StockListVO;
 import com.nq.vo.user.UserInfoVO;
 
@@ -117,8 +119,14 @@
     @Autowired
     ISiteMessageService iSiteMessageService;
 
+    @Autowired
+    private UserPositionMapper userPositionMapper;
 
+    @Autowired
+    IPriceServices priceServices;
 
+    @Resource
+    ApplyLeverMapper applyLeverMapper;
 
 
 
@@ -286,9 +294,30 @@
         String userJson = RedisShardedPoolUtils.get(loginToken);
         User user = (User) JsonUtil.string2Obj(userJson, User.class);
         User dbuser = this.userMapper.selectById(user.getId());
+
         SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
         UserInfoVO userInfoVO = assembleUserInfoVO(dbuser, siteSetting);
+        ApplyLever applyLever = applyLeverMapper.selectOne(new LambdaQueryWrapper<ApplyLever>()
+                .eq(ApplyLever::getUserId, user.getId())
+                .eq(ApplyLever::getState, 1)
+                .orderByDesc(ApplyLever::getCreateTime)
+                .last(" limit 1"));
+        if(null == applyLever || applyLever.getLever().equals("1")){
+            userInfoVO.setSiteLever("1");
+        }else{
+            userInfoVO.setSiteLever(leverSplit(applyLever.getLever()));
+        }
         return ServerResponse.createBySuccess(userInfoVO);
+    }
+
+    public String leverSplit(String lever){
+        String levers = "1/2/5/10";
+        String[] parts = levers.split("/");
+        int index = Arrays.asList(parts).indexOf(lever);
+        if (index != -1) {
+            return String.join("/", Arrays.copyOfRange(parts, 0, index + 1));
+        }
+        return null;
     }
 
 
@@ -484,19 +513,20 @@
             rUserAssets.setCumulativeProfitAndLoss(hProfitAndLose.toString());
             rUserAssets.setHandlingCharge(hMoney.toString());
             rUserAssets.setProfitAndLoss(profitAndLose.toString());
-
+            rUserAssets.setIsZf(userAssets.getIsZf());
+            rUserAssets.setAmountToBeCovered(userAssets.getAmountToBeCovered().toString());
             BigDecimal rate = rateServices.currencyRate(
                     EStockType.getEStockTypeByCode(userAssets.getAccectType()),EStockType.US);
 
-           BigDecimal  availableBalanceUSD = amt;
-           if(amt.compareTo(BigDecimal.ZERO)>0){
-               availableBalanceUSD = amt.multiply(rate);
-           }
+            BigDecimal  availableBalanceUSD = amt;
+            if(amt.compareTo(BigDecimal.ZERO)>0){
+                availableBalanceUSD = amt.multiply(rate);
+            }
 
             BigDecimal  freezeMoneyUSD = freeMoney;
-           if(freeMoney.compareTo(BigDecimal.ZERO)>0){
-               freezeMoneyUSD  = freeMoney.multiply(rate);
-           }
+            if(freeMoney.compareTo(BigDecimal.ZERO)>0){
+                freezeMoneyUSD  = freeMoney.multiply(rate);
+            }
 
             BigDecimal  totleMoneyUSD = totalAssets;
             if(totalAssets.compareTo(BigDecimal.ZERO)>0){
@@ -527,7 +557,9 @@
             rUserAssets.setCumulativeProfitAndLossUSD(cumulativeProfitAndLossUSD.setScale(s,BigDecimal.ROUND_UP).toString());
             rUserAssets.setHandlingChargeUSD(handlingChargeUSD.setScale(s,BigDecimal.ROUND_UP).toString());
             rUserAssets.setProfitAndLossUSD(profitAndLossUSD.setScale(s,BigDecimal.ROUND_UP).toString());
-
+            rUserAssets.setProfitAndLoss(getProfitAndLose(userId,userAssets.getAccectType()).toString());
+            BigDecimal decimal = new BigDecimal(rUserAssets.getTotalMoney()).add(new BigDecimal(rUserAssets.getProfitAndLoss()));
+            rUserAssets.setTotalMoney(decimal.toString());
             AllProfitAndLose = AllProfitAndLose.add(profitAndLossUSD);
             allTotalAssets = allTotalAssets.add(totleMoneyUSD);
             allAmt = allAmt.add(availableBalanceUSD);
@@ -566,6 +598,28 @@
         return ServerResponse.createBySuccess(rUserAssetsList);
     }
 
+    public BigDecimal getProfitAndLose(Integer userId,String  accectType){
+        List<UserPosition> userPositions;
+        userPositions = userPositionMapper.
+                findMyPositionByCodeAndSpell(userId,
+                        "","",
+                        0, accectType);
+
+
+        List<UserPositionVO> userPositionVOS = Lists.newArrayList();
+        if (userPositions.size() > 0) {
+            for (UserPosition position : userPositions) {
+                UserPositionVO userPositionVO = UserPointUtil.assembleUserPositionVO(position, priceServices.getNowPrice(position.getStockCode()));
+                userPositionVOS.add(userPositionVO);
+            }
+        }
+        BigDecimal profitAndLose = BigDecimal.ZERO;
+        for (UserPositionVO f : userPositionVOS) {
+            profitAndLose = profitAndLose.add(f.getProfitAndLose());
+        }
+        return profitAndLose;
+    }
+
     @Override
     public ServerResponse transfer(String fromType, String toType, String amt,HttpServletRequest request) {
         User user =  userService.getCurrentUser(request);
diff --git a/src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java b/src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java
index cb37e3b..21dd53c 100644
--- a/src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java
@@ -1,13 +1,17 @@
 package com.nq.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.nq.common.ServerResponse;
+import com.nq.dao.StockMapper;
 import com.nq.dao.StockSubscribeMapper;
 import com.nq.dao.UserMapper;
 import com.nq.dao.UserStockSubscribeMapper;
+import com.nq.enums.EStockType;
+import com.nq.enums.EUserAssets;
 import com.nq.pojo.*;
 import com.nq.service.*;
 import com.nq.utils.timeutil.DateTimeUtil;
@@ -59,6 +63,10 @@
     ISiteSettingService iSiteSettingService;
     @Autowired
     TradingHourServiceImpl tradingHourService;
+    @Resource
+    IUserAssetsServices iUserAssetsServices;
+    @Autowired
+    StockMapper stockMapper;
     /**
      * 用户新股申购
      * @param model
@@ -81,14 +89,8 @@
                 if (siteProduct.getRealNameDisplay() && (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()))) {
                     return ServerResponse.createByErrorMsg("订单失败,请先实名认证",request);
                 }
-//                //判断休息日不能买入
-//                if (siteProduct.getHolidayDisplay()) {
-//                    return ServerResponse.createByErrorMsg("No trading on weekends or holidays!");
-//                }
-                //判断股票是否在可交易时间段
-                Boolean b = tradingHourService.timeCheck();
-                if (b) {
-                    return ServerResponse.createByErrorMsg("订单失败,不在股票交易时段",request);
+                if(new Date().before(stockSubscribe.getSubscribeTime())){
+                    return ServerResponse.createByErrorMsg("未到申购时间",request);
                 }
                 //重复申购限制
                 UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.selectOne(new QueryWrapper<UserStockSubscribe>().eq("new_code", model.getNewCode()).eq("user_id", user.getId()));
@@ -183,23 +185,7 @@
 
                     siteMessage.setAddTime(DateTimeUtil.getCurrentDate());
 
-
-                    if (stockSubscribe.getType() == 2){
-                        User user = userMapper.selectById(userStockSubscribe.getUserId());
-                        UserStockSubscribe userStockSubscribe1 = userStockSubscribeMapper.load(model.getId());
-                        int refundenum = userStockSubscribe1.getApplyNums() - model.getApplyNumber();
-//                        log.info("refundenum"+refundenum);
-                        Integer refund =refundenum * stockSubscribe.getPrice().intValue();
-//                        log.info("退还金额"+refund);
-                       int ret1 = userMapper.updateByPrimaryKey(user);
-                       if (ret1 <= 0) {
-                                return ServerResponse.createByErrorMsg("Application failed due to unknown reasons");
-                            }
-                        siteMessage.setContent("【新股申购中签】恭喜您,新股申购中签成功,申购金额:"+ userStockSubscribe.getBond() +"退还"+refund+",请及时关注哦。");
-                    }else {
-
-                        siteMessage.setContent("【新股申购中签】恭喜您,新股申购中签成功,申购金额:" + userStockSubscribe.getBond() + ",请及时关注哦。");
-                    }
+                    siteMessage.setContent("【新股申购中签】恭喜您,新股申购中签成功,申购金额:"+ userStockSubscribe.getBond() );
                     iSiteMessageService.insert(siteMessage);
                 }else
                 if(ret>0 && model.getStatus() == 2) {
@@ -367,39 +353,39 @@
                 return ServerResponse.createByErrorMsg("参数错误",request);
             }
             UserStockSubscribe userStockSubscribe = userStockSubscribeMapper.load(id);
-            log.info("userStockSubscribe:{}",userStockSubscribe);
             if (userStockSubscribe != null && userStockSubscribe.getUserId().equals(user.getId())) {
-                StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<>(new StockSubscribe()).eq("code", userStockSubscribe.getNewCode()));
-                if(userStockSubscribe.getType()== 2 ){
+                StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<>(new StockSubscribe())
+                        .eq("code", userStockSubscribe.getNewCode()));
+                if(userStockSubscribe.getStatus()== 2 ){
                     return ServerResponse.createByErrorMsg("未中签,无需支付",request);
                 }
-                //判断时间
-                if (stockSubscribe.getSubscriptionTime().getTime() < System.currentTimeMillis()) {
-                    return ServerResponse.createByErrorMsg("不在认缴时间之内",request);
+                if(null == stockSubscribe){
+                    return  ServerResponse.createByErrorMsg("新股不存在",request);
+                }
+                Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockCode, stockSubscribe.getCode()));
+                if(null == stock){
+                    return  ServerResponse.createByErrorMsg("股票不存在",request);
                 }
                 if (userStockSubscribe.getStatus() == 3) {
                     userStockSubscribe.setSubmitTime(DateTimeUtil.getCurrentDate());
                     userStockSubscribe.setStatus(4);
+                    BigDecimal bigDecimal =  iUserAssetsServices.
+                            getAvailableBalance(stock.getStockType(),
+                                    userStockSubscribe.getUserId());
 
-                    User user1 = userMapper.selectById(userStockSubscribe.getUserId());
-                    ret = userMapper.updateById(user1);
-                }
-                else {
+                    BigDecimal multiply = userStockSubscribe.getBuyPrice().multiply(new BigDecimal(userStockSubscribe.getApplyNumber()));
+                    if(bigDecimal.compareTo(multiply) < 0){
+                        return ServerResponse.createByErrorMsg("余额不足",request);
+                    }
+                    iUserAssetsServices.availablebalanceChange(stock.getStockType(),userStockSubscribe.getUserId(),
+                            EUserAssets.BUY,multiply.negate(),"","");
+                    userStockSubscribeMapper.update1(userStockSubscribe);
+                    return  ServerResponse.createBySuccess();
+                } else {
                     return ServerResponse.createByErrorMsg("不成功的申请者不收取任何费用",request);
                 }
             } else {
                 return ServerResponse.createByErrorMsg("新股认购订单不存在!",request);
-            }
-
-            if (ret > 0) {
-                ret = userStockSubscribeMapper.update1(userStockSubscribe);
-                if (ret > 0) {
-                    return ServerResponse.createBySuccessMsg("成功操作",request);
-                } else {
-                    return ServerResponse.createByErrorMsg("失败操作",request);
-                }
-            }else {
-                return ServerResponse.createByErrorMsg("扣除失败",request);
             }
         }
         return ServerResponse.createByErrorMsg("请先登录",request);
diff --git a/src/main/java/com/nq/utils/task/stock/StockTask.java b/src/main/java/com/nq/utils/task/stock/StockTask.java
index a45fb92..f79c87d 100644
--- a/src/main/java/com/nq/utils/task/stock/StockTask.java
+++ b/src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -1,15 +1,23 @@
 package com.nq.utils.task.stock;
 
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.google.gson.Gson;
+import com.nq.common.ServerResponse;
 import com.nq.dao.*;
 import com.nq.enums.EStockType;
 import com.nq.pojo.*;
 import com.nq.service.IMandatoryLiquidationService;
 import com.nq.service.IStockService;
+import com.nq.service.IUserAssetsServices;
+import com.nq.service.IUserPositionService;
 import com.nq.utils.http.HttpClientRequest;
 import com.nq.utils.redis.RedisKeyUtil;
+import com.nq.utils.redis.RedisShardedPoolUtils;
 import com.nq.utils.stock.BuyAndSellUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,6 +29,9 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
 
 
 @Component
@@ -30,10 +41,34 @@
     @Autowired
     StockMapper stockMapper;
 
+    @Autowired
+    IUserPositionService userPositionService;
+
+    @Autowired
+    UserPositionMapper userPositionMapper;
 
     @Autowired
     IMandatoryLiquidationService mandatoryLiquidationService;
 
+    @Autowired
+    UserStockSubscribeMapper userStockSubscribeMapper;
+
+
+    @Autowired
+    StockSubscribeMapper stockSubscribeMapper;
+
+    @Autowired
+    IUserPositionService iUserPositionService;
+
+
+    @Autowired
+    IUserAssetsServices userAssetsServices;
+
+    private final Lock ballotLock = new ReentrantLock();
+
+    private final Lock subscriptionLock = new ReentrantLock();
+
+    private final Lock stockConstraintLock = new ReentrantLock();
 
 
     private static final Logger log = LoggerFactory.getLogger(StockTask.class);
@@ -42,9 +77,8 @@
     /**
      * 同步系统所需要的股票
      * */
-    @Scheduled(cron = "0 0/1 *  * * ?")
+    @Scheduled(cron = "0 0 0/2  * * ?")
     public void syncINStockData() {
-        loadAllStock(EStockType.US);
         loadAllStock(EStockType.IN);
 //        loadAllStock(EStockType.HK);
     }
@@ -55,10 +89,10 @@
     /**
      * 同步美国股票
      * */
-//    @Scheduled(cron = "0 0/3 * * * ?")
-//    public  void loadStockCompanies(){
-//        loadAllCompanies();
-//    }
+//    @Scheduled(cron = "0 0/30 * * * ?")
+    public  void loadStockCompanies(){
+        loadAllCompanies();
+    }
 
 
 
@@ -147,4 +181,87 @@
             log.error("同步出错", e);
         }
     }
+
+    @Scheduled(cron = "0 0/10 * * * ?")
+    public void ballot() {
+        if (ballotLock.tryLock()) {
+            try {
+                log.info("新股上市转持仓定时任务--------->开始");
+                List<StockSubscribe> stockSubscribes = stockSubscribeMapper.selectList(new LambdaQueryWrapper<StockSubscribe>()
+                        .lt(StockSubscribe::getListDate, DateUtil.date()));
+                if (CollectionUtils.isNotEmpty(stockSubscribes)) {
+                    List<String> codeList = stockSubscribes.stream().map(StockSubscribe::getCode).collect(Collectors.toList());
+                    List<UserStockSubscribe> userStockSubscribes = userStockSubscribeMapper.selectList(new LambdaQueryWrapper<UserStockSubscribe>()
+                            .eq(UserStockSubscribe::getStatus, 4).in(UserStockSubscribe::getNewCode, codeList));
+                    //订单转持仓
+                    userStockSubscribes.forEach(f -> {
+                        ServerResponse serverResponse = iUserPositionService.newStockToPosition(f.getId());//转持仓
+                        if(serverResponse.isSuccess()){
+                            f.setStatus(5);
+                            userStockSubscribeMapper.updateById(f);
+                        }else{
+                            log.info("新股上市转持仓失败申购订单id:"+f.getId()+",失败原因:"+serverResponse.getMsg());
+                        }
+                    });
+                }
+                log.info("新股上市转持仓定时任务--------->结束");
+            } catch (Exception e) {
+                log.error("新股上市转持仓定时任务发生异常", e);
+            } finally {
+                ballotLock.unlock();
+            }
+        } else {
+            log.info("新股上市转持仓定时任务--------->上次任务还未执行完成,本次任务忽略");
+        }
+    }
+
+//    @Scheduled(cron = "0/5 * * * * ?")
+//    public void subscription() {
+//        if (subscriptionLock.tryLock()) {
+//            try {
+//                log.info("自动转已认缴--------->开始");
+//                List<UserStockSubscribe> userStockSubscribes = userStockSubscribeMapper.selectList(new LambdaQueryWrapper<UserStockSubscribe>()
+//                        .eq(UserStockSubscribe::getStatus, 3));
+//                userStockSubscribes.forEach(f->{
+//                    Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockCode, f.getNewCode()));
+//                    UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId(stock.getStockType(),f.getUserId());
+//                    if(null != userAssets && userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) == 0){
+//                        f.setStatus(4);
+//                        userStockSubscribeMapper.updateById(f);
+//                    }
+//                });
+//                log.info("自动转已认缴--------->结束");
+//            } catch (Exception e) {
+//                log.error("自动转已认缴定时任务发生异常", e);
+//            } finally {
+//                subscriptionLock.unlock();
+//            }
+//        } else {
+//            log.info("自动转已认缴定时任务--------->上次任务还未执行完成,本次任务忽略");
+//        }
+//    }
+
+    /**
+     * 强制平仓
+     */
+    @Scheduled(cron = "0/1 * * * * ?")
+    public void stockConstraint(){
+        if (stockConstraintLock.tryLock()) {
+            log.info("强制平仓任务:--------->开始");
+            try {
+                List<UserPosition> userPositions = userPositionMapper.selectList(new LambdaQueryWrapper<UserPosition>().isNull(UserPosition::getSellOrderId));
+                if(CollectionUtils.isNotEmpty(userPositions)){
+                    userPositionService.stockConstraint(userPositions);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                log.error("强制平仓任务错误:" + e.getMessage());
+            } finally {
+                stockConstraintLock.unlock();
+                log.info("强制平仓任务:--------->结束");
+            }
+        } else {
+            log.info("强制平仓任务--------->上次任务还未执行完成,本次任务忽略");
+        }
+    }
 }

--
Gitblit v1.9.3