新版仿ok交易所-后端
zyy
2025-08-22 451a7241e9c020e7f40ce255776fbb10016e8463
app新币申购
4 files modified
1 files renamed
3 files added
185 ■■■■■ changed files
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIcoController.java 15 ●●●● patch | view | raw | blame | history
trading-order-bean/src/main/java/com/yami/trading/bean/ico/domain/Ico.java 5 ●●●●● patch | view | raw | blame | history
trading-order-bean/src/main/java/com/yami/trading/bean/ico/domain/UserSubscription.java 8 ●●●● patch | view | raw | blame | history
trading-order-common/src/main/java/com/yami/trading/common/constants/Constants.java 12 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/dao/ico/UserSubscriptionMapper.java 14 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/ico/IcoService.java 101 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/ico/UserSubscriptionService.java 23 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/resources/mapper/ico/UserSubscriptionMapper.xml 7 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIcoController.java
@@ -2,9 +2,8 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.trading.api.dto.OpenAction;
import com.yami.trading.bean.ico.domain.Ico;
import com.yami.trading.bean.ico.domain.UserSubscriptionRecord;
import com.yami.trading.bean.ico.domain.UserSubscription;
import com.yami.trading.bean.item.query.ItemQuery;
import com.yami.trading.common.domain.Result;
import com.yami.trading.common.exception.YamiShopBindException;
@@ -14,15 +13,13 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.concurrent.TimeUnit;
@RestController
@@ -48,8 +45,11 @@
    @ApiOperation(value = "新币申购")
    @PostMapping("subscribe")
    @ResponseBody
    public Result<String> subscribe(@Valid UserSubscriptionRecord model) throws IOException, InterruptedException {
    public Result<String> subscribe(@Valid UserSubscription model) {
        String partyId = SecurityUtils.getUser().getUserId();
        if (StringUtils.isEmpty(partyId)) {
            throw new YamiShopBindException("请重新登录");
        }
        RLock rLock = redissonClient.getLock("subscribe" + partyId);
        boolean lockAcquired = false;
        try {
@@ -59,7 +59,8 @@
                log.warn("无法获取锁: subscribe{}", partyId);
                throw new YamiShopBindException("请稍后再试");
            }
            subscribe(model);
            model.setUserId(partyId);
            icoService.subscribe(model);
        } catch (YamiShopBindException e) {
            log.error("错误信息: {}", e.getMessage(), e);
            throw e; // 重新抛出自定义异常
trading-order-bean/src/main/java/com/yami/trading/bean/ico/domain/Ico.java
@@ -3,7 +3,6 @@
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yami.trading.common.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@
/**
 * 产品Entity
 * 新币Entity
 *
 */
@Data
@@ -62,7 +61,7 @@
    private BigDecimal borrowingRate;
    @ApiModelProperty("发行价")
    private String issuePrice;
    private BigDecimal issuePrice;
    @ApiModelProperty("接受的支付货币")
    private  String currency;
trading-order-bean/src/main/java/com/yami/trading/bean/ico/domain/UserSubscription.java
File was renamed from trading-order-bean/src/main/java/com/yami/trading/bean/ico/domain/UserSubscriptionRecord.java
@@ -17,7 +17,7 @@
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("user_subscription_record")
public class UserSubscriptionRecord {
public class UserSubscription {
    @TableId(type = IdType.AUTO,value = "id")
    private Integer id;
@@ -26,7 +26,11 @@
    private Integer icoProjectId;
    @ApiModelProperty("用户id")
    private Integer userId;
    private String userId;
    @ApiModelProperty("订单号")
    private String orderNo;
    @ApiModelProperty("申购数量")
    private Integer subscribeNums;
trading-order-common/src/main/java/com/yami/trading/common/constants/Constants.java
@@ -160,6 +160,18 @@
    };
    /**
     * 新币交易
     */
    public static final String MONEYLOG_CONTENT_NEW_COIN = "new_coin";
    /**
     * 新币买入
     */
    public static final String MONEYLOG_CONTENT_NEW_COIN_OPEN = "new_coin_open";
    /**
     * 币币交易
     */
    public static final String MONEYLOG_CATEGORY_EXCHANGE = "exchange";
trading-order-service/src/main/java/com/yami/trading/dao/ico/UserSubscriptionMapper.java
New file
@@ -0,0 +1,14 @@
package com.yami.trading.dao.ico;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.trading.bean.ico.domain.UserSubscription;
/**
 * 新币记录MAPPER接口
 */
public interface UserSubscriptionMapper extends BaseMapper<UserSubscription> {
}
trading-order-service/src/main/java/com/yami/trading/service/ico/IcoService.java
@@ -3,13 +3,28 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.trading.bean.ico.domain.Ico;
import com.yami.trading.bean.ico.domain.UserSubscriptionRecord;
import com.yami.trading.bean.ico.domain.UserSubscription;
import com.yami.trading.bean.model.MoneyLog;
import com.yami.trading.bean.model.User;
import com.yami.trading.bean.model.Wallet;
import com.yami.trading.common.constants.Constants;
import com.yami.trading.common.domain.Result;
import com.yami.trading.common.exception.YamiShopBindException;
import com.yami.trading.common.util.Arith;
import com.yami.trading.common.util.C2cLock;
import com.yami.trading.dao.ico.IcoMapper;
import com.yami.trading.service.MoneyLogService;
import com.yami.trading.service.WalletService;
import com.yami.trading.service.user.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
/**
 * 新币Service
@@ -20,14 +35,92 @@
@Slf4j
public class IcoService extends ServiceImpl<IcoMapper, Ico> {
    @Autowired
    UserService userService;
    @Autowired
    WalletService walletService;
    @Autowired
    UserSubscriptionService userSubscriptionService;
    @Autowired
    MoneyLogService moneyLogService;
    /**
     * 申购
     * 新币申购
     * @param model
     * @return
     */
    public Result<String> subscribe(UserSubscriptionRecord model) {
    public Result<String> subscribe(UserSubscription model) {
        try {
            if (model == null || model.getIcoProjectId() == null) {
                throw new YamiShopBindException("参数异常");
            }
            String partyId = model.getUserId();
            Ico ico = this.getById(model.getIcoProjectId());
            if (ico == null) {
                throw new YamiShopBindException("新币不存在");
            }
        return Result.ok("保存产品成功" );
            User party = userService.getById(partyId);
            if (!party.isEnabled()) {
                return Result.succeed("User is locked");
            }
            if (Constants.SECURITY_ROLE_TEST.equals(party.getRoleName())) {
                throw new YamiShopBindException("无权限");
            }
            if (!C2cLock.add(partyId)) {
                throw new YamiShopBindException("Please try again later");
            }
            if (model.getSubscribeNums() == null || model.getSubscribeNums() == 0) {
                throw new YamiShopBindException("申请数量不能为空");
            }
            //购买金额
            BigDecimal amount = ico.getUnitAmount().multiply(new BigDecimal(model.getSubscribeNums()));
            Wallet wallet = walletService.saveWalletByPartyId(partyId);
            if (amount.compareTo(wallet.getMoney()) > 0) {
                throw new YamiShopBindException("余额不足");
            }
            if(amount.compareTo(ico.getMinContribution()) < 0 ){
                throw new YamiShopBindException("最低投资额: " + ico.getMinContribution());
            }
            if(amount.compareTo(ico.getMaxContribution()) > 0 ){
                throw new YamiShopBindException("最高投资额: " + ico.getMaxContribution());
            }
            Date currentDate = new Date();
            if(currentDate.before(ico.getStartDate())){
                throw new YamiShopBindException("未开售");
            }
            if(currentDate.after(ico.getEndDate())){
                throw new YamiShopBindException("已结束");
            }
            model.setStatus(1);
            model.setUserId(partyId);
            if (model.getSubscriptionType() == null) { //默认自主申购
                model.setSubscriptionType(1);
            }
            userSubscriptionService.save(model);
            walletService.update(partyId, Arith.sub(0, amount.doubleValue()));
            // 保存 资金日志
            MoneyLog moneylog = new MoneyLog();
            moneylog.setCategory(Constants.MONEYLOG_CONTENT_NEW_COIN);
            moneylog.setAmountBefore(wallet.getMoney());
            moneylog.setAmount(amount);
            moneylog.setAmountAfter(BigDecimal.valueOf(Arith.sub(wallet.getMoney().doubleValue(), amount.doubleValue())));
            moneylog.setLog("新币购买,申购金额[" + amount + "]");
            moneylog.setUserId(partyId);
            moneylog.setSymbol(ico.getSymbol());
            moneylog.setWalletType(ico.getSymbol());
            moneylog.setContentType(Constants.MONEYLOG_CONTENT_NEW_COIN_OPEN);
            moneyLogService.save(moneylog);
            return Result.ok("申请成功" );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
trading-order-service/src/main/java/com/yami/trading/service/ico/UserSubscriptionService.java
New file
@@ -0,0 +1,23 @@
package com.yami.trading.service.ico;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.trading.bean.ico.domain.UserSubscription;
import com.yami.trading.dao.ico.UserSubscriptionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * 新币记录Service
 */
@Service
@Transactional
@Slf4j
public class UserSubscriptionService extends ServiceImpl<UserSubscriptionMapper, UserSubscription> {
}
trading-order-service/src/main/resources/mapper/ico/UserSubscriptionMapper.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.trading.dao.ico.UserSubscriptionMapper">
</mapper>