From 83b56237a9e0b379b46d31ab77def13226f33548 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Mon, 27 Nov 2023 14:15:16 +0800
Subject: [PATCH] 匹配

---
 src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java         |    4 
 src/main/resources/templates/febs/views/modules/news/productBuyListNew.html |  299 ++++++++++++++++++
 src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java             |   12 
 src/main/resources/templates/febs/views/modules/news/buyRecordImg.html      |   82 +++++
 src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java         |    9 
 src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java          |    3 
 src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java         |    2 
 src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java             |    3 
 src/main/resources/mapper/modules/MallProductNftMapper.xml                  |   22 +
 src/main/java/cc/mrbird/febs/mall/dto/AdminPickSellRecordDtoDto.java        |    7 
 src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java          |   17 +
 src/main/java/cc/mrbird/febs/mall/dto/AdminBuyRecordPayDto.java             |   16 +
 src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java |  149 ++++++++
 src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java        |   50 +-
 src/main/resources/templates/febs/views/modules/news/buyRecordPay.html      |  122 +++++++
 src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java |   25 +
 src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java   |   36 ++
 src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java           |    2 
 src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java            |    6 
 src/main/resources/templates/febs/views/modules/news/productSellPick.html   |    2 
 src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java        |   37 ++
 src/main/resources/templates/febs/views/modules/news/productBuyList.html    |    8 
 22 files changed, 877 insertions(+), 36 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java b/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
index cb52579..062b8d8 100644
--- a/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
+++ b/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
@@ -230,4 +230,21 @@
     }
     //卖单用户确认 end
 
+    //买单取消 start
+    @Bean
+    public DirectExchange fcmOrderBuyCancelExchange() {
+        return new DirectExchange(RabbitQueueEnum.FCMPAY_FCM_ORDER_BUY_CANCEL.getExchange());
+    }
+
+    @Bean
+    public Queue fcmOrderBuyCancelQueue() {
+        return new Queue(RabbitQueueEnum.FCMPAY_FCM_ORDER_BUY_CANCEL.getQueue());
+    }
+
+    @Bean
+    public Binding fcmOrderBuyCancelBind() {
+        return BindingBuilder.bind(fcmOrderBuyCancelQueue()).to(fcmOrderBuyCancelExchange()).with(RabbitQueueEnum.FCMPAY_FCM_ORDER_BUY_CANCEL.getRoute());
+    }
+    //买单取消 end
+
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java b/src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java
index 3cfe34a..0cab0c6 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java
@@ -101,6 +101,15 @@
     }
 
     /**
+     * 用户NFT预约子记录列表
+     */
+    @GetMapping("getBuyRecordList")
+    public FebsResponse getBuyRecordList(MallProductBuy mallProductBuy, QueryRequest request) {
+        Map<String, Object> data = getDataTable(mallNewsInfoService.getBuyRecordList(mallProductBuy, request));
+        return new FebsResponse().success().data(data);
+    }
+
+    /**
      * 用户NFT提现列表
      */
     @GetMapping("getSellList")
@@ -129,6 +138,33 @@
     }
 
     /**
+     * 用户NFT提现-取消
+     */
+    @GetMapping("buyRecordCancel/{id}")
+    @ControllerEndpoint(operation = " 用户NFT提现-取消", exceptionMessage = "操作失败")
+    public FebsResponse buyRecordCancel(@NotNull(message = "{required}") @PathVariable Long id) {
+        return mallNewsInfoService.buyRecordCancel(id);
+    }
+
+    /**
+     * 用户NFT提现-确认支付
+     */
+    @PostMapping("buyRecordPay")
+    @ControllerEndpoint(operation = "用户NFT提现-确认支付", exceptionMessage = "操作失败")
+    public FebsResponse buyRecordPay(@Valid AdminBuyRecordPayDto buyRecordPayDto) {
+        return mallNewsInfoService.buyRecordPay(buyRecordPayDto);
+    }
+
+    /**
+     * 用户NFT提现-确认收款
+     */
+    @GetMapping("buyRecordConfirm/{id}")
+    @ControllerEndpoint(operation = " 用户NFT提现-确认收款", exceptionMessage = "操作失败")
+    public FebsResponse buyRecordConfirm(@NotNull(message = "{required}") @PathVariable Long id) {
+        return mallNewsInfoService.buyRecordConfirm(id);
+    }
+
+    /**
      * 基础设置
      * @param gfaBasicSetDto
      * @return
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java b/src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java
index e5c2e32..4669428 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java
@@ -8,6 +8,7 @@
 import cc.mrbird.febs.mall.entity.*;
 import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
 import cc.mrbird.febs.mall.mapper.MallProductBuyMapper;
+import cc.mrbird.febs.mall.mapper.MallProductBuyRecordMapper;
 import cc.mrbird.febs.mall.mapper.MallProductNftMapper;
 import cc.mrbird.febs.mall.service.IMallNewsInfoService;
 import cn.hutool.core.util.ObjectUtil;
@@ -31,6 +32,7 @@
     private final IMallNewsInfoService mallNewsInfoService;
     private final MallProductNftMapper mallProductNftMapper;
     private final MallProductBuyMapper mallProductBuyMapper;
+    private final MallProductBuyRecordMapper mallProductBuyRecordMapper;
     private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
 
     /**
@@ -73,6 +75,15 @@
     }
 
     /**
+     * 用户NFT预约列表
+     */
+    @GetMapping("productBuyListNew")
+    @RequiresPermissions("productBuyListNew:view")
+    public String productBuyListNew() {
+        return FebsUtil.view("modules/news/productBuyListNew");
+    }
+
+    /**
      * 用户NFT提现列表
      */
     @GetMapping("productSellList")
@@ -93,6 +104,32 @@
         return FebsUtil.view("modules/news/productSellPick");
     }
 
