KKSU
2023-11-22 c3793ad938cefba5fa76258d70e0cbc37bcf151c
匹配
2 files added
36 files modified
465 ■■■■■ changed files
src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeNewEnum.java 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/enumerates/ProductEnum.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/runner/FebsStartedUpRunner.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java 12 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java 18 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ApiMallProductController.java 26 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/ApiOrderBuyInsureDto.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/ApiOrderSellInsureDto.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallProductBuy.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallProductSellRecord.java 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyMapper.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyRecordMapper.java 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellRecordMapper.java 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java 8 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IAgentService.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IApiMallProductService.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java 68 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallProductServiceImpl.java 107 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java 65 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/vo/ApiOrderBuyInfoVo.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/service/impl/AliPayServiceImpl.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java 6 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallProductBuyMapper.xml 9 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallProductBuyRecordMapper.xml 7 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallProductNftMapper.xml 7 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallProductSellRecordMapper.xml 7 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/error/403.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/error/404.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/error/500.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/layout.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/login.html 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
@@ -213,4 +213,21 @@
    }
    //强制卖出 end
    //卖单用户确认 start
    @Bean
    public DirectExchange fcmOrderSellInsureExchange() {
        return new DirectExchange(RabbitQueueEnum.FCMPAY_FCM_ORDER_SELL_INSURE.getExchange());
    }
    @Bean
    public Queue fcmOrderSellInsureQueue() {
        return new Queue(RabbitQueueEnum.FCMPAY_FCM_ORDER_SELL_INSURE.getQueue());
    }
    @Bean
    public Binding fcmOrderSellInsureBind() {
        return BindingBuilder.bind(fcmOrderSellInsureQueue()).to(fcmOrderSellInsureExchange()).with(RabbitQueueEnum.FCMPAY_FCM_ORDER_SELL_INSURE.getRoute());
    }
    //卖单用户确认 end
}
src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeNewEnum.java
@@ -10,6 +10,7 @@
 **/
@Getter
public enum MoneyFlowTypeNewEnum {
    PAY(12,"支付"),
    NFT_OUT_FEE(11,"NFT提现手续费"),
    NFT_OUT(10,"NFT提现"),
    NFT_IN(9,"FCM动态兑换"),
src/main/java/cc/mrbird/febs/common/enumerates/ProductEnum.java
@@ -29,6 +29,11 @@
    PRODUCT_BUY_ON_GOING(1,"进行中"),
    PRODUCT_BUY_FAIL(0,"失败"),
    /**
     * 用户买单转换买单状态  转换卖单状态 0:未转换 1:已转换
     */
    PRODUCT_BUY_MATE_STATE_SUCCESS(1,"已转换"),
    PRODUCT_BUY_MATE_STATE_FAIL(0,"未转换"),
    /**
     * 预约产品是否开启
     */
    PRODUCT_NFT_OPEN(1,"开启"),
src/main/java/cc/mrbird/febs/common/runner/FebsStartedUpRunner.java
@@ -63,7 +63,7 @@
            log.info("/ /`  / / \\ | |\\/| | |_) | |   | |_   | |  | |_  ");
            log.info("\\_\\_, \\_\\_/ |_|  | |_|   |_|__ |_|__  |_|  |_|__ ");
            log.info("                                                      ");
            log.info("鸿楼梦 权限系统启动完毕,地址:{}", url);
            log.info("GFA 权限系统启动完毕,地址:{}", url);
            boolean auto = febsProperties.isAutoOpenBrowser();
            if (auto && StringUtils.equalsIgnoreCase(active, FebsConstant.DEVELOP)) {
src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java
@@ -29,38 +29,38 @@
    private final IApiMallMemberService memberService;
    @ApiOperation(value = "点击生成账号", notes = "点击生成账号")
    @ApiOperation(value = "FCM-点击生成账号", notes = "FCM-点击生成账号")
    @GetMapping(value = "/createAccount")
    public FebsResponse createAccount() {
        return memberService.createAccount();
    }
    @ApiOperation(value = "点击生成密钥", notes = "点击生成密钥")
    @ApiOperation(value = "FCM-点击生成密钥", notes = "FCM-点击生成密钥")
    @GetMapping(value = "/createKey")
    public FebsResponse createKey() {
        return memberService.createKey();
    }
    @ApiOperation(value = "app注册接口", notes = "app注册接口")
    @ApiOperation(value = "FCM-app注册接口", notes = "FCM-app注册接口")
    @PostMapping(value = "/register")
    public FebsResponse register(@RequestBody @Valid RegisterDto registerDto) {
        return memberService.register(registerDto);
    }
    @ApiOperation(value = "账号密码登录接口", notes = "账号密码登录接口")
    @ApiOperation(value = "FCM-账号密码登录接口", notes = "FCM-账号密码登录接口")
    @PostMapping(value = "/toLogin")
    public FebsResponse login(@RequestBody @Valid LoginDto loginDto) {
        return memberService.toLogin(loginDto);
    }
    @ApiOperation(value = "忘记/修改密码", notes = "忘记/修改密码")
    @ApiOperation(value = "FCM-忘记/修改密码", notes = "FCM-忘记/修改密码")
    @PostMapping(value = "/forgetPwd")
    public FebsResponse forgetPwd(@RequestBody @Valid ForgetPwdDto forgetPwdDto) {
        return memberService.forgetPwd(forgetPwdDto);
    }
    @ApiOperation(value = "忘记密码", notes = "忘记/修改密码")
    @ApiOperation(value = "FCM-忘记密码", notes = "FCM-忘记/修改密码")
    @PostMapping(value = "/pwdForget")
    public FebsResponse pwdForget(@RequestBody @Valid ForgetPwdDto forgetPwdDto) {
        return memberService.pwdForget(forgetPwdDto);
src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java
@@ -36,7 +36,7 @@
    private final IMallMemberWithdrawService mallMemberWithdrawService;
    private final IApiMallMemberWalletService walletService;
    @ApiOperation(value = "获取商城用户信息", notes = "获取商城用户信息")
    @ApiOperation(value = "FCM-获取商城用户信息", notes = "FCM-获取商城用户信息")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = MallMemberVo.class)
    })
