1
zj
2024-04-25 23c07b71a269f2540e5c09eb8d2002d9f20a857e
1
13 files modified
154 ■■■■ changed files
src/main/java/com/nq/StockApplication.java 4 ●●● patch | view | raw | blame | history
src/main/java/com/nq/controller/backend/AdminStockSubscribeController.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/controller/protol/UserController.java 10 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/dao/UserAssetsMapper.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/IStockSubscribeService.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/StockSubscribeServiceImpl.java 6 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserAssetsServices.java 42 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserServiceImpl.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java 33 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/utils/task/stock/CarryPositionTask.java 44 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/utils/task/stock/StockTask.java 4 ●●●● patch | view | raw | blame | history
src/main/resources/application.yml 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/StockApplication.java
@@ -4,7 +4,9 @@
import com.nq.utils.ip.ipUtil;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
@@ -15,7 +17,7 @@
@MapperScan(basePackages = "com.nq.dao")
@EnableScheduling
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableAutoConfiguration(exclude={FlywayAutoConfiguration.class})
public class StockApplication {
src/main/java/com/nq/controller/backend/AdminStockSubscribeController.java
@@ -43,7 +43,7 @@
                               @RequestParam(value = "isLock", required = false) Integer isLock,
                               @RequestParam(value = "type", required = false) Integer type,
                               HttpServletRequest request) {
        return this.iStockSubscribeService.list(name,code,zt,isLock,type,request);
        return this.iStockSubscribeService.list(name,code,zt,0,isLock,type,request);
    }
    /** 
    * @Description:  新增新股
src/main/java/com/nq/controller/protol/UserController.java
@@ -274,8 +274,14 @@
     */
    @RequestMapping({"list.do"})
    @ResponseBody
    public ServerResponse list(@RequestParam(value = "name", required = false) String name,@RequestParam(value = "code", required = false) String code,@RequestParam(value = "zt", required = false) Integer zt,@RequestParam(value = "isLock", required = false) Integer isLock,@RequestParam(value = "type", required = false) Integer type, HttpServletRequest request) {
        return this.iStockSubscribeService.list(name,code,zt,isLock,type,request);
    public ServerResponse list(@RequestParam(value = "name", required = false) String name,
                               @RequestParam(value = "code", required = false) String code,
                               @RequestParam(value = "zt", required = false) Integer zt,
                               @RequestParam(value = "isLock", required = false) Integer isLock,
                               @RequestParam(value = "type", required = false) Integer type,
                               @RequestParam(value = "getType", required = false) Integer getType,
                               HttpServletRequest request) {
        return this.iStockSubscribeService.list(name,code,zt,getType,isLock,type,request);
    }
    /**
     * 新股申购 添加
src/main/java/com/nq/dao/UserAssetsMapper.java
@@ -2,6 +2,8 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nq.pojo.UserAssets;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserAssetsMapper extends BaseMapper<UserAssets> {
}
src/main/java/com/nq/service/IStockSubscribeService.java
@@ -14,7 +14,7 @@
* @createDate 2022-10-24 23:27:27
*/
public interface IStockSubscribeService extends IService<StockSubscribe> {
    ServerResponse list( String name,String code,Integer zt,Integer isLock,Integer type, HttpServletRequest paramHttpServletRequest);
    ServerResponse list( String name,String code,Integer zt,Integer getType,Integer isLock,Integer type, HttpServletRequest paramHttpServletRequest);
    ServerResponse add(StockSubscribe model, HttpServletRequest request);
src/main/java/com/nq/service/impl/StockSubscribeServiceImpl.java
@@ -16,6 +16,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
/**
@@ -41,7 +42,7 @@
     * @Date: 2022/10/25
     */
    @Override
    public ServerResponse list(String name, String code, Integer zt, Integer isLock, Integer type, HttpServletRequest request) {
    public ServerResponse list(String name, String code, Integer zt,Integer getType, Integer isLock, Integer type, HttpServletRequest request) {
        //name和code模糊查询
        QueryWrapper<StockSubscribe> queryWrapper = new QueryWrapper();
@@ -60,6 +61,9 @@
        if (type != null && !type.equals("")) {
            queryWrapper.eq("type", type);
        }
        if(getType == 1){
            queryWrapper.gt("list_date", new Date());
        }
        queryWrapper.orderByDesc("newlist_id");
        List<StockSubscribe> stockSubscribeList = this.stockSubscribeMapper.selectList(queryWrapper);
        PageInfo pageInfo = new PageInfo(stockSubscribeList);
src/main/java/com/nq/service/impl/UserAssetsServices.java
@@ -64,8 +64,20 @@
            if(type.equals("1")){
                bigAmt = bigAmt.negate();
            }
            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(bigAmt));
            if(type.equals("0")){
                if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){
                    BigDecimal availableBalance = bigAmt.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(bigAmt);
                        userAssets.setAmountToBeCovered(amountToBeCovered);
                    }
                }else{
                    userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(bigAmt));
                }
            }
            if( userAssetsMapper.updateById(userAssets)>0){
                return ServerResponse.createBySuccess();
            }else{
@@ -114,7 +126,18 @@
            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
           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())){
           extracted(amount, userAssets);
@@ -122,7 +145,18 @@
            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount));
           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())){
src/main/java/com/nq/service/impl/UserServiceImpl.java
@@ -506,6 +506,7 @@
            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);
