From 9b96b21235ee41b47bfdeaa745ee2e56a119e09e Mon Sep 17 00:00:00 2001
From: peternameyakj <908253177@qq.com>
Date: Sun, 14 Jul 2024 17:54:42 +0800
Subject: [PATCH] 部分平仓

---
 src/main/java/com/nq/utils/task/OrderTask.java                                 |   22 +
 src/main/java/com/nq/service/IUserPurchaseApplicationService.java              |   13 
 src/main/java/com/nq/dao/SiteVipRobMapper.java                                 |    9 
 src/main/java/com/nq/service/impl/UserPositionServiceImpl.java                 |  141 ++++++++-
 src/main/java/com/nq/controller/backend/UserPurchaseApplicationController.java |   34 ++
 src/main/java/com/nq/service/IUserPositionService.java                         |    6 
 src/main/java/com/nq/common/ServerResponse.java                                |    3 
 src/main/java/com/nq/pojo/UserPurchaseApplication.java                         |   39 ++
 src/main/java/com/nq/service/impl/SiteVipRobServiceImpl.java                   |  130 ++++++++
 src/main/java/com/nq/controller/UserApiController.java                         |    3 
 src/main/java/com/nq/controller/backend/AdminPendingorder.java                 |   17 
 src/main/java/com/nq/service/IUserAssetsServices.java                          |   12 
 src/main/java/com/nq/service/impl/StockConfigServicesImpl.java                 |   20 +
 src/main/java/com/nq/controller/backend/AdminSiteVipRobController.java         |   52 +++
 src/main/java/com/nq/dao/UserPurchaseApplicationMapper.java                    |    9 
 src/main/java/com/nq/enums/EUserAssets.java                                    |    1 
 src/main/java/com/nq/vo/position/UserPendingorderVO.java                       |    1 
 src/main/java/com/nq/service/impl/UserPendingorderServiceImpl.java             |  116 +++++--
 src/main/java/com/nq/service/impl/UserAssetsServices.java                      |   28 +
 src/main/java/com/nq/service/IStockConfigServices.java                         |    5 
 src/main/resources/mapper/UserPositionMapper.xml                               |    4 
 src/main/java/com/nq/service/impl/UserPurchaseApplicationServiceImpl.java      |   92 ++++++
 src/main/java/com/nq/controller/protol/UserController.java                     |   23 +
 src/main/java/com/nq/service/ISiteVipRobService.java                           |   13 
 src/main/java/com/nq/service/UserPendingorderService.java                      |    4 
 src/main/java/com/nq/pojo/SiteVipRob.java                                      |   44 ++
 26 files changed, 771 insertions(+), 70 deletions(-)

diff --git a/src/main/java/com/nq/common/ServerResponse.java b/src/main/java/com/nq/common/ServerResponse.java
index 208c7ac..3355367 100644
--- a/src/main/java/com/nq/common/ServerResponse.java
+++ b/src/main/java/com/nq/common/ServerResponse.java
@@ -105,6 +105,9 @@
     public static <T> ServerResponse<T> createByErrorMsg(String errormsg, HttpServletRequest request) {
         return new ServerResponse(ResponseCode.ERROR.getCode(), new GoogleTranslateUtil().translate(errormsg,request.getHeader(LANG)));
     }
+    public static <T> ServerResponse<T> createByErrorMsg(String errormsg, String langFrom ,String lang) throws Exception {
+        return new ServerResponse(ResponseCode.ERROR.getCode(), new GoogleTranslateUtil().translate(langFrom,lang,errormsg));
+    }
 
 
     public static <T> ServerResponse<T> createByErrorCodeMsg(int errorcode, String errormsg) {
diff --git a/src/main/java/com/nq/controller/UserApiController.java b/src/main/java/com/nq/controller/UserApiController.java
index 8c42607..096d45c 100644
--- a/src/main/java/com/nq/controller/UserApiController.java
+++ b/src/main/java/com/nq/controller/UserApiController.java
@@ -17,6 +17,7 @@
 
 import com.nq.utils.redis.RedisShardedPoolUtils;
 
+import com.nq.utils.translate.GoogleTranslateUtil;
 import com.nq.vo.user.UserLoginResultVO;
 
 import javax.servlet.http.HttpServletRequest;
@@ -75,7 +76,7 @@
             UserLoginResultVO resultVO = new UserLoginResultVO();
             resultVO.setKey(pc_cookie_name);
             resultVO.setToken(token);
-            return ServerResponse.createBySuccess("登录成功", resultVO);
+            return ServerResponse.createBySuccess(new GoogleTranslateUtil().translate("登录成功",request.getHeader("lang")), resultVO);
         }
         return serverResponse;
     }
diff --git a/src/main/java/com/nq/controller/backend/AdminPendingorder.java b/src/main/java/com/nq/controller/backend/AdminPendingorder.java
index f330f0a..8d136fc 100644
--- a/src/main/java/com/nq/controller/backend/AdminPendingorder.java
+++ b/src/main/java/com/nq/controller/backend/AdminPendingorder.java
@@ -5,10 +5,7 @@
 import com.nq.service.UserPendingorderService;
 import com.nq.vo.position.UserPendingorderVO;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 
@@ -28,7 +25,7 @@
      * @return
      */
     @GetMapping({"orderList.do"})