@@ -45,25 +45,25 @@
        return memberService.findMemberInfo();
    }
    @ApiOperation(value = "修改用户信息")
    @ApiOperation(value = "FCM-修改用户信息")
    @PostMapping(value = "/modifyInfo")
    public FebsResponse modifyInfo(@RequestBody @Valid ModifyMemberInfoDto modifyMemberInfoDto) {
        return memberService.modifyMemberInfo(modifyMemberInfoDto);
    }
    @ApiOperation(value = "解除冻结")
    @ApiOperation(value = "FCM-解除冻结")
    @PostMapping(value = "/unfreeze")
    public FebsResponse unfreeze(@RequestBody @Valid UnfreezeDto unfreezeDto) {
        return memberService.unfreeze(unfreezeDto);
    }
    @ApiOperation(value = "找回密钥")
    @ApiOperation(value = "FCM-找回密钥")
    @PostMapping(value = "/getKey")
    public FebsResponse getKey(@RequestBody @Valid GetKeyDto getKeyDto) {
        return memberService.getKey(getKeyDto);
    }
    @ApiOperation(value = "获取收款信息", notes = "获取收款信息")
    @ApiOperation(value = "FCM-获取收款信息", notes = "FCM-获取收款信息")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = MallMemberPaymentVo.class)
    })
@@ -72,13 +72,13 @@
        return memberService.getPayment();
    }
    @ApiOperation(value = "修改收款信息", notes = "修改收款信息")
    @ApiOperation(value = "FCM-修改收款信息", notes = "FCM-修改收款信息")
    @PostMapping(value = "/updatePayment")
    public FebsResponse updatePayment(@RequestBody @Valid UpdatePaymentDto updatePaymentDto) {
        return memberService.updatePayment(updatePaymentDto);
    }
    @ApiOperation(value = "推出登录", notes = "推出登录")
    @ApiOperation(value = "FCM-推出登录", notes = "FCM-推出登录")
    @PostMapping(value = "/logout")
    public FebsResponse logout() {
        return memberService.logout();
@@ -90,7 +90,7 @@
        return memberService.findMemberMarkCnt();
    }
    @ApiOperation(value = "设置支付密码")
    @ApiOperation(value = "FCM-设置支付密码")
    @PostMapping(value = "/setTradePwd")
    public FebsResponse setTradePwd(@RequestBody ForgetPwdDto forgetPwdDto) {
        return memberService.setTradePwd(forgetPwdDto);
@@ -115,7 +115,7 @@
        return memberService.moneyFlows(moneyFlowDto);
    }
    @ApiOperation(value = "转账")
    @ApiOperation(value = "FCM-转账")
    @PostMapping(value = "/transfer")
    public FebsResponse transfer(@RequestBody @Validated TransferDto transferDto) {
        memberService.transfer(transferDto);
src/main/java/cc/mrbird/febs/mall/controller/ApiMallProductController.java
@@ -26,19 +26,19 @@
    private final IApiMallProductService iApiMallProductService;
    @ApiOperation(value = "预约产品列表", notes = "预约产品列表")
    @ApiOperation(value = "FCM-预约产品列表", notes = "FCM-预约产品列表")
    @GetMapping(value = "/productNFTList")
    public FebsResponse productNFTList() {
        return new FebsResponse().success().data(iApiMallProductService.productNFTList());
    }
    @ApiOperation(value = "预约", notes = "预约")
    @ApiOperation(value = "FCM-预约", notes = "FCM-预约")
    @PostMapping(value = "/createNFT")
    public FebsResponse createNFT(@RequestBody @Valid ApiCreateNFTDto createNFTDto) {
        return iApiMallProductService.createNFT(createNFTDto);
    }
    @ApiOperation(value = "订单管理-列表", notes = "订单管理-列表")
    @ApiOperation(value = "FCM-订单管理-列表", notes = "FCM-订单管理-列表")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiOrderListVo.class)
    })
