| | |
| | | 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; |
| | | |
| | |
| | | @MapperScan(basePackages = "com.nq.dao") |
| | | @EnableScheduling |
| | | @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) |
| | | |
| | | @EnableAutoConfiguration(exclude={FlywayAutoConfiguration.class}) |
| | | public class StockApplication { |
| | | |
| | | |
| | |
| | | @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: 新增新股 |
| | |
| | | */ |
| | | @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); |
| | | } |
| | | /** |
| | | * 新股申购 添加 |
| | |
| | | |
| | | 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> { |
| | | } |
| | |
| | | * @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); |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | * @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(); |
| | |
| | | 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); |
| | |
| | | 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{ |
| | |
| | | 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); |
| | |
| | | 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())){ |
| | |
| | | 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); |
| | | |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | |
| | | @Resource |
| | | IUserAssetsServices iUserAssetsServices; |
| | | |
| | | @Autowired |
| | | UserAssetsMapper userAssetsMapper; |
| | | |
| | | /** |
| | | * 用户新股申购 |
| | | * @param model |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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()); |
| | |
| | | * 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()); |
| | |
| | | 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()){ |
| | |
| | | |
| | | return ServerResponse.createByErrorMsg("Operation failure"); |
| | | } |
| | | |
| | | /** |
| | | * 发送站内信 |
| | | */ |
| | |
| | | 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(); |
| | |
| | | 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()); |
| | |
| | | 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; |
| | |
| | | @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() { |
| | |
| | | .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("新股上市转持仓定时任务--------->结束"); |
| | |
| | | } |
| | | } |
| | | |
| | | @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("自动转已认缴定时任务--------->上次任务还未执行完成,本次任务忽略"); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | /** |
| | | * 同步系统所需要的股票 |
| | | * */ |
| | | // @Scheduled(cron = "0/30 * * * * ?") |
| | | @Scheduled(cron = "0 0 0/2 * * ?") |
| | | public void syncINStockData() { |
| | | loadAllStock(EStockType.IN); |
| | | // loadAllStock(EStockType.HK); |
| | |
| | | /** |
| | | * 强制平仓 |
| | | */ |
| | | @Scheduled(cron = "0/1 * * * * ?") |
| | | // @Scheduled(cron = "0/1 * * * * ?") |
| | | public void stockConstraint(){ |
| | | if (stockConstraintLock.tryLock()) { |
| | | log.info("强制平仓任务:--------->开始"); |
| | |
| | | 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 |