新版仿ok交易所-后端
1
zj
2026-01-21 01e664e79f39091408570625f538898683658b92
1
3 files modified
5 files added
328 ■■■■■ changed files
trading-order-admin/src/main/java/com/yami/trading/admin/dto/PurchaseRecordDto.java 62 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIcoController.java 27 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java 129 ●●●● patch | view | raw | blame | history
trading-order-bean/src/main/java/com/yami/trading/bean/ico/dto/UserSubscriptionDTO.java 19 ●●●●● patch | view | raw | blame | history
trading-order-bean/src/main/java/com/yami/trading/bean/model/PurchaseRecord.java 54 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/dao/PurchaseRecordMapper.java 10 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/user/PurchaseRecordService.java 8 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/user/impl/PurchaseRecordServiceImpl.java 19 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/admin/dto/PurchaseRecordDto.java
New file
@@ -0,0 +1,62 @@
package com.yami.trading.admin.dto;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
 * @program: trading-order-master
 * @description:
 * @create: 2026-01-21 18:06
 **/
@Data
public class PurchaseRecordDto {
    /**
     * 用户ID
     */
    private String userId;
    /**
     * 申购数量
     */
    private BigDecimal purchaseQuantity;
    /**
     * 购买价
     */
    private BigDecimal purchasePrice;
    /**
     * 现价
     */
    private BigDecimal currentPrice;
    /**
     * 持仓市值
     */
    private BigDecimal positionvalue;
    /**
     * 购买总额(申购数量 × 购买价)
     */
    private BigDecimal totalAmount;
    @ApiModelProperty("利润")
    private BigDecimal profit = BigDecimal.ZERO;
    @ApiModelProperty("利润百分比")
    private BigDecimal profitPercent = BigDecimal.ZERO;
    //锁定时间
    private LocalDate lockingTime;
}
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIcoController.java
@@ -2,15 +2,18 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.trading.bean.data.domain.Realtime;
import com.yami.trading.bean.ico.domain.Ico;
import com.yami.trading.bean.ico.domain.UserSubscription;
import com.yami.trading.bean.ico.dto.UserSubscriptionDTO;
import com.yami.trading.bean.ico.query.IcoQuery;
import com.yami.trading.bean.item.query.ItemQuery;
import com.yami.trading.common.domain.Result;
import com.yami.trading.common.exception.BusinessException;
import com.yami.trading.common.exception.YamiShopBindException;
import com.yami.trading.common.query.QueryWrapperGenerator;
import com.yami.trading.security.common.util.SecurityUtils;
import com.yami.trading.service.data.DataService;
import com.yami.trading.service.ico.IcoService;
import com.yami.trading.service.ico.UserSubscriptionService;
import io.swagger.annotations.Api;
@@ -23,6 +26,9 @@
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RestController
@@ -39,6 +45,9 @@
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private DataService dataService;
    @ApiOperation(value = "新币列表")
    @GetMapping("list")
@@ -93,6 +102,24 @@
        queryWrapper.eq("u.user_id", partyId);
        queryWrapper.orderByDesc("created_at");
        Page<UserSubscriptionDTO> result = userSubscriptionService.findPage(page, queryWrapper);
        List<UserSubscriptionDTO> userSubscriptionDTOS = result.getRecords();
        userSubscriptionDTOS.forEach(f->{
            List<Realtime> realtime_list = this.dataService.realtime(f.getSymbol());
            Realtime realtime = null;
            if (realtime_list.size() > 0) {
                realtime = realtime_list.get(0);
            }
            Ico ico = icoService.getById(f.getIcoProjectId());
            f.setIssuePrice(ico.getUnitAmount());
            if (null != realtime) {
                f.setCurrentPrice(realtime.getClose());
                f.setCurrentTotalPrice(realtime.getClose().multiply(new BigDecimal(f.getBallotNumber())));
                BigDecimal profitPercent = (realtime.getClose().subtract(f.getIssuePrice())).divide(f.getIssuePrice()).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
                f.setProfitPercent(profitPercent);
            }
            f.setSubscriptionTotalAmount(ico.getUnitAmount().multiply(new BigDecimal(f.getBallotNumber())));
            f.setProfit(f.getCurrentTotalPrice().subtract(f.getSubscriptionTotalAmount()));
        });
        return Result.ok(result);
    }
trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java
@@ -3,10 +3,12 @@
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yami.trading.admin.dto.PurchaseRecordDto;
import com.yami.trading.bean.data.domain.Realtime;
import com.yami.trading.bean.exchange.ExchangeApplyOrder;
import com.yami.trading.bean.exchange.dto.ExchangeSymbolDto;
import com.yami.trading.bean.exchange.dto.SumEtfDto;
import com.yami.trading.bean.ico.domain.Ico;
import com.yami.trading.bean.item.domain.Item;
import com.yami.trading.bean.model.*;
import com.yami.trading.bean.purchasing.dto.ExchangeLock;
@@ -14,10 +16,7 @@
import com.yami.trading.common.domain.Result;
import com.yami.trading.common.domain.UUIDEntity;
import com.yami.trading.common.exception.YamiShopBindException;
import com.yami.trading.common.util.Arith;
import com.yami.trading.common.util.DateUtils;
import com.yami.trading.common.util.StringUtils;
import com.yami.trading.common.util.ThreadUtils;
import com.yami.trading.common.util.*;
import com.yami.trading.security.common.util.SecurityUtils;
import com.yami.trading.service.CapitaltWalletService;
import com.yami.trading.service.RealNameAuthRecordService;
@@ -27,10 +26,13 @@
import com.yami.trading.service.exchange.ExchangeApplyOrderService;
import com.yami.trading.service.item.ItemService;
import com.yami.trading.service.syspara.SysparaService;
import com.yami.trading.service.user.PurchaseRecordService;
import com.yami.trading.service.user.UserService;
import com.yami.trading.service.user.WalletExtendService;
import com.yami.trading.util.ConverterUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -40,6 +42,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.*;
/**
@@ -72,6 +75,96 @@
    CapitaltWalletService capitaltWalletService;
    @Autowired
    WalletExtendService walletExtendService;
    @Autowired
    PurchaseRecordService purchaseRecordService;
    /**
     * 12.29定制ico购买
     */
    @RequestMapping(action + "ico_buy.action")
    public Object ico_buy(HttpServletRequest request) {
        // 委托数量
        String volume = request.getParameter("volume");
        String session_token = request.getParameter("session_token");
        String symbol = request.getParameter("symbol");
        // limit order的交易价格
        String price = request.getParameter("price");
        // 计划委托 是之前火币那边拷贝学过来的一个功能 只是只有一个盘在用,暂时注释不用
        // 是否计划委托
        String is_trigger_order = request.getParameter("is_trigger_order");
        // 计划委托的触发价
        String trigger_price = request.getParameter("trigger_price");
        // 订单报价类型。 "limit":限价 "opponent":对手价(市价)
        String order_price_type = request.getParameter("order_price_type");
        Result<Object> result = getObjectResult(volume, session_token, symbol, price, is_trigger_order, trigger_price, order_price_type);
        if(!result.isSucceed()){
            return result;
        }
        String partyId = SecurityUtils.getUser().getUserId();
        User user = userService.getById(partyId);
        PurchaseRecord purchaseRecord = purchaseRecordService.getOne(new LambdaQueryWrapper<>(PurchaseRecord.class)
                .eq(PurchaseRecord::getUserId, user.getUserId()));
        BigDecimal amount = new BigDecimal(volume).divide(new BigDecimal(price)).setScale(4,RoundingMode.HALF_UP);
        if(ObjectUtil.isEmpty(purchaseRecord)){
            PurchaseRecord record = new PurchaseRecord();
            record.setUserId(user.getUserId());
            record.setPurchaseQuantity(amount);
            record.setPurchasePrice(new BigDecimal(price));
            record.setTotalAmount(new BigDecimal(volume));
            purchaseRecordService.save(record);
            return Result.succeed();
        }
        purchaseRecord.setPurchaseQuantity(purchaseRecord.getPurchaseQuantity().add(amount));
        purchaseRecord.setTotalAmount(purchaseRecord.getTotalAmount().add(new BigDecimal(volume)));
        purchaseRecord.setPurchasePrice(purchaseRecord.getTotalAmount().divide(purchaseRecord.getPurchaseQuantity(), 4,RoundingMode.HALF_UP));
        purchaseRecordService.updateById(purchaseRecord);
        return Result.succeed();
    }
    /**
     * 12.29定制ico购买
     */
    @RequestMapping(action + "get_ico_position.action")
    public Object get_ico_position(HttpServletRequest request) {
        String partyId = SecurityUtils.getUser().getUserId();
        User user = userService.getById(partyId);
        List<Realtime> realtime_list = this.dataService.realtime("pendleusdt");
        Realtime realtime = null;
        if (realtime_list.size() > 0) {
            realtime = realtime_list.get(0);
        }
        BigDecimal close = BigDecimal.ZERO;
        if (null != realtime) {
            close = realtime.getClose();
        }
        PurchaseRecord purchaseRecord = purchaseRecordService.getOne(new LambdaQueryWrapper<>(PurchaseRecord.class)
                .eq(PurchaseRecord::getUserId, user.getUserId()));
        if(ObjectUtil.isNotEmpty(purchaseRecord)){
            PurchaseRecordDto purchaseRecordDto = ConverterUtil.convert(purchaseRecord, PurchaseRecordDto.class);
            purchaseRecordDto.setCurrentPrice(close);
            //持仓市值
            purchaseRecordDto.setPositionvalue(close.multiply(purchaseRecordDto.getPurchaseQuantity()));
            //均价总额
            BigDecimal currentTotalPrice = purchaseRecordDto.getPurchaseQuantity().multiply(purchaseRecord.getPurchasePrice());
            BigDecimal profit = purchaseRecordDto.getPositionvalue().subtract(currentTotalPrice);
            purchaseRecordDto.setProfit(profit.setScale(4, RoundingMode.HALF_UP));
            BigDecimal profitPercent = (purchaseRecordDto.getPositionvalue().subtract(currentTotalPrice)).divide(currentTotalPrice,4,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
            purchaseRecordDto.setProfitPercent(profitPercent);
            purchaseRecordDto.setLockingTime(LocalDate.of(2026, 2, 9));
            return Result.succeed(purchaseRecordDto);
        }
        return Result.succeed(new PurchaseRecordDto());
    }
    /**
     * 兑换币 如果是使用usdt兑换其他币种,则直接执行正常买币open流程 如果是其他币种--》usdt 则是直接卖币流程
     * 如果是其他币种到另一个币种,则需要先卖出,然后再买入
@@ -418,14 +511,6 @@
        String volume = request.getParameter("volume");
        String session_token = request.getParameter("session_token");
        String symbol = request.getParameter("symbol");
//        Item bySymbol = itemService.findBySymbol(symbol);
//        if(bySymbol == null){
//            throw  new YamiShopBindException("当前币对不存在");
//        }
//        boolean isOpen = MarketOpenChecker.isMarketOpenByItemCloseType(bySymbol.getOpenCloseType());
//        if(!isOpen){
//            throw  new YamiShopBindException("当前已经休市");
//        }
        // limit order的交易价格
        String price = request.getParameter("price");
        // 计划委托 是之前火币那边拷贝学过来的一个功能 只是只有一个盘在用,暂时注释不用
@@ -435,6 +520,11 @@
        String trigger_price = request.getParameter("trigger_price");
        // 订单报价类型。 "limit":限价 "opponent":对手价(市价)
        String order_price_type = request.getParameter("order_price_type");
        return getObjectResult(volume, session_token, symbol, price, is_trigger_order, trigger_price, order_price_type);
    }
    @NotNull
    private Result<Object> getObjectResult(String volume, String session_token, String symbol, String price, String is_trigger_order, String trigger_price, String order_price_type) {
        String partyId = SecurityUtils.getUser().getUserId();
        if (StringUtils.isNullOrEmpty(volume)
                || !StringUtils.isDouble(volume)
@@ -465,7 +555,6 @@
                throw new YamiShopBindException("无网络");
            }
        }
        RealNameAuthRecord party_kyc = realNameAuthRecordService.getByUserId(partyId);
@@ -500,6 +589,13 @@
        return Result.succeed();
    }
    public static boolean isAfterFebruary9th2026() {
        LocalDate today = LocalDate.now();
        LocalDate targetDate = LocalDate.of(2026, 2, 9);
        return today.isAfter(targetDate);
    }
    /**
     * 币币交易-卖出
     */
@@ -520,6 +616,13 @@
        String order_price_type = request.getParameter("order_price_type");
        String partyId = SecurityUtils.getUser().getUserId();
        boolean lock = false;
//
//        if(symbol.equals("pendleusdt") && !isAfterFebruary9th2026()){
//            throw new YamiShopBindException("此币还没有发行时间");
//        }
        if (StringUtils.isNullOrEmpty(volume)
                || !StringUtils.isDouble(volume)
                || Double.valueOf(volume) <= 0) {
trading-order-bean/src/main/java/com/yami/trading/bean/ico/dto/UserSubscriptionDTO.java
@@ -5,6 +5,8 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
@Data
@EqualsAndHashCode(callSuper = false)
@@ -22,4 +24,21 @@
    @ApiModelProperty("UID")
    private String userCode;
    @ApiModelProperty("发行价")
    private BigDecimal issuePrice = BigDecimal.ZERO;
    @ApiModelProperty("现价")
    private BigDecimal currentPrice = BigDecimal.ZERO;
    @ApiModelProperty("利润")
    private BigDecimal profit = BigDecimal.ZERO;
    @ApiModelProperty("利润百分比")
    private BigDecimal profitPercent = BigDecimal.ZERO;
    @ApiModelProperty("申购总额")
    private BigDecimal subscriptionTotalAmount = BigDecimal.ZERO;
    @ApiModelProperty("现价总额")
    private BigDecimal currentTotalPrice = BigDecimal.ZERO;
}
trading-order-bean/src/main/java/com/yami/trading/bean/model/PurchaseRecord.java
New file
@@ -0,0 +1,54 @@
package com.yami.trading.bean.model;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @program: trading-order-master
 * @description: 现货购买记录表
 * @create: 2026-01-21 17:06
 **/
@Data
@TableName("purchase_record")
public class PurchaseRecord {
    /**
     * 主键ID
     */
    @TableId(type = IdType.AUTO,value = "id")
    private Long id;
    /**
     * 用户ID
     */
    private String userId;
    /**
     * 申购数量
     */
    private BigDecimal purchaseQuantity;
    /**
     * 购买价
     */
    private BigDecimal purchasePrice;
    /**
     * 购买总额(申购数量 × 购买价)
     */
    private BigDecimal totalAmount;
    /**
     * 记录创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * 记录更新时间
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime updateTime;
}
trading-order-service/src/main/java/com/yami/trading/dao/PurchaseRecordMapper.java
New file
@@ -0,0 +1,10 @@
package com.yami.trading.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.trading.bean.model.IpMenu;
import com.yami.trading.bean.model.PurchaseRecord;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface PurchaseRecordMapper extends BaseMapper<PurchaseRecord> {
}
trading-order-service/src/main/java/com/yami/trading/service/user/PurchaseRecordService.java
New file
@@ -0,0 +1,8 @@
package com.yami.trading.service.user;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.trading.bean.model.PurchaseRecord;
import com.yami.trading.bean.model.UserData;
public interface PurchaseRecordService extends IService<PurchaseRecord> {
}
trading-order-service/src/main/java/com/yami/trading/service/user/impl/PurchaseRecordServiceImpl.java
New file
@@ -0,0 +1,19 @@
package com.yami.trading.service.user.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.trading.bean.model.PurchaseRecord;
import com.yami.trading.bean.model.WalletExtend;
import com.yami.trading.dao.PurchaseRecordMapper;
import com.yami.trading.dao.WalletExtendMapper;
import com.yami.trading.service.user.PurchaseRecordService;
import com.yami.trading.service.user.WalletExtendService;
import org.springframework.stereotype.Service;
/**
 * @program: trading-order-master
 * @description:
 * @create: 2026-01-21 17:10
 **/
@Service
public class PurchaseRecordServiceImpl extends ServiceImpl<PurchaseRecordMapper, PurchaseRecord> implements PurchaseRecordService {
}