@@ -47,7 +47,7 @@
        return iApiMallProductService.orderList(apiOrderListDto);
    }
    @ApiOperation(value = "订单管理-查看提现详情", notes = "订单管理-查看提现详情")
    @ApiOperation(value = "FCM-订单管理-查看提现详情", notes = "FCM-订单管理-查看提现详情")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiOrderSellInfoVo.class)
    })
@@ -56,7 +56,7 @@
        return iApiMallProductService.orderSell(apiOrderSellInfoDto);
    }
    @ApiOperation(value = "订单管理-查看预约详情", notes = "订单管理-查看预约详情")
    @ApiOperation(value = "FCM-订单管理-查看预约详情", notes = "FCM-订单管理-查看预约详情")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiOrderBuyInfoVo.class)
    })
@@ -65,13 +65,25 @@
        return iApiMallProductService.orderBuy(apiOrderBuyInfoDto);
    }
    @ApiOperation(value = "FCM提现", notes = "FCM提现")
    @ApiOperation(value = "FCM-订单管理-查看预约详情-打款", notes = "FCM-订单管理-查看预约详情-打款")
    @PostMapping(value = "/orderBuyInsure")
    public FebsResponse orderBuyInsure(@RequestBody @Valid ApiOrderBuyInsureDto apiOrderBuyInsureDto) {
        return iApiMallProductService.orderBuyInsure(apiOrderBuyInsureDto);
    }
    @ApiOperation(value = "FCM-订单管理-查看提现详情-确认", notes = "FCM-订单管理-查看提现详情-确认")
    @PostMapping(value = "/orderSellInsure")
    public FebsResponse orderSellInsure(@RequestBody @Valid ApiOrderSellInsureDto apiOrderSellInsureDto) {
        return iApiMallProductService.orderSellInsure(apiOrderSellInsureDto);
    }
    @ApiOperation(value = "FCM-FCM提现", notes = "FCM-FCM提现")
    @PostMapping(value = "/outFcm")
    public FebsResponse outFcm(@RequestBody @Valid ApiOutFcmDto outFcmDto) {
        return iApiMallProductService.outFcm(outFcmDto);
    }
    @ApiOperation(value = "NFT提现", notes = "NFT提现")
    @ApiOperation(value = "FCM-NFT提现", notes = "FCM-NFT提现")
    @PostMapping(value = "/outNFT")
    public FebsResponse outNFT(@RequestBody @Valid ApiOutNFTDto outNFTDto) {
        return iApiMallProductService.outNFT(outNFTDto);
src/main/java/cc/mrbird/febs/mall/dto/ApiOrderBuyInsureDto.java
New file
@@ -0,0 +1,22 @@
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 = "ApiOrderBuyInsureDto", description = "参数接收类")
public class ApiOrderBuyInsureDto {
    @NotNull(message = "类型参数不能为空")
    private Long buyRecordId;//ApiOrderSellRecordInfoVo中的ID,预约单子表ID
    @NotNull(message = "类型参数不能为空")
    private String nftImg;//支付凭证
    @NotNull(message = "类型参数不能为空")
    private Integer type;//支付类型 1:微信 2:支付宝 3:银行转账 4:USDT转账
    @NotNull(message = "交易密码不能为空")
    @ApiModelProperty(value = "交易密码", example = "1")
    private String tradePassword;
}
src/main/java/cc/mrbird/febs/mall/dto/ApiOrderSellInsureDto.java
New file
@@ -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.NotNull;
@Data
@ApiModel(value = "ApiOrderSellInsureDto", description = "参数接收类")
public class ApiOrderSellInsureDto {
    @NotNull(message = "交易密码不能为空")
    private Long sellRecordId;//ApiOrderSellRecordInfoVo的id,提现子表的ID
    @NotNull(message = "交易密码不能为空")
    @ApiModelProperty(value = "交易密码", example = "1")
    private String tradePassword;
}
src/main/java/cc/mrbird/febs/mall/entity/MallProductBuy.java
@@ -18,9 +18,9 @@
    private Long sellId;//出售ID
    private Long productNftId;//预约NFTID
    private int state;//预约状态  0:失败 1:进行中 2:超时  3:已完成
    private int mateState;//匹配状态0:失败 1:匹配中 2:待支付 3:已支付 4:对方已确认 5:已完成
    private int mateState;//转换卖单状态 0:未转换 1:已转换
    private BigDecimal nftTotal;//nft预约额度
    private BigDecimal nftAva;//nft分配额度
    private BigDecimal nftAva;//待分配额度
    private Date orderTime;//匹配时间
    private Date payTime;//支付时间
