From bac072f518a357363ae3f201beb665021cd75efc Mon Sep 17 00:00:00 2001
From: xiaoyong931011 <15274802129@163.com>
Date: Mon, 03 Apr 2023 18:13:51 +0800
Subject: [PATCH] 关于积分凭证

---
 src/main/resources/mapper/modules/MallScoreVoucherMapper.xml                 |   20 +
 src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherRecordVo.java            |   39 +++
 src/main/java/cc/mrbird/febs/mall/controller/ApiScoreController.java         |   39 ++
 src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java              |   12 
 src/main/java/cc/mrbird/febs/mall/mapper/MallScoreVoucherMapper.java         |   14 +
 src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java       |   34 ++
 src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java        |   12 
 src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java      |   40 +++
 src/main/java/cc/mrbird/febs/mall/dto/ApiVoucherBusinessDto.java             |   30 ++
 src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java           |   21 +
 src/main/java/cc/mrbird/febs/mall/dto/ApiScoreVoucherRecordDto.java          |   17 +
 src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java    |    2 
 src/main/java/cc/mrbird/febs/mall/mapper/DataDictionaryCustomMapper.java     |    2 
 src/main/java/cc/mrbird/febs/mall/vo/MemberBankListVo.java                   |    3 
 src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java            |    2 
 src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java             |    5 
 src/main/resources/mapper/modules/DataDictionaryCustomMapper.xml             |    5 
 src/main/java/cc/mrbird/febs/mall/dto/AddMemberBankDto.java                  |    3 
 src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html    |   22 +
 src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java           |    8 
 src/main/java/cc/mrbird/febs/mall/entity/MallMemberBank.java                 |    1 
 src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java          |    6 
 src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherInfoVo.java              |   25 +
 src/main/java/cc/mrbird/febs/mall/dto/UpdateMemberBankDto.java               |    3 
 src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java         |    2 
 src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherButtonDto.java               |   17 +
 src/main/java/cc/mrbird/febs/mall/service/impl/ScoreServiceImpl.java         |  177 +++++++++++++
 src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java          |    2 
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java |    1 
 src/main/java/cc/mrbird/febs/mall/entity/MallScoreVoucher.java               |   34 ++
 src/main/resources/mapper/modules/MallMemberWalletMapper.xml                 |    9 
 src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java  |   79 ++++++
 src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java             |    6 
 src/main/java/cc/mrbird/febs/mall/service/IScoreService.java                 |   13 +
 src/main/resources/templates/febs/views/modules/system/hlmVoucherButton.html |   43 ++
 src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java                  |    4 
 36 files changed, 726 insertions(+), 26 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 8acc19d..7079411 100644
--- a/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
+++ b/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
@@ -143,4 +143,25 @@
     }
     //补贴金额 end
 
+    /**
+     * 强制卖出
+     * @return
+     */
+    //强制卖出 start
+    @Bean
+    public DirectExchange forceVoucherSaleExchange() {
+        return new DirectExchange(RabbitQueueEnum.FORCE_VOUCHER_SALE.getExchange());
+    }
+
+    @Bean
+    public Queue forceVoucherSaleQueue() {
+        return new Queue(QueueConstants.FORCE_VOUCHER_SALE);
+    }
+
+    @Bean
+    public Binding forceVoucherSaleBind() {
+        return BindingBuilder.bind(forceVoucherSaleQueue()).to(forceVoucherSaleExchange()).with(RabbitQueueEnum.FORCE_VOUCHER_SALE.getRoute());
+    }
+    //强制卖出 end
+
 }
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java
index d3fea93..edcb291 100644
--- a/src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java
@@ -37,7 +37,11 @@
     /**
      * 凭证数量
      */
-    VOUCHER_CNT(7);
+    VOUCHER_CNT(7),
+    /**
+     * 凭证数量
+     */
+    VOUCHER_AMOUNT(8);
 
     private final int value;
 
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java
index dd625f3..436dad3 100644
--- a/src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java
@@ -8,6 +8,14 @@
 @Getter
 public enum GreenScoreEnum {
     /**
+     * 绿色凭证提现开关 1:开启 2:关闭
+     */
+    VOUCHER_ON_OFF("GREEN_SCORE", "VOUCHER_ON_OFF"),
+    /**
+     * 绿色凭证买卖池
+     */
+    SCORE_POOL_CNT("GREEN_SCORE", "SCORE_POOL_CNT"),
+    /**
      * 绿色凭证价格
      */
     SCORE_PRICE("GREEN_SCORE", "SCORE_PRICE"),
diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java
index 27d0fdf..3122c32 100644
--- a/src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java
@@ -178,7 +178,17 @@
     /**
      * 业绩释放星级凭证
      */
-    ACHIEVE_RELEASE_SCORE_XJ(35);
+    ACHIEVE_RELEASE_SCORE_XJ(35),
+
+    /**
+     * 凭证买入
+     */
+    VOUCHER_BUY(36),
+
+    /**
+     * 凭证卖出
+     */
+    VOUCHER_SALE(37);
 
     private final int value;
 
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java b/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
index 2b18daa..dd081f1 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
@@ -4,8 +4,12 @@
 import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
 import cc.mrbird.febs.common.enumerates.GreenScoreEnum;
 import cc.mrbird.febs.mall.dto.*;
+import cc.mrbird.febs.mall.entity.DataDictionaryCustom;
+import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
 import cc.mrbird.febs.mall.service.ICommonService;
+import cc.mrbird.febs.mall.service.IMemberProfitService;
 import cc.mrbird.febs.mall.service.ISystemService;
+import cc.mrbird.febs.rabbit.producter.AgentProducer;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,6 +33,13 @@
     private ISystemService systemService;
 
     private final ICommonService commonService;
+
+    @Autowired
+    private IMemberProfitService memberProfitService;
+
+    private final AgentProducer agentProducer;
+
+    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
 
     @PostMapping(value = "/bonusSystemSetting")
     public FebsResponse bonusSystemSetting(@RequestBody Map<String, Object> map) {
@@ -146,4 +157,33 @@
                 hlmVoucherSetDto.getLevelAchievePercent());
         return new FebsResponse().success();
     }