+
+    /**
+     * 用户预约打款记录--确认支付
+     * @return
+     */
+    @GetMapping("buyRecordPay/{id}")
+    @RequiresPermissions("buyRecordPay:update")
+    public String buyRecordPay(@PathVariable long id, Model model) {
+        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(id);
+        model.addAttribute("mallProductBuyRecord", mallProductBuyRecord);
+        return FebsUtil.view("modules/news/buyRecordPay");
+    }
+
+
+    /**
+     * 用户预约打款记录--凭证
+     * @return
+     */
+    @GetMapping("buyRecordImg/{id}")
+    @RequiresPermissions("buyRecordImg:update")
+    public String buyRecordImg(@PathVariable long id, Model model) {
+        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(id);
+        model.addAttribute("mallProductBuyRecord", mallProductBuyRecord);
+        return FebsUtil.view("modules/news/buyRecordImg");
+    }
+
     /**
      * 基础设置
      * @param model
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/AdminBuyRecordPayDto.java b/src/main/java/cc/mrbird/febs/mall/dto/AdminBuyRecordPayDto.java
new file mode 100644
index 0000000..ceaa726
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/AdminBuyRecordPayDto.java
@@ -0,0 +1,16 @@
+package cc.mrbird.febs.mall.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+public class AdminBuyRecordPayDto {
+    @NotNull(message = "类型参数不能为空")
+    private Long id;//ApiOrderSellRecordInfoVo中的ID,预约单子表ID
+    @NotBlank(message = "类型参数不能为空")
+    private String nftImg;//支付凭证
+    @NotNull(message = "类型参数不能为空")
+    private Integer type;//支付类型 1:微信 2:支付宝 3:银行转账 4:USDT转账
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/AdminPickSellRecordDtoDto.java b/src/main/java/cc/mrbird/febs/mall/dto/AdminPickSellRecordDtoDto.java
index f9e7c6c..ec7761f 100644
--- a/src/main/java/cc/mrbird/febs/mall/dto/AdminPickSellRecordDtoDto.java
+++ b/src/main/java/cc/mrbird/febs/mall/dto/AdminPickSellRecordDtoDto.java
@@ -2,10 +2,15 @@
 
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
 @Data
 public class AdminPickSellRecordDtoDto {
-
+    @NotNull(message = "参数不能为空")
     private Long productSellId;
+    @NotNull(message = "参数不能为空")
     private Long id;
+    @NotBlank(message = "参数不能为空")
     private String pickNftCnt;
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java
index a93dd4b..20921aa 100644
--- a/src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java
@@ -2,6 +2,7 @@
 
 import cc.mrbird.febs.common.enumerates.ProductEnum;
 import cc.mrbird.febs.mall.entity.MallProductBuy;
+import cc.mrbird.febs.mall.entity.MallProductBuyRecord;
 import cc.mrbird.febs.mall.entity.MallProductNft;
 import cc.mrbird.febs.mall.entity.MallProductSell;
 import cc.mrbird.febs.mall.vo.*;
@@ -25,4 +26,6 @@
     List<AdminMallProductSellPickVo> selectProductSellByState(@Param("state")int value);
 
     List<MallProductNft> selectListByState(@Param("state")ProductEnum productNftOpen);
+
+    IPage<MallProductBuyRecord> getBuyRecordList(Page<MallProductBuyRecord> page, @Param("record")MallProductBuy mallProductBuy);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java b/src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java
index 695f658..236939b 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java
@@ -2,6 +2,7 @@
 
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.common.entity.QueryRequest;
+import cc.mrbird.febs.mall.dto.AdminBuyRecordPayDto;
 import cc.mrbird.febs.mall.dto.AdminMallProductNftDto;
 import cc.mrbird.febs.mall.dto.AdminPickSellRecordDtoDto;
 import cc.mrbird.febs.mall.dto.MallNewsInfoDto;
@@ -44,9 +45,17 @@
 
     IPage<AdminMallProductBuyVo> getBuyList(MallProductBuy mallProductBuy, QueryRequest request);
 
+    IPage<MallProductBuyRecord> getBuyRecordList(MallProductBuy mallProductBuy, QueryRequest request);
+
     IPage<AdminMallProductSellVo> getSellList(MallProductSell mallProductSell, QueryRequest request);
 
     List<AdminMallProductSellPickVo> findSellList();
 
     FebsResponse pickSellRecord(AdminPickSellRecordDtoDto pickSellRecordDto);
+
+    FebsResponse buyRecordPay(AdminBuyRecordPayDto buyRecordPayDto);
+
+    FebsResponse buyRecordConfirm(Long id);
+
+    FebsResponse buyRecordCancel(Long id);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java b/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
index 442d128..cd2ca46 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
@@ -59,4 +59,6 @@
     void fcmNFTExchangeMsg(String cnt);
 
     void fcmOrderSellInsureMsg(Long sellRecordId);
+
+    void fcmOrderBuyCancelMsg(Long buyRecordId);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java
index 8c177c2..69dc437 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java
@@ -8,6 +8,7 @@
 import cc.mrbird.febs.mall.service.*;
 import cc.mrbird.febs.mall.vo.AdminMallMoneyFlowVo;
 import cc.mrbird.febs.mall.vo.AdminTeamEqualsPerkVo;
+import cc.mrbird.febs.rabbit.producter.AgentProducer;
 import cc.mrbird.febs.system.mapper.UserMapper;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
@@ -62,6 +63,7 @@
     private final MallProductSellMapper mallProductSellMapper;
     private final MallProductSellRecordMapper mallProductSellRecordMapper;
     private final MallProductNftMapper mallProductNftMapper;
+    private final AgentProducer agentProducer;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -888,29 +890,31 @@
                      * 3、更新买单子表的数据
                      * 3、更新卖单子表的数据
                      */