-    public ServerResponse orderList(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,@RequestParam(value = "keywords", required = false) String keywords,@RequestParam(value = "status", required = false) String status, HttpServletRequest request) {
+    public ServerResponse orderList(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,@RequestParam(value = "keywords", required = false) String keywords,@RequestParam(value = "status", required = false) Integer status, HttpServletRequest request) {
         return userPendingorderService.orderListByAdmin( pageNum,  pageSize, keywords, status, request);
     }
 
@@ -44,6 +41,16 @@
     }
 
     /**
+     * 管理员审核挂单
+     * @param id
+     * @return
+     */
+    @PostMapping({"examine.do"})
+    public ServerResponse examine(Integer id,HttpServletRequest request) {
+        return userPendingorderService.examine(id);
+    }
+
+    /**
      * 管理员修改挂单
      * @param UserPendingorder
      * @param request
diff --git a/src/main/java/com/nq/controller/backend/AdminSiteVipRobController.java b/src/main/java/com/nq/controller/backend/AdminSiteVipRobController.java
new file mode 100644
index 0000000..4192e59
--- /dev/null
+++ b/src/main/java/com/nq/controller/backend/AdminSiteVipRobController.java
@@ -0,0 +1,52 @@
+package com.nq.controller.backend;
+
+import com.nq.common.ServerResponse;
+import com.nq.pojo.SiteVipRob;
+import com.nq.service.ISiteVipRobService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+@Controller
+@RequestMapping({"/admin/sitevip/"})
+public class AdminSiteVipRobController {
+
+    @Autowired
+    private ISiteVipRobService iSiteVipRobService;
+
+    //添加VIP抢筹配置
+    @PostMapping({"add.do"})
+    @ResponseBody
+    public ServerResponse add(SiteVipRob siteVipRob) {
+        return iSiteVipRobService.insert(siteVipRob);
+    }
+
+    //修改VIP抢筹配置
+    @PostMapping({"update.do"})
+    @ResponseBody
+    public ServerResponse update(SiteVipRob siteVipRob) {
+
+        return iSiteVipRobService.modify(siteVipRob);
+    }
+
+    @PostMapping({"updateStatus.do"})
+    @ResponseBody
+    public ServerResponse updateStatus(@RequestParam("id") Integer id,@RequestParam("status") Integer status) {
+
+        return iSiteVipRobService.updateStatus(id,status);
+    }
+
+    //分页查VIP抢筹配置
+    @GetMapping({"list.do"})
+    @ResponseBody
+    public ServerResponse list(@RequestParam("keyword") String keyword,@RequestParam("status") Integer status, @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
+        return iSiteVipRobService.list(keyword,status,pageNum, pageSize);
+    }
+
+    //删除VIP抢筹配置
+    @GetMapping({"del.do"})
+    @ResponseBody
+    public ServerResponse del(@RequestParam("id") Integer id) {
+        return iSiteVipRobService.removeById(id)?ServerResponse.createBySuccessMsg("删除成功"):ServerResponse.createByErrorMsg("删除失败");
+    }
+}
diff --git a/src/main/java/com/nq/controller/backend/UserPurchaseApplicationController.java b/src/main/java/com/nq/controller/backend/UserPurchaseApplicationController.java
new file mode 100644
index 0000000..2ad7233
--- /dev/null
+++ b/src/main/java/com/nq/controller/backend/UserPurchaseApplicationController.java
@@ -0,0 +1,34 @@
+package com.nq.controller.backend;
+
+import com.nq.common.ServerResponse;
+import com.nq.service.IUserPurchaseApplicationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+@Controller
+@RequestMapping({"/admin/purchase/"})
+public class UserPurchaseApplicationController {
+
+    @Autowired
+    private IUserPurchaseApplicationService purchaseApplicationService;
+
+    //分页查VIP抢筹配置
+    @GetMapping({"list.do"})
+    @ResponseBody
+    public ServerResponse list(@RequestParam("keywords") String keyword,@RequestParam("status") Integer status, @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
+        return purchaseApplicationService.list(keyword,status,pageNum, pageSize);
+    }
+    /**
+     * 管理员审核挂单
+     * @param id
+     * @return
+     */
+    @PostMapping({"examine.do"})
+    @ResponseBody
+    public ServerResponse examine(Integer id, HttpServletRequest request) {
+        return purchaseApplicationService.examine(id,request);
+    }
+}
diff --git a/src/main/java/com/nq/controller/protol/UserController.java b/src/main/java/com/nq/controller/protol/UserController.java
index 6c4315c..469ae58 100644
--- a/src/main/java/com/nq/controller/protol/UserController.java
+++ b/src/main/java/com/nq/controller/protol/UserController.java
@@ -23,6 +23,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -60,10 +61,11 @@
     @Autowired
     IUserRechargeService iUserRechargeService;
 
-
-
     @Autowired
     IApplyLeverServices iApplyLeverServices;
+
+    @Autowired
+    private ISiteVipRobService iSiteVipRobService;
 
     private static final ThreadLocal<Boolean> orderCreated = ThreadLocal.withInitial(() -> false);
     private final Lock lock = new ReentrantLock();
@@ -112,6 +114,7 @@
                               @RequestParam("buyNum") Integer buyNum,
                               @RequestParam("buyType") Integer buyType,
                               @RequestParam("lever") Integer lever,
+                              @RequestParam("password") String password,
                               @RequestParam(value = "profitTarget",required = false)
                                   BigDecimal profitTarget,@RequestParam(value = "stopLoss",required = false) BigDecimal stopLoss, HttpServletRequest request) {
         buyLock.lock();
@@ -120,13 +123,23 @@
                 return ServerResponse.createByErrorMsg("当前下单人数过多,请稍后重试", request);
             }
             buyOrderCreated.set(true);
-            return this.iUserPositionService.buy(stockId, buyNum, buyType, lever,profitTarget,stopLoss, request);
+            return this.iUserPositionService.buy(stockId, buyNum, buyType, lever,profitTarget,stopLoss, password,request,null);
         } catch (Exception e) {
             return ServerResponse.createByErrorMsg("订单异常,请稍后重试", request);
         }  finally{
             buyLock.unlock();
             buyOrderCreated.set(false);
         }
+    }
+    @GetMapping("checkStockVip.do")
+    @ResponseBody
+    public ServerResponse checkStockVip(@RequestParam("stockId") Integer stockId,
+                                        @RequestParam("buyNum") Integer buyNum,
+                                        @RequestParam("buyType") Integer buyType,
+                                        @RequestParam("lever") Integer lever,
+                                        @RequestParam(value = "profitTarget",required = false) BigDecimal profitTarget,
+                                        @RequestParam(value = "stopLoss",required = false) BigDecimal stopLoss, HttpServletRequest request){
+        return ServerResponse.createBySuccess(iUserPositionService.checkStockVip(stockId,buyNum,buyType,lever,profitTarget,stopLoss,request));
     }
     //修改涨跌板
     @RequestMapping({"updateProfitTarget.do"})
@@ -143,8 +156,8 @@
     //用户平仓操作
     @RequestMapping({"sell.do"})
     @ResponseBody