+
+    @PostMapping(value = "/hlmVoucherButton")
+    public FebsResponse hlmVoucherButton(HlmVoucherButtonDto hlmVoucherButtonDto) {
+        BigDecimal scorePrice = new BigDecimal(hlmVoucherButtonDto.getScorePrice());
+        if(scorePrice.compareTo(BigDecimal.ZERO) <= 0){
+            return new FebsResponse().fail().message("请输入合理的价格");
+        }
+
+        commonService.updateDataDic(
+                GreenScoreEnum.SCORE_PRICE.getType(),
+                GreenScoreEnum.SCORE_PRICE.getCode(),
+                hlmVoucherButtonDto.getScorePrice());
+
+        commonService.updateDataDic(
+                GreenScoreEnum.VOUCHER_ON_OFF.getType(),
+                GreenScoreEnum.VOUCHER_ON_OFF.getCode(),
+                hlmVoucherButtonDto.getVoucherOnOff());
+        return new FebsResponse().success();
+    }
+
+    @PostMapping(value = "/selaHalfVoucher")
+    public FebsResponse selaHalfVoucher() {
+        DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.SCORE_PRICE.getType(),
+                GreenScoreEnum.SCORE_PRICE.getCode()
+        );
+        agentProducer.sendForceVoucherSaleMsg(scorePriceDic.getValue());
+        return new FebsResponse().success();
+    }
 }
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 3ffb084..987f855 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java
@@ -215,4 +215,6 @@
         return memberService.delMemberBank(id);
     }
 
+
+
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ApiScoreController.java b/src/main/java/cc/mrbird/febs/mall/controller/ApiScoreController.java
index 6542390..879a06b 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ApiScoreController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ApiScoreController.java
@@ -2,12 +2,12 @@
 
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.mall.dto.ApiMallScoreSignRecordDto;
+import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto;
+import cc.mrbird.febs.mall.dto.ApiVoucherBusinessDto;
 import cc.mrbird.febs.mall.dto.OrderListDto;
 import cc.mrbird.febs.mall.service.ICommonService;
 import cc.mrbird.febs.mall.service.IScoreService;
-import cc.mrbird.febs.mall.vo.ApiMallScoreSignRecordVo;
-import cc.mrbird.febs.mall.vo.OrderListVo;
-import cc.mrbird.febs.mall.vo.ScoreSignVo;
+import cc.mrbird.febs.mall.vo.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
@@ -17,6 +17,8 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
 
 /**
  * @author wzy
@@ -57,4 +59,35 @@
     public FebsResponse signRecordList(@RequestBody ApiMallScoreSignRecordDto apiMallScoreSignRecordDto) {
         return new FebsResponse().success().data(scoreService.findMallScoreSignRecordList(apiMallScoreSignRecordDto));
     }
+
+    @ApiOperation(value = "绿色积分个人信息", notes = "绿色积分个人信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "success", response = ApiScoreVoucherInfoVo.class)
+    })
+    @GetMapping(value = "/memberScoreVoucher")
+    public FebsResponse memberScoreVoucher() {
+        return new FebsResponse().success().data(scoreService.memberScoreVoucher());
+    }
+
+    @ApiOperation(value = "绿色积分个人信息-买卖信息", notes = "绿色积分个人信息-买卖信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "success", response = ApiScoreVoucherRecordVo.class)
+    })
+    @PostMapping(value = "/memberScoreVoucher")
+    public FebsResponse memberScoreVoucher(@RequestBody ApiScoreVoucherRecordDto apiScoreVoucherRecordDto) {
+        return new FebsResponse().success().data(scoreService.findMallScoreVoucherList(apiScoreVoucherRecordDto));
+    }
+
+    @ApiOperation(value = "绿色积分个人信息-买入", notes = "绿色积分个人信息-买入")
+    @PostMapping(value = "/voucherBusinessBuy")
+    public FebsResponse voucherBusinessBuy(@Valid @RequestBody ApiVoucherBusinessDto apiVoucherBusinessDto) {
+        return scoreService.voucherBusinessBuy(apiVoucherBusinessDto);
+    }
+
+    @ApiOperation(value = "绿色积分个人信息-卖出", notes = "绿色积分个人信息-卖出")
+    @PostMapping(value = "/voucherBusinessSale")
+    public FebsResponse voucherBusinessSale(@Valid @RequestBody ApiVoucherBusinessDto apiVoucherBusinessDto) {
+        return scoreService.voucherBusinessSale(apiVoucherBusinessDto);
+    }
+
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java b/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
index 796674d..3d2d302 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
@@ -291,7 +291,41 @@
             String levelAchievePercent = ObjectUtil.isEmpty(levelAchievePercentDic.getValue()) ? "0" : levelAchievePercentDic.getValue();
             hlmVoucherSetDto.setLevelAchievePercent(levelAchievePercent);
         }
+        DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.SCORE_POOL_CNT.getType(),
+                GreenScoreEnum.SCORE_POOL_CNT.getCode());
+        if (scorePoolCntDic != null) {
+            String scorePoolCnt = ObjectUtil.isEmpty(scorePoolCntDic.getValue()) ? "0" : scorePoolCntDic.getValue();
+            hlmVoucherSetDto.setScorePoolCnt(scorePoolCnt);
+        }
         model.addAttribute("hlmVoucherSetDto", hlmVoucherSetDto);
         return FebsUtil.view("modules/system/hlmVoucherSet");
     }
+
+    /**
+     * 一键卖出
+     * @param model
+     * @return
+     */
+    @GetMapping("hlmVoucherButton")
+    @RequiresPermissions("hlmVoucherButton:view")
+    public String hlmVoucherButton(Model model) {
+        HlmVoucherButtonDto hlmVoucherButtonDto = new HlmVoucherButtonDto();
+        DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.SCORE_PRICE.getType(),
+                GreenScoreEnum.SCORE_PRICE.getCode());
+        if (scorePriceDic != null) {
+            String scorePrice = ObjectUtil.isEmpty(scorePriceDic.getValue()) ? "0" : scorePriceDic.getValue();
+            hlmVoucherButtonDto.setScorePrice(scorePrice);
+        }
+        DataDictionaryCustom voucherOnOffDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.VOUCHER_ON_OFF.getType(),
+                GreenScoreEnum.VOUCHER_ON_OFF.getCode());
+        if (voucherOnOffDic != null) {
+            String voucherOnOff = ObjectUtil.isEmpty(voucherOnOffDic.getValue()) ? "0" : voucherOnOffDic.getValue();
+            hlmVoucherButtonDto.setVoucherOnOff(voucherOnOff);
+        }
+        model.addAttribute("hlmVoucherButtonDto", hlmVoucherButtonDto);
+        return FebsUtil.view("modules/system/hlmVoucherButton");
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/AddMemberBankDto.java b/src/main/java/cc/mrbird/febs/mall/dto/AddMemberBankDto.java
index d96d705..9598a1b 100644
--- a/src/main/java/cc/mrbird/febs/mall/dto/AddMemberBankDto.java
+++ b/src/main/java/cc/mrbird/febs/mall/dto/AddMemberBankDto.java
@@ -20,6 +20,9 @@
     // 银行卡号
     @ApiModelProperty(value = "银行卡号")
     private String bankNo;