-                    Long buyId = mallProductBuyRecord.getBuyId();
-                    Long sellRecordId = mallProductBuyRecord.getSellRecordId();
-                    MallProductBuy mallProductBuy = mallProductBuyMapper.selectById(buyId);
-                    Long memberIdBuy = mallProductBuy.getMemberId();
-                    //冻结账户
-                    MallMember mallMemberBuy = memberMapper.selectById(memberIdBuy);
-                    mallMemberBuy.setIsFrozen(ProductEnum.MEMBER_FROZEN.getValue());
-                    memberMapper.updateById(mallMemberBuy);
-                    //更新买单子表的数据
-                    mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
-                    mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
-                    //更新买单主表
-                    mallProductBuy.setNftAva(mallProductBuy.getNftAva().add(mallProductBuyRecord.getPickNftCnt()));
-                    mallProductBuyMapper.updateById(mallProductBuy);
-                    //更新卖单子表的数据
-                    MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(sellRecordId);
-                    mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
-                    mallProductSellRecordMapper.updateById(mallProductSellRecord);
-                    //更新卖单主表
-                    Long sellId = mallProductSellRecord.getSellId();
-                    MallProductSell mallProductSell = mallProductSellMapper.selectById(sellId);
-                    mallProductSell.setNftCntAva(mallProductSell.getNftCntAva().add(mallProductSellRecord.getNftCnt()));
-                    mallProductSellMapper.updateById(mallProductSell);
+                    agentProducer.sendFcmOrderBuyCancelMsg(mallProductBuyRecord.getId());
+
+//                    Long buyId = mallProductBuyRecord.getBuyId();
+//                    Long sellRecordId = mallProductBuyRecord.getSellRecordId();
+//                    MallProductBuy mallProductBuy = mallProductBuyMapper.selectById(buyId);
+//                    Long memberIdBuy = mallProductBuy.getMemberId();
+//                    //冻结账户
+//                    MallMember mallMemberBuy = memberMapper.selectById(memberIdBuy);
+//                    mallMemberBuy.setIsFrozen(ProductEnum.MEMBER_FROZEN.getValue());
+//                    memberMapper.updateById(mallMemberBuy);
+//                    //更新买单子表的数据
+//                    mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
+//                    mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
+//                    //更新买单主表
+//                    mallProductBuy.setNftAva(mallProductBuy.getNftAva().add(mallProductBuyRecord.getPickNftCnt()));
+//                    mallProductBuyMapper.updateById(mallProductBuy);
+//                    //更新卖单子表的数据
+//                    MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(sellRecordId);
+//                    mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
+//                    mallProductSellRecordMapper.updateById(mallProductSellRecord);
+//                    //更新卖单主表
+//                    Long sellId = mallProductSellRecord.getSellId();
+//                    MallProductSell mallProductSell = mallProductSellMapper.selectById(sellId);
+//                    mallProductSell.setNftCntAva(mallProductSell.getNftCntAva().add(mallProductSellRecord.getNftCnt()));
+//                    mallProductSellMapper.updateById(mallProductSell);
                 }
             }
         }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java
index f32080a..32b8fdb 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java
@@ -2,21 +2,30 @@
 
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.common.entity.QueryRequest;
+import cc.mrbird.febs.common.enumerates.FlowTypeNewEnum;
+import cc.mrbird.febs.common.enumerates.MoneyFlowTypeNewEnum;
 import cc.mrbird.febs.common.enumerates.ProductEnum;
+import cc.mrbird.febs.common.exception.FebsException;
+import cc.mrbird.febs.common.utils.LoginUserUtil;
+import cc.mrbird.febs.common.utils.MallUtils;
 import cc.mrbird.febs.mall.conversion.MallProductNftConversion;
+import cc.mrbird.febs.mall.dto.AdminBuyRecordPayDto;
 import cc.mrbird.febs.mall.dto.AdminMallProductNftDto;
 import cc.mrbird.febs.mall.dto.AdminPickSellRecordDtoDto;
 import cc.mrbird.febs.mall.dto.MallNewsInfoDto;
 import cc.mrbird.febs.mall.entity.*;
 import cc.mrbird.febs.mall.mapper.*;
+import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
 import cc.mrbird.febs.mall.service.IMallNewsInfoService;
 import cc.mrbird.febs.mall.vo.*;
+import cc.mrbird.febs.rabbit.producter.AgentProducer;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -42,6 +51,8 @@
     private final MallProductSellMapper mallProductSellMapper;
     private final MallProductSellRecordMapper mallProductSellRecordMapper;
     private final MallProductBuyRecordMapper mallProductBuyRecordMapper;
+    private final IMallMoneyFlowService mallMoneyFlowService;
+    private final AgentProducer agentProducer;
 
     @Override
     public IPage<AdminMallNewsInfoVo> getNewInfoList(MallNewsInfo mallNewsInfo, QueryRequest request) {
@@ -195,14 +206,18 @@
     public IPage<AdminMallProductBuyVo> getBuyList(MallProductBuy mallProductBuy, QueryRequest request) {
         Page<AdminMallProductBuyVo> page = new Page<>(request.getPageNum(), request.getPageSize());
         IPage<AdminMallProductBuyVo> adminMallProductBuyVoIPage = mallProductNftMapper.getBuyList(page, mallProductBuy);
-        if(CollUtil.isNotEmpty(adminMallProductBuyVoIPage.getRecords())){
-            List<AdminMallProductBuyVo> records = adminMallProductBuyVoIPage.getRecords();
-            for(AdminMallProductBuyVo adminMallProductBuyVo : records){
-                List<MallProductBuyRecord> mallProductBuyRecords = mallProductBuyRecordMapper.selectRecordListByBuyId(adminMallProductBuyVo.getId());
-                adminMallProductBuyVo.setMallProductBuyRecords(mallProductBuyRecords);
-            }
-        }
         return adminMallProductBuyVoIPage;
+    }
+
+    @Override
+    public IPage<MallProductBuyRecord> getBuyRecordList(MallProductBuy mallProductBuy, QueryRequest request) {
+        if(ObjectUtil.isNotEmpty(mallProductBuy.getAccountLogin())){
+            String accountLogin = mallProductBuy.getAccountLogin();
+
+        }
+        Page<MallProductBuyRecord> page = new Page<>(request.getPageNum(), request.getPageSize());
+        IPage<MallProductBuyRecord> mallProductBuyRecordIPage = mallProductNftMapper.getBuyRecordList(page, mallProductBuy);
+        return mallProductBuyRecordIPage;
     }
 
     @Override
@@ -281,4 +296,124 @@
         mallProductBuyMapper.updateById(mallProductBuy);
         return new FebsResponse().success();
     }
