From 990c09c842d87d1f179e3a0070541da0457b8393 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Tue, 21 Nov 2023 14:07:19 +0800
Subject: [PATCH] 匹配

---
 src/main/java/cc/mrbird/febs/mall/dto/UpdatePaymentDto.java                   |   38 
 src/main/java/cc/mrbird/febs/mall/entity/MallProductSellRecord.java           |   22 
 src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java               |   12 
 src/main/java/cc/mrbird/febs/mall/dto/ApiCreateNFTDto.java                    |   21 
 src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellRecordMapper.java     |    7 
 src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java          |    8 
 src/main/java/cc/mrbird/febs/mall/mapper/MallNewsInfoMapper.java              |    2 
 src/main/resources/templates/febs/views/modules/news/productNFTAdd.html       |  158 +++
 src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java            |   49 +
 src/main/java/cc/mrbird/febs/mall/dto/ApiOutNFTDto.java                       |   25 
 src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberWalletService.java    |    1 
 src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellMapper.java           |    7 
 src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java     |   78 +
 src/main/java/cc/mrbird/febs/mall/entity/MallProductBuy.java                  |   24 
 src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java             |    8 
 src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java              |   26 
 src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java           |   16 
 src/main/java/cc/mrbird/febs/mall/dto/ApiOutFcmDto.java                       |   25 
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallProductServiceImpl.java |  266 +++++
 src/main/java/cc/mrbird/febs/mall/service/IApiMallProductService.java         |   22 
 src/main/resources/mapper/modules/MallMemberAmountMapper.xml                  |   40 
 src/main/java/cc/mrbird/febs/mall/entity/MallProductNft.java                  |   22 
 src/main/java/cc/mrbird/febs/mall/mapper/MallMemberAmountMapper.java          |   15 
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java  |  256 ++++-
 src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java               |   24 
 src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java   |   62 +
 src/main/resources/templates/febs/views/modules/news/productBuyList.html      |  191 ++++
 src/main/resources/templates/febs/views/modules/news/productSellList.html     |  162 +++
 src/main/java/cc/mrbird/febs/mall/vo/MallMemberPaymentVo.java                 |   27 
 src/main/java/cc/mrbird/febs/mall/dto/ModifyMemberInfoDto.java                |    9 
 src/main/java/cc/mrbird/febs/mall/dto/GetKeyDto.java                          |   18 
 src/main/java/cc/mrbird/febs/mall/entity/MallMemberPayment.java               |   30 
 src/main/java/cc/mrbird/febs/mall/dto/AdminMallProductNftDto.java             |   22 
 src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java           |   19 
 src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java            |   27 
 src/main/resources/templates/febs/views/modules/news/productNFTUpdate.html    |  184 +++
 src/main/java/cc/mrbird/febs/mall/entity/MallMemberAmount.java                |   17 
 src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java     |   41 
 src/main/java/cc/mrbird/febs/mall/entity/MallProductSell.java                 |   20 
 src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java        |   22 
 src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductNftVo.java               |   23 
 src/main/java/cc/mrbird/febs/mall/conversion/MallMemberPaymentConversion.java |   15 
 src/main/java/cc/mrbird/febs/common/enumerates/ProductEnum.java               |   45 
 src/main/java/cc/mrbird/febs/mall/dto/TransferDto.java                        |   13 
 src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductSellVo.java              |   20 
 src/main/java/cc/mrbird/febs/mall/conversion/MallMemberAmountConversion.java  |   15 
 src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java          |   10 
 src/main/java/cc/mrbird/febs/mall/service/impl/MallMoneyFlowServiceImpl.java  |    5 
 src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeNewEnum.java           |   20 
 src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeNewEnum.java      |   33 
 src/main/java/cc/mrbird/febs/mall/controller/ApiMallProductController.java    |   51 +
 src/main/java/cc/mrbird/febs/mall/vo/ApiMallProductNftVo.java                 |   33 
 src/main/java/cc/mrbird/febs/mall/conversion/MallProductNftConversion.java    |   19 
 src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java           |    2 
 src/main/resources/mapper/modules/MallProductBuyMapper.xml                    |   37 
 src/main/resources/mapper/modules/MallProductNftMapper.xml                    |   19 
 src/main/java/cc/mrbird/febs/mall/vo/MallMemberVo.java                        |   55 
 src/main/java/cc/mrbird/febs/mall/entity/MallMember.java                      |    2 
 src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java   |   56 +
 src/main/java/cc/mrbird/febs/mall/dto/UnfreezeDto.java                        |   21 
 src/main/java/cc/mrbird/febs/common/utils/AppContants.java                    |    5 
 src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyMapper.java            |   12 
 src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java          |   51 +
 src/main/resources/templates/febs/views/modules/news/productNFTList.html      |  176 +++
 src/main/java/cc/mrbird/febs/mall/service/IMallMoneyFlowService.java          |    2 
 65 files changed, 2,605 insertions(+), 158 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 7079411..b4b5144 100644
--- a/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
+++ b/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
@@ -164,4 +164,53 @@
     }
     //强制卖出 end
 