+    // 银行卡号
+    @ApiModelProperty(value = "数字账号")
+    private String digitalNo;
     // 手机号
     @ApiModelProperty(value = "手机号")
     private String phone;
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ApiScoreVoucherRecordDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ApiScoreVoucherRecordDto.java
new file mode 100644
index 0000000..83c6151
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/ApiScoreVoucherRecordDto.java
@@ -0,0 +1,17 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "ApiScoreVoucherRecordDto", description = "请求类")
+public class ApiScoreVoucherRecordDto {
+
+    @ApiModelProperty(value = "一页数量", example = "10")
+    private Integer pageSize;
+
+    @ApiModelProperty(value = "第几页", example = "1")
+    private Integer pageNum;
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ApiVoucherBusinessDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ApiVoucherBusinessDto.java
new file mode 100644
index 0000000..3176f3c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/ApiVoucherBusinessDto.java
@@ -0,0 +1,30 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "ApiVoucherBusinessDto", description = "请求类")
+public class ApiVoucherBusinessDto {
+
+    /**
+     * B:买入S:卖出
+     */
+    @ApiModelProperty(value = "B:买入S:卖出")
+    @NotBlank(message = "请选择买入")
+    private String type;
+
+    @ApiModelProperty(value = "数量")
+    @NotNull(message = "请输入合理的数量")
+    private BigDecimal voucherCnt;
+
+    @ApiModelProperty(value = "交易密码")
+    @NotBlank(message = "请输入支付密码")
+    private String tradePassword;
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherButtonDto.java b/src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherButtonDto.java
new file mode 100644
index 0000000..2dea48d
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherButtonDto.java
@@ -0,0 +1,17 @@
+package cc.mrbird.febs.mall.dto;
+
+import lombok.Data;
+
+@Data
+public class HlmVoucherButtonDto {
+
+    /**
+     * 绿色凭证价格
+     */
+    private String scorePrice;
+
+    /**
+     * 绿色凭证提现开关 1:开启 2:关闭
+     */
+    private String voucherOnOff;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java b/src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java
index 45cb50c..429f083 100644
--- a/src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java
+++ b/src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java
@@ -42,5 +42,9 @@
      * 业绩积分凭证按用户星级比例
      */
     private String levelAchievePercent;
+    /**
+     * 绿色凭证买卖池
+     */
+    private String scorePoolCnt;
 
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/UpdateMemberBankDto.java b/src/main/java/cc/mrbird/febs/mall/dto/UpdateMemberBankDto.java
index c9b1015..156fe52 100644
--- a/src/main/java/cc/mrbird/febs/mall/dto/UpdateMemberBankDto.java
+++ b/src/main/java/cc/mrbird/febs/mall/dto/UpdateMemberBankDto.java
@@ -25,4 +25,7 @@
     // 手机号
     @ApiModelProperty(value = "手机号")
     private String phone;
+    // 银行卡号
+    @ApiModelProperty(value = "数字账号")
+    private String digitalNo;
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallMemberBank.java b/src/main/java/cc/mrbird/febs/mall/entity/MallMemberBank.java
index c434330..41f656f 100644
--- a/src/main/java/cc/mrbird/febs/mall/entity/MallMemberBank.java
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallMemberBank.java
@@ -18,4 +18,5 @@
     private String bankNo;
     // 手机号
     private String phone;
+    private String digitalNo;
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallScoreVoucher.java b/src/main/java/cc/mrbird/febs/mall/entity/MallScoreVoucher.java
new file mode 100644
index 0000000..fbfa074
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallScoreVoucher.java
@@ -0,0 +1,34 @@
+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_score_voucher")
+public class MallScoreVoucher extends BaseEntity {
+
+    private String voucherNo;
+
+    private Long memberId;
+
+    /**
+     * B:买入S:卖出
+     */
+    private String type;
+    /**
+     * 数量
+     */
+    private BigDecimal voucherCnt;
+    /**
+     * 单价
+     */
+    private BigDecimal price;
+    /**
+     * 总价
+     */
+    private BigDecimal voucherAmount;
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/DataDictionaryCustomMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/DataDictionaryCustomMapper.java
index c86b42f..b6a31ee 100644
--- a/src/main/java/cc/mrbird/febs/mall/mapper/DataDictionaryCustomMapper.java
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/DataDictionaryCustomMapper.java
@@ -31,4 +31,6 @@
     AdminRankAwardUpdateInfoVo getRankAwardUpdateInfoById(@Param("id")long id);
 
     int updateDicValueByTypeAndCode(@Param("type") String type, @Param("code") String code, @Param("value") String value);
+
+    DataDictionaryCustom selectScorePoolCntForUpdate(@Param("type") String type, @Param("code") String code);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java
index dcb70c8..54108b4 100644
--- a/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java
@@ -47,4 +47,6 @@
     BigDecimal selectSumStar();
 
     List<MallMemberWallet> selectStar();
+
+    void addVorCherAmountAndCntById(@Param("voucherAmount")BigDecimal voucherAmountAdd,@Param("voucherCnt")BigDecimal voucherCnt, @Param("id")Long id);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallScoreVoucherMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallScoreVoucherMapper.java
new file mode 100644
index 0000000..7b5bb2e
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallScoreVoucherMapper.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.mall.mapper;
+
+import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto;
+import cc.mrbird.febs.mall.entity.MallScoreVoucher;
+import cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+
+public interface MallScoreVoucherMapper extends BaseMapper<MallScoreVoucher> {
+
+    IPage<ApiScoreVoucherRecordVo> findMallScoreVoucherListInPage(IPage<ApiScoreVoucherRecordVo> page, @Param("record")ApiScoreVoucherRecordDto apiScoreVoucherRecordDto);
+
+}
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 0251cd1..7806be2 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
@@ -53,4 +53,6 @@
     void scoreRecordReleaseJob();
 
     void achieveReleaseJob();
+
+    void selaHalfVoucher(String price);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IScoreService.java b/src/main/java/cc/mrbird/febs/mall/service/IScoreService.java
index 5cb2a85..f04f1cf 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IScoreService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IScoreService.java
@@ -1,8 +1,13 @@
 package cc.mrbird.febs.mall.service;
 
+import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.mall.dto.ApiMallScoreSignRecordDto;
+import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto;
+import cc.mrbird.febs.mall.dto.ApiVoucherBusinessDto;
 import cc.mrbird.febs.mall.entity.MallScoreSignRecord;
 import cc.mrbird.febs.mall.vo.ApiMallScoreSignRecordVo;
+import cc.mrbird.febs.mall.vo.ApiScoreVoucherInfoVo;
+import cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo;
 import cc.mrbird.febs.mall.vo.ScoreSignVo;
 
 import java.util.List;
@@ -16,4 +21,12 @@
     MallScoreSignRecord judgeScoreIsContinuity(MallScoreSignRecord mallScoreSignRecord);
 
     List<ApiMallScoreSignRecordVo> findMallScoreSignRecordList(ApiMallScoreSignRecordDto apiMallScoreSignRecordDto);
+
+    ApiScoreVoucherInfoVo memberScoreVoucher();
+
+    List<ApiScoreVoucherRecordVo> findMallScoreVoucherList(ApiScoreVoucherRecordDto apiScoreVoucherRecordDto);
+
+    FebsResponse voucherBusinessBuy(ApiVoucherBusinessDto apiVoucherBusinessDto);
+
+    FebsResponse voucherBusinessSale(ApiVoucherBusinessDto apiVoucherBusinessDto);
 }
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 7dc8669..7e11deb 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
@@ -613,6 +613,7 @@
         mallMemberBank.setIdCardNum(updateMemberBankDto.getIdCardNum());
         mallMemberBank.setBankNo(updateMemberBankDto.getBankNo());
         mallMemberBank.setPhone(updateMemberBankDto.getPhone());
+        mallMemberBank.setDigitalNo(updateMemberBankDto.getDigitalNo());
         mallMemberBankMapper.updateById(mallMemberBank);
         return new FebsResponse().success();
     }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
index 5993c95..1e11453 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
@@ -58,6 +58,7 @@
     private final AgentProducer agentProducer;
     private final MallScoreRecordMapper mallScoreRecordMapper;
     private final MallScoreAchieveReleaseMapper mallScoreAchieveReleaseMapper;
+    private final MallScoreVoucherMapper mallScoreVoucherMapper;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -789,6 +790,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void scoreRecordReleaseJob() {
         /**
          * 每日按照比例释放记录的百分比到用户的绿色凭证账户
@@ -831,6 +833,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void achieveReleaseJob() {
         /**
          * 业绩产生凭证
@@ -1009,6 +1012,82 @@
 
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void selaHalfVoucher(String price) {
+        /**
+         * 获取所有凭证大于0的用户
+         * 当前价格卖出账户的一半凭证
+         */
+        BigDecimal scorePrice = new BigDecimal(price == null ? "0" : price);
+        if(scorePrice.compareTo(BigDecimal.ZERO) <= 0){
+            return;
+        }
+        List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectList(null);
+        if(CollUtil.isNotEmpty(mallMemberWallets)){
+            List<MallMemberWallet> wallets = mallMemberWallets
+                    .stream()
+                    .filter(mallMemberWallet -> mallMemberWallet.getVoucherCnt().compareTo(BigDecimal.ZERO) > 0)
+                    .collect(Collectors.toList());
+            if(CollUtil.isNotEmpty(wallets)){
+                BigDecimal scorePoolCntAdd = BigDecimal.ZERO;
+                //绿色积分剩余数量
+                for(MallMemberWallet mallMemberWallet : wallets){
+                    //增加账户的凭证金额,减少当前的一半的凭证数量
+                    BigDecimal voucherCnt = mallMemberWallet.getVoucherCnt().divide(new BigDecimal(2), 2, BigDecimal.ROUND_DOWN)
+                            .setScale(2,BigDecimal.ROUND_DOWN);
+                    BigDecimal voucherAmountAdd = scorePrice.multiply(voucherCnt)
+                            .setScale(2,BigDecimal.ROUND_DOWN);
+                    mallMemberWalletMapper.addVorCherAmountAndCntById(voucherAmountAdd,voucherCnt,mallMemberWallet.getId());
+
+                    scorePoolCntAdd = scorePoolCntAdd.add(voucherCnt);
+
+                    DataDictionaryCustom surplusCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                            GreenScoreEnum.SURPLUS_CNT.getType(),
+                            GreenScoreEnum.SURPLUS_CNT.getCode()
+                    );
+                    //增加绿色积分剩余数量
+                    BigDecimal surplusCnt = new BigDecimal(surplusCntDic.getValue() == null ? "0" : surplusCntDic.getValue());
+                    BigDecimal voucherCntAdd = surplusCnt.add(voucherCnt).setScale(2,BigDecimal.ROUND_DOWN);
+                    surplusCntDic.setValue(voucherCntAdd.toString());
+                    dataDictionaryCustomMapper.updateById(surplusCntDic);
+
+                    /**
+                     * 生成一条卖出记录
+                     */
+                    String voucherNo = MallUtils.getOrderNum("VS");
+                    MallScoreVoucher mallScoreVoucher = new MallScoreVoucher();
+                    mallScoreVoucher.setVoucherNo(voucherNo);
+                    mallScoreVoucher.setMemberId(mallMemberWallet.getMemberId());
+                    mallScoreVoucher.setVoucherCnt(voucherCnt);
+                    mallScoreVoucher.setPrice(scorePrice);
+                    mallScoreVoucher.setVoucherAmount(voucherAmountAdd);
+                    mallScoreVoucher.setType("S");
+                    mallScoreVoucherMapper.insert(mallScoreVoucher);
+
+                    //产生一条流水记录
+                    mallMoneyFlowService.addMoneyFlow(
+                            mallMemberWallet.getMemberId(),
+                            voucherAmountAdd,
+                            MoneyFlowTypeEnum.VOUCHER_SALE.getValue(),
+                            voucherNo,
+                            FlowTypeEnum.VOUCHER_AMOUNT.getValue());
+                }
+
+                //增加积分凭证池的凭证数量
+                DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                        GreenScoreEnum.SCORE_POOL_CNT.getType(),
+                        GreenScoreEnum.SCORE_POOL_CNT.getCode()
+                );
+                //增加绿色积分剩余数量
+                BigDecimal scorePoolCnt = new BigDecimal(scorePoolCntDic.getValue() == null ? "0" : scorePoolCntDic.getValue());
+                scorePoolCnt = scorePoolCnt.add(scorePoolCntAdd);
+                scorePoolCntDic.setValue(scorePoolCnt.toString());
+                dataDictionaryCustomMapper.updateById(scorePoolCntDic);
+            }
+        }
+    }
+
     /**
      * 给用户的增加凭证数据,并且增加流水
      * @param memberAchieveRelease 释放数量
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ScoreServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ScoreServiceImpl.java
index 6f6bf9a..38d7485 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ScoreServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ScoreServiceImpl.java
@@ -1,28 +1,34 @@
 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.FlowTypeEnum;
+import cc.mrbird.febs.common.enumerates.GreenScoreEnum;
 import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
 import cc.mrbird.febs.common.exception.FebsException;
 import cc.mrbird.febs.common.utils.LoginUserUtil;
+import cc.mrbird.febs.common.utils.MallUtils;
 import cc.mrbird.febs.mall.conversion.MallOrderInfoConversion;
 import cc.mrbird.febs.mall.dto.ApiMallScoreSignRecordDto;
+import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto;
+import cc.mrbird.febs.mall.dto.ApiVoucherBusinessDto;
 import cc.mrbird.febs.mall.dto.ScoreSettingDto;
 import cc.mrbird.febs.mall.entity.*;
-import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
-import cc.mrbird.febs.mall.mapper.MallMemberMapper;
-import cc.mrbird.febs.mall.mapper.MallMemberWalletMapper;
-import cc.mrbird.febs.mall.mapper.MallScoreSignRecordMapper;
+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.IMallMoneyFlowService;
 import cc.mrbird.febs.mall.service.IScoreService;
 import cc.mrbird.febs.mall.vo.ApiMallScoreSignRecordVo;
+import cc.mrbird.febs.mall.vo.ApiScoreVoucherInfoVo;
+import cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo;
 import cc.mrbird.febs.mall.vo.ScoreSignVo;
 import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -51,6 +57,8 @@
     private final IMallMoneyFlowService mallMoneyFlowService;
     private final IApiMallMemberWalletService walletService;
     private final MallMemberMapper mallMemberMapper;
+    private final MallScoreVoucherMapper mallScoreVoucherMapper;
+    private final IApiMallMemberWalletService memberWalletService;
 
     @Override
     public ScoreSignVo scoreSign() {
@@ -94,6 +102,167 @@
     }
 
     @Override
+    public ApiScoreVoucherInfoVo memberScoreVoucher() {
+        MallMember member = LoginUserUtil.getLoginUser();
+        ApiScoreVoucherInfoVo apiScoreVoucherInfoVo = new ApiScoreVoucherInfoVo();
+
+        MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(member.getId());
+        apiScoreVoucherInfoVo.setVoucherCnt(mallMemberWallet.getVoucherCnt().compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : mallMemberWallet.getVoucherCnt());
+        apiScoreVoucherInfoVo.setVoucherAmount(mallMemberWallet.getVoucherAmount().compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : mallMemberWallet.getVoucherAmount());
+        DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.SCORE_PRICE.getType(),
+                GreenScoreEnum.SCORE_PRICE.getCode());
+        apiScoreVoucherInfoVo.setScorePrice(new BigDecimal(scorePriceDic.getValue()).setScale(2,BigDecimal.ROUND_DOWN));
+        DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.SCORE_POOL_CNT.getType(),
+                GreenScoreEnum.SCORE_POOL_CNT.getCode());
+        apiScoreVoucherInfoVo.setScorePoolCnt(new BigDecimal(scorePoolCntDic.getValue()).setScale(2,BigDecimal.ROUND_DOWN));
+        return apiScoreVoucherInfoVo;
+    }
+
+    @Override
+    public List<ApiScoreVoucherRecordVo> findMallScoreVoucherList(ApiScoreVoucherRecordDto apiScoreVoucherRecordDto) {
+        IPage<ApiScoreVoucherRecordVo> page = new Page<>(apiScoreVoucherRecordDto.getPageNum(), apiScoreVoucherRecordDto.getPageSize());
+        IPage<ApiScoreVoucherRecordVo> apiScoreVoucherRecordVoIPage = mallScoreVoucherMapper.findMallScoreVoucherListInPage(page, apiScoreVoucherRecordDto);
+        return apiScoreVoucherRecordVoIPage.getRecords();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public FebsResponse voucherBusinessBuy(ApiVoucherBusinessDto apiVoucherBusinessDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        BigDecimal voucherCnt = apiVoucherBusinessDto.getVoucherCnt();
+        if(voucherCnt.compareTo(BigDecimal.ZERO) <= 0){
+            throw new FebsException("请输入合理的数量");
+        }
+        DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectScorePoolCntForUpdate(
+                GreenScoreEnum.SCORE_POOL_CNT.getType(),
+                GreenScoreEnum.SCORE_POOL_CNT.getCode());
+        BigDecimal scorePoolCnt = new BigDecimal(scorePoolCntDic.getValue() == null ? "0" : scorePoolCntDic.getValue());
+        if(scorePoolCnt.compareTo(voucherCnt) < 0){
+            throw new FebsException("可购买总量不足");
+        }
+        String tradePassword = apiVoucherBusinessDto.getTradePassword();
+        if (StrUtil.isBlank(tradePassword)) {
+            throw new FebsException("支付密码错误");
+        }
+
+        MallMember mallMember = mallMemberMapper.selectById(memberId);
+        if (StrUtil.isBlank(mallMember.getTradePassword())) {
+            throw new FebsException("未设置支付密码");
+        }
+
+        if (!SecureUtil.md5(tradePassword).equals(mallMember.getTradePassword())) {
+            throw new FebsException("支付密码错误");
+        }
+
+        DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.SCORE_PRICE.getType(),
+                GreenScoreEnum.SCORE_PRICE.getCode());
+        BigDecimal scorePrice = new BigDecimal(scorePriceDic.getValue()).setScale(2, BigDecimal.ROUND_DOWN);
+        BigDecimal voucherAmount = voucherCnt.multiply(scorePrice);
+
+        MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
+        BigDecimal balance = mallMemberWallet.getBalance();
+        if(voucherAmount.compareTo(balance) > 0){
+            throw new FebsException("余额不足");
+        }
+        //减少余额
+        memberWalletService.reduceBalance(voucherAmount,memberId);
+        //减少绿色积分池
+        scorePoolCnt = scorePoolCnt.subtract(voucherCnt);
+        scorePoolCntDic.setValue(scorePoolCnt.toString());
+        dataDictionaryCustomMapper.updateById(scorePoolCntDic);
+        //增加凭证数量
+        mallMemberWalletMapper.addVorCherCntByMemberId(voucherCnt,memberId);
+        //增加购买记录
+        String voucherNo = MallUtils.getOrderNum("VB");
+        MallScoreVoucher mallScoreVoucher = new MallScoreVoucher();
+        mallScoreVoucher.setVoucherNo(voucherNo);
+        mallScoreVoucher.setMemberId(memberId);
+        mallScoreVoucher.setVoucherCnt(voucherCnt);
+        mallScoreVoucher.setPrice(scorePrice);
+        mallScoreVoucher.setVoucherAmount(voucherAmount);
+        mallScoreVoucher.setType("B");
+        mallScoreVoucherMapper.insert(mallScoreVoucher);
+
+        //产生一条流水记录
+        mallMoneyFlowService.addMoneyFlow(
+                mallMemberWallet.getMemberId(),
+                voucherCnt,
+                MoneyFlowTypeEnum.VOUCHER_BUY.getValue(),
+                voucherNo,
+                FlowTypeEnum.VOUCHER_CNT.getValue());
+        return new FebsResponse().success().message("操作成功");
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public FebsResponse voucherBusinessSale(ApiVoucherBusinessDto apiVoucherBusinessDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        BigDecimal voucherCnt = apiVoucherBusinessDto.getVoucherCnt();
+        if(voucherCnt.compareTo(BigDecimal.ZERO) <= 0){
+            throw new FebsException("请输入合理的数量");
+        }
+        String tradePassword = apiVoucherBusinessDto.getTradePassword();
+        if (StrUtil.isBlank(tradePassword)) {
+            throw new FebsException("支付密码错误");
+        }
+
+        MallMember mallMember = mallMemberMapper.selectById(memberId);
+        if (StrUtil.isBlank(mallMember.getTradePassword())) {
+            throw new FebsException("未设置支付密码");
+        }
+
+        if (!SecureUtil.md5(tradePassword).equals(mallMember.getTradePassword())) {
+            throw new FebsException("支付密码错误");
+        }
+
+        MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
+        BigDecimal voucherCntMember = mallMemberWallet.getVoucherCnt();
+        if(voucherCntMember.compareTo(voucherCnt) < 0){
+            throw new FebsException("绿色积分不足");
+        }
+
+        DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
+                GreenScoreEnum.SCORE_PRICE.getType(),
+                GreenScoreEnum.SCORE_PRICE.getCode());
+        BigDecimal scorePrice = new BigDecimal(scorePriceDic.getValue()).setScale(2, BigDecimal.ROUND_DOWN);
+        BigDecimal voucherAmount = voucherCnt.multiply(scorePrice);
+        //减少凭证积分
+        //增加凭证现金
+        mallMemberWalletMapper.addVorCherAmountAndCntById(voucherAmount,voucherCnt,mallMemberWallet.getId());
+        //增加积分池
+        DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectScorePoolCntForUpdate(
+                GreenScoreEnum.SCORE_POOL_CNT.getType(),
+                GreenScoreEnum.SCORE_POOL_CNT.getCode());
+        BigDecimal scorePoolCnt = new BigDecimal(scorePoolCntDic.getValue() == null ? "0" : scorePoolCntDic.getValue());
+        scorePoolCnt = scorePoolCnt.add(voucherCnt).setScale(2,BigDecimal.ROUND_DOWN);
+        scorePoolCntDic.setValue(scorePoolCnt.toString());
+        dataDictionaryCustomMapper.updateById(scorePoolCntDic);
+
+        //增加购买记录
+        String voucherNo = MallUtils.getOrderNum("VS");
+        MallScoreVoucher mallScoreVoucher = new MallScoreVoucher();
+        mallScoreVoucher.setVoucherNo(voucherNo);
+        mallScoreVoucher.setMemberId(memberId);
+        mallScoreVoucher.setVoucherCnt(voucherCnt);
+        mallScoreVoucher.setPrice(scorePrice);
+        mallScoreVoucher.setVoucherAmount(voucherAmount);
+        mallScoreVoucher.setType("S");
+        mallScoreVoucherMapper.insert(mallScoreVoucher);
+
+        //产生一条流水记录
+        mallMoneyFlowService.addMoneyFlow(
+                mallMemberWallet.getMemberId(),
+                voucherAmount,
+                MoneyFlowTypeEnum.VOUCHER_SALE.getValue(),
+                voucherNo,
+                FlowTypeEnum.VOUCHER_AMOUNT.getValue());
+        return new FebsResponse().success().message("操作成功");
+    }
+
+    @Override
     @Transactional(rollbackFor = Exception.class)
     public void sign() {
         MallMember member = LoginUserUtil.getLoginUser();
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherInfoVo.java b/src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherInfoVo.java
new file mode 100644
index 0000000..9f1fd42
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherInfoVo.java
@@ -0,0 +1,25 @@
+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 = "ApiScoreVoucherInfoVo", description = "绿色积分个人信息")
+public class ApiScoreVoucherInfoVo {
+
+
+    @ApiModelProperty(value = "绿色积分")
+    private BigDecimal voucherCnt;
+
+    @ApiModelProperty(value = "现金元")
+    private BigDecimal voucherAmount;
+
+    @ApiModelProperty(value = "当前积分价格")
+    private BigDecimal scorePrice;
+
+    @ApiModelProperty(value = "可购买总量")
+    private BigDecimal scorePoolCnt;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherRecordVo.java b/src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherRecordVo.java
new file mode 100644
index 0000000..b995b8f
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherRecordVo.java
@@ -0,0 +1,39 @@
+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 = "ApiScoreVoucherRecordVo", description = "绿色积分买卖信息")
+public class ApiScoreVoucherRecordVo {
+
+    @ApiModelProperty(value = "编号")
+    private String voucherNo;
+
+    @ApiModelProperty(value = "会员")
+    private String memberName;
+
+    /**
+     * B:买入S:卖出
+     */
+    @ApiModelProperty(value = "B:买入S:卖出")
+    private String type;
+    /**
+     * 数量
+     */
+    @ApiModelProperty(value = "数量")
+    private BigDecimal voucherCnt;
+    /**
+     * 单价
+     */
+    @ApiModelProperty(value = "单价")
+    private BigDecimal price;
+    /**
+     * 总价
+     */
+    @ApiModelProperty(value = "总价")
+    private BigDecimal voucherAmount;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/MemberBankListVo.java b/src/main/java/cc/mrbird/febs/mall/vo/MemberBankListVo.java
index 5f708dc..5ba69e1 100644
--- a/src/main/java/cc/mrbird/febs/mall/vo/MemberBankListVo.java
+++ b/src/main/java/cc/mrbird/febs/mall/vo/MemberBankListVo.java
@@ -23,4 +23,7 @@
     // 手机号
     @ApiModelProperty(value = "手机号")
     private String phone;