+
+    @Override
+    public FebsResponse buyRecordPay(AdminBuyRecordPayDto buyRecordPayDto) {
+        Long buyRecordId = buyRecordPayDto.getId();
+        String nftImg = buyRecordPayDto.getNftImg();
+        Integer type = buyRecordPayDto.getType();
+        /**
+         * 验证订单是否存在
+         * 更新买单状态
+         * 更新卖单状态
+         * 生成流水信息
+         */
+        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(buyRecordId);
+        if(ObjectUtil.isEmpty(mallProductBuyRecord)){
+            throw new FebsException("记录不存在");
+        }
+        Integer state = mallProductBuyRecord.getState();
+        if(ProductEnum.PRODUCT_MATE_STATE_WAIT_PAY.getValue() != state){
+            throw new FebsException("记录不是待支付状态");
+        }
+
+        MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(mallProductBuyRecord.getSellRecordId());
+        if(ObjectUtil.isEmpty(mallProductSellRecord)){
+            throw new FebsException("记录不存在");
+        }
+        Integer stateSell = mallProductSellRecord.getState();
+        if(ProductEnum.PRODUCT_MATE_STATE_WAIT_PAY.getValue() != stateSell){
+            throw new FebsException("记录不是待支付状态");
+        }
+
+        DateTime payTime = DateUtil.date();
+        mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue());
+        mallProductBuyRecord.setPayTime(payTime);
+        mallProductBuyRecord.setNftImg(nftImg);
+        mallProductBuyRecord.setType(type);
+        mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
+
+        mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue());
+        mallProductSellRecord.setPayTime(payTime);
+        mallProductSellRecord.setNftImg(nftImg);
+        mallProductSellRecord.setType(type);
+        mallProductSellRecordMapper.updateById(mallProductSellRecord);
+
+        String orderNo = MallUtils.getOrderNum("ZF");
+        mallMoneyFlowService.addMoneyFlow(
+                mallProductSellRecord.getMemberId(),
+                mallProductBuyRecord.getPickNftCnt(),
+                MoneyFlowTypeNewEnum.PAY.getValue(),
+                orderNo,
+                mallProductSellRecord.getMemberId(),
+                FlowTypeNewEnum.NFT.getValue(),
+                MoneyFlowTypeNewEnum.PAY.getDescrition());
+        return new FebsResponse().success();
+    }
+
+    @Override
+    public FebsResponse buyRecordConfirm(Long id) {
+        /**
+         * 验证订单是否存在
+         * 更新买单状态
+         * 更新卖单状态
+         * 生成流水信息
+         */
+        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(id);
+        if(ObjectUtil.isEmpty(mallProductBuyRecord)){
+            throw new FebsException("记录不存在");
+        }
+        Integer state = mallProductBuyRecord.getState();
+        if(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue() != state){
+            throw new FebsException("记录不是已支付状态");
+        }
+        Long sellRecordId = mallProductBuyRecord.getSellRecordId();
+        MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(mallProductBuyRecord.getSellRecordId());
+        if(ObjectUtil.isEmpty(mallProductSellRecord)){
+            throw new FebsException("记录不存在");
+        }
+        Integer stateSell = mallProductSellRecord.getState();
+        if(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue() != stateSell){
+            throw new FebsException("记录不是已支付状态");
+        }
+
+        mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_CONFIRM.getValue());
+        mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
+
+        mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_CONFIRM.getValue());
+        mallProductSellRecordMapper.updateById(mallProductSellRecord);
+
+        agentProducer.sendFcmOrderSellInsureMsg(sellRecordId);
+        return new FebsResponse().success();
+    }
+
+    @Override
+    public FebsResponse buyRecordCancel(Long id) {
+        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(id);
+        if(ObjectUtil.isEmpty(mallProductBuyRecord)){
+            throw new FebsException("记录不存在");
+        }
+        Integer state = mallProductBuyRecord.getState();
+        if(ProductEnum.PRODUCT_MATE_STATE_WAIT_PAY.getValue() != state){
+            throw new FebsException("记录不是待支付状态");
+        }
+        Long sellRecordId = mallProductBuyRecord.getSellRecordId();
+        //更新买单子表的数据
+        mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
+        mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
+        //更新买单主表
+        MallProductBuy mallProductBuy = mallProductBuyMapper.selectById(mallProductBuyRecord.getBuyId());
+        mallProductBuy.setNftAva(mallProductBuy.getNftAva().add(mallProductBuyRecord.getPickNftCnt()));
+        mallProductBuyMapper.updateById(mallProductBuy);
+        //更新卖单子表的数据
+        MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(sellRecordId);
+        mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
+        mallProductSellRecordMapper.updateById(mallProductSellRecord);
+        //更新卖单主表
+        Long sellId = mallProductSellRecord.getSellId();
+        MallProductSell mallProductSell = mallProductSellMapper.selectById(sellId);
+        mallProductSell.setNftCntAva(mallProductSell.getNftCntAva().add(mallProductSellRecord.getNftCnt()));
+        mallProductSellMapper.updateById(mallProductSell);
+        return new FebsResponse().success();
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
index 2c83e72..4578086 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
@@ -1228,6 +1228,31 @@
         mallProductBuyMapper.updateById(mallProductBuy);
     }
 
+    @Override
+    public void fcmOrderBuyCancelMsg(Long buyRecordId) {
+        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(buyRecordId);
+        if(ProductEnum.PRODUCT_MATE_STATE_WAIT_PAY.getValue() != mallProductBuyRecord.getState()){
+            return;
+        }
+        Long sellRecordId = mallProductBuyRecord.getSellRecordId();
+        //更新买单子表的数据
+        mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
+        mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
+        //更新买单主表
+        MallProductBuy mallProductBuy = mallProductBuyMapper.selectById(mallProductBuyRecord.getBuyId());
+        mallProductBuy.setNftAva(mallProductBuy.getNftAva().add(mallProductBuyRecord.getPickNftCnt()));
+        mallProductBuyMapper.updateById(mallProductBuy);
+        //更新卖单子表的数据
+        MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(sellRecordId);
+        mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FAIL.getValue());
+        mallProductSellRecordMapper.updateById(mallProductSellRecord);
+        //更新卖单主表
+        Long sellId = mallProductSellRecord.getSellId();
+        MallProductSell mallProductSell = mallProductSellMapper.selectById(sellId);
+        mallProductSell.setNftCntAva(mallProductSell.getNftCntAva().add(mallProductSellRecord.getNftCnt()));
+        mallProductSellMapper.updateById(mallProductSell);
+    }
+
     public static void main(String[] args) {
         BigDecimal divide = new BigDecimal(12000).divide(new BigDecimal(10000), 0, BigDecimal.ROUND_DOWN);
         System.out.println(divide);
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java
index e92ef66..75fb7c4 100644
--- a/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java
+++ b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java
@@ -14,6 +14,7 @@
 
     private Long id;
     private String accountLogin;//登录账户
+    private String orderNo;//编号
     private Long memberId;//
     private Long sellId;//出售ID
     private Long productNftId;//预约NFT编码
@@ -23,6 +24,4 @@
     private BigDecimal nftAva;//nft分配额度
     private Date orderTime;//匹配时间
     private Date payTime;//支付时间
-
-    private List<MallProductBuyRecord> mallProductBuyRecords;
 }