-    public ServerResponse sell(HttpServletRequest request, @RequestParam("positionSn") String positionSn) {
-            return this.iUserPositionService.sell(positionSn, 1,request);
+    public ServerResponse sell(HttpServletRequest request, @RequestParam("positionSn") String positionSn, @RequestParam("closeNumber") Integer closeNumber) {
+            return this.iUserPositionService.sell(positionSn,closeNumber, 1,request);
     }
 
 
diff --git a/src/main/java/com/nq/dao/SiteVipRobMapper.java b/src/main/java/com/nq/dao/SiteVipRobMapper.java
new file mode 100644
index 0000000..ef6b0df
--- /dev/null
+++ b/src/main/java/com/nq/dao/SiteVipRobMapper.java
@@ -0,0 +1,9 @@
+package com.nq.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nq.pojo.SiteVipRob;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface SiteVipRobMapper extends BaseMapper<SiteVipRob> {
+}
diff --git a/src/main/java/com/nq/dao/UserPurchaseApplicationMapper.java b/src/main/java/com/nq/dao/UserPurchaseApplicationMapper.java
new file mode 100644
index 0000000..0765191
--- /dev/null
+++ b/src/main/java/com/nq/dao/UserPurchaseApplicationMapper.java
@@ -0,0 +1,9 @@
+package com.nq.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nq.pojo.UserPurchaseApplication;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface UserPurchaseApplicationMapper extends BaseMapper<UserPurchaseApplication> {
+}
diff --git a/src/main/java/com/nq/enums/EUserAssets.java b/src/main/java/com/nq/enums/EUserAssets.java
index 4036884..ea764e7 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","平仓"),
+    PART_CLOSE_POSITION("PART_CLOSE_POSITION","平仓"),
     CONSTRAINT_CLOSE_POSITION("CONSTRAINT_CLOSE_POSITION","强制平仓"),
     BUY("BUY","购买"),
     WITHDRAW("WITHDRAW","提现"),
diff --git a/src/main/java/com/nq/pojo/SiteVipRob.java b/src/main/java/com/nq/pojo/SiteVipRob.java
new file mode 100644
index 0000000..9807a88
--- /dev/null
+++ b/src/main/java/com/nq/pojo/SiteVipRob.java
@@ -0,0 +1,44 @@
+package com.nq.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@TableName("site_vip_rob")
+public class SiteVipRob {
+    @TableId(type = IdType.AUTO,value = "id")
+    private Integer id;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 股票代码
+     */
+    private String stockCode;
+    /**
+     * 涨跌幅
+     */
+    private BigDecimal stockChg;
+    /**
+     * 状态 0关 1开
+     */
+    private Integer status;
+    /**
+     * 最低交易数量(手)
+     */
+    private Integer lowestTrade;
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    private Date updateTime;
+}
diff --git a/src/main/java/com/nq/pojo/UserPurchaseApplication.java b/src/main/java/com/nq/pojo/UserPurchaseApplication.java
new file mode 100644
index 0000000..1fa3065
--- /dev/null
+++ b/src/main/java/com/nq/pojo/UserPurchaseApplication.java
@@ -0,0 +1,39 @@
+package com.nq.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+@TableName(value ="user_purchase_application")
+@Data
+public class UserPurchaseApplication {
+    @TableId(type = IdType.AUTO,value = "id")
+    private Integer id;
+
+    private Integer userId;
+
+    private String stockCode;
+
+    private Integer buyNum;
+
+    private Integer buyType;
+
+    private Integer lever;
+
+    private BigDecimal profitTarget;
+
+    private BigDecimal stopTarget;
+
+    private BigDecimal nowPrice;
+
+    private Date addTime;
+
+    private Integer status;
+
+    private static final long serialVersionUID = 1L;
+}
diff --git a/src/main/java/com/nq/service/ISiteVipRobService.java b/src/main/java/com/nq/service/ISiteVipRobService.java
new file mode 100644
index 0000000..5690b05
--- /dev/null
+++ b/src/main/java/com/nq/service/ISiteVipRobService.java
@@ -0,0 +1,13 @@
+package com.nq.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nq.common.ServerResponse;
+import com.nq.pojo.SiteVipRob;
+
+public interface ISiteVipRobService extends IService<SiteVipRob> {
+    ServerResponse insert(SiteVipRob siteVipRob);
+    ServerResponse modify(SiteVipRob siteVipRob);
+    ServerResponse list(String keyword,Integer status,int pageNum,int pageSize);
+    SiteVipRob getByStockCode(String stockCode);
+    ServerResponse updateStatus(Integer id,Integer status);
+}
diff --git a/src/main/java/com/nq/service/IStockConfigServices.java b/src/main/java/com/nq/service/IStockConfigServices.java
index 48d3c96..155bef2 100644
--- a/src/main/java/com/nq/service/IStockConfigServices.java
+++ b/src/main/java/com/nq/service/IStockConfigServices.java
@@ -3,6 +3,9 @@
 import com.nq.common.ServerResponse;
 import com.nq.pojo.StockConfig;
 
+import java.util.List;
+import java.util.Map;
+
 public interface IStockConfigServices {
 
 
@@ -15,4 +18,6 @@
 
     StockConfig queryByKey(String key);
 
+    Map<String, StockConfig> queryByKeys(List<String> key);
+
 }
diff --git a/src/main/java/com/nq/service/IUserAssetsServices.java b/src/main/java/com/nq/service/IUserAssetsServices.java
index ae7475a..bec35c2 100644
--- a/src/main/java/com/nq/service/IUserAssetsServices.java
+++ b/src/main/java/com/nq/service/IUserAssetsServices.java
@@ -35,6 +35,8 @@
     BigDecimal getAvailableBalance(String accetType,Integer userId);
 
 
+    int updateById(UserAssets userAssets);
+
 
 
     /**
@@ -47,5 +49,13 @@
      * */
     Boolean availablebalanceChange(String accetType, Integer userId, EUserAssets eUserAssets, BigDecimal amount, String desc, String descType);
 
-
+    /**
+     * 部分平仓用
+     * @param accetType  资产类型
+     * @param userId  用户id
+     * @param eUserAssets EUserAssets
+     * @param  amount 金额
+     * @param  freezeMoney 解除冻结金额
+     * */
+    Boolean availablebalanceChangePart(String accetType, Integer userId, EUserAssets eUserAssets, BigDecimal amount, BigDecimal freezeMoney);
 }
diff --git a/src/main/java/com/nq/service/IUserPositionService.java b/src/main/java/com/nq/service/IUserPositionService.java
index 19a31e3..13734b5 100644
--- a/src/main/java/com/nq/service/IUserPositionService.java
+++ b/src/main/java/com/nq/service/IUserPositionService.java
@@ -13,10 +13,10 @@
 
 public interface IUserPositionService {
   ServerResponse buy(Integer paramInteger1, Integer paramInteger2, Integer paramInteger3,
-                     Integer paramInteger4,BigDecimal paramInteger5,BigDecimal paramInteger6, HttpServletRequest paramHttpServletRequest) ;
+                     Integer paramInteger4,BigDecimal paramInteger5,BigDecimal paramInteger6,String password,HttpServletRequest paramHttpServletRequest,Integer userId) ;
   
   ServerResponse sell(String paramString, int paramInt);
-  ServerResponse sell(String paramString, int paramInt,  HttpServletRequest request);
+  ServerResponse sell(String paramString,Integer closeNumber, int paramInt,  HttpServletRequest request);
 
   ServerResponse allSell(HttpServletRequest request,String stockType)throws  Exception;
   
@@ -85,4 +85,6 @@
   ServerResponse buyStockDzList(HttpServletRequest request);
 
   void stockConstraint(List<UserPosition> userPositions);
+
+  Integer checkStockVip(Integer stockId,Integer buyNum,Integer buyType,Integer lever,BigDecimal profitTarget,BigDecimal stopLoss, HttpServletRequest request);
 }
diff --git a/src/main/java/com/nq/service/IUserPurchaseApplicationService.java b/src/main/java/com/nq/service/IUserPurchaseApplicationService.java
new file mode 100644
index 0000000..973d114
--- /dev/null
+++ b/src/main/java/com/nq/service/IUserPurchaseApplicationService.java
@@ -0,0 +1,13 @@
+package com.nq.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nq.common.ServerResponse;
+import com.nq.pojo.UserPurchaseApplication;
+
+import javax.servlet.http.HttpServletRequest;
+
+public interface IUserPurchaseApplicationService extends IService<UserPurchaseApplication> {
+    ServerResponse list(String keyword,Integer status,int pageNum,int pageSize);
+    ServerResponse examine(Integer id, HttpServletRequest request);
+
+}
diff --git a/src/main/java/com/nq/service/UserPendingorderService.java b/src/main/java/com/nq/service/UserPendingorderService.java
index 4c86362..72511a3 100644
--- a/src/main/java/com/nq/service/UserPendingorderService.java
+++ b/src/main/java/com/nq/service/UserPendingorderService.java
@@ -24,11 +24,13 @@
     ServerResponse delOrder(Integer id, HttpServletRequest request);
 
 
-    ServerResponse orderListByAdmin(int pageNum, int pageSize, String keywords, String status, HttpServletRequest request);
+    ServerResponse orderListByAdmin(int pageNum, int pageSize, String keywords, Integer status, HttpServletRequest request);
 
     ServerResponse updateOrderByAdmin(UserPendingorder userPendingorder);
 
     ServerResponse addOrderByAdmin(String phone, String buyNum,String code, String buyType, String lever, String targetPrice, HttpServletRequest request);
 
     ServerResponse delOrderByAdmin(Integer id);
