8 files modified
5 files added
| | |
| | | @Autowired |
| | | UserPositionMapper userPositionMapper; |
| | | |
| | | @Autowired |
| | | TransactionLogService transactionLogService; |
| | | |
| | | private static final ThreadLocal<Boolean> orderCreated = ThreadLocal.withInitial(() -> false); |
| | | private final Lock lock = new ReentrantLock(); |
| | | |
| | |
| | | userPendingorderService.updateById(userPendingorder); |
| | | iUserAssetsServices.availablebalanceChange(userPendingorder.getStockGid().equals("ST") ? userPendingorder.getStockGid() : "USD", |
| | | userPendingorder.getUserId(), |
| | | EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT, |
| | | EUserAssets.THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED, |
| | | userPendingorder.getOrderTotalPrice(), "", ""); |
| | | return ServerResponse.createBySuccess("撤销挂单成功",request); |
| | | } |
| | |
| | | return iApplyLeverServices.applyLever(applyLever,request); |
| | | } |
| | | |
| | | |
| | | @RequestMapping({"flowLog.do"}) |
| | | @ResponseBody |
| | | public ServerResponse flowLog(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum, |
| | | @RequestParam(value = "pageSize", defaultValue = "100") int pageSize,HttpServletRequest request) { |
| | | return transactionLogService.flowLog(pageNum,pageSize,request); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.nq.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.nq.pojo.TradingHour; |
| | | import com.nq.pojo.TransactionLog; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | @Mapper |
| | | public interface TransactionLogMapper extends BaseMapper<TransactionLog> { |
| | | } |
| | |
| | | CALCULATE_PROFIT_AND_LOSS("CALCULATE_PROFIT_AND_LOSS","计算盈亏"), |
| | | |
| | | CLOSE_POSITION_RETURN_SECURITY_DEPOSIT("CLOSE_POSITION_RETURN_SECURITY","平仓返回保证金"), |
| | | THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED("THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED","挂单撤销返回保证金"), |
| | | CLOSE_POSITION("CLOSE_POSITION","平仓"), |
| | | CONSTRAINT_CLOSE_POSITION("CONSTRAINT_CLOSE_POSITION","强制平仓"), |
| | | BUY("BUY","购买"), |
| | |
| | | |
| | | private String desc; |
| | | |
| | | |
| | | public static EUserAssets fromString(String value) { |
| | | for (EUserAssets eUserAssets : EUserAssets.values()) { |
| | | if (eUserAssets.getCode().equalsIgnoreCase(value)) { |
| | | return eUserAssets; |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("未知的交易类型: " + value); |
| | | } |
| | | EUserAssets(String code, String desc) { |
| | | this.code = code; |
| | | this.desc = desc; |
| New file |
| | |
| | | package com.nq.enums; |
| | | |
| | | /** |
| | | * 交易类型 |
| | | */ |
| | | public enum TradeType { |
| | | |
| | | // 枚举常量 |
| | | BUY("买入"), |
| | | SELL("卖出"), |
| | | SERVICE_CHARGE("手续费"), |
| | | TRANSFER("划转"), |
| | | WITHDRAW("提现"), |
| | | WITHDRAW_RETURN("提现返还"), |
| | | DEPOSIT("存款"); |
| | | |
| | | // 枚举常量对应的描述 |
| | | private String description; |
| | | |
| | | // 构造方法 |
| | | TradeType(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | // 获取描述 |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | // 根据字符串获取对应的枚举值 |
| | | public static TradeType fromString(String value) { |
| | | for (TradeType tradeType : TradeType.values()) { |
| | | if (tradeType.name().equalsIgnoreCase(value)) { |
| | | return tradeType; |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("未知的交易类型: " + value); |
| | | } |
| | | |
| | | // 重写toString方法,返回描述 |
| | | @Override |
| | | public String toString() { |
| | | return this.description; |
| | | } |
| | | |
| | | } |
| | |
| | | //价格 |
| | | private BigDecimal nowPrice; |
| | | |
| | | // 差价 |
| | | // 折扣价 |
| | | @TableField(exist = false) |
| | | private BigDecimal priceSpread; |
| | | // 百分比 |
| New file |
| | |
| | | package com.nq.pojo; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 用户交易流水 |
| | | */ |
| | | @Data |
| | | public class TransactionLog { |
| | | |
| | | @TableId(type = IdType.AUTO,value = "id") |
| | | private Integer id; // 交易日志的唯一标识符 |
| | | private Integer userId; // 用户 ID |
| | | private String transactionType; // 交易类型 |
| | | private String amount; // 交易金额 |
| | | private String description; // 交易描述 |
| | | private Date transactionTime; // 交易时间 |
| | | |
| | | } |
| New file |
| | |
| | | package com.nq.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.nq.common.ServerResponse; |
| | | import com.nq.pojo.StockDz; |
| | | import com.nq.pojo.TransactionLog; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.math.BigDecimal; |
| | | |
| | | public interface TransactionLogService extends IService<TransactionLog> { |
| | | |
| | | void add(Integer userId, String transactionType, String amount,String description); |
| | | |
| | | ServerResponse flowLog(int pageNum, int pageSize, HttpServletRequest request); |
| | | } |
| | |
| | | stockTypeDz.forEach(f->{ |
| | | String price = iPriceServices.getNowPrice(f.getStockCode()).toString(); |
| | | BigDecimal subtract = new BigDecimal(price).subtract(f.getNowPrice()); |
| | | f.setPriceSpread(subtract); |
| | | f.setPriceSpread(f.getNowPrice()); |
| | | f.setNowPrice(new BigDecimal(price)); |
| | | f.setPriceSpreadPercentum( |
| | | subtract.divide(new BigDecimal(price), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)) |
| New file |
| | |
| | | package com.nq.service.impl; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | 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.TradingHourMapper; |
| | | import com.nq.dao.TransactionLogMapper; |
| | | import com.nq.pojo.TradingHour; |
| | | import com.nq.pojo.TransactionLog; |
| | | import com.nq.pojo.User; |
| | | import com.nq.pojo.UserPositionCheckDz; |
| | | import com.nq.service.ITradingHourService; |
| | | import com.nq.service.TransactionLogService; |
| | | import com.nq.utils.translate.GoogleTranslateUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class TransactionLogServiceImpl extends ServiceImpl<TransactionLogMapper, TransactionLog> implements TransactionLogService { |
| | | |
| | | @Autowired |
| | | UserServiceImpl userService; |
| | | |
| | | @Override |
| | | public ServerResponse flowLog(int pageNum, int pageSize, HttpServletRequest request) { |
| | | |
| | | User user = this.userService.getCurrentRefreshUser(request); |
| | | if(ObjectUtil.isEmpty(user)){ |
| | | return ServerResponse.createByErrorMsg("登录已失效,请重新登录!",request); |
| | | } |
| | | Page<TransactionLog> page = Page.of(pageNum, pageSize); |
| | | Page<TransactionLog> pageList = page(page,new LambdaQueryWrapper<TransactionLog>() |
| | | .eq(TransactionLog::getUserId, user.getId()) |
| | | .orderByDesc(TransactionLog::getTransactionTime) |
| | | ); |
| | | pageList.getRecords().forEach(f->{ |
| | | f.setTransactionType(new GoogleTranslateUtil().translate(f.getTransactionType(),request.getHeader("lang"))); |
| | | f.setDescription(new GoogleTranslateUtil().translate(f.getDescription(),request.getHeader("lang"))); |
| | | }); |
| | | return ServerResponse.createBySuccess(pageList); |
| | | } |
| | | |
| | | @Override |
| | | public void add(Integer userId, String transactionType, String amount, String description) { |
| | | TransactionLog transactionLog = new TransactionLog(); |
| | | transactionLog.setUserId(userId); |
| | | transactionLog.setTransactionType(transactionType); |
| | | transactionLog.setAmount(amount); |
| | | transactionLog.setDescription(description); |
| | | transactionLog.setTransactionTime(new Date()); |
| | | save(transactionLog); |
| | | } |
| | | } |
| | |
| | | import com.nq.dao.*; |
| | | import com.nq.enums.EStockType; |
| | | import com.nq.enums.EUserAssets; |
| | | import com.nq.enums.TradeType; |
| | | import com.nq.pojo.*; |
| | | import com.nq.service.IUserAssetsServices; |
| | | import com.nq.service.TransactionLogService; |
| | | import com.nq.utils.KeyUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | @Autowired |
| | | StockConfigMapper stockConfigMapper; |
| | | |
| | | @Autowired |
| | | TransactionLogService transactionLogService; |
| | | @Override |
| | | public UserAssets assetsByTypeAndUserId(String accetType, Integer userId) { |
| | | if(accetType.equals("SZHB")){ |
| | |
| | | userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(amount)); |
| | | } |
| | | userAssets.setFreezeMoney(userAssets.getFreezeMoney().subtract(amount)); |
| | | }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.THE_DEPOSIT_WILL_BE_RETURNED_IF_THE_ORDER_IS_CANCELLED.getCode())){ |
| | | if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ |
| | | BigDecimal availableBalance = amount.subtract(userAssets.getAmountToBeCovered()); |
| | | availableBalance = availableBalance.subtract(userAssets.getHandlingChargeWritten()); |
| | | if(availableBalance.compareTo(BigDecimal.ZERO) >= 0){ |
| | | userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(availableBalance)); |
| | | userAssets.setAmountToBeCovered(BigDecimal.ZERO); |
| | | userAssets.setHandlingChargeWritten(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); |
| | | }else if(Objects.equals(eUserAssets.getCode(), EUserAssets.TRANSFER.getCode())){ |
| | |
| | | moneyLog.setSymbol(EStockType.getEStockTypeByCode(accetType).getSymbol()); |
| | | moneyLog.setCreateTime(new Date()); |
| | | moneyLogMapper.insert(moneyLog); |
| | | return userAssetsMapper.updateById(userAssets)>1; |
| | | int update = userAssetsMapper.updateById(userAssets); |
| | | if(update > 0){ |
| | | if(Objects.equals(eUserAssets.getCode(), EUserAssets.HANDLING_CHARGE.getCode())){ |
| | | amount = amount.negate(); |
| | | } |
| | | transactionLogService.add(userId, eUserAssets.getDesc(),amount.toString(),eUserAssets.getDesc()); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | UserPositionVO userPositionVO = UserPointUtil.assembleUserPositionVO(position, nowPrice); |
| | | userPositionVO.setOrderTotalPrice(userPositionVO.getOrderTotalPrice().multiply(new BigDecimal(userPositionVO.getOrderLever()))); |
| | | |
| | | userPositionVO.setBuyOrderPrice(userPositionVO.getBuyOrderPrice().setScale(2, BigDecimal.ROUND_DOWN)); |
| | | StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new LambdaQueryWrapper<StockSubscribe>() |
| | | .eq(StockSubscribe::getCode, userPositionVO.getStockCode())); |
| | | if (position.getSellOrderId() == null) { |
| | |
| | | public ServerResponse saveUserRecharge(Integer id, String amt, HttpServletRequest request){ |
| | | User user = this.userMapper.selectById(id); |
| | | if (user == null) { |
| | | return ServerResponse.createBySuccessMsg("请登录后操作",request); |
| | | return ServerResponse.createByErrorMsg("请登录后操作",request); |
| | | } |
| | | List<UserRecharge> userRecharges = userRechargeMapper.selectList(new LambdaQueryWrapper<>(UserRecharge.class).eq(UserRecharge::getUserId, id).eq(UserRecharge::getOrderStatus, 0)); |
| | | if(CollectionUtils.isNotEmpty(userRecharges)){ |
| | | return ServerResponse.createBySuccessMsg("当前有未处理充值订单,请联系客服完成充值!",request); |
| | | return ServerResponse.createByErrorMsg("当前有未处理充值订单,请联系客服完成充值!",request); |
| | | } |
| | | UserRecharge userRecharge = new UserRecharge(); |
| | | userRecharge.setUserId(user.getId()); |
| | |
| | | import com.nq.enums.EConfigKey; |
| | | import com.nq.enums.EStockType; |
| | | import com.nq.enums.EUserAssets; |
| | | import com.nq.enums.TradeType; |
| | | import com.nq.pay.PayUtil; |
| | | import com.nq.pojo.*; |
| | | import com.nq.service.*; |
| | |
| | | |
| | | @Resource |
| | | StockTimeSettingMapper stockTimeSettingMapper; |
| | | |
| | | @Autowired |
| | | TransactionLogService transactionLogService; |
| | | |
| | | @Transactional |
| | | public ServerResponse outMoney(String amt, String with_Pwd,String accsetType,String bankName,String bankNo,HttpServletRequest request) throws Exception { |
| | |
| | | } |
| | | int updateCount = userAssetsMapper.updateById(userAssets); |
| | | if (updateCount > 0) { |
| | | transactionLogService.add(user.getId(), TradeType.WITHDRAW_RETURN.getDescription(),userWithdraw.getWithAmt().toString(),EStockType.ST.getSymbol()); |
| | | log.info("提现失败,返还用户资金成功!"); |
| | | } else { |
| | | log.error("返还用户资金出错,抛出异常"); |