diff --git a/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java b/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
index e02e6eb..d5d4991 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
@@ -27,4 +27,6 @@
     public static final String QUEUE_FCM_NFT_EXCHANGE = "queue_fcm_nft_exchange";
     //卖单用户确认
     public static final String QUEUE_FCM_ORDER_SELL_INSURE = "queue_fcm_order_sell_insure";
+    //买单取消
+    public static final String QUEUE_FCM_ORDER_BUY_CANCEL = "queue_fcm_order_buy_cancel";
 }
diff --git a/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java b/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
index 4b76be9..5597736 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
@@ -120,4 +120,16 @@
 
         }
     }
+
+    @RabbitListener(queues = QueueConstants.QUEUE_FCM_ORDER_BUY_CANCEL)
+    public void fcmOrderBuyCancelMsg(Long buyRecordId) {
+        log.info("收到买单取消确认:{}",buyRecordId);
+        try {
+            memberProfitService.fcmOrderBuyCancelMsg(buyRecordId);
+        } catch (Exception e) {
+            log.error("收到买单取消确认异常", e);
+            // todo 更新表
+
+        }
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java b/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
index 06b776f..455a39d 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
@@ -5,6 +5,10 @@
 
 @Getter
 public enum RabbitQueueEnum {
+    //买单取消
+    FCMPAY_FCM_ORDER_BUY_CANCEL("exchange_fcm_order_buy_cancel",
+            "route_key_fcm_order_buy_cancel",
+            QueueConstants.QUEUE_FCM_ORDER_BUY_CANCEL),
     //卖单用户确认
     FCMPAY_FCM_ORDER_SELL_INSURE("exchange_fcm_order_sell_insure",
             "route_key_fcm_order_sell_insure",
diff --git a/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java b/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
index af3930d..a9b4df7 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
@@ -94,6 +94,12 @@
                 RabbitQueueEnum.FCMPAY_FCM_ORDER_SELL_INSURE.getRoute(),sellRecordId);
     }
 
+    public void sendFcmOrderBuyCancelMsg(Long buyRecordId) {
+        log.info("发送买单取消:{}",buyRecordId);
+        rabbitTemplate.convertAndSend(RabbitQueueEnum.FCMPAY_FCM_ORDER_BUY_CANCEL.getExchange(),
+                RabbitQueueEnum.FCMPAY_FCM_ORDER_BUY_CANCEL.getRoute(),buyRecordId);
+    }
+
     /**
      * 发送代理自动升级消息
      *
diff --git a/src/main/resources/mapper/modules/MallProductNftMapper.xml b/src/main/resources/mapper/modules/MallProductNftMapper.xml
index 3895cb2..3cfd8fd 100644
--- a/src/main/resources/mapper/modules/MallProductNftMapper.xml
+++ b/src/main/resources/mapper/modules/MallProductNftMapper.xml
@@ -32,6 +32,28 @@
         order by a.CREATED_TIME desc
     </select>
 
+    <select id="getBuyRecordList" resultType="cc.mrbird.febs.mall.entity.MallProductBuyRecord">
+        SELECT
+        a.*,
+        b.account_login
+        FROM mall_product_buy_record a
+        left join mall_member b on a.member_id = b.id
+        <where>
+            <if test="record != null" >
+                <if test="record.accountLogin!=null and record.accountLogin!=''">
+                    and a.buy_id in  (
+                    SELECT
+                    c.id
+                    FROM mall_product_buy c
+                    left join mall_member d on c.member_id = d.id
+                        where d.account_login like concat('%',  #{record.accountLogin},'%')
+                    )
+                </if>
+            </if>
+        </where>
+        order by a.CREATED_TIME desc
+    </select>
+
     <select id="getSellList" resultType="cc.mrbird.febs.mall.vo.AdminMallProductSellVo">
         SELECT
             a.*,
diff --git a/src/main/resources/templates/febs/views/modules/news/buyRecordImg.html b/src/main/resources/templates/febs/views/modules/news/buyRecordImg.html
new file mode 100644
index 0000000..266871e
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/buyRecordImg.html
@@ -0,0 +1,82 @@
+<style>
+    #buyRecordImg-update {
+        padding: 20px 25px 25px 0;
+    }
+
+    #buyRecordImg-update .layui-treeSelect .ztree li a, .ztree li span {
+        margin: 0 0 2px 3px !important;
+    }
+    #buyRecordImg-update #data-permission-tree-block {
+        border: 1px solid #eee;
+        border-radius: 2px;
+        padding: 3px 0;
+    }
+    #buyRecordImg-update .layui-treeSelect .ztree li span.button.switch {
+        top: 1px;
+        left: 3px;
+    }
+    #buyRecordImg-update img{
+        max-width:100px
+    }
+
+</style>
+<div class="layui-fluid" id="buyRecordImg-update">
+    <form class="layui-form" action="" lay-filter="buyRecordImg-update-form">
+        <div class="layui-form-item febs-hide">
+            <label class="layui-form-label febs-form-item-require">id:</label>
+            <div class="layui-input-block">
+                <input type="text" name="id">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label febs-form-item-require">凭证:</label>
+            <div class="layui-input-block">
+                <div class="layui-upload">
+                    <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 20px;">
+                        <div class="layui-upload-list" id="nftImgImagePay"></div>
+                    </blockquote>
+                    <div class="febs-hide">
+                        <input type="text" id="nftImg"  name="nftImg" autocomplete="off" class="layui-input" readonly>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </form>
+</div>
+
+<script data-th-inline="javascript">
+    layui.use(['febs', 'form', 'formSelects', 'validate', 'upload'], function () {
+        var $ = layui.$,
+            febs = layui.febs,
+            layer = layui.layer,
+            upload = layui.upload,
+            form = layui.form,
+            mallProductBuyRecord = [[${mallProductBuyRecord}]],
+            $view = $('#buyRecordImg-update'),
+            $uploadDel = $view.find('#uploadDel'),
+            validate = layui.validate;
+
+        form.render();
+        initPayImgValue();
+
+        function initPayImgValue() {
+            var nftImg = mallProductBuyRecord.nftImg;
+            layer.open({
+                type: 1,
+                title: "图片",
+                skin: 'layui-layer-rim', //加上边框
+                area: ['80%', '80%'], //宽高
+                shadeClose: true, //开启遮罩关闭
+                end: function (index, layero) {
+                    return false;
+                },
+                content: '<div style="text-align:center"><img src="' + nftImg + '" /></div>'
+            });
+            // $('#nftImgImagePay').html('<img src="' + nftImg + '" alt="" class="layui-upload-img new-image" style="width: 100px">')
+            form.val("buyRecordImg-update-form", {
+                "id": mallProductBuyRecord.id,
+                "nftImg": mallProductBuyRecord.nftImg,
+            });
+        }
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/febs/views/modules/news/buyRecordPay.html b/src/main/resources/templates/febs/views/modules/news/buyRecordPay.html
new file mode 100644
index 0000000..e014d55
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/buyRecordPay.html
@@ -0,0 +1,122 @@
+<style>
+    #buyRecordPay-update {
+        padding: 20px 25px 25px 0;
+    }
+
+    #buyRecordPay-update .layui-treeSelect .ztree li a, .ztree li span {
+        margin: 0 0 2px 3px !important;
+    }
+    #buyRecordPay-update #data-permission-tree-block {
+        border: 1px solid #eee;
+        border-radius: 2px;
+        padding: 3px 0;
+    }
+    #buyRecordPay-update .layui-treeSelect .ztree li span.button.switch {
+        top: 1px;
+        left: 3px;
+    }
+    #buyRecordPay-update img{
+        max-width:100px
+    }
+
+</style>
+<div class="layui-fluid" id="buyRecordPay-update">
+    <form class="layui-form" action="" lay-filter="buyRecordPay-update-form">
+        <div class="layui-form-item febs-hide">
+            <label class="layui-form-label febs-form-item-require">id:</label>
+            <div class="layui-input-block">
+                <input type="text" name="id">
+            </div>
+        </div>
+        <div class="layui-row layui-col-space10 layui-form-item">
+            <div class="layui-col-lg6">
+                <label class="layui-form-label febs-form-item-require">待支付:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="pickNftCnt" lay-verify="required" placeholder="" autocomplete="off" class="layui-input" readonly>
+                </div>
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label febs-form-item-require">缩略图:</label>
+            <div class="layui-input-block">
+                <div class="layui-upload">
+                    <button type="button" class="layui-btn layui-btn-normal layui-btn" id="nftImgUploadPay">上传</button>
+                    <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
+                        <div class="layui-upload-list" id="nftImgImagePay"></div>
+                    </blockquote>
+                    <div class="febs-hide">
+                        <input type="text" id="nftImg"  name="nftImg" autocomplete="off" class="layui-input" readonly>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div class="layui-form-item">
+            <div class="layui-col-lg6">
+                <label class="layui-form-label">支付类型:</label>
+                <div class="layui-input-block">
+                    <input type="radio" name="type" value="1" title="微信" checked/>
+                    <input type="radio" name="type" value="2" title="支付宝"  />
+                    <input type="radio" name="type" value="3" title="银行转账"  />
+                    <input type="radio" name="type" value="4" title="USDT转账" />
+                </div>
+            </div>
+        </div>
+        <div class="layui-form-item febs-hide">
+            <button class="layui-btn" lay-submit="" lay-filter="buyRecordPay-update-form-submit" id="submit"></button>
+        </div>
+    </form>
+</div>
+
+<script data-th-inline="javascript">
+    layui.use(['febs', 'form', 'formSelects', 'validate', 'upload'], function () {
+        var $ = layui.$,
+            febs = layui.febs,
+            layer = layui.layer,
+            upload = layui.upload,
+            form = layui.form,
+            mallProductBuyRecord = [[${mallProductBuyRecord}]],
+            $view = $('#buyRecordPay-update'),
+            $uploadDel = $view.find('#uploadDel'),
+            validate = layui.validate;
+
+        form.render();
+        initPayValue();
+
+
+        form.on('submit(buyRecordPay-update-form-submit)', function (data) {
+            febs.post(ctx + 'admin/news/buyRecordPay', data.field, function () {
+                layer.closeAll();
+                febs.alert.success('操作成功');
+                $('#febs-product-buy').find('#query').click();
+            });
+            return false;
+        });
+
+        upload.render({
+            elem: '#nftImgUploadPay'
+            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
+            ,multiple: false
+            ,before: function(obj){
+                //预读本地文件示例,不支持ie8
+                obj.preview(function(index, file, result){
+                    $('#nftImgImagePay').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img" style="width: 100px">')
+                });
+            }
+            ,done: function(res){
+                $("#nftImg").val(res.data.src);
+            }
+        });
+
+        function initPayValue() {
+            var nftImg = mallProductBuyRecord.nftImg;
+            $('#nftImgImagePay').html('<img src="' + nftImg + '" alt="" class="layui-upload-img new-image" style="width: 100px">')
+            form.val("buyRecordPay-update-form", {
+                "id": mallProductBuyRecord.id,
+                "pickNftCnt": mallProductBuyRecord.pickNftCnt,
+                "type": mallProductBuyRecord.type,
+                "nftImg": mallProductBuyRecord.nftImg,
+            });
+        }
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/febs/views/modules/news/productBuyList.html b/src/main/resources/templates/febs/views/modules/news/productBuyList.html
index e401bda..257b4b4 100644
--- a/src/main/resources/templates/febs/views/modules/news/productBuyList.html
+++ b/src/main/resources/templates/febs/views/modules/news/productBuyList.html
@@ -137,9 +137,11 @@
                             '<td>'+data.mallProductBuyRecords[i].accountLogin+'</td>\n' +
                             '<td>'+data.mallProductBuyRecords[i].pickNftCnt+'</td>\n' +
                             '<td>'+data.mallProductBuyRecords[i].orderTime+'</td>\n' +
-                            '<td>'+data.mallProductBuyRecords[i].payTime+'</td>\n' +
+                            // '<td>'+data.mallProductBuyRecords[i].payTime+'</td>\n' +
                             '<td><img src="'+data.mallProductBuyRecords[i].nftImg+'" alt="" ></td>\n' +
                             '<td>'+data.mallProductBuyRecords[i].type+'</td>\n' +
+                            '<td>'+data.mallProductBuyRecords[i].state+'</td>\n' +
+                            '<td>'+data.mallProductBuyRecords[i].state+'</td>\n' +
                             '<td>'+data.mallProductBuyRecords[i].state+'</td>\n' +
                             '</tr>';
                         obj.tr.after(html);
@@ -149,10 +151,12 @@
                         '      <td>匹配用户</td>\n' +
                         '      <td>支付金额</td>\n' +
                         '      <td>匹配时间</td>\n' +
-                        '      <td>支付时间</td>\n' +
+                        // '      <td>支付时间</td>\n' +
                         '      <td>支付凭证</td>\n' +
                         '      <td>支付类型</td>\n' +
                         '      <td>支付状态</td>\n' +
+                        '      <td>支付状态</td>\n' +
+                        '      <td>操作</td>\n' +
                         '    </tr>';
                     obj.tr.after(html);
                 }
diff --git a/src/main/resources/templates/febs/views/modules/news/productBuyListNew.html b/src/main/resources/templates/febs/views/modules/news/productBuyListNew.html
new file mode 100644
index 0000000..eb86ec8
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/productBuyListNew.html
@@ -0,0 +1,299 @@
+<div class="layui-fluid layui-anim febs-anim" id="febs-product-buy" lay-title="用户预约记录">
+    <div class="layui-row febs-container">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-body febs-table-full">
+                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
+                        <div class="layui-row">
+
+                            <div class="layui-col-md10">
+                                <div class="layui-form-item">
+                                    <div class="layui-inline">
+                                        <label class="layui-form-label">登录账户:</label>
+                                        <div class="layui-input-inline">
+                                            <input type="text" placeholder="登录账户" name="accountLogin" autocomplete="off" class="layui-input">
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
+<!--                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="add">-->
+<!--                                    新增-->
+<!--                                </div>-->
+                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
+                                    <i class="layui-icon">&#xe848;</i>
+                                </div>
+                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
+                                    <i class="layui-icon">&#xe79b;</i>
+                                </div>
+                            </div>
+                        </div>
+                    </form>
+                    <table lay-filter="buyTable" lay-data="{id: 'buyTable'}" id="buyTable"></table>
+                </div>
+                <blockquote class="layui-elem-quote blue-border">用户预约打款记录</blockquote>
+                <div class="layui-card-body febs-table-full">
+                    <table lay-filter="buyRecordTable"  lay-data="{id: 'buyRecordTable'}" id="buyRecordTable"></table>
+                </div>
+
+            </div>
+        </div>
+    </div>
+</div>
+<style>
+    .layui-table-cell {
+        height: auto;
+    }
+    .layui-form-onswitch {
+        background-color: #5FB878 !important;
+    }
+</style>
+<script type="text/html" id="isBuyState">
+    {{# if(d.state === 0) { }}
+    <span class="layui-badge febs-bg-red">失败</span>
+    {{# } else if(d.state === 1) { }}
+    <span class="layui-badge febs-bg-blue">进行中</span>
+    {{# } else if(d.state === 2) { }}
+    <span class="layui-badge febs-bg-orange">超时</span>
+    {{# } else if(d.state === 3) { }}
+    <span class="layui-badge febs-bg-green">已完成</span>
+    {{# } else { }}
+    {{# } }}
+</script>
+<script type="text/html" id="isBuyMateState">
+    {{# if(d.mateState === 0) { }}
+    <span class="layui-badge febs-bg-red">未转换</span>
+    {{# } else if(d.mateState === 1) { }}
+    <span class="layui-badge febs-bg-blue">已转换</span>
+    {{# } else if(d.mateState === 2) { }}
+    <span class="layui-badge febs-bg-orange">待支付</span>
+    {{# } else if(d.mateState === 3) { }}
+    <span class="layui-badge febs-bg-green">已支付</span>
+    {{# } else if(d.mateState === 4) { }}
+    <span class="layui-badge febs-bg-green">已确认</span>
+    {{# } else if(d.mateState === 5) { }}
+    <span class="layui-badge febs-bg-green">已完成</span>
+    {{# } else { }}
+    {{# } }}
+</script>
+<script type="text/html" id="isBuyRecordState">
+    {{# if(d.state === 0) { }}
+    <span class="layui-badge febs-bg-red">失败</span>
+    {{# } else if(d.state === 1) { }}
+    <span class="layui-badge febs-bg-blue">匹配中</span>
+    {{# } else if(d.state === 2) { }}
+    <span class="layui-badge febs-bg-orange">待支付</span>
+    {{# } else if(d.state === 3) { }}
+    <span class="layui-badge febs-bg-green">已支付</span>
+    {{# } else if(d.state === 4) { }}
+    <span class="layui-badge febs-bg-green">已确认</span>
+    {{# } else if(d.state === 5) { }}
+    <span class="layui-badge febs-bg-green">已完成</span>
+    {{# } else { }}
+    {{# } }}
+</script>
+<!-- 表格操作栏 start -->
+<script type="text/html" id="user-option">
+    <span shiro:lacksPermission="user:view,user:update,user:delete">
+        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
+    </span>
+    <a lay-event="edit" shiro:hasPermission="user:update"><i
+            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
+</script>
+<style>
+    .layui-form-onswitch {
+        background-color: #5FB878 !important;
+    }
+    .thead {background-color: rgba(255, 175, 16,0.2);text-align: center;}
+    .tbody {
+        background-color: rgba(255, 175, 16, 0.1);
+        text-align: center;
+        width:100px;
+    }
+</style>
+<!-- 表格操作栏 end -->
+<script data-th-inline="none" type="text/javascript">
+    // 引入组件并初始化
+    layui.use([ 'jquery', 'form', 'table', 'febs'], function () {
+        var $ = layui.jquery,
+            febs = layui.febs,
+            form = layui.form,
+            table = layui.table,
+            $view = $('#febs-product-buy'),
+            $query = $view.find('#query'),
+            $reset = $view.find('#reset'),
+            $searchForm = $view.find('form'),
+            sortObject = {field: 'phone', type: null},
+            buyRecordTable,
+            buyTable,
+            tableIns;
+
+        form.render();
+
+        // 表格初始化
+        initBuyTable();
+        initBuyTable();
+
+        // 初始化表格操作栏各个按钮功能
+        table.on('tool(buyTable)', function (obj) {
+            var data = obj.data,
+                layEvent = obj.event;
+            if (layEvent === 'productSellPick') {
+                febs.modal.open('编辑', 'modules/news/productSellPick/' + data.id, {
+                    btn: ['提交', '取消'],
+                    yes: function (index, layero) {
+                        $('#product-sell-pick').find('#submit').trigger('click');
+                    },
+                    btn2: function () {
+                        layer.closeAll();
+                    }
+                });
+            }
+        });
+
+        // 初始化表格操作栏各个按钮功能
+        table.on('tool(buyRecordTable)', function (obj) {
+            var data = obj.data,
+                layEvent = obj.event;
+            /**
+             *  +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="buyRecordPay" shiro:hasPermission="user:update">确认支付</button>'
+             +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="buyRecordConfirm" shiro:hasPermission="user:update">确认收款</button>'
+             +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="buyRecordImg" shiro:hasPermission="user:update">收款凭证</button>'
+             */
+            if (layEvent === 'buyRecordCancel') {
+                febs.modal.confirm('取消', '是否确认取消?', function () {
+                    buyRecordCancel(data.id);
+                });
+            }
+            if (layEvent === 'buyRecordPay') {
+                febs.modal.open('确认支付', 'modules/news/buyRecordPay/' + data.id, {
+                    btn: ['提交', '取消'],
+                    yes: function (index, layero) {
+                        $('#buyRecordPay-update').find('#submit').trigger('click');
+                    },
+                    btn2: function () {
+                        layer.closeAll();
+                    }
+                });
+            }
+            if (layEvent === 'buyRecordConfirm') {
+                febs.modal.confirm('确认收款', '是否确认收款?', function () {
+                    buyRecordConfirm(data.id);
+                });
+            }
+            if (layEvent === 'buyRecordImg') {
+                if(data.nftImg == null || data.nftImg == ''){
+                    febs.modal.warn('告警信息', '凭证未上传', function () {
+                        febs.alert.info("请上传凭证");
+                    });
+                    return false;
+                }
+                layer.open({
+                    type: 1,
+                    title: "凭证",
+                    skin: 'layui-layer-rim', //加上边框
+                    area: ['80%', '80%'], //宽高
+                    shadeClose: true, //开启遮罩关闭
+                    end: function (index, layero) {
+                        return false;
+                    },
+                    content: '<div style="text-align:center"><img src="' + data.nftImg + '" /></div>'
+                });
+                // febs.modal.open('凭证', 'modules/news/buyRecordImg/' + data.id, {
+                //     btn2: function () {
+                //         layer.closeAll();
+                //     }
+                // });
+            }
+        });
+        function buyRecordCancel(id) {
+            febs.get(ctx + 'admin/news/buyRecordCancel/' + id, null, function () {
+                febs.alert.success('操作成功');
+                $query.click();
+            });
+        }
+        function buyRecordConfirm(id) {
+            febs.get(ctx + 'admin/news/buyRecordConfirm/' + id, null, function () {
+                febs.alert.success('操作成功');
+                $query.click();
+            });
+        }
+
+        // 查询按钮
+        $query.on('click', function () {
+            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
+            buyRecordTable.reload({where: params, page: {curr: 1}});
+            buyTable.reload({where: params, page: {curr: 1}});
+        });
+
+        // 刷新按钮
+        $reset.on('click', function () {
+            $searchForm[0].reset();
+            sortObject.type = 'null';
+            buyRecordTable.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
+            buyTable.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
+        });
+
+        function initBuyTable() {
+            buyTable = febs.table.init({
+                elem: $('#buyTable'),
+                url: ctx + 'admin/news/getBuyList',
+                cols: [[
+                    {field: 'accountLogin', title: '登录账户', minWidth: 120,align:'center'},
+                    {field: 'nftTotal', title: '预约额度', minWidth: 120,align:'center'},
+                    {field: 'nftAva', title: '可分配', minWidth: 120,align:'center'},
+                    {field: 'orderTime', title: '匹配时间', minWidth: 120,align:'center'},
+                    {templet: '#isBuyState', title: '预约状态', minWidth: 120,align:'center'},
+                    {templet: '#isBuyMateState', title: '匹配状态', minWidth: 120,align:'center'},
+                    {title: '操作',
+                        templet: function (d) {
+                            if(d.state == 1){
+                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="productSellPick" shiro:hasPermission="user:update">手动匹配</button>'
+                            }else{
+                                return ''
+                            }
+                        },minWidth: 300,align:'center'}
+                ]]
+            });
+            buyRecordTable = febs.table.init({
+                elem: $('#buyRecordTable'),
+                url: ctx + 'admin/news/getBuyRecordList',
+                cols: [[
+                    {field: 'id', title: '', minWidth: 120,align:'center'},
+                    {field: 'accountLogin', title: '匹配用户', minWidth: 120,align:'center'},
+                    {field: 'pickNftCnt', title: '支付金额', minWidth: 120,align:'center'},
+                    {field: 'orderTime', title: '匹配时间', minWidth: 120,align:'center'},
+                    {field: 'payTime', title: '支付时间', minWidth: 120,align:'center'},
+                    {templet: '#isBuyRecordState', title: '支付状态', minWidth: 120,align:'center'},
+                    {title: '操作',
+                        templet: function (d) {
+                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="buyRecordCancel" shiro:hasPermission="user:update">取消</button>'
+                            +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="buyRecordPay" shiro:hasPermission="user:update">确认支付</button>'
+                            +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="buyRecordConfirm" shiro:hasPermission="user:update">确认收款</button>'
+                            +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="buyRecordImg" shiro:hasPermission="user:update">收款凭证</button>'
+                        },minWidth: 300,align:'center'}
+                ]]
+            });
+        }
+        // 获取查询参数
+        function getQueryParams() {
+            return {
+                accountLogin: $searchForm.find('input[name="accountLogin"]').val().trim(),
+            };
+        }
+
+        form.on('switch(isState)', function (data) {
+            if (data.elem.checked) {
+                febs.post(ctx + 'admin/news/upNFT/' + data.value, null, function () {
+                    febs.alert.success('操作成功');
+                    $query.click();
+                });
+            } else {
+                febs.post(ctx + 'admin/news/unUpNFT/' + data.value, null, function () {
+                    febs.alert.success('操作成功');
+                    $query.click();
+                });
+            }
+        })
+    })
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/febs/views/modules/news/productSellPick.html b/src/main/resources/templates/febs/views/modules/news/productSellPick.html
index 80be54c..b474f7d 100644
--- a/src/main/resources/templates/febs/views/modules/news/productSellPick.html
+++ b/src/main/resources/templates/febs/views/modules/news/productSellPick.html
@@ -137,7 +137,7 @@
             febs.post(ctx + 'admin/news/pickSellRecord', data.field, function () {
                 layer.closeAll();
                 febs.alert.success('操作成功');
-                $('#febs-product-buy').find('#reset').click();
+                $('#febs-product-buy').find('#query').click();
             });
             return false;
         });

--
Gitblit v1.9.1