Explorar o código

拍卖项目
保证金管理
保证金详情

hr~ hai 1 mes
pai
achega
0fddcf60b7

+ 47 - 0
auc/src/main/java/cn/hobbystocks/auc/web/DepositRecordController.java

@@ -0,0 +1,47 @@
+package cn.hobbystocks.auc.web;
+
+import cn.hobbystocks.auc.common.core.domain.AjaxResult;
+import cn.hobbystocks.auc.common.user.UserInfo;
+import cn.hobbystocks.auc.common.user.UserUtils;
+import cn.hobbystocks.auc.dto.DepositRecordDTO;
+import cn.hobbystocks.auc.request.DepositRecordRequest;
+import cn.hobbystocks.auc.response.DiamondPositionResponse;
+import cn.hobbystocks.auc.service.DepositOrderService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author huang_run
+ * @date 2026/5/7 16:13
+ */
+@RestController
+@RequestMapping("/deposit/record")
+@Api(tags = "后台保证金管理")
+public class DepositRecordController extends AdminBaseController {
+
+    @Autowired
+    private DepositOrderService depositOrderService;
+
+
+    @ApiOperation(value = "分页查询保证金", notes = "分页查询保证金列表", response = DepositRecordDTO.class, responseContainer = "List<DepositRecordDTO>")
+    @PostMapping("/list")
+    @ApiResponses({
+        @ApiResponse(code = 0, message = "请求成功", response = DiamondPositionResponse.class)
+    })
+    public AjaxResult page(@RequestBody DepositRecordRequest request) {
+        UserInfo userInfo = UserUtils.getSimpleUserInfo();
+        if (Objects.isNull(userInfo)) {
+            return AjaxResult.error("请先登录");
+        }
+        startPage(request);
+        List<DepositRecordDTO> list = depositOrderService.selectDepositRecordPage(request);
+        return AjaxResult.successPage(list);
+    }
+}

+ 5 - 9
bid/src/main/java/cn/hobbystocks/auc/task/BidTask.java

@@ -354,18 +354,15 @@ public class BidTask implements CacheMap {
                 List<Order> orderList = orderService.getOrderListByUserAndAuction(order.getAuctionId(), userId);
                 if (CollectionUtils.isEmpty(orderList)){
                     //todo 没有待支付订单,或没中标,或已支付,执行退保证金操作
-                    OrderVO orderVO = depositOrderService.refundDepositOrder(order.getOrderNo());
-                    // todo 更新保证金订单状态
-
-                    depositOrderService.lambdaUpdate().eq(DepositOrder::getId,order.getId()).set(DepositOrder::getStatus,orderVO.getStatus());
+                   depositOrderService.refundDepositOrder(order.getOrderNo());
                     continue;
                 }
                 //有待支付的订单列表,判断订单是否已过期,并更新订单记录表状态,
                 for (Order order1 : orderList) {
                   if (order1.getFlag()==2){
                       //todo 订单待支付已过期,调用扣除保证金接口,更新订单记录表状态
-
-                      // todo 更新保证金订单状态
+                      depositOrderService.reduceDeposit(order.getOrderNo());
+                      break;
                   }
                 }
             }else{
@@ -379,15 +376,14 @@ public class BidTask implements CacheMap {
                 LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
                 queryWrapper.eq(Order::getLotId,lotId).eq(Order::getUserId,order.getUserId());
                 Order order1 = orderService.getOne(queryWrapper);
-
                 if (order1==null){
                     //todo 未中标,退拍品保证金
-
+                    depositOrderService.refundDepositOrder(order.getOrderNo());
                     continue;
                 }
                 if (order1.getFlag()==2){
                     //todo 订单已过期 调用接口扣除保证金
-
+                    depositOrderService.reduceDeposit(order.getOrderNo());
                 }
             }
         }

+ 21 - 8
bid/src/main/java/cn/hobbystocks/auc/web/DepositOrderController.java