src/main/java/cc/mrbird/febs/mall/entity/MallProductSellRecord.java
@@ -13,6 +13,7 @@
    private Long sellId;//
    private Long memberId;//
    private Long buyRecordId;//
    private Date orderTime;//匹配时间
    private Date payTime;//支付时间
    private BigDecimal nftCnt;//支付数量
src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyMapper.java
@@ -8,6 +8,8 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface MallProductBuyMapper extends BaseMapper<MallProductBuy> {
    MallProductBuy selectMemberIdAndNFTIdAndStateAndMateState(@Param("memberId")Long memberId,
                                                              @Param("productNFTId")Long productNFTId,
@@ -17,4 +19,6 @@
    IPage<ApiOrderListVo> selectListInPage(IPage<ApiOrderListVo> page, @Param("record")ApiOrderListDto apiOrderListDto);
    ApiOrderBuyInfoVo selectBuyById(@Param("id")Long productBuyId);
    List<MallProductBuy> selectListByStateAndProductNFTId(@Param("state")int value, @Param("nftId")Long nftId, @Param("mateState")int mateState);
}
src/main/java/cc/mrbird/febs/mall/mapper/MallProductBuyRecordMapper.java
@@ -11,4 +11,5 @@
    List<ApiOrderBuyRecordInfoVo> selectByBuyId(@Param("productBuyId")Long productBuyId);
    List<MallProductBuyRecord> selectListByBuyId(@Param("buyId")Long buyId,@Param("state")Integer state);
}
src/main/java/cc/mrbird/febs/mall/mapper/MallProductNftMapper.java
@@ -1,5 +1,6 @@
package cc.mrbird.febs.mall.mapper;
import cc.mrbird.febs.common.enumerates.ProductEnum;
import cc.mrbird.febs.mall.entity.MallProductBuy;
import cc.mrbird.febs.mall.entity.MallProductNft;
import cc.mrbird.febs.mall.entity.MallProductSell;
@@ -22,4 +23,6 @@
    IPage<AdminMallProductSellVo> getSellList(Page<AdminMallProductSellVo> page, @Param("record")MallProductSell mallProductSell);
    List<AdminMallProductSellPickVo> selectProductSellByState(@Param("state")int value);
    List<MallProductNft> selectListByState(@Param("state")ProductEnum productNftOpen);
}
src/main/java/cc/mrbird/febs/mall/mapper/MallProductSellRecordMapper.java
@@ -11,4 +11,5 @@
    List<ApiOrderSellRecordInfoVo> selectBySellId(@Param("productSellId")Long productSellId);
    List<MallProductSellRecord> selectListBySellId(@Param("sellId")Long sellId,@Param("state")Integer state);
}
src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
@@ -117,6 +117,14 @@
        agentService.perkAgent();
    }
    /**
     * 用户预约完成之后,根据产品周期,将用户买单变成买单
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void BuyToSell() {
        agentService.BuyToSell();
    }
src/main/java/cc/mrbird/febs/mall/service/IAgentService.java
@@ -39,4 +39,6 @@
    void achieveReleasePercent();
    void perkAgent();
    void BuyToSell();
}
src/main/java/cc/mrbird/febs/mall/service/IApiMallProductService.java
@@ -23,4 +23,8 @@
    FebsResponse orderSell(ApiOrderSellInfoDto apiOrderSellInfoDto);
    FebsResponse orderBuy(ApiOrderBuyInfoDto apiOrderBuyInfoDto);
    FebsResponse orderBuyInsure(ApiOrderBuyInsureDto apiOrderBuyInsureDto);
    FebsResponse orderSellInsure(ApiOrderSellInsureDto apiOrderSellInsureDto);
}
src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
@@ -57,4 +57,6 @@
    void selaHalfVoucher(String price);
    void fcmNFTExchangeMsg(String cnt);
    void fcmOrderSellInsureMsg(Long sellRecordId);
}
src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java
@@ -10,6 +10,8 @@
import cc.mrbird.febs.mall.vo.AdminTeamEqualsPerkVo;
import cc.mrbird.febs.system.mapper.UserMapper;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@@ -54,6 +56,12 @@
    private final MallGoodsMapper mallGoodsMapper;
    private final ICommonService commonService;
    private final MallProductBuyRecordMapper mallProductBuyRecordMapper;
    private final MallProductBuyMapper mallProductBuyMapper;
    private final MallProductSellMapper mallProductSellMapper;
    private final MallProductSellRecordMapper mallProductSellRecordMapper;
    private final MallProductNftMapper mallProductNftMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -810,5 +818,65 @@
        List<MallMember> secondLevelRecord = getStarRecord(thirdLevelRecord,  MemberLevelEnum.SECOND_LEVEL.name(), amount, orderNo, 0L,MoneyFlowTypeEnum.STAR_PERK_TWO.getValue());
    }
    @Override
    public void BuyToSell() {
        /**
         * nft产品周期到期的已完成买单变成卖单
         * 计算收益,本金
         */
        List<MallProductNft> mallProductNfts = mallProductNftMapper.selectList(null);
        if(CollUtil.isEmpty(mallProductNfts)){
            return;
        }
        DateTime now = DateUtil.date();
        for(MallProductNft mallProductNft : mallProductNfts){
            Long nftId = mallProductNft.getId();
            List<MallProductBuy> mallProductBuys = mallProductBuyMapper.selectListByStateAndProductNFTId(
                    ProductEnum.PRODUCT_BUY_SUCCESS.getValue(),
                    nftId,
                    ProductEnum.PRODUCT_BUY_MATE_STATE_FAIL.getValue());
            if(CollUtil.isEmpty(mallProductBuys)){
                continue;
            }
            //周期
            int cycle = mallProductNft.getCycle();
            //收益率
            BigDecimal profitPercent = mallProductNft.getProfit();
            for(MallProductBuy mallProductBuy : mallProductBuys){
                Date payTime = mallProductBuy.getPayTime();
                //偏移时间
                DateTime dateTime = DateUtil.offsetDay(payTime, cycle);
                int compare = DateUtil.compare(now, dateTime);
                if(compare <= 0){
                    /**
                     * 更新买单状态
                     * 收益生成一条卖单
                     * 本金生成一条卖单
                     */
                    mallProductBuy.setMateState(ProductEnum.PRODUCT_BUY_MATE_STATE_SUCCESS.getValue());
                    mallProductBuyMapper.updateById(mallProductBuy);
                    BigDecimal nftTotal = mallProductBuy.getNftTotal();
                    insertSell(mallProductBuy.getMemberId(),nftTotal,nftTotal,BigDecimal.ZERO,BigDecimal.ZERO);
                    BigDecimal profit = nftTotal.multiply(profitPercent.multiply(new BigDecimal(0.01)));
                    insertSell(mallProductBuy.getMemberId(),profit,profit,BigDecimal.ZERO,BigDecimal.ZERO);
                }
            }
        }
    }
    public void insertSell(Long memberId,BigDecimal nftCnt,BigDecimal nftCntAva,
                           BigDecimal nftFee,BigDecimal fcmFeeCnt){
        String orderNo = MallUtils.getOrderNum("NFT");
        MallProductSell mallProductSell = new MallProductSell();
        mallProductSell.setMemberId(memberId);
        mallProductSell.setOrderNo(orderNo);
        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);
    }
}
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallProductServiceImpl.java
@@ -16,6 +16,8 @@
import cc.mrbird.febs.mall.vo.*;
import cc.mrbird.febs.rabbit.producter.AgentProducer;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -91,7 +93,7 @@
        mallProductBuy.setOrderNo(orderNo);
        mallProductBuy.setProductNftId(mallProductNft.getId());
        mallProductBuy.setState(ProductEnum.PRODUCT_BUY_ON_GOING.getValue());
        mallProductBuy.setMateState(ProductEnum.PRODUCT_MATE_STATE_ON_GOING.getValue());
        mallProductBuy.setMateState(ProductEnum.PRODUCT_BUY_MATE_STATE_FAIL.getValue());
        mallProductBuy.setNftTotal(mallProductNft.getPriceNft());
        mallProductBuy.setNftAva(BigDecimal.ZERO);
        mallProductBuyMapper.insert(mallProductBuy);