+    // === 机器人自动抢红包 延时  start ===
+    @Bean
+    public DirectExchange buyTimeDelayTtlExchange() {
+        return new DirectExchange(RabbitQueueEnum.FCMPAY_BUY_TIME_TTL.getExchange());
+    }
+    @Bean
+    public Binding buyTimeDelayBindTtl() {
+        return BindingBuilder.bind(buyTimeDelayQueueTtl()).to(buyTimeDelayTtlExchange()).with(RabbitQueueEnum.FCMPAY_BUY_TIME_TTL.getRoute());
+    }
+    @Bean
+    public Queue buyTimeDelayQueueTtl() {
+        return QueueBuilder.durable(RabbitQueueEnum.FCMPAY_BUY_TIME_TTL.getQueue())
+                //到期后转发的交换机
+                .withArgument("x-dead-letter-exchange", RabbitQueueEnum.FCMPAY_BUY_TIME.getExchange())
+                //到期后转发的路由键
+                .withArgument("x-dead-letter-routing-key", RabbitQueueEnum.FCMPAY_BUY_TIME.getRoute())
+                .build();
+    }
+    @Bean
+    public DirectExchange buyTimeDelayExchange() {
+        return new DirectExchange(RabbitQueueEnum.FCMPAY_BUY_TIME.getExchange());
+    }
+    @Bean
+    public Queue buyTimeDelayQueue() {
+        return new Queue(RabbitQueueEnum.FCMPAY_BUY_TIME.getQueue());
+    }
+    @Bean
+    public Binding buyTimeDelayBind() {
+        return BindingBuilder.bind(buyTimeDelayQueue()).to(buyTimeDelayExchange()).with(RabbitQueueEnum.FCMPAY_BUY_TIME.getRoute());
+    }
+    // === 机器人自动抢红包 延时  end ===
+
+    //强制卖出 start
+    @Bean
+    public DirectExchange fcmNFTExchangeExchange() {
+        return new DirectExchange(RabbitQueueEnum.FCMPAY_FCM_NFT_EXCHANGE.getExchange());
+    }
+
+    @Bean
+    public Queue fcmNFTExchangeQueue() {
+        return new Queue(RabbitQueueEnum.FCMPAY_FCM_NFT_EXCHANGE.getQueue());
+    }
+
+    @Bean
+    public Binding fcmNFTExchangeBind() {
+        return BindingBuilder.bind(fcmNFTExchangeQueue()).to(fcmNFTExchangeExchange()).with(RabbitQueueEnum.FCMPAY_FCM_NFT_EXCHANGE.getRoute());
+    }
+    //强制卖出 end
+
 }
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java
index 82c087e..1064f96 100644
--- a/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/DataDictionaryEnum.java
@@ -6,6 +6,28 @@
 @Getter
 public enum DataDictionaryEnum {
     /**
+     * NFT最小提现数量
+     * NFT手续费
+     */
+    NFT_MIN("NFT_MIN","NFT_MIN"),
+    NFT_FEE("NFT_FEE","NFT_FEE"),
+    /**
+     * FCM最小提现数量
+     * FCM销毁数,累计10000,清零重新累计
+     * FCM销毁总数
+     * FCM代币价格
+     * FCM提现收续费
+     */
+    OUT_FCM_MIN("OUT_FCM_MIN","OUT_FCM_MIN"),
+    FCM_DESTORY_CNT("FCM_DESTORY_CNT","FCM_DESTORY_CNT"),
+    FCM_DESTORY_TOTAL("FCM_DESTORY_TOTAL","FCM_DESTORY_TOTAL"),
+    FCM_PRICE("FCM_PRICE","FCM_PRICE"),
+    OUT_FCM_FEE("OUT_FCM_FEE","OUT_FCM_FEE"),
+    /**
+     * 银行转账设置-客户号
+     */
+    MEMBER_FROZEN_FCM_CNT("MEMBER_FROZEN_FCM_CNT","MEMBER_FROZEN_FCM_CNT"),
+    /**
      * 银行转账设置-客户号
      */
     BANK_TRANS_softwareId("BANK_TRANS_SET","BANK_TRANS_softwareId"),
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeNewEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeNewEnum.java
new file mode 100644
index 0000000..b9cee35
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeNewEnum.java
@@ -0,0 +1,20 @@
+package cc.mrbird.febs.common.enumerates;
+
+import lombok.Getter;
+
+@Getter
+public enum FlowTypeNewEnum {
+
+    NFT(3,"NFT"),
+    TOKEN(2,"令牌"),
+    FCM_COIN(1,"FCM代币")//
+    ;
+
+    private int value;
+    private String description;
+
+    FlowTypeNewEnum(int value,String description) {
+        this.value = value;
+        this.description = description;
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeNewEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeNewEnum.java
new file mode 100644
index 0000000..2dee09d
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeNewEnum.java
@@ -0,0 +1,33 @@
+package cc.mrbird.febs.common.enumerates;
+
+import lombok.Getter;
+
+/**
+ *
+ * 1-静态收益 2-直推奖 3-代理收益 4-排名收益 5-总监收益 6-社区点补 7-一代收益 8-提现 9-转增 10-支付 11-退款
+ * @author wzy
+ * @date 2021-09-24
+ **/
+@Getter
+public enum MoneyFlowTypeNewEnum {
+    NFT_OUT_FEE(11,"NFT提现手续费"),
+    NFT_OUT(10,"NFT提现"),
+    NFT_IN(9,"FCM动态兑换"),
+    FCM_OUT_FEE(8,"动态兑换手续费"),
+    FCM_OUT(7,"FCM动态兑换"),
+    TOKEN_BUY_FROZEN(6,"预约冻结令牌"),
+    TOKEN_INSIDE_IN(5,"令牌转入"),
+    TOKEN_INSIDE_OUT(4,"令牌转出"),
+    FCM_INSIDE_IN(3,"代币转入"),
+    FCM_INSIDE_OUT(2,"代币转出"),
+    UNFREEZE_USER(1,"解除冻结")//解除冻结
+    ;
+
+    private int value;
+    private String descrition;
+
+    MoneyFlowTypeNewEnum(int value,String descrition) {
+        this.value = value;
+        this.descrition = descrition;
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/ProductEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/ProductEnum.java
new file mode 100644
index 0000000..f825942
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/ProductEnum.java
@@ -0,0 +1,45 @@
+package cc.mrbird.febs.common.enumerates;
+
+import lombok.Getter;
+
+@Getter
+public enum ProductEnum {
+    /**
+     * 用户NFT提现状态  0:失败 1:进行中 2:超时  3:已完成
+     */
+    PRODUCT_SELL_SUCCESS(3,"已完成"),
+    PRODUCT_SELL_TIMEOUT(2,"超时"),
+    PRODUCT_SELL_ON_GOING(1,"进行中"),
+    PRODUCT_SELL_FAIL(0,"失败"),
+
+    /**
+     * 匹配状态0:失败 1:匹配中 2:待支付 3:已支付 4:对方已确认 5:已完成
+     */
+    PRODUCT_MATE_STATE_FINISH(5,"已完成"),
+    PRODUCT_MATE_STATE_CONFIRM(4,"对方已确认"),
+    PRODUCT_MATE_STATE_PAY(3,"已支付"),
+    PRODUCT_MATE_STATE_WAIT_PAY(2,"待支付"),
+    PRODUCT_MATE_STATE_ON_GOING(1,"匹配中"),
+    PRODUCT_MATE_STATE_FAIL(0,"失败"),
+    /**
+     * 用户预约状态  0:失败 1:进行中 2:超时  3:已完成
+     */
+    PRODUCT_BUY_SUCCESS(3,"已完成"),
+    PRODUCT_BUY_TIMEOUT(2,"超时"),
+    PRODUCT_BUY_ON_GOING(1,"进行中"),
+    PRODUCT_BUY_FAIL(0,"失败"),
+    /**
+     * 预约产品是否开启
+     */
+    PRODUCT_NFT_OPEN(1,"开启"),
+    PRODUCT_NFT_CLOSE(0,"关闭")
+    ;
+
+    private int value;
+    private String description;
+
+    ProductEnum(int value, String description) {
+        this.value = value;
+        this.description = description;
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/common/utils/AppContants.java b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java
index 4110120..e167981 100644
--- a/src/main/java/cc/mrbird/febs/common/utils/AppContants.java
+++ b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java
@@ -39,6 +39,11 @@
      * 账号类型-邮箱
      */
     public static final String ACCOUNT_TYPE_EMAIL = "2";
+    /**
+     * 每次销毁10000个,价格增加0.1
+     */
+    public static final BigDecimal FCM_BASIC = new BigDecimal(10000);
+    public static final BigDecimal FCM_BASIC_ADD_PRICE = new BigDecimal("0.1");
 
     /**
      * 系统推荐人id
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 96a8c09..a766cc9 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/AdminNewsInfoController.java
@@ -4,10 +4,13 @@
 import cc.mrbird.febs.common.controller.BaseController;
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.common.entity.QueryRequest;
+import cc.mrbird.febs.common.enumerates.ProductEnum;
+import cc.mrbird.febs.mall.dto.AdminMallProductNftDto;
 import cc.mrbird.febs.mall.dto.MallNewsInfoDto;
-import cc.mrbird.febs.mall.entity.MallNewsCategory;
-import cc.mrbird.febs.mall.entity.MallNewsInfo;
+import cc.mrbird.febs.mall.entity.*;
+import cc.mrbird.febs.mall.mapper.MallProductNftMapper;
 import cc.mrbird.febs.mall.service.IMallNewsInfoService;
+import cc.mrbird.febs.mall.vo.AdminMallProductNftVo;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.validation.annotation.Validated;
@@ -31,6 +34,77 @@
 public class AdminNewsInfoController extends BaseController {
 
     private final IMallNewsInfoService mallNewsInfoService;
+    private final MallProductNftMapper mallProductNftMapper;
+
+    /**
+     * NFT预约产品
+     */
+    @GetMapping("getProductNFTList")
+    public FebsResponse getProductNFTList(MallProductNft mallProductNft, QueryRequest request) {
+        Map<String, Object> data = getDataTable(mallNewsInfoService.getProductNFTList(mallProductNft, request));
+        return new FebsResponse().success().data(data);
+    }
+
+    /**
+     * NFT预约产品-新增
+     */
+    @PostMapping("addProductNFT")
+    @ControllerEndpoint(operation = "NFT预约产品-新增", exceptionMessage = "操作失败")
+    public FebsResponse addProductNFT(@Valid AdminMallProductNftDto adminMallProductNftDto) {
+        return mallNewsInfoService.addProductNFT(adminMallProductNftDto);
+    }
+
+    @PostMapping(value = "/upNFT/{id}")
+    public FebsResponse upNFT(@PathVariable Long id) {
+        MallProductNft mallProductNft = mallProductNftMapper.selectById(id);
+        mallProductNft.setState(ProductEnum.PRODUCT_NFT_OPEN.getValue());
+        mallProductNftMapper.updateById(mallProductNft);
+        return new FebsResponse().success();
+    }
+
+    @PostMapping(value = "/unUpNFT/{id}")
+    public FebsResponse unUpNFT(@PathVariable Long id) {
+        MallProductNft mallProductNft = mallProductNftMapper.selectById(id);
+        mallProductNft.setState(ProductEnum.PRODUCT_NFT_CLOSE.getValue());
+        mallProductNftMapper.updateById(mallProductNft);
+        return new FebsResponse().success();
+    }
+
+    /**
+     * NFT预约产品-删除
+     */
+    @GetMapping("delNFT/{id}")
+    @ControllerEndpoint(operation = " 新闻中心-删除", exceptionMessage = "操作失败")
+    public FebsResponse delNFT(@NotNull(message = "{required}") @PathVariable Long id) {
+        return mallNewsInfoService.delNFT(id);
+    }
+
+    /**
+     * NFT预约产品-更新
+     */
+    @PostMapping("nftInfoUpdate")
+    @ControllerEndpoint(operation = "NFT预约产品-更新", exceptionMessage = "操作失败")
+    public FebsResponse nftInfoUpdate(@Valid MallProductNft mallProductNft) {
+        return mallNewsInfoService.nftInfoUpdate(mallProductNft);
+    }
+
+    /**
+     * 用户NFT预约列表
+     */
+    @GetMapping("getBuyList")
+    public FebsResponse getBuyList(MallProductBuy mallProductBuy, QueryRequest request) {
+        Map<String, Object> data = getDataTable(mallNewsInfoService.getBuyList(mallProductBuy, request));
+        return new FebsResponse().success().data(data);
+    }
+
+    /**
+     * 用户NFT提现列表
+     */
+    @GetMapping("getSellList")
+    public FebsResponse getSellList(MallProductSell mallProductSell, QueryRequest request) {
+        Map<String, Object> data = getDataTable(mallNewsInfoService.getSellList(mallProductSell, request));
+        return new FebsResponse().success().data(data);
+    }
 
     /**
      * 新闻中心-列表
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java b/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java
index e5eb1ad..5b55e36 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java
@@ -43,32 +43,32 @@
 
     @ApiOperation(value = "app注册接口", notes = "app注册接口")
     @PostMapping(value = "/register")
-    public FebsResponse register(@RequestBody RegisterDto registerDto) {
+    public FebsResponse register(@RequestBody @Valid RegisterDto registerDto) {
         return memberService.register(registerDto);
     }
 
 
     @ApiOperation(value = "账号密码登录接口", notes = "账号密码登录接口")
     @PostMapping(value = "/toLogin")
-    public FebsResponse login(@RequestBody LoginDto loginDto) {
+    public FebsResponse login(@RequestBody @Valid LoginDto loginDto) {
         return memberService.toLogin(loginDto);
     }
 
     @ApiOperation(value = "忘记/修改密码", notes = "忘记/修改密码")
     @PostMapping(value = "/forgetPwd")
-    public FebsResponse forgetPwd(@RequestBody ForgetPwdDto forgetPwdDto) {
+    public FebsResponse forgetPwd(@RequestBody @Valid ForgetPwdDto forgetPwdDto) {
         return memberService.forgetPwd(forgetPwdDto);
     }
 
     @ApiOperation(value = "忘记密码", notes = "忘记/修改密码")
     @PostMapping(value = "/pwdForget")
-    public FebsResponse pwdForget(@RequestBody ForgetPwdDto forgetPwdDto) {
+    public FebsResponse pwdForget(@RequestBody @Valid ForgetPwdDto forgetPwdDto) {
         return memberService.pwdForget(forgetPwdDto);
     }
 
     @ApiOperation(value = "提交注册申诉", notes = "提交注册申诉")
     @PostMapping(value = "addRegisterAppeal")
-    public FebsResponse addRegisterAppeal(@RequestBody RegisterAppealDto registerAppeal) {
+    public FebsResponse addRegisterAppeal(@RequestBody @Valid RegisterAppealDto registerAppeal) {
         memberService.addRegisterAppeal(registerAppeal);
         return new FebsResponse().success().message("申请成功");
     }
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java b/src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java
index e787aaa..4dc5754 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java
@@ -45,6 +45,39 @@
         return memberService.findMemberInfo();
     }
 
+    @ApiOperation(value = "修改用户信息")
+    @PostMapping(value = "/modifyInfo")
+    public FebsResponse modifyInfo(@RequestBody @Valid ModifyMemberInfoDto modifyMemberInfoDto) {
+        return memberService.modifyMemberInfo(modifyMemberInfoDto);
+    }
+
+    @ApiOperation(value = "解除冻结")
+    @PostMapping(value = "/unfreeze")
+    public FebsResponse unfreeze(@RequestBody @Valid UnfreezeDto unfreezeDto) {
+        return memberService.unfreeze(unfreezeDto);
+    }
+
+    @ApiOperation(value = "找回密钥")
+    @PostMapping(value = "/getKey")
+    public FebsResponse getKey(@RequestBody @Valid GetKeyDto getKeyDto) {
+        return memberService.getKey(getKeyDto);
+    }
+
+    @ApiOperation(value = "获取收款信息", notes = "获取收款信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "success", response = MallMemberPaymentVo.class)
+    })
+    @GetMapping(value = "/getPayment")
+    public FebsResponse getPayment() {
+        return memberService.getPayment();
+    }
+
+    @ApiOperation(value = "修改收款信息", notes = "修改收款信息")
+    @PostMapping(value = "/updatePayment")
+    public FebsResponse updatePayment(@RequestBody @Valid UpdatePaymentDto updatePaymentDto) {
+        return memberService.updatePayment(updatePaymentDto);
+    }
+
     @ApiOperation(value = "推出登录", notes = "推出登录")
     @PostMapping(value = "/logout")
     public FebsResponse logout() {
@@ -61,12 +94,6 @@
     @PostMapping(value = "/setTradePwd")
     public FebsResponse setTradePwd(@RequestBody ForgetPwdDto forgetPwdDto) {
         return memberService.setTradePwd(forgetPwdDto);
-    }
-
-    @ApiOperation(value = "修改用户信息")
-    @PostMapping(value = "/modifyInfo")
-    public FebsResponse modifyInfo(@RequestBody ModifyMemberInfoDto modifyMemberInfoDto) {
-        return memberService.modifyMemberInfo(modifyMemberInfoDto);
     }
 
     @ApiOperation(value = "我的团队列表")
@@ -92,7 +119,7 @@
     @PostMapping(value = "/transfer")
     public FebsResponse transfer(@RequestBody @Validated TransferDto transferDto) {
         memberService.transfer(transferDto);
-        return new FebsResponse().success().message("转账成功");
+        return new FebsResponse().success().message("操作成功");
     }
 
     @ApiOperation(value = "提现规则", notes = "提现规则")
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ApiMallProductController.java b/src/main/java/cc/mrbird/febs/mall/controller/ApiMallProductController.java
new file mode 100644
index 0000000..2c9a301
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ApiMallProductController.java
@@ -0,0 +1,51 @@
+package cc.mrbird.febs.mall.controller;
+
+import cc.mrbird.febs.common.entity.FebsResponse;
+import cc.mrbird.febs.mall.dto.*;
+import cc.mrbird.febs.mall.entity.MallNewsInfo;
+import cc.mrbird.febs.mall.service.IApiMallNewsService;
+import cc.mrbird.febs.mall.service.IApiMallProductService;
+import cc.mrbird.febs.mall.vo.NewsListVo;
+import cc.mrbird.febs.mall.vo.OrderListVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@Slf4j
+@RestController
+@CrossOrigin("*")
+@RequestMapping(value = "/api/product")
+@RequiredArgsConstructor
+@Api(value = "ApiMallProductController", tags = "NFT/FCM")
+public class ApiMallProductController {
+
+    private final IApiMallProductService iApiMallProductService;
+
+    @ApiOperation(value = "预约产品列表", notes = "预约产品列表")
+    @GetMapping(value = "/productNFTList")
+    public FebsResponse productNFTList() {
+        return new FebsResponse().success().data(iApiMallProductService.productNFTList());
+    }
+    @ApiOperation(value = "预约", notes = "预约")
+    @PostMapping(value = "/createNFT")
+    public FebsResponse createNFT(@RequestBody @Valid ApiCreateNFTDto createNFTDto) {
+        return iApiMallProductService.createNFT(createNFTDto);
+    }
+    @ApiOperation(value = "FCM提现", notes = "FCM提现")
+    @PostMapping(value = "/outFcm")
+    public FebsResponse outFcm(@RequestBody @Valid ApiOutFcmDto outFcmDto) {
+        return iApiMallProductService.outFcm(outFcmDto);
+    }
+    @ApiOperation(value = "NFT提现", notes = "NFT提现")
+    @PostMapping(value = "/outNFT")
+    public FebsResponse outNFT(@RequestBody @Valid ApiOutNFTDto outNFTDto) {
+        return iApiMallProductService.outNFT(outNFTDto);
+    }
+
+}
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 b30b048..c16302a 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ViewNewsController.java
@@ -4,6 +4,8 @@
 import cc.mrbird.febs.common.utils.FebsUtil;
 import cc.mrbird.febs.mall.entity.MallNewsCategory;
 import cc.mrbird.febs.mall.entity.MallNewsInfo;
+import cc.mrbird.febs.mall.entity.MallProductNft;
+import cc.mrbird.febs.mall.mapper.MallProductNftMapper;
 import cc.mrbird.febs.mall.service.IMallNewsInfoService;
 import lombok.RequiredArgsConstructor;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
@@ -23,6 +25,55 @@
 public class ViewNewsController {
 
     private final IMallNewsInfoService mallNewsInfoService;
+    private final MallProductNftMapper mallProductNftMapper;
+
+    /**
+     * NFT预约产品
+     */
+    @GetMapping("productNFTList")
+    @RequiresPermissions("productNFTList:view")
+    public String productNFTList() {
+        return FebsUtil.view("modules/news/productNFTList");
+    }
+
+    /**
+     * NFT预约产品-新增
+     */
+    @GetMapping("productNFTAdd")
+    @RequiresPermissions("productNFTAdd:add")
+    public String productNFTAdd() {
+        return FebsUtil.view("modules/news/productNFTAdd");
+    }
+
+    /**
+     * NFT预约产品-详情
+     * @return
+     */
+    @GetMapping("productNFTUpdate/{id}")
+    @RequiresPermissions("productNFTUpdate:update")
+    public String productNFTUpdate(@PathVariable long id, Model model) {
+        MallProductNft mallProductNft = mallProductNftMapper.selectById(id);
+        model.addAttribute("mallProductNft", mallProductNft);
+        return FebsUtil.view("modules/news/productNFTUpdate");
+    }
+
+    /**
+     * 用户NFT预约列表
+     */
+    @GetMapping("productBuyList")
+    @RequiresPermissions("productBuyList:view")
+    public String productBuyList() {
+        return FebsUtil.view("modules/news/productBuyList");
+    }
+
+    /**
+     * 用户NFT提现列表
+     */
+    @GetMapping("productSellList")
+    @RequiresPermissions("productSellList:view")
+    public String productSellList() {
+        return FebsUtil.view("modules/news/productSellList");
+    }
 
     /**
      * 新闻中心-列表
diff --git a/src/main/java/cc/mrbird/febs/mall/conversion/MallMemberAmountConversion.java b/src/main/java/cc/mrbird/febs/mall/conversion/MallMemberAmountConversion.java
new file mode 100644
index 0000000..5ce0656
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/conversion/MallMemberAmountConversion.java
@@ -0,0 +1,15 @@
+package cc.mrbird.febs.mall.conversion;
+
+import cc.mrbird.febs.mall.entity.MallMember;
+import cc.mrbird.febs.mall.entity.MallMemberAmount;
+import cc.mrbird.febs.mall.vo.MallMemberPaymentVo;
+import cc.mrbird.febs.mall.vo.MallMemberVo;
+import cc.mrbird.febs.mall.vo.MyCommissionVo;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public abstract class MallMemberAmountConversion {
+    public static final MallMemberAmountConversion INSTANCE = Mappers.getMapper(MallMemberAmountConversion.class);
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/conversion/MallMemberPaymentConversion.java b/src/main/java/cc/mrbird/febs/mall/conversion/MallMemberPaymentConversion.java
new file mode 100644
index 0000000..6d8e64c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/conversion/MallMemberPaymentConversion.java
@@ -0,0 +1,15 @@
+package cc.mrbird.febs.mall.conversion;
+
+import cc.mrbird.febs.mall.dto.UpdatePaymentDto;
+import cc.mrbird.febs.mall.entity.MallMemberPayment;
+import cc.mrbird.febs.mall.vo.MallMemberPaymentVo;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public abstract class MallMemberPaymentConversion {
+    public static final MallMemberPaymentConversion INSTANCE = Mappers.getMapper(MallMemberPaymentConversion.class);
+
+    public abstract MallMemberPaymentVo entityToVo(MallMemberPayment mallMemberPayment);
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/conversion/MallProductNftConversion.java b/src/main/java/cc/mrbird/febs/mall/conversion/MallProductNftConversion.java
new file mode 100644
index 0000000..92dd457
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/conversion/MallProductNftConversion.java
@@ -0,0 +1,19 @@
+package cc.mrbird.febs.mall.conversion;
+
+import cc.mrbird.febs.mall.dto.AdminMallProductNftDto;
+import cc.mrbird.febs.mall.entity.MallProductNft;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * @author wzy
+ * @date 2021-09-18
+ **/
+@Mapper
+public abstract class MallProductNftConversion {
+    public static final MallProductNftConversion INSTANCE = Mappers.getMapper(MallProductNftConversion.class);
+
+    public abstract MallProductNft dtoToEntity(AdminMallProductNftDto adminMallProductNftDto);
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/AdminMallProductNftDto.java b/src/main/java/cc/mrbird/febs/mall/dto/AdminMallProductNftDto.java
new file mode 100644
index 0000000..459fd81
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/AdminMallProductNftDto.java
@@ -0,0 +1,22 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@ApiModel(value = "AdminMallProductNftDto", description = "参数接收类")
+public class AdminMallProductNftDto {
+
+    private String nftCode;//编码
+    private String nftImg;//图片
+    private BigDecimal priceNft;//NFT价格
+    private BigDecimal priceToken;//TOKEN价格
+    private BigDecimal profit;//收益 5 即百分之五
+    private int cycle;//周期
+    private int state;//产品状态 1:开启 0:关闭
+    private int memberCnt;//预约人数
+    private int memberReal;//已预约人数
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ApiCreateNFTDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ApiCreateNFTDto.java
new file mode 100644
index 0000000..8257ab7
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/ApiCreateNFTDto.java
@@ -0,0 +1,21 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel(value = "ApiCreateNFTDto", description = "参数接收类")
+public class ApiCreateNFTDto {
+
+    @NotNull(message = "交易不能为空")
+    @ApiModelProperty(value = "id", example = "1")
+    private Long id;
+
+    @NotNull(message = "交易密码不能为空")
+    @ApiModelProperty(value = "交易密码", example = "1")
+    private String tradePassword;
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ApiOutFcmDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ApiOutFcmDto.java
new file mode 100644
index 0000000..9631a57
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/ApiOutFcmDto.java
@@ -0,0 +1,25 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "ApiOutFcmDto", description = "参数接收类")
+public class ApiOutFcmDto {
+
+    @Valid
+    @NotNull(message = "FCM数量不能为空")
+    @Min(0)
+    @ApiModelProperty(value = "兑换FCM数量", example = "1")
+    private BigDecimal fcmCnt;
+
+    @NotNull(message = "交易密码不能为空")
+    @ApiModelProperty(value = "交易密码", example = "1")
+    private String tradePassword;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ApiOutNFTDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ApiOutNFTDto.java
new file mode 100644
index 0000000..3d9258b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/ApiOutNFTDto.java
@@ -0,0 +1,25 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "ApiOutNFTDto", description = "参数接收类")
+public class ApiOutNFTDto {
+
+    @Valid
+    @NotNull(message = "NFT数量不能为空")
+    @Min(0)
+    @ApiModelProperty(value = "兑换NFT数量", example = "1")
+    private BigDecimal nftCnt;
+
+    @NotNull(message = "交易密码不能为空")
+    @ApiModelProperty(value = "交易密码", example = "1")
+    private String tradePassword;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/GetKeyDto.java b/src/main/java/cc/mrbird/febs/mall/dto/GetKeyDto.java
new file mode 100644
index 0000000..a6f3a3d
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/GetKeyDto.java
@@ -0,0 +1,18 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "GetKeyDto", description = "找回密钥参数接收类")
+public class GetKeyDto {
+    @NotBlank(message = "密码不能为空")
+    @ApiModelProperty(value = "密码", example = "123456")
+    private String password;
+    @NotBlank(message = "交易密码不能为空")
+    @ApiModelProperty(value = "交易密码", example = "123456")
+    private String tradePassword;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ModifyMemberInfoDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ModifyMemberInfoDto.java
index f595a4b..a535285 100644
--- a/src/main/java/cc/mrbird/febs/mall/dto/ModifyMemberInfoDto.java
+++ b/src/main/java/cc/mrbird/febs/mall/dto/ModifyMemberInfoDto.java
@@ -4,6 +4,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+
 /**
  * @author wzy
  * @date 2021-09-24
@@ -12,9 +14,14 @@
 @ApiModel(value = "ModifyMemberInfoDto", description = "修改用户信息参数接收类")
 public class ModifyMemberInfoDto {
 
-    @ApiModelProperty(value = "昵称", example = "123")
+    @NotBlank(message = "用户名不能为空")
+    @ApiModelProperty(value = "用户名", example = "123")
     private String name;
 
     @ApiModelProperty(value = "头像", example = "123")
     private String photo;
+
+    @NotBlank(message = "电话不能为空")
+    @ApiModelProperty(value = "电话", example = "123")
+    private String phone;
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/TransferDto.java b/src/main/java/cc/mrbird/febs/mall/dto/TransferDto.java
index 91428c2..fec677f 100644
--- a/src/main/java/cc/mrbird/febs/mall/dto/TransferDto.java
+++ b/src/main/java/cc/mrbird/febs/mall/dto/TransferDto.java
@@ -4,6 +4,7 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.Valid;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
@@ -17,16 +18,20 @@
 @ApiModel(value = "TransferDto", description = "转账接收参数类")
 public class TransferDto {
 
-    @NotBlank(message = "参数不能为空")
-    @ApiModelProperty(value = "联系电话或邀请码", example = "123")
+    @ApiModelProperty(value = "转出类型 1:FCM 2:令牌", example = "1")
+    private int type;
+
+    @NotBlank(message = "转出账户不能为空")
+    @ApiModelProperty(value = "转出账户", example = "123")
     private String account;
 
-    @NotNull(message = "参数不能为空")
+    @Valid
+    @NotNull(message = "金额不能为空")
     @Min(0)
     @ApiModelProperty(value = "金额", example = "1")
     private BigDecimal amount;
 
-    @NotBlank(message = "参数不能为空")
+    @NotBlank(message = "交易密码不能为空")
     @ApiModelProperty(value = "交易密码", example = "123456")
     private String tradePwd;
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/UnfreezeDto.java b/src/main/java/cc/mrbird/febs/mall/dto/UnfreezeDto.java
new file mode 100644
index 0000000..5ea7b9b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/UnfreezeDto.java
@@ -0,0 +1,21 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "UnfreezeDto", description = "参数接收类")
+public class UnfreezeDto {
+
+    @NotBlank(message = "用户ID不能为空")
+    @ApiModelProperty(value = "用户ID")
+    private Long memberId;
+
+    @NotBlank(message = "类型不能为空")
+    @ApiModelProperty(value = "类型 1:本人解冻 2:上级解冻")
+    private int type;
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/UpdatePaymentDto.java b/src/main/java/cc/mrbird/febs/mall/dto/UpdatePaymentDto.java
new file mode 100644
index 0000000..682787a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/UpdatePaymentDto.java
@@ -0,0 +1,38 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "UpdatePaymentDto", description = "参数接收类")
+public class UpdatePaymentDto {
+
+    @NotBlank(message = "微信收款码不能为空")
+    @ApiModelProperty(value = "微信收款码")
+    private String wxQrcode;//
+    @NotBlank(message = "支付宝收款码不能为空")
+    @ApiModelProperty(value = "支付宝收款码")
+    private String aliQrcode;//
+    @NotBlank(message = "真实姓名不能为空")
+    @ApiModelProperty(value = "真实姓名")
+    private String bankName;//
+    @NotBlank(message = "银行卡号不能为空")
+    @ApiModelProperty(value = "银行卡号")
+    private String bankNo;//
+    @NotBlank(message = "开户行不能为空")
+    @ApiModelProperty(value = "开户行")
+    private String bank;//
+    @NotBlank(message = "手机号不能为空")
+    @ApiModelProperty(value = "手机号")
+    private String phone;//
+    @NotBlank(message = "USDT通道类型不能为空")
+    @ApiModelProperty(value = "USDT通道类型:  TRC20 BEP20")
+    private String usdtTongdao;//
+    @NotBlank(message = "USDT地址不能为空")
+    @ApiModelProperty(value = "USDT地址")
+    private String usdtAddress;//
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java b/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java
index aed3e8e..f73d8be 100644
--- a/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java
@@ -173,4 +173,6 @@
 
     //提现开关 1:开启 2:关闭
     private Integer outsideWith;
+    private String userKey;
+    private Integer isFrozen;//是否冻结 1:是 0 :否
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallMemberAmount.java b/src/main/java/cc/mrbird/febs/mall/entity/MallMemberAmount.java
index 8d50479..10f661e 100644
--- a/src/main/java/cc/mrbird/febs/mall/entity/MallMemberAmount.java
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallMemberAmount.java
@@ -3,6 +3,9 @@
 import cc.mrbird.febs.common.entity.BaseEntity;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
+
+import java.math.BigDecimal;
+
 /**
  * CREATE TABLE `mall_member_amount` (
  *   `id` bigint(20) NOT NULL AUTO_INCREMENT,
@@ -26,11 +29,11 @@
 @TableName("mall_member_amount")
 public class MallMemberAmount extends BaseEntity {
     private Long memberId;
-    private Long staticNft;//静态NFT
-    private Long trendsNft;//动态NFT
-    private Long frozenNft;//冻结NFT
-    private Long fcmCntAva;//FCM代币可用
-    private Long fcmCntFrozen;//FCM代币冻结
-    private Long tokenAva;//令牌可用
-    private Long tokenFrozen;//令牌冻结
+    private BigDecimal staticNft;//静态NFT
+    private BigDecimal trendsNft;//动态NFT
+    private BigDecimal frozenNft;//冻结NFT
+    private BigDecimal fcmCntAva;//FCM代币可用
+    private BigDecimal fcmCntFrozen;//FCM代币冻结
+    private BigDecimal tokenAva;//令牌可用
+    private BigDecimal tokenFrozen;//令牌冻结
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallMemberPayment.java b/src/main/java/cc/mrbird/febs/mall/entity/MallMemberPayment.java
index 396c31f..7e73453 100644
--- a/src/main/java/cc/mrbird/febs/mall/entity/MallMemberPayment.java
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallMemberPayment.java
@@ -13,31 +13,17 @@
 public class MallMemberPayment extends BaseEntity {
 
     private Long memberId;
-
-    private String wxQrcode;
-
+    private String wxQrcode;//微信收款码
     private String wxName;
-
     private String wxAccount;
-
-    private String aliQrcode;
-
+    private String aliQrcode;//支付宝收款码
     private String aliName;
-
     private String aliAccount;
+    private String bankName;//真实姓名
+    private String bankNo;//银行卡号
+    private String bank;//开户行
+    private String phone;//手机号
+    private String usdtTongdao;//USDT通道类型:  TRC20 BEP20
+    private String usdtAddress;//USDT地址
 
-    /**
-     * 持卡人姓名
-     */
-    private String bankName;
-
-    /**
-     * 银行卡号
-     */
-    private String bankNo;
-
-    /**
-     * 开户行
-     */
-    private String bank;
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallProductBuy.java b/src/main/java/cc/mrbird/febs/mall/entity/MallProductBuy.java
new file mode 100644
index 0000000..1123f40
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallProductBuy.java
@@ -0,0 +1,24 @@
+package cc.mrbird.febs.mall.entity;
+
+import cc.mrbird.febs.common.entity.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+import java.math.BigDecimal;
+
+@Data
+@TableName("mall_product_buy")
+public class MallProductBuy extends BaseEntity {
+
+    private Long memberId;//
+    private Long sellId;//出售ID
+    private Long productNftId;//预约NFT编码
+    private int state;//预约状态  0:失败 1:进行中 2:超时  3:已完成
+    private int mateState;//匹配状态0:失败 1:匹配中 2:待支付 3:已支付 4:对方已确认 5:已完成
+    private BigDecimal nftTotal;//nft预约额度
+    private BigDecimal nftAva;//nft分配额度
+    private Date orderTime;//匹配时间
+    private Date payTime;//支付时间
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallProductNft.java b/src/main/java/cc/mrbird/febs/mall/entity/MallProductNft.java
new file mode 100644
index 0000000..737209e
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallProductNft.java
@@ -0,0 +1,22 @@
+package cc.mrbird.febs.mall.entity;
+
+import cc.mrbird.febs.common.entity.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@TableName("mall_product_nft")
+public class MallProductNft extends BaseEntity {
+
+    private String nftCode;//编码
+    private String nftImg;//图片
+    private BigDecimal priceNft;//NFT价格
+    private BigDecimal priceToken;//TOKEN价格
+    private BigDecimal profit;//收益 5 即百分之五
+    private int cycle;//周期
+    private int state;//产品状态 1:开启 0:关闭
+    private int memberCnt;//预约人数
+    private int memberReal;//已预约人数
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallProductSell.java b/src/main/java/cc/mrbird/febs/mall/entity/MallProductSell.java
new file mode 100644
index 0000000..f37423b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallProductSell.java
@@ -0,0 +1,20 @@
+package cc.mrbird.febs.mall.entity;
+
+import cc.mrbird.febs.common.entity.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@TableName("mall_product_sell")
+public class MallProductSell extends BaseEntity {
+
+    private Long memberId;//
+    private BigDecimal nftTotal;//动态NFT总数
+    private BigDecimal nftCnt;//实际提现数量
+    private BigDecimal nftCntAva;//剩余数量
+    private BigDecimal nftFee;//NFT手续费
+    private BigDecimal fcmFee;//代币手续费
+    private Integer state;//预约状态  0:失败 1:进行中 2:超时  3:已完成
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallProductSellRecord.java b/src/main/java/cc/mrbird/febs/mall/entity/MallProductSellRecord.java
new file mode 100644
index 0000000..c3e75ac
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallProductSellRecord.java
@@ -0,0 +1,22 @@
+package cc.mrbird.febs.mall.entity;
+
+import cc.mrbird.febs.common.entity.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@TableName("mall_product_sell_record")
+public class MallProductSellRecord extends BaseEntity {
+
+    private Long sellId;//
+    private Long memberId;//
+    private Date orderTime;//匹配时间
+    private Date payTime;//支付时间
+    private BigDecimal nftCnt;//支付数量
+    private String nftImg;//支付凭证
+    private Integer type;//支付类型 1:微信 2:支付宝 3:银行转账 4:USDT转账
+    private Integer state;//匹配状态0:失败 1:匹配中 2:待支付 3:已支付 4:对方已确认 5:已完成
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberAmountMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberAmountMapper.java
index 5d7fcbf..ccf187e 100644
--- a/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberAmountMapper.java
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberAmountMapper.java
@@ -2,6 +2,21 @@
 
 import cc.mrbird.febs.mall.entity.MallMemberAmount;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
 
 public interface MallMemberAmountMapper extends BaseMapper<MallMemberAmount> {
+
+    MallMemberAmount selectByMemberId(@Param("memberId")Long memberId);
+
+    void updateFcmCntAvaById(@Param("record")MallMemberAmount mallMemberAmount);
+
+    void updateTokenAvaById(@Param("record")MallMemberAmount mallMemberAmount);
+
+    void updateTokenAvaAndTokenFrozenById(@Param("record")MallMemberAmount mallMemberAmount);
+
+    void updateTrendsNftById(@Param("record")MallMemberAmount mallMemberAmount);
+
+    void updateFrozenNftById(@Param("record")MallMemberAmount mallMemberAmount);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallNewsInfoMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallNewsInfoMapper.java
index 4c3a65f..781e3b9 100644
--- a/src/main/java/cc/mrbird/febs/mall/mapper/MallNewsInfoMapper.java
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallNewsInfoMapper.java
@@ -2,7 +2,9 @@
 
 import cc.mrbird.febs.mall.dto.NewsListDto;
 import cc.mrbird.febs.mall.entity.MallNewsInfo;
+import cc.mrbird.febs.mall.entity.MallProductNft;
 import cc.mrbird.febs.mall.vo.AdminMallNewsInfoVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductNftVo;
 import cc.mrbird.febs.mall.vo.NewsListVo;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyMapper.java
new file mode 100644
index 0000000..3212291
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyMapper.java
@@ -0,0 +1,12 @@
+package cc.mrbird.febs.mall.mapper;
+
+import cc.mrbird.febs.mall.entity.MallProductBuy;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+public interface MallProductBuyMapper extends BaseMapper<MallProductBuy> {
+    MallProductBuy selectMemberIdAndNFTIdAndStateAndMateState(@Param("memberId")Long memberId,
+                                                              @Param("productNFTId")Long productNFTId,
+                                                              @Param("state")Integer state,
+                                                              @Param("mateState")Integer mateState);
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java
new file mode 100644
index 0000000..d2142ae
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java
@@ -0,0 +1,27 @@
+package cc.mrbird.febs.mall.mapper;
+
+import cc.mrbird.febs.mall.entity.MallProductBuy;
+import cc.mrbird.febs.mall.entity.MallProductNft;
+import cc.mrbird.febs.mall.entity.MallProductSell;
+import cc.mrbird.febs.mall.vo.AdminMallProductBuyVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductNftVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductSellVo;
+import cc.mrbird.febs.mall.vo.ApiMallProductNftVo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface MallProductNftMapper extends BaseMapper<MallProductNft> {
+
+    IPage<AdminMallProductNftVo> getProductNFTList(Page<AdminMallProductNftVo> page, @Param("record")MallProductNft mallProductNft);
+
+    List<ApiMallProductNftVo> selectByState(@Param("state")int value);
+
+    IPage<AdminMallProductBuyVo> getBuyList(Page<AdminMallProductBuyVo> page, @Param("record")MallProductBuy mallProductBuy);
+
+    IPage<AdminMallProductSellVo> getSellList(Page<AdminMallProductSellVo> page, @Param("record")MallProductSell mallProductSell);
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellMapper.java
new file mode 100644
index 0000000..09541dd
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellMapper.java
@@ -0,0 +1,7 @@
+package cc.mrbird.febs.mall.mapper;
+
+import cc.mrbird.febs.mall.entity.MallProductSell;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface MallProductSellMapper extends BaseMapper<MallProductSell> {
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellRecordMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellRecordMapper.java
new file mode 100644
index 0000000..8cb5822
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellRecordMapper.java
@@ -0,0 +1,7 @@
+package cc.mrbird.febs.mall.mapper;
+
+import cc.mrbird.febs.mall.entity.MallProductSellRecord;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface MallProductSellRecordMapper extends BaseMapper<MallProductSellRecord> {
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java
index e51671b..686d2b7 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java
@@ -82,4 +82,12 @@
     FebsResponse createAccount();
 
     FebsResponse createKey();
+
+    FebsResponse getPayment();
+
+    FebsResponse getKey(GetKeyDto getKeyDto);
+
+    FebsResponse updatePayment(UpdatePaymentDto updatePaymentDto);
+
+    FebsResponse unfreeze(UnfreezeDto unfreezeDto);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberWalletService.java b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberWalletService.java
index d6dfd39..811d8d8 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberWalletService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberWalletService.java
@@ -26,4 +26,5 @@
     int reduce(BigDecimal amount, Long memberId, String field, Map<String, BigDecimal> map);
 
     void commissionChange(CommissionChangeDto commissionChange);
+
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IApiMallProductService.java b/src/main/java/cc/mrbird/febs/mall/service/IApiMallProductService.java
new file mode 100644
index 0000000..8388b5e
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/service/IApiMallProductService.java
@@ -0,0 +1,22 @@
+package cc.mrbird.febs.mall.service;
+
+import cc.mrbird.febs.common.entity.FebsResponse;
+import cc.mrbird.febs.mall.dto.ApiCreateNFTDto;
+import cc.mrbird.febs.mall.dto.ApiOutFcmDto;
+import cc.mrbird.febs.mall.dto.ApiOutNFTDto;
+import cc.mrbird.febs.mall.entity.MallNewsCategory;
+import cc.mrbird.febs.mall.entity.MallProductNft;
+import cc.mrbird.febs.mall.vo.ApiMallProductNftVo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+public interface IApiMallProductService extends IService<MallProductNft> {
+    List<ApiMallProductNftVo> productNFTList();
+
+    FebsResponse createNFT(ApiCreateNFTDto createNFTDto);
+
+    FebsResponse outFcm(ApiOutFcmDto outFcmDto);
+
+    FebsResponse outNFT(ApiOutNFTDto outNFTDto);
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IMallMoneyFlowService.java b/src/main/java/cc/mrbird/febs/mall/service/IMallMoneyFlowService.java
index 5b35700..8cea027 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IMallMoneyFlowService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IMallMoneyFlowService.java
@@ -15,4 +15,6 @@
 
     void addMoneyFlow(Long memberId, BigDecimal amount, Integer type, String orderNo, Long rtMemberId, Integer flowType);
 
+    void addMoneyFlow(Long memberId, BigDecimal amount, Integer type, String orderNo, Long rtMemberId, Integer flowType, String description);
+
 }
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 2332a5a..762d896 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IMallNewsInfoService.java
@@ -2,10 +2,13 @@
 
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.common.entity.QueryRequest;
+import cc.mrbird.febs.mall.dto.AdminMallProductNftDto;
 import cc.mrbird.febs.mall.dto.MallNewsInfoDto;
-import cc.mrbird.febs.mall.entity.MallNewsCategory;
-import cc.mrbird.febs.mall.entity.MallNewsInfo;
+import cc.mrbird.febs.mall.entity.*;
 import cc.mrbird.febs.mall.vo.AdminMallNewsInfoVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductBuyVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductNftVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductSellVo;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -32,4 +35,16 @@
     List<MallNewsCategory> findAllCategory();
 
     FebsResponse delNewsCategoryInfo(Long id);
+
+    IPage<AdminMallProductNftVo> getProductNFTList(MallProductNft mallProductNft, QueryRequest request);
+
+    FebsResponse addProductNFT(AdminMallProductNftDto adminMallProductNftDto);
+
+    FebsResponse delNFT(Long id);
+
+    FebsResponse nftInfoUpdate(MallProductNft mallProductNft);
+
+    IPage<AdminMallProductBuyVo> getBuyList(MallProductBuy mallProductBuy, QueryRequest request);
+
+    IPage<AdminMallProductSellVo> getSellList(MallProductSell mallProductSell, QueryRequest request);
 }
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 7806be2..8283291 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
@@ -55,4 +55,6 @@
     void achieveReleaseJob();
 
     void selaHalfVoucher(String price);
+
+    void fcmNFTExchangeMsg(String cnt);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
index 230a6e7..d948432 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
@@ -4,16 +4,14 @@
 import cc.mrbird.febs.common.enumerates.*;
 import cc.mrbird.febs.common.exception.FebsException;
 import cc.mrbird.febs.common.utils.*;
-import cc.mrbird.febs.mall.conversion.MallGoodsConversion;
-import cc.mrbird.febs.mall.conversion.MallMemberBankConversion;
-import cc.mrbird.febs.mall.conversion.MallMemberConversion;
-import cc.mrbird.febs.mall.conversion.MallShopApplyConversion;
+import cc.mrbird.febs.mall.conversion.*;
 import cc.mrbird.febs.mall.dto.*;
 import cc.mrbird.febs.mall.entity.*;
 import cc.mrbird.febs.mall.mapper.*;
 import cc.mrbird.febs.mall.service.IApiMallMemberService;
 import cc.mrbird.febs.mall.service.IApiMallMemberWalletService;
 import cc.mrbird.febs.mall.service.ICommonService;
+import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
 import cc.mrbird.febs.mall.vo.*;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
@@ -60,6 +58,7 @@
     private final MallShopApplyMapper mallShopApplyMapper;
     private final MallRegisterAppealMapper mallRegisterAppealMapper;
     private final MallMemberBankMapper mallMemberBankMapper;
+    private final IMallMoneyFlowService mallMoneyFlowService;
 
 
     @Value("${spring.profiles.active}")
@@ -88,6 +87,7 @@
         mallMember = new MallMember();
         mallMember.setAccountLogin(accountLogin);
         mallMember.setPassword(SecureUtil.md5(registerDto.getPassword()));
+        mallMember.setUserKey(userKey);
         mallMember.setTradePassword(SecureUtil.md5(registerDto.getTradePassword()));
 
         Integer count = this.baseMapper.selectCount(null);
@@ -201,7 +201,7 @@
         this.baseMapper.updateById(mallMember);
 
         redisUtils.del(AppContants.APP_LOGIN_PREFIX + mallMember.getId());
-        return new FebsResponse().success().message("重置成功");
+        return new FebsResponse().success().message("操作成功");
     }
 
     @Override
@@ -223,27 +223,32 @@
             mallMemberVo.setReferrerName(referMember.getName());
         }
 
-        if (StrUtil.isNotBlank(mallMember.getTradePassword())) {
-            mallMemberVo.setHasTradePwd(1);
-        }
-
         MallMemberPayment payment = mallMemberPaymentMapper.selectByMemberId(id);
         if (payment != null) {
             mallMemberVo.setHasPayment(1);
         }
 
+        DataDictionaryCustom fcmPriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.FCM_PRICE.getType(),
+                DataDictionaryEnum.FCM_PRICE.getCode());
+        mallMemberVo.setFcmPrice(ObjectUtil.isEmpty(fcmPriceDic) ? new BigDecimal(2) : new BigDecimal(fcmPriceDic.getValue()));
+
+        DataDictionaryCustom outFcmFeeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.OUT_FCM_FEE.getType(),
+                DataDictionaryEnum.OUT_FCM_FEE.getCode());
+        mallMemberVo.setOutFcmFee(ObjectUtil.isEmpty(outFcmFeeDic) ? new BigDecimal(20) : new BigDecimal(outFcmFeeDic.getValue()));
         DataDictionaryCustom dic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.AGENT_LEVEL, mallMember.getLevel());
         if (dic != null) {
             mallMemberVo.setLevelName(dic.getDescription());
         }
-        MallMemberWallet wallet = mallMemberWalletMapper.selectWalletByMemberId(mallMemberVo.getId());
-        mallMemberVo.setBalance(wallet.getBalance());
-        mallMemberVo.setScore(wallet.getScore());
-        mallMemberVo.setPrizeScore(wallet.getPrizeScore());
-        mallMemberVo.setTotalScore(wallet.getTotalScore());
-        mallMemberVo.setStar(wallet.getStar());
-        mallMemberVo.setVoucherCnt(wallet.getVoucherCnt());
-        mallMemberVo.setTotalCost(mallOrderInfoMapper.selectTotalAmount(id));
+        MallMemberAmount mallMemberAmount = mallMemberAmountMapper.selectByMemberId(mallMember.getId());
+        mallMemberVo.setStaticNft(mallMemberAmount.getStaticNft());
+        mallMemberVo.setTrendsNft(mallMemberAmount.getTrendsNft());
+        mallMemberVo.setFrozenNft(mallMemberAmount.getFrozenNft());
+        mallMemberVo.setFcmCntAva(mallMemberAmount.getFcmCntAva());
+        mallMemberVo.setFcmCntFrozen(mallMemberAmount.getFcmCntFrozen());
+        mallMemberVo.setTokenAva(mallMemberAmount.getTokenAva());
+        mallMemberVo.setTokenFrozen(mallMemberAmount.getTokenFrozen());
         return new FebsResponse().success().data(mallMemberVo);
     }
 
@@ -279,23 +284,22 @@
         }
         mallMember.setTradePassword(SecureUtil.md5(forgetPwdDto.getPassword()));
         this.baseMapper.updateById(mallMember);
-        return new FebsResponse().success().message("设置成功");
+        return new FebsResponse().success().message("操作成功");
     }
 
     @Override
     public FebsResponse modifyMemberInfo(ModifyMemberInfoDto modifyMemberInfoDto) {
         MallMember member = LoginUserUtil.getLoginUser();
         MallMember mallMember = this.baseMapper.selectById(member.getId());
-        if (StrUtil.isNotBlank(modifyMemberInfoDto.getName())) {
-            mallMember.setName(modifyMemberInfoDto.getName());
-        }
+        mallMember.setName(modifyMemberInfoDto.getName());
+        mallMember.setPhone(modifyMemberInfoDto.getPhone());
 
         if (StrUtil.isNotBlank(modifyMemberInfoDto.getPhoto())) {
             mallMember.setAvatar(modifyMemberInfoDto.getPhoto());
         }
 
         this.baseMapper.updateById(mallMember);
-        return new FebsResponse().success().message("修改成功");
+        return new FebsResponse().success().message("操作成功");
     }
 
     @Override
@@ -351,64 +355,91 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void transfer(TransferDto transferDto) {
-        MallMember mallMember = this.baseMapper.selectInfoByAccount(transferDto.getAccount());
-        if (mallMember == null) {
-            throw new FebsException("用户不存在");
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        MallMember loginMember = this.baseMapper.selectById(memberId);
+        BigDecimal amount = transferDto.getAmount();
+        int type = transferDto.getType();
+
+        if(1 != type || 2 != type){
+            throw new FebsException("请选择互转类型");
         }
-        Integer insideWith = mallMember.getInsideWith() == null ? 2 :mallMember.getInsideWith();
+        Integer insideWith = loginMember.getInsideWith() == null ? 2 :loginMember.getInsideWith();
         if (1 != insideWith) {
             throw new FebsException("功能升级中");
         }
 
-        Long memberId = LoginUserUtil.getLoginUser().getId();
-        MallMember loginMember = this.baseMapper.selectById(memberId);
+        MallMember mallMember = this.baseMapper.selectByAccountLogin(transferDto.getAccount());
+        if (mallMember == null) {
+            throw new FebsException("转出账户不存在");
+        }
 
-        if (loginMember.getPhone().equals(transferDto.getAccount()) || loginMember.getInviteId().equals(transferDto.getAccount())) {
+        if (loginMember.getAccountLogin().equals(transferDto.getAccount())) {
             throw new FebsException("不能给自己转账");
         }
 
         if (StrUtil.isBlank(loginMember.getTradePassword())) {
-            throw new FebsException("未设置支付密码");
+            throw new FebsException("请设置交易密码");
         }
 
         if (!loginMember.getTradePassword().equals(SecureUtil.md5(transferDto.getTradePwd()))) {
-            throw new FebsException("支付密码错误");
+            throw new FebsException("交易密码错误");
         }
 
-        DataDictionaryCustom cashOutSettingDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
-                DataDictionaryEnum.CASHOUT_SETTING.getType(),
-                DataDictionaryEnum.CASHOUT_SETTING.getCode()
-        );
-        CashOutSettingVo cashOutSettingVo = JSONObject.parseObject(cashOutSettingDic.getValue(), CashOutSettingVo.class);
-        BigDecimal insideFee = cashOutSettingVo.getInsideFee().multiply(BigDecimal.valueOf(0.01));
-        //转账手续费
-        BigDecimal insideFeeAmount = transferDto.getAmount().multiply(insideFee).setScale(2, BigDecimal.ROUND_DOWN);
-
-        BigDecimal avaAmount = transferDto.getAmount().subtract(insideFeeAmount).setScale(2, BigDecimal.ROUND_DOWN);
-        walletService.reduceBalance(avaAmount, memberId);
-        String orderNo = MallUtils.getOrderNum("T");
-        this.addMoneyFlow(
-                memberId,
-                avaAmount.negate(),
-                MoneyFlowTypeEnum.TRANSFER.getValue(),
-                orderNo,
-                null,
-                null,
-                mallMember.getId(),
-                null,
-                FlowTypeEnum.BALANCE.getValue());
-
-        walletService.addBalance(avaAmount, mallMember.getId());
-        this.addMoneyFlow(
-                mallMember.getId(),
-                avaAmount,
-                MoneyFlowTypeEnum.TRANSFER.getValue(),
-                orderNo,
-                null,
-                null,
-                memberId,
-                null,
-                FlowTypeEnum.BALANCE.getValue());
+        BigDecimal avaAmount = transferDto.getAmount().setScale(2, BigDecimal.ROUND_DOWN);
+        MallMemberAmount mallMemberAmountLogin = mallMemberAmountMapper.selectByMemberId(loginMember.getId());
+        MallMemberAmount mallMemberAmount = mallMemberAmountMapper.selectByMemberId(mallMember.getId());
+        if(1 == type){
+            if (amount.compareTo(mallMemberAmountLogin.getFcmCntAva()) > 0) {
+                throw new FebsException("代币不足");
+            }
+            mallMemberAmountLogin.setFcmCntAva(mallMemberAmountLogin.getFcmCntAva().subtract(amount));
+            mallMemberAmountMapper.updateFcmCntAvaById(mallMemberAmountLogin);
+            String orderNo = MallUtils.getOrderNum("DB");
+            mallMoneyFlowService.addMoneyFlow(
+                    loginMember.getId(),
+                    amount.negate(),
+                    MoneyFlowTypeNewEnum.FCM_INSIDE_OUT.getValue(),
+                    orderNo,
+                    mallMember.getId(),
+                    FlowTypeNewEnum.FCM_COIN.getValue(),
+                    MoneyFlowTypeNewEnum.FCM_INSIDE_OUT.getDescrition());
+            mallMemberAmount.setFcmCntAva(mallMemberAmount.getFcmCntAva().add(amount));
+            mallMemberAmountMapper.updateFcmCntAvaById(mallMemberAmount);
+            mallMoneyFlowService.addMoneyFlow(
+                    mallMember.getId(),
+                    amount,
+                    MoneyFlowTypeNewEnum.FCM_INSIDE_IN.getValue(),
+                    orderNo,
+                    loginMember.getId(),
+                    FlowTypeNewEnum.FCM_COIN.getValue(),
+                    MoneyFlowTypeNewEnum.FCM_INSIDE_IN.getDescrition());
+        }
+        if(2 == type){
+            if (amount.compareTo(mallMemberAmountLogin.getTokenAva()) > 0) {
+                throw new FebsException("令牌不足");
+            }
+            mallMemberAmountLogin.setTokenAva(mallMemberAmountLogin.getTokenAva().subtract(amount));
+            mallMemberAmountMapper.updateTokenAvaById(mallMemberAmountLogin);
+            String orderNo = MallUtils.getOrderNum("LP");
+            mallMoneyFlowService.addMoneyFlow(
+                    loginMember.getId(),
+                    amount.negate(),
+                    MoneyFlowTypeNewEnum.TOKEN_INSIDE_OUT.getValue(),
+                    orderNo,
+                    mallMember.getId(),
+                    FlowTypeNewEnum.TOKEN.getValue(),
+                    MoneyFlowTypeNewEnum.TOKEN_INSIDE_OUT.getDescrition());
+            mallMemberAmount.setTokenAva(mallMemberAmount.getTokenAva().add(amount));
+            mallMemberAmountMapper.updateTokenAvaById(mallMemberAmount);
+            mallMoneyFlowService.addMoneyFlow(
+                    mallMember.getId(),
+                    amount,
+                    MoneyFlowTypeNewEnum.TOKEN_INSIDE_IN.getValue(),
+                    orderNo,
+                    loginMember.getId(),
+                    FlowTypeNewEnum.TOKEN.getValue(),
+                    MoneyFlowTypeNewEnum.TOKEN_INSIDE_IN.getDescrition());
+        }
     }
 
     @Override
@@ -655,7 +686,7 @@
         String pwd = SecureUtil.md5(forgetPwdDto.getPassword());
         mallMember.setPassword(pwd);
         this.baseMapper.updateById(mallMember);
-        return new FebsResponse().success().message("重置成功");
+        return new FebsResponse().success().message("操作成功");
     }
 
     @Override
@@ -672,6 +703,99 @@
         return new FebsResponse().success().data(key);
     }
 
+    @Override
+    public FebsResponse getPayment() {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        MallMemberPayment mallMemberPayment = mallMemberPaymentMapper.selectByMemberId(memberId);
+        MallMemberPaymentVo mallMemberPaymentVo = MallMemberPaymentConversion.INSTANCE.entityToVo(mallMemberPayment);
+        return new FebsResponse().success().data(mallMemberPaymentVo);
+    }
+
+    @Override
+    public FebsResponse getKey(GetKeyDto getKeyDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        MallMember mallMember = this.baseMapper.selectById(memberId);
+        String md5Pwd = SecureUtil.md5(getKeyDto.getPassword());
+        String md5TraPwd = SecureUtil.md5(getKeyDto.getTradePassword());
+        if(!mallMember.getPassword().equals(md5Pwd)){
+            throw new FebsException("登录密码错误");
+        }
+        if(!mallMember.getTradePassword().equals(md5TraPwd)){
+            throw new FebsException("交易密码错误");
+        }
+        return new FebsResponse().success().data(mallMember.getUserKey());
+    }
+
+    @Override
+    public FebsResponse updatePayment(UpdatePaymentDto updatePaymentDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+
+        MallMemberPayment mallMemberPayment = mallMemberPaymentMapper.selectByMemberId(memberId);
+        mallMemberPayment.setWxQrcode(updatePaymentDto.getWxQrcode());
+        mallMemberPayment.setAliQrcode(updatePaymentDto.getAliQrcode());
+        mallMemberPayment.setBankName(updatePaymentDto.getBankName());
+        mallMemberPayment.setBankNo(updatePaymentDto.getBankNo());
+        mallMemberPayment.setBank(updatePaymentDto.getBank());
+        mallMemberPayment.setPhone(updatePaymentDto.getPhone());
+        mallMemberPayment.setUsdtTongdao(updatePaymentDto.getUsdtTongdao());
+        mallMemberPayment.setUsdtAddress(updatePaymentDto.getUsdtAddress());
+        mallMemberPaymentMapper.updateById(mallMemberPayment);
+
+        return new FebsResponse().success().message("操作成功");
+    }
+
+    @Override
+    public FebsResponse unfreeze(UnfreezeDto unfreezeDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        /**
+         * 判断账号是否冻结
+         * 判断账号FCM代币是否足够
+         *  1、自行解冻:扣除对应的FCM代币
+         *  2、上级解冻:查询是否是解冻用户的直接上级,扣除对应的FCM代币
+         * 更新账号状态
+         * 生成流水记录
+         */
+        Long unfreezeMemberId = unfreezeDto.getMemberId();
+        MallMember mallMember = this.baseMapper.selectById(unfreezeMemberId);
+        Integer isFrozen = mallMember.getIsFrozen();
+        if(1 != isFrozen){
+            throw new FebsException("账户未被冻结");
+        }
+        DataDictionaryCustom memberFrozenFcmCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.MEMBER_FROZEN_FCM_CNT.getType(),
+                DataDictionaryEnum.MEMBER_FROZEN_FCM_CNT.getCode()
+        );
+        BigDecimal memberFrozenFcmCnt = new BigDecimal(memberFrozenFcmCntDic.getValue());
+        MallMemberAmount mallMemberAmount = mallMemberAmountMapper.selectByMemberId(unfreezeMemberId);
+        BigDecimal fcmCntAva = mallMemberAmount.getFcmCntAva();
+        if(memberFrozenFcmCnt.compareTo(fcmCntAva) > 0){
+            throw new FebsException("解除冻结需要FCM的数量为:" + fcmCntAva);
+        }
+        if(2 == unfreezeDto.getType()){
+            List<MallMember> mallMembers = this.baseMapper.selectByRefererId(mallMember.getInviteId());
+            List<Long> collectMemberIds = mallMembers.stream().map(MallMember::getId).collect(Collectors.toList());
+            if(!collectMemberIds.contains(unfreezeMemberId)){
+                throw new FebsException("直接推荐人才能解除账户的冻结状态");
+            }
+        }
+        BigDecimal fcmCntAvaSub = fcmCntAva.subtract(memberFrozenFcmCnt);
+        mallMemberAmount.setFcmCntAva(fcmCntAvaSub);
+        mallMemberAmountMapper.updateById(mallMemberAmount);
+        mallMember.setIsFrozen(0);
+        this.baseMapper.updateById(mallMember);
+
+        mallMoneyFlowService.addMoneyFlow(
+                mallMember.getId(),
+                memberFrozenFcmCnt.negate(),
+                MoneyFlowTypeNewEnum.UNFREEZE_USER.getValue(),
+                MallUtils.getOrderNum(),
+                memberId,
+                FlowTypeNewEnum.FCM_COIN.getValue(),
+                MoneyFlowTypeNewEnum.UNFREEZE_USER.getDescrition());
+
+        return new FebsResponse().success().message("操作成功");
+    }
+
     public static void main(String[] args) {
         Set<String> objectsAccount = new HashSet<>();
         Set<String> objects = new HashSet<>();
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallProductServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallProductServiceImpl.java
new file mode 100644
index 0000000..c2750fd
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallProductServiceImpl.java
@@ -0,0 +1,266 @@
+package cc.mrbird.febs.mall.service.impl;
+
+import cc.mrbird.febs.common.entity.FebsResponse;
+import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
+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.dto.ApiCreateNFTDto;
+import cc.mrbird.febs.mall.dto.ApiOutFcmDto;
+import cc.mrbird.febs.mall.dto.ApiOutNFTDto;
+import cc.mrbird.febs.mall.entity.*;
+import cc.mrbird.febs.mall.mapper.*;
+import cc.mrbird.febs.mall.service.IApiMallProductService;
+import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
+import cc.mrbird.febs.mall.vo.ApiMallProductNftVo;
+import cc.mrbird.febs.rabbit.producter.AgentProducer;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ApiMallProductServiceImpl extends ServiceImpl<MallProductNftMapper, MallProductNft> implements IApiMallProductService {
+
+    private final MallMemberMapper memberMapper;
+    private final MallProductBuyMapper mallProductBuyMapper;
+    private final MallMemberAmountMapper mallMemberAmountMapper;
+    private final IMallMoneyFlowService iMallMoneyFlowService;
+    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
+    private final AgentProducer agentProducer;
+    private final MallProductSellMapper mallProductSellMapper;
+    private final MallProductSellRecordMapper mallProductSellRecordMapper;
+
+    @Override
+    public List<ApiMallProductNftVo> productNFTList() {
+        List<ApiMallProductNftVo> list = this.baseMapper.selectByState(ProductEnum.PRODUCT_NFT_OPEN.getValue());
+        return list;
+    }
+
+    @Override
+    @Transactional
+    public FebsResponse createNFT(ApiCreateNFTDto createNFTDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        MallMember mallMember = memberMapper.selectById(memberId);
+        Long productNFTId = createNFTDto.getId();
+        String tradePassword = SecureUtil.md5(createNFTDto.getTradePassword());
+        /**
+         * 预约,验证交易密码、预约产品是否开启状态、该产品是否已经预约、token是否足够
+         * 冻结对应的令牌数量、生成预约记录、生成流水记录
+         */
+        if(!tradePassword.equals(mallMember.getTradePassword())){
+            throw new FebsException("请输入正确的交易密码");
+        }
+        MallProductNft mallProductNft = this.baseMapper.selectById(productNFTId);
+        if(ObjectUtil.isEmpty(mallProductNft)){
+            throw new FebsException("网络异常");
+        }
+        if(ProductEnum.PRODUCT_NFT_OPEN.getValue() != mallProductNft.getState()){
+            throw new FebsException("预约超时");
+        }
+        MallProductBuy mallProductBuy = mallProductBuyMapper.selectMemberIdAndNFTIdAndStateAndMateState(
+                memberId,productNFTId,ProductEnum.PRODUCT_BUY_ON_GOING.getValue(),null);
+        if(ObjectUtil.isNotEmpty(mallProductBuy)){
+            throw new FebsException("不可重复预约");
+        }
+
+        BigDecimal priceToken = mallProductNft.getPriceToken();
+        MallMemberAmount mallMemberAmount = mallMemberAmountMapper.selectByMemberId(memberId);
+        if(BigDecimal.ZERO.compareTo(mallMemberAmount.getTokenAva()) >= 0
+         || priceToken.compareTo(mallMemberAmount.getTokenAva()) > 0){
+            throw new FebsException("余额不足");
+        }
+        mallProductBuy = new MallProductBuy();
+        mallProductBuy.setMemberId(memberId);
+        mallProductBuy.setProductNftId(mallProductNft.getId());
+        mallProductBuy.setState(ProductEnum.PRODUCT_BUY_ON_GOING.getValue());
+        mallProductBuy.setMateState(ProductEnum.PRODUCT_MATE_STATE_ON_GOING.getValue());
+        mallProductBuy.setNftTotal(mallProductNft.getPriceNft());
+        mallProductBuy.setNftAva(BigDecimal.ZERO);
+        mallProductBuyMapper.insert(mallProductBuy);
+        //令牌 可用减少,冻结增加
+        mallMemberAmount.setTokenAva(mallMemberAmount.getTokenAva().subtract(priceToken));
+        mallMemberAmount.setTokenFrozen(mallMemberAmount.getTokenFrozen().add(priceToken));
+        mallMemberAmountMapper.updateTokenAvaAndTokenFrozenById(mallMemberAmount);
+
+        String orderNo = MallUtils.getOrderNum("YY");
+        iMallMoneyFlowService.addMoneyFlow(
+                memberId,
+                priceToken.negate(),
+                MoneyFlowTypeNewEnum.TOKEN_BUY_FROZEN.getValue(),
+                orderNo,
+                null,
+                FlowTypeNewEnum.TOKEN.getValue(),
+                MoneyFlowTypeNewEnum.TOKEN_BUY_FROZEN.getDescrition());
+        return new FebsResponse().success();
+    }
+
+    @Override
+    @Transactional
+    public FebsResponse outFcm(ApiOutFcmDto outFcmDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        MallMember mallMember = memberMapper.selectById(memberId);
+        String tradePassword = SecureUtil.md5(outFcmDto.getTradePassword());
+        /**
+         * 实时兑换FCM-to-NFT
+         * 验证账户交易密码,fcm余额
+         * 计算手续费、减少用户的fcm余额
+         * 增加流水
+         */
+        if(!tradePassword.equals(mallMember.getTradePassword())){
+            throw new FebsException("请输入正确的交易密码");
+        }
+        BigDecimal fcmCnt = outFcmDto.getFcmCnt();
+        DataDictionaryCustom outFcmMinDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.OUT_FCM_MIN.getType(),
+                DataDictionaryEnum.OUT_FCM_MIN.getCode());
+        BigDecimal outFcmMin = ObjectUtil.isEmpty(outFcmMinDic) ? new BigDecimal(100) : new BigDecimal(outFcmMinDic.getValue());
+        if(outFcmMin.compareTo(fcmCnt) > 0){
+            throw new FebsException("最少"+outFcmMin);
+        }
+        MallMemberAmount mallMemberAmount = mallMemberAmountMapper.selectByMemberId(memberId);
+        if(BigDecimal.ZERO.compareTo(mallMemberAmount.getFcmCntAva()) >= 0
+                || fcmCnt.compareTo(mallMemberAmount.getTokenAva()) > 0){
+            throw new FebsException("余额不足");
+        }
+        DataDictionaryCustom fcmPriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.FCM_PRICE.getType(),
+                DataDictionaryEnum.FCM_PRICE.getCode());
+        BigDecimal fcmPrice = ObjectUtil.isEmpty(fcmPriceDic) ? new BigDecimal(2) : new BigDecimal(fcmPriceDic.getValue());
+        //手续费
+        DataDictionaryCustom outFcmFeeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.OUT_FCM_FEE.getType(),
+                DataDictionaryEnum.OUT_FCM_FEE.getCode());
+        BigDecimal outFcmFeePercent = ObjectUtil.isEmpty(outFcmFeeDic) ? new BigDecimal(20) : new BigDecimal(outFcmFeeDic.getValue());
+        outFcmFeePercent = outFcmFeePercent.divide(new BigDecimal(100),4,BigDecimal.ROUND_DOWN);
+        BigDecimal outFcmFee = fcmCnt.multiply(outFcmFeePercent);
+        //实际到账数量
+        BigDecimal fcmCntReal = fcmCnt.subtract(outFcmFee).setScale(2, BigDecimal.ROUND_DOWN);
+
+        BigDecimal nftCnt = fcmCntReal.multiply(fcmPrice);
+
+        mallMemberAmount.setFcmCntAva(mallMemberAmount.getFcmCntAva().subtract(fcmCnt));
+        mallMemberAmountMapper.updateFcmCntAvaById(mallMemberAmount);
+        String orderNo = MallUtils.getOrderNum("DB");
+        iMallMoneyFlowService.addMoneyFlow(
+                memberId,
+                fcmCnt.negate(),
+                MoneyFlowTypeNewEnum.FCM_OUT.getValue(),
+                orderNo,
+                mallMember.getId(),
+                FlowTypeNewEnum.FCM_COIN.getValue(),
+                MoneyFlowTypeNewEnum.FCM_OUT.getDescrition());
+        iMallMoneyFlowService.addMoneyFlow(
+                memberId,
+                outFcmFee.negate(),
+                MoneyFlowTypeNewEnum.FCM_OUT_FEE.getValue(),
+                orderNo,
+                mallMember.getId(),
+                FlowTypeNewEnum.FCM_COIN.getValue(),
+                MoneyFlowTypeNewEnum.FCM_OUT_FEE.getDescrition());
+
+        mallMemberAmount.setTrendsNft(mallMemberAmount.getTrendsNft().add(nftCnt));
+        mallMemberAmountMapper.updateTrendsNftById(mallMemberAmount);
+        String orderNoNFT = MallUtils.getOrderNum("NFT");
+        iMallMoneyFlowService.addMoneyFlow(
+                memberId,
+                nftCnt,
+                MoneyFlowTypeNewEnum.NFT_IN.getValue(),
+                orderNoNFT,
+                mallMember.getId(),
+                FlowTypeNewEnum.NFT.getValue(),
+                MoneyFlowTypeNewEnum.NFT_IN.getDescrition());
+
+        agentProducer.sendFcmNFTExchangeMsg(outFcmFee.toString());
+        return new FebsResponse().success();
+    }
+
+    @Override
+    @Transactional
+    public FebsResponse outNFT(ApiOutNFTDto outNFTDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        MallMember mallMember = memberMapper.selectById(memberId);
+        String tradePassword = SecureUtil.md5(outNFTDto.getTradePassword());
+        /**
+         * 验证数量、交易密码、NFT余额
+         * 计算手续费、减少动态NFT、增加冻结NFT
+         * 增加流水
+         */
+        if(!tradePassword.equals(mallMember.getTradePassword())){
+            throw new FebsException("请输入正确的交易密码");
+        }
+        BigDecimal nftCnt = outNFTDto.getNftCnt();
+        DataDictionaryCustom nftMinDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.NFT_MIN.getType(),
+                DataDictionaryEnum.NFT_MIN.getCode());
+        BigDecimal nftMin = ObjectUtil.isEmpty(nftMinDic) ? new BigDecimal(100) : new BigDecimal(nftMinDic.getValue());
+        if(nftMin.compareTo(nftCnt) > 0){
+            throw new FebsException("最少"+nftMin);
+        }
+        MallMemberAmount mallMemberAmount = mallMemberAmountMapper.selectByMemberId(memberId);
+        if(BigDecimal.ZERO.compareTo(mallMemberAmount.getTrendsNft()) >= 0
+                || nftCnt.compareTo(mallMemberAmount.getTrendsNft()) > 0){
+            throw new FebsException("余额不足");
+        }
+        DataDictionaryCustom nftFeeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.NFT_FEE.getType(),
+                DataDictionaryEnum.NFT_FEE.getCode());
+        BigDecimal nftFeePercent = ObjectUtil.isEmpty(nftFeeDic) ? new BigDecimal(20) : new BigDecimal(nftFeeDic.getValue());
+        nftFeePercent = nftFeePercent.divide(new BigDecimal(100),4,BigDecimal.ROUND_DOWN);
+        BigDecimal nftFee = nftCnt.multiply(nftFeePercent);
+        BigDecimal nftCntAva = nftCnt.subtract(nftFee);
+
+        DataDictionaryCustom fcmPriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.FCM_PRICE.getType(),
+                DataDictionaryEnum.FCM_PRICE.getCode());
+        BigDecimal fcmPrice = ObjectUtil.isEmpty(fcmPriceDic) ? new BigDecimal(2) : new BigDecimal(fcmPriceDic.getValue());
+        BigDecimal fcmFeeCnt = nftFee.divide(fcmPrice, 2, BigDecimal.ROUND_DOWN);
+
+        MallProductSell mallProductSell = new MallProductSell();
+        mallProductSell.setMemberId(memberId);
+        mallProductSell.setNftTotal(nftCnt);
+        mallProductSell.setNftCnt(nftCntAva);
+        mallProductSell.setNftCntAva(nftCntAva);
+        mallProductSell.setNftFee(nftFee);
+        mallProductSell.setFcmFee(fcmFeeCnt);
+        mallProductSell.setState(ProductEnum.PRODUCT_SELL_ON_GOING.getValue());
+        mallProductSellMapper.insert(mallProductSell);
+
+        mallMemberAmount.setTrendsNft(mallMemberAmount.getTrendsNft().subtract(nftCnt));
+        mallMemberAmountMapper.updateTrendsNftById(mallMemberAmount);
+
+        mallMemberAmount.setFrozenNft(mallMemberAmount.getFrozenNft().add(nftCntAva));
+        mallMemberAmountMapper.updateFrozenNftById(mallMemberAmount);
+        String orderNo = MallUtils.getOrderNum("NFT");
+        iMallMoneyFlowService.addMoneyFlow(
+                memberId,
+                nftCnt.negate(),
+                MoneyFlowTypeNewEnum.NFT_OUT.getValue(),
+                orderNo,
+                mallMember.getId(),
+                FlowTypeNewEnum.NFT.getValue(),
+                MoneyFlowTypeNewEnum.NFT_OUT.getDescrition());
+        iMallMoneyFlowService.addMoneyFlow(
+                memberId,
+                nftFee.negate(),
+                MoneyFlowTypeNewEnum.NFT_OUT_FEE.getValue(),
+                orderNo,
+                mallMember.getId(),
+                FlowTypeNewEnum.NFT.getValue(),
+                MoneyFlowTypeNewEnum.NFT_OUT_FEE.getDescrition());
+
+        agentProducer.sendFcmNFTExchangeMsg(fcmFeeCnt.toString());
+        return new FebsResponse().success();
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/MallMoneyFlowServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/MallMoneyFlowServiceImpl.java
index 54e1212..ee0c8e0 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/MallMoneyFlowServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/MallMoneyFlowServiceImpl.java
@@ -49,4 +49,9 @@
     public void addMoneyFlow(Long memberId, BigDecimal amount, Integer type, String orderNo, Long rtMemberId, Integer flowType) {
         this.addMoneyFlow(memberId, amount, type, orderNo, null, null, rtMemberId, null, flowType, null);
     }
+
+    @Override
+    public void addMoneyFlow(Long memberId, BigDecimal amount, Integer type, String orderNo, Long rtMemberId, Integer flowType, String description) {
+        this.addMoneyFlow(memberId, amount, type, orderNo, description, null, rtMemberId, null, flowType, null);
+    }
 }
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 6eb4ae0..1a68d76 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,13 +2,18 @@
 
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.common.entity.QueryRequest;
+import cc.mrbird.febs.mall.conversion.MallProductNftConversion;
+import cc.mrbird.febs.mall.dto.AdminMallProductNftDto;
 import cc.mrbird.febs.mall.dto.MallNewsInfoDto;
-import cc.mrbird.febs.mall.entity.MallNewsCategory;
-import cc.mrbird.febs.mall.entity.MallNewsInfo;
+import cc.mrbird.febs.mall.entity.*;
 import cc.mrbird.febs.mall.mapper.MallNewsCategoryMapper;
 import cc.mrbird.febs.mall.mapper.MallNewsInfoMapper;
+import cc.mrbird.febs.mall.mapper.MallProductNftMapper;
 import cc.mrbird.febs.mall.service.IMallNewsInfoService;
 import cc.mrbird.febs.mall.vo.AdminMallNewsInfoVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductBuyVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductNftVo;
+import cc.mrbird.febs.mall.vo.AdminMallProductSellVo;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
@@ -31,7 +36,8 @@
 public class MallNewsInfoServiceImpl extends ServiceImpl<MallNewsInfoMapper, MallNewsInfo> implements IMallNewsInfoService {
 
     private final MallNewsCategoryMapper mallNewsCategoryMapper;
-    
+    private final MallProductNftMapper mallProductNftMapper;
+
     @Override
     public IPage<AdminMallNewsInfoVo> getNewInfoList(MallNewsInfo mallNewsInfo, QueryRequest request) {
         Page<AdminMallNewsInfoVo> page = new Page<>(request.getPageNum(), request.getPageSize());
@@ -149,4 +155,48 @@
         mallNewsCategoryMapper.deleteById(id);
         return new FebsResponse().success();
     }
+
+    @Override
+    public IPage<AdminMallProductNftVo> getProductNFTList(MallProductNft mallProductNft, QueryRequest request) {
+        Page<AdminMallProductNftVo> page = new Page<>(request.getPageNum(), request.getPageSize());
+        IPage<AdminMallProductNftVo> adminMallNewsInfoVoIPage = mallProductNftMapper.getProductNFTList(page, mallProductNft);
+        return adminMallNewsInfoVoIPage;
+    }
+
+    @Override
+    public FebsResponse addProductNFT(AdminMallProductNftDto adminMallProductNftDto) {
+        MallProductNft mallProductNft = MallProductNftConversion.INSTANCE.dtoToEntity(adminMallProductNftDto);
+        mallProductNftMapper.insert(mallProductNft);
+        return new FebsResponse().success();
+    }
+
+    @Override
+    public FebsResponse delNFT(Long id) {
+        MallProductNft mallProductNft = mallProductNftMapper.selectById(id);
+        if(ObjectUtil.isEmpty(mallProductNft)){
+            return new FebsResponse().fail().message("系统繁忙,请刷新页面重试");
+        }
+        mallProductNftMapper.deleteById(id);
+        return new FebsResponse().success();
+    }
+
+    @Override
+    public FebsResponse nftInfoUpdate(MallProductNft mallProductNft) {
+        mallProductNftMapper.updateById(mallProductNft);
+        return new FebsResponse().success();
+    }
+
+    @Override
+    public IPage<AdminMallProductBuyVo> getBuyList(MallProductBuy mallProductBuy, QueryRequest request) {
+        Page<AdminMallProductBuyVo> page = new Page<>(request.getPageNum(), request.getPageSize());
+        IPage<AdminMallProductBuyVo> adminMallProductBuyVoIPage = mallProductNftMapper.getBuyList(page, mallProductBuy);
+        return adminMallProductBuyVoIPage;
+    }
+
+    @Override
+    public IPage<AdminMallProductSellVo> getSellList(MallProductSell mallProductSell, QueryRequest request) {
+        Page<AdminMallProductSellVo> page = new Page<>(request.getPageNum(), request.getPageSize());
+        IPage<AdminMallProductSellVo> adminMallProductSellVoIPage = mallProductNftMapper.getSellList(page, mallProductSell);
+        return adminMallProductSellVoIPage;
+    }
 }
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 e035f39..e061508 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
@@ -59,6 +59,7 @@
     private final MallScoreRecordMapper mallScoreRecordMapper;
     private final MallScoreAchieveReleaseMapper mallScoreAchieveReleaseMapper;
     private final MallScoreVoucherMapper mallScoreVoucherMapper;
+    private final CommonService commonService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -1106,6 +1107,67 @@
         }
     }
 
+    @Override
+    public void fcmNFTExchangeMsg(String cnt) {
+        //销毁数量
+        BigDecimal destoryCnt = new BigDecimal(cnt);
+        DataDictionaryCustom fcmDestoryCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                DataDictionaryEnum.FCM_DESTORY_CNT.getType(),
+                DataDictionaryEnum.FCM_DESTORY_CNT.getCode()
+        );
+        BigDecimal fcmDestoryCnt = new BigDecimal(fcmDestoryCntDic.getValue());
+
+        BigDecimal fcmDestoryCntAdd = fcmDestoryCnt.add(destoryCnt);
+         /**
+         * 每次销毁10000个,价格增加0.1
+          * 满足的次数 divide
+         */
+        BigDecimal divide = fcmDestoryCntAdd.divide(AppContants.FCM_BASIC, 0, BigDecimal.ROUND_DOWN);
+        if(BigDecimal.ZERO.compareTo(divide) == 0){
+            commonService.updateDataDic(
+                    DataDictionaryEnum.BANK_TRANS_URL.getType(),
+                    DataDictionaryEnum.BANK_TRANS_URL.getCode(),
+                    fcmDestoryCntAdd.toString());
+        }
+
+        if(BigDecimal.ZERO.compareTo(divide) < 0){
+            //例:累计15000 去掉10000,累计只剩5000
+            BigDecimal fcmDestoryCntReal = fcmDestoryCntAdd.subtract(divide.multiply(AppContants.FCM_BASIC));
+            commonService.updateDataDic(
+                    DataDictionaryEnum.FCM_DESTORY_CNT.getType(),
+                    DataDictionaryEnum.FCM_DESTORY_CNT.getCode(),
+                    fcmDestoryCntReal.toString());
+
+            //更新总销毁数量
+            DataDictionaryCustom fcmDestoryTotalDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                    DataDictionaryEnum.FCM_DESTORY_TOTAL.getType(),
+                    DataDictionaryEnum.FCM_DESTORY_TOTAL.getCode()
+            );
+            BigDecimal fcmDestoryTotal = new BigDecimal(fcmDestoryTotalDic.getValue());
+            fcmDestoryTotal = fcmDestoryTotal.add(destoryCnt);
+            commonService.updateDataDic(
+                    DataDictionaryEnum.FCM_DESTORY_TOTAL.getType(),
+                    DataDictionaryEnum.FCM_DESTORY_TOTAL.getCode(),
+                    fcmDestoryTotal.toString());
+            //更新价格
+            DataDictionaryCustom fcmPriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                    DataDictionaryEnum.FCM_PRICE.getType(),
+                    DataDictionaryEnum.FCM_PRICE.getCode()
+            );
+            BigDecimal fcmPrice = new BigDecimal(fcmPriceDic.getValue());
+            fcmPrice = fcmPrice.add(AppContants.FCM_BASIC_ADD_PRICE.multiply(divide));
+            commonService.updateDataDic(
+                    DataDictionaryEnum.FCM_PRICE.getType(),
+                    DataDictionaryEnum.FCM_PRICE.getCode(),
+                    fcmPrice.toString());
+        }
+    }
+
+    public static void main(String[] args) {
+        BigDecimal divide = new BigDecimal(12000).divide(new BigDecimal(10000), 0, BigDecimal.ROUND_DOWN);
+        System.out.println(divide);
+    }
+
     /**
      * 给用户的增加凭证数据,并且增加流水
      * @param memberAchieveRelease 释放数量
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java
new file mode 100644
index 0000000..93894be
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductBuyVo.java
@@ -0,0 +1,24 @@
+package cc.mrbird.febs.mall.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@ApiModel(value = "AdminMallProductBuyVo", description = "信息返回类")
+public class AdminMallProductBuyVo {
+
+    private Long id;
+    private String accountLogin;//登录账户
+    private Long memberId;//
+    private Long sellId;//出售ID
+    private Long productNftId;//预约NFT编码
+    private int state;//预约状态  0:失败 1:进行中 2:超时  3:已完成
+    private int mateState;//匹配状态0:失败 1:匹配中 2:待支付 3:已支付 4:对方已确认 5:已完成
+    private BigDecimal nftTotal;//nft预约额度
+    private BigDecimal nftAva;//nft分配额度
+    private Date orderTime;//匹配时间
+    private Date payTime;//支付时间
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductNftVo.java b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductNftVo.java
new file mode 100644
index 0000000..0f780e5
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductNftVo.java
@@ -0,0 +1,23 @@
+package cc.mrbird.febs.mall.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@ApiModel(value = "AdminMallProductNftVo", description = "信息返回类")
+public class AdminMallProductNftVo {
+
+    private Long id;//编码
+    private String nftCode;//编码
+    private String nftImg;//图片
+    private BigDecimal priceNft;//NFT价格
+    private BigDecimal priceToken;//TOKEN价格
+    private BigDecimal profit;//收益 5 即百分之五
+    private int cycle;//周期
+    private int state;//产品状态 1:开启 0:关闭
+    private int memberCnt;//预约人数
+    private int memberReal;//已预约人数
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductSellVo.java b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductSellVo.java
new file mode 100644
index 0000000..99a8c35
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/AdminMallProductSellVo.java
@@ -0,0 +1,20 @@
+package cc.mrbird.febs.mall.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "AdminMallProductSellVo", description = "信息返回类")
+public class AdminMallProductSellVo {
+
+    private Long id;
+    private String accountLogin;//登录账户
+    private BigDecimal nftTotal;//动态NFT总数
+    private BigDecimal nftCnt;//实际提现数量
+    private BigDecimal nftCntAva;//剩余数量
+    private BigDecimal nftFee;//NFT手续费
+    private BigDecimal fcmFee;//代币手续费
+    private Integer state;//预约状态  0:失败 1:进行中 2:超时  3:已完成
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/ApiMallProductNftVo.java b/src/main/java/cc/mrbird/febs/mall/vo/ApiMallProductNftVo.java
new file mode 100644
index 0000000..2d6309a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/ApiMallProductNftVo.java
@@ -0,0 +1,33 @@
+package cc.mrbird.febs.mall.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "ApiMallProductNftVo", description = "返回参数类")
+public class ApiMallProductNftVo {
+
+    @ApiModelProperty(value = "id")
+    private Long id;
+    @ApiModelProperty(value = "编码")
+    private String nftCode;//编码
+    @ApiModelProperty(value = "图片")
+    private String nftImg;//图片
+    @ApiModelProperty(value = "NFT价格")
+    private BigDecimal priceNft;//NFT价格
+    @ApiModelProperty(value = "TOKEN价格")
+    private BigDecimal priceToken;//TOKEN价格
+    @ApiModelProperty(value = "收益 5 即百分之五")
+    private BigDecimal profit;//收益 5 即百分之五
+    @ApiModelProperty(value = "周期")
+    private int cycle;//周期
+    @ApiModelProperty(value = "产品状态 1:开启 0:关闭")
+    private int state;//产品状态 1:开启 0:关闭
+    @ApiModelProperty(value = "预约人数")
+    private int memberCnt;//预约人数
+    @ApiModelProperty(value = "已预约人数")
+    private int memberReal;//已预约人数
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/MallMemberPaymentVo.java b/src/main/java/cc/mrbird/febs/mall/vo/MallMemberPaymentVo.java
new file mode 100644
index 0000000..473b1f4
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/MallMemberPaymentVo.java
@@ -0,0 +1,27 @@
+package cc.mrbird.febs.mall.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "MallMemberPaymentVo", description = "用户收款信息")
+public class MallMemberPaymentVo {
+
+    @ApiModelProperty(value = "微信收款码")
+    private String wxQrcode;//
+    @ApiModelProperty(value = "支付宝收款码")
+    private String aliQrcode;//
+    @ApiModelProperty(value = "真实姓名")
+    private String bankName;//
+    @ApiModelProperty(value = "银行卡号")
+    private String bankNo;//
+    @ApiModelProperty(value = "开户行")
+    private String bank;//
+    @ApiModelProperty(value = "手机号")
+    private String phone;//
+    @ApiModelProperty(value = "USDT通道类型:  TRC20 BEP20")
+    private String usdtTongdao;//
+    @ApiModelProperty(value = "USDT地址")
+    private String usdtAddress;//
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/MallMemberVo.java b/src/main/java/cc/mrbird/febs/mall/vo/MallMemberVo.java
index 20d222a..078d858 100644
--- a/src/main/java/cc/mrbird/febs/mall/vo/MallMemberVo.java
+++ b/src/main/java/cc/mrbird/febs/mall/vo/MallMemberVo.java
@@ -18,34 +18,26 @@
     @ApiModelProperty(value = "登录账号")
     private String accountLogin;
 
-    @ApiModelProperty(value = "昵称")
+    @ApiModelProperty(value = "头像")
+    private String avatar;
+
+    @ApiModelProperty(value = "用户名")
     private String name;
 
     @ApiModelProperty(value = "手机号")
     private String phone;
 
-    @ApiModelProperty(value = "邮箱")
-    private String email;
-
-    @ApiModelProperty(value = "性别")
-    private String sex;
-
     @ApiModelProperty(value = "邀请码")
     private String inviteId;
 
-    @ApiModelProperty(value = "头像")
-    private String avatar;
-
-    @ApiModelProperty(value = "余额")
-    private BigDecimal balance;
+    @ApiModelProperty(value = "代理层级")
+    private String level;
 
     @ApiModelProperty(value = "代理等级")
     private String levelName;
 
     @ApiModelProperty(value = "推荐人昵称")
     private String referrerName;
-
-    private String level;
 
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date createdTime;
@@ -57,23 +49,8 @@
     public static final int ACCOUNTSTATUS_Y = 1;
     public static final int ACCOUNTSTATUS_N = 2;
 
-    @ApiModelProperty(value = "是否设置收款方式", example = "1是2否")
+    @ApiModelProperty(value = "是否设置收款信息", example = "1是2否")
     private Integer hasPayment = 2;
-
-    @ApiModelProperty(value = "是否设置交易密码", example = "1是2否")
-    private Integer hasTradePwd = 2;
-
-    @ApiModelProperty(value = "绑定手机号")
-    private String bindPhone;
-
-    @ApiModelProperty(value = "累计消费")
-    private BigDecimal totalCost;
-
-    @ApiModelProperty(value = "赠送积分")
-    private BigDecimal score;
-
-    @ApiModelProperty(value = "抽奖积分")
-    private BigDecimal prizeScore;
 
     /**
      * 董事
@@ -87,16 +64,16 @@
     @ApiModelProperty(value = "是否店长 1-是 2-否")
     private Integer storeMaster;
 
-    @ApiModelProperty(value = "补贴额度")
-    private BigDecimal totalScore;
-
-    @ApiModelProperty(value = "贡献点")
-    private Integer star;
-
-    @ApiModelProperty(value = "凭证数量")
-    private BigDecimal voucherCnt;
-
     @ApiModelProperty(value = "内转标识 1:开启 2:关闭")
     private Integer insideWith;
+    private BigDecimal staticNft;//静态NFT
+    private BigDecimal trendsNft;//动态NFT
+    private BigDecimal frozenNft;//冻结NFT
+    private BigDecimal fcmCntAva;//FCM代币可用
+    private BigDecimal fcmCntFrozen;//FCM代币冻结
+    private BigDecimal tokenAva;//令牌可用
+    private BigDecimal tokenFrozen;//令牌冻结
+    private BigDecimal outFcmFee;//FCM提现收续费
+    private BigDecimal fcmPrice;//FCM价格
 
 }
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 458cedf..a06a328 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
@@ -17,4 +17,12 @@
     public static final String PERK_MONEY = "hlm_queue_perk_money";
 
     public static final String FORCE_VOUCHER_SALE = "hlm_queue_force_voucher_sale";
+
+    /**
+     * 预约超时队列
+     */
+    public static final String QUEUE_FCMPAY_BUY_TIME = "queue_fcm_buy_time";
+    public static final String QUEUE_FCMPAY_BUY_TIME_TTL = "queue_fcm_buy_time_ttl";
+    //fcm实时兑换
+    public static final String QUEUE_FCM_NFT_EXCHANGE = "queue_fcm_nft_exchange";
 }
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 30df9c7..bc17147 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
@@ -96,4 +96,16 @@
 
         }
     }