@@ -34,9 +34,9 @@ public class DepositOrderController {
 
     //创建保证金订单接口
     @PostMapping("/deposit/create")
-    @ApiOperation(value = "创建保证金订单接口",notes = "")
+    @ApiOperation(value = "创建保证金订单接口", notes = "")
     @ResponseBody
-    public AjaxResult createDepositOrder(@RequestBody DepositOrderDTO depositOrderDTO){
+    public AjaxResult createDepositOrder(@RequestBody DepositOrderDTO depositOrderDTO) {
         UserInfo simpleUserInfo = UserUtils.getSimpleUserInfo();
         if (Objects.isNull(simpleUserInfo))
             return AjaxResult.error("请先登录");
@@ -49,22 +49,35 @@ public class DepositOrderController {
     //我的保证金订单
     @PostMapping("/deposit/list")
     @ResponseBody
-    @ApiOperation(value = "保证金订单查询",notes = "根据保证金订单状态分页查询保证金信息;")
-    public AjaxResult depositOrderList(@RequestBody DepositOrderDTO depositOrderDTO){
+    @ApiOperation(value = "保证金订单查询", notes = "根据保证金订单状态分页查询保证金信息;")
+    public AjaxResult depositOrderList(@RequestBody DepositOrderDTO depositOrderDTO) {
 
         UserInfo simpleUserInfo = UserUtils.getSimpleUserInfo();
-        if (simpleUserInfo==null)
+        if (simpleUserInfo == null)
             return AjaxResult.error("请先登录");
         Integer userId = simpleUserInfo.getId();
         //根据userId 查询保证金信息
         LambdaQueryWrapper<DepositOrder> depositOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        depositOrderLambdaQueryWrapper.eq(DepositOrder::getUserId,userId);
+        depositOrderLambdaQueryWrapper.eq(DepositOrder::getUserId, userId);
         Integer status = depositOrderDTO.getStatus();
-        if (status!=null){
-            depositOrderLambdaQueryWrapper.eq(DepositOrder::getStatus,status);
+        if (status != null) {
+            depositOrderLambdaQueryWrapper.eq(DepositOrder::getStatus, status);
         }
         PageUtils.startPage(depositOrderDTO);
         List<DepositOrder> list = orderService.list(depositOrderLambdaQueryWrapper);
         return AjaxResult.success(list);
     }
+
+    @GetMapping("deposit/detail/{depositOrderNo}")
+    public AjaxResult depositOrderDetail(@PathVariable String depositOrderNo) {
+        UserInfo simpleUserInfo = UserUtils.getSimpleUserInfo();
+        if (simpleUserInfo == null)
+            return AjaxResult.error("请先登录");
+        Integer userId = simpleUserInfo.getId();
+        LambdaQueryWrapper<DepositOrder> depositOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        depositOrderLambdaQueryWrapper.eq(DepositOrder::getOrderNo, depositOrderNo);
+        depositOrderLambdaQueryWrapper.eq(DepositOrder::getUserId, userId);
+        DepositOrder depositOrder = orderService.getOne(depositOrderLambdaQueryWrapper);
+        return AjaxResult.success(depositOrder);
+    }
 }

+ 9 - 8
bid/src/main/java/cn/hobbystocks/auc/web/LotController.java

@@ -5,17 +5,15 @@ import cn.hobbystocks.auc.common.core.domain.AjaxResult;
 import cn.hobbystocks.auc.domain.Lot;
 import cn.hobbystocks.auc.request.CategoryQueryRequest;
 import cn.hobbystocks.auc.request.LotQueryRequest;
+import cn.hobbystocks.auc.response.LotDetailResponse;
 import cn.hobbystocks.auc.response.LotFansResponse;
 import cn.hobbystocks.auc.response.SpuMainCategoryResponse;
 import cn.hobbystocks.auc.service.ILotService;
 import cn.hobbystocks.auc.service.SpuCategoryService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import io.swagger.annotations.ApiParam;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.util.List;
@@ -71,8 +69,11 @@ public class LotController extends BaseController {
         return AjaxResult.success(allCategoryList);
     }
 
-
-
-
+    @GetMapping("/detail/{lotId}")
+    @ApiOperation("lot detail")
+    public AjaxResult detail(@PathVariable("lotId")@ApiParam("拍品ID") Long lotId) {
+        LotDetailResponse response = lotService.queryLotDetail(lotId);
+        return AjaxResult.success(response);
+    }
 
 }

+ 1 - 8
bid/src/main/java/cn/hobbystocks/auc/web/SelfController.java

@@ -21,14 +21,7 @@ public class SelfController {
     @ApiOperation("分页获取正在进行的拍卖/已结束的拍卖/已获胜的拍卖")
     @PostMapping
     public AjaxResult self(@RequestBody SelfVO selfVO) {
-        if ("live".equals(selfVO.getType())) {
-            return AjaxResult.success(PaginationUtil.page(selfVO, lotService.selfLive(selfVO)));
-        }else if ("finish".equals(selfVO.getType())) {
-            return AjaxResult.success(PaginationUtil.page(selfVO, lotService.selfFinish(selfVO)));
-        }else if ("win".equals(selfVO.getType())){
-            return AjaxResult.success(PaginationUtil.page(selfVO, lotService.selfWin(selfVO)));
-        }
-        return AjaxResult.success();
+        return AjaxResult.success(PaginationUtil.page(selfVO, lotService.selfList(selfVO)));
     }
 
 }

BIN=BIN
img.png


+ 6 - 0
lot/src/main/java/cn/hobbystocks/auc/domain/DepositOrder.java

@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 
+import java.util.Date;
+
 @TableName("deposit_order_record")
 @Data
 public class DepositOrder extends BaseEntity {
@@ -22,4 +24,8 @@ public class DepositOrder extends BaseEntity {
     private Long amount;//订单金额
     private String orderNo;
     private Long merchantId;
+
+    private Date payTime;
+
+    private Integer payType;
 }

+ 62 - 0
lot/src/main/java/cn/hobbystocks/auc/dto/DepositRecordDTO.java

@@ -0,0 +1,62 @@
+package cn.hobbystocks.auc.dto;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author huang_run
+ * @date 2026/5/7 16:14
+ */
+@Data
+@Builder
+@ApiModel("后台保证金列表")
+@NoArgsConstructor
+@AllArgsConstructor
+public class DepositRecordDTO {
+
+    @ApiModelProperty("保证金Id")
+    private Long id;
+
+    @ApiModelProperty("保证金类型")
+    private String depositType;
+
+    @ApiModelProperty("保证金名称")
+    private String depositName;
+
+    @ApiModelProperty("保证金状态")
+    private Integer status;
+
+    @ApiModelProperty("保证金金额")
+    private BigDecimal amount;
+
+    @ApiModelProperty("用户信息")
+    private UserInfo userInfo;
+
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    @ApiModelProperty("支付时间")
+    private Date payTime;
+
+
+    @ApiModel("用户信息")
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class UserInfo {
+        @ApiModelProperty("用户id")
+        private Long userId;
+        @ApiModelProperty("用户昵称")
+        private String nickname;
+        @ApiModelProperty("用户手机号")
+        private String phone;
+    }
+}

+ 4 - 0
lot/src/main/java/cn/hobbystocks/auc/mapper/DepositOrderMapper.java

@@ -1,6 +1,8 @@
 package cn.hobbystocks.auc.mapper;
 
 import cn.hobbystocks.auc.domain.DepositOrder;
+import cn.hobbystocks.auc.dto.DepositRecordDTO;
+import cn.hobbystocks.auc.request.DepositRecordRequest;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 
 import java.util.List;
@@ -8,4 +10,6 @@ import java.util.List;
 public interface DepositOrderMapper extends BaseMapper<DepositOrder> {
 
     List<DepositOrder> selectDepositList(DepositOrder depositOrder);
+
+    List<DepositRecordDTO> selectDepositRecordPage(DepositRecordRequest request);
 }

+ 25 - 0
lot/src/main/java/cn/hobbystocks/auc/request/DepositRecordRequest.java

@@ -0,0 +1,25 @@
+package cn.hobbystocks.auc.request;
+
+import cn.hobbystocks.auc.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+/**
+ * @author huang_run
+ * @date 2026/5/7 16:37
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("保证金订单Request")
+public class DepositRecordRequest extends BaseEntity {
+    @ApiModelProperty("名称")
+    private String name;
+    @ApiModelProperty("状态")
+    private Integer status;
+    @ApiModelProperty("保证金订单号")
+    private String depositNo;
+}

+ 14 - 0
lot/src/main/java/cn/hobbystocks/auc/request/LotDetailRequest.java

@@ -0,0 +1,14 @@
+package cn.hobbystocks.auc.request;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class LotDetailRequest {
+
+    @NotNull(message = "lotId required")
+    @ApiModelProperty("lot id")
+    private Long lotId;
+}

+ 77 - 0
lot/src/main/java/cn/hobbystocks/auc/response/LotDetailResponse.java

@@ -0,0 +1,77 @@
+package cn.hobbystocks.auc.response;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.JsonNode;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("lot detail response")
+public class LotDetailResponse {
+
+    @ApiModelProperty("拍品ID")
+    private Long lotId;
+    @ApiModelProperty("拍卖会Id")
+    private Long auctionId;
+    @ApiModelProperty("拍卖会名称")
+    private String auctionName;
+
+    @ApiModelProperty("名称")
+    private String name;
+    @ApiModelProperty("主图")
+    private String imgs;
+    @ApiModelProperty("从图")
+    private String carouselImgs;
+    @ApiModelProperty("拍品状态")
+    private String status;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty("开始时间")
+    private Date startTime;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty("结束时间")
+    private Date endTime;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty("真实结束时间")
+    private Date realEndTime;
+    @ApiModelProperty("起拍价")
+    private BigDecimal startPrice;
+    @ApiModelProperty("当前价")
+    private BigDecimal currentPrice;
+    @ApiModelProperty("出价次数")
+    private Long bidCount;
+    @ApiModelProperty("保证金")
+    private Long depositAmount;
+    @ApiModelProperty("保证金类型")
+    private String depositType;
+    @ApiModelProperty("服务费")
+    private BigDecimal serviceTariff;
+    @ApiModelProperty("拍卖方式")
+    private String ruleType;
+    @ApiModelProperty("加价幅度")
+    private BigDecimal markupAmount;
+    @ApiModelProperty("中拍支付时限")
+    private Integer payTimeLimit;
+    @ApiModelProperty("拍品介绍")
+    private String detail;
+    @ApiModelProperty("properties")
+    private JsonNode properties;
+    @ApiModelProperty("是否收藏")
+    private Boolean isFans;
+    @ApiModelProperty("是否缴纳过保证金")
+    private Boolean hasDeposit;
+    @ApiModelProperty("成交用户昵称")
+    private String dealNickname;
+    @ApiModelProperty("倒计时")
+    private Long timestamp;
+
+}

+ 6 - 3
lot/src/main/java/cn/hobbystocks/auc/service/DepositOrderService.java

@@ -1,8 +1,9 @@
 package cn.hobbystocks.auc.service;
 
 import cn.hobbystocks.auc.domain.DepositOrder;
+import cn.hobbystocks.auc.dto.DepositRecordDTO;
 import cn.hobbystocks.auc.dto.DepositOrderDTO;
-import cn.hobbystocks.auc.vo.OrderVO;
+import cn.hobbystocks.auc.request.DepositRecordRequest;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import java.util.List;
@@ -19,14 +20,16 @@ public interface DepositOrderService extends IService<DepositOrder> {
      * @param orderNo 订单号
      * @return 退款结果
      */
-    OrderVO refundDepositOrder(String orderNo);
+    void refundDepositOrder(String orderNo);
 
     /**
      * 扣减保证金
      * @param orderNo 保证金订单编号
      * @return
      */
-    OrderVO reduceDeposit(String orderNo);
+    void reduceDeposit(String orderNo);
 
     List<DepositOrder> selectDepositOrder(DepositOrder depositOrder);
+
+    List<DepositRecordDTO> selectDepositRecordPage(DepositRecordRequest request);
 }

+ 5 - 0
lot/src/main/java/cn/hobbystocks/auc/service/ILotService.java

@@ -8,6 +8,7 @@ import cn.hobbystocks.auc.dto.LotExportDTO;
 import cn.hobbystocks.auc.handle.context.Live;
 import cn.hobbystocks.auc.request.LotQueryRequest;
 import cn.hobbystocks.auc.request.LotRequest;
+import cn.hobbystocks.auc.response.LotDetailResponse;
 import cn.hobbystocks.auc.response.LotFansResponse;
 import cn.hobbystocks.auc.vo.LiveVO;
 import cn.hobbystocks.auc.vo.LotVO;
@@ -62,6 +63,8 @@ public interface ILotService extends IService<Lot> {
 
     List<LotVO> selfWin(SelfVO selfVO);
 
+    List<LotVO> selfList(SelfVO selfVO);
+
     int updateLotEx(Lot lot);
 
     List<Lot> selectBidding();
@@ -126,6 +129,8 @@ public interface ILotService extends IService<Lot> {
      */
     List<LotFansResponse> queryLotByCategory(LotQueryRequest request);
 
+    LotDetailResponse queryLotDetail(Long lotId);
+
     /**
      * 导出拍品列表信息
      * @param request

+ 26 - 10
lot/src/main/java/cn/hobbystocks/auc/service/impl/DepositOrderServiceImpl.java

@@ -3,13 +3,15 @@ package cn.hobbystocks.auc.service.impl;
 import cn.hobbystocks.auc.domain.Auction;
 import cn.hobbystocks.auc.domain.DepositOrder;
 import cn.hobbystocks.auc.domain.Lot;
+import cn.hobbystocks.auc.dto.DepositRecordDTO;
 import cn.hobbystocks.auc.dto.DepositOrderDTO;
 import cn.hobbystocks.auc.forest.OrderApi;
 import cn.hobbystocks.auc.mapper.DepositOrderMapper;
+import cn.hobbystocks.auc.request.DepositRecordRequest;
 import cn.hobbystocks.auc.service.DepositOrderService;
 import cn.hobbystocks.auc.service.IAuctionService;
 import cn.hobbystocks.auc.service.ILotService;
-import cn.hobbystocks.auc.vo.OrderVO;
+import cn.hutool.core.util.IdUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import java.util.Date;
 import java.util.List;
+import java.util.UUID;
 
 @Service
 public class DepositOrderServiceImpl extends ServiceImpl<DepositOrderMapper, DepositOrder> implements DepositOrderService {
@@ -30,6 +33,8 @@ public class DepositOrderServiceImpl extends ServiceImpl<DepositOrderMapper, Dep
     @Resource
     OrderApi orderApi;
 
+    final String DEPOSIT_ORDER_PRE = "DT";
+
     @Override
     @Transactional
     public int createDepositOrder(DepositOrderDTO depositOrderDTO) {
@@ -53,31 +58,42 @@ public class DepositOrderServiceImpl extends ServiceImpl<DepositOrderMapper, Dep
         depositOrderDTO.setDepositType(depositType);
         depositOrderDTO.setLotId(lotId);
         depositOrderDTO.setMerchantId(lot.getMerchantId());
-        //todo 调用创建保证金订单接口
 //        OrderVO orderVO = orderApi.createDepositOrder(depositOrderDTO);
         //保存保证金订单记录
         DepositOrder depositOrder=new DepositOrder();
         BeanUtils.copyProperties(depositOrderDTO,depositOrder);
         depositOrder.setStatus(0);
+        //生成订单号
+        depositOrder.setOrderNo(DEPOSIT_ORDER_PRE + IdUtil.getSnowflakeNextId());
         depositOrder.setCreateTime(new Date());
         return baseMapper.insert(depositOrder);
     }
     @Override
-    public OrderVO refundDepositOrder(String orderNo) {
-        OrderVO orderVO=new OrderVO();
-        orderVO.setOrderNo(orderNo);
-        return orderApi.refundDepositOrder(orderVO);
+    public void refundDepositOrder(String orderNo) {
+//        OrderVO orderVO=new OrderVO();
+//        orderVO.setOrderNo(orderNo);
+//        //TODO 执行保证金退款逻辑
+//        return orderApi.refundDepositOrder(orderVO);
+        this.lambdaUpdate().eq(DepositOrder::getOrderNo,orderNo).set(DepositOrder::getStatus,2);
     }
 
     @Override
-    public OrderVO reduceDeposit(String orderNo) {
-        OrderVO orderVO=new OrderVO();
-        orderVO.setOrderNo(orderNo);
-        return orderApi.reduceDeposit(orderVO);
+    public void reduceDeposit(String orderNo) {
+//        OrderVO orderVO=new OrderVO();
+//        orderVO.setOrderNo(orderNo);
+//        //TODO 执行扣减保证金
+//
+//        return orderApi.reduceDeposit(orderVO);
+        this.lambdaUpdate().eq(DepositOrder::getOrderNo,orderNo).set(DepositOrder::getStatus,3);
     }
 
     @Override
     public List<DepositOrder> selectDepositOrder(DepositOrder depositOrder) {
         return getBaseMapper().selectDepositList(depositOrder);
     }
+
+    @Override
+    public List<DepositRecordDTO> selectDepositRecordPage(DepositRecordRequest request) {
+        return getBaseMapper().selectDepositRecordPage(request);
+    }
 }

+ 201 - 3
lot/src/main/java/cn/hobbystocks/auc/service/impl/LotServiceImpl.java

@@ -2,13 +2,14 @@ package cn.hobbystocks.auc.service.impl;
 
 import cn.hobbystocks.auc.cache.CacheMap;
 import cn.hobbystocks.auc.common.constant.Constants;
-import cn.hobbystocks.auc.common.core.domain.AjaxResult;
 import cn.hobbystocks.auc.common.core.redis.Locker;
 import cn.hobbystocks.auc.common.core.redis.RedisCache;
 import cn.hobbystocks.auc.common.core.text.Convert;
 import cn.hobbystocks.auc.common.enums.LotStatusEnum;
 import cn.hobbystocks.auc.common.enums.PubStatusEnum;
 import cn.hobbystocks.auc.common.enums.RuleTypeEnum;
+import cn.hobbystocks.auc.common.exception.ServiceException;
+import cn.hobbystocks.auc.common.user.UserInfo;
 import cn.hobbystocks.auc.common.user.UserUtils;
 import cn.hobbystocks.auc.common.utils.CloneUtils;
 import cn.hobbystocks.auc.common.utils.DateUtils;
@@ -28,6 +29,7 @@ import cn.hobbystocks.auc.handle.context.tradition.TraditionRule;
 import cn.hobbystocks.auc.mapper.*;
 import cn.hobbystocks.auc.request.LotQueryRequest;
 import cn.hobbystocks.auc.request.LotRequest;
+import cn.hobbystocks.auc.response.LotDetailResponse;
 import cn.hobbystocks.auc.response.LotFansResponse;
 import cn.hobbystocks.auc.service.ILotService;
 import cn.hobbystocks.auc.task.DynamicTaskService;
@@ -35,14 +37,12 @@ import cn.hobbystocks.auc.vo.LiveVO;
 import cn.hobbystocks.auc.vo.LotVO;
 import cn.hobbystocks.auc.vo.SelfVO;
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
-
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -50,6 +50,7 @@ import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -87,6 +88,8 @@ public class LotServiceImpl extends ServiceImpl<LotMapper,Lot> implements ILotSe
     private LotFansMapper lotFansMapper;
     @Autowired
     private SpuCategoryMapper spuCategoryMapper;
+    @Autowired
+    private DepositOrderMapper depositOrderMapper;
 
     @Override
     public Lot selectLotById(Long id) {
@@ -542,6 +545,122 @@ public class LotServiceImpl extends ServiceImpl<LotMapper,Lot> implements ILotSe
         return finishOrWin(selfVO, 1);
     }
 
+    @Override
+    public List<LotVO> selfList(SelfVO selfVO) {
+        UserInfo userInfo = UserUtils.getSimpleUserInfo();
+        if (userInfo == null) {
+            throw new ServiceException("请先登录");
+        }
+        String userId = userInfo.getId().toString();
+        List<Lot> lotList = lotMapper.selectLotByAucId(selfVO.getAuctionId());
+        List<DepositOrder> depositOrders = depositOrderMapper.selectList(new LambdaQueryWrapper<DepositOrder>()
+                .eq(DepositOrder::getUserId, userInfo.getId())
+                .eq(DepositOrder::getAuctionId, selfVO.getAuctionId())
+                .in(DepositOrder::getStatus,  1));
+
+        String type = StringUtils.isEmpty(selfVO.getType()) ? "all" : selfVO.getType();
+        List<LotVO> result = new ArrayList<>();
+        for (Lot lot : lotList) {
+            List<Bid> userBids = bidMapper.selectBidList(Bid.builder()
+                    .lotId(lot.getId())
+                    .accountId(userId)
+                    .build());
+            boolean hasUserBid = !CollectionUtils.isEmpty(userBids);
+            boolean hasWinBid = hasUserBid && userBids.stream().anyMatch(bid -> Objects.equals(bid.getStatus(), 1));
+            boolean hasDeposit = hasDepositQualification(lot, depositOrders);
+
+            if (matchSelfScene(type, lot, hasDeposit, hasUserBid, hasWinBid)) {
+                result.add(buildSelfLotVo(lot, userBids));
+            }
+        }
+        sortSelfLots(type, result);
+        return result;
+    }
+
+    private boolean hasDepositQualification(Lot lot, List<DepositOrder> depositOrders) {
+        if (CollectionUtils.isEmpty(depositOrders)) {
+            return false;
+        }
+        if (Objects.nonNull(lot.getDeposit())) {
+            return depositOrders.stream().anyMatch(order -> Objects.equals(order.getLotId(), lot.getId()));
+        }
+        return depositOrders.stream().anyMatch(order -> Objects.equals(order.getAuctionId(), lot.getAuctionId()));
+    }
+
+    private boolean matchSelfScene(String type, Lot lot, boolean hasDeposit, boolean hasUserBid, boolean hasWinBid) {
+        if ("all".equals(type)) {
+            return isWaitingLot(lot, hasDeposit) || isLiveLot(lot, hasDeposit, hasUserBid) || isLoseLot(lot, hasUserBid, hasWinBid);
+        }
+        if ("waiting".equals(type)) {
+            return isWaitingLot(lot, hasDeposit);
+        }
+        if ("live".equals(type)) {
+            return isLiveLot(lot, hasDeposit, hasUserBid);
+        }
+        if ("lose".equals(type) || "pass".equals(type) || "finish".equals(type)) {
+            return isLoseLot(lot, hasUserBid, hasWinBid);
+        }
+        return false;
+    }
+
+    private boolean isWaitingLot(Lot lot, boolean hasDeposit) {
+        return Constants.LOT_STATUS_WAITING.equals(lot.getStatus()) && hasDeposit;
+    }
+
+    private boolean isLiveLot(Lot lot, boolean hasDeposit, boolean hasUserBid) {
+        return (Constants.LOT_STATUS_STARTING.equals(lot.getStatus()) || Constants.LOT_STATUS_BIDDING.equals(lot.getStatus()))
+                && (hasDeposit || hasUserBid);
+    }
+
+    private boolean isLoseLot(Lot lot, boolean hasUserBid, boolean hasWinBid) {
+        if (!hasUserBid) {
+            return false;
+        }
+        if (Constants.LOT_STATUS_PASS.equals(lot.getStatus())) {
+            return true;
+        }
+        return Constants.LOT_STATUS_SOLD.equals(lot.getStatus()) && !hasWinBid;
+    }
+
+    private LotVO buildSelfLotVo(Lot lot, List<Bid> userBids) {
+        LotVO lotVO = new LotVO();
+        BeanUtils.copyProperties(lot, lotVO);
+        lotVO.setBids(userBids);
+        lotVO.setCurrentPrice(Objects.nonNull(lot.getLastPrice()) ? lot.getLastPrice() : null);
+        return SensitiveDataUtils.handleViewDataSafe(lotVO);
+    }
+
+    private void sortSelfLots(String type, List<LotVO> lots) {
+        if ("waiting".equals(type)) {
+            lots.sort(Comparator.comparing(Lot::getStartTime, Comparator.nullsLast(Date::compareTo)));
+            return;
+        }
+        if ("live".equals(type)) {
+            lots.sort(Comparator.comparing(Lot::getLastPriceTime, Comparator.nullsLast(Date::compareTo)).reversed());
+            return;
+        }
+        if ("lose".equals(type) || "pass".equals(type) || "finish".equals(type)) {
+            lots.sort(Comparator.comparing(Lot::getRealEndTime, Comparator.nullsLast(Date::compareTo)).reversed());
+            return;
+        }
+
+        List<LotVO> waiting = lots.stream().filter(lot -> Constants.LOT_STATUS_WAITING.equals(lot.getStatus()))
+                .sorted(Comparator.comparing(Lot::getStartTime, Comparator.nullsLast(Date::compareTo)))
+                .collect(Collectors.toList());
+        List<LotVO> live = lots.stream()
+                .filter(lot -> Constants.LOT_STATUS_STARTING.equals(lot.getStatus()) || Constants.LOT_STATUS_BIDDING.equals(lot.getStatus()))
+                .sorted(Comparator.comparing(Lot::getLastPriceTime, Comparator.nullsLast(Date::compareTo)).reversed())
+                .collect(Collectors.toList());
+        List<LotVO> lose = lots.stream()
+                .filter(lot -> Constants.LOT_STATUS_PASS.equals(lot.getStatus()) || Constants.LOT_STATUS_SOLD.equals(lot.getStatus()))
+                .sorted(Comparator.comparing(Lot::getRealEndTime, Comparator.nullsLast(Date::compareTo)).reversed())
+                .collect(Collectors.toList());
+        lots.clear();
+        lots.addAll(waiting);
+        lots.addAll(live);
+        lots.addAll(lose);
+    }
+
     private List<LotVO> finishOrWin(SelfVO selfVO, Integer win) {
         String account = UserUtils.getSimpleUserInfo().getId().toString();
         List<LotVO> resultList = new ArrayList<>();
@@ -691,6 +810,85 @@ public class LotServiceImpl extends ServiceImpl<LotMapper,Lot> implements ILotSe
         return lotFansResponses;
     }
 
+    @Override
+    public LotDetailResponse queryLotDetail(Long lotId) {
+        Lot lot = lotMapper.selectLotById(lotId);
+        if (Objects.isNull(lot)) {
+            throw new ServiceException("未找到拍品数据");
+        }
+        Auction auction = auctionMapper.selectAuctionById(lot.getAuctionId());
+        if (Objects.isNull(auction)) {
+            throw new ServiceException("未找到拍卖会相关数据");
+        }
+        TraditionRule rule = StringUtils.isEmpty(lot.getRuleContent())
+                ? null
+                : JSON.parseObject(lot.getRuleContent(), TraditionRule.class);
+        BigDecimal startPrice = Objects.isNull(rule) ? null : rule.getStartPrice();
+        BigDecimal markupAmount = Objects.isNull(rule) ? null : rule.getDefaultOnceAddPrice();
+        Long depositAmount = lot.getDeposit();
+        String depositType = "LOT";
+        if (Objects.isNull(depositAmount)) {
+            depositAmount = auction.getDeposit();
+            depositType = "AUCTION";
+        }
+        LotDetailResponse response = new LotDetailResponse();
+        response.setLotId(lot.getId());
+        response.setAuctionId(lot.getAuctionId());
+        response.setName(lot.getName());
+        response.setAuctionName(auction.getName());
+        response.setImgs(lot.getImgs());
+        response.setCarouselImgs(lot.getCarouselImgs());
+        response.setStatus(lot.getStatus());
+        response.setStartTime(lot.getStartTime());
+        response.setEndTime(lot.getEndTime());
+        response.setRealEndTime(lot.getRealEndTime());
+        response.setStartPrice(startPrice);
+        response.setCurrentPrice(Objects.nonNull(lot.getLastPrice()) ? lot.getLastPrice() : startPrice);
+        response.setBidCount(lot.getBidCount());
+        response.setDepositAmount(depositAmount);
+        response.setDepositType(depositType);
+        response.setServiceTariff(lot.getServiceTariff());
+        response.setRuleType(lot.getRuleType());
+        response.setMarkupAmount(markupAmount);
+        response.setDetail(lot.getDetail());
+        response.setProperties(lot.getProperties());
+        response.setIsFans(Boolean.FALSE);
+        response.setHasDeposit(Boolean.FALSE);
+        response.setPayTimeLimit(lot.getPayTimeLimit());
+        if (Objects.equals("Waiting", lot.getStatus())) {
+            response.setTimestamp(lot.getStartTime().getTime() - System.currentTimeMillis());
+        } else if (Objects.equals("Bidding", lot.getStatus())) {
+            response.setTimestamp(lot.getEndTime().getTime() - System.currentTimeMillis());
+        }
+        //TODO 成交用户暂时无
+        fillUserFlags(lot, response, depositType);
+        return response;
+    }
+
+    private void fillUserFlags(Lot lot, LotDetailResponse response, String depositType) {
+        UserInfo userInfo = UserUtils.getSimpleUserInfo();
+        if (Objects.isNull(userInfo)) {
+            return;
+        }
+
+        Long favoriteCount = lotFansMapper.selectCount(new LambdaQueryWrapper<LotFans>()
+                .eq(LotFans::getLotId, lot.getId())
+                .eq(LotFans::getUserId, userInfo.getId().longValue())
+                .eq(LotFans::getType, "user_like"));
+        response.setIsFans(favoriteCount > 0);
+
+        LambdaQueryWrapper<DepositOrder> depositQuery = new LambdaQueryWrapper<DepositOrder>()
+                .eq(DepositOrder::getUserId, userInfo.getId())
+                .in(DepositOrder::getStatus,  1);
+        if (Objects.equals("LOT", depositType)) {
+            depositQuery.eq(DepositOrder::getLotId, lot.getId());
+        } else {
+            depositQuery.eq(DepositOrder::getAuctionId, lot.getAuctionId());
+        }
+        Long depositCount = depositOrderMapper.selectCount(depositQuery);
+        response.setHasDeposit(depositCount > 0);
+    }
+
     @Override
     public List<LotExportDTO> exportLotList(LotRequest request) {
 

+ 45 - 1
lot/src/main/resources/mapper/DepositOrderMapper.xml

@@ -7,13 +7,57 @@
     <sql id="selectDeposit">
         select id,user_id,lot_id,status,amount,order_no,auction_id,name,deposit_type from deposit_order_record
     </sql>
+
+    <resultMap id="DepositRecordResult" type="cn.hobbystocks.auc.dto.DepositRecordDTO">
+        <id property="id" column="id"/>
+        <result property="depositType" column="deposit_type"/>
+        <result property="depositName" column="name"/>
+        <result property="status" column="status"/>
+        <result property="amount" column="amount"/>
+        <result property="createTime" column="create_time"/>
+        <result property="payTime" column="pay_time"/>
+        <association property="userInfo" javaType="cn.hobbystocks.auc.dto.DepositRecordDTO$UserInfo">
+            <result property="userId" column="user_id"/>
+            <result property="nickname" column="nickname"/>
+            <result property="phone" column="phone"/>
+        </association>
+    </resultMap>
+
     <select id="selectDepositList" resultType="cn.hobbystocks.auc.domain.DepositOrder">
         <include refid="selectDeposit"></include>
         <where>
             <if test="userId!=null">and user_id=#{userId}</if>
             <if test="lotId!=null">and lot_id=#{lotId}</if>
             <if test="auctionId!=null"> and auction_id=#{auctionId}</if>
-            <if test="status!=null">status=#{status}</if>
+            <if test="status!=null">and status=#{status}</if>
+        </where>
+    </select>
+
+    <select id="selectDepositRecordPage" resultMap="DepositRecordResult">
+        select dor.id,
+               dor.deposit_type,
+               dor.name,
+               dor.status,
+               dor.amount,
+               dor.create_time,
+               dor.pay_time,
+               abu.nickname,
+               a.phone,
+               dor.user_id
+        from deposit_order_record dor
+                 inner join app_base_user abu on abu.id = dor.user_id
+                 inner join app_account a on abu.username = a.account
+        <where>
+            <if test="name != null and name != ''">
+                and dor.name like concat('%', #{name}, '%')
+            </if>
+            <if test="status != null">
+                and dor.status = #{status}
+            </if>
+            <if test="depositNo!=null">
+                and dor.order_no like concat('%', #{depositNo}, '%')
+            </if>
         </where>
+        order by dor.create_time desc
     </select>
 </mapper>