@@ -328,4 +330,107 @@
        }
        return new FebsResponse().success().data(apiOrderBuyInfoVo);
    }
    @Override
    public FebsResponse orderBuyInsure(ApiOrderBuyInsureDto apiOrderBuyInsureDto) {
        Long memberId = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = memberMapper.selectById(memberId);
        Long buyRecordId = apiOrderBuyInsureDto.getBuyRecordId();
        String nftImg = apiOrderBuyInsureDto.getNftImg();
        Integer type = apiOrderBuyInsureDto.getType();
        String tradePassword = SecureUtil.md5(apiOrderBuyInsureDto.getTradePassword());
        /**
         * 验证订单是否存在
         * 更新买单状态
         * 更新卖单状态
         * 生成流水信息
         */
        if(!tradePassword.equals(mallMember.getTradePassword())){
            throw new FebsException("请输入正确的交易密码");
        }
        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(buyRecordId);
        if(ObjectUtil.isEmpty(mallProductBuyRecord)){
            throw new FebsException("记录不存在");
        }
        Integer state = mallProductBuyRecord.getState();
        if(ProductEnum.PRODUCT_MATE_STATE_WAIT_PAY.getValue() != state){
            throw new FebsException("记录不是待支付状态");
        }
        MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(mallProductBuyRecord.getSellRecordId());
        if(ObjectUtil.isEmpty(mallProductSellRecord)){
            throw new FebsException("记录不存在");
        }
        Integer stateSell = mallProductSellRecord.getState();
        if(ProductEnum.PRODUCT_MATE_STATE_WAIT_PAY.getValue() != stateSell){
            throw new FebsException("记录不是待支付状态");
        }
        DateTime payTime = DateUtil.date();
        mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue());
        mallProductBuyRecord.setPayTime(payTime);
        mallProductBuyRecord.setNftImg(nftImg);
        mallProductBuyRecord.setType(type);
        mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
        mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue());
        mallProductSellRecord.setPayTime(payTime);
        mallProductSellRecord.setNftImg(nftImg);
        mallProductSellRecord.setType(type);
        mallProductSellRecordMapper.updateById(mallProductSellRecord);
        String orderNo = MallUtils.getOrderNum("ZF");
        iMallMoneyFlowService.addMoneyFlow(
                memberId,
                mallProductBuyRecord.getPickNftCnt(),
                MoneyFlowTypeNewEnum.PAY.getValue(),
                orderNo,
                mallMember.getId(),
                FlowTypeNewEnum.NFT.getValue(),
                MoneyFlowTypeNewEnum.PAY.getDescrition());
        return new FebsResponse().success();
    }
    @Override
    public FebsResponse orderSellInsure(ApiOrderSellInsureDto apiOrderSellInsureDto) {
        Long memberId = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = memberMapper.selectById(memberId);
        String tradePassword = SecureUtil.md5(apiOrderSellInsureDto.getTradePassword());
        Long sellRecordId = apiOrderSellInsureDto.getSellRecordId();
        /**
         * 验证订单是否存在
         * 更新买单状态
         * 更新卖单状态
         * 生成流水信息
         */
        if(!tradePassword.equals(mallMember.getTradePassword())){
            throw new FebsException("请输入正确的交易密码");
        }
        MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(sellRecordId);
        if(ObjectUtil.isEmpty(mallProductSellRecord)){
            throw new FebsException("记录不存在");
        }
        Integer stateSell = mallProductSellRecord.getState();
        if(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue() != stateSell){
            throw new FebsException("记录不是已支付状态");
        }
        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(mallProductSellRecord.getBuyRecordId());
        if(ObjectUtil.isEmpty(mallProductBuyRecord)){
            throw new FebsException("记录不存在");
        }
        Integer state = mallProductBuyRecord.getState();
        if(ProductEnum.PRODUCT_MATE_STATE_PAY.getValue() != state){
            throw new FebsException("记录不是已支付状态");
        }
        mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_CONFIRM.getValue());
        mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
        mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_CONFIRM.getValue());
        mallProductSellRecordMapper.updateById(mallProductSellRecord);
        agentProducer.sendFcmOrderSellInsureMsg(sellRecordId);
        return new FebsResponse().success();
    }
}
src/main/java/cc/mrbird/febs/mall/service/impl/MallNewsInfoServiceImpl.java
@@ -266,6 +266,8 @@
        //更新卖单
        mallProductSell.setNftCntAva(mallProductSell.getNftCntAva().subtract(pickNftCnt));
        mallProductSellMapper.updateById(mallProductSell);
        mallProductSellRecord.setBuyRecordId(mallProductBuyRecord.getId());
        mallProductSellRecordMapper.updateById(mallProductSellRecord);
        //更新买单
        mallProductBuy.setNftAva(mallProductBuy.getNftAva().subtract(pickNftCnt));
        mallProductBuyMapper.updateById(mallProductBuy);