src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java
@@ -6,6 +6,7 @@
import com.github.pagehelper.PageInfo;
import com.nq.common.ServerResponse;
import com.nq.dao.StockSubscribeMapper;
import com.nq.dao.UserAssetsMapper;
import com.nq.dao.UserMapper;
import com.nq.dao.UserStockSubscribeMapper;
import com.nq.enums.EStockType;
@@ -18,6 +19,7 @@
import com.nq.utils.redis.JsonUtil;
import com.nq.utils.redis.RedisShardedPoolUtils;
import com.nq.utils.stock.BuyAndSellUtils;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -64,6 +66,10 @@
    @Resource
    IUserAssetsServices iUserAssetsServices;
    @Autowired
    UserAssetsMapper userAssetsMapper;
    /**
     * 用户新股申购
     * @param model
@@ -81,7 +87,7 @@
                StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("code", model.getNewCode()));
                //实名认证开关
                SiteProduct siteProduct = iSiteProductService.getProductSetting();
                if (siteProduct.getRealNameDisplay() && (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()))) {
                if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) {
                    return ServerResponse.createByErrorMsg("订单失败,请先实名认证",request);
                }
@@ -127,7 +133,7 @@
                   BigDecimal bound =  new BigDecimal(model.getApplyNums()).multiply(stockSubscribe.getPrice());
                   BigDecimal useEnaAmount = iUserAssetsServices.getAvailableBalance(EStockType.IN.getCode(), user.getId());
                   if(useEnaAmount.compareTo(bound)<0){
                       ServerResponse.createByErrorMsg("余额不足,配售失败",request);
                       return ServerResponse.createByErrorMsg("余额不足,配售失败",request);
                   }
                    model.setUserId(user.getId());
                    model.setNewName(stockSubscribe.getName());
@@ -164,9 +170,9 @@
     * admin 新股申购-添加和修改
     */
    @Override
    @Transactional
    public ServerResponse save(UserStockSubscribe model, HttpServletRequest request) {
        int ret = 0;
        if( model.getId() != null  ){
            if (model.getStatus() == 3||model.getStatus() == 2) {
                model.setEndTime(DateTimeUtil.getCurrentDate());
@@ -176,10 +182,28 @@
                return ServerResponse.createByErrorMsg("It's been converted");
            }
            StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<>(new StockSubscribe()).eq("code", userStockSubscribe.getNewCode()));
            if((model.getStatus() == 3 && model.getApplyNumber() == null) || (model.getStatus() == 3 && model.getApplyNumber() == 0) ){
                return ServerResponse.createByErrorMsg("中签数量不能小于0");
            }
            if (model.getStatus() == 3 && model.getApplyNumber() != null){
                if(stockSubscribe.getType() == 1){
                    model.setBond(stockSubscribe.getPrice().multiply(BigDecimal.valueOf(model.getApplyNumber())));
                    model.setDbMoney(model.getDbMoney());
                    //客户中签直接扣除客户账户可用资金
                    UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId("IN", userStockSubscribe.getUserId());
                    if(null == userAssets){
                        return ServerResponse.createByErrorMsg("客户资金账户不存在");
                    }
                    BigDecimal decimal = userStockSubscribe.getBuyPrice().multiply(new BigDecimal(model.getApplyNumber()));//中签总价
                    BigDecimal availableBalance = userAssets.getAvailableBalance().subtract(decimal);//剩余可用余额
                    if(decimal.compareTo(userAssets.getAvailableBalance()) <= 0){
                        userAssets.setAvailableBalance(availableBalance);
                    }else{
                        BigDecimal amountToBeCovered = decimal.subtract(userAssets.getAvailableBalance());//待补金额
                        userAssets.setAvailableBalance(BigDecimal.ZERO);
                        userAssets.setAmountToBeCovered(userAssets.getAmountToBeCovered().add(amountToBeCovered));
                    }
                    userAssetsMapper.updateById(userAssets);
                    ret = userStockSubscribeMapper.update1(model);
                }else{
                    if(model.getApplyNumber()>model.getApplyNums()){
@@ -278,7 +302,6 @@
        return ServerResponse.createByErrorMsg("Operation failure");
    }
    /**
     * 发送站内信
     */
@@ -395,7 +418,7 @@
                        return ServerResponse.createByErrorMsg("余额不足",request);
                    }
                    iUserAssetsServices.availablebalanceChange(EStockType.IN.getCode(),userStockSubscribe.getUserId(),
                            EUserAssets.BUY,multiply,"","");
                            EUserAssets.BUY,multiply.negate(),"","");
                    userStockSubscribe.setDbMoney(BigDecimal.ZERO);
                    userStockSubscribeMapper.update1(userStockSubscribe);
                    return  ServerResponse.createBySuccess();
src/main/java/com/nq/service/impl/UserWithdrawServiceImpl.java
@@ -106,7 +106,7 @@
            if (user.getIsLogin().intValue() == 1) {
                return ServerResponse.createByErrorMsg("用户被锁定",request);
            }
            if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard())) {
            if (user.getIsActive() != 2) {
                return ServerResponse.createByErrorMsg("未实名认证",request);
            }
            UserBank userBank = this.iUserBankService.findUserBankByUserId(user.getId());
src/main/java/com/nq/utils/task/stock/CarryPositionTask.java
@@ -4,12 +4,16 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.nq.common.ServerResponse;
import com.nq.dao.StockSubscribeMapper;
import com.nq.dao.UserAssetsMapper;
import com.nq.dao.UserMapper;
import com.nq.dao.UserStockSubscribeMapper;
import com.nq.pojo.StockSubscribe;
import com.nq.pojo.User;
import com.nq.pojo.UserAssets;
import com.nq.pojo.UserStockSubscribe;
import com.nq.service.IUserAssetsServices;
import com.nq.service.IUserPositionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.DateUtils;
@@ -45,7 +49,12 @@
    @Autowired
    UserMapper userMapper;
    @Autowired
    IUserAssetsServices userAssetsServices;
    private final Lock ballotLock = new ReentrantLock();
    private final Lock subscriptionLock = new ReentrantLock();
    @Scheduled(cron = "0 0/10 * * * ?")
    public void ballot() {
@@ -60,9 +69,13 @@
                            .eq(UserStockSubscribe::getStatus, 4).in(UserStockSubscribe::getNewCode, codeList));
                    //订单转持仓
                    userStockSubscribes.forEach(f -> {
                        iUserPositionService.newStockToPosition(f.getId());//转持仓
                        f.setStatus(5);
                        userStockSubscribeMapper.updateById(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("新股上市转持仓定时任务--------->结束");
@@ -76,4 +89,29 @@
        }
    }
    @Scheduled(cron = "0 0/1 * * * ?")
    public void subscription() {
        if (subscriptionLock.tryLock()) {
            try {
                log.info("自动转已认缴--------->开始");
                List<UserStockSubscribe> userStockSubscribes = userStockSubscribeMapper.selectList(new LambdaQueryWrapper<UserStockSubscribe>()
                        .eq(UserStockSubscribe::getStatus, 3));
                userStockSubscribes.forEach(f->{
                    UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId("IN",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("自动转已认缴定时任务--------->上次任务还未执行完成,本次任务忽略");
        }
    }
}
src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -58,7 +58,7 @@
    /**
     * 同步系统所需要的股票
     * */
//    @Scheduled(cron = "0/30 * *  * * ?")
    @Scheduled(cron = "0 0 0/2  * * ?")
    public void syncINStockData() {
        loadAllStock(EStockType.IN);
//        loadAllStock(EStockType.HK);
@@ -166,7 +166,7 @@
    /**
     * 强制平仓
     */
    @Scheduled(cron = "0/1 * * * * ?")
//    @Scheduled(cron = "0/1 * * * * ?")
    public void stockConstraint(){
        if (stockConstraintLock.tryLock()) {
            log.info("强制平仓任务:--------->开始");
src/main/resources/application.yml
@@ -122,7 +122,7 @@
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/caicai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    url: jdbc:mysql://127.0.0.1:3306/zyqsstock?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
#    url: jdbc:mysql://127.0.0.1:3306/cgstock?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: 123456