+    // 银行卡号
+    @ApiModelProperty(value = "数字账号")
+    private String digitalNo;
 }
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 d3f9dc2..458cedf 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
@@ -15,4 +15,6 @@
      *      分享补贴,星级补贴
      */
     public static final String PERK_MONEY = "hlm_queue_perk_money";
+
+    public static final String FORCE_VOUCHER_SALE = "hlm_queue_force_voucher_sale";
 }
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 2bf1c81..30df9c7 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
@@ -84,4 +84,16 @@
 
         }
     }
+
+    @RabbitListener(queues = QueueConstants.FORCE_VOUCHER_SALE)
+    public void forceVoucherSaleConsumer(String price) {
+        log.info("收到强制卖出消息,价格:{}",price);
+        try {
+            memberProfitService.selaHalfVoucher(price);
+        } 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 79ca466..ea6f262 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
@@ -26,7 +26,11 @@
 
     PERK_MONEY("hlm_exchange_perk_money",
             "hlm_route_key_perk_money",
-            "hlm_queue_perk_money");
+            "hlm_queue_perk_money"),
+
+    FORCE_VOUCHER_SALE("hlm_exchange_force_voucher_sale",
+            "hlm_route_key_force_voucher_sale",
+            "hlm_queue_force_voucher_sale");
 
     private String exchange;
 
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 1b9a1e9..e44c1a2 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
@@ -81,4 +81,9 @@
         log.info("发送补贴消息:{}", orderId);
         rabbitTemplate.convertAndSend(RabbitQueueEnum.PERK_MONEY.getExchange(), RabbitQueueEnum.PERK_MONEY.getRoute(), orderId);
     }
