wangqifan 3 rokov pred
rodič
commit
b45093450b

+ 4 - 0
src/main/java/com/izouma/nineth/domain/TradeAuction.java

@@ -62,8 +62,12 @@ public class TradeAuction extends BaseEntity {
     @ApiModelProperty("开始时间")
     private LocalDateTime startTime;
 
+    //当前报价
     private BigDecimal currentPrice;
 
+    //起拍价
+    private BigDecimal price;
+
     private String currentOwner;
 
     private Long currentOwnerId;

+ 100 - 1
src/main/java/com/izouma/nineth/domain/TradeAuctionOrder.java

@@ -1,4 +1,103 @@
 package com.izouma.nineth.domain;
 
-public class TradeAuctionOrder {
+import com.izouma.nineth.annotations.Searchable;
+import com.izouma.nineth.annotations.SearchableOne;
+import com.izouma.nineth.converter.FileObjectListConverter;
+import com.izouma.nineth.enums.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Data
+@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@ApiModel("易拍订单")
+public class TradeAuctionOrder extends BaseEntity {
+    private Long id;
+
+    @ApiModelProperty("用户ID")
+    @SearchableOne
+    private Long userId;
+
+    private String nickname;
+
+    @ApiModelProperty("拍卖ID")
+    private Long tradeAuctionId;
+
+    @ApiModelProperty("名称")
+    @SearchableOne
+    private String name;
+
+    @ApiModelProperty("图片")
+    @Column(columnDefinition = "TEXT")
+    @Convert(converter = FileObjectListConverter.class)
+    private List<FileObject> pic;
+
+    @ApiModelProperty("手续费")
+    private BigDecimal serviceCharge;
+
+    @ApiModelProperty("收益补偿")
+    private BigDecimal earnedPrice;
+
+    @Enumerated(EnumType.STRING)
+    @ApiModelProperty("拍卖类型")
+    private AuctionSource source;
+
+    @Enumerated(EnumType.STRING)
+    @ApiModelProperty("支付类型")
+    private AuctionPaymentType paymentType;
+
+    @ApiModelProperty("产品起拍价")
+    @Column(precision = 10, scale = 2)
+    private BigDecimal originPrice;
+
+    @ApiModelProperty("支付价格")
+    @Column(precision = 10, scale = 2)
+    private BigDecimal price;
+
+    @ApiModelProperty("拍卖报价")
+    @Column(precision = 10, scale = 2)
+    private BigDecimal currentPrice;
+
+    @ApiModelProperty("状态")
+    @Enumerated(EnumType.STRING)
+    private AuctionOrderStatus status;
+
+    @ApiModelProperty("支付方式")
+    @Enumerated(EnumType.STRING)
+    private PayMethod payMethod;
+
+    @ApiModelProperty("交易ID")
+    @Searchable
+    @Column(length = 90)
+    private String transactionId;
+
+    @ApiModelProperty("支付时间")
+    private LocalDateTime payTime;
+
+    @ApiModelProperty("取消时间")
+    private LocalDateTime cancelTime;
+
+    @ApiModelProperty("退款时间")
+    private LocalDateTime refundTime;
+
+
+    @ApiModelProperty("拍卖记录id")
+    private Long recordId;
+
+    @ApiModelProperty("补偿状态")
+    @Enumerated(EnumType.STRING)
+    private PaybackStatus paybackStatus;
+
+    private Long balanceRecordId;
 }

+ 17 - 0
src/main/java/com/izouma/nineth/enums/PaybackStatus.java

@@ -0,0 +1,17 @@
+package com.izouma.nineth.enums;
+
+public enum PaybackStatus {
+    NOPASSED("未出局"),
+    PASSED("已出局"),
+    PAYED("已补偿");
+
+    private final String description;
+
+    PaybackStatus(String description) {
+        this.description = description;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

+ 1 - 0
src/main/java/com/izouma/nineth/enums/TradeAuctionStatus.java

@@ -3,6 +3,7 @@ package com.izouma.nineth.enums;
 public enum TradeAuctionStatus {
     NOTSTARTED("未开始"),
     ONGOING("进行中"),
+    WAITING("冷却中"),
     PURCHASED("成熟"),
     FIXED_PRICE_PURCHASED("一口价成交"),
     PASS("流拍"),

+ 22 - 0
src/main/java/com/izouma/nineth/repo/TradeAuctionOrderRepo.java

@@ -0,0 +1,22 @@
+package com.izouma.nineth.repo;
+
+import com.izouma.nineth.domain.TradeAuctionOrder;
+import com.izouma.nineth.enums.AuctionOrderStatus;
+import com.izouma.nineth.service.LikeService;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import javax.transaction.Transactional;
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface TradeAuctionOrderRepo extends JpaRepository<TradeAuctionOrder, Long>, JpaSpecificationExecutor<TradeAuctionOrder> {
+    @Query("update TradeAuctionOrder t set t.del = true where t.id = ?1")
+    @Modifying
+    @Transactional
+    void softDelete(Long id);
+
+    List<TradeAuctionOrder> findByStatusAndCreatedAtBeforeAndDelFalse(AuctionOrderStatus status, LocalDateTime time);
+}

+ 16 - 0
src/main/java/com/izouma/nineth/repo/TradeAuctionRecordRepo.java

@@ -0,0 +1,16 @@
+package com.izouma.nineth.repo;
+
+import com.izouma.nineth.domain.TradeAuctionRecord;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import javax.transaction.Transactional;
+
+public interface TradeAuctionRecordRepo extends JpaRepository<TradeAuctionRecord, Long>, JpaSpecificationExecutor<TradeAuctionRecord> {
+    @Query("update TradeAuctionRecord t set t.del = true where t.id = ?1")
+    @Modifying
+    @Transactional
+    void softDelete(Long id);
+}

+ 6 - 0
src/main/java/com/izouma/nineth/repo/TradeAuctionRepo.java

@@ -1,12 +1,16 @@
 package com.izouma.nineth.repo;
 
 import com.izouma.nineth.domain.TradeAuction;
+import com.izouma.nineth.enums.TradeAuctionStatus;
+import com.izouma.nineth.service.LikeService;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
 import javax.transaction.Transactional;
+import java.time.LocalDateTime;
+import java.util.List;
 
 public interface TradeAuctionRepo extends JpaRepository<TradeAuction, Long>, JpaSpecificationExecutor<TradeAuction> {
     @Query("update TradeAuction t set t.del = true where t.id = ?1")
@@ -29,4 +33,6 @@ public interface TradeAuctionRepo extends JpaRepository<TradeAuction, Long>, Jpa
     @Transactional
     @Modifying
     int updateSale(Long id, int sale);
+
+    List<TradeAuction> findByStatusAndCurrentEndTimeAfter(TradeAuctionStatus status, LocalDateTime time);
 }

+ 126 - 0
src/main/java/com/izouma/nineth/service/TradeAuctionOrderService.java

@@ -0,0 +1,126 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.domain.*;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.*;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.TradeAuctionOrderRepo;
+import com.izouma.nineth.repo.TradeAuctionRepo;
+import com.izouma.nineth.repo.UserRepo;
+import com.izouma.nineth.utils.JpaUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.domain.Page;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+@Slf4j
+public class TradeAuctionOrderService {
+
+    private TradeAuctionOrderRepo tradeAuctionOrderRepo;
+    private TradeAuctionService   tradeAuctionService;
+    private TradeAuctionRepo      tradeAuctionRepo;
+    private UserRepo              userRepo;
+
+    private static int orderCancelInterval = 210;
+
+    public Page<TradeAuctionOrder> all(PageQuery pageQuery) {
+        return tradeAuctionOrderRepo.findAll(JpaUtils.toSpecification(pageQuery, TradeAuctionOrder.class), JpaUtils
+                .toPageRequest(pageQuery));
+    }
+
+    public TradeAuctionOrder create(Long auctionId, Long userId, BigDecimal price) {
+        TradeAuction tradeAuction = tradeAuctionRepo.findById(auctionId).orElseThrow(new BusinessException("未找到易拍活动"));
+        User user = userRepo.findById(userId).orElseThrow(new BusinessException("暂无用户"));
+        if (tradeAuction.getCurrentOwnerId().equals(userId)) {
+            throw new BusinessException("不可竞价持有的易拍产品");
+        }
+        if (LocalDateTime.now().compareTo(tradeAuction.getCurrentEndTime()) < 0) {
+            throw new BusinessException("未到竞价时间");
+        }
+        if (!tradeAuction.getStatus().equals(TradeAuctionStatus.ONGOING)) {
+            throw new BusinessException("易拍产品未处在竞价状态");
+        }
+        BigDecimal serviceCharge = (BigDecimal.valueOf(0.03).multiply(tradeAuction.getCurrentPrice()))
+                .add(tradeAuction.getCurrentPrice().subtract(tradeAuction.getPrice()));
+        TradeAuctionOrder tradeAuctionOrder = TradeAuctionOrder.builder()
+                .tradeAuctionId(tradeAuction.getId())
+                .earnedPrice(price.subtract(tradeAuction.getPrice()))
+                .serviceCharge(serviceCharge)
+                .name(tradeAuction.getName())
+                .nickname(user.getNickname())
+                .userId(user.getId())
+                .originPrice(tradeAuction.getPrice())
+                .currentPrice(tradeAuction.getCurrentPrice())
+                .price(price)
+                .paybackStatus(PaybackStatus.NOPASSED)
+                .pic(tradeAuction.getPic())
+                .source(AuctionSource.OFFICIAL)
+                .status(AuctionOrderStatus.NOT_PAID)
+                .build();
+        tradeAuctionOrder = tradeAuctionOrderRepo.save(tradeAuctionOrder);
+        //下订单减库存
+        tradeAuctionService.decreaseStock(tradeAuction.getStock(), 1);
+        return tradeAuctionOrder;
+    }
+
+    @Transactional
+    public void notify(Long orderId, String transactionId, PayMethod payMethod) {
+        TradeAuctionOrder tradeAuctionOrder = tradeAuctionOrderRepo.findById(orderId)
+                .orElseThrow(new BusinessException("未找到订单"));
+        if (!tradeAuctionOrder.getStatus().equals(AuctionOrderStatus.NOT_PAID)) {
+            throw new BusinessException("订单已经处理");
+        }
+        tradeAuctionOrder.setPayTime(LocalDateTime.now());
+        tradeAuctionOrder.setPayMethod(payMethod);
+        tradeAuctionOrder.setTransactionId(transactionId);
+        tradeAuctionOrder.setStatus(AuctionOrderStatus.FINISH);
+        tradeAuctionOrderRepo.save(tradeAuctionOrder);
+
+        TradeAuction tradeAuction = tradeAuctionRepo.findById(tradeAuctionOrder.getTradeAuctionId())
+                .orElseThrow(new BusinessException("未找到该易拍活动"));
+        tradeAuction.setStatus(TradeAuctionStatus.WAITING);
+        tradeAuction.setCurrentPrice(tradeAuctionOrder.getCurrentPrice());
+        tradeAuction.setCurrentOwner(tradeAuctionOrder.getNickname());
+        tradeAuction.setCurrentOwnerId(tradeAuctionOrder.getUserId());
+        tradeAuction.setCurrentEndTime(tradeAuction.getCurrentEndTime().plusDays(1));
+        tradeAuctionRepo.save(tradeAuction);
+
+        tradeAuctionService.increaseSale(tradeAuction.getId(), 1);
+    }
+
+    @Scheduled(fixedRate = 30000)
+    public void batchCancelledAuctionOrder() {
+        List<TradeAuctionOrder> orders = tradeAuctionOrderRepo
+                .findByStatusAndCreatedAtBeforeAndDelFalse(AuctionOrderStatus.NOT_PAID,
+                        LocalDateTime.now().minusSeconds(orderCancelInterval));
+        orders.parallelStream().forEach(o -> {
+            try {
+                TradeAuctionOrder order = tradeAuctionOrderRepo.findById(o.getId())
+                        .orElseThrow(new BusinessException("订单不存在"));
+                if (order.getStatus() == AuctionOrderStatus.NOT_PAID) {
+                    cancel(order);
+                }
+            } catch (Exception e) {
+                log.error("取消易拍订单错误 " + o.getId(), e);
+            }
+        });
+    }
+
+    public void cancel(TradeAuctionOrder order) {
+        if (order.getStatus() != AuctionOrderStatus.NOT_PAID) {
+            throw new BusinessException("当前订单状态无法取消[" + order.getStatus().name() + "]");
+        }
+        order.setStatus(AuctionOrderStatus.CANCELLED);
+        order.setCancelTime(LocalDateTime.now());
+        tradeAuctionService.increaseStock(order.getTradeAuctionId(), 1);
+        tradeAuctionOrderRepo.save(order);
+    }
+}

+ 20 - 0
src/main/java/com/izouma/nineth/service/TradeAuctionRecordService.java

@@ -0,0 +1,20 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.domain.TradeAuctionRecord;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.repo.TradeAuctionRecordRepo;
+import com.izouma.nineth.utils.JpaUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class TradeAuctionRecordService {
+
+    private TradeAuctionRecordRepo tradeAuctionRecordRepo;
+
+    public Page<TradeAuctionRecord> all(PageQuery pageQuery) {
+        return tradeAuctionRecordRepo.findAll(JpaUtils.toSpecification(pageQuery, TradeAuctionRecord.class), JpaUtils.toPageRequest(pageQuery));
+    }
+}

+ 36 - 5
src/main/java/com/izouma/nineth/service/TradeAuctionService.java

@@ -3,8 +3,10 @@ package com.izouma.nineth.service;
 import com.izouma.nineth.config.GeneralProperties;
 import com.izouma.nineth.config.RedisKeys;
 import com.izouma.nineth.domain.TradeAuction;
+import com.izouma.nineth.domain.TradeAuctionOrder;
 import com.izouma.nineth.domain.TradeAuctionRecord;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.AuctionOrderStatus;
 import com.izouma.nineth.enums.TradeAuctionStatus;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.TradeAuctionRepo;
@@ -15,9 +17,12 @@ import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.data.domain.Page;
 import org.springframework.data.redis.core.BoundValueOperations;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import java.security.PrivateKey;
+import java.time.LocalDateTime;
+import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 
@@ -36,11 +41,12 @@ public class TradeAuctionService {
                 .findAll(JpaUtils.toSpecification(pageQuery, TradeAuction.class), JpaUtils.toPageRequest(pageQuery));
     }
 
-    public void createRecord(Long id) {
-        TradeAuctionRecord tradeAuctionRecord = new TradeAuctionRecord();
-        TradeAuction tradeAuction = tradeAuctionRepo.findById(id).orElseThrow(new BusinessException("暂无"));
-        tradeAuction.setStatus(TradeAuctionStatus.FINISH);
-    }
+//    public void transfer(Long id) {
+//        TradeAuctionRecord tradeAuctionRecord = new TradeAuctionRecord();
+//        TradeAuction tradeAuction = tradeAuctionRepo.findById(id).orElseThrow(new BusinessException("暂无"));
+//        tradeAuction.setStatus(TradeAuctionStatus.WAITING);
+//        increaseSale(tr)
+//    }
 
     public synchronized Long increaseStock(Long id, int number) {
         BoundValueOperations<String, Object> ops = redisTemplate.boundValueOps(RedisKeys.AUCTION_STOCK + id);
@@ -107,4 +113,29 @@ public class TradeAuctionService {
 //            cacheService.clearCollection(id);
         }
     }
+
+    @Scheduled(fixedRate = 6000)
+    public void batchStartAuction() {
+        List<TradeAuction> tradeAuctions = tradeAuctionRepo
+                .findByStatusAndCurrentEndTimeAfter(TradeAuctionStatus.WAITING,
+                        LocalDateTime.now().plusMinutes(1));
+        tradeAuctions.parallelStream().forEach(o -> {
+            try {
+                TradeAuction auction = tradeAuctionRepo.findById(o.getId())
+                        .orElseThrow(new BusinessException("订单不存在"));
+                if (auction.getStatus() == TradeAuctionStatus.WAITING) {
+                    start(auction);
+                }
+            } catch (Exception e) {
+                log.error("取消易拍订单错误 " + o.getId(), e);
+            }
+        });
+    }
+
+    public void start(TradeAuction tradeAuction) {
+        tradeAuction.setStatus(TradeAuctionStatus.ONGOING);
+        tradeAuctionRepo.save(tradeAuction);
+
+        increaseStock(tradeAuction.getId(), 1);
+    }
 }

+ 77 - 0
src/main/java/com/izouma/nineth/web/TradeAuctionOrderController.java

@@ -0,0 +1,77 @@
+package com.izouma.nineth.web;
+
+import com.izouma.nineth.domain.TradeAuctionOrder;
+import com.izouma.nineth.enums.PayMethod;
+import com.izouma.nineth.service.TradeAuctionOrderService;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.TradeAuctionOrderRepo;
+import com.izouma.nineth.utils.ObjUtils;
+import com.izouma.nineth.utils.excel.ExcelUtils;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.data.domain.Page;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Locale;
+
+@RestController
+@RequestMapping("/tradeAuctionOrder")
+@AllArgsConstructor
+public class TradeAuctionOrderController extends BaseController {
+    private TradeAuctionOrderService tradeAuctionOrderService;
+    private TradeAuctionOrderRepo    tradeAuctionOrderRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public TradeAuctionOrder save(@RequestBody TradeAuctionOrder record) {
+        if (record.getId() != null) {
+            TradeAuctionOrder orig = tradeAuctionOrderRepo.findById(record.getId())
+                    .orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return tradeAuctionOrderRepo.save(orig);
+        }
+        return tradeAuctionOrderRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<TradeAuctionOrder> all(@RequestBody PageQuery pageQuery) {
+        return tradeAuctionOrderService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public TradeAuctionOrder get(@PathVariable Long id) {
+        return tradeAuctionOrderRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        tradeAuctionOrderRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<TradeAuctionOrder> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+
+    @PostMapping("/createOrder")
+    public TradeAuctionOrder create(Long tradeAuctionId, Long userId, BigDecimal price) {
+        return tradeAuctionOrderService.create(tradeAuctionId, userId, price);
+    }
+
+    @PostMapping("/testPay")
+    public void create(Long orderId) {
+        tradeAuctionOrderService.notify(orderId, RandomStringUtils
+                .randomAlphanumeric(10).toLowerCase(Locale.ROOT), PayMethod.BALANCE);
+    }
+}
+

+ 60 - 0
src/main/java/com/izouma/nineth/web/TradeAuctionRecordController.java

@@ -0,0 +1,60 @@
+package com.izouma.nineth.web;
+import com.izouma.nineth.domain.TradeAuctionRecord;
+import com.izouma.nineth.service.TradeAuctionRecordService;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.TradeAuctionRecordRepo;
+import com.izouma.nineth.utils.ObjUtils;
+import com.izouma.nineth.utils.excel.ExcelUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/tradeAuctionRecord")
+@AllArgsConstructor
+public class TradeAuctionRecordController extends BaseController {
+    private TradeAuctionRecordService tradeAuctionRecordService;
+    private TradeAuctionRecordRepo tradeAuctionRecordRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public TradeAuctionRecord save(@RequestBody TradeAuctionRecord record) {
+        if (record.getId() != null) {
+            TradeAuctionRecord orig = tradeAuctionRecordRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return tradeAuctionRecordRepo.save(orig);
+        }
+        return tradeAuctionRecordRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<TradeAuctionRecord> all(@RequestBody PageQuery pageQuery) {
+        return tradeAuctionRecordService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public TradeAuctionRecord get(@PathVariable Long id) {
+        return tradeAuctionRecordRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        tradeAuctionRecordRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<TradeAuctionRecord> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+