+
+    ServerResponse examine(Integer id);
 }
diff --git a/src/main/java/com/nq/service/impl/SiteVipRobServiceImpl.java b/src/main/java/com/nq/service/impl/SiteVipRobServiceImpl.java
new file mode 100644
index 0000000..0ee8d2a
--- /dev/null
+++ b/src/main/java/com/nq/service/impl/SiteVipRobServiceImpl.java
@@ -0,0 +1,130 @@
+package com.nq.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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.SiteVipRobMapper;
+import com.nq.dao.StockMapper;
+import com.nq.pojo.SiteVipRob;
+import com.nq.pojo.Stock;
+import com.nq.pojo.UserPurchaseApplication;
+import com.nq.service.ISiteVipRobService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+@Service("iSiteVipRobService")
+public class SiteVipRobServiceImpl extends ServiceImpl<SiteVipRobMapper, SiteVipRob> implements ISiteVipRobService {
+    private static final Logger log = LoggerFactory.getLogger(SiteVipRobServiceImpl.class);
+
+    @Autowired
+    SiteVipRobMapper siteVipRobMapper;
+    @Autowired
+    StockMapper stockMapper;
+
+    @Override
+    public ServerResponse insert(SiteVipRob siteVipRob) {
+        // 构造查询条件
+        LambdaQueryWrapper<SiteVipRob> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(SiteVipRob::getStockCode, siteVipRob.getStockCode());
+        if(siteVipRob.getStockChg().compareTo(new BigDecimal(0)) < 0 || siteVipRob.getStockChg().compareTo(new BigDecimal(100)) >= 0){
+            return ServerResponse.createByErrorMsg("涨跌幅在0~100之间");
+        }
+        // 查询是否存在相同的股票代码设置
+        List<SiteVipRob> list = list(wrapper);
+        if (!list.isEmpty()) {
+            return ServerResponse.createByErrorMsg("该股票代码设置已存在");
+        }
+        Stock stock = stockMapper.findStockByCode(siteVipRob.getStockCode());
+        if(null == stock){
+            return ServerResponse.createByErrorMsg("股票代码不存在");
+        }
+        // 设置创建时间
+        siteVipRob.setCreateTime(new Date());
+
+        // 执行保存操作
+        if (save(siteVipRob)) {
+            return ServerResponse.createBySuccessMsg("添加成功");
+        } else {
+            return ServerResponse.createByErrorMsg("添加失败");
+        }
+    }
+
+
+    @Override
+    public ServerResponse modify(SiteVipRob siteVipRob) {
+        // 构造查询条件
+        LambdaQueryWrapper<SiteVipRob> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(SiteVipRob::getStockCode, siteVipRob.getStockCode())
+                .ne(SiteVipRob::getId, siteVipRob.getId());
+        if(siteVipRob.getStockChg().compareTo(new BigDecimal(0)) < 0 || siteVipRob.getStockChg().compareTo(new BigDecimal(100)) >= 0){
+            return ServerResponse.createByErrorMsg("涨跌幅在0~100之间");
+        }
+        // 查询是否存在相同的股票代码设置
+        List<SiteVipRob> list = list(wrapper);
+        if (!list.isEmpty()) {
+            return ServerResponse.createByErrorMsg("该股票代码设置已存在");
+        }
+        Stock stock = stockMapper.findStockByCode(siteVipRob.getStockCode());
+        if(null == stock){
+            return ServerResponse.createByErrorMsg("股票代码不存在");
+        }
+        // 更新修改时间
+        siteVipRob.setUpdateTime(new Date());
+
+        // 执行更新操作
+        if (updateById(siteVipRob)) {
+            return ServerResponse.createBySuccessMsg("修改成功");
+        } else {
+            return ServerResponse.createByErrorMsg("修改失败");
+        }
+    }
+
+
+    @Override
+    public ServerResponse list(String keyword, Integer status, int pageNum, int pageSize) {
+        // 创建分页对象
+        Page<SiteVipRob> page = new Page<>(pageNum, pageSize);
+
+        // 构造查询条件
+        LambdaQueryWrapper<SiteVipRob> wrapper = new LambdaQueryWrapper<>();
+        wrapper.and(q -> q.like(SiteVipRob::getStockCode, keyword).or().like(SiteVipRob::getName, keyword));
+        if (status != null) {
+            wrapper.eq(SiteVipRob::getStatus, status);
+        }
+        wrapper.orderByDesc(SiteVipRob::getCreateTime);
+        // 执行分页查询
+        IPage<SiteVipRob> resultPage = page(page, wrapper);
+
+        // 返回分页结果
+        return ServerResponse.createBySuccess(resultPage);
+    }
+
+
+    @Override
+    public SiteVipRob getByStockCode(String stockCode) {
+        LambdaQueryWrapper<SiteVipRob> wrapper = new LambdaQueryWrapper<SiteVipRob>().eq(SiteVipRob::getStockCode, stockCode);
+        return siteVipRobMapper.selectOne(wrapper);
+    }
+
+    @Override
+    public ServerResponse updateStatus(Integer id,Integer status) {
+        SiteVipRob siteVipRob = siteVipRobMapper.selectById(id);
+        siteVipRob.setStatus(status);
+        siteVipRob.setUpdateTime(new Date());
+        // 执行更新操作
+        if (updateById(siteVipRob)) {
+            return ServerResponse.createBySuccessMsg("修改成功");
+        } else {
+            return ServerResponse.createByErrorMsg("修改失败");
+        }
+    }
+
+}
diff --git a/src/main/java/com/nq/service/impl/StockConfigServicesImpl.java b/src/main/java/com/nq/service/impl/StockConfigServicesImpl.java
index 98000f9..da25c66 100644
--- a/src/main/java/com/nq/service/impl/StockConfigServicesImpl.java
+++ b/src/main/java/com/nq/service/impl/StockConfigServicesImpl.java
@@ -11,6 +11,10 @@
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Service
 public class StockConfigServicesImpl  implements IStockConfigServices {
@@ -42,4 +46,20 @@
         queryWrapper.eq("c_key",key);
         return stockConfigMapper.selectOne(queryWrapper);
     }
+
+    @Override
+    public Map<String, StockConfig> queryByKeys(List<String> keys) {
+        QueryWrapper<StockConfig> queryWrapper = new QueryWrapper<>();
+        queryWrapper.in("c_key", keys);
+
+        List<StockConfig> stockConfigs = stockConfigMapper.selectList(queryWrapper);
+
+        // 构建结果的 Map
+        Map<String, StockConfig> resultMap = new HashMap<>();
+        for (StockConfig config : stockConfigs) {
+            resultMap.put(config.getCKey(), config);
+        }
+
+        return resultMap;
+    }
 }
diff --git a/src/main/java/com/nq/service/impl/UserAssetsServices.java b/src/main/java/com/nq/service/impl/UserAssetsServices.java
index 7ab3733..7652a08 100644
--- a/src/main/java/com/nq/service/impl/UserAssetsServices.java
+++ b/src/main/java/com/nq/service/impl/UserAssetsServices.java
@@ -117,6 +117,34 @@
         return  assetsByTypeAndUserId(accetType,userId).getAvailableBalance();
     }
 