+
+    public void sendForceVoucherSaleMsg(String value) {
+        log.info("发送强制卖出消息,价格:{}",value);
+        rabbitTemplate.convertAndSend(RabbitQueueEnum.FORCE_VOUCHER_SALE.getExchange(), RabbitQueueEnum.FORCE_VOUCHER_SALE.getRoute(),value);
+    }
 }
diff --git a/src/main/resources/mapper/modules/DataDictionaryCustomMapper.xml b/src/main/resources/mapper/modules/DataDictionaryCustomMapper.xml
index 69c0f97..79cd99d 100644
--- a/src/main/resources/mapper/modules/DataDictionaryCustomMapper.xml
+++ b/src/main/resources/mapper/modules/DataDictionaryCustomMapper.xml
@@ -53,4 +53,9 @@
             </if>
         </where>
     </update>
+
+    <select id="selectScorePoolCntForUpdate" resultType="cc.mrbird.febs.mall.entity.DataDictionaryCustom">
+        select a.* from data_dictionary_custom a
+        where a.type = #{type} and a.code = #{code} for update
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/MallMemberWalletMapper.xml b/src/main/resources/mapper/modules/MallMemberWalletMapper.xml
index 09beb31..d77b4f2 100644
--- a/src/main/resources/mapper/modules/MallMemberWalletMapper.xml
+++ b/src/main/resources/mapper/modules/MallMemberWalletMapper.xml
@@ -144,5 +144,14 @@
         where  star > 0
     </select>
 