src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
@@ -60,6 +60,10 @@
    private final MallScoreAchieveReleaseMapper mallScoreAchieveReleaseMapper;
    private final MallScoreVoucherMapper mallScoreVoucherMapper;
    private final CommonService commonService;
    private final MallProductBuyRecordMapper mallProductBuyRecordMapper;
    private final MallProductBuyMapper mallProductBuyMapper;
    private final MallProductSellMapper mallProductSellMapper;
    private final MallProductSellRecordMapper mallProductSellRecordMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -1163,6 +1167,67 @@
        }
    }
    @Override
    public void fcmOrderSellInsureMsg(Long sellRecordId) {
        /**
         * 买单确认
         * 判断买单是否存在、是否已支付
         * 判断买单是否存在、是否已支付
         * 更新卖单状态
         * 更新买单状态
         */
        MallProductSellRecord mallProductSellRecord = mallProductSellRecordMapper.selectById(sellRecordId);
        if(ObjectUtil.isEmpty(mallProductSellRecord)){
            return;
        }
        Integer state = mallProductSellRecord.getState();
        if(ProductEnum.PRODUCT_MATE_STATE_CONFIRM.getValue() != state){
            return;
        }
        MallProductBuyRecord mallProductBuyRecord = mallProductBuyRecordMapper.selectById(mallProductSellRecord.getBuyRecordId());
        if(ObjectUtil.isEmpty(mallProductBuyRecord)){
            return;
        }
        Integer stateBuy = mallProductBuyRecord.getState();
        if(ProductEnum.PRODUCT_MATE_STATE_CONFIRM.getValue() != stateBuy){
            return;
        }
        mallProductSellRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FINISH.getValue());
        mallProductSellRecordMapper.updateById(mallProductSellRecord);
        mallProductBuyRecord.setState(ProductEnum.PRODUCT_MATE_STATE_FINISH.getValue());
        mallProductBuyRecordMapper.updateById(mallProductBuyRecord);
        Long sellId = mallProductSellRecord.getSellId();
        //已完成的买单
        List<MallProductSellRecord> mallProductSellRecords = mallProductSellRecordMapper.selectListBySellId(sellId,ProductEnum.PRODUCT_MATE_STATE_FINISH.getValue());
        if(CollUtil.isEmpty(mallProductSellRecords)){
            return;
        }
        //实际支付总数
        BigDecimal nftCntTotal = mallProductSellRecords.stream().map(MallProductSellRecord::getNftCnt).reduce(BigDecimal.ZERO, BigDecimal::add);
        MallProductSell mallProductSell = mallProductSellMapper.selectById(sellId);
        if(nftCntTotal.compareTo(mallProductSell.getNftCnt()) < 0){
            return;
        }
        mallProductSell.setState(ProductEnum.PRODUCT_SELL_SUCCESS.getValue());
        mallProductSellMapper.updateById(mallProductSell);
        Long buyId = mallProductBuyRecord.getBuyId();
        List<MallProductBuyRecord> mallProductBuyRecords = mallProductBuyRecordMapper.selectListByBuyId(buyId,ProductEnum.PRODUCT_MATE_STATE_FINISH.getValue());
        if(CollUtil.isEmpty(mallProductBuyRecords)){
            return;
        }
        //实际支付总数
        BigDecimal nftCntTotalBuy = mallProductBuyRecords.stream().map(MallProductBuyRecord::getPickNftCnt).reduce(BigDecimal.ZERO, BigDecimal::add);
        MallProductBuy mallProductBuy = mallProductBuyMapper.selectById(buyId);
        if(nftCntTotalBuy.compareTo(mallProductBuy.getNftTotal()) < 0){
            return;
        }
        mallProductBuy.setState(ProductEnum.PRODUCT_BUY_SUCCESS.getValue());
        mallProductBuy.setPayTime(DateUtil.date());
        mallProductBuyMapper.updateById(mallProductBuy);
    }
    public static void main(String[] args) {
        BigDecimal divide = new BigDecimal(12000).divide(new BigDecimal(10000), 0, BigDecimal.ROUND_DOWN);
        System.out.println(divide);
src/main/java/cc/mrbird/febs/mall/vo/ApiOrderBuyInfoVo.java
@@ -15,7 +15,7 @@
    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 BigDecimal nftAva;//待分配
    private Date orderTime;//匹配时间
    private Date payTime;//支付时间
    private List<ApiOrderBuyRecordInfoVo> apiOrderBuyRecordInfoVos;
src/main/java/cc/mrbird/febs/pay/service/impl/AliPayServiceImpl.java
@@ -55,7 +55,7 @@
    @Override
    public String aliPay(MallOrderInfo orderInfo) {
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setSubject("鸿楼梦商品支付");
        model.setSubject("GFA商品支付");
        model.setBody(orderInfo.getName());
        model.setOutTradeNo(orderInfo.getOrderNo());
        model.setTimeoutExpress("15m");
src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
@@ -25,4 +25,6 @@
    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";
    //卖单用户确认
    public static final String QUEUE_FCM_ORDER_SELL_INSURE = "queue_fcm_order_sell_insure";
}
src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
@@ -103,7 +103,19 @@
        try {
            memberProfitService.fcmNFTExchangeMsg(cnt);
        } catch (Exception e) {
            log.error("强制卖出异常", e);
            log.error("收到FCM实时兑换销毁数量异常", e);
            // todo 更新表
        }
    }
    @RabbitListener(queues = QueueConstants.QUEUE_FCM_ORDER_SELL_INSURE)
    public void fcmOrderSellInsureMsg(Long sellRecordId) {
        log.info("收到卖单用户确认:{}",sellRecordId);
        try {
            memberProfitService.fcmOrderSellInsureMsg(sellRecordId);
        } catch (Exception e) {
            log.error("收到卖单用户确认异常", e);
            // todo 更新表
        }
src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
@@ -5,6 +5,10 @@
@Getter
public enum RabbitQueueEnum {
    //卖单用户确认
    FCMPAY_FCM_ORDER_SELL_INSURE("exchange_fcm_order_sell_insure",
            "route_key_fcm_order_sell_insure",
            QueueConstants.QUEUE_FCM_ORDER_SELL_INSURE),
    FCMPAY_FCM_NFT_EXCHANGE("exchange_fcm_nft_exchange",
            "route_key_fcm_nft_exchange",
src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
@@ -88,6 +88,12 @@
        rabbitTemplate.convertAndSend(RabbitQueueEnum.FCMPAY_FCM_NFT_EXCHANGE.getExchange(), RabbitQueueEnum.FCMPAY_FCM_NFT_EXCHANGE.getRoute(),value);
    }
    public void sendFcmOrderSellInsureMsg(Long sellRecordId) {
        log.info("发送卖单用户确认:{}",sellRecordId);
        rabbitTemplate.convertAndSend(RabbitQueueEnum.FCMPAY_FCM_ORDER_SELL_INSURE.getExchange(),
                RabbitQueueEnum.FCMPAY_FCM_ORDER_SELL_INSURE.getRoute(),sellRecordId);
    }
    /**
     * 发送代理自动升级消息
     *
src/main/resources/mapper/modules/MallProductBuyMapper.xml
@@ -30,4 +30,13 @@
        where a.id = #{id}
    </select>
    <select id="selectListByStateAndProductNFTId" resultType="cc.mrbird.febs.mall.entity.MallProductBuy">
        select a.*
        from mall_product_buy a
        where a.product_nft_id = #{nftId}
        and a.state = #{state}
        and a.mate_state = #{mateState}
        order by a.CREATED_TIME asc
    </select>
</mapper>
src/main/resources/mapper/modules/MallProductBuyRecordMapper.xml
@@ -19,4 +19,11 @@
        where a.buy_id = #{productBuyId}
    </select>
    <select id="selectListByBuyId" resultType="cc.mrbird.febs.mall.entity.MallProductBuyRecord">
        select a.*
        from mall_product_buy_record a
        where a.buy_id = #{buyId}
          and a.state = #{state}
    </select>
</mapper>
src/main/resources/mapper/modules/MallProductNftMapper.xml
@@ -58,4 +58,11 @@
        and a.nft_cnt_ava > 0
    </select>
    <select id="selectListByState" resultType="cc.mrbird.febs.mall.entity.MallProductNft">
        SELECT
        a.*
        FROM mall_product_nft a
        where a.state = #{state}
    </select>
</mapper>
src/main/resources/mapper/modules/MallProductSellRecordMapper.xml
@@ -19,4 +19,11 @@
        where a.sell_id = #{productSellId}
    </select>
    <select id="selectListBySellId" resultType="cc.mrbird.febs.mall.entity.MallProductSellRecord">
        select a.*
        from mall_product_sell_record a
        where a.sell_id = #{sellId}
            and a.state = #{state}
    </select>
</mapper>
src/main/resources/templates/error/403.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>鸿楼梦 权限系统</title>
    <title>GFA 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
src/main/resources/templates/error/404.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>鸿楼梦 权限系统</title>
    <title>GFA 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
src/main/resources/templates/error/500.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>鸿楼梦 权限系统</title>
    <title>GFA 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
src/main/resources/templates/febs/views/layout.html
@@ -64,7 +64,7 @@
        <div class="layui-side-scroll">
            <div class="layui-logo" style="cursor: pointer">
                <img data-th-src="@{febs/images/logo.png}">
                <span>鸿楼梦 权限系统</span>
                <span>GFA 权限系统</span>
            </div>
            <script
                    type="text/html"
src/main/resources/templates/febs/views/login.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>鸿楼梦 权限系统</title>
    <title>GFA 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
@@ -19,7 +19,7 @@
        <div class="layui-container">
            <div class="layui-row">
                <div class="layui-col-xs12 layui-col-lg4 layui-col-lg-offset4 febs-tc">
                    <div class="layui-logo"><span><b>鸿楼梦</b> 权限系统</span></div>
                    <div class="layui-logo"><span><b>GFA</b> 权限系统</span></div>
                </div>
                <div class="layui-col-xs12 layui-col-lg4 layui-col-lg-offset4" id="login-div">
                    <div class="layui-form" lay-filter="login-form">