+    @Override
+    public int updateById(UserAssets userAssets) {
+        return userAssetsMapper.updateById(userAssets);
+    }
+
+    @Override
+    public Boolean availablebalanceChangePart(String accetType, Integer userId, EUserAssets eUserAssets, BigDecimal amount, BigDecimal freezeMoney) {
+        UserAssets userAssets =   assetsByTypeAndUserId(accetType,userId);
+        String before = userAssets.getAvailableBalance().toString();
+        String accectType = userAssets.getAccectType();
+        if(Objects.equals(eUserAssets.getCode(), EUserAssets.PART_CLOSE_POSITION.getCode())){
+            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
+            userAssets.setFreezeMoney(userAssets.getFreezeMoney().subtract(freezeMoney));
+        }
+        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(accectType);
+        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;
+    }
 
     @Override
     public Boolean availablebalanceChange(String accetType, Integer userId, EUserAssets eUserAssets, BigDecimal amount, String desc, String descType) {
diff --git a/src/main/java/com/nq/service/impl/UserPendingorderServiceImpl.java b/src/main/java/com/nq/service/impl/UserPendingorderServiceImpl.java
index f5637cb..52914a4 100644
--- a/src/main/java/com/nq/service/impl/UserPendingorderServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserPendingorderServiceImpl.java
@@ -1,10 +1,12 @@
 package com.nq.service.impl;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -12,6 +14,7 @@
 import com.github.pagehelper.PageInfo;
 import com.nq.common.ServerResponse;
 import com.nq.dao.*;
+import com.nq.enums.EStockType;
 import com.nq.pojo.*;
 import com.nq.service.*;
 import com.nq.utils.timeutil.DateTimeUtil;
@@ -65,6 +68,8 @@
     private ISiteSettingService iSiteSettingService;
     @Autowired
     private UserPositionMapper userPositionMapper;
+    @Autowired
+    UserAssetsMapper userAssetsMapper;
 
     @Override
     public ServerResponse addOrder(String stockId, Integer buyNum, Integer buyType, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, BigDecimal targetPrice, HttpServletRequest request) {
@@ -86,6 +91,15 @@
         if (userPendingorder != null) {
             return ServerResponse.createByErrorMsg("Please do not repeat the order");
         }
+
+        UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<UserAssets>()
+                .eq(UserAssets::getUserId, user.getId())
+                .eq(UserAssets::getAccectType, "IN")
+        );
+        BigDecimal amount = new BigDecimal(buyNum).multiply(targetPrice).setScale(5, RoundingMode.DOWN);
+        userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount.negate()));
+        userAssets.setFreezeMoney(userAssets.getFreezeMoney().add(amount));
+        userAssetsMapper.updateById(userAssets);
 
         userPendingorder = new UserPendingorder();
         userPendingorder.setUserId(user.getId());
@@ -118,7 +132,7 @@
             User user = (User) JsonUtil.string2Obj(userJson, User.class);
 //            log.info("user:{}",user);
             if (user != null) {
-                List<UserPendingorder> userPendingorders = userPendingorderMapper.selectList(new QueryWrapper<UserPendingorder>().eq("user_id", user.getId()));
+                List<UserPendingorder> userPendingorders = userPendingorderMapper.selectList(new QueryWrapper<UserPendingorder>().eq("user_id", user.getId()).ne("status",1));
 
                 List UserPendingorderList = new ArrayList();
 
@@ -208,7 +222,7 @@
                         //                        stockCoin = iStockCoinService.selectCoinByCode("USD");
                         ExchangeVO exchangeVO = this.iStockFuturesService.queryExchangeVO("USD").getData();
                         nowPrice = String.valueOf(new BigDecimal(stockListVO.getNowPrice()).multiply(new BigDecimal(exchangeVO.getNowPrice())));
-                    } else {
+                    }else {
                         stockListVO = StockApi.getStockRealTime(stock);
                         nowPrice = stockListVO.getNowPrice();
                     }
@@ -224,7 +238,7 @@
                     int ret = userPendingorder.getBuyType().intValue() == 0 ? userPendingorder.getTargetPrice().compareTo(new BigDecimal(nowPrice)) : new BigDecimal(nowPrice).compareTo(userPendingorder.getTargetPrice());
                     //当前时间String
                     String buyTime = DateTimeUtil.dateToStr(new Date());