+    <update id="addVorCherAmountAndCntById">
+        update mall_member_wallet
+        <set>
+            voucher_amount = voucher_amount + #{voucherAmount},
+            voucher_cnt = voucher_cnt - #{voucherCnt},
+        </set>
+        WHERE id =  #{id}
+    </update>
+
 
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/modules/MallScoreVoucherMapper.xml b/src/main/resources/mapper/modules/MallScoreVoucherMapper.xml
new file mode 100644
index 0000000..e357925
--- /dev/null
+++ b/src/main/resources/mapper/modules/MallScoreVoucherMapper.xml
@@ -0,0 +1,20 @@
+<?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.MallScoreVoucherMapper">
+
+    <select id="findMallScoreVoucherListInPage" resultType="cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo">
+        SELECT
+            a.voucher_no voucherNo,
+            a.type type,
+            a.voucher_cnt voucherCnt,
+            a.price price,
+            a.voucher_amount voucherAmount,
+            RPAD(SUBSTRING(b.NAME,1,1),CHAR_LENGTH(b.NAME),'*') memberName
+        FROM
+            mall_score_voucher 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/templates/febs/views/modules/system/hlmVoucherButton.html b/src/main/resources/templates/febs/views/modules/system/hlmVoucherButton.html
index d47f681..5f441f9 100644
--- a/src/main/resources/templates/febs/views/modules/system/hlmVoucherButton.html
+++ b/src/main/resources/templates/febs/views/modules/system/hlmVoucherButton.html
@@ -9,16 +9,25 @@
                             <label class="layui-form-label febs-form-item-require">价格:</label>
                             <div class="layui-form-mid layui-word-aux">当前价格:</div>
                             <div class="layui-input-inline">