+
+    @RabbitListener(queues = QueueConstants.QUEUE_FCM_NFT_EXCHANGE)
+    public void fcmNFTExchangeMsg(String cnt) {
+        log.info("收到FCM实时兑换销毁数量:{}",cnt);
+        try {
+            memberProfitService.fcmNFTExchangeMsg(cnt);
+        } 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 ea6f262..60544f7 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
@@ -1,9 +1,23 @@
 package cc.mrbird.febs.rabbit.enumerates;
 
+import cc.mrbird.febs.rabbit.constants.QueueConstants;
 import lombok.Getter;
 
 @Getter
 public enum RabbitQueueEnum {
+
+    FCMPAY_FCM_NFT_EXCHANGE("exchange_fcm_nft_exchange",
+            "route_key_fcm_nft_exchange",
+            QueueConstants.QUEUE_FCM_NFT_EXCHANGE),
+    /**
+     * 机器人自动抢红包
+     */
+    FCMPAY_BUY_TIME("exchange_fcm_buy_time",
+            "route_key_fcm_buy_time",
+            QueueConstants.QUEUE_FCMPAY_BUY_TIME),
+    FCMPAY_BUY_TIME_TTL("exchange_fcm_buy_time_ttl",
+            "route_key_fcm_buy_time_ttl",
+            QueueConstants.QUEUE_FCMPAY_BUY_TIME_TTL),
 
     DEFAULT("hlm_exchange_default",
             "hlm_route_key_default",
@@ -32,6 +46,8 @@
             "hlm_route_key_force_voucher_sale",
             "hlm_queue_force_voucher_sale");
 
+
+
     private String exchange;
 
     private String route;
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 e44c1a2..76f593c 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
@@ -63,6 +63,32 @@
     }
 
     /**
+     * 匹配成功,有一个倒计时,超时后
+     * 匹配成功2小时内不打款或收到款不确认的自动冻结帐户,但可以登陆,
+     * 会员解封号自己可以解冻或找上级解冻帐户,解冻需要消毁相应代币FCM,
+     * 封号期间该帐户不产生团队奖金。
+     * 中途如有问题可以点申诉,留言与客服交流窗口,后台可以核实和查询
+     * @param id
+     * @param times
+     */
+    public void sendFcmPayBuyTimeTTLMsg(Long id, Long times) {
+        rabbitTemplate.convertAndSend(RabbitQueueEnum.FCMPAY_BUY_TIME_TTL.getExchange(),
+                RabbitQueueEnum.FCMPAY_BUY_TIME_TTL.getRoute(),
+                id, new MessagePostProcessor() {
+            @Override
+            public Message postProcessMessage(Message message) throws AmqpException {
+                message.getMessageProperties().setExpiration(String.valueOf(times));
+                return message;
+            }
+        });
+    }
+
+    public void sendFcmNFTExchangeMsg(String value) {
+        log.info("发送FCM实时兑换销毁数量:{}",value);
+        rabbitTemplate.convertAndSend(RabbitQueueEnum.FCMPAY_FCM_NFT_EXCHANGE.getExchange(), RabbitQueueEnum.FCMPAY_FCM_NFT_EXCHANGE.getRoute(),value);
+    }
+
+    /**
      * 发送代理自动升级消息
      *
      * @param memberId
diff --git a/src/main/resources/mapper/modules/MallMemberAmountMapper.xml b/src/main/resources/mapper/modules/MallMemberAmountMapper.xml
index 30f21f8..86f5f15 100644
--- a/src/main/resources/mapper/modules/MallMemberAmountMapper.xml
+++ b/src/main/resources/mapper/modules/MallMemberAmountMapper.xml
@@ -2,4 +2,44 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="cc.mrbird.febs.mall.mapper.MallMemberAmountMapper">
 
+    <select id="selectByMemberId" resultType="cc.mrbird.febs.mall.entity.MallMemberAmount">
+        select * from mall_member_amount where member_id = #{memberId}
+    </select>
+
+    <update id="updateFcmCntAvaById">
+        update mall_member_amount
+        set revision = revision + 1,
+            fcm_cnt_ava = #{record.fcmCntAva}
+        where id = #{record.id} and revision=#{record.revision}
+    </update>
+
+    <update id="updateTokenAvaById">
+        update mall_member_amount
+        set revision = revision + 1,
+            token_ava = #{record.tokenAva}
+        where id = #{record.id} and revision=#{record.revision}
+    </update>
+
+    <update id="updateTokenAvaAndTokenFrozenById">
+        update mall_member_amount
+        set revision = revision + 1,
+            token_ava = #{record.tokenAva},
+            token_frozen = #{record.tokenFrozen}
+        where id = #{record.id} and revision=#{record.revision}
+    </update>
+
+    <update id="updateTrendsNftById">
+        update mall_member_amount
+        set revision = revision + 1,
+            trends_nft = #{record.trendsNft}
+        where id = #{record.id} and revision=#{record.revision}
+    </update>
+
+    <update id="updateFrozenNftById">
+        update mall_member_amount
+        set revision = revision + 1,
+            frozen_nft = #{record.frozenNft}
+        where id = #{record.id} and revision=#{record.revision}
+    </update>
+
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/MallProductBuyMapper.xml b/src/main/resources/mapper/modules/MallProductBuyMapper.xml
new file mode 100644
index 0000000..25a8ecf
--- /dev/null
+++ b/src/main/resources/mapper/modules/MallProductBuyMapper.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cc.mrbird.febs.mall.mapper.MallProductNftMapper">
+
+    <select id="getProductNFTList" resultType="cc.mrbird.febs.mall.vo.AdminMallProductNftVo">
+        SELECT
+            a.*
+        FROM mall_product_nft a
+        order by a.CREATED_TIME desc
+    </select>
+
+    <select id="selectByState" resultType="cc.mrbird.febs.mall.vo.ApiMallProductNftVo">
+        SELECT
+            a.*
+        FROM mall_product_nft a
+        where a.state = #{state}
+    </select>
+
+    <select id="getBuyList" resultType="cc.mrbird.febs.mall.vo.AdminMallProductBuyVo">
+        SELECT
+            a.*,
+               b.account_login
+        FROM mall_product_buy a
+        left join mall_member b on a.member_id = b.id
+        order by a.CREATED_TIME desc
+    </select>
+
+    <select id="getSellList" resultType="cc.mrbird.febs.mall.vo.AdminMallProductSellVo">
+        SELECT
+            a.*,
+               b.account_login
+        FROM mall_product_sell a
+        left join mall_member b on a.member_id = b.id
+        order by a.CREATED_TIME desc
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/MallProductNftMapper.xml b/src/main/resources/mapper/modules/MallProductNftMapper.xml
new file mode 100644
index 0000000..7a702a3
--- /dev/null
+++ b/src/main/resources/mapper/modules/MallProductNftMapper.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cc.mrbird.febs.mall.mapper.MallProductBuyMapper">
+
+    <select id="selectMemberIdAndNFTIdAndStateAndMateState" resultType="cc.mrbird.febs.mall.entity.MallProductBuy">
+        select * from mall_product_buy
+        <where>
+            member_id = #{memberId}
+            and product_nft_id = #{productNFTId}
+            <if test="state != null">
+                and state = #{state}
+            </if>
+            <if test="mateState != null">
+                and mate_state = #{mateState}
+            </if>
+        </where>
+    </select>
+
+</mapper>
\ 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
new file mode 100644
index 0000000..8001b1f
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/productBuyList.html
@@ -0,0 +1,191 @@
+<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-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'}"></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>
+<!-- 表格操作栏 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>
+<!-- 表格操作栏 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'),
+            $add = $view.find('#add'),
+            $reset = $view.find('#reset'),
+            $searchForm = $view.find('form'),
+            sortObject = {field: 'phone', type: null},
+            tableIns;
+
+        form.render();
+
+        // 表格初始化
+        initBuyTable();
+
+        // 初始化表格操作栏各个按钮功能
+        table.on('tool(buyTable)', function (obj) {
+            var data = obj.data,
+                layEvent = obj.event;
+            if (layEvent === 'productNFTUpdate') {
+                febs.modal.open('编辑', 'modules/news/productNFTUpdate/' + data.id, {
+                    btn: ['提交', '取消'],
+                    yes: function (index, layero) {
+                        $('#nftInfo-update').find('#submit').trigger('click');
+                    },
+                    btn2: function () {
+                        layer.closeAll();
+                    }
+                });
+            }
+            if (layEvent === 'delNFT') {
+                febs.modal.confirm('删除', '确认删除?', function () {
+                    delNFT(data.id);
+                });
+            }
+        });
+
+        function delNFT(id) {
+            febs.get(ctx + 'admin/news/delNFT/' + id, null, function () {
+                febs.alert.success('操作成功');
+                $query.click();
+            });
+        }
+
+        // 查询按钮
+        $query.on('click', function () {
+            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
+            tableIns.reload({where: params, page: {curr: 1}});
+        });
+
+        // 刷新按钮
+        $reset.on('click', function () {
+            $searchForm[0].reset();
+            sortObject.type = 'null';
+            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
+        });
+
+        $add.on('click', function () {
+            febs.modal.open('新增', 'modules/news/productNFTAdd/', {
+                btn: ['提交', '取消'],
+                yes: function (index, layero) {
+                    $('#productNFT-add').find('#submit').trigger('click');
+                },
+                btn2: function () {
+                    layer.closeAll();
+                }
+            });
+        });
+
+        function initBuyTable() {
+            tableIns = febs.table.init({
+                elem: $view.find('table'),
+                id: '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 ''
+                        }else{
+                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="productNFTUpdate" shiro:hasPermission="user:update">编辑</button>'
+                                +'<button class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delNFT" shiro:hasPermission="user:update">删除</button>'
+                        }
+                        },minWidth: 300,align:'center'}
+                ]]
+            });
+        }
+
+        // 获取查询参数
+        function getQueryParams() {
+            return {
+            };
+        }
+
+        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/productNFTAdd.html b/src/main/resources/templates/febs/views/modules/news/productNFTAdd.html
new file mode 100644
index 0000000..6aa481d
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/productNFTAdd.html
@@ -0,0 +1,158 @@
+<style>
+    #productNFT-add {
+        padding: 20px 25px 25px 0;
+    }
+
+    #productNFT-add .layui-treeSelect .ztree li a, .ztree li span {
+        margin: 0 0 2px 3px !important;
+    }
+    #productNFT-add #data-permission-tree-block {
+        border: 1px solid #eee;
+        border-radius: 2px;
+        padding: 3px 0;
+    }
+    #productNFT-add .layui-treeSelect .ztree li span.button.switch {
+        top: 1px;
+        left: 3px;
+    }
+    #productNFT-add img{
+        max-width:100px
+    }
+
+</style>
+<div class="layui-fluid" id="productNFT-add">
+    <form class="layui-form" action="" lay-filter="productNFT-add-form">
+        <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="nftCode" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </div>
+            </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">NFT:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="priceNft" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                    <div class="layui-form-mid layui-word-aux">需要NFT数量</div>
+                </div>
+            </div>
+            <div class="layui-col-lg6">
+                <label class="layui-form-label febs-form-item-require">TOKEN:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="priceToken" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                    <div class="layui-form-mid layui-word-aux">需要token数量</div>
+                </div>
+            </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="profit" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                    <div class="layui-form-mid layui-word-aux"> 5 即百分之五</div>
+                </div>
+            </div>
+            <div class="layui-col-lg6">
+                <label class="layui-form-label febs-form-item-require">周期:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="cycle" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </div>
+            </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="memberCnt" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </div>
+            </div>
+            <div class="layui-col-lg6">
+                <label class="layui-form-label febs-form-item-require">已预约数:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="memberReal" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </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="nftImgUpload">上传</button>
+                    <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
+                        <div class="layui-upload-list" id="nftImgImage"></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="state" value="1" title="开启" />
+                    <input type="radio" name="state" value="0" title="关闭" checked />
+                </div>
+            </div>
+        </div>
+        <div class="layui-form-item febs-hide">
+            <button class="layui-btn" lay-submit="" lay-filter="productNFT-add-form-submit" id="submit"></button>
+        </div>
+    </form>
+</div>
+
+<script data-th-inline="javascript">
+    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','layedit', 'laydate', 'upload'], function () {
+        var $ = layui.$,
+            febs = layui.febs,
+            layer = layui.layer,
+            upload = layui.upload,
+            formSelects = layui.formSelects,
+            form = layui.form,
+            laydate = layui.laydate,
+            layedit = layui.layedit,
+            $view = $('#productNFT-add'),
+            validate = layui.validate;
+
+
+        form.render();
+        laydate.render({
+            elem: '#febs-form-group-date'
+        });
+
+        layedit.set({	//设置图片接口
+            uploadImage: {
+                url: 'admin/goods/uploadFileBase64', //接口url
+                type: 'post',
+            }
+        });
+        form.on('submit(productNFT-add-form-submit)', function (data) {
+            febs.post(ctx + 'admin/news/addProductNFT', data.field, function () {
+                layer.closeAll();
+                febs.alert.success('操作成功');
+                $('#febs-nft').find('#reset').click();
+            });
+            return false;
+        });
+
+        upload.render({
+            elem: '#nftImgUpload'
+            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
+            ,multiple: false
+            ,before: function(obj){
+                //预读本地文件示例,不支持ie8
+                obj.preview(function(index, file, result){
+                    $('#nftImgImage').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img" style="width: 100px">')
+                });
+            }
+            ,done: function(res){
+                $("#nftImg").val(res.data.src);
+            }
+        });
+
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/febs/views/modules/news/productNFTList.html b/src/main/resources/templates/febs/views/modules/news/productNFTList.html
new file mode 100644
index 0000000..40f8c83
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/productNFTList.html
@@ -0,0 +1,176 @@
+<div class="layui-fluid layui-anim febs-anim" id="febs-nft" 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-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="NFTInfoTable" lay-data="{id: 'NFTInfoTable'}"></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="isState">
+    {{# if(d.state === 1) { }}
+    <input type="checkbox" value={{d.id}} lay-text="开启|关闭" checked lay-skin="switch" lay-filter="isState">
+    {{# } else { }}
+    <input type="checkbox" value={{d.id}} lay-text="开启|关闭" lay-skin="switch" lay-filter="isState">
+    {{# } }}
+</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>
+<!-- 表格操作栏 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-nft'),
+            $query = $view.find('#query'),
+            $add = $view.find('#add'),
+            $reset = $view.find('#reset'),
+            $searchForm = $view.find('form'),
+            sortObject = {field: 'phone', type: null},
+            tableIns;
+
+        form.render();
+
+        // 表格初始化
+        initTable();
+
+        // 初始化表格操作栏各个按钮功能
+        table.on('tool(NFTInfoTable)', function (obj) {
+            var data = obj.data,
+                layEvent = obj.event;
+            if (layEvent === 'productNFTUpdate') {
+                febs.modal.open('编辑', 'modules/news/productNFTUpdate/' + data.id, {
+                    btn: ['提交', '取消'],
+                    yes: function (index, layero) {
+                        $('#nftInfo-update').find('#submit').trigger('click');
+                    },
+                    btn2: function () {
+                        layer.closeAll();
+                    }
+                });
+            }
+            if (layEvent === 'delNFT') {
+                febs.modal.confirm('删除', '确认删除?', function () {
+                    delNFT(data.id);
+                });
+            }
+        });
+
+        function delNFT(id) {
+            febs.get(ctx + 'admin/news/delNFT/' + id, null, function () {
+                febs.alert.success('操作成功');
+                $query.click();
+            });
+        }
+
+        // 查询按钮
+        $query.on('click', function () {
+            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
+            tableIns.reload({where: params, page: {curr: 1}});
+        });
+
+        // 刷新按钮
+        $reset.on('click', function () {
+            $searchForm[0].reset();
+            sortObject.type = 'null';
+            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
+        });
+
+        $add.on('click', function () {
+            febs.modal.open('新增', 'modules/news/productNFTAdd/', {
+                btn: ['提交', '取消'],
+                yes: function (index, layero) {
+                    $('#productNFT-add').find('#submit').trigger('click');
+                },
+                btn2: function () {
+                    layer.closeAll();
+                }
+            });
+        });
+
+        function initTable() {
+            tableIns = febs.table.init({
+                elem: $view.find('table'),
+                id: 'NFTInfoTable',
+                url: ctx + 'admin/news/getProductNFTList',
+                cols: [[
+                    {field: 'nftCode', title: '编码', minWidth: 120,align:'center'},
+                    {field: 'priceNft', title: 'NFT', minWidth: 120,align:'center'},
+                    {field: 'priceToken', title: 'TOKEN', minWidth: 120,align:'center'},
+                    {field: 'profit', title: '收益(%)', minWidth: 120,align:'center'},
+                    {field: 'cycle', title: '周期(天)', minWidth: 120,align:'center'},
+                    {field: 'memberCnt', title: '预约总数', minWidth: 120,align:'center'},
+                    {field: 'memberReal', title: '已预约数', minWidth: 120,align:'center'},
+                    {field: 'nftImg', title: '缩略图',
+                        templet: function (d) {
+                            return '<img src="'+d.nftImg+'" >';
+                        }, minWidth: 150,align:'center'},
+                    {templet: '#isState', title: '产品状态', minWidth: 120,align:'center'},
+                    {title: '操作',
+                        templet: function (d) {
+                        if(d.state == 1){
+                            return ''
+                        }else{
+                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="productNFTUpdate" shiro:hasPermission="user:update">编辑</button>'
+                                +'<button class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delNFT" shiro:hasPermission="user:update">删除</button>'
+                        }
+                        },minWidth: 300,align:'center'}
+                ]]
+            });
+        }
+
+        // 获取查询参数
+        function getQueryParams() {
+            return {
+            };
+        }
+
+        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/productNFTUpdate.html b/src/main/resources/templates/febs/views/modules/news/productNFTUpdate.html
new file mode 100644
index 0000000..58d84e9
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/productNFTUpdate.html
@@ -0,0 +1,184 @@
+<style>
+    #nftInfo-update {
+        padding: 20px 25px 25px 0;
+    }
+
+    #nftInfo-update .layui-treeSelect .ztree li a, .ztree li span {
+        margin: 0 0 2px 3px !important;
+    }
+    #nftInfo-update #data-permission-tree-block {
+        border: 1px solid #eee;
+        border-radius: 2px;
+        padding: 3px 0;
+    }
+    #nftInfo-update .layui-treeSelect .ztree li span.button.switch {
+        top: 1px;
+        left: 3px;
+    }
+    #nftInfo-update img{
+        max-width:100px
+    }
+
+</style>
+<div class="layui-fluid" id="nftInfo-update">
+    <form class="layui-form" action="" lay-filter="nftInfo-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="nftCode" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </div>
+            </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">NFT:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="priceNft" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                    <div class="layui-form-mid layui-word-aux">需要NFT数量</div>
+                </div>
+            </div>
+            <div class="layui-col-lg6">
+                <label class="layui-form-label febs-form-item-require">TOKEN:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="priceToken" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                    <div class="layui-form-mid layui-word-aux">需要token数量</div>
+                </div>
+            </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="profit" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                    <div class="layui-form-mid layui-word-aux"> 5 即百分之五</div>
+                </div>
+            </div>
+            <div class="layui-col-lg6">
+                <label class="layui-form-label febs-form-item-require">周期:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="cycle" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </div>
+            </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="memberCnt" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </div>
+            </div>
+            <div class="layui-col-lg6">
+                <label class="layui-form-label febs-form-item-require">已预约数:</label>
+                <div class="layui-input-block">
+                    <input type="text" name="memberReal" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
+                </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="nftImgUpload">上传</button>
+                    <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
+                        <div class="layui-upload-list" id="nftImgImage"></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="state" value="1" title="开启" />
+                    <input type="radio" name="state" value="0" title="关闭" checked />
+                </div>
+            </div>
+        </div>
+        <div class="layui-form-item febs-hide">
+            <button class="layui-btn" lay-submit="" lay-filter="nftInfo-update-form-submit" id="submit"></button>
+        </div>
+    </form>
+</div>
+
+<script data-th-inline="javascript">
+    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','layedit', 'laydate', 'upload'], function () {
+        var $ = layui.$,
+            febs = layui.febs,
+            layer = layui.layer,
+            upload = layui.upload,
+            formSelects = layui.formSelects,
+            form = layui.form,
+            laydate = layui.laydate,
+            layedit = layui.layedit,
+            mallProductNft = [[${mallProductNft}]],
+            $view = $('#nftInfo-update'),
+            $uploadDel = $view.find('#uploadDel'),
+            validate = layui.validate;
+
+        form.render();
+        initUserValue();
+        laydate.render({
+            elem: '#febs-form-group-date'
+        });
+
+
+        layedit.set({	//设置图片接口
+            uploadImage: {
+                url: 'admin/goods/uploadFileBase64', //接口url
+                type: 'post',
+            }
+        });
+
+        form.on('submit(nftInfo-update-form-submit)', function (data) {
+            febs.post(ctx + 'admin/news/nftInfoUpdate', data.field, function () {
+                layer.closeAll();
+                febs.alert.success('操作成功');
+                $('#febs-nft').find('#reset').click();
+            });
+            return false;
+        });
+
+        upload.render({
+            elem: '#nftImgUpload'
+            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
+            ,multiple: false
+            ,before: function(obj){
+                //预读本地文件示例,不支持ie8
+                obj.preview(function(index, file, result){
+                    $('#nftImgImage').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img" style="width: 100px">')
+                });
+            }
+            ,done: function(res){
+                $("#nftImg").val(res.data.src);
+            }
+        });
+
+        function initUserValue() {
+            var nftImg = mallProductNft.nftImg;
+            $('#nftImgImage').html('<img src="' + nftImg + '" alt="" class="layui-upload-img new-image" style="width: 100px">')
+            form.val("nftInfo-update-form", {
+                "id": mallProductNft.id,
+                "nftCode": mallProductNft.nftCode,
+                "nftImg": mallProductNft.nftImg,
+                "priceNft": mallProductNft.priceNft,
+                "priceToken": mallProductNft.priceToken,
+                "profit": mallProductNft.profit,
+                "cycle": mallProductNft.cycle,
+                "state": mallProductNft.state,
+                "memberCnt": mallProductNft.memberCnt,
+                "memberReal": mallProductNft.memberReal,
+            });
+        }
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/febs/views/modules/news/productSellList.html b/src/main/resources/templates/febs/views/modules/news/productSellList.html
new file mode 100644
index 0000000..e3ad58d
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/news/productSellList.html
@@ -0,0 +1,162 @@
+<div class="layui-fluid layui-anim febs-anim" id="febs-product-sell" lay-title="NFT提现记录">
+    <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-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="sellTable" lay-data="{id: 'sellTable'}"></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="isSellState">
+    {{# 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>
+<!-- 表格操作栏 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>
+<!-- 表格操作栏 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-sell'),
+            $query = $view.find('#query'),
+            $add = $view.find('#add'),
+            $reset = $view.find('#reset'),
+            $searchForm = $view.find('form'),
+            sortObject = {field: 'phone', type: null},
+            tableIns;
+
+        form.render();
+
+        // 表格初始化
+        initSellTable();
+
+        // 初始化表格操作栏各个按钮功能
+        table.on('tool(sellTable)', function (obj) {
+            var data = obj.data,
+                layEvent = obj.event;
+            if (layEvent === 'productNFTUpdate') {
+                febs.modal.open('编辑', 'modules/news/productNFTUpdate/' + data.id, {
+                    btn: ['提交', '取消'],
+                    yes: function (index, layero) {
+                        $('#nftInfo-update').find('#submit').trigger('click');
+                    },
+                    btn2: function () {
+                        layer.closeAll();
+                    }
+                });
+            }
+            if (layEvent === 'delNFT') {
+                febs.modal.confirm('删除', '确认删除?', function () {
+                    delNFT(data.id);
+                });
+            }
+        });
+
+        function delNFT(id) {
+            febs.get(ctx + 'admin/news/delNFT/' + id, null, function () {
+                febs.alert.success('操作成功');
+                $query.click();
+            });
+        }
+
+        // 查询按钮
+        $query.on('click', function () {
+            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
+            tableIns.reload({where: params, page: {curr: 1}});
+        });
+
+        // 刷新按钮
+        $reset.on('click', function () {
+            $searchForm[0].reset();
+            sortObject.type = 'null';
+            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
+        });
+
+        $add.on('click', function () {
+            febs.modal.open('新增', 'modules/news/productNFTAdd/', {
+                btn: ['提交', '取消'],
+                yes: function (index, layero) {
+                    $('#productNFT-add').find('#submit').trigger('click');
+                },
+                btn2: function () {
+                    layer.closeAll();
+                }
+            });
+        });
+
+        function initSellTable() {
+            tableIns = febs.table.init({
+                elem: $view.find('table'),
+                id: 'sellTable',
+                url: ctx + 'admin/news/getSellList',
+                cols: [[
+                    {field: 'accountLogin', title: '登录账户', minWidth: 120,align:'center'},
+                    {field: 'nftTotal', title: '动态NFT', minWidth: 120,align:'center'},
+                    {field: 'nftCnt', title: '实际提现', minWidth: 120,align:'center'},
+                    {field: 'nftCntAva', title: '剩余数量', minWidth: 120,align:'center'},
+                    {field: 'nftFee', title: 'NFT手续费', minWidth: 120,align:'center'},
+                    {field: 'fcmFee', title: '代币手续费', minWidth: 120,align:'center'},
+                    {templet: '#isSellState', title: '提现状态', minWidth: 120,align:'center'},
+                    // {title: '操作',
+                    //     templet: function (d) {
+                    //     if(d.state == 1){
+                    //         return ''
+                    //     }else{
+                    //         return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="productNFTUpdate" shiro:hasPermission="user:update">编辑</button>'
+                    //             +'<button class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delNFT" shiro:hasPermission="user:update">删除</button>'
+                    //     }
+                    //     },minWidth: 300,align:'center'}
+                ]]
+            });
+        }
+
+        // 获取查询参数
+        function getQueryParams() {
+            return {
+            };
+        }
+    })
+</script>
\ No newline at end of file

--
Gitblit v1.9.1