-                    if (ret <= 0) {
+                    if (ret == 0) {
                         if (code != null && !"".equals(code)) {
                             try {
                                 this.iUserPositionService.create(userPendingorder.getUserId(), code, nowPrice, buyTime, userPendingorder.getBuyNum(), userPendingorder.getBuyType(), userPendingorder.getLever(), userPendingorder.getProfitTarget(), userPendingorder.getStopTarget());
@@ -303,6 +317,14 @@
             }
             int delCount = this.userPendingorderMapper.deleteById(id);
             if (delCount > 0) {
+                UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<UserAssets>()
+                        .eq(UserAssets::getUserId, user.getId())
+                        .eq(UserAssets::getAccectType, "IN")
+                );
+                BigDecimal amount = new BigDecimal(userPendingorder.getBuyNum()).multiply(userPendingorder.getTargetPrice()).setScale(5, RoundingMode.DOWN);
+                userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
+                userAssets.setFreezeMoney(userAssets.getFreezeMoney().add(amount.negate()));
+                userAssetsMapper.updateById(userAssets);
                 return ServerResponse.createByErrorMsg("Successfully deleted");
             }
             return ServerResponse.createByErrorMsg("Deletion failure");
@@ -313,9 +335,10 @@
 
 
     @Override
-    public ServerResponse orderListByAdmin(int pageNum, int pageSize, String keywords, String status, HttpServletRequest request) {
+    public ServerResponse orderListByAdmin(int pageNum, int pageSize, String keywords, Integer status, HttpServletRequest request) {
         PageHelper.startPage(pageNum, pageSize);
         QueryWrapper<UserPendingorder> queryWrapper = new QueryWrapper();
+        queryWrapper.eq("buy_type",0);
         if (keywords != null && !keywords.equals("")) {
             queryWrapper.like("stock_id", keywords).or().like("user_id", keywords);
         }
@@ -327,42 +350,37 @@
         List UserPendingorderList = new ArrayList();
         for (UserPendingorder userPendingorder : stockSubscribeList) {
             UserPendingorderVO userPendingorderVO = new UserPendingorderVO();
-            //挂单-指数
-            if (userPendingorder.getStockId().contains("sh") || userPendingorder.getStockId().contains("sz") || userPendingorder.getStockId().contains("hk") || userPendingorder.getStockId().contains("us")) {
-                StockIndex model = stockIndexMapper.selectIndexByCode(userPendingorder.getStockId().replace("sh", "").replace("sz", "").replace("hk", "").replace("us", ""));
-
-                MarketVO marketVO = this.iStockIndexService.querySingleIndex(model.getIndexGid());
-                userPendingorderVO.setNowPrice(new BigDecimal(marketVO.getNowPrice()));
-                userPendingorderVO.setStockName(model.getIndexName());
-                userPendingorderVO.setStockId(model.getIndexGid());
-
+            //挂单-股票
+            Stock stock = stockMapper.findStockByCode(userPendingorder.getStockId());
+            StockListVO stockListVO = new StockListVO();
+            if (stock.getStockType().equals("hk")) {
+                String hk = RedisShardedPoolUtils.get(stock.getStockGid(), 1);
+                stockListVO = StockApi.otherStockListVO(hk);
+            } else if (stock.getStockType().equals("us")) {
+                String us = RedisShardedPoolUtils.get(stock.getStockGid(), 2);
+                stockListVO = StockApi.otherStockListVO(us);
             } else {
-                //挂单-股票
-                Stock stock = stockMapper.findStockByCode(userPendingorder.getStockId());
-                StockListVO stockListVO = new StockListVO();
-                if (stock.getStockType().equals("hk")) {
-                    String hk = RedisShardedPoolUtils.get(stock.getStockGid(), 1);
-                    stockListVO = StockApi.otherStockListVO(hk);
-                } else if (stock.getStockType().equals("us")) {
-                    String us = RedisShardedPoolUtils.get(stock.getStockGid(), 2);
-                    stockListVO = StockApi.otherStockListVO(us);
-                } else {
-                    stockListVO = StockApi.getStockRealTime(
-                            stock);
-                }
-                String nowPrice = stockListVO.getNowPrice();
-                if (nowPrice == null) {
-                    nowPrice = String.valueOf(0);
-                }
-                userPendingorderVO.setNowPrice(new BigDecimal(nowPrice));
-                userPendingorderVO.setStockName(stock.getStockName());
-                userPendingorderVO.setStockId(stock.getStockCode());
+                stockListVO = StockApi.getStockRealTime(
+                        stock);
             }
+            String nowPrice = stockListVO.getNowPrice();
+            if (nowPrice == null) {
+                nowPrice = String.valueOf(0);
+            }
+            userPendingorderVO.setUserId(userPendingorder.getUserId());
+            userPendingorderVO.setNowPrice(new BigDecimal(nowPrice));
+            userPendingorderVO.setStockName(stock.getStockName());
+            userPendingorderVO.setStockId(stock.getStockCode());
             userPendingorderVO.setBuyNum(userPendingorder.getBuyNum());
             userPendingorderVO.setBuyType(userPendingorder.getBuyType());
             userPendingorderVO.setLever(userPendingorder.getLever());
-            userPendingorderVO.setProfitTarget(userPendingorder.getProfitTarget());
-            userPendingorderVO.setStopTarget(userPendingorder.getStopTarget());
+            if(null != userPendingorder.getProfitTarget()){
+                userPendingorderVO.setProfitTarget(userPendingorder.getProfitTarget());
+            }
+            if(null != userPendingorder.getStopTarget()){
+                userPendingorderVO.setStopTarget(userPendingorder.getStopTarget());
+            }
+
             userPendingorderVO.setTargetPrice(userPendingorder.getTargetPrice());
             userPendingorderVO.setAddTime(userPendingorder.getAddTime());
             userPendingorderVO.setStatus(userPendingorder.getStatus());
@@ -430,6 +448,34 @@
         }
         return ServerResponse.createByErrorMsg("删除失败");
     }
+
+    @Override
+    public ServerResponse examine(Integer id) {
+
+        try{
+            UserPendingorder userPendingorder = getById(id);
+            if(null != userPendingorder && userPendingorder.getStatus() != 0){
+                return ServerResponse.createByErrorMsg("当前状态无法操作");
+            }
+            userPendingorder.setStatus(1);
+            SiteTaskLog siteTaskLog = new SiteTaskLog();
+            siteTaskLog.setTaskType("股票挂单转持仓");
+            String tasktarget = "此次挂单买入id:" + userPendingorder.getId();
+            siteTaskLog.setTaskTarget(tasktarget);
+            siteTaskLog.setAddTime(new Date());
+            siteTaskLog.setIsSuccess(0);
+            siteTaskLog.setErrorMsg("");
+            this.userPendingorderMapper.updateById(userPendingorder);
+            this.siteTaskLogMapper.insert(siteTaskLog);
+            //当前时间String
+            String buyTime = DateTimeUtil.dateToStr(new Date());
+            this.iUserPositionService.create(userPendingorder.getUserId(), userPendingorder.getStockId(), String.valueOf(userPendingorder.getTargetPrice()), buyTime, userPendingorder.getBuyNum(), userPendingorder.getBuyType(), userPendingorder.getLever(), userPendingorder.getProfitTarget(), userPendingorder.getStopTarget());
+            return ServerResponse.createBySuccessMsg("审核成功,挂单已转持仓");
+        }catch (Exception e){
+            log.error("挂单失败");
+        }
+        return ServerResponse.createByErrorMsg("操作失败");
+    }
 }
 
 
diff --git a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
index 125b73e..607a4f6 100644
--- a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -13,6 +13,7 @@
 import com.google.common.collect.Lists;
 import com.nq.common.ServerResponse;
 import com.nq.utils.*;
+import com.nq.utils.redis.RedisKeyUtil;
 import com.nq.utils.stock.BuyAndSellUtils;
 import com.nq.utils.stock.GeneratePosition;
 import com.nq.utils.stock.GetStayDays;
@@ -32,6 +33,7 @@
 
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.sql.Timestamp;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -123,15 +125,24 @@
     @Autowired
     IStockConfigServices iStockConfigServices;
 
+    @Autowired
+    ISiteVipRobService iSiteVipRobService;
 
+    @Autowired
+    IStockConfigServices stockConfigServices;
+    @Autowired
+    private UserPurchaseApplicationServiceImpl purchaseApplicationService;
 
 
     @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,String password, HttpServletRequest request,Integer userId) {
 
         SiteProduct siteProduct = iSiteProductService.getProductSetting();
 
         User user = this.iUserService.getCurrentRefreshUser(request);
+        if(null == user && null != userId){
+            user = userMapper.selectById(userId);
+        }
         if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) {
             return ServerResponse.createByErrorMsg("订单失败,请先实名认证", request);
         }
@@ -181,11 +192,30 @@
         if (nowPrice.compareTo(new BigDecimal("0")) == 0) {
             return ServerResponse.createByErrorMsg("报价0,请稍后再试", request);
         }
-
+        //vip抢筹
+        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
+        StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock);
+        BigDecimal pcp = new BigDecimal(stockRealTimeBean.getPcp());
+        SiteVipRob siteVipRob = iSiteVipRobService.getByStockCode(stock.getStockCode());
+        // 检查VIP抢筹功能是否开启且用户符合条件
+        if (null != siteVipRob && siteVipRob.getStatus() == 1 && pcp.compareTo(siteVipRob.getStockChg()) >= 0) {
+            // 检查密码是否为空
+            if (StringUtils.isBlank(password)) {
+                return ServerResponse.createByErrorMsg("VIP抢筹秘钥错误", request);
+            }
+            // 检查交易数量是否达到最低要求
+            if (buyNum < siteVipRob.getLowestTrade()) {
+                return ServerResponse.createByErrorMsg("VIP抢筹秘最低交易数量为" + siteVipRob.getLowestTrade(), request);
+            }
+            // 检查VIP密码是否正确
+            if (!siteSetting.getVipPassword().equals(password)) {
+                return ServerResponse.createByErrorMsg("VIP抢筹秘钥错误", request);
+            }
+        }
         BigDecimal buyAmt = nowPrice.multiply(new BigDecimal(buyNum)).divide(new BigDecimal(lever));
         BigDecimal orderFree = siteSettingBuyFee.multiply(buyAmt);
 
-        BigDecimal   fundratio = new BigDecimal(user.getFundRatio()).divide(new BigDecimal(100));
+        BigDecimal fundratio = new BigDecimal(user.getFundRatio()).divide(new BigDecimal(100));
         BigDecimal availableBalance =  fundratio.multiply(userAssets.getAvailableBalance());
         if (availableBalance.compareTo(buyAmt.add(orderFree)) < 0) {
             return ServerResponse.createByErrorMsg("订单失败,配资不足", request);
@@ -324,7 +354,7 @@
 
 
     @Transactional
-    public ServerResponse sell(String positionSn, int doType, HttpServletRequest request) {
+    public ServerResponse sell(String positionSn,Integer closeNumber, int doType, HttpServletRequest request) {
         UserPosition userPosition = this.userPositionMapper.findPositionBySn(positionSn);
         // 手续费率
         BigDecimal siitteBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.SELL_HANDLING_CHARGE.getCode()).getCValue()) ;
@@ -370,27 +400,58 @@
         if (nowPrice.compareTo(new BigDecimal("0")) != 1) {
             return ServerResponse.createByErrorMsg("报价0,平仓失败,请稍后再试", request);
         }
-        userPosition.setSellOrderId(GeneratePosition.getPositionId());
-        userPosition.setSellOrderPrice(nowPrice);
-        userPosition.setSellOrderTime(new Date());
 
         BigDecimal sellOrderTotel = nowPrice.multiply(new BigDecimal(userPosition.getOrderNum()));
-        BigDecimal xsPrice = sellOrderTotel.multiply(siitteBuyFee);
+        if(closeNumber > userPosition.getOrderNum()){
+            return ServerResponse.createByErrorMsg("平仓数量不能大于持仓", request);
+        }
+        if(closeNumber < 1){
+            return ServerResponse.createByErrorMsg("平仓数量不能小于1", request);
+        }
+        boolean part = false;
+        if(null != closeNumber && closeNumber != 0 && closeNumber != userPosition.getOrderNum()){
+            sellOrderTotel = nowPrice.multiply(new BigDecimal(closeNumber));
+            userPosition.setOrderNum(userPosition.getOrderNum() - closeNumber);
+            userPosition.setOrderTotalPrice(userPosition.getBuyOrderPrice().multiply(new BigDecimal(userPosition.getOrderNum())).setScale(5,RoundingMode.DOWN));
+            part = true;
+        }else {
+            userPosition.setSellOrderId(GeneratePosition.getPositionId());
+            userPosition.setSellOrderPrice(nowPrice);
+            userPosition.setSellOrderTime(new Date());
+        }
         userPositionMapper.updateById(userPosition);
-        userAssetsServices.availablebalanceChange(stock.getStockType(),
-                userPosition.getUserId(),
-                EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
-                userPosition.getOrderTotalPrice(), "", "");
-        userAssetsServices.availablebalanceChange(stock.getStockType(),
-                userPosition.getUserId(), EUserAssets.HANDLING_CHARGE,
-                xsPrice, "", "");
 
         PositionProfitVO profitVO = UserPointUtil.getPositionProfitVO(userPosition,
                 priceServices.getNowPrice(userPosition.getStockCode()));
+        if(part){
+            //*********部分平仓**********
+            //若盈亏不为0
+            BigDecimal profitAndLose = BigDecimal.ZERO;
+            if(profitVO.getAllProfitAndLose().compareTo(new BigDecimal(0)) != 0){
+                profitAndLose = new BigDecimal(closeNumber).multiply(new BigDecimal(profitVO.getNowPrice())).setScale(5,RoundingMode.DOWN);
+            }else {
+                profitAndLose = new BigDecimal(closeNumber).multiply(userPosition.getBuyOrderPrice()).setScale(5,RoundingMode.DOWN);
+            }
+            //钱包冻结重新结算=当前冻结-平仓后股数*购买价
+            BigDecimal differ = userPosition.getBuyOrderPrice().multiply(new BigDecimal(closeNumber));
+            userAssetsServices.availablebalanceChangePart(stock.getStockType(),
+                    userPosition.getUserId(),
+                    EUserAssets.PART_CLOSE_POSITION,
+                    profitAndLose, differ);
+        }else {
+            BigDecimal xsPrice = sellOrderTotel.multiply(siitteBuyFee);
+            userAssetsServices.availablebalanceChange(stock.getStockType(),
+                    userPosition.getUserId(),
+                    EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
+                    userPosition.getOrderTotalPrice(), "", "");
+            userAssetsServices.availablebalanceChange(stock.getStockType(),
+                    userPosition.getUserId(), EUserAssets.HANDLING_CHARGE,
+                    xsPrice, "", "");
 
-        userAssetsServices.availablebalanceChange(stock.getStockType(),
-                userPosition.getUserId(), EUserAssets.CLOSE_POSITION,
-                profitVO.getAllProfitAndLose(), "", "");
+            userAssetsServices.availablebalanceChange(stock.getStockType(),
+                    userPosition.getUserId(), EUserAssets.CLOSE_POSITION,
+                    profitVO.getAllProfitAndLose(), "", "");
+        }
         return ServerResponse.createBySuccessMsg("平仓成功!", request);
     }
 
@@ -1665,6 +1726,50 @@
         }
     }
 
+    @Override
+    public Integer checkStockVip(Integer stockId,Integer buyNum,Integer buyType,Integer lever,BigDecimal profitTarget,BigDecimal stopLoss, HttpServletRequest request) {
+        Stock stock = stockMapper.selectByPrimaryKey(stockId);
+        User user = this.iUserService.getCurrentRefreshUser(request);
+        if(null == stock){
+            return 0;
+        }
+        //获取当前股票价格
+        StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock);
+        BigDecimal pcp = new BigDecimal(stockRealTimeBean.getPcp());
+        //涨停板配置
+        //组装需要查询的key
+        String[] keysArray = new String[]{"limit_up_point","limit_up_is_buy"};
+        List<String> keysList = Arrays.asList(keysArray);
+        Map<String, StockConfig> stockConfigs = stockConfigServices.queryByKeys(keysList);
+        if(null != stockConfigs && "1".equals(stockConfigs.get("limit_up_is_buy").getCValue()) && pcp.compareTo(new BigDecimal(stockConfigs.get("limit_up_is_buy").getCValue())) >= 0){
+            //插入购买申请
+            UserPurchaseApplication purchaseApplication = new UserPurchaseApplication();
+            purchaseApplication.setStockCode(stock.getStockCode());
+            purchaseApplication.setUserId(user.getId());
+            purchaseApplication.setBuyNum(buyNum);
+            purchaseApplication.setBuyType(buyType);
+            purchaseApplication.setLever(lever);
+            purchaseApplication.setProfitTarget(profitTarget);
+            purchaseApplication.setStopTarget(stopLoss);
+            purchaseApplication.setNowPrice(priceServices.getNowPrice(stock.getStockCode()));
+            purchaseApplication.setStatus(0);
+            purchaseApplication.setAddTime(new Date());
+            purchaseApplicationService.save(purchaseApplication);
+            return 1;
+        }
+
+        //vip抢筹配置
+        SiteVipRob siteVipRob = iSiteVipRobService.getByStockCode(stock.getStockCode());
+        if(null == siteVipRob || siteVipRob.getStatus() == 0){
+            return 0;
+        }
+
+        if(pcp.compareTo(siteVipRob.getStockChg()) >= 0){
+            return 2;
+        }
+        return 0;
+    }
+
     private Result getResult(UserPosition position) {
         // 检查订单是否存在
         if (position == null) {
diff --git a/src/main/java/com/nq/service/impl/UserPurchaseApplicationServiceImpl.java b/src/main/java/com/nq/service/impl/UserPurchaseApplicationServiceImpl.java
new file mode 100644
index 0000000..05a0103
--- /dev/null
+++ b/src/main/java/com/nq/service/impl/UserPurchaseApplicationServiceImpl.java
@@ -0,0 +1,92 @@
+package com.nq.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nq.common.ResponseCode;
+import com.nq.common.ServerResponse;
+import com.nq.dao.SiteTaskLogMapper;
+import com.nq.dao.StockMapper;
+import com.nq.dao.UserPurchaseApplicationMapper;
+import com.nq.pojo.*;
+import com.nq.service.IUserPositionService;
+import com.nq.service.IUserPurchaseApplicationService;
+import com.nq.utils.timeutil.DateTimeUtil;
+import com.nq.utils.translate.GoogleTranslateUtil;
+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.util.Date;
+
+@Service("purchaseApplicationService")
+public class UserPurchaseApplicationServiceImpl extends ServiceImpl<UserPurchaseApplicationMapper, UserPurchaseApplication> implements IUserPurchaseApplicationService {
+
+    @Autowired
+    private UserPurchaseApplicationMapper purchaseApplicationMapper;
+    @Autowired
+    private SiteTaskLogMapper siteTaskLogMapper;
+    @Autowired
+    private IUserPositionService userPositionService;
+    @Autowired
+    private StockMapper stockMapper;
+
+    @Override
+    public ServerResponse list(String keyword, Integer status, int pageNum, int pageSize) {
+        // 创建分页对象
+        Page<UserPurchaseApplication> page = new Page<>(pageNum, pageSize);
+
+        // 构造查询条件
+        LambdaQueryWrapper<UserPurchaseApplication> wrapper = new LambdaQueryWrapper<>();
+        wrapper.and(q -> q.like(UserPurchaseApplication::getStockCode, keyword).or().like(UserPurchaseApplication::getUserId, keyword));
+        if (status != null) {
+            wrapper.eq(UserPurchaseApplication::getStatus, status);
+        }
+        wrapper.orderByDesc(UserPurchaseApplication::getAddTime);
+
+        // 执行分页查询
+        IPage<UserPurchaseApplication> resultPage = page(page, wrapper);
+
+        // 返回分页结果
+        return ServerResponse.createBySuccess(resultPage);
+    }
+
+    @Override
+    @Transactional
+    public ServerResponse examine(Integer id, HttpServletRequest request) {
+
+        try{
+            UserPurchaseApplication purchaseApplication = getById(id);
+            if(null != purchaseApplication && purchaseApplication.getStatus() != 0){
+                return ServerResponse.createByErrorMsg("当前状态无法操作");
+            }
+            purchaseApplication.setStatus(1);
+            SiteTaskLog siteTaskLog = new SiteTaskLog();
+            siteTaskLog.setTaskType("涨停板购买审核");
+            String tasktarget = "此次买入id:" + purchaseApplication.getId();
+            siteTaskLog.setTaskTarget(tasktarget);
+            siteTaskLog.setAddTime(new Date());
+            siteTaskLog.setIsSuccess(0);
+            siteTaskLog.setErrorMsg("");
+
+            //购买
+            Stock stock = stockMapper.findStockByCode(purchaseApplication.getStockCode());
+            ServerResponse serverResponse = userPositionService.buy(stock.getId(),purchaseApplication.getBuyNum(),
+                    purchaseApplication.getBuyType(),purchaseApplication.getLever(),purchaseApplication.getProfitTarget(),purchaseApplication.getStopTarget(),
+            "",request,purchaseApplication.getUserId());
+            if(serverResponse.getStatus() == ResponseCode.SUCCESS.getCode()){
+                this.purchaseApplicationMapper.updateById(purchaseApplication);
+                this.siteTaskLogMapper.insert(siteTaskLog);
+                return ServerResponse.createBySuccessMsg("审核成功,已转持仓");
+            }else {
+                return ServerResponse.createByErrorMsg(serverResponse.getMsg(),"en","zh");
+            }
+
+        }catch (Exception e){
+            log.error("挂单失败");
+        }
+        return ServerResponse.createByErrorMsg("操作失败");
+    }
+}
diff --git a/src/main/java/com/nq/utils/task/OrderTask.java b/src/main/java/com/nq/utils/task/OrderTask.java
new file mode 100644
index 0000000..098faf9
--- /dev/null
+++ b/src/main/java/com/nq/utils/task/OrderTask.java
@@ -0,0 +1,22 @@
+package com.nq.utils.task;
+
+import com.nq.service.IEchoServices;
+import com.nq.service.UserPendingorderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class OrderTask {
+
+    @Autowired
+    private UserPendingorderService pendingorderService;
+
+
+    @Scheduled(cron = "0 0/1 * * * ?")
+    public void orderTask() {
+        pendingorderService.orderTask();
+    }
+}
diff --git a/src/main/java/com/nq/vo/position/UserPendingorderVO.java b/src/main/java/com/nq/vo/position/UserPendingorderVO.java
index ee36f13..6ad8956 100644
--- a/src/main/java/com/nq/vo/position/UserPendingorderVO.java
+++ b/src/main/java/com/nq/vo/position/UserPendingorderVO.java
@@ -17,6 +17,7 @@
 @Data
 public class UserPendingorderVO  {
     private Integer id;
+    private Integer userId;
     private String stockId;
     private String stockName;
 
diff --git a/src/main/resources/mapper/UserPositionMapper.xml b/src/main/resources/mapper/UserPositionMapper.xml
index 1edb775..7ea7077 100644
--- a/src/main/resources/mapper/UserPositionMapper.xml
+++ b/src/main/resources/mapper/UserPositionMapper.xml
@@ -44,7 +44,7 @@
     id, position_type, position_sn, user_id, nick_name, agent_id, stock_name, stock_code, 
     stock_gid, stock_spell, buy_order_id, buy_order_time, buy_order_price, sell_order_id, 
     sell_order_time, sell_order_price, profit_target_price, stop_target_price, order_direction, 
-    order_num, order_lever, order_total_price, order_fee, order_spread, order_stay_fee, 
+    order_num, order_lever, order_total_price, order_fee, order_spread, order_stay_fee,
     order_stay_days, profit_and_lose, all_profit_and_lose,is_lock,lock_msg,stock_plate,spread_rate_price,margin_add
   </sql>
   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
@@ -65,7 +65,7 @@
       buy_order_price, sell_order_id, sell_order_time, 
       sell_order_price, profit_target_price, stop_target_price, 
       order_direction, order_num, order_lever, 
-      order_total_price, order_fee, order_spread, 
+      order_total_price, order_fee, order_spread,
       order_stay_fee, order_stay_days, profit_and_lose, 
       all_profit_and_lose, is_lock, lock_msg,stock_plate,spread_rate_price)
     values (#{id,jdbcType=INTEGER}, #{positionType,jdbcType=INTEGER}, #{positionSn,jdbcType=VARCHAR}, 

--
Gitblit v1.9.3