-                                <input type="text" name="scorePrice" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly>
+                                <input type="text" name="scorePrice" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input">
                             </div>
-                            <div class="layui-form-mid layui-word-aux">剩余:</div>
+                        </div>
+                    </div>
+                    <blockquote class="layui-elem-quote blue-border">提现设置,提现时,是否需要凭证</blockquote>
+                    <div class="layui-col-lg6">
+                        <label class="layui-form-label febs-form-item-require">需要凭证:</label>
+                        <div class="layui-input-block">
+                            <input type="radio" name="voucherOnOff" value="1" title="是"  />
+                            <input type="radio" name="voucherOnOff" value="2" title="否"  checked />
                         </div>
                     </div>
                     <div class="layui-card-footer">
                         <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="hlm-voucher-button-submit" id="submit">保存</button>
+                            <div class="layui-btn layui-btn-warm table-action" id="voucherButton">
+                                确认一键卖出
+                            </div>
                     </div>
                     <div class="layui-card-footer">
-                        <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="hlm-voucher-button-submit" id="submit">确认一键卖出</button>
                     </div>
                 </div>
             </div>
@@ -38,12 +47,15 @@
         margin-bottom: 20px !important;
     }
 </style>
+
 <script data-th-inline="javascript" type="text/javascript">
     layui.use(['dropdown', 'jquery', 'febs', 'form', 'eleTree'], function () {
         var $ = layui.jquery,
             febs = layui.febs,
             form = layui.form,
-            hlmVoucherSet = [[${hlmVoucherSetDto}]],
+            $view = $('#hlm-voucher-button'),
+            hlmVoucherButton = [[${hlmVoucherButtonDto}]],
+            $voucherButton = $view.find('#voucherButton'),
             $view = $('#hlm-voucher-button');
 
         form.verify({
@@ -53,18 +65,33 @@
             ]
         });
 
-        initHlmVoucherSetValue();
+        initHlmVoucherButtonValue();
+
+        $voucherButton.on('click', function () {
+            febs.modal.confirm('确认一键卖出', '点击【确定】,即强制卖出所有账户的一半积分凭证?', function () {
+                selaHalfVoucher();
+            });
+        });
+
+
+        function selaHalfVoucher() {
+            febs.post(ctx + 'admin/system/selaHalfVoucher', null, function (res) {
+                febs.alert.success('设置成功');
+                return ;
+            });
+        }
 
         form.render();
 
-        function initHlmVoucherSetValue() {
+        function initHlmVoucherButtonValue() {
             form.val("hlm-voucher-button-form", {
-                "roleReleasePercent": hlmVoucherSet.roleReleasePercent
+                "scorePrice": hlmVoucherButton.scorePrice,
+                "voucherOnOff": hlmVoucherButton.voucherOnOff,
             });
         }
 
         form.on('submit(hlm-voucher-button-submit)', function (data) {
-            febs.post(ctx + 'admin/system/hlmVoucherSet', data.field, function (res) {
+            febs.post(ctx + 'admin/system/hlmVoucherButton', data.field, function (res) {
                 febs.alert.success('设置成功');
                 return ;
             });
diff --git a/src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html b/src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html
index 024e2e0..15f6934 100644
--- a/src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html
+++ b/src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html
@@ -11,10 +11,15 @@
                             <div class="layui-input-inline">
                                 <input type="text" name="totalCnt" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly>
                             </div>
-                            <div class="layui-form-mid layui-word-aux">剩余:</div>
+                            <div class="layui-form-mid layui-word-aux">,剩余:</div>
                             <div class="layui-input-inline">
                                 <input type="text" name="surplusCnt" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly>
                             </div>
+                            <div class="layui-form-mid layui-word-aux">,可购买总量:</div>
+                            <div class="layui-input-inline">
+                                <input type="text" name="scorePoolCnt" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly>
+                            </div>
+                            <div class="layui-form-mid layui-word-aux">。</div>
                         </div>
                     </div>
 
@@ -23,7 +28,7 @@
                         <label class="layui-form-label febs-form-item-require">比例:</label>
                         <div class="layui-input-block">
                             <input type="text" name="roleReleasePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
-                            <div class="layui-word-aux">设置1,每日拨付千分之1</div>
+                            <div class="layui-word-aux">设置1,每日拨付千分之1。</div>
                         </div>
                     </div>
 
@@ -34,7 +39,7 @@
                         <div class="layui-input-inline">
                             <input type="text" name="achieveReleasePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                         </div>
-                        <div class="layui-form-mid layui-word-aux">例如:1,则表示总凭证数3000000*0.9*0.0001</div>
+                        <div class="layui-form-mid layui-word-aux">,例如:1,则表示总凭证数3000000*0.9*0.0001。</div>
                     </div>
                     <div class="layui-form-item">
                         <label class="layui-form-label febs-form-item-require">规则一:</label>
@@ -42,7 +47,7 @@
                         <div class="layui-input-inline">
                             <input type="text" name="achieveMin" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input">
                         </div>
-                        <div class="layui-form-mid layui-word-aux">才释放积分凭证。</div>
+                        <div class="layui-form-mid layui-word-aux">,才释放积分凭证。</div>
                     </div>
                     <div class="layui-form-item">
                         <label class="layui-form-label febs-form-item-require">规则二:</label>
@@ -50,7 +55,7 @@
                         <div class="layui-input-inline">
                             <input type="text" name="achieveMax" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input">
                         </div>
-                        <div class="layui-form-mid layui-word-aux">释放今日的全额积分凭证。</div>
+                        <div class="layui-form-mid layui-word-aux">,释放今日的全额积分凭证。</div>
                     </div>
                     <blockquote class="layui-elem-quote blue-border">业绩产生积分凭证设置二</blockquote>
                     <div class="layui-form-item">
@@ -59,7 +64,7 @@
                         <div class="layui-input-inline">
                             <input type="text" name="roleAchievePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                         </div>
-                        <div class="layui-form-mid layui-word-aux">设置20,则表示比例为20%</div>
+                        <div class="layui-form-mid layui-word-aux">,设置20,则表示比例为20%。</div>
                     </div>
                     <div class="layui-form-item">
                         <label class="layui-form-label febs-form-item-require">比例二:</label>
@@ -67,7 +72,7 @@
                         <div class="layui-input-inline">
                             <input type="text" name="starAchievePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                         </div>
-                        <div class="layui-form-mid layui-word-aux">设置20,则表示比例为20%</div>
+                        <div class="layui-form-mid layui-word-aux">,设置20,则表示比例为20%。</div>
                     </div>
                     <div class="layui-form-item">
                         <label class="layui-form-label febs-form-item-require">比例三:</label>
@@ -75,7 +80,7 @@
                         <div class="layui-input-inline">
                             <input type="text" name="levelAchievePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                         </div>
-                        <div class="layui-form-mid layui-word-aux">。设置20,则表示比例为20%</div>
+                        <div class="layui-form-mid layui-word-aux">,设置20,则表示比例为20%。</div>
                     </div>
                     <div class="layui-card-footer">
                         <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="hlm-voucher-set-submit" id="submit">保存</button>
@@ -127,6 +132,7 @@
                 "achieveMax": hlmVoucherSet.achieveMax,
                 "totalCnt": hlmVoucherSet.totalCnt,
                 "surplusCnt": hlmVoucherSet.surplusCnt,
+                "scorePoolCnt": hlmVoucherSet.scorePoolCnt,
                 "roleReleasePercent": hlmVoucherSet.roleReleasePercent
             });
         }

--
Gitblit v1.9.1