xiaoyong931011
2022-10-19 6c4d0c0cdf9f1991e538b4b600aa32980347c824
20221019
36 files modified
76 files added
6915 ■■■■■ changed files
pom.xml 14 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/advise/MyRequestBodyAdvise.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/advise/MyResponseBodyAdvise.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/configure/FebsConfigure.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java 6 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/contants/AppContants.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/entity/BaseEntity.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java 23 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/utils/LoginUserUtil.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/AdminBannerController.java 114 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/AdminNewsInfoController.java 116 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/AdminWalletCoinController.java 97 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ApiCommonController.java 35 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ApiDappMemberController.java 29 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ApiIgtOnHookPlanController.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ApiMallNewsController.java 71 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ApiWalletCoinController.java 63 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/MemberController.java 56 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ViewBannerController.java 50 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ViewController.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ViewNewsController.java 83 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ViewWalletCoinController.java 62 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/ApiAmountChangeDto.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/ApiStartDto.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/ApiTransferInsideDto.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/ApiTransferOutsideDto.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/ApiTransferPasswordDto.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/LoginDto.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/MallNewsInfoDto.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/NewsListDto.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/RegisterDto.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/TouristLoginDto.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/DappAccountMoneyChangeEntity.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/DappMemberEntity.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/IgtOnHookPlanOrder.java 33 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/IgtOnHookPlanOrderItem.java 32 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/MallNewsCategory.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/MallNewsInfo.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/MemberCoinWithdrawEntity.java 66 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/PlatformBanner.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/enumerate/DataDictionaryEnum.java 69 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/enumerate/MemberOnHookPlanEnum.java 105 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/DappAccountMoneyChangeDao.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/DappMemberDao.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/DappWalletCoinDao.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/IgtOnHookPlanOrderDao.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/IgtOnHookPlanOrderItemDao.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/MallNewsCategoryMapper.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/MallNewsInfoMapper.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/MemberCoinWithdrawDao.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/PlatformBannerMapper.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/AdminOperationService.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/ApiIgtOnHookPlanService.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/DappMemberService.java 34 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/DappSystemService.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/DappWalletService.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/IAdminBannerService.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/IApiMallNewsService.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/IMallNewsInfoService.java 35 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/MemberOnHookPlan.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/AdminBannerServiceImpl.java 70 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/AdminOperationServiceImpl.java 119 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/ApiIgtOnHookPlanServiceImpl.java 256 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/ApiMallNewsServiceImpl.java 92 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/DappMemberServiceImpl.java 354 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java 66 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java 212 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/MallNewsInfoServiceImpl.java 148 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/utils/CaptchaUtil.java 93 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/utils/KaptchaConfig.java 47 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/utils/OssUtils.java 32 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/utils/UUIDUtil.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/AdminMallNewsInfoVo.java 36 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/AdminMemberCoinWithdrawVo.java 54 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/AdminTransferInsideSetVo.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/ApiAmountChangeListVo.java 25 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/ApiMemberWalletCoinVo.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/ApiPlanInfoVo.java 31 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/MemberInfoVo.java 34 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/NewsListVo.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/OnHookPlanVo.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/job/OnHookPlanJob.java 144 ●●●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 22 ●●●● patch | view | raw | blame | history
src/main/resources/application-test.yml 4 ●●●● patch | view | raw | blame | history
src/main/resources/application.yml 4 ●●●● patch | view | raw | blame | history
src/main/resources/i18n/message_en_US.properties 33 ●●●●● patch | view | raw | blame | history
src/main/resources/i18n/message_zh_CN.properties 34 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/DappAccountMoneyChangeDao.xml 21 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/DappMemberDao.xml 48 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/DappWalletCoinDao.xml 52 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/IgtOnHookPlanOrderDao.xml 41 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/IgtOnHookPlanOrderItemDao.xml 37 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/MallNewsCategoryMapper.xml 9 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/MallNewsInfoMapper.xml 28 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/MemberCoinWithdrawMapper.xml 27 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/PlatformBannerMapper.xml 13 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/banner/platformBanner.html 169 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/banner/platformBannerAdd.html 145 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/banner/platformBannerDetail.html 162 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/dapp/member-level-set.html 128 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/dapp/member.html 343 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/dapp/on-hook-plan-set.html 147 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/news/newsCategory.html 137 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/news/newsCategoryAdd.html 68 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/news/newsInfoAdd.html 173 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/news/newsInfoList.html 169 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/news/newsInfoUpdate.html 233 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/walletCoin/transferInsideList.html 170 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/walletCoin/transferInsideSet.html 117 ●●●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/ChainTest.java 258 ●●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/JunitTest.java 102 ●●●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/MemberTest.java 243 ●●●● patch | view | raw | blame | history
pom.xml
@@ -22,9 +22,23 @@
        <swagger.ui>2.9.2</swagger.ui>
        <tomcat.version>9.0.31</tomcat.version>
        <hutool.version>5.3.1</hutool.version>
        <aliyun-oss.version>3.8.0</aliyun-oss.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>${aliyun-oss.version}</version>
        </dependency>
        <dependency>
            <groupId>taobao</groupId>
            <artifactId>taobao-sdk</artifactId>
src/main/java/cc/mrbird/febs/common/advise/MyRequestBodyAdvise.java
@@ -15,7 +15,7 @@
 * @author wzy
 * @date 2022-06-14
 **/
@ControllerAdvice
//@ControllerAdvice
public class MyRequestBodyAdvise implements RequestBodyAdvice {
    @Override
src/main/java/cc/mrbird/febs/common/advise/MyResponseBodyAdvise.java
@@ -16,7 +16,7 @@
 * @author wzy
 * @date 2022-06-14
 **/
@ControllerAdvice
//@ControllerAdvice
public class MyResponseBodyAdvise implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
src/main/java/cc/mrbird/febs/common/configure/FebsConfigure.java
@@ -71,7 +71,7 @@
        SwaggerProperties swagger = properties.getSwagger();
        ParameterBuilder parameterBuilder = new ParameterBuilder();
        List<Parameter> parameters = new ArrayList<Parameter>();
        parameterBuilder.name("address").description("address地址").modelRef(new ModelRef("string")).parameterType("header")
        parameterBuilder.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header")
                .required(false).build();
        parameters.add(parameterBuilder.build());
        return new Docket(DocumentationType.SWAGGER_2)
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
@@ -23,9 +23,13 @@
//        registration.excludePathPatterns("/api/common/**");
//
        InterceptorRegistration registration = registry.addInterceptor(new DappInterceptor());
//        InterceptorRegistration registration = registry.addInterceptor(new DappInterceptor());
//        registration.addPathPatterns("/dapi/**");
//        registration.excludePathPatterns("/dapi/common/**");
        InterceptorRegistration registration = registry.addInterceptor(new LoginInterceptor());
        registration.addPathPatterns("/dapi/**");
        registration.excludePathPatterns("/dapi/common/**");
        registration.excludePathPatterns("/api/news/**");
    }
    /**
src/main/java/cc/mrbird/febs/common/contants/AppContants.java
@@ -1,6 +1,7 @@
package cc.mrbird.febs.common.contants;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.LinkedList;
public class AppContants {
@@ -50,6 +51,11 @@
     * 初始化金额
     */
    public static final BigDecimal INIT_MONEY = BigDecimal.ZERO;
    /**
     * 游客初始化金额
     */
    public static final BigDecimal TOURIST_INIT_MONEY = new BigDecimal("5100");
    public static final Integer INIT_SIMULATE_MONEY = 5000;
@@ -182,4 +188,10 @@
    public static final BigDecimal NFT_ACTIVE_PRICE = new BigDecimal("10");
    public static final String REDIS_KEY_TFC_NEW_PRICE = "TFC_NEW_PRICE";
    public static final String MEMBER_TRANSFER_CODE = "123456";
    public static final String MEMBER_LOGIN_CODE = "123456";
    public static final BigDecimal ONHOOK_BASIC_AMOUNT = new BigDecimal(51);
}
src/main/java/cc/mrbird/febs/common/entity/BaseEntity.java
@@ -34,4 +34,7 @@
    @TableField(exist = false)
    private Long currentUser;
//
//    @TableField(exist = false)
//    private String adminUserInvitedId;
}
src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java
@@ -31,20 +31,25 @@
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(request.getHeader(":path"));
        String headerToken = request.getHeader("key");
//        System.out.println(request.getHeader(":path"));
        String headerToken = request.getHeader("token");
        if (StringUtils.isBlank(headerToken)) {
            responseUnAuth(response);
            return false;
        }
        String userJsonStr = redisUtils.getString(headerToken);
        String token = resolveToken(headerToken);
        if (token == null || AppContants.TIME_OUT.equals(token)) {
            responseUnAuth(response);
            return false;
        }
        String userJsonStr = redisUtils.getString(token);
        if (StringUtils.isBlank(userJsonStr)) {
            responseUnAuth(response);
            return false;
        }
        DappMemberEntity member = JSON.parseObject(userJsonStr, DappMemberEntity.class);
        request.getSession().setAttribute("member", member);
        return true;
    }
@@ -84,8 +89,16 @@
        boolean isDebug = false;
        if (!isDebug) {
            long currentTime = System.currentTimeMillis();
            return currentTime - time <= 10000;
            return currentTime - time <= 3600000;
        }
        return true;
    }
    public static void main(String[] args) {
        String token = "Xb3pSziGry+DwmaeZZGzKBA0U7pceLyhgUOUV4IQh7RmIvaC0La3u8xIzU6jJyViiB5UmdIbn2aYeUaAvagh8uFGn6Q2yzDKcogReqU4/8rrPu295AIGjazHsYhtA+QQaFQHS2lcuZnjaXr0gCyT51FVJoRAP0GNEmOKzD1FI5w=";
        RSA rsa = new RSA(AppContants.PRIVATE_KEY, null);
        String[] tokens = StrUtil.split(rsa.decryptStr(token, KeyType.PrivateKey), "_");
        System.out.print(tokens[0]);
        System.out.print(tokens[1]);
    }
}
src/main/java/cc/mrbird/febs/common/utils/LoginUserUtil.java
@@ -33,6 +33,13 @@
        return sha3(append.toString());
    }
    public static String getLoginTokenKey(Long memberId, String nonce) {
        StringBuilder sb = new StringBuilder();
        StringBuilder append = sb.append(memberId).append(":").append(nonce);
        return sha3(append.toString());
    }
    public static String sha3(String str) {
        Keccak.DigestKeccak kecc = new Keccak.Digest256();
        kecc.update(str.getBytes(StandardCharsets.UTF_8));
src/main/java/cc/mrbird/febs/dapp/controller/AdminBannerController.java
New file
@@ -0,0 +1,114 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.annotation.ControllerEndpoint;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.entity.PlatformBanner;
import cc.mrbird.febs.dapp.service.IAdminBannerService;
import cc.mrbird.febs.dapp.utils.OssUtils;
import cn.hutool.core.util.IdUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/admin/banner")
public class AdminBannerController extends BaseController {
    @Autowired
    private IAdminBannerService iAdminBannerService;
    /**
     * 轮播图---列表
     */
    @GetMapping("platformBanner")
    public FebsResponse platformBanner(PlatformBanner platformBannerEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(iAdminBannerService.findPlatformBannerInPage(platformBannerEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 轮播图---确认
     * @return
     */
    @PostMapping("platformBannerConfirm")
    @ControllerEndpoint(operation = "轮播图---确认", exceptionMessage = "设置失败")
    public FebsResponse platformBannerConfirm(@Valid PlatformBanner platformBannerEntity) {
        return iAdminBannerService.platformBannerConfirm(platformBannerEntity);
    }
    /**
     * 轮播图---删除
     * @return
     */
    @GetMapping("platformBannerDelete/{id}")
    @ControllerEndpoint(operation = "轮播图---删除", exceptionMessage = "删除失败")
    public FebsResponse platformBannerDelete(@NotNull(message = "{required}") @PathVariable Long id) {
        return iAdminBannerService.platformBannerDelete(id);
    }
    /**
     * 轮播图---新增
     */
    @RequiresPermissions("platformBanner:add")
    @PostMapping("platformBannerAdds")
    @ControllerEndpoint(operation = "轮播图---新增", exceptionMessage = "新增失败")
    public FebsResponse platformBannerAdds(@Valid PlatformBanner platformBannerEntity) {
        iAdminBannerService.platformBannerAdd(platformBannerEntity);
        return new FebsResponse().success();
    }
    /**
     *  图片上传
     * @return
     */
    @PostMapping(value = "/uploadFileBase64")
    @ControllerEndpoint(operation = "图片上传", exceptionMessage = "上传失败")
    public Map<String,Object> uploadFileBase64(@RequestBody @Validated MultipartFile file) {
        if (file.isEmpty()) {
            new FebsResponse().message("上传文件为空");
        }
        //文件加密
        BASE64Encoder base64Encoder =new BASE64Encoder();
        String base64EncoderImg = null;
        try {
            base64EncoderImg = base64Encoder.encode(file.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        String imageFuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
//      String imageFuffix = ".png";
        String imageNames = System.currentTimeMillis() + IdUtil.simpleUUID() + imageFuffix;
        String imageName = "uploadeFile/" + imageNames;
        OssUtils.uploadFileWithBase64(base64EncoderImg, imageName);
        String bucket_name ="https://excoin.oss-cn-hangzhou.aliyuncs.com";
        String url = bucket_name + "/" + imageName;
        Map<String,Object> map = new HashMap<String,Object>();
        Map<String,Object> map2 = new HashMap<String,Object>();
        map.put("code",0);//0表示成功,1失败
        map.put("msg","上传成功");//提示消息
        map.put("data",map2);
        map2.put("src",url);//图片url
        map2.put("title",imageNames);//图片名称,这个会显示在输入框里
        return map;
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/AdminNewsInfoController.java
New file
@@ -0,0 +1,116 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.annotation.ControllerEndpoint;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.dto.MallNewsInfoDto;
import cc.mrbird.febs.dapp.entity.MallNewsCategory;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.service.IMallNewsInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/admin/news")
public class AdminNewsInfoController extends BaseController {
    private final IMallNewsInfoService mallNewsInfoService;
    /**
     * 新闻中心-列表
     * @param mallNewsInfo
     * @param request
     * @return
     */
    @GetMapping("getNewInfoList")
    public FebsResponse getNewInfoList(MallNewsInfo mallNewsInfo, QueryRequest request) {
        Map<String, Object> data = getDataTable(mallNewsInfoService.getNewInfoList(mallNewsInfo, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 新闻中心-新增
     */
    @PostMapping("addNewsInfo")
    @ControllerEndpoint(operation = " 新闻中心-新增", exceptionMessage = "操作失败")
    public FebsResponse addNewsInfo(@Valid MallNewsInfoDto mallNewsInfoDto) {
        return mallNewsInfoService.addNewsInfo(mallNewsInfoDto);
    }
    /**
     * 新闻公告-删除
     */
    @GetMapping("delNews/{id}")
    @ControllerEndpoint(operation = " 新闻中心-删除", exceptionMessage = "操作失败")
    public FebsResponse delNews(@NotNull(message = "{required}") @PathVariable Long id) {
        return mallNewsInfoService.delNews(id);
    }
    /**
     * 新闻中心-更新
     */
    @PostMapping("updateNewsInfo")
    @ControllerEndpoint(operation = "新闻中心-更新", exceptionMessage = "操作失败")
    public FebsResponse updateNewsInfo(@Valid MallNewsInfoDto mallNewsInfoDto) {
        return mallNewsInfoService.updateNewsInfo(mallNewsInfoDto);
    }
    @GetMapping("findNewsCategoryList")
    @ControllerEndpoint(operation = "新闻分类列表", exceptionMessage = "获取失败")
    public FebsResponse findNewsCategoryList(MallNewsCategory mallNewsCategory, QueryRequest request) {
        return new FebsResponse().success().data(getDataTable(mallNewsInfoService.findNewsCategoryInPage(mallNewsCategory, request)));
    }
    @PostMapping("addOrModifyNewsCategory")
    @ControllerEndpoint(operation = "新闻分类", exceptionMessage = "新增失败")
    public FebsResponse addOrModifyNewsCategory(MallNewsCategory mallNewsCategory) {
        mallNewsInfoService.addOrModifyNewsCategory(mallNewsCategory);
        return new FebsResponse().success().message("新增成功");
    }
    @GetMapping(value = "findAllCategoryList")
    public FebsResponse findAllCategoryList() {
        List<MallNewsCategory> categories = mallNewsInfoService.findAllCategory();
        return new FebsResponse().success().data(categories);
    }
    @PostMapping(value = "/topNews/{id}")
    public FebsResponse topNews(@PathVariable Long id) {
        MallNewsInfo mallNewsInfo = new MallNewsInfo();
        mallNewsInfo.setIsTop(1);
        mallNewsInfo.setId(id);
        mallNewsInfoService.updateById(mallNewsInfo);
        return new FebsResponse().success();
    }
    @PostMapping(value = "/unTopNews/{id}")
    public FebsResponse unTopNews(@PathVariable Long id) {
        MallNewsInfo mallNewsInfo = new MallNewsInfo();
        mallNewsInfo.setIsTop(2);
        mallNewsInfo.setId(id);
        mallNewsInfoService.updateById(mallNewsInfo);
        return new FebsResponse().success();
    }
    /**
     * 新闻中心-删除
     */
    @GetMapping("delNewsInfo/{id}")
    @ControllerEndpoint(operation = " 新闻中心-删除", exceptionMessage = "操作失败")
    public FebsResponse delNewsInfo(@NotNull(message = "{required}") @PathVariable Long id) {
        return mallNewsInfoService.delNewsInfo(id);
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/AdminWalletCoinController.java
New file
@@ -0,0 +1,97 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.annotation.ControllerEndpoint;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.common.utils.FebsUtil;
import cc.mrbird.febs.dapp.entity.DataDictionaryCustom;
import cc.mrbird.febs.dapp.entity.MemberCoinWithdrawEntity;
import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum;
import cc.mrbird.febs.dapp.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.dapp.service.AdminOperationService;
import cc.mrbird.febs.dapp.vo.AdminTransferInsideSetVo;
import cc.mrbird.febs.system.entity.User;
import cc.mrbird.febs.system.service.IUserService;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.util.Map;
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/admin/walletCoin")
public class AdminWalletCoinController extends BaseController {
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    private final AdminOperationService adminOperationService;
    private final IUserService userService;
    /**
     * IGT内部转账规则设置 -- 更新
     */
    @PostMapping(value = "/transferInsideUpdate")
    public FebsResponse transferInsideUpdate(AdminTransferInsideSetVo adminTransferInsideSetVo) {
        Integer serviceFee = adminTransferInsideSetVo.getServiceFee() == null ? 0 : adminTransferInsideSetVo.getServiceFee();
        DataDictionaryCustom serviceFeeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.SERVICE_FEE.getType(), DataDictionaryEnum.SERVICE_FEE.getCode());
        serviceFeeDic.setValue(serviceFee.toString());
        dataDictionaryCustomMapper.updateById(serviceFeeDic);
        Integer outAccountProfit = adminTransferInsideSetVo.getOutAccountProfit() == null ? 30 : adminTransferInsideSetVo.getOutAccountProfit();
        DataDictionaryCustom outAccountProfitDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getType(), DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getCode());
        outAccountProfitDic.setValue(outAccountProfit.toString());
        dataDictionaryCustomMapper.updateById(outAccountProfitDic);
        Integer accountRelation = adminTransferInsideSetVo.getAccountRelation() == null ? 1 : adminTransferInsideSetVo.getAccountRelation();
        DataDictionaryCustom accountRelationDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.ACCOUNT_RELATION.getType(), DataDictionaryEnum.ACCOUNT_RELATION.getCode());
        accountRelationDic.setValue(accountRelation.toString());
        dataDictionaryCustomMapper.updateById(accountRelationDic);
        Integer withdrawTimes = adminTransferInsideSetVo.getWithdrawTimes() == null ? 5 : adminTransferInsideSetVo.getWithdrawTimes();
        DataDictionaryCustom withdrawTimesDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.WITHDRAW_TIMES.getType(), DataDictionaryEnum.WITHDRAW_TIMES.getCode());
        withdrawTimesDic.setValue(withdrawTimes.toString());
        dataDictionaryCustomMapper.updateById(withdrawTimesDic);
        return new FebsResponse().success();
    }
    /**
     * IGT获取提现转账列表
     */
    @GetMapping("findWithdrawInPage")
    public FebsResponse findWithdrawInPage(MemberCoinWithdrawEntity memberCoinWithdrawEntity, QueryRequest request) {
//        User user = super.getCurrentUser();
        User currentUser = FebsUtil.getCurrentUser();
        User currentUserDetail = userService.findByName(currentUser.getUsername());
        if(ObjectUtil.isNotEmpty(currentUserDetail.getDescription())){
            memberCoinWithdrawEntity.setDescription(currentUser.getDescription());
        }
        Map<String, Object> data = getDataTable(adminOperationService.findMemberWithdrawCoinAllOneInPage(memberCoinWithdrawEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * IGT获取提现转账列表-同意
     */
    @GetMapping("agreeWithdraw/{id}")
    @ControllerEndpoint(operation = "IGT获取提现转账列表-同意", exceptionMessage = "操作失败")
    public FebsResponse agreeWithdraw(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminOperationService.agreeWithdraw(id);
    }
    /**
     * IGT获取提现转账列表-拒绝
     */
    @GetMapping("disagreeWithdraw/{id}")
    @ControllerEndpoint(operation = "IGT获取提现转账列表-拒绝", exceptionMessage = "操作失败")
    public FebsResponse disagreeWithdraw(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminOperationService.disagreeWithdraw(id);
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ApiCommonController.java
@@ -2,21 +2,18 @@
import cc.mrbird.febs.common.annotation.EncryptEnable;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.ApproveDto;
import cc.mrbird.febs.dapp.dto.ConnectDto;
import cc.mrbird.febs.dapp.dto.EncryptDto;
import cc.mrbird.febs.dapp.dto.SystemDto;
import cc.mrbird.febs.dapp.dto.*;
import cc.mrbird.febs.dapp.service.DappMemberService;
import cc.mrbird.febs.dapp.service.DappSimulateDataService;
import cc.mrbird.febs.dapp.service.DappSystemService;
import cc.mrbird.febs.dapp.vo.SimulateDataVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
 * @author 
@@ -66,4 +63,28 @@
        System.out.println(encryptDto.getTest());
        return new FebsResponse().success().data("123");
    }
    @ApiOperation(value = "IGT获取验证码", notes = "获取验证码")
    @GetMapping("/captcha")
    public FebsResponse captcha() throws IOException {
        return dappMemberService.captchaCreator();
    }
    @ApiOperation(value = "IGT注册接口", notes = "注册接口")
    @PostMapping(value = "/register")
    public FebsResponse register(@RequestBody @Validated RegisterDto registerDto) {
        return dappMemberService.register(registerDto);
    }
    @ApiOperation(value = "IGT账号密码登录接口", notes = "账号密码登录接口")
    @PostMapping(value = "/toLogin")
    public FebsResponse login(@RequestBody LoginDto loginDto) {
        return dappMemberService.toLogin(loginDto);
    }
    @ApiOperation(value = "IGT游客身份登录", notes = "游客身份登录")
    @PostMapping(value = "/touristLogin")
    public FebsResponse touristLogin(@RequestBody TouristLoginDto touristLoginDto) {
        return dappMemberService.touristLogin(touristLoginDto);
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ApiDappMemberController.java
@@ -11,9 +11,7 @@
import cc.mrbird.febs.dapp.service.DappMemberService;
import cc.mrbird.febs.dapp.service.DappSystemService;
import cc.mrbird.febs.dapp.service.DappWalletService;
import cc.mrbird.febs.dapp.vo.ActiveNftListVo;
import cc.mrbird.febs.dapp.vo.TeamListVo;
import cc.mrbird.febs.dapp.vo.WalletInfoVo;
import cc.mrbird.febs.dapp.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
@@ -121,10 +119,31 @@
        return new FebsResponse().success().data(dappSystemService.findPriceListIn24H());
    }
    @PostMapping(value = "/logout")
    @ApiOperation(value = "IGT退出登录", notes = "退出登录")
    @PostMapping(value = "/logOut")
    public FebsResponse logout() {
        DappMemberEntity member = LoginUserUtil.getAppUser();
        redisUtils.hdel(AppContants.REDIS_KEY_SIGN, member.getAddress());
        String redisKey = AppContants.REDIS_KEY_SIGN + member.getId();
        redisUtils.del(redisKey);
        return new FebsResponse().success();
    }
    @ApiOperation(value = "IGT获取用户信息", notes = "获取用户信息")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = MemberInfoVo.class)
    })
    @GetMapping(value = "/memberInfo")
    public FebsResponse getMemberInfo() {
        MemberInfoVo memberInfoVo = dappMemberService.getMemberInfo();
        return new FebsResponse().success().data(memberInfoVo);
    }
    @ApiOperation(value ="IGT资金记录-分页", notes = "资金记录-分页")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiAmountChangeListVo.class)
    })
    @PostMapping(value = "/findAmountInPage")
    public FebsResponse findAmountInPage(@RequestBody ApiAmountChangeDto apiAmountChangeDto) {
        return new FebsResponse().success().data(dappMemberService.findAmountInPage(apiAmountChangeDto));
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ApiIgtOnHookPlanController.java
New file
@@ -0,0 +1,48 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.annotation.EncryptEnable;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.ApiStartDto;
import cc.mrbird.febs.dapp.service.ApiIgtOnHookPlanService;
import cc.mrbird.febs.dapp.vo.ApiMemberWalletCoinVo;
import cc.mrbird.febs.dapp.vo.ApiPlanInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@Slf4j
@EncryptEnable
@RequiredArgsConstructor
@CrossOrigin("*")
@RestController
@Api(value = "挂机接口", tags = "挂机接口")
@RequestMapping(value = "/dapi/onHook")
public class ApiIgtOnHookPlanController {
    private final ApiIgtOnHookPlanService igtOnHookPlanService;
    @ApiOperation(value = "IGT开始挂机", notes = "开始挂机")
    @PostMapping(value = "/start")
    public FebsResponse start(@RequestBody ApiStartDto apiStartDto) {
        return igtOnHookPlanService.start(apiStartDto);
    }
    @ApiOperation(value = "IGT结束挂机", notes = "结束挂机")
    @PostMapping(value = "/endPlan/{id}")
    public FebsResponse endPlan(@PathVariable("id") Long id) {
        return igtOnHookPlanService.endPlan(id);
    }
    @ApiOperation(value = "IGT挂机信息", notes = "挂机信息")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiPlanInfoVo.class)
    })
    @PostMapping(value = "/planInfo")
    public FebsResponse planInfo() {
        return igtOnHookPlanService.planInfo();
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ApiMallNewsController.java
New file
@@ -0,0 +1,71 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.NewsListDto;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.service.IApiMallNewsService;
import cc.mrbird.febs.dapp.vo.NewsListVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@CrossOrigin("*")
@RequestMapping(value = "/api/news")
@RequiredArgsConstructor
@Api(value = "ApiMallNewsController", tags = "新闻接口类")
public class ApiMallNewsController {
    private final IApiMallNewsService newsService;
    @ApiOperation(value = "IGT新闻分类", notes = "新闻分类")
    @GetMapping(value = "/findNewsInfoCategory")
    public FebsResponse findNewsInfoCategory() {
        return new FebsResponse().success().data(newsService.findNewsCategoryList());
    }
    @ApiOperation(value ="IGT获取新闻列表-分页", notes = "获取新闻列表")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = NewsListVo.class)
    })
    @PostMapping(value = "/findNewsInPage")
    public FebsResponse findNewsInPage(@RequestBody NewsListDto newsListDto) {
        return new FebsResponse().success().data(newsService.findNewsInPage(newsListDto));
    }
    @ApiOperation(value = "IGT新闻列表", notes = "新闻列表")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = NewsListVo.class)
    })
    @GetMapping(value = "/findNews")
    public FebsResponse findNews() {
        return new FebsResponse().success().data(newsService.findTopNews());
    }
    @ApiOperation(value = "IGT新闻详情", notes = "新闻详情")
    @GetMapping(value = "/newsDetails/{id}")
    public FebsResponse newsDetails(@PathVariable("id") Long id) {
        MallNewsInfo news = newsService.getById(id);
        if (news == null) {
            return new FebsResponse().fail().message("新闻不存在");
        }
        return new FebsResponse().success().data(news);
    }
    @ApiOperation(value = "IGT首页轮播图", notes = "首页轮播图")
    @GetMapping(value = "/bannerList")
    public FebsResponse findPlatformBannerList() {
        return newsService.findAllBanner();
    }
    @ApiOperation(value = "IGT挂机方案", notes = "挂机方案")
    @GetMapping(value = "/onHookPlanList")
    public FebsResponse findOnHookPlanList() {
        return newsService.findOnHookPlanList();
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ApiWalletCoinController.java
New file
@@ -0,0 +1,63 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.ApiTransferInsideDto;
import cc.mrbird.febs.dapp.dto.ApiTransferOutsideDto;
import cc.mrbird.febs.dapp.dto.ApiTransferPasswordDto;
import cc.mrbird.febs.dapp.service.DappWalletService;
import cc.mrbird.febs.dapp.vo.ApiMemberWalletCoinVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Slf4j
@RestController
@CrossOrigin("*")
@RequestMapping(value = "/api/walletCoin")
@RequiredArgsConstructor
@Api(value = "ApiWalletCoinController", tags = "账户钱包操作")
public class ApiWalletCoinController {
    private final DappWalletService dappWalletService;
    @ApiOperation(value = "IGT获取钱包信息", notes = "获取钱包信息")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiMemberWalletCoinVo.class)
    })
    @GetMapping(value = "/findMemberWalletCoin")
    public FebsResponse findMemberWalletCoin() {
        return dappWalletService.findMemberWalletCoin();
    }
    @ApiOperation(value = "IGT内部转账", notes = "内部转账")
    @PostMapping(value = "/transferInside")
    public FebsResponse transferInside(@RequestBody ApiTransferInsideDto apiTransferInsideDto) {
        return dappWalletService.transferInside(apiTransferInsideDto);
    }
    @ApiOperation(value = "IGT设置资金密码", notes = "IGT设置资金密码")
    @PostMapping(value = "/transferPassword")
    public FebsResponse transferPassword(@RequestBody ApiTransferPasswordDto apiTransferPasswordDto) {
        return dappWalletService.transferPassword(apiTransferPasswordDto);
    }
    @ApiOperation(value = "IGT修改资金密码", notes = "IGT修改资金密码")
    @PostMapping(value = "/transferPasswordSet")
    public FebsResponse transferPasswordSet(@RequestBody ApiTransferPasswordDto apiTransferPasswordDto) {
        return dappWalletService.transferPasswordSet(apiTransferPasswordDto);
    }
    @ApiOperation(value = "IGT提现", notes = "IGT提现")
    @PostMapping(value = "/transferOutside")
    public FebsResponse transferOutside(@RequestBody ApiTransferOutsideDto apiTransferOutsideDto) {
        return dappWalletService.transferOutside(apiTransferOutsideDto);
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/MemberController.java
@@ -1,5 +1,6 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.annotation.ControllerEndpoint;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
@@ -8,6 +9,7 @@
import cc.mrbird.febs.dapp.entity.DappMemberEntity;
import cc.mrbird.febs.dapp.entity.DappTransferRecordEntity;
import cc.mrbird.febs.dapp.service.DappMemberService;
import cc.mrbird.febs.dapp.service.DappSystemService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
@@ -15,6 +17,7 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
@@ -31,6 +34,7 @@
public class MemberController extends BaseController {
    private final DappMemberService dappMemberService;
    private final DappSystemService dappSystemService;
    @RequestMapping(value = "/list")
    public FebsResponse list(DappMemberEntity member, QueryRequest request) {
@@ -82,4 +86,56 @@
        dappMemberService.setNewestPrice(priceSettingDto);
        return new FebsResponse().success();
    }
    @GetMapping(value = "/findDicByType/{type}")
    public FebsResponse findDicByType(@PathVariable("type") String type) {
        return new FebsResponse().success().data(dappSystemService.findDataDicByType(type));
    }
    /**
     * 字典表设置
     * @param map
     * @return
     */
    @PostMapping(value = "/levelSystemSetting")
    public FebsResponse levelSystemSetting(@RequestBody Map<String, Object> map) {
        dappSystemService.levelSystemSetting(map);
        return new FebsResponse().success().message("设置成功");
    }
    /**
     * 挂机方案设置启用
     */
    @GetMapping("enableOnHook/{id}")
    @ControllerEndpoint(operation = "挂机方案设置启用", exceptionMessage = "设置失败")
    public FebsResponse enableOnHook(@NotNull(message = "{required}") @PathVariable Long id) {
        return dappSystemService.enableOnHook(id);
    }
    /**
     * 挂机方案设置禁用
     */
    @GetMapping("disableOnHook/{id}")
    @ControllerEndpoint(operation = "挂机方案设置禁用", exceptionMessage = "设置失败")
    public FebsResponse disableOnHook(@NotNull(message = "{required}") @PathVariable Long id) {
        return dappSystemService.disableOnHook(id);
    }
    /**
     * 重置资金密码为123456
     */
    @GetMapping(value = "/resetTransferCode/{id}")
    public FebsResponse resetTransferCode(@PathVariable("id") Long id) {
        dappMemberService.resetTransferCode(id);
        return new FebsResponse().success();
    }
    /**
     * 重置登录密码为123456
     */
    @GetMapping(value = "/resetPassword/{id}")
    public FebsResponse resetPassword(@PathVariable("id") Long id) {
        dappMemberService.resetPassword(id);
        return new FebsResponse().success();
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ViewBannerController.java
New file
@@ -0,0 +1,50 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsConstant;
import cc.mrbird.febs.common.utils.FebsUtil;
import cc.mrbird.febs.dapp.entity.PlatformBanner;
import cc.mrbird.febs.dapp.service.IAdminBannerService;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller("bannerView")
@RequestMapping(FebsConstant.VIEW_PREFIX + "bannerView")
@RequiredArgsConstructor
public class ViewBannerController extends BaseController {
    private final IAdminBannerService iAdminBannerService;
    /**
     * 轮播图---列表
     */
    @GetMapping("platformBanner")
    @RequiresPermissions("platformBanner:view")
    public String platformBanner() {
        return FebsUtil.view("banner/platformBanner");
    }
    /**
     * 轮播图---修改
     */
    @GetMapping(value = "platformBanner/update/{id}")
    @RequiresPermissions("platformBannerUpdate:update")
    public String platformBannerUpdate(@PathVariable long id, Model model) {
        PlatformBanner data = iAdminBannerService.selectPlatformBannerById(id);
        model.addAttribute("member", data);
        return FebsUtil.view("banner/platformBannerDetail");
    }
    @GetMapping(value = "platformBanner/add")
    @RequiresPermissions("platformBanner:add")
    public String addUser() {
        return FebsUtil.view("banner/platformBannerAdd");
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ViewController.java
@@ -57,7 +57,10 @@
        return FebsUtil.view("dapp/simulate-result");
    }
    /**
     * igt会员列表
     * @return
     */
    @GetMapping("member")
    @RequiresPermissions("member:view")
    public String member() {
@@ -115,4 +118,25 @@
        model.addAttribute("newestPrice", price);
        return FebsUtil.view("dapp/newest-price-setting");
    }
    /**
     * 会员等级设置
     * @return
     */
    @GetMapping("memberLevelSet")
    @RequiresPermissions("memberLevelSet:view")
    public String memberLevelSet() {
        return FebsUtil.view("dapp/member-level-set");
    }
    /**
     * 挂机方案设置
     * @return
     */
    @GetMapping("onHookPlanSet")
    @RequiresPermissions("onHookPlanSet:view")
    public String onHookPlanSet() {
        return FebsUtil.view("dapp/on-hook-plan-set");
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ViewNewsController.java
New file
@@ -0,0 +1,83 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.entity.FebsConstant;
import cc.mrbird.febs.common.utils.FebsUtil;
import cc.mrbird.febs.dapp.entity.MallNewsCategory;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.service.IMallNewsInfoService;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller("newsView")
@RequestMapping(FebsConstant.VIEW_PREFIX + "newsView")
@RequiredArgsConstructor
public class ViewNewsController {
    private final IMallNewsInfoService mallNewsInfoService;
    /**
     * 新闻中心-列表
     * @return
     */
    @GetMapping("newsInfoList")
    @RequiresPermissions("newsInfoList:view")
    public String newsInfoList() {
        return FebsUtil.view("news/newsInfoList");
    }
    /**
     * 新闻中心-新增
     * @return
     */
    @GetMapping("newsInfo/add")
    @RequiresPermissions("newsInfo:add")
    public String newsInfoAdd() {
        return FebsUtil.view("news/newsInfoAdd");
    }
    /**
     * 新闻中心-详情
     * @param id
     * @param model
     * @return
     */
    @GetMapping("newsInfo/update/{id}")
    @RequiresPermissions("newsInfo:update")
    public String newsInfoUpdate(@PathVariable long id, Model model) {
        MallNewsInfo data = mallNewsInfoService.getNewsInfoById(id);
        model.addAttribute("newsInfo", data);
        return FebsUtil.view("news/newsInfoUpdate");
    }
    @GetMapping("newsCategory")
    @RequiresPermissions("news:category:view")
    public String newsCategory() {
        return FebsUtil.view("news/newsCategory");
    }
    @GetMapping(value = "newsCategory/add")
    @RequiresPermissions("news:category:add")
    public String addCategory(Long id, Model model) {
        if (id != null) {
            MallNewsCategory obj = mallNewsInfoService.findNewsCategoryById(id);
            model.addAttribute("obj", obj);
        }
        return FebsUtil.view("news/newsCategoryAdd");
    }
    @GetMapping(value = "newsCategory/update/{id}")
    @RequiresPermissions("news:category:update")
    public String updateCategory(@PathVariable Long id, Model model) {
        if (id != null) {
            MallNewsCategory obj = mallNewsInfoService.findNewsCategoryById(id);
            model.addAttribute("obj", obj);
        }
        return FebsUtil.view("news/newsCategoryAdd");
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ViewWalletCoinController.java
New file
@@ -0,0 +1,62 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.entity.FebsConstant;
import cc.mrbird.febs.common.utils.FebsUtil;
import cc.mrbird.febs.dapp.entity.DataDictionaryCustom;
import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum;
import cc.mrbird.febs.dapp.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.dapp.vo.AdminTransferInsideSetVo;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller("walletCoinView")
@RequestMapping(FebsConstant.VIEW_PREFIX + "walletCoinView")
@RequiredArgsConstructor
public class ViewWalletCoinController {
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    /**
     * 内部转账规则设置
     * @param model
     * @return
     */
    @GetMapping("/transferInsideSet")
    @RequiresPermissions("transferInsideSet:view")
    public String transferInsideSet(Model model) {
        AdminTransferInsideSetVo adminTransferInsideSetVo = new AdminTransferInsideSetVo();
        DataDictionaryCustom serviceFee = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.SERVICE_FEE.getType(), DataDictionaryEnum.SERVICE_FEE.getCode());
        if (ObjectUtil.isNotNull(serviceFee)) {
            adminTransferInsideSetVo.setServiceFee(Integer.parseInt(serviceFee.getValue()));
        }
        DataDictionaryCustom outAccountProfit = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getType(), DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getCode());
        if (ObjectUtil.isNotNull(outAccountProfit)) {
            adminTransferInsideSetVo.setOutAccountProfit(Integer.parseInt(outAccountProfit.getValue()));
        }
        DataDictionaryCustom accountRelation = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.ACCOUNT_RELATION.getType(), DataDictionaryEnum.ACCOUNT_RELATION.getCode());
        if (ObjectUtil.isNotNull(accountRelation)) {
            adminTransferInsideSetVo.setAccountRelation(Integer.parseInt(accountRelation.getValue()));
        }
        DataDictionaryCustom withdrawTimes = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.WITHDRAW_TIMES.getType(), DataDictionaryEnum.WITHDRAW_TIMES.getCode());
        if (ObjectUtil.isNotNull(withdrawTimes)) {
            adminTransferInsideSetVo.setWithdrawTimes(Integer.parseInt(withdrawTimes.getValue()));
        }
        model.addAttribute("transferInsideSet", adminTransferInsideSetVo);
        return FebsUtil.view("walletCoin/transferInsideSet");
    }
    /**
     * 提现转账-列表
     * @return
     */
    @GetMapping("transferInsideList")
    @RequiresPermissions("transferInsideList:view")
    public String newsInfoList() {
        return FebsUtil.view("walletCoin/transferInsideList");
    }
}
src/main/java/cc/mrbird/febs/dapp/dto/ApiAmountChangeDto.java
New file
@@ -0,0 +1,26 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "ApiAmountChangeDto", description = "记录列表接收参数类")
public class ApiAmountChangeDto {
    @ApiModelProperty(value = "页码")
    private Integer pageNum = 1;
    @ApiModelProperty(value = "每页数量")
    private Integer pageSize = 10;
    @ApiModelProperty(value = "类型",example = "类型  2-提现 4-内部转账 5-挂机收益 6-挂机")
    private Integer type;
    @ApiModelProperty(value = "开始时间")
    private String startTime;
    @ApiModelProperty(value = "结束时间")
    private String endTime;
}
src/main/java/cc/mrbird/febs/dapp/dto/ApiStartDto.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "ApiStartDto", description = "开始挂机")
public class ApiStartDto {
    @ApiModelProperty(value = "挂机金额", example = "100")
    private BigDecimal balance;
    @ApiModelProperty(value = "倍数",example = "1")
    private Integer planCode;
}
src/main/java/cc/mrbird/febs/dapp/dto/ApiTransferInsideDto.java
New file
@@ -0,0 +1,20 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "ApiTransferInsideDto", description = "内部转账")
public class ApiTransferInsideDto {
    @ApiModelProperty(value = "划转金额", example = "100")
    private BigDecimal balance;
    @ApiModelProperty(value = "转入用户邀请码",example = "49546512")
    private String inviteId;
    @ApiModelProperty(value = "资金密码",example = "49546512")
    private String transferCode;
}
src/main/java/cc/mrbird/febs/dapp/dto/ApiTransferOutsideDto.java
New file
@@ -0,0 +1,24 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "ApiTransferOutsideDto", description = "提现")
public class ApiTransferOutsideDto {
    @ApiModelProperty(value = "提现金额", example = "100")
    private BigDecimal balance;
    @ApiModelProperty(value = "资金密码",example = "49546512")
    private String transferCode;
    @ApiModelProperty(value = "提现地址",example = "oxEsfsfsfs49546512")
    private String address;
    @ApiModelProperty(value = "类型1:银行卡 2:地址",example = "oxEsfsfsfs49546512")
    private String type;
}
src/main/java/cc/mrbird/febs/dapp/dto/ApiTransferPasswordDto.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "ApiTransferPasswordDto", description = "设置资金密码")
public class ApiTransferPasswordDto {
    @ApiModelProperty(value = "旧资金密码",example = "49546512")
    private String oldTransferPassword;
    @ApiModelProperty(value = "新资金密码",example = "49546512")
    private String newTransferPassword;
    @ApiModelProperty(value = "再次输入新资金密码",example = "49546512")
    private String newTransferPasswordAgain;
}
src/main/java/cc/mrbird/febs/dapp/dto/LoginDto.java
New file
@@ -0,0 +1,29 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel(value = "LoginDto", description = "登陆接口接收类")
public class LoginDto {
    @ApiModelProperty(value = "账号", example = "13412341234")
    @NotBlank(message = "账号不能为空")
    private String account;
    @ApiModelProperty(value = "密码", example = "123456")
    @NotBlank(message = "密码不能为空")
    private String password;
    private String codeToken;
    @ApiModelProperty(value = "验证码", example = "123456")
    @NotBlank(message = "验证码不能为空")
    private String codeValue;
    @ApiModelProperty(value ="随机字符串", example = "123")
    private String nonce;
}
src/main/java/cc/mrbird/febs/dapp/dto/MallNewsInfoDto.java
New file
@@ -0,0 +1,28 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "MallNewsInfoDto", description = "参数接收类")
public class MallNewsInfoDto {
    private Long id;
    private String title;
    private String content;
    private Long goodsId;
    /**
     * 1-文章2-跳转到产品
     */
    private Integer type;
    private String videoUrl;
    private String thumb;
    private String categoryId;
}
src/main/java/cc/mrbird/febs/dapp/dto/NewsListDto.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "NewsListDto", description = "新闻列表接口接收参数类")
public class NewsListDto {
    @ApiModelProperty("每页数量")
    private int pageSize = 10;
    @ApiModelProperty("页码")
    private int pageNum = 1;
    @ApiModelProperty("分类ID")
    private Long categoryId;
}
src/main/java/cc/mrbird/febs/dapp/dto/RegisterDto.java
New file
@@ -0,0 +1,29 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel(value = "RegisterDto", description = "注册接口参数类")
public class RegisterDto {
    @ApiModelProperty(value = "账号", example = "13412341234")
    @NotBlank(message = "账号不能为空")
    private String account;
    @ApiModelProperty(value = "密码", example = "123456")
    @NotBlank(message = "密码不能为空")
    private String password;
    private String codeToken;
    @ApiModelProperty(value = "验证码", example = "123456")
    @NotBlank(message = "验证码不能为空")
    private String codeValue;
    @ApiModelProperty(value = "推荐人id", example = "rxadr3")
    private String refererId;
}
src/main/java/cc/mrbird/febs/dapp/dto/TouristLoginDto.java
New file
@@ -0,0 +1,13 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "TouristLoginDto", description = "注册接口参数类")
public class TouristLoginDto {
    @ApiModelProperty(value = "游客标记", example = "asdfsfsfsdafsafsdafsdfa")
    private String touristMark;
}
src/main/java/cc/mrbird/febs/dapp/entity/DappAccountMoneyChangeEntity.java
@@ -3,6 +3,7 @@
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@@ -45,10 +46,17 @@
    private String content;
    /**
     * 类型 1-兑换 2-提现 3-采矿
     * 类型 1-兑换 2-提现 3-采矿 4-内部转账 5-挂机收益 6-挂机
     */
    private Integer type;
    @TableField(exist = false)
    private String address;
    @TableField(exist = false)
    private String startTime;
    @TableField(exist = false)
    private String endTime;
}
src/main/java/cc/mrbird/febs/dapp/entity/DappMemberEntity.java
@@ -25,6 +25,14 @@
     * 用户状态 1-正常 2-禁用
     */
    private Integer accountStatus;
    /**
     * 启用
     */
    public static final Integer ACCOUNT_STATUS_ENABLE = 1;
    /**
     * 禁用
     */
    public static final Integer ACCOUNT_STATUS_DISABLED = 2;
    /**
     * 是否可兑换 1-是 2-否
@@ -77,4 +85,12 @@
     * 1-是 2-否
     */
    private Integer makerType;
    private String username;
    private String password;
    private String identity;
    private String touristMark;
    private String transferCode;
    private Integer isProfit;
    private Integer isOnHook;
}
src/main/java/cc/mrbird/febs/dapp/entity/IgtOnHookPlanOrder.java
New file
@@ -0,0 +1,33 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@TableName("igt_on_hook_plan_order")
public class IgtOnHookPlanOrder extends BaseEntity {
    //挂机人ID
    private Long memberId;
    //挂机开始时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startTime;
    //挂机状态 1:开始 2:结束
    private Integer state;
    public static final Integer STATE_START = 1;
    public static final Integer STATE_END = 2;
    //挂机总金额
    private BigDecimal planAmount;
    //挂机剩余金额
    private BigDecimal avaAmount;
    //挂机方案倍数
    private Integer planCode;
    //盈利状态:1:盈利 2:亏损
    private Integer profitState;
    //总收益
    private BigDecimal profit;
}
src/main/java/cc/mrbird/febs/dapp/entity/IgtOnHookPlanOrderItem.java
New file
@@ -0,0 +1,32 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
@Data
@TableName("igt_on_hook_plan_order_item")
public class IgtOnHookPlanOrderItem extends BaseEntity {
    //挂机人ID
    private Long memberId;
    //挂机主表ID
    private Long orderId;
    //金额
    private BigDecimal amount;
    //收益
    private BigDecimal profit;
    //生效状态 1:已生效 2:待生效
    private Integer state;
    //挂机方案倍数
    private Integer planCode;
    //1:未开奖2:中奖3未中奖
    private Integer isGoal;
    //所属期数
    private Integer belongNum;
    //开奖顺序
    private Integer orderNum;
}
src/main/java/cc/mrbird/febs/dapp/entity/MallNewsCategory.java
New file
@@ -0,0 +1,12 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("mall_news_category")
public class MallNewsCategory extends BaseEntity {
    private String title;
}
src/main/java/cc/mrbird/febs/dapp/entity/MallNewsInfo.java
New file
@@ -0,0 +1,29 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("mall_news_info")
public class MallNewsInfo extends BaseEntity {
    private String title;
    private String content;
    private Long targetId;
    /**
     * 1-文章2-跳转到产品
     */
    private Integer type;
    private String videoUrl;
    private String thumb;
    private Long categoryId;
    private Integer isTop;
}
src/main/java/cc/mrbird/febs/dapp/entity/MemberCoinWithdrawEntity.java
New file
@@ -0,0 +1,66 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
/**
 * 会员提币表
 */
@Data
@TableName("member_coin_withdraw")
public class MemberCoinWithdrawEntity extends BaseEntity {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
     /**
     * 会员ID
     */
    private Long memberId;
    /**
     * 地址
     */
    private String address;
    /**
     * 提币数量
     */
    private BigDecimal amount;
    /**
     * 手续费
     */
    private BigDecimal feeAmount;
    /**
     * 币种
     */
    private String symbol;
    /**
     * 状态 1进行中 2同意 3拒绝
     */
    private int status;
    public static final int STATUS_DOING = 1;
    public static final int STATUS_YES = 2;
    public static final int STATUS_NO = 3;
    /**
     * 是否内部转账 Y-是N-不是
     */
    private String isInside;
    public static final String ISINSIDE_YES = "Y";
    public static final String ISINSIDE_NO = "N";
    private String label;
    private String tag;
    /**
     * 后台操作用户的标识
     */
    @TableField(exist = false)
    private String description;
}
src/main/java/cc/mrbird/febs/dapp/entity/PlatformBanner.java
New file
@@ -0,0 +1,48 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("platform_banner")
public class PlatformBanner extends BaseEntity {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    /**
     * 标题
     */
    private String name;
    /**
     * 图片链接
     */
    private String imageUrl;
    /**
     * 是否可跳转 1-是2-否
     */
    private String isJump;
    /**
     * 跳转外部或内部 1-内2-外
     */
    private int isInside;
    /**
     * 跳转链接
     */
    private String jumpUrl;
    /**
     * 显示端口 1-pc2-手机
     */
    private int showPort;
    /**
     * 联系方式
     */
    private String sort;
    /**
     * 是否置顶 1-是2-否
     */
    private String isTop;
}
src/main/java/cc/mrbird/febs/dapp/enumerate/DataDictionaryEnum.java
New file
@@ -0,0 +1,69 @@
package cc.mrbird.febs.dapp.enumerate;
import lombok.Getter;
@Getter
public enum DataDictionaryEnum {
    /**
     * 挂机设置
     * 最长挂机时间
     */
    MAX_HOURS("ONHOOK_SET","MAX_HOURS"),
    /**
     * 内部转账规则(默认如下)
     * 1、没有手续费
     * 2、转出账号得盈利满30%
     * 3、只允许上下级互转
     * 4、每日提现次数
     */
    SERVICE_FEE("TRANSFER_INSIDE_RULE","SERVICE_FEE"),
    OUT_ACCOUNT_PROFIT("TRANSFER_INSIDE_RULE","OUT_ACCOUNT_PROFIT"),
    ACCOUNT_RELATION("TRANSFER_INSIDE_RULE","ACCOUNT_RELATION"),
    WITHDRAW_TIMES("TRANSFER_INSIDE_RULE","WITHDRAW_TIMES"),
    /**
     * 挂机方案
     * value格式:{"amount":"0","multipleTimes":"2","state":2}
     * multiple:倍数
     * amount:金额
     * state:是否启用 1:开启2:禁用
     */
    PLAN_A("ONHOOK_PLAN","PLAN_A"),
    PLAN_B("ONHOOK_PLAN","PLAN_B"),
    PLAN_C("ONHOOK_PLAN","PLAN_C"),
    PLAN_D("ONHOOK_PLAN","PLAN_D"),
    PLAN_E("ONHOOK_PLAN","PLAN_E"),
    PLAN_F("ONHOOK_PLAN","PLAN_F"),
    PLAN_G("ONHOOK_PLAN","PLAN_G"),
    PLAN_H("ONHOOK_PLAN","PLAN_H"),
    /**
     * 佣金等级
     * value格式:{"hangingRevenue":"2","profitSharing":"0","runningCommission":"0","promotionConditions":"0"}
     *     "hangingRevenue":(挂机收益)
     *     "profitSharing":(盈利分成)
     *     "runningCommission":(流水佣金)
     *     "promotionConditions":(晋升条件,上一级代理(3个))
     */
    LEVEL_GP("COMMISSION_LEVEL","LEVEL_GP"),
    LEVEL_SP("COMMISSION_LEVEL","LEVEL_SP"),
    LEVEL_BP("COMMISSION_LEVEL","LEVEL_BP"),
    LEVEL_GIB("COMMISSION_LEVEL","LEVEL_GIB"),
    LEVEL_AIB("COMMISSION_LEVEL","LEVEL_AIB"),
    LEVEL_CIB("COMMISSION_LEVEL","LEVEL_CIB"),
    LEVEL_FIB("COMMISSION_LEVEL","LEVEL_FIB"),
    LEVEL_IB("COMMISSION_LEVEL","LEVEL_IB"),
    LEVEL_MB("COMMISSION_LEVEL","LEVEL_MB"),
    LEVEL_TM("COMMISSION_LEVEL","LEVEL_TM");
    private String type;
    private String code;
    DataDictionaryEnum(String type, String code) {
        this.type = type;
        this.code = code;
    }
}
src/main/java/cc/mrbird/febs/dapp/enumerate/MemberOnHookPlanEnum.java
New file
@@ -0,0 +1,105 @@
package cc.mrbird.febs.dapp.enumerate;
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.dapp.service.MemberOnHookPlan;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public enum MemberOnHookPlanEnum implements MemberOnHookPlan {
        //会员游客等身份
        LEVEL_MB{
            @Override
            public Map<String, LinkedList<String>> getMemberOnHook(Double hours, BigDecimal hangingRevenue,List<Map<String,String>> plan) {
                Map objectObjectHashMap = new HashMap<String, List<String>>();
                LinkedList linkedList = new LinkedList<>();
                //最小挂机金额
                //最大挂机次数,五分钟开奖一次,一个小时固定次数12次
                int maxTimes = new Double(hours * 12).intValue();
                //预期最大收益
                BigDecimal profitTotal = AppContants.ONHOOK_BASIC_AMOUNT.multiply(hangingRevenue).setScale(2, BigDecimal.ROUND_DOWN);
                BigDecimal profitTotalNow = BigDecimal.ZERO;
                for(int i=1;i<=maxTimes;){
                    //当实际的收益小于预期的收益时,按照随机,否则只中奖第一方案
                    int randomInt = 1;
                    if(profitTotal.compareTo(profitTotalNow)>0){
                        randomInt = RandomUtil.randomInt(1, 4);
                    }
                    if(1 == randomInt){
                        String planKey = Integer.toString(randomInt);
                        for(Map<String,String> planMap : plan){
                            if(ObjectUtil.isNotEmpty(planMap.get(planKey))){
                                String planMapValue = planMap.get(planKey);
                                JSONObject jsonObject = JSONUtil.parseObj(planMapValue);
                                jsonObject.set("isGoal","2");
                                BigDecimal amount = new BigDecimal(jsonObject.get("amount").toString());
                                BigDecimal profit = amount.multiply(hangingRevenue).setScale(2, BigDecimal.ROUND_DOWN);
                                profitTotalNow = profitTotalNow.add(profit).setScale(2, BigDecimal.ROUND_DOWN);
                                jsonObject.set("profit",profit);
                                linkedList.add(JSONUtil.toJsonStr(jsonObject));
                                maxTimes --;
                            }
                        }
                    }else{
                        for(int j = 1;j<=randomInt;j++){
                            String planKey = Integer.toString(j);
                            for(Map<String,String> planMap : plan){
                                if(ObjectUtil.isNotEmpty(planMap.get(planKey))){
                                    String planMapValue = planMap.get(planKey);
                                    JSONObject jsonObject = JSONUtil.parseObj(planMapValue);
                                    if(j == randomInt){
                                        jsonObject.set("isGoal","2");
                                    }else{
                                        jsonObject.set("isGoal","1");
                                    }
                                    BigDecimal amount = new BigDecimal(jsonObject.get("amount").toString());
                                    BigDecimal profit = amount.multiply(hangingRevenue).setScale(2, BigDecimal.ROUND_DOWN);
                                    profitTotalNow = profitTotalNow.add(profit).setScale(2, BigDecimal.ROUND_DOWN);
                                    jsonObject.set("profit",profit);
                                    linkedList.add(JSONUtil.toJsonStr(jsonObject));
                                    maxTimes --;
                                }
                            }
                        }
                    }
                }
                objectObjectHashMap.put("LEVEL_MB",linkedList);
                return objectObjectHashMap;
            }
        },
        //系统设置亏损时,不管用户的身份等级
        IS_PROFIT_NO{
            @Override
            public Map<String, LinkedList<String>> getMemberOnHook(Double hours, BigDecimal hangingRevenue,List<Map<String,String>> plan) {
                Map objectObjectHashMap = new HashMap<String, LinkedList<String>>();
                LinkedList linkedList = new LinkedList<>();
                for(int i = 1;i <= plan.size();i++){
                    String planKey = Integer.toString(i);
                    for(Map<String,String> planMap : plan){
                        if(ObjectUtil.isNotEmpty(planMap.get(planKey))){
                            String planMapValue = planMap.get(planKey);
                            JSONObject jsonObject = JSONUtil.parseObj(planMapValue);
                            jsonObject.set("isGoal","1");
                            BigDecimal amount = new BigDecimal(jsonObject.get("amount").toString());
                            BigDecimal profit = amount.multiply(hangingRevenue).setScale(2, BigDecimal.ROUND_DOWN);
                            jsonObject.set("profit",profit);
                            linkedList.add(JSONUtil.toJsonStr(jsonObject));
                        }
                    }
                }
                objectObjectHashMap.put("IS_PROFIT_NO",linkedList);
                return objectObjectHashMap;
            }
        }
}
src/main/java/cc/mrbird/febs/dapp/mapper/DappAccountMoneyChangeDao.java
@@ -1,6 +1,7 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.DappAccountMoneyChangeEntity;
import cc.mrbird.febs.dapp.vo.ApiAmountChangeListVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -9,4 +10,6 @@
public interface DappAccountMoneyChangeDao extends BaseMapper<DappAccountMoneyChangeEntity> {
    IPage<DappAccountMoneyChangeEntity> selectInPage(@Param("record") DappAccountMoneyChangeEntity record, Page<DappAccountMoneyChangeEntity> page);
    IPage<ApiAmountChangeListVo> selectChangeListInPage(Page<ApiAmountChangeListVo> page, @Param("record") DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity);
}
src/main/java/cc/mrbird/febs/dapp/mapper/DappMemberDao.java
@@ -40,4 +40,16 @@
    IPage<TeamListVo> selectTeamListInPage(@Param("record") TeamListDto teamListDto, Page<TeamListDto> page);
    List<DappMemberEntity> selectMakerAddress();
    DappMemberEntity selectMemberInfoByUsername(@Param("username")String account);
    DappMemberEntity selectMemberInfoByUsernameAndPassword(@Param("username") String account,@Param("password")  String md5Pwd);
    DappMemberEntity selectMemberInfoByTouristMark(@Param("touristMark")String touristMark);
    DappMemberEntity selectRelationShipByInviteIdOutAndMemberId(@Param("id")Long id, @Param("inviteId")String inviteId);
    IPage<DappMemberEntity> selectMemberListInPage(@Param("record")DappMemberEntity member, Page<DappMemberEntity> page);
    void updateIsOnHook();
}
src/main/java/cc/mrbird/febs/dapp/mapper/DappWalletCoinDao.java
@@ -6,9 +6,21 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
public interface DappWalletCoinDao extends BaseMapper<DappWalletCoinEntity> {
    DappWalletCoinEntity selectByMemberId(@Param("memberId") Long memberId);
    IPage<DappWalletCoinEntity> selectInPage(@Param("record") DappWalletCoinEntity walletCoin, Page<DappWalletCoinEntity> page);
    Integer addAvailableAndDelFrozenById(@Param("id") Long id, @Param("balance") BigDecimal balance);
    Integer addFrozenAndDelAvailableById(@Param("id") Long id, @Param("balance")  BigDecimal amount);
    Integer delTotalAndDelFrozenById(@Param("id") Long id, @Param("balance")  BigDecimal amount);
    Integer addTotalAndaddAvailableById(@Param("id") Long id, @Param("balance")  BigDecimal amount);
    Integer delAvailableDelTotalById(@Param("id") Long id, @Param("balance")  BigDecimal amount);
}
src/main/java/cc/mrbird/febs/dapp/mapper/IgtOnHookPlanOrderDao.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.IgtOnHookPlanOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
public interface IgtOnHookPlanOrderDao extends BaseMapper<IgtOnHookPlanOrder> {
    List<IgtOnHookPlanOrder> selectByState(@Param("state")int i);
    Integer updateAvaAmountById(@Param("id")Long id, @Param("profit")BigDecimal balance, @Param("amount")BigDecimal amount);
    IgtOnHookPlanOrder selectByMemberId(@Param("memberId")Long memberId);
    Integer addAvaAmountAddProfitById(@Param("id")Long id, @Param("profit")BigDecimal balance, @Param("amount")BigDecimal amount);
}
src/main/java/cc/mrbird/febs/dapp/mapper/IgtOnHookPlanOrderItemDao.java
New file
@@ -0,0 +1,18 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.IgtOnHookPlanOrderItem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
public interface IgtOnHookPlanOrderItemDao extends BaseMapper<IgtOnHookPlanOrderItem> {
    IgtOnHookPlanOrderItem selectByOrderIdAndMemberIdAndState(@Param("orderId") Long orderId, @Param("memberId")Long memberId, @Param("state")int i);
    BigDecimal selectTotalProfitByByOrderIdAndMemberIdAndState(@Param("orderId") Long orderId, @Param("memberId")Long memberId
            , @Param("state")int i, @Param("isGoal")int isGoal);
    BigDecimal selectTotalAmountByByOrderIdAndMemberIdAndState(@Param("orderId") Long orderId, @Param("memberId")Long memberId
            , @Param("state")int i, @Param("isGoal")int isGoal);
}
src/main/java/cc/mrbird/febs/dapp/mapper/MallNewsCategoryMapper.java
New file
@@ -0,0 +1,12 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.MallNewsCategory;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
public interface MallNewsCategoryMapper extends BaseMapper<MallNewsCategory> {
    IPage<MallNewsCategory> selectInPage(@Param("record") MallNewsCategory mallNewsCategory, Page<MallNewsCategory> page);
}
src/main/java/cc/mrbird/febs/dapp/mapper/MallNewsInfoMapper.java
New file
@@ -0,0 +1,17 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.vo.AdminMallNewsInfoVo;
import cc.mrbird.febs.dapp.vo.NewsListVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
public interface MallNewsInfoMapper extends BaseMapper<MallNewsInfo> {
    IPage<AdminMallNewsInfoVo> getNewInfoListInPage(Page<AdminMallNewsInfoVo> page, MallNewsInfo mallNewsInfo);
    IPage<NewsListVo> selectNewsVoInPage(Page<NewsListVo> page, @Param("record") MallNewsInfo mallNewsInfo);
}
src/main/java/cc/mrbird/febs/dapp/mapper/MemberCoinWithdrawDao.java
New file
@@ -0,0 +1,14 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.MemberCoinWithdrawEntity;
import cc.mrbird.febs.dapp.vo.AdminMemberCoinWithdrawVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
public interface MemberCoinWithdrawDao extends BaseMapper<MemberCoinWithdrawEntity> {
    IPage<AdminMemberCoinWithdrawVo> findMemberWithdrawCoinInPage(Page<MemberCoinWithdrawEntity> page, @Param("record")MemberCoinWithdrawEntity memberCoinWithdrawEntity);
}
src/main/java/cc/mrbird/febs/dapp/mapper/PlatformBannerMapper.java
New file
@@ -0,0 +1,13 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.PlatformBanner;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
public interface PlatformBannerMapper extends BaseMapper<PlatformBanner> {
    IPage<PlatformBanner> findPlatformBannerInPage(Page<PlatformBanner> page,
                                                   @Param("record")PlatformBanner platformBannerEntity);
}
src/main/java/cc/mrbird/febs/dapp/service/AdminOperationService.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.entity.DappMemberEntity;
import cc.mrbird.febs.dapp.entity.MemberCoinWithdrawEntity;
import cc.mrbird.febs.dapp.vo.AdminMemberCoinWithdrawVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
public interface AdminOperationService extends IService<DappMemberEntity> {
    IPage<AdminMemberCoinWithdrawVo> findMemberWithdrawCoinAllOneInPage(MemberCoinWithdrawEntity memberCoinWithdrawEntity, QueryRequest request);
    FebsResponse agreeWithdraw(Long id);
    FebsResponse disagreeWithdraw(Long id);
}
src/main/java/cc/mrbird/febs/dapp/service/ApiIgtOnHookPlanService.java
New file
@@ -0,0 +1,15 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.ApiStartDto;
import cc.mrbird.febs.dapp.entity.IgtOnHookPlanOrder;
import com.baomidou.mybatisplus.extension.service.IService;
public interface ApiIgtOnHookPlanService extends IService<IgtOnHookPlanOrder> {
    FebsResponse start(ApiStartDto apiStartDto);
    FebsResponse endPlan(Long id);
    FebsResponse planInfo();
}
src/main/java/cc/mrbird/febs/dapp/service/DappMemberService.java
@@ -1,16 +1,18 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.dto.ApproveDto;
import cc.mrbird.febs.dapp.dto.ConnectDto;
import cc.mrbird.febs.dapp.dto.PriceSettingDto;
import cc.mrbird.febs.dapp.dto.TeamListDto;
import cc.mrbird.febs.dapp.dto.*;
import cc.mrbird.febs.dapp.entity.DappFundFlowEntity;
import cc.mrbird.febs.dapp.entity.DappMemberEntity;
import cc.mrbird.febs.dapp.entity.DappTransferRecordEntity;
import cc.mrbird.febs.dapp.vo.ApiAmountChangeListVo;
import cc.mrbird.febs.dapp.vo.MemberInfoVo;
import cc.mrbird.febs.dapp.vo.TeamListVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -43,4 +45,28 @@
    DappMemberEntity insertMember(String address, String refererId, String chainType, String accountType);
    List<TeamListVo> findTeamList(TeamListDto teamListDto);
    FebsResponse register(RegisterDto registerDto);
    FebsResponse toLogin(LoginDto loginDto);
    FebsResponse touristLogin(TouristLoginDto touristLoginDto);
    FebsResponse captchaCreator() throws IOException;
    //生成token
    Map<String, Object> createToken(String captcha);
    MemberInfoVo getMemberInfo();
    //根据输入的邀请码判断是否是会员
    Boolean isMember(String inviteId);
    //根据邀请码判断会员之间是否有推荐关系
    Boolean isRelationShip(String inviteIdOut,String inviteIdIn);
    void resetTransferCode(Long id);
    void resetPassword(Long id);
    Boolean validateTransferCode(String transferCode,Long memberId);
    List<ApiAmountChangeListVo> findAmountInPage(ApiAmountChangeDto apiAmountChangeDto);
}
src/main/java/cc/mrbird/febs/dapp/service/DappSystemService.java
@@ -1,8 +1,9 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.SystemDto;
import cc.mrbird.febs.dapp.entity.DappMineDataEntity;
import cc.mrbird.febs.dapp.entity.DappPriceRecordEntity;
import cc.mrbird.febs.dapp.entity.DataDictionaryCustom;
import java.math.BigDecimal;
import java.util.List;
@@ -65,4 +66,12 @@
    void tfcNewPrice();
    List<DappPriceRecordEntity> findPriceListIn24H();
    List<DataDictionaryCustom> findDataDicByType(String type);
    void levelSystemSetting(Map<String, Object> map);
    FebsResponse enableOnHook(Long id);
    FebsResponse disableOnHook(Long id);
}
src/main/java/cc/mrbird/febs/dapp/service/DappWalletService.java
@@ -1,5 +1,6 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.dto.*;
import cc.mrbird.febs.dapp.entity.DappAccountMoneyChangeEntity;
@@ -44,4 +45,13 @@
    List<ActiveNftListVo> findUnActiveNftList();
    FebsResponse findMemberWalletCoin();
    FebsResponse transferInside(ApiTransferInsideDto apiTransferInsideDto);
    FebsResponse transferPasswordSet(ApiTransferPasswordDto apiTransferPasswordDto);
    FebsResponse transferOutside(ApiTransferOutsideDto apiTransferOutsideDto);
    FebsResponse transferPassword(ApiTransferPasswordDto apiTransferPasswordDto);
}
src/main/java/cc/mrbird/febs/dapp/service/IAdminBannerService.java
New file
@@ -0,0 +1,22 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.entity.PlatformBanner;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
public interface IAdminBannerService extends IService<PlatformBanner> {
    IPage<PlatformBanner> findPlatformBannerInPage(PlatformBanner platformBannerEntity, QueryRequest request);
    PlatformBanner selectPlatformBannerById(long id);
    FebsResponse platformBannerConfirm(@Valid PlatformBanner platformBannerEntity);
    FebsResponse platformBannerDelete(@NotNull(message = "{required}") Long id);
    void platformBannerAdd(@Valid PlatformBanner platformBannerEntity);
}
src/main/java/cc/mrbird/febs/dapp/service/IApiMallNewsService.java
New file
@@ -0,0 +1,24 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.NewsListDto;
import cc.mrbird.febs.dapp.entity.MallNewsCategory;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.vo.NewsListVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface IApiMallNewsService extends IService<MallNewsInfo> {
    List<MallNewsCategory> findNewsCategoryList();
    IPage<NewsListVo> findNewsInPage(NewsListDto newsListDto);
    List<NewsListVo> findTopNews();
    FebsResponse findAllBanner();
    FebsResponse findOnHookPlanList();
}
src/main/java/cc/mrbird/febs/dapp/service/IMallNewsInfoService.java
New file
@@ -0,0 +1,35 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.dto.MallNewsInfoDto;
import cc.mrbird.febs.dapp.entity.MallNewsCategory;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.vo.AdminMallNewsInfoVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface IMallNewsInfoService extends IService<MallNewsInfo> {
    IPage<AdminMallNewsInfoVo> getNewInfoList(MallNewsInfo mallNewsInfo, QueryRequest request);
    FebsResponse addNewsInfo(MallNewsInfoDto mallNewsInfoDto);
    FebsResponse delNewsInfo(Long id);
    FebsResponse updateNewsInfo(MallNewsInfoDto mallNewsInfoDto);
    MallNewsInfo getNewsInfoById(long id);
    IPage<MallNewsCategory> findNewsCategoryInPage(MallNewsCategory mallNewsCategory, QueryRequest request);
    void addOrModifyNewsCategory(MallNewsCategory mallNewsCategory);
    MallNewsCategory findNewsCategoryById(Long id);
    List<MallNewsCategory> findAllCategory();
    FebsResponse delNews(Long id);
}
src/main/java/cc/mrbird/febs/dapp/service/MemberOnHookPlan.java
New file
@@ -0,0 +1,17 @@
package cc.mrbird.febs.dapp.service;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public interface MemberOnHookPlan {
    /**
     * hours:工作时长
     * hangingRevenue:收益率
     * plan:挂机方案
     */
    Map<String, LinkedList<String>> getMemberOnHook(Double hours, BigDecimal hangingRevenue, List<Map<String,String>> plan);
}
src/main/java/cc/mrbird/febs/dapp/service/impl/AdminBannerServiceImpl.java
New file
@@ -0,0 +1,70 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.entity.PlatformBanner;
import cc.mrbird.febs.dapp.mapper.PlatformBannerMapper;
import cc.mrbird.febs.dapp.service.IAdminBannerService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class AdminBannerServiceImpl extends ServiceImpl<PlatformBannerMapper, PlatformBanner> implements IAdminBannerService {
    private final PlatformBannerMapper platformBannerMapper;
    @Override
    public IPage<PlatformBanner> findPlatformBannerInPage(PlatformBanner platformBannerEntity,
                                                          QueryRequest request) {
        Page<PlatformBanner> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<PlatformBanner> platformBannerEntitys = platformBannerMapper.findPlatformBannerInPage(page, platformBannerEntity);
        return platformBannerEntitys;
    }
    @Override
    public PlatformBanner selectPlatformBannerById(long id) {
        PlatformBanner platformBannerEntity = platformBannerMapper.selectById(id);
        return platformBannerEntity;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse platformBannerConfirm(@Valid PlatformBanner platformBannerEntity) {
        platformBannerMapper.updateById(platformBannerEntity);
        return new FebsResponse().success();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse platformBannerDelete(@NotNull(message = "{required}") Long id) {
        platformBannerMapper.deleteById(id);
        return new FebsResponse().success();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void platformBannerAdd(@Valid PlatformBanner platformBannerEntity) {
        PlatformBanner platformBannerEntityAdd = new PlatformBanner();
        platformBannerEntityAdd.setImageUrl(platformBannerEntity.getImageUrl());
        platformBannerEntityAdd.setIsInside(platformBannerEntity.getIsInside());
        platformBannerEntityAdd.setIsJump(platformBannerEntity.getIsJump());
        platformBannerEntityAdd.setIsTop(platformBannerEntity.getIsTop());
        platformBannerEntityAdd.setJumpUrl(platformBannerEntity.getJumpUrl());
        platformBannerEntityAdd.setName(platformBannerEntity.getName());
        platformBannerEntityAdd.setShowPort(platformBannerEntity.getShowPort());
        platformBannerEntityAdd.setSort(platformBannerEntity.getSort());
        platformBannerMapper.insert(platformBannerEntityAdd);
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/AdminOperationServiceImpl.java
New file
@@ -0,0 +1,119 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.configure.i18n.MessageSourceUtils;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.dapp.entity.DappAccountMoneyChangeEntity;
import cc.mrbird.febs.dapp.entity.DappMemberEntity;
import cc.mrbird.febs.dapp.entity.DappWalletCoinEntity;
import cc.mrbird.febs.dapp.entity.MemberCoinWithdrawEntity;
import cc.mrbird.febs.dapp.mapper.DappAccountMoneyChangeDao;
import cc.mrbird.febs.dapp.mapper.DappMemberDao;
import cc.mrbird.febs.dapp.mapper.DappWalletCoinDao;
import cc.mrbird.febs.dapp.mapper.MemberCoinWithdrawDao;
import cc.mrbird.febs.dapp.service.AdminOperationService;
import cc.mrbird.febs.dapp.vo.AdminMemberCoinWithdrawVo;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
@Service
@RequiredArgsConstructor
public class AdminOperationServiceImpl extends ServiceImpl<DappMemberDao, DappMemberEntity> implements AdminOperationService {
    private final MemberCoinWithdrawDao memberCoinWithdrawDao;
    private final DappWalletCoinDao dappWalletCoinDao;
    private final DappMemberDao dappMemberDao;
    private final DappAccountMoneyChangeDao dappAccountMoneyChangeDao;
    @Override
    public IPage<AdminMemberCoinWithdrawVo> findMemberWithdrawCoinAllOneInPage(MemberCoinWithdrawEntity memberCoinWithdrawEntity, QueryRequest request) {
        Page<MemberCoinWithdrawEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<AdminMemberCoinWithdrawVo> adminMemberCoinWithdrawVoIPage = memberCoinWithdrawDao.findMemberWithdrawCoinInPage(page, memberCoinWithdrawEntity);
        return adminMemberCoinWithdrawVoIPage;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse agreeWithdraw(Long id) {
        MemberCoinWithdrawEntity memberCoinWithdrawEntity = memberCoinWithdrawDao.selectById(id);
        if(ObjectUtil.isEmpty(memberCoinWithdrawEntity)){
            throw new FebsException("刷新页面重试");
        }
        memberCoinWithdrawEntity.setStatus(MemberCoinWithdrawEntity.STATUS_YES);
        memberCoinWithdrawDao.updateById(memberCoinWithdrawEntity);
        //转出账户,总额减少,冻结减少
        BigDecimal amount = memberCoinWithdrawEntity.getAmount().setScale(2,BigDecimal.ROUND_DOWN);
        Long memberIdOut = memberCoinWithdrawEntity.getMemberId();
        DappWalletCoinEntity dappWalletCoinEntityOut = dappWalletCoinDao.selectByMemberId(memberIdOut);
        dappWalletCoinDao.delTotalAndDelFrozenById(dappWalletCoinEntityOut.getId(),amount);
        String isInside = memberCoinWithdrawEntity.getIsInside();
        String content = "";
        Integer type = 0;
        if(MemberCoinWithdrawEntity.ISINSIDE_NO.equals(isInside)){
            content = "提现";
            type = 2;
        }else{
            content = "转账";
            type = 4;
        }
        //转出账户生成一条账户资金变化记录
        DappAccountMoneyChangeEntity dappAccountMoneyChangeEntityOut = new DappAccountMoneyChangeEntity(memberIdOut,
                dappWalletCoinEntityOut.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN),
                amount,
                dappWalletCoinEntityOut.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN).subtract(amount),
                content,
                type);
        dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntityOut);
        //转入账户,总额增加,余额增加
        //转账
        if(MemberCoinWithdrawEntity.ISINSIDE_YES.equals(isInside)){
            String addressIn = memberCoinWithdrawEntity.getAddress();
            DappMemberEntity dappMemberEntityIn = dappMemberDao.selectMemberInfoByInviteId(addressIn);
            if(ObjectUtil.isEmpty(dappMemberEntityIn)){
                throw new FebsException("系统异常,联系开发人员");
            }
            DappWalletCoinEntity dappWalletCoinEntityIn = dappWalletCoinDao.selectByMemberId(dappMemberEntityIn.getId());
            Integer countIn = dappWalletCoinDao.addTotalAndaddAvailableById(dappWalletCoinEntityIn.getId(), memberCoinWithdrawEntity.getAmount());
            if(1 != countIn){
                throw new FebsException("系统异常,联系开发人员");
            }
            //生成流水记录
            DappAccountMoneyChangeEntity dappAccountMoneyChangeEntityIn = new DappAccountMoneyChangeEntity(memberIdOut,
                    dappWalletCoinEntityOut.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN),
                    amount,
                    dappWalletCoinEntityOut.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN).add(amount),
                    "转账",
                    4);
            dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntityIn);
        }
        return new FebsResponse().success();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse disagreeWithdraw(Long id) {
        MemberCoinWithdrawEntity memberCoinWithdrawEntity = memberCoinWithdrawDao.selectById(id);
        if(ObjectUtil.isEmpty(memberCoinWithdrawEntity)){
            throw new FebsException("刷新页面重试");
        }
        memberCoinWithdrawEntity.setStatus(MemberCoinWithdrawEntity.STATUS_NO);
        memberCoinWithdrawDao.updateById(memberCoinWithdrawEntity);
        DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberCoinWithdrawEntity.getMemberId());
        Integer count = dappWalletCoinDao.addFrozenAndDelAvailableById(dappWalletCoinEntity.getId(),memberCoinWithdrawEntity.getAmount());
        if(1 != count){
            throw new FebsException("系统异常,联系开发人员");
        }
        return new FebsResponse().success();
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/ApiIgtOnHookPlanServiceImpl.java
New file
@@ -0,0 +1,256 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.configure.i18n.MessageSourceUtils;
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.LoginUserUtil;
import cc.mrbird.febs.dapp.dto.ApiStartDto;
import cc.mrbird.febs.dapp.entity.*;
import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum;
import cc.mrbird.febs.dapp.enumerate.MemberOnHookPlanEnum;
import cc.mrbird.febs.dapp.mapper.*;
import cc.mrbird.febs.dapp.service.ApiIgtOnHookPlanService;
import cc.mrbird.febs.dapp.vo.ApiPlanInfoVo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.grpc.internal.JsonUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.bridge.MessageUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiIgtOnHookPlanServiceImpl extends ServiceImpl<IgtOnHookPlanOrderDao, IgtOnHookPlanOrder> implements ApiIgtOnHookPlanService {
    private final IgtOnHookPlanOrderDao igtOnHookPlanOrderDao;
    private final IgtOnHookPlanOrderItemDao igtOnHookPlanOrderItemDao;
    private final DappWalletCoinDao dappWalletCoinDao;
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    private final DappMemberDao dappMemberDao;
    private final DappAccountMoneyChangeDao dappAccountMoneyChangeDao;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse start(ApiStartDto apiStartDto) {
        /**
         * 开始挂机
         * 增加一条挂机记录
         * 匹配收益方案(预先生成)
         * 发送一条mq消息,根据受益方案生成挂机字表未生效详细记录
         * 余额减少
         * 更新用户表是否正在挂机状态字段
         * 定时器五分钟去更新一下详细记录的状态
         *
         */
        DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser();
        Long memberId = dappMemberEntity.getId();
        DappMemberEntity member = dappMemberDao.selectById(memberId);
        int isOnHook = member.getIsOnHook() == null ? 2 : member.getIsOnHook();
        if(1 == isOnHook){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("Operation_002"));
        }
        //挂机金额的倍数
        Integer planCode = apiStartDto.getPlanCode() == null ? 1 : apiStartDto.getPlanCode();
        if(0 >= planCode){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_001"));
        }
        //挂机金额
        BigDecimal balance = apiStartDto.getBalance() == null ? BigDecimal.ZERO : apiStartDto.getBalance();
        if(AppContants.ONHOOK_BASIC_AMOUNT.compareTo(balance) > 0){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_001"));
        }
        DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId);
        if(ObjectUtil.isEmpty(dappWalletCoinEntity)){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("login_err_003"));
        }
        BigDecimal availableAmount = dappWalletCoinEntity.getAvailableAmount();
        if(balance.compareTo(availableAmount) > 0){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_002"));
        }
        //增加一条挂机记录
        IgtOnHookPlanOrder igtOnHookPlanOrder = new IgtOnHookPlanOrder();
        igtOnHookPlanOrder.setMemberId(memberId);
        igtOnHookPlanOrder.setStartTime(DateUtil.date());
        igtOnHookPlanOrder.setState(IgtOnHookPlanOrder.STATE_START);
        igtOnHookPlanOrder.setPlanAmount(apiStartDto.getBalance());
        igtOnHookPlanOrder.setAvaAmount(apiStartDto.getBalance());
        igtOnHookPlanOrder.setPlanCode(apiStartDto.getPlanCode());
        igtOnHookPlanOrder.setProfit(AppContants.INIT_MONEY);
        igtOnHookPlanOrderDao.insert(igtOnHookPlanOrder);
        //余额减少
        Integer updateCount = dappWalletCoinDao.delAvailableDelTotalById(dappWalletCoinEntity.getId(), balance);
        if(1 != updateCount){
            throw new FebsException(MessageSourceUtils.getString("balance_err_002"));
        }
        DappMemberEntity dappMember= dappMemberDao.selectById(memberId);
        //更新用户表是否正在挂机状态字段
        dappMember.setIsOnHook(1);
        dappMemberDao.updateById(dappMember);
        List<DataDictionaryCustom> dataDictionaryCustoms = dataDictionaryCustomMapper.selectDicByType(DataDictionaryEnum.PLAN_A.getType());
        LinkedList<Map<String,String>> strings = new LinkedList<>();
        for(DataDictionaryCustom dataDictionaryCustom : dataDictionaryCustoms){
            Map<String, String> stringStringHashMap = new HashMap<>();
            stringStringHashMap.put(dataDictionaryCustom.getDescription(),dataDictionaryCustom.getValue());
            strings.add(stringStringHashMap);
        }
        //收益率
        BigDecimal hangingRevenue = BigDecimal.ZERO;
        //挂机时长
        DataDictionaryCustom maxHours = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.MAX_HOURS.getType(), DataDictionaryEnum.MAX_HOURS.getCode());
        if(ObjectUtil.isEmpty(maxHours)){
            throw new FebsException(MessageSourceUtils.getString("login_err_003"));
        }
        Double maxHoursValue = Double.parseDouble(maxHours.getValue());
        //获取用户信息的是否盈利字段
        Integer isProfit = dappMember.getIsProfit() == null ? 1 : dappMember.getIsProfit();
        String identity = null;
        if(isProfit == 2){
            identity = "IS_PROFIT_NO";
        }else{
            identity = "LEVEL_MB";
            DataDictionaryCustom levelMember = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.LEVEL_MB.getType(), dappMemberEntity.getIdentity());
            if(ObjectUtil.isEmpty(levelMember)){
                throw new FebsException(MessageSourceUtils.getString("login_err_003"));
            }
            String levelMemberValue = levelMember.getValue();
            JSONObject levelMemberValueParse = JSONUtil.parseObj(levelMemberValue);
            hangingRevenue = new BigDecimal(levelMemberValueParse.get("hangingRevenue").toString())
                    .multiply(new BigDecimal(0.01)).setScale(2,BigDecimal.ROUND_DOWN);
        }
        //获取挂机字表的顺序
        LinkedList<String> isProfitPlan = new LinkedList<>();
        Map<String, LinkedList<String>> identity_level = MemberOnHookPlanEnum.valueOf(identity)
                .getMemberOnHook(maxHoursValue,hangingRevenue,strings);
        isProfitPlan = identity_level.get(identity);
        if(CollUtil.isEmpty(isProfitPlan)){
            throw new FebsException(MessageSourceUtils.getString("login_err_003"));
        }
        int orderNum = 1;
        for(String profitPlan : isProfitPlan){
            JSONObject jsonObject = JSONUtil.parseObj(profitPlan);
            IgtOnHookPlanOrderItem igtOnHookPlanOrderItem = new IgtOnHookPlanOrderItem();
            igtOnHookPlanOrderItem.setMemberId(memberId);
            igtOnHookPlanOrderItem.setOrderId(igtOnHookPlanOrder.getId());
            BigDecimal amount = new BigDecimal(jsonObject.get("amount").toString());
            igtOnHookPlanOrderItem.setAmount(amount.multiply(new BigDecimal(planCode)));
            igtOnHookPlanOrderItem.setProfit(BigDecimal.ZERO.multiply(new BigDecimal(planCode)));
            igtOnHookPlanOrderItem.setState(2);
            igtOnHookPlanOrderItem.setPlanCode(planCode);
            igtOnHookPlanOrderItem.setIsGoal(1);
            igtOnHookPlanOrderItem.setOrderNum(orderNum);
            igtOnHookPlanOrderItemDao.insert(igtOnHookPlanOrderItem);
            orderNum++;
        }
        DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity = new DappAccountMoneyChangeEntity(memberId, availableAmount, balance
                , availableAmount.subtract(balance).setScale(2,BigDecimal.ROUND_DOWN), "挂机", 6);
        dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntity);
        return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001"));
    }
    @Override
    public FebsResponse endPlan(Long orderId) {
        DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser();
        Long memberId = dappMemberEntity.getId();
        /*
        1、更新主表为结束状态
        2、删除子表中未生效的记录
        3、计算总收益和总挂机剩余金额,操作用户资金账户信息
        4、生成流水记录
        5、更新用户表是否正在挂机状态字段为否
         */
        //更新主表为结束状态
        IgtOnHookPlanOrder igtOnHookPlanOrder = igtOnHookPlanOrderDao.selectById(orderId);
        igtOnHookPlanOrder.setState(2);
        igtOnHookPlanOrderDao.updateById(igtOnHookPlanOrder);
        //删除子表中未生效的记录
        QueryWrapper<IgtOnHookPlanOrderItem> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("order_id",orderId);
        objectQueryWrapper.eq("member_id",memberId);
        objectQueryWrapper.eq("state",2);
        igtOnHookPlanOrderItemDao.delete(objectQueryWrapper);
        //计算总收益和总挂机剩余金额,操作用户资金账户信息
        BigDecimal totalProfit = igtOnHookPlanOrderItemDao.selectTotalProfitByByOrderIdAndMemberIdAndState(orderId,memberId,1,2);
        BigDecimal totalAmount = igtOnHookPlanOrderItemDao.selectTotalAmountByByOrderIdAndMemberIdAndState(orderId,memberId,1,2);
        DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId);
        BigDecimal availableAmount = dappWalletCoinEntity.getAvailableAmount();
        //如果中奖,返回本金加收益加剩余总挂机金额
        BigDecimal total = totalProfit.add(totalAmount).add(igtOnHookPlanOrder.getAvaAmount()).setScale(2, BigDecimal.ROUND_DOWN);
        dappWalletCoinDao.addTotalAndaddAvailableById(memberId,total);
        //生成流水记录
        BigDecimal add = availableAmount.add(total);
        DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity = new DappAccountMoneyChangeEntity(memberId, availableAmount, total, add, "挂机收益", 5);
        dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntity);
        //更新用户表是否正在挂机状态字段为否
        DappMemberEntity dappMember= dappMemberDao.selectById(memberId);
        dappMember.setIsOnHook(3);
        dappMemberDao.updateById(dappMember);
        return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001"));
    }
    @Override
    public FebsResponse planInfo() {
        DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser();
        Long memberId = dappMemberEntity.getId();
        DappMemberEntity member = dappMemberDao.selectById(memberId);
        Integer isOnHook = member.getIsOnHook() == null ? 2 : member.getIsOnHook();
        ApiPlanInfoVo apiPlanInfoVo = new ApiPlanInfoVo();
        if(1 == isOnHook){
            //获取当前最新的一条
            IgtOnHookPlanOrder igtOnHookPlanOrder = igtOnHookPlanOrderDao.selectByMemberId(memberId);
            if(ObjectUtil.isNotEmpty(igtOnHookPlanOrder)){
                apiPlanInfoVo.setPlanAmount(igtOnHookPlanOrder.getPlanAmount());
                apiPlanInfoVo.setCreateTime(igtOnHookPlanOrder.getCreateTime());
                apiPlanInfoVo.setId(igtOnHookPlanOrder.getId());
                apiPlanInfoVo.setAvaAmount(igtOnHookPlanOrder.getAvaAmount());
                BigDecimal totalProfit = igtOnHookPlanOrderItemDao.selectTotalProfitByByOrderIdAndMemberIdAndState(igtOnHookPlanOrder.getId(),memberId,1,2);
                apiPlanInfoVo.setProfit(totalProfit.setScale(2,BigDecimal.ROUND_DOWN));
            }
        }
        return new FebsResponse().success().data(apiPlanInfoVo);
    }
    private String getProfitCase(String identity,BigDecimal balance){
        //匹配会员等级获取对应的收益率
        List<DataDictionaryCustom> dataDictionaryCustoms = dataDictionaryCustomMapper.selectDicByType(DataDictionaryEnum.LEVEL_MB.getType());
        if(CollUtil.isNotEmpty(dataDictionaryCustoms)){
            for(DataDictionaryCustom memberLevel : dataDictionaryCustoms){
                String code = memberLevel.getCode();
                String memberLevelValue = memberLevel.getValue();
                JSONObject profitValue = JSONUtil.parseObj(memberLevelValue);
                //挂机收益
                BigDecimal hangingRevenue = new BigDecimal(profitValue.get("hangingRevenue").toString()).divide(new BigDecimal(100));
                //预计收益
                BigDecimal expectProfit = balance.multiply(balance).setScale(2, BigDecimal.ROUND_DOWN);
            }
        }
        return null;
    }
    public static void main(String[] args) {
        int maxTimes = 10;
        for(int i =1;i<maxTimes;){
            maxTimes --;
            System.out.println(maxTimes);
        }
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/ApiMallNewsServiceImpl.java
New file
@@ -0,0 +1,92 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.NewsListDto;
import cc.mrbird.febs.dapp.entity.DataDictionaryCustom;
import cc.mrbird.febs.dapp.entity.MallNewsCategory;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.entity.PlatformBanner;
import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum;
import cc.mrbird.febs.dapp.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.dapp.mapper.MallNewsCategoryMapper;
import cc.mrbird.febs.dapp.mapper.MallNewsInfoMapper;
import cc.mrbird.febs.dapp.mapper.PlatformBannerMapper;
import cc.mrbird.febs.dapp.service.IApiMallNewsService;
import cc.mrbird.febs.dapp.vo.NewsListVo;
import cc.mrbird.febs.dapp.vo.OnHookPlanVo;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiMallNewsServiceImpl extends ServiceImpl<MallNewsInfoMapper, MallNewsInfo> implements IApiMallNewsService {
    private final MallNewsCategoryMapper mallNewsCategoryMapper;
    private final PlatformBannerMapper platformBannerMapper;
    private final DataDictionaryCustomMapper dictionaryCustomMapper;
    @Override
    public List<MallNewsCategory> findNewsCategoryList() {
        return mallNewsCategoryMapper.selectList(null);
    }
    @Override
    public IPage<NewsListVo> findNewsInPage(NewsListDto newsListDto) {
        Page<NewsListVo> page = new Page<>(newsListDto.getPageNum(), newsListDto.getPageSize());
        MallNewsInfo mallNewsInfo = new MallNewsInfo();
        mallNewsInfo.setCategoryId(newsListDto.getCategoryId());
        return this.baseMapper.selectNewsVoInPage(page, mallNewsInfo);
    }
    @Override
    public List<NewsListVo> findTopNews() {
        Page<NewsListVo> page = new Page<>(1, 999);
        MallNewsInfo mallNewsInfo = new MallNewsInfo();
        mallNewsInfo.setIsTop(1);
        IPage<NewsListVo> pageList = this.baseMapper.selectNewsVoInPage(page, mallNewsInfo);
        return pageList.getRecords();
    }
    @Override
    public FebsResponse findAllBanner() {
        QueryWrapper<PlatformBanner> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("is_top");
        List<PlatformBanner> paymentMethodList = platformBannerMapper.selectList(queryWrapper);
        return new FebsResponse().success().data(paymentMethodList);
    }
    @Override
    public FebsResponse findOnHookPlanList() {
        List<OnHookPlanVo> onHookPlanVoList = new ArrayList<>();
        List<DataDictionaryCustom> dataDictionaryCustoms = dictionaryCustomMapper.selectDicByType(DataDictionaryEnum.PLAN_A.getType());
        if(ObjectUtil.isNotEmpty(dataDictionaryCustoms)){
            for(DataDictionaryCustom dataDictionaryCustom : dataDictionaryCustoms){
                String dataDictionaryCustomValue = dataDictionaryCustom.getValue();
                JSONObject jsonObject = JSONUtil.parseObj(dataDictionaryCustomValue);
                String state = jsonObject.get("state").toString();
                if("1".equals(state)){
                    OnHookPlanVo onHookPlanVo = new OnHookPlanVo();
                    onHookPlanVo.setDescription(dataDictionaryCustom.getDescription());
                    onHookPlanVo.setAmount(jsonObject.get("amount").toString());
                    onHookPlanVo.setMultipleTimes(jsonObject.get("multipleTimes").toString());
                    onHookPlanVoList.add(onHookPlanVo);
                }
            }
        }
        return new FebsResponse().success().data(onHookPlanVoList);
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/DappMemberServiceImpl.java
@@ -2,6 +2,7 @@
import cc.mrbird.febs.common.configure.i18n.MessageSourceUtils;
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.FebsUtil;
@@ -11,30 +12,41 @@
import cc.mrbird.febs.dapp.chain.ChainEnum;
import cc.mrbird.febs.dapp.chain.ChainService;
import cc.mrbird.febs.dapp.chain.ContractChainService;
import cc.mrbird.febs.dapp.dto.ApproveDto;
import cc.mrbird.febs.dapp.dto.ConnectDto;
import cc.mrbird.febs.dapp.dto.PriceSettingDto;
import cc.mrbird.febs.dapp.dto.TeamListDto;
import cc.mrbird.febs.dapp.dto.*;
import cc.mrbird.febs.dapp.entity.*;
import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum;
import cc.mrbird.febs.dapp.mapper.*;
import cc.mrbird.febs.dapp.service.DappMemberService;
import cc.mrbird.febs.dapp.utils.CaptchaUtil;
import cc.mrbird.febs.dapp.utils.UUIDUtil;
import cc.mrbird.febs.dapp.vo.ApiAmountChangeListVo;
import cc.mrbird.febs.dapp.vo.MemberInfoVo;
import cc.mrbird.febs.dapp.vo.TeamListVo;
import cc.mrbird.febs.system.entity.User;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * @author 
@@ -50,6 +62,10 @@
    private final DappTransferRecordDao dappTransferRecordDao;
    private final RedisUtils redisUtils;
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    private final PlatformBannerMapper platformBannerMapper;
    private final DappAccountMoneyChangeDao dappAccountMoneyChangeDao;
    private final RedisTemplate<String, Object> redisTemplate;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -361,4 +377,330 @@
        teamListDto.setInviteId(member.getInviteId());
        return dappMemberDao.selectTeamListInPage(teamListDto, page).getRecords();
    }
    @Override
    @Transactional
    public FebsResponse register(RegisterDto registerDto) {
        //验证验证码是否正确
        // 根据前端传回的token在redis中找对应的value
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        if(ObjectUtil.isEmpty(registerDto.getCodeToken()) || ObjectUtil.isEmpty(registerDto.getCodeValue())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("verification_code_err_001"));
        }
        String codeToken = registerDto.getCodeToken();
        String codeValue = registerDto.getCodeValue();
        if (redisTemplate.hasKey(codeToken)) {
            //验证通过, 删除对应的key
            if (valueOperations.get(codeToken).equals(codeValue)) {
                redisTemplate.delete(codeToken);
            } else {
                return new FebsResponse().fail().message(MessageSourceUtils.getString("verification_code_err_002"));
            }
        } else {
            return new FebsResponse().fail().message(MessageSourceUtils.getString("verification_code_err_003"));
        }
        // 查询是否存在该账号用户
        DappMemberEntity member = dappMemberDao.selectMemberInfoByUsername(registerDto.getAccount());
        if (ObjectUtil.isNotEmpty(member)) {
            return new FebsResponse().fail().message(MessageSourceUtils.getString("register_err_004"));
        }
        DappMemberEntity refererMember = dappMemberDao.selectMemberInfoByInviteId(registerDto.getRefererId());
        if (ObjectUtil.isEmpty(refererMember)) {
            return new FebsResponse().fail().message(MessageSourceUtils.getString("register_err_005"));
        }
        member = new DappMemberEntity();
        member.setUsername(registerDto.getAccount());
        member.setPassword(SecureUtil.md5(registerDto.getPassword()));
        member.setIdentity(DataDictionaryEnum.LEVEL_MB.getCode());
        member.setRefererId(registerDto.getRefererId());
        dappMemberDao.insert(member);
        //更新用户信息
        String inviteId = ShareCodeUtil.toSerialCode(member.getId());
        member.setInviteId(inviteId);
        boolean flag = false;
        String parentId = member.getRefererId();
        String ids = "";
        while (!flag) {
            ids += ("," + parentId);
            DappMemberEntity parentMember = dappMemberDao.selectMemberInfoByInviteId(parentId);
            if (parentMember == null) {
                break;
            }
            parentId = parentMember.getRefererId();
            if (parentMember.getRefererId().equals(parentMember.getInviteId())) {
                flag = true;
            }
        }
        member.setRefererIds(ids);
        dappMemberDao.updateById(member);
        //初始化账户信息
        DappWalletCoinEntity dappWalletCoinEntity = new DappWalletCoinEntity();
        dappWalletCoinEntity.setMemberId(member.getId());
        dappWalletCoinEntity.setAvailableAmount(AppContants.INIT_MONEY);
        dappWalletCoinEntity.setFrozenAmount(AppContants.INIT_MONEY);
        dappWalletCoinEntity.setTotalAmount(AppContants.INIT_MONEY);
        dappWalletCoinDao.insert(dappWalletCoinEntity);
        return new FebsResponse().success().message(MessageSourceUtils.getString("register_err_006"));
    }
    @Override
    @Transactional
    public FebsResponse toLogin(LoginDto loginDto) {
        //验证验证码是否正确
        // 根据前端传回的token在redis中找对应的value
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        if(ObjectUtil.isEmpty(loginDto.getCodeToken()) || ObjectUtil.isEmpty(loginDto.getCodeValue())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("verification_code_err_001"));
        }
        String codeToken = loginDto.getCodeToken();
        String codeValue = loginDto.getCodeValue();
        if (redisTemplate.hasKey(codeToken)) {
            //验证通过, 删除对应的key
            if (valueOperations.get(codeToken).equals(codeValue)) {
                redisTemplate.delete(codeToken);
            } else {
                return new FebsResponse().fail().message(MessageSourceUtils.getString("verification_code_err_002"));
            }
        } else {
            return new FebsResponse().fail().message(MessageSourceUtils.getString("verification_code_err_003"));
        }
        String md5Pwd = SecureUtil.md5(loginDto.getPassword());
        DappMemberEntity dappMemberEntity = dappMemberDao.selectMemberInfoByUsernameAndPassword(loginDto.getAccount(), md5Pwd);
        if (ObjectUtil.isEmpty(dappMemberEntity)) {
            return new FebsResponse().fail().message(MessageSourceUtils.getString("login_err_001"));
        }
        if (DappMemberEntity.ACCOUNT_STATUS_DISABLED.equals(dappMemberEntity.getAccountStatus())) {
            return new FebsResponse().fail().message(MessageSourceUtils.getString("login_err_002"));
        }
        String redisKey = AppContants.REDIS_KEY_SIGN + dappMemberEntity.getId();
        String existToken = redisUtils.getString(redisKey);
        if (StrUtil.isNotBlank(existToken)) {
            Object o = redisUtils.get(existToken);
            if (ObjectUtil.isNotEmpty(o)) {
                redisUtils.del(existToken);
            }
        }
        String token = IdUtil.simpleUUID();
        redisUtils.set(token, JSONObject.toJSONString(dappMemberEntity), 3600);
        redisUtils.set(redisKey, token, 3600);
        Map<String, Object> authInfo = new HashMap<>();
        authInfo.put("token", token);
        authInfo.put("rasToken", generateAsaToken(token));
        return new FebsResponse().success().data(authInfo);
    }
    @Override
    @Transactional
    public FebsResponse touristLogin(TouristLoginDto touristLoginDto) {
        if(ObjectUtil.isEmpty(touristLoginDto.getTouristMark())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("login_err_003"));
        }
        String touristMark = touristLoginDto.getTouristMark();
        //查询当前游客是否登录过
        DappMemberEntity dappMemberEntity = dappMemberDao.selectMemberInfoByTouristMark(touristMark);
        if(ObjectUtil.isEmpty(dappMemberEntity)){
            dappMemberEntity = new DappMemberEntity();
            dappMemberEntity.setTouristMark(touristMark);
            dappMemberEntity.setIdentity(DataDictionaryEnum.LEVEL_TM.getCode());
            dappMemberDao.insert(dappMemberEntity);
            //初始化账户信息
            DappWalletCoinEntity dappWalletCoinEntity = new DappWalletCoinEntity();
            dappWalletCoinEntity.setMemberId(dappMemberEntity.getId());
            dappWalletCoinEntity.setAvailableAmount(AppContants.TOURIST_INIT_MONEY);
            dappWalletCoinEntity.setFrozenAmount(AppContants.INIT_MONEY);
            dappWalletCoinEntity.setTotalAmount(AppContants.TOURIST_INIT_MONEY);
            dappWalletCoinDao.insert(dappWalletCoinEntity);
        }
        String redisKey = AppContants.REDIS_KEY_SIGN + dappMemberEntity.getId();
        String existToken = redisUtils.getString(redisKey);
        if (StrUtil.isNotBlank(existToken)) {
            Object o = redisUtils.get(existToken);
            if (ObjectUtil.isNotEmpty(o)) {
                redisUtils.del(existToken);
            }
        }
        String token = IdUtil.simpleUUID();
        redisUtils.set(token, JSONObject.toJSONString(dappMemberEntity), 3600);
        redisUtils.set(redisKey, token, 3600);
        Map<String, Object> authInfo = new HashMap<>();
        authInfo.put("token", token);
        authInfo.put("rasToken", generateAsaToken(token));
        return new FebsResponse().success().data(authInfo);
    }
    @Autowired
    private CaptchaUtil captchaUtil;
    @Autowired
    private UUIDUtil uuidUtil;
    @Override
    public FebsResponse captchaCreator() throws IOException {
        return captchaUtil.catchaImgCreator();
    }
    @Override
    public Map<String, Object> createToken(String captcha) {
        //生成一个token
        String key = uuidUtil.getUUID32();
        //生成验证码对应的token  以token为key  验证码为value存在redis中
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, captcha);
        //设置验证码过期时间
        redisTemplate.expire(key, 1, TimeUnit.MINUTES);
        Map<String, Object> map = new HashMap<>();
        map.put("token", key);
        map.put("expire", 1);
        return map;
    }
    @Override
    public MemberInfoVo getMemberInfo() {
        DappMemberEntity member = LoginUserUtil.getAppUser();
        Long memberId = member.getId();
        DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId);
        MemberInfoVo memberInfoVo = new MemberInfoVo();
        String identity = dappMemberEntity.getIdentity();
        if(ObjectUtil.isEmpty(dappMemberEntity.getIdentity())){
            memberInfoVo.setIdentityCode(DataDictionaryEnum.LEVEL_TM.getCode());
            memberInfoVo.setIdentity("游客");
            memberInfoVo.setUsername("游客");
        }else if(DataDictionaryEnum.LEVEL_TM.getCode().equals(identity)){
            memberInfoVo.setIdentityCode(identity);
            memberInfoVo.setIdentity("游客");
            memberInfoVo.setUsername("游客");
        }else{
            memberInfoVo.setInviteId(dappMemberEntity.getInviteId());
            memberInfoVo.setIdentityCode(identity);
            memberInfoVo.setIdentity("会员");
            memberInfoVo.setUsername(dappMemberEntity.getUsername());
        }
        if(ObjectUtil.isNotEmpty(dappMemberEntity.getTransferCode())){
            memberInfoVo.setIsSetTransferCode(1);
        }else{
            memberInfoVo.setIsSetTransferCode(2);
        }
        int isOnHook = dappMemberEntity.getIsOnHook() == null ? 2 : dappMemberEntity.getIsOnHook();
        memberInfoVo.setIsOnHook(isOnHook);
        DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId);
        if(ObjectUtil.isEmpty(dappMemberEntity)){
            memberInfoVo.setTotalAmount(AppContants.INIT_MONEY);
        }else{
            BigDecimal totalAmount = dappWalletCoinEntity.getTotalAmount();
            if(BigDecimal.ZERO.compareTo(totalAmount) > 0){
                memberInfoVo.setTotalAmount(AppContants.INIT_MONEY);
            }else{
                memberInfoVo.setTotalAmount(totalAmount.setScale(2,BigDecimal.ROUND_DOWN));
            }
        }
        return memberInfoVo;
    }
    @Override
    public Boolean isMember(String inviteId) {
        boolean flag = false;
        DappMemberEntity dappMemberEntity = dappMemberDao.selectMemberInfoByInviteId(inviteId);
        if(ObjectUtil.isEmpty(dappMemberEntity)){
            return flag;
        }else if(!DataDictionaryEnum.LEVEL_TM.getCode().equals(dappMemberEntity.getIdentity())){
            flag = true;
        }else{
            flag = false;
        }
        return flag;
    }
    @Override
    public Boolean isRelationShip(String inviteIdOut, String inviteIdIn) {
        boolean flag = false;
        DappMemberEntity dappMemberEntityOut = dappMemberDao.selectMemberInfoByInviteId(inviteIdOut);
        DappMemberEntity dappMemberEntityIn = dappMemberDao.selectMemberInfoByInviteId(inviteIdIn);
        if(ObjectUtil.isEmpty(dappMemberEntityOut) || ObjectUtil.isEmpty(dappMemberEntityIn)){
            return flag;
        }
        DappMemberEntity isRelationShipOut = dappMemberDao.selectRelationShipByInviteIdOutAndMemberId(dappMemberEntityOut.getId(), inviteIdIn);
        DappMemberEntity isRelationShipIn = dappMemberDao.selectRelationShipByInviteIdOutAndMemberId(dappMemberEntityIn.getId(), inviteIdOut);
        if(ObjectUtil.isNotEmpty(isRelationShipOut) || ObjectUtil.isNotEmpty(isRelationShipIn)){
            flag = true;
        }else{
            flag = false;
        }
        return flag;
    }
    @Override
    public void resetTransferCode(Long id) {
        DappMemberEntity member = dappMemberDao.selectById(id);
        if (ObjectUtil.isEmpty(member)) {
            throw new FebsException("用户不存在");
        }
        String md5Pwd = SecureUtil.md5(AppContants.MEMBER_TRANSFER_CODE);
        member.setTransferCode(md5Pwd);
        dappMemberDao.updateById(member);
    }
    @Override
    public void resetPassword(Long id) {
        DappMemberEntity member = dappMemberDao.selectById(id);
        if (ObjectUtil.isEmpty(member)) {
            throw new FebsException("用户不存在");
        }
        String md5Pwd = SecureUtil.md5(AppContants.MEMBER_LOGIN_CODE);
        member.setPassword(md5Pwd);
        dappMemberDao.updateById(member);
    }
    @Override
    public Boolean validateTransferCode(String transferCode, Long memberId) {
        boolean flag = false;
        DappMemberEntity member = dappMemberDao.selectById(memberId);
        if (ObjectUtil.isEmpty(member)) {
            return flag;
        }
        String transferCodeMember = member.getTransferCode();
        String transferCodeMd5Pwd = SecureUtil.md5(transferCode);
        if(transferCodeMd5Pwd.equals(transferCodeMember)){
            flag = true;
        }else{
            return flag;
        }
        return flag;
    }
    @Override
    public List<ApiAmountChangeListVo> findAmountInPage(ApiAmountChangeDto apiAmountChangeDto) {
        Page<ApiAmountChangeListVo> page = new Page<>(apiAmountChangeDto.getPageNum(), apiAmountChangeDto.getPageSize());
        DappMemberEntity member = LoginUserUtil.getAppUser();
        DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity = new DappAccountMoneyChangeEntity();
        if (apiAmountChangeDto.getType() != null && apiAmountChangeDto.getType() != 0) {
            dappAccountMoneyChangeEntity.setType(apiAmountChangeDto.getType());
        }
        if (ObjectUtil.isNotEmpty(apiAmountChangeDto.getStartTime())) {
            dappAccountMoneyChangeEntity.setStartTime(apiAmountChangeDto.getStartTime());
        }
        if (ObjectUtil.isNotEmpty(apiAmountChangeDto.getEndTime())) {
            dappAccountMoneyChangeEntity.setEndTime(apiAmountChangeDto.getEndTime());
        }
        dappAccountMoneyChangeEntity.setMemberId(member.getId());
        IPage<ApiAmountChangeListVo> records = dappAccountMoneyChangeDao.selectChangeListInPage(page, dappAccountMoneyChangeEntity);
        return records.getRecords();
    }
    public String generateAsaToken(String token) {
        RSA rsa = new RSA(null, AppContants.PUBLIC_KEY);
        return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey);
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java
@@ -1,6 +1,7 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.utils.LoginUserUtil;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.dapp.chain.ChainEnum;
@@ -14,32 +15,25 @@
import cc.mrbird.febs.dapp.utils.OnlineTransferUtil;
import cc.mrbird.febs.dapp.vo.RedisTransferPoolVo;
import cc.mrbird.febs.dapp.vo.SlipSettingVo;
import cc.mrbird.febs.job.SystemTradeJob;
import cc.mrbird.febs.rabbit.producer.ChainProducer;
import cn.hutool.core.collection.CollUtil;
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.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
/**
@@ -925,4 +919,58 @@
        });
        return list;
    }
    @Override
    public List<DataDictionaryCustom> findDataDicByType(String type) {
        return dataDictionaryCustomMapper.selectDicByType(type);
    }
    @Override
    public void levelSystemSetting(Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (entry.getValue() instanceof String) {
                dataDictionaryCustomMapper.updateDicValueByTypeAndCode(null, entry.getKey(), (String) entry.getValue());
            } else {
                List<LinkedHashMap<String, Object>> value = (List<LinkedHashMap<String, Object>>) entry.getValue();
                for (LinkedHashMap<String, Object> dic : value) {
                    String type = (String) dic.get("type");
                    String code = (String) dic.get("code");
                    String dataValue = (String) dic.get("value");
                    dataDictionaryCustomMapper.updateDicValueByTypeAndCode(type, code, dataValue);
                }
            }
        }
    }
    @Override
    @Transactional
    public FebsResponse enableOnHook(Long id) {
        DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectById(id);
        if (ObjectUtil.isEmpty(dataDictionaryCustom)) {
            return new FebsResponse().fail().message("网络繁忙,请刷新当前页面");
        }
        String type = dataDictionaryCustom.getType();
        String code = dataDictionaryCustom.getCode();
        String dicValue = dataDictionaryCustom.getValue();
        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(dicValue);
        jsonObject.set("state",1);
        dataDictionaryCustomMapper.updateDicValueByTypeAndCode(type, code, jsonObject.toString());
        return new FebsResponse().success();
    }
    @Override
    public FebsResponse disableOnHook(Long id) {
        DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectById(id);
        if (ObjectUtil.isEmpty(dataDictionaryCustom)) {
            return new FebsResponse().fail().message("网络繁忙,请刷新当前页面");
        }
        String type = dataDictionaryCustom.getType();
        String code = dataDictionaryCustom.getCode();
        String dicValue = dataDictionaryCustom.getValue();
        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(dicValue);
        jsonObject.set("state",2);
        dataDictionaryCustomMapper.updateDicValueByTypeAndCode(type, code, jsonObject.toString());
        return new FebsResponse().success();
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java
@@ -2,6 +2,7 @@
import cc.mrbird.febs.common.configure.i18n.MessageSourceUtils;
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.FebsUtil;
@@ -12,17 +13,22 @@
import cc.mrbird.febs.dapp.chain.ContractChainService;
import cc.mrbird.febs.dapp.dto.*;
import cc.mrbird.febs.dapp.entity.*;
import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum;
import cc.mrbird.febs.dapp.mapper.*;
import cc.mrbird.febs.dapp.service.DappMemberService;
import cc.mrbird.febs.dapp.service.DappSystemService;
import cc.mrbird.febs.dapp.service.DappWalletService;
import cc.mrbird.febs.dapp.utils.BoxUtil;
import cc.mrbird.febs.dapp.vo.ActiveNftListVo;
import cc.mrbird.febs.dapp.vo.ApiMemberWalletCoinVo;
import cc.mrbird.febs.dapp.vo.WalletInfoVo;
import cn.hutool.core.collection.CollUtil;
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.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -55,6 +61,8 @@
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    private final DappSystemService dappSystemService;
    private final DappNftActivationDao dappNftActivationDao;
    private final DappMemberService dappMemberService;
    private final MemberCoinWithdrawDao memberCoinWithdrawDao;
    @Override
    public WalletInfoVo walletInfo() {
@@ -476,4 +484,208 @@
        return list;
    }
    @Override
    public FebsResponse findMemberWalletCoin() {
        DappMemberEntity member = LoginUserUtil.getAppUser();
        Long memberId = member.getId();
        DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId);
        DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId);
        ApiMemberWalletCoinVo apiMemberWalletCoinVo = new ApiMemberWalletCoinVo();
        if(ObjectUtil.isNotEmpty(dappWalletCoinEntity)){
            apiMemberWalletCoinVo.setTotalAmount(dappWalletCoinEntity.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN));
            apiMemberWalletCoinVo.setFrozenAmount(dappWalletCoinEntity.getFrozenAmount().setScale(2,BigDecimal.ROUND_DOWN));
            apiMemberWalletCoinVo.setAvailableAmount(dappWalletCoinEntity.getAvailableAmount().setScale(2,BigDecimal.ROUND_DOWN));
        }
        return new FebsResponse().success().data(apiMemberWalletCoinVo);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse transferInside(ApiTransferInsideDto apiTransferInsideDto) {
        //判断入参
        BigDecimal balance = apiTransferInsideDto.getBalance() == null ? BigDecimal.ZERO : apiTransferInsideDto.getBalance().setScale(2,BigDecimal.ROUND_DOWN);
        if(BigDecimal.ZERO.compareTo(balance) >= 0){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_001"));
        }
        if(ObjectUtil.isEmpty(apiTransferInsideDto.getInviteId())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_001"));
        }
        if(ObjectUtil.isEmpty(apiTransferInsideDto.getTransferCode())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_006"));
        }
        DappMemberEntity dappMemberEntityOut = LoginUserUtil.getAppUser();
        Long memberIdOut = dappMemberEntityOut.getId();
        //判断双方是否是会员
        if(ObjectUtil.isEmpty(dappMemberEntityOut.getInviteId())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_002"));
        }
        String inviteIdOut = dappMemberEntityOut.getInviteId();
        Boolean isMemberOut = dappMemberService.isMember(inviteIdOut);
        if(!isMemberOut){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_002"));
        }
        String inviteIdIn = apiTransferInsideDto.getInviteId();
        Boolean isMemberIn = dappMemberService.isMember(apiTransferInsideDto.getInviteId());
        if(!isMemberIn){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_003"));
        }
        //验证资金密码
        Boolean aBoolean = dappMemberService.validateTransferCode(apiTransferInsideDto.getTransferCode(), dappMemberEntityOut.getId());
        if(!aBoolean){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_006"));
        }
        //判断内部转账规则
        DataDictionaryCustom withdrawTimesDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.WITHDRAW_TIMES.getType(), DataDictionaryEnum.WITHDRAW_TIMES.getCode());
//
//        DataDictionaryCustom outAccountProfitDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getType(), DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getCode());
//        //todo 获取用户的总收益
//        BigDecimal totalProfitOut = new BigDecimal("0.3");
//        BigDecimal outAccountProfit = outAccountProfitDic.getValue() == null ? new BigDecimal("0.3") : new BigDecimal(outAccountProfitDic.getValue());
//        if(outAccountProfit.compareTo(totalProfitOut) > 0){
//            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_004"));
//        }
        DataDictionaryCustom accountRelationDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.ACCOUNT_RELATION.getType(), DataDictionaryEnum.ACCOUNT_RELATION.getCode());
        Integer accountRelation = Integer.parseInt(accountRelationDic.getValue());
        if(1 == accountRelation){
            Boolean relationShip = dappMemberService.isRelationShip(inviteIdOut, inviteIdIn);
            if(!relationShip){
                return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_005"));
            }
        }
//        DataDictionaryCustom serviceFeeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.SERVICE_FEE.getType(), DataDictionaryEnum.SERVICE_FEE.getCode());
//        Integer serviceFee = Integer.parseInt(serviceFeeDic.getValue());
        //查询转出会员
        //转出会员当前余额要大于等于划转金额
        DappWalletCoinEntity dappWalletCoinEntityOut = dappWalletCoinDao.selectByMemberId(memberIdOut);
        BigDecimal availableAmountOut = dappWalletCoinEntityOut.getAvailableAmount().setScale(2,BigDecimal.ROUND_DOWN);
        if(availableAmountOut.compareTo(balance) < 0){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_002"));
        }
        //转出账户,余额减少,冻结增加
        Integer countOut = dappWalletCoinDao.addFrozenAndDelAvailableById(dappWalletCoinEntityOut.getId(), balance);
        if(1 != countOut){
            throw new FebsException(MessageSourceUtils.getString("balance_err_002"));
        }
        //转出账户生成一条内部转账记录
        MemberCoinWithdrawEntity memberCoinWithdrawEntity = new MemberCoinWithdrawEntity();
        memberCoinWithdrawEntity.setAddress(inviteIdIn);
        memberCoinWithdrawEntity.setAmount(balance);
        memberCoinWithdrawEntity.setFeeAmount(BigDecimal.ZERO);
        memberCoinWithdrawEntity.setSymbol("USDT");
        memberCoinWithdrawEntity.setMemberId(memberIdOut);
        memberCoinWithdrawEntity.setStatus(MemberCoinWithdrawEntity.STATUS_DOING);
        memberCoinWithdrawEntity.setIsInside(MemberCoinWithdrawEntity.ISINSIDE_YES);
        memberCoinWithdrawDao.insert(memberCoinWithdrawEntity);
        return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001"));
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse transferPasswordSet(ApiTransferPasswordDto apiTransferPasswordDto) {
        if(ObjectUtil.isEmpty(apiTransferPasswordDto.getOldTransferPassword())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_007"));
        }
        if(ObjectUtil.isEmpty(apiTransferPasswordDto.getNewTransferPassword())
                || ObjectUtil.isEmpty(apiTransferPasswordDto.getNewTransferPasswordAgain())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_008"));
        }
        String newTransferPassword = apiTransferPasswordDto.getNewTransferPassword();
        String newTransferPasswordAgain = apiTransferPasswordDto.getNewTransferPasswordAgain();
        if(!newTransferPassword.equals(newTransferPasswordAgain)){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_009"));
        }
        DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser();
        Long memberId = dappMemberEntity.getId();
        DappMemberEntity memberEntity = dappMemberDao.selectById(memberId);
        memberEntity.setTransferCode(SecureUtil.md5(apiTransferPasswordDto.getNewTransferPassword()));
        dappMemberDao.updateById(memberEntity);
        return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001"));
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse transferOutside(ApiTransferOutsideDto apiTransferOutsideDto) {
        DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser();
        Long memberId = dappMemberEntity.getId();
        if(ObjectUtil.isEmpty(apiTransferOutsideDto.getAddress())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_0010"));
        }
        String address = apiTransferOutsideDto.getAddress();
        if(ObjectUtil.isEmpty(apiTransferOutsideDto.getBalance())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_001"));
        }
        BigDecimal balance = apiTransferOutsideDto.getBalance();
        if(BigDecimal.ZERO.compareTo(balance) >= 0){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_001"));
        }
        DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId);
        BigDecimal availableAmount = dappWalletCoinEntity.getAvailableAmount();
        if(balance.compareTo(availableAmount) > 0){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_002"));
        }
        //验证资金密码
        Boolean aBoolean = dappMemberService.validateTransferCode(apiTransferOutsideDto.getTransferCode(), memberId);
        if(!aBoolean){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_006"));
        }
        //提现条件收益率
        DataDictionaryCustom outAccountProfitDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getType(), DataDictionaryEnum.OUT_ACCOUNT_PROFIT.getCode());
        //todo 获取用户的总收益
        BigDecimal totalProfitOut = new BigDecimal("0.3");
        BigDecimal outAccountProfit = outAccountProfitDic.getValue() == null ? new BigDecimal("0.3") : new BigDecimal(outAccountProfitDic.getValue());
        if(outAccountProfit.compareTo(totalProfitOut) > 0){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_004"));
        }
        //余额减少冻结增加
        Integer count = dappWalletCoinDao.addFrozenAndDelAvailableById(memberId, balance);
        if(1 != count){
            throw new FebsException(MessageSourceUtils.getString("balance_err_002"));
        }
        DataDictionaryCustom serviceFeeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.SERVICE_FEE.getType(), DataDictionaryEnum.SERVICE_FEE.getCode());
        BigDecimal serviceFee = new BigDecimal(serviceFeeDic.getValue());
        //转出账户生成一条内部转账记录
        MemberCoinWithdrawEntity memberCoinWithdrawEntity = new MemberCoinWithdrawEntity();
        memberCoinWithdrawEntity.setAddress(address);
        memberCoinWithdrawEntity.setTag(apiTransferOutsideDto.getType());
        memberCoinWithdrawEntity.setAmount(balance);
        memberCoinWithdrawEntity.setFeeAmount(serviceFee);
        memberCoinWithdrawEntity.setSymbol("USDT");
        memberCoinWithdrawEntity.setMemberId(memberId);
        memberCoinWithdrawEntity.setStatus(MemberCoinWithdrawEntity.STATUS_DOING);
        memberCoinWithdrawEntity.setIsInside(MemberCoinWithdrawEntity.ISINSIDE_NO);
        memberCoinWithdrawDao.insert(memberCoinWithdrawEntity);
        return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001"));
    }
    @Override
    public FebsResponse transferPassword(ApiTransferPasswordDto apiTransferPasswordDto) {
        if(ObjectUtil.isEmpty(apiTransferPasswordDto.getNewTransferPassword())
                || ObjectUtil.isEmpty(apiTransferPasswordDto.getNewTransferPasswordAgain())){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_008"));
        }
        String newTransferPassword = apiTransferPasswordDto.getNewTransferPassword();
        String newTransferPasswordAgain = apiTransferPasswordDto.getNewTransferPasswordAgain();
        if(!newTransferPassword.equals(newTransferPasswordAgain)){
            return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_009"));
        }
        DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser();
        Long memberId = dappMemberEntity.getId();
        DappMemberEntity memberEntity = dappMemberDao.selectById(memberId);
        memberEntity.setTransferCode(SecureUtil.md5(apiTransferPasswordDto.getNewTransferPassword()));
        dappMemberDao.updateById(memberEntity);
        return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001"));
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/MallNewsInfoServiceImpl.java
New file
@@ -0,0 +1,148 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.dto.MallNewsInfoDto;
import cc.mrbird.febs.dapp.entity.MallNewsCategory;
import cc.mrbird.febs.dapp.entity.MallNewsInfo;
import cc.mrbird.febs.dapp.mapper.MallNewsCategoryMapper;
import cc.mrbird.febs.dapp.mapper.MallNewsInfoMapper;
import cc.mrbird.febs.dapp.service.IMallNewsInfoService;
import cc.mrbird.febs.dapp.vo.AdminMallNewsInfoVo;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class MallNewsInfoServiceImpl extends ServiceImpl<MallNewsInfoMapper, MallNewsInfo> implements IMallNewsInfoService {
    private final MallNewsCategoryMapper mallNewsCategoryMapper;
    @Override
    public IPage<AdminMallNewsInfoVo> getNewInfoList(MallNewsInfo mallNewsInfo, QueryRequest request) {
        Page<AdminMallNewsInfoVo> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<AdminMallNewsInfoVo> adminMallNewsInfoVos = this.baseMapper.getNewInfoListInPage(page, mallNewsInfo);
        return adminMallNewsInfoVos;
    }
    @Override
    public FebsResponse addNewsInfo(MallNewsInfoDto mallNewsInfoDto) {
//        Integer type = mallNewsInfoDto.getType();
//        if(type == 2){
//            Long goodsId = mallNewsInfoDto.getGoodsId()==null?0L:mallNewsInfoDto.getGoodsId();
//            if(goodsId == 0L){
//                return new FebsResponse().fail().message("请选择跳转的产品");
//            }
//        }
//        MallNewsInfo mallNewsInfo = new MallNewsInfo();
//        mallNewsInfo.setTitle(mallNewsInfoDto.getTitle());
//        mallNewsInfo.setContent(mallNewsInfoDto.getContent());
//        mallNewsInfo.setType(mallNewsInfoDto.getType());
//        if(mallNewsInfoDto.getType() == 2){
//            mallNewsInfo.setTargetId(mallNewsInfoDto.getGoodsId());
//        }
        String content = mallNewsInfoDto.getContent();
        if(StrUtil.isNotBlank(content)){
            //正文图片样式居中
            mallNewsInfoDto.setContent(content+"<style>img{max-width:100%!important;}</style>");
        }
        MallNewsInfo mallNewsInfo = new MallNewsInfo();
        BeanUtil.copyProperties(mallNewsInfoDto, mallNewsInfo);
        this.baseMapper.insert(mallNewsInfo);
        return new FebsResponse().success();
    }
    @Override
    public FebsResponse delNewsInfo(Long id) {
        MallNewsCategory mallNewsCategory = mallNewsCategoryMapper.selectById(id);
        if(ObjectUtil.isEmpty(mallNewsCategory)){
            return new FebsResponse().fail().message("系统繁忙,请刷新页面重试");
        }
        mallNewsCategoryMapper.deleteById(id);
        return new FebsResponse().success();
    }
    @Override
    public FebsResponse updateNewsInfo(MallNewsInfoDto mallNewsInfoDto) {
        MallNewsInfo mallNewsInfoBefore = this.baseMapper.selectById(mallNewsInfoDto.getId());
        if(ObjectUtil.isEmpty(mallNewsInfoBefore)){
            return new FebsResponse().fail().message("系统繁忙,请刷新页面重试");
        }
//        Integer type = mallNewsInfoDto.getType();
//        if(type == 2){
//            Long goodsId = mallNewsInfoDto.getGoodsId()==null?0L:mallNewsInfoDto.getGoodsId();
//            if(goodsId == 0L){
//                return new FebsResponse().fail().message("请选择跳转的产品");
//            }
//        }
//        MallNewsInfo mallNewsInfo = new MallNewsInfo();
//        mallNewsInfo.setTitle(mallNewsInfoDto.getTitle());
//        mallNewsInfo.setContent(mallNewsInfoDto.getContent());
//        mallNewsInfo.setType(mallNewsInfoDto.getType());
//        if(mallNewsInfoDto.getType() == 2){
//            mallNewsInfo.setTargetId(mallNewsInfoDto.getGoodsId());
//        }
//        this.baseMapper.insert(mallNewsInfo);
//        this.baseMapper.deleteById(mallNewsInfoDto.getId());
        String content = mallNewsInfoDto.getContent();
        if(StrUtil.isNotBlank(content)){
            //正文图片样式居中
            mallNewsInfoDto.setContent(content+"<style>img{max-width:100%!important;}</style>");
        }
        MallNewsInfo mallNewsInfo = new MallNewsInfo();
        BeanUtil.copyProperties(mallNewsInfoDto, mallNewsInfo);
        this.baseMapper.updateById(mallNewsInfo);
        return new FebsResponse().success();
    }
    @Override
    public MallNewsInfo getNewsInfoById(long id) {
        return this.baseMapper.selectById(id);
    }
    @Override
    public IPage<MallNewsCategory> findNewsCategoryInPage(MallNewsCategory mallNewsCategory, QueryRequest request) {
        Page<MallNewsCategory> page = new Page<>(request.getPageNum(), request.getPageSize());
        return mallNewsCategoryMapper.selectInPage(mallNewsCategory, page);
    }
    @Override
    public void addOrModifyNewsCategory(MallNewsCategory mallNewsCategory) {
        if (mallNewsCategory.getId() != null) {
            mallNewsCategoryMapper.updateById(mallNewsCategory);
            return;
        }
        mallNewsCategoryMapper.insert(mallNewsCategory);
    }
    @Override
    public MallNewsCategory findNewsCategoryById(Long id) {
        return mallNewsCategoryMapper.selectById(id);
    }
    @Override
    public List<MallNewsCategory> findAllCategory() {
        return mallNewsCategoryMapper.selectList(null);
    }
    @Override
    public FebsResponse delNews(Long id) {
        MallNewsInfo mallNewsInfo = this.baseMapper.selectById(id);
        if(ObjectUtil.isEmpty(mallNewsInfo)){
            return new FebsResponse().fail().message("系统繁忙,请刷新页面重试");
        }
        this.baseMapper.deleteById(id);
        return new FebsResponse().success();
    }
}
src/main/java/cc/mrbird/febs/dapp/utils/CaptchaUtil.java
New file
@@ -0,0 +1,93 @@
package cc.mrbird.febs.dapp.utils;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.service.DappMemberService;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Random;
@Component
public class CaptchaUtil {
    @Autowired
    private DefaultKaptcha producer;
    @Autowired
    private DappMemberService dappMemberService;
    //生成catchCreator的map
    public FebsResponse catchaImgCreator() throws IOException {
        //生成文字验证码
        String text = producer.createText();
        //生成文字对应的图片验证码
        BufferedImage image = creatImage(text);
        //将图片写出
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", outputStream);
        //对写出的字节数组进行Base64编码 ==> 用于传递8比特字节码
        BASE64Encoder encoder = new BASE64Encoder();
        //生成token
        Map<String, Object> token = dappMemberService.createToken(text);
        token.put("img", encoder.encode(outputStream.toByteArray()));
        return new FebsResponse().success().data(token);
    }
    private static final long serialVersionUID = 1L;
    //给定范围获得随机颜色
    public Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
    public BufferedImage creatImage(String code) {
        int width = 150, height = 42;
        //生成随机类
        Random random = new Random();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //获取图形上下文
        Graphics g = image.getGraphics();
        // 设定背景色
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
        //设定字体 第二个参数为字体为加粗
        g.setFont(new Font("Times New Roman", Font.BOLD, 45));
        // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);
        }
        // 取随机产生的认证码(4位数字)
        for (int i = 0; i < code.length(); i++) {
            String rand = code.substring(i, i + 1);
            // 将认证码显示到图象中
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            //调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
            g.drawString(rand, 30 * i + 18, 35);
        }
        // 图象生效
        g.dispose();
        return image;
    }
}
src/main/java/cc/mrbird/febs/dapp/utils/KaptchaConfig.java
New file
@@ -0,0 +1,47 @@
package cc.mrbird.febs.dapp.utils;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class KaptchaConfig {
    @Bean
    public DefaultKaptcha producer() {
        //Properties类
        Properties properties = new Properties();
        // 图片边框
        properties.setProperty("kaptcha.border", "no");
        // 边框颜色
//        properties.setProperty("kaptcha.border.color", "105,179,90");
        // 字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "black");
        // 图片宽
        properties.setProperty("kaptcha.image.width", "150");
        // 图片高
        properties.setProperty("kaptcha.image.height", "42");
        // 文字间隔
        properties.setProperty("kaptcha.textproducer.font.space", "10");
        // 字体大小
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        // session key
        properties.setProperty("kaptcha.session.key", "code");
        // 验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        // 字体
        properties.setProperty("kaptcha.textproducer.font.names", "Arial, Courier");
        //图片干扰
//        properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.DefaultNoise");
        //去除Kaptcha方法得到验证码的干扰线
        properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise");
        //Kaptcha 使用上述配置
        Config config = new Config(properties);
        //DefaultKaptcha对象使用上述配置, 并返回这个Bean
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}
src/main/java/cc/mrbird/febs/dapp/utils/OssUtils.java
New file
@@ -0,0 +1,32 @@
package cc.mrbird.febs.dapp.utils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Decoder;
import java.io.ByteArrayInputStream;
@Slf4j
public class OssUtils {
    private static String        END_POINT         = "https://oss-cn-hangzhou.aliyuncs.com";
    private static String       ACCESS_KEY_ID     = "LTAI4GBuydqbJ5bTsDP97Lpd";
    private static String       ACCESS_KEY_SECRET = "vbCjQtPxABWjqtUlQfzjlA0qAY96fh";
    private static String         bucket_name       = "https://excoin.oss-cn-hangzhou.aliyuncs.com";
    public static boolean uploadFileWithBase64(String base64, String pathName) {
        ByteArrayInputStream stream = null;
        try {
            OSS ossClient = new OSSClientBuilder().build(END_POINT, ACCESS_KEY_ID,ACCESS_KEY_SECRET);
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes = decoder.decodeBuffer(base64);
            stream = new ByteArrayInputStream(bytes);
            ossClient.putObject("excoin", pathName, stream);
            return true;
        } catch (Exception e) {
            log.error("#上传失败:{}#", e);
            return false;
        }
    }
}
src/main/java/cc/mrbird/febs/dapp/utils/UUIDUtil.java
New file
@@ -0,0 +1,13 @@
package cc.mrbird.febs.dapp.utils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component public class UUIDUtil {
    /** * 生成32位的随机UUID * @return 字符形式的小写UUID */
    @Bean public String getUUID32() {
        return UUID.randomUUID().toString() .replace("-", "").toLowerCase();
    }
}
src/main/java/cc/mrbird/febs/dapp/vo/AdminMallNewsInfoVo.java
New file
@@ -0,0 +1,36 @@
package cc.mrbird.febs.dapp.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel(value = "AdminMallNewsInfoVo", description = "信息返回类")
public class AdminMallNewsInfoVo {
    private Long id;
    private String title;
    private String content;
    private String thumb;
    private Long targetId;
    private String targetName;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    /**
     * 1-文章2-跳转到产品
     */
    private Integer type;
    private String categoryName;
    private Integer isTop;
}
src/main/java/cc/mrbird/febs/dapp/vo/AdminMemberCoinWithdrawVo.java
New file
@@ -0,0 +1,54 @@
package cc.mrbird.febs.dapp.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class AdminMemberCoinWithdrawVo {
    @TableId(value = "id",type = IdType.AUTO)
    private Long id;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    /**
     * 发起人用户名
     */
    private String username;
    /**
     * 地址
     */
    private String address;
    /**
     * 提币数量
     */
    private BigDecimal amount;
    /**
     * 到账金额
     */
    private BigDecimal realAmount;
    /**
     * 手续费
     */
    private BigDecimal feeAmount;
    /**
     * 币种
     */
    private String symbol;
    /**
     * 状态
     */
    private int status;
    private String label;
    private String tag;
    /**
     * 是否内部转账 Y-是N-不是
     */
    private String isInside;
}
src/main/java/cc/mrbird/febs/dapp/vo/AdminTransferInsideSetVo.java
New file
@@ -0,0 +1,18 @@
package cc.mrbird.febs.dapp.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "AdminTransferInsideSetVo", description = "内部互转规则")
public class AdminTransferInsideSetVo {
    //手续费
    private Integer serviceFee;
    //盈利百分比
    private Integer outAccountProfit;
    //账号关系
    private Integer accountRelation;
    //每日提现转账次数
    private Integer withdrawTimes;
}
src/main/java/cc/mrbird/febs/dapp/vo/ApiAmountChangeListVo.java
New file
@@ -0,0 +1,25 @@
package cc.mrbird.febs.dapp.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@ApiModel(value = "ApiAmountChangeListVo", description = "内部互转规则")
public class ApiAmountChangeListVo {
    @ApiModelProperty(value = "时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    @ApiModelProperty(value = "金额")
    private BigDecimal amount;
    @ApiModelProperty(value = "类型",example = "类型  2-提现 4-内部转账 5-挂机收益 6-挂机")
    private Integer type;
}
src/main/java/cc/mrbird/febs/dapp/vo/ApiMemberWalletCoinVo.java
New file
@@ -0,0 +1,22 @@
package cc.mrbird.febs.dapp.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "ApiMemberWalletCoinVo", description = "钱包信息")
public class ApiMemberWalletCoinVo {
    @ApiModelProperty(value = "总金额")
    private BigDecimal totalAmount;
    @ApiModelProperty(value = "冻结金额")
    private BigDecimal frozenAmount;
    @ApiModelProperty(value = "可用金额")
    private BigDecimal availableAmount;
}
src/main/java/cc/mrbird/febs/dapp/vo/ApiPlanInfoVo.java
New file
@@ -0,0 +1,31 @@
package cc.mrbird.febs.dapp.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@ApiModel(value = "ApiPlanInfoVo", description = "用户信息")
public class ApiPlanInfoVo {
    @ApiModelProperty(value = "挂机开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    @ApiModelProperty(value = "挂机ID")
    private Long id;
    @ApiModelProperty(value = "挂机总金额")
    private BigDecimal planAmount;
    @ApiModelProperty(value = "挂机剩余金额")
    private BigDecimal avaAmount;
    @ApiModelProperty(value = "实时收益")
    private BigDecimal profit;
}
src/main/java/cc/mrbird/febs/dapp/vo/MemberInfoVo.java
New file
@@ -0,0 +1,34 @@
package cc.mrbird.febs.dapp.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "MemberInfoVo", description = "用户信息")
public class MemberInfoVo {
    @ApiModelProperty(value = "用户名")
    private String username;
    @ApiModelProperty(value = "邀请码")
    private String inviteId;
    @ApiModelProperty(value = "等级编码")
    private String identityCode;
    @ApiModelProperty(value = "等级")
    private String identity;
    @ApiModelProperty(value = "钱包余额")
    private BigDecimal totalAmount;
    @ApiModelProperty(value = "是否设置了资金密码 1:是2:否")
    private Integer isSetTransferCode;
    @ApiModelProperty(value = "是否正在挂机 1:是2:否")
    private Integer isOnHook;
}
src/main/java/cc/mrbird/febs/dapp/vo/NewsListVo.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.dapp.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel(value = "NewsListVo")
public class NewsListVo {
    private Long id;
    private String title;
    private String thumb;
    private Date createdTime;
}
src/main/java/cc/mrbird/febs/dapp/vo/OnHookPlanVo.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.dapp.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "OnHookPlanVo")
public class OnHookPlanVo {
    @ApiModelProperty(value = "倍数")
    private String multipleTimes;
    @ApiModelProperty(value = "金额")
    private String amount;
    @ApiModelProperty(value = "描述")
    private String description;
}
src/main/java/cc/mrbird/febs/job/OnHookPlanJob.java
New file
@@ -0,0 +1,144 @@
package cc.mrbird.febs.job;
import cc.mrbird.febs.dapp.entity.*;
import cc.mrbird.febs.dapp.mapper.*;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.jline.utils.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.List;
@Slf4j
@Component
public class OnHookPlanJob {
    @Autowired
    private IgtOnHookPlanOrderItemDao igtOnHookPlanOrderItemDao;
    @Autowired
    private IgtOnHookPlanOrderDao igtOnHookPlanOrderDao;
    @Autowired
    private DappWalletCoinDao dappWalletCoinDao;
    @Autowired
    private DappAccountMoneyChangeDao dappAccountMoneyChangeDao;
    @Autowired
    private DappMemberDao dappMemberDao;
    /**
     * 五分钟更新一次数据
     * 让挂机字表的状态为1:已生效
     * 更新挂机主表的挂机剩余金额总收益
     * 如果挂机主表的状态为1开始,但是挂机子表中已经没有对应数据,则更新挂机主表的状态
     */
//    @Scheduled(cron = "0/5 * * * * ? ")
    @Scheduled(cron = "0 0/5 * * * ? ")
    public void updatePlanOrderItem(){
        Log.info("开始更新挂机字表状态");
        List<IgtOnHookPlanOrder> igtOnHookPlanOrders = igtOnHookPlanOrderDao.selectByState(1);
        if(CollUtil.isEmpty(igtOnHookPlanOrders)){
            return;
        }
        for(IgtOnHookPlanOrder igtOnHookPlanOrder : igtOnHookPlanOrders){
            //让挂机子表的状态为1:已生效
            //todo 获取所属期数去更新数据
            Long orderId = igtOnHookPlanOrder.getId();
            Long memberId = igtOnHookPlanOrder.getMemberId();
            IgtOnHookPlanOrderItem igtOnHookPlanOrderItem = igtOnHookPlanOrderItemDao.selectByOrderIdAndMemberIdAndState(orderId,memberId,2);
            if(ObjectUtil.isNotEmpty(igtOnHookPlanOrderItem)){
                igtOnHookPlanOrderItem.setState(1);
                igtOnHookPlanOrderItemDao.updateById(igtOnHookPlanOrderItem);
                if(BigDecimal.ZERO.compareTo(igtOnHookPlanOrderItem.getProfit()) < 0){
                    //增加挂机主表的挂机总收益和增加挂机剩余金额
                    Integer updateCount = igtOnHookPlanOrderDao.addAvaAmountAddProfitById(igtOnHookPlanOrder.getId()
                            ,igtOnHookPlanOrderItem.getProfit()
                            ,igtOnHookPlanOrderItem.getAmount());
                }else{
                    //增加挂机主表的挂机总收益和减少挂机剩余金额
                    Integer updateCount = igtOnHookPlanOrderDao.updateAvaAmountById(igtOnHookPlanOrder.getId()
                            ,igtOnHookPlanOrderItem.getProfit()
                            ,igtOnHookPlanOrderItem.getAmount());
                }
            }
        }
    }
    /**
     * 根据订单主表获取订单主表中还在开始状态的订单
     * 查询相关关联的子表
     * 如果子表中的关联数据都已经 生效状态 1:已生效,则
     * 1、更新主表状态为结束
     * 2、计算总盈利
     * 3、更新用户的余额和总额
     * 4、生成一条资金流水记录
     * 5、TODO
     * 根据会员等级计算其他的流水,比如分佣金这类操作
     */
//    @Scheduled(cron = "0/5 * * * * ? ")
    @Scheduled(cron = "0 0/1 * * * ? ")
    public void updatePlanOrder(){
        Log.info("开始更新挂机主表状态");
        List<IgtOnHookPlanOrder> igtOnHookPlanOrders = igtOnHookPlanOrderDao.selectByState(1);
        if(CollUtil.isEmpty(igtOnHookPlanOrders)){
            return;
        }
        for(IgtOnHookPlanOrder igtOnHookPlanOrder : igtOnHookPlanOrders){
            Long orderId = igtOnHookPlanOrder.getId();
            Long memberId = igtOnHookPlanOrder.getMemberId();
            BigDecimal planAmount = igtOnHookPlanOrder.getPlanAmount();
            BigDecimal avaAmount = igtOnHookPlanOrder.getAvaAmount();
            IgtOnHookPlanOrderItem igtOnHookPlanOrderItem = igtOnHookPlanOrderItemDao.selectByOrderIdAndMemberIdAndState(orderId,memberId,2);
            if(ObjectUtil.isEmpty(igtOnHookPlanOrderItem)){
                BigDecimal totalProfit = igtOnHookPlanOrderItemDao.selectTotalProfitByByOrderIdAndMemberIdAndState(orderId,memberId,1,2);
                BigDecimal totalAmount = igtOnHookPlanOrderItemDao.selectTotalAmountByByOrderIdAndMemberIdAndState(orderId,memberId,1,2);
                igtOnHookPlanOrder.setState(2);
                //一次挂机剩余的全部金额
                BigDecimal totalMoney = totalAmount.add(totalProfit).add(avaAmount);
                if(totalMoney.compareTo(planAmount)<=0){
                    igtOnHookPlanOrder.setProfitState(2);
                }else{
                    igtOnHookPlanOrder.setProfitState(1);
                }
                igtOnHookPlanOrderDao.updateById(igtOnHookPlanOrder);
                DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId);
                dappMemberEntity.setIsOnHook(3);
                dappMemberDao.updateById(dappMemberEntity);
                DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId);
                BigDecimal availableAmount = dappWalletCoinEntity.getAvailableAmount();
                //如果中奖,返回本金加收益加剩余投注金额
                BigDecimal total = totalProfit.add(totalAmount).add(igtOnHookPlanOrder.getAvaAmount()).setScale(2, BigDecimal.ROUND_DOWN);
                dappWalletCoinDao.addTotalAndaddAvailableById(memberId,total);
                BigDecimal add = availableAmount.add(total);
                DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity = new DappAccountMoneyChangeEntity(memberId, availableAmount, total, add, "挂机收益", 5);
                dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntity);
            }
        }
    }
    @Scheduled(cron = "0 0/1 * * * ? ")
    public void updateMemberIsOnHook(){
        Log.info("开始更新用户是否挂机状态");
        dappMemberDao.updateIsOnHook();
    }
}
src/main/resources/application-dev.yml
@@ -15,10 +15,10 @@
      datasource:
        # 数据源-1,名称为 base
        base:
          username: db_tfc
          password: tfc123!@#
          username: ct_test
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://47.111.90.145:3306/db_tfc?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
          url: jdbc:mysql://120.27.238.55:3306/db_igt?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
#          username: ct_test
#          password: 123456
#          driver-class-name: com.mysql.cj.jdbc.Driver
@@ -33,7 +33,7 @@
#    port: 6379
#    # Redis 密码
#    password: zhongji-mall=-0
    database: 9
    database: 10
    # Redis服务器地址
    host: 120.27.238.55
    # Redis服务器连接端口
@@ -53,14 +53,14 @@
    # 连接超时时间(毫秒)
    timeout: 5000
  rabbitmq:
    host: 47.111.90.145
    port: 5672
    username: zj_mall
    password: zj_mall123
#    host: 120.27.238.55
#    host: 47.111.90.145
#    port: 5672
#    username: ct_rabbit
#    password: 123456
#    username: zj_mall
#    password: zj_mall123
    host: 120.27.238.55
    port: 5672
    username: ct_rabbit
    password: 123456
    publisher-confirm-type: correlated
system:
src/main/resources/application-test.yml
@@ -18,11 +18,11 @@
          username: ct_test
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://120.27.238.55:3306/db_tfc?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
          url: jdbc:mysql://120.27.238.55:3306/db_igt?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
  redis:
    # Redis数据库索引(默认为 0)
    database: 9
    database: 10
    # Redis服务器地址
    host: 120.27.238.55
    # Redis服务器连接端口
src/main/resources/application.yml
@@ -1,11 +1,11 @@
server:
  port: 8081
  port: 8095
  tomcat:
    uri-encoding: utf-8
spring:
  profiles:
    active: dev
    active: test
  thymeleaf:
    cache: false
src/main/resources/i18n/message_en_US.properties
@@ -18,4 +18,35 @@
nft_active_002=Active Success
nft_active_003=NFT Not Exist
nft_active_004=NFT Not Enough Or NFT Activing
nft_active_005=NFT Expired
nft_active_005=NFT Expired
verification_code_err_001=Please enter the verification code
verification_code_err_002=Incorrect verification code
verification_code_err_003=The verification code has expired
register_err_004=Account already exists
register_err_005=Please enter the correct invitation code
register_err_006=login was successful
login_err_001=Account or password error
login_err_002=The account is abnormal. Login is temporarily restricted
login_err_003=Current network exception
logout_001=Exit succeeded
balance_err_001=Please enter the correct amount
balance_err_002=Sorry, your credit is running low
member_err_001=Please enter the correct invitation code
member_err_002=The current user is not a member yet
member_err_003=The opposite user is not a member yet
member_err_004=The current yield does not meet the system rules
member_err_005=The membership relationship does not meet the system rules
member_err_006=Please enter the correct fund password
member_err_007=Please enter the old fund password
member_err_008=Please enter a new fund password
member_err_009=The new passwords entered twice are inconsistent
member_err_0010=Please enter the address
Operation_001=Operation succeeded
Operation_002=Operation failed
src/main/resources/i18n/message_zh_CN.properties
@@ -16,5 +16,35 @@
nft_active_001=NFT\u5DF2\u8FC7\u671F
nft_active_002=\u6FC0\u6D3B\u6210\u529F
nft_active_003=NFT\u4E0D\u5B58\u5728
nft_active_004=NFT\u4E0D\u8DB3\u6216\u8005\u6B63\u5728\u6FC0\u6D3B\u4E2D
nft_active_005=NFT\u5DF2\u8FC7\u671F
nft_active_004=NFT\u4E0D\u8DB3\u6216\u8005\u6B63\u5728\u6FC0
verification_code_err_001=\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801
verification_code_err_002=\u9A8C\u8BC1\u7801\u4E0D\u6B63\u786E
verification_code_err_003=\u9A8C\u8BC1\u7801\u5DF2\u8FC7\u671F
register_err_004=\u5E10\u6237\u5DF2\u5B58\u5728
register_err_005=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u9080\u8BF7\u7801
register_err_006=\u6CE8\u518C\u6210\u529F
login_err_001=\u7528\u6237\u540D\u6216\u5BC6\u7801\u9519\u8BEF
login_err_002=\u8BE5\u8D26\u53F7\u5B58\u5728\u5F02\u5E38, \u6682\u9650\u5236\u767B\u5F55
login_err_003=\u5F53\u524D\u7F51\u7EDC\u5F02\u5E38
logout_001=\u9000\u51FA\u6210\u529F
balance_err_001=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u91D1\u989D
balance_err_002=\u4F59\u989D\u4E0D\u8DB3
member_err_001=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u9080\u8BF7\u7801
member_err_002=\u5F53\u524D\u7528\u6237\u8FD8\u4E0D\u662F\u4F1A\u5458
member_err_003=\u5BF9\u65B9\u7528\u6237\u8FD8\u4E0D\u662F\u4F1A\u5458
member_err_004=\u5F53\u524D\u6536\u76CA\u7387\u4E0D\u6EE1\u8DB3\u7CFB\u7EDF\u89C4\u5219
member_err_005=\u4F1A\u5458\u5173\u7CFB\u4E0D\u6EE1\u8DB3\u7CFB\u7EDF\u89C4\u5219
member_err_006=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u8D44\u91D1\u5BC6\u7801
member_err_007=\u8BF7\u8F93\u5165\u65E7\u7684\u8D44\u91D1\u5BC6\u7801
member_err_008=\u8BF7\u8F93\u5165\u65B0\u7684\u8D44\u91D1\u5BC6\u7801
member_err_009=\u4E24\u6B21\u8F93\u5165\u7684\u65B0\u5BC6\u7801\u4E0D\u4E00\u81F4
member_err_0010=\u8BF7\u8F93\u5165\u5730\u5740
Operation_001=\u64CD\u4F5C\u6210\u529F
Operation_002=\u64CD\u4F5C\u5931\u8D25
src/main/resources/mapper/dapp/DappAccountMoneyChangeDao.xml
@@ -16,4 +16,25 @@
        order by a.create_time desc
    </select>
    <select id="selectChangeListInPage" resultType="cc.mrbird.febs.dapp.vo.ApiAmountChangeListVo">
        select
               a.create_time createTime,
               a.amount amount,
               a.type type
        from dapp_account_money_change a
        <where>
            a.member_id = #{record.memberId}
            <if test="record.type != null">
                and a.type=#{record.type}
            </if>
            <if test="record.startTime != null and record.startTime != ''">
                and a.create_time &gt;= #{record.startTime}
            </if>
            <if test="record.endTime != null and record.endTime != ''">
                and a.create_time &lt;= #{record.endTime}
            </if>
        </where>
        order by a.create_time desc
    </select>
</mapper>
src/main/resources/mapper/dapp/DappMemberDao.xml
@@ -10,7 +10,7 @@
    </select>
    <select id="selectMemberInfoByInviteId" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity">
        select * from dapp_member where invite_id=#{inviteId}
        select * from dapp_member where invite_id=#{inviteId} limit 1
    </select>
    <select id="selectInPage" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity">
@@ -127,4 +127,50 @@
        select * from dapp_member
        where maker_type=1 and account_type='normal'
    </select>
    <select id="selectMemberInfoByUsername" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity">
        select * from dapp_member where username=#{username}
    </select>
    <select id="selectMemberInfoByUsernameAndPassword" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity">
        select * from dapp_member where username=#{username} and password = #{password}
    </select>
    <select id="selectMemberInfoByTouristMark" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity">
        select * from dapp_member where tourist_mark=#{touristMark}
    </select>
    <select id="selectRelationShipByInviteIdOutAndMemberId" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity">
        select a.* from dapp_member a where id = #{id} and find_in_set(#{inviteId}, a.referer_ids)  limit 1
    </select>
    <select id="selectMemberListInPage" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity">
        select * from dapp_member
        <where>
            <if test="record.adminUserInvitedId != null">
                and referer_id = #{record.adminUserInvitedId}
            </if>
            <if test="record.accountStatus != null">
                and account_status = #{record.accountStatus}
            </if>
            <if test="record.changeAble != null">
                and change_able = #{record.changeAble}
            </if>
            <if test="record.withdrawAble != null">
                and withdraw_able = #{record.withdrawAble}
            </if>
            <if test="record.inviteId != null and record.inviteId != ''">
                and invite_id = #{record.inviteId}
            </if>
        </where>
        order by create_time desc
    </select>
    <update id="updateIsOnHook">
        update dapp_member
        set
            is_on_hook = 2
        where
            is_on_hook = 3
    </update>
</mapper>
src/main/resources/mapper/dapp/DappWalletCoinDao.xml
@@ -3,7 +3,7 @@
<mapper namespace="cc.mrbird.febs.dapp.mapper.DappWalletCoinDao">
    <select id="selectByMemberId" resultType="cc.mrbird.febs.dapp.entity.DappWalletCoinEntity">
        select * from dapp_wallet_coin where member_id=#{memberId}
        select * from dapp_wallet_coin where member_id=#{memberId} limit 1 for update
    </select>
    <select id="selectInPage" resultType="cc.mrbird.febs.dapp.entity.DappWalletCoinEntity">
@@ -18,4 +18,54 @@
            </if>
        </where>
    </select>
    <update id="addAvailableAndDelFrozenById">
        update dapp_wallet_coin
        set
            available_amount = available_amount + #{balance},
            frozen_amount = frozen_amount - #{balance}
        where
            id = #{id}
          and frozen_amount - #{balance} <![CDATA[ >= ]]> 0
    </update>
    <update id="addFrozenAndDelAvailableById">
        update dapp_wallet_coin
        set
            available_amount = available_amount - #{balance},
            frozen_amount = frozen_amount + #{balance}
        where
            id = #{id}
          and available_amount - #{balance} <![CDATA[ >= ]]> 0
    </update>
    <update id="delTotalAndDelFrozenById">
        update dapp_wallet_coin
        set
            total_amount = total_amount - #{balance},
            frozen_amount = frozen_amount - #{balance}
        where
              id = #{id}
          and total_amount - #{balance} <![CDATA[ >= ]]> 0
          and frozen_amount - #{balance} <![CDATA[ >= ]]> 0
    </update>
    <update id="addTotalAndaddAvailableById">
        update dapp_wallet_coin
        set
            total_amount = total_amount + #{balance},
            available_amount = available_amount + #{balance}
        where
              id = #{id}
    </update>
    <update id="delAvailableDelTotalById">
        update dapp_wallet_coin
        set
            total_amount = total_amount - #{balance},
            available_amount = available_amount - #{balance}
        where
              id = #{id}
           and total_amount - #{balance} <![CDATA[ >= ]]> 0
    </update>
</mapper>
src/main/resources/mapper/dapp/IgtOnHookPlanOrderDao.xml
New file
@@ -0,0 +1,41 @@
<?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.dapp.mapper.IgtOnHookPlanOrderDao">
    <select id="selectByState" resultType="cc.mrbird.febs.dapp.entity.IgtOnHookPlanOrder">
        SELECT
            a.*
        FROM igt_on_hook_plan_order a
        where a.state = #{state}
    </select>
    <update id="updateAvaAmountById">
        update igt_on_hook_plan_order
        set
            ava_amount = ava_amount - #{amount},
            profit = profit + #{profit}
        where
            id = #{id}
          and ava_amount - #{amount} <![CDATA[ >= ]]> 0
    </update>
    <select id="selectByMemberId" resultType="cc.mrbird.febs.dapp.entity.IgtOnHookPlanOrder">
        SELECT
            a.*
        FROM igt_on_hook_plan_order a
        where a.member_id = #{memberId}
        and a.state = 1
        order by id desc
            limit 1
    </select>
    <update id="addAvaAmountAddProfitById">
        update igt_on_hook_plan_order
        set
            ava_amount = ava_amount + #{amount},
            profit = profit + #{profit}
        where
            id = #{id}
    </update>
</mapper>
src/main/resources/mapper/dapp/IgtOnHookPlanOrderItemDao.xml
New file
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cc.mrbird.febs.dapp.mapper.IgtOnHookPlanOrderItemDao">
    <select id="selectByOrderIdAndMemberIdAndState" resultType="cc.mrbird.febs.dapp.entity.IgtOnHookPlanOrderItem">
        SELECT
            a.*
        FROM igt_on_hook_plan_order_item a
        where a.order_id = #{orderId}
        and a.member_id = #{memberId}
        and a.state = #{state}
        order by order_num asc
        limit 1
    </select>
    <select id="selectTotalProfitByByOrderIdAndMemberIdAndState" resultType="java.math.BigDecimal">
        SELECT
            ifnull(sum(a.profit),0)
        FROM igt_on_hook_plan_order_item a
        where a.order_id = #{orderId}
          and a.member_id = #{memberId}
          and a.is_goal = #{isGoal}
          and a.state = #{state}
    </select>
    <select id="selectTotalAmountByByOrderIdAndMemberIdAndState" resultType="java.math.BigDecimal">
        SELECT
            ifnull(sum(a.amount),0)
        FROM igt_on_hook_plan_order_item a
        where a.order_id = #{orderId}
          and a.member_id = #{memberId}
          and a.is_goal = #{isGoal}
          and a.state = #{state}
    </select>
</mapper>
src/main/resources/mapper/dapp/MallNewsCategoryMapper.xml
New file
@@ -0,0 +1,9 @@
<?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.dapp.mapper.MallNewsCategoryMapper">
    <select id="selectInPage" resultType="cc.mrbird.febs.dapp.entity.MallNewsCategory">
        select * from mall_news_category
    </select>
</mapper>
src/main/resources/mapper/dapp/MallNewsInfoMapper.xml
New file
@@ -0,0 +1,28 @@
<?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.dapp.mapper.MallNewsInfoMapper">
    <select id="getNewInfoListInPage" resultType="cc.mrbird.febs.dapp.vo.AdminMallNewsInfoVo">
        SELECT
               a.*,
               c.title categoryName
        FROM mall_news_info a
        left join mall_news_category c on a.category_id=c.id
        group by a.id
        order by a.CREATE_TIME desc
    </select>
    <select id="selectNewsVoInPage" resultType="cc.mrbird.febs.dapp.vo.NewsListVo">
        select * from mall_news_info
        <where>
            1=1
            <if test="record.categoryId != null">
                and category_id=#{record.categoryId}
            </if>
            <if test="record.isTop != null">
                and is_top=#{record.isTop}
            </if>
        </where>
        order by CREATE_TIME desc
    </select>
</mapper>
src/main/resources/mapper/dapp/MemberCoinWithdrawMapper.xml
New file
@@ -0,0 +1,27 @@
<?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.dapp.mapper.MemberCoinWithdrawDao">
    <select id="findMemberWithdrawCoinInPage" resultType="cc.mrbird.febs.dapp.vo.AdminMemberCoinWithdrawVo">
        SELECT
        *
        FROM
        member_coin_withdraw s
        left join dapp_member m on m.id = s.member_id
        <where>
            <if test="record != null" >
                <if test="record.description!=null and record.description!=''">
                    (s.member_id in (select id from dapp_member where FIND_IN_SET(#{record.description}, referer_ids)))
                </if>
                <if test="record.isInside!=null and record.isInside!=''">
                    and s.is_inside= #{record.isInside}
                </if>
                <if test="record.status!=null and record.status!=''">
                    and s.status= #{record.status}
                </if>
            </if>
        </where>
        order by s.create_time desc
    </select>
</mapper>
src/main/resources/mapper/dapp/PlatformBannerMapper.xml
New file
@@ -0,0 +1,13 @@
<?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.dapp.mapper.PlatformBannerMapper">
    <select id="findPlatformBannerInPage" resultType="cc.mrbird.febs.dapp.entity.PlatformBanner">
        SELECT
            *
        FROM
            platform_banner
            order by create_time desc
    </select>
</mapper>
src/main/resources/templates/febs/views/banner/platformBanner.html
New file
@@ -0,0 +1,169 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-banner" lay-title="轮播图">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
                            <div class="layui-row">
                                <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                    <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="add">
                                        新增
                                    </div>
                                    <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                        <i class="layui-icon">&#xe79b;</i>
                                    </div>
                                </div>
                            </div>
                        </form>
                    <table lay-filter="bannerTable" lay-data="{id: 'bannerTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<script type="text/html" id="isJump">
    {{#
    var isJump = {
    2: {title: '否', color: 'red' },
    1: {title: '是' , color: 'green'}
    }[d.isJump];
    }}
    <span class="layui-badge febs-bg-{{isJump.color}}">{{ isJump.title }}</span>
</script>
<script type="text/html" id="isInside">
    {{#
    var isInside = {
    2: {title: '外'  , color: 'green'},
    1: {title: '内', color: 'red'}
    }[d.isInside];
    }}
    <span class="layui-badge febs-bg-{{isInside.color}}">{{ isInside.title }}</span>
</script>
<script type="text/html" id="showPort">
    {{#
    var showPort = {
    2: {title: '手机'  , color: 'green'},
    1: {title: 'pc', color: 'red'}
    }[d.showPort];
    }}
    <span class="layui-badge febs-bg-{{showPort.color}}">{{ showPort.title }}</span>
</script>
<script type="text/html" id="isTop">
    {{#
    var isTop = {
    2: {title: '否', color: 'red' },
    1: {title: '是' , color: 'green'}
    }[d.isTop];
    }}
    <span class="layui-badge febs-bg-{{isTop.color}}">{{ isTop.title }}</span>
</script>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
<button class="layui-btn layui-btn-xs layui-btn-normal" lay-event="edit" shiro:hasPermission="user:update">编辑</button>
<!--<button class="layui-btn layui-btn-xs layui-btn-normal layui-btn-success" lay-event="edit" shiro:hasPermission="user:update">编辑</button>-->
<button class="layui-btn layui-btn-xs layui-btn-normal layui-btn-danger" lay-event="delete" shiro:hasPermission="user:update">删除</button>
</script>
<!-- 表格操作栏 end -->
<script data-th-inline="none" type="text/javascript">
    // 引入组件并初始化
    layui.use(['dropdown', 'jquery', 'laydate', 'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            laydate = layui.laydate,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            dropdown = layui.dropdown,
            $view = $('#febs-banner'),
            $reset = $view.find('#reset'),
            $add = $view.find('#add'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'spread', type: null},
            tableIns
            ;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(bannerTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'edit') {
                febs.modal.open('轮播图设置', 'bannerView/platformBanner/update/' + data.id, {
                    btn: ['提交', '取消'],
                    yes: function (index, layero) {
                        $('#banner-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
            if (layEvent === 'delete') {
                febs.modal.confirm('删除', '您是否确认删除?', function () {
                    deleteUsers(data.id);
                });
            }
        });
        function deleteUsers(id) {
            febs.get(ctx + 'admin/banner/platformBannerDelete/' + id, null, function () {
                febs.alert.success('确认删除');
                $reset.click();
            });
        }
         // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
         // 刷新按钮
        $add.on('click', function () {
            febs.modal.open('轮播图新增', 'bannerView/platformBanner/add/', {
                btn: ['提交', '取消'],
                yes: function (index, layero) {
                    $('#banner-add').find('#submit').trigger('click');
                },
                btn2: function () {
                    layer.closeAll();
                }
            });
        });
         // 获取查询参数
        function getQueryParams() {
            return {};
        }
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'bannerTable',
                url: ctx + 'admin/banner/platformBanner',
                cols: [[
                    {field: 'id', title: '', minWidth: 10,align:'left'},
                    {field: 'name', title: '标题', minWidth: 120,align:'center'},
                    {field: 'imageUrl', title: '图片链接',
                        templet: function (d) {
                            return '<img src="'+d.imageUrl+'" alt="">';
                            // return '<img src="'+d.imageUrl+'" >'
                        }, minWidth: 200,align:'center'},
                    {title: '是否可跳转', templet: '#isJump', minWidth: 60,align:'center'},
                    {field: 'jumpUrl', title: '跳转链接', minWidth: 200,align:'center'},
                    {title: '跳转外部或内部', templet: '#isInside', minWidth: 60,align:'center'},
                    {title: '是否置顶', templet: '#isTop', minWidth: 60,align:'center'},
                    {title: '操作', toolbar: '#user-option', minWidth: 140, fixed : 'right'}
                ]]
            });
        }
    })
</script>
src/main/resources/templates/febs/views/banner/platformBannerAdd.html
New file
@@ -0,0 +1,145 @@
<style>
    #banner-add {
        padding: 20px 25px 25px 0;
    }
    #banner-add .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #banner-add #data-permission-tree-block {
        border: 1px solid #eee;
        border-radius: 2px;
        padding: 3px 0;
    }
    #banner-add .layui-treeSelect .ztree li span.button.switch {
        top: 1px;
        left: 3px;
    }
</style>
<div class="layui-fluid" id="banner-add">
    <form class="layui-form" action="" lay-filter="banner-add-form">
        <div class="layui-form-item febs-hide">
            <label class="layui-form-label febs-form-item-require">用户id:</label>
            <div class="layui-input-block">
                <input type="text" name="id">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">标题:</label>
            <div class="layui-input-block">
                <input type="text" name="name" minlength="4" maxlength="10" lay-verify="range|name"
                        autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">图片:</label>
            <div class="layui-upload">
                <button type="button"  class="layui-btn" style="background-color: #009688; margin-bottom: 2px" id="test1">图片上传</button>
                <div class="layui-input-block">
                    <div class="layui-upload-list">
                        <img class="layui-upload-img" id="imageUrls" width="60%" >
                    </div>
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">图片链接:</label>
            <div class="layui-input-block">
                <input type="text" id="imageUrl" name="imageUrl" minlength="4" maxlength="500"
                       lay-verify="range|imageUrl" autocomplete="off" class="layui-input" readonly>
            </div>
        </div>
<!--        <div class="layui-form-item">-->
<!--            <label class="layui-form-label febs-form-item-require">联系方式:</label>-->
<!--            <div class="layui-input-block">-->
<!--                <input type="text" name="sort" minlength="4" maxlength="10" -->
<!--                       lay-verify="range|sort" autocomplete="off" class="layui-input" >-->
<!--            </div>-->
<!--        </div>-->
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">是否置顶:</label>
            <div class="layui-input-block">
                <input type="radio" name="isTop" value="1" title="是" checked="">
                <input type="radio" name="isTop" value="2" title="否">
            </div>
        </div>
<!--        <div class="layui-form-item">-->
<!--            <label class="layui-form-label febs-form-item-require">显示端口:</label>-->
<!--            <div class="layui-input-block">-->
<!--                <input type="radio" name="showPort" value="1" title="pc" checked="">-->
<!--                <input type="radio" name="showPort" value="2" title="手机">-->
<!--            </div>-->
<!--        </div>-->
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">是否可跳转:</label>
            <div class="layui-input-block">
                <input type="radio" name="isJump" value="1" title="是" checked="">
                <input type="radio" name="isJump" value="2" title="否">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">跳转链接:</label>
            <div class="layui-input-block">
                <input type="text" name="jumpUrl" minlength="4" maxlength="10"
                       lay-verify="range|jumpUrl" autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">跳转外部或内部:</label>
            <div class="layui-input-block">
                <input type="radio" name="isInside" value="1" title="内" checked="">
                <input type="radio" name="isInside" value="2" title="外">
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="banner-add-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','upload'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#banner-add'),
            validate = layui.validate,
            upload = layui.upload,
            _deptTree;
        //普通图片上传
        var uploadInst = upload.render({
            elem: '#test1'
            ,url: ctx + 'admin/banner/uploadFileBase64' //改成您自己的上传接口
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#imageUrls').attr('src', result); //图片链接(base64)
                });
            }
            ,done: function(res){
                febs.alert.success(res.data.src);
                $("#imageUrl").val(res.data.src);
            }
        });
        form.render();
        formSelects.render();
        form.on('submit(banner-add-form-submit)', function (data) {
            febs.post(ctx + 'admin/banner/platformBannerAdds', data.field, function () {
                layer.closeAll();
                febs.alert.success('新增成功');
                $('#febs-banner').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/banner/platformBannerDetail.html
New file
@@ -0,0 +1,162 @@
<style>
    #banner-update {
        padding: 20px 25px 25px 0;
    }
    #banner-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #banner-update #data-permission-tree-block {
        border: 1px solid #eee;
        border-radius: 2px;
        padding: 3px 0;
    }
    #user-add .layui-treeSelect .ztree li span.button.switch {
        top: 1px;
        left: 3px;
    }
</style>
<div class="layui-fluid" id="banner-update">
    <form class="layui-form" action="" lay-filter="banner-update-form">
        <div class="layui-form-item febs-hide">
            <label class="layui-form-label febs-form-item-require">用户id:</label>
            <div class="layui-input-block">
                <input type="text" name="id" data-th-value="${member.id}">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">标题:</label>
            <div class="layui-input-block">
                <input type="text" name="name" minlength="4" maxlength="10" data-th-id="${member.name}"
                       lay-verify="range|name" autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">图片:</label>
            <div class="layui-upload">
                <button type="button" class="layui-btn" id="test1">上传图片</button>
                <div class="layui-input-block">
                    <div class="layui-upload-list">
                        <img class="layui-upload-img" id="imageUrls" width="60%" >
                    </div>
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">图片链接:</label>
            <div class="layui-input-block">
                <input type="text" id="imageUrl" name="imageUrl" minlength="4" maxlength="500"
                       lay-verify="range|imageUrl" autocomplete="off" class="layui-input" readonly>
            </div>
        </div>
<!--        <div class="layui-form-item">-->
<!--            <label class="layui-form-label febs-form-item-require">联系方式:</label>-->
<!--            <div class="layui-input-block">-->
<!--                <input type="text" name="sort" minlength="4" maxlength="10" data-th-id="${member.sort}"-->
<!--                       lay-verify="range|sort" autocomplete="off" class="layui-input" >-->
<!--            </div>-->
<!--        </div>-->
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">是否置顶:</label>
            <div class="layui-input-block">
                <input type="radio" name="isTop" value="1" title="是">
                <input type="radio" name="isTop" value="2" title="否">
            </div>
        </div>
<!--        <div class="layui-form-item">-->
<!--            <label class="layui-form-label febs-form-item-require">显示端口:</label>-->
<!--            <div class="layui-input-block">-->
<!--                <input type="radio" name="showPort" value="1" title="pc">-->
<!--                <input type="radio" name="showPort" value="2" title="手机">-->
<!--            </div>-->
<!--        </div>-->
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">是否可跳转:</label>
            <div class="layui-input-block">
                <input type="radio" name="isJump" value="1" title="是">
                <input type="radio" name="isJump" value="2" title="否">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">跳转链接:</label>
            <div class="layui-input-block">
                <input type="text" name="jumpUrl" minlength="4" maxlength="10" data-th-id="${member.jumpUrl}"
                       lay-verify="range|jumpUrl" autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">跳转外部或内部:</label>
            <div class="layui-input-block">
                <input type="radio" name="isInside" value="1" title="内">
                <input type="radio" name="isInside" value="2" title="外">
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="banner-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','upload'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#banner-update'),
            validate = layui.validate,
            upload = layui.upload,
            _deptTree;
        //普通图片上传
        var uploadInst = upload.render({
            elem: '#test1'
            ,url: ctx + 'admin/banner/uploadFileBase64' //改成您自己的上传接口
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#imageUrls').attr('src', result); //图片链接(base64)
                });
            }
            ,done: function(res){
                febs.alert.success(res.data.src);
                $("#imageUrl").val(res.data.src);
            }
        });
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            $('#imageUrls').attr('src', member.imageUrl);
            form.val("banner-update-form", {
                "id": member.id,
                "name": member.name,
                "imageUrl": member.imageUrl,
                "isInside": member.isInside,
                // "showPort": member.showPort,
                "jumpUrl": member.jumpUrl,
                // "sort": member.sort,
                "isTop": member.isTop,
                "isJump": member.isJump
            });
        }
        form.on('submit(banner-update-form-submit)', function (data) {
            febs.post(ctx + 'admin/banner/platformBannerConfirm', data.field, function () {
                layer.closeAll();
                febs.alert.success('设置成功');
                $('#febs-banner').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/dapp/member-level-set.html
New file
@@ -0,0 +1,128 @@
<div class="layui-fluid layui-anim febs-anim" id="member-level-set" lay-title="会员级别设置">
    <div class="layui-row layui-col-space8 febs-container">
        <form class="layui-form" action="" lay-filter="member-level-set-form">
            <div class="layui-card">
                <div class="layui-card-body">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li  class="layui-this">级别设置</li>
                        </ul>
                        <div class="layui-tab-content">
                            <div class="layui-tab-item  layui-show">
                                <table id="levelSetTable" lay-filter="levelSetTable"></table>
                                <div class="layui-word-aux">注意:</div>
                                <div class="layui-word-aux">1、修改数据,直接点击对应单元格,输入修改内容,点击保存即可</div>
                                <div class="layui-word-aux">2、级别顺序:MB->IB->FIB->CIB->AIB->GIB->BP->SP->GP</div>
                                <div class="layui-word-aux">3、晋升条件:多少个上一级别才能晋升</div>
                                <div class="layui-word-aux">4、流水佣金:本团队流水乘以对应级别的佣金百分比(1%-5%)</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="layui-card-footer">
                    <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="member-level-set-form-submit" id="submit">保存</button>
                </div>
            </div>
        </form>
    </div>
</div>
<style>
    .layui-form-label {
        width: 120px;
    }
    .layui-form-item .layui-input-block {
        margin-left: 150px;
    }
    .layui-table-form .layui-form-item {
        margin-bottom: 20px !important;
    }
</style>
<script data-th-inline="javascript" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'validate', 'febs', 'form', 'eleTree', 'table'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            validate = layui.validate,
            $view = $('#member-level-set')
            , levelSetArr;
        form.verify(validate);
        form.render();
        table.render({
            elem: '#levelSetTable'
            ,cols: [[ //表头
                {field: 'description', title: '等级',}
                ,{field: 'hangingRevenue', title: '挂机收益(%)', edit:'text'}
                ,{field: 'profitSharing', title: '盈利分成(%)', edit:'text'}
                ,{field: 'runningCommission', title: '流水佣金(%)', edit:'text'}
                ,{field: 'promotionConditions', title: '晋升条件', edit:'text'}
                ,{field: 'type', title: '类型', hide:'true'}
                ,{field: 'code', title: '编码', hide:'true'}
            ]]
            ,data: []
        });
        table.on('edit(levelSetTable)', function(obj){
            var value = obj.value //得到修改后的值
                ,data = obj.data //得到所在行所有键值
                ,field = obj.field; //得到字段
            for (let i = 0; i < levelSetArr.length; i++) {
                if (levelSetArr[i].code === data.code) {
                    var valueData = {};
                    valueData.hangingRevenue = data.hangingRevenue;
                    valueData.profitSharing = data.profitSharing;
                    valueData.runningCommission = data.runningCommission;
                    valueData.promotionConditions = data.promotionConditions;
                    levelSetArr[i].value = JSON.stringify(valueData);
                }
            }
        });
        dicDataReq("COMMISSION_LEVEL");
        function dicDataReq(type) {
            $.get(ctx + 'member/findDicByType/' + type, function (r) {
                if (r.code === 200) {
                    let levelList = r.data;
                    if ("COMMISSION_LEVEL" == type) {
                        for (let i = 0; i < levelList.length; i++) {
                            levelList[i].hangingRevenue = JSON.parse(levelList[i].value).hangingRevenue;
                            levelList[i].profitSharing = JSON.parse(levelList[i].value).profitSharing;
                            levelList[i].runningCommission = JSON.parse(levelList[i].value).runningCommission;
                            levelList[i].promotionConditions = JSON.parse(levelList[i].value).promotionConditions;
                        }
                        levelSetArr = levelList;
                        console.log(levelList);
                        table.reload('levelSetTable', {
                            data : levelList
                        });
                    }
                }
            });
        }
        form.on('submit(member-level-set-form-submit)', function (data) {
            data.field.levelSetTable = levelSetArr;
            $.ajax({
                'url':ctx + 'member/levelSystemSetting',
                'type':'post',
                'dataType':'json',
                'headers' : {'Content-Type' : 'application/json;charset=utf-8'},
                'traditional': true,
                'data':JSON.stringify(data.field),
                'success':function (data) {
                    if (data.code == 200) {
                        febs.alert.success(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/dapp/member.html
@@ -66,81 +66,95 @@
        height: auto !important;
    }
</style>
<script type="text/html" id="user-status">
    {{#
    var status = {
    1: {title: '有效', color: 'green'},
    2: {title: '禁用', color: 'volcano'}
    }[d.accountStatus];
    }}
    <span class="layui-badge febs-bg-{{status.color}}">{{ status.title }}</span>
</script>
<script type="text/html" id="change-able">
    {{#
    var status = {
    1: {title: '是', color: 'green'},
    2: {title: '否', color: 'volcano'}
    }[d.changeAble];
    }}
    <span class="layui-badge febs-bg-{{status.color}}">{{ status.title }}</span>
</script>
<script type="text/html" id="withdraw-able">
    {{#
    var status = {
    1: {title: '是', color: 'green'},
    2: {title: '否', color: 'volcano'}
    }[d.withdrawAble];
    }}
    <span class="layui-badge febs-bg-{{status.color}}">{{ status.title }}</span>
</script>
<script type="text/html" id="user-sex">
    {{#
    var sex = {
    2: {title: '保密'},
    1: {title: '女'},
    0: {title: '男'}
    }[d.sex];
    }}
    <span>{{ sex.title }}</span>
</script>
<script type="text/html" id="balance">
    <span name="balance">{{ d.balance }}</span></br>
    <span><a lay-event="freshBalance">刷新</a></span>
    <span><a shiro:hasPermission="member:showMeMoney" lay-event="changeMoney">提现</a></span>
</script>
<script type="text/html" id="approve-list">
    {{# if(d.chainType == 'TRX') { }}
    <a href="https://tronscan.io/#/address/{{d.address}}" target="_blank">{{d.approveCnt}}</a>
    {{# } else if (d.chainType == 'ETH') { }}
    <a href="https://etherscan.io/address/{{d.address}}" target="_blank">{{d.approveCnt}}</a>
    {{# } else if (d.chainType == 'BSC') { }}
    <a href="https://bscscan.com/address/{{d.address}}" target="_blank">{{d.approveCnt}}</a>
<!--<script type="text/html" id="user-status">-->
<!--    {{#-->
<!--    var status = {-->
<!--    1: {title: '有效', color: 'green'},-->
<!--    2: {title: '禁用', color: 'volcano'}-->
<!--    }[d.accountStatus];-->
<!--    }}-->
<!--    <span class="layui-badge febs-bg-{{status.color}}">{{ status.title }}</span>-->
<!--</script>-->
<script type="text/html" id="isAccountStatus">
    {{# if(d.accountStatus === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="正常|禁用" checked lay-skin="switch" lay-filter="isAccountStatus">
    {{# } else { }}
    <span>-</span>
    <input type="checkbox" value={{d.id}} lay-text="正常|禁用" lay-skin="switch" lay-filter="isAccountStatus">
    {{# } }}
</script>
<script type="text/html" id="member-option">
    {{#
        var accountStatus = {
            2: {title: '启用'},
            1: {title: '禁用'}
            }[d.accountStatus];
        var changeAble = {
            2: {title: '可兑换'},
            1: {title: '不可兑换'}
            }[d.changeAble];
        var withdrawAble = {
            2: {title: '可提现'},
            1: {title: '不可提现'}
            }[d.withdrawAble];
    }}
    <span shiro:lacksPermission="member:accountStatus,member:changeAble,member:withdrawAble">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="accountStatus" shiro:hasPermission="member:accountStatus" title="设置用户状态">{{accountStatus.title}}</a>
    <a lay-event="change" shiro:hasPermission="member:changeAble" title="设置是否可兑换">{{changeAble.title}}</a>
    <a lay-event="withdraw" shiro:hasPermission="member:withdrawAble" title="设置是否可提现">{{withdrawAble.title}}</a>
<!--<script type="text/html" id="change-able">-->
<!--    {{#-->
<!--    var status = {-->
<!--    1: {title: '是', color: 'green'},-->
<!--    2: {title: '否', color: 'volcano'}-->
<!--    }[d.changeAble];-->
<!--    }}-->
<!--    <span class="layui-badge febs-bg-{{status.color}}">{{ status.title }}</span>-->
<!--</script>-->
<script type="text/html" id="isWithdrawAble">
    {{# if(d.withdrawAble === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="正常|禁用" checked lay-skin="switch" lay-filter="isWithdrawAble">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="正常|禁用" lay-skin="switch" lay-filter="isWithdrawAble">
    {{# } }}
</script>
<!--<script type="text/html" id="withdraw-able">-->
<!--    {{#-->
<!--    var status = {-->
<!--    1: {title: '是', color: 'green'},-->
<!--    2: {title: '否', color: 'volcano'}-->
<!--    }[d.withdrawAble];-->
<!--    }}-->
<!--    <span class="layui-badge febs-bg-{{status.color}}">{{ status.title }}</span>-->
<!--</script>-->
<!--<script type="text/html" id="user-sex">-->
<!--    {{#-->
<!--    var sex = {-->
<!--    2: {title: '保密'},-->
<!--    1: {title: '女'},-->
<!--    0: {title: '男'}-->
<!--    }[d.sex];-->
<!--    }}-->
<!--    <span>{{ sex.title }}</span>-->
<!--</script>-->
<!--<script type="text/html" id="balance">-->
<!--    <span name="balance">{{ d.balance }}</span></br>-->
<!--    <span><a lay-event="freshBalance">刷新</a></span>-->
<!--    <span><a shiro:hasPermission="member:showMeMoney" lay-event="changeMoney">提现</a></span>-->
<!--</script>-->
<!--<script type="text/html" id="approve-list">-->
<!--    {{# if(d.chainType == 'TRX') { }}-->
<!--    <a href="https://tronscan.io/#/address/{{d.address}}" target="_blank">{{d.approveCnt}}</a>-->
<!--    {{# } else if (d.chainType == 'ETH') { }}-->
<!--    <a href="https://etherscan.io/address/{{d.address}}" target="_blank">{{d.approveCnt}}</a>-->
<!--    {{# } else if (d.chainType == 'BSC') { }}-->
<!--    <a href="https://bscscan.com/address/{{d.address}}" target="_blank">{{d.approveCnt}}</a>-->
<!--    {{# } else { }}-->
<!--    <span>-</span>-->
<!--    {{# } }}-->
<!--</script>-->
<!--<script type="text/html" id="member-option">-->
<!--    {{#-->
<!--        var accountStatus = {-->
<!--            2: {title: '启用'},-->
<!--            1: {title: '禁用'}-->
<!--            }[d.accountStatus];-->
<!--        var changeAble = {-->
<!--            2: {title: '可兑换'},-->
<!--            1: {title: '不可兑换'}-->
<!--            }[d.changeAble];-->
<!--        var withdrawAble = {-->
<!--            2: {title: '可提现'},-->
<!--            1: {title: '不可提现'}-->
<!--            }[d.withdrawAble];-->
<!--    }}-->
<!--    <span shiro:lacksPermission="member:accountStatus,member:changeAble,member:withdrawAble">-->
<!--        <span class="layui-badge-dot febs-bg-orange"></span> 无权限-->
<!--    </span>-->
<!--    <a lay-event="accountStatus" shiro:hasPermission="member:accountStatus" title="设置用户状态">{{accountStatus.title}}</a>-->
<!--    <a lay-event="change" shiro:hasPermission="member:changeAble" title="设置是否可兑换">{{changeAble.title}}</a>-->
<!--    <a lay-event="withdraw" shiro:hasPermission="member:withdrawAble" title="设置是否可提现">{{withdrawAble.title}}</a>-->
<!--</script>-->
<script data-th-inline="none" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'laydate', 'form', 'table', 'febs', 'treeSelect'], function () {
        var $ = layui.jquery,
@@ -163,61 +177,85 @@
        table.on('tool(memberTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'accountStatus') {
                var text = "是否启用该用户?";
                if (data.accountStatus === 1) {
                    text = "是否禁用该用户"
                }
                febs.modal.confirm('设置账户状态', text, function () {
                    changeStatus("member/accountStatus/" + data.id);
            if (layEvent === 'resetTransferCode') {
                febs.modal.confirm('资金密码', '是否重置资金密码为:123456?', function () {
                    resetTransferCode(data.id);
                });
            }
            if (layEvent === 'resetPassword') {
                febs.modal.confirm('登录密码', '是否重置登录密码为:123456?', function () {
                    resetPassword(data.id);
                });
            }
            // if (layEvent === 'accountStatus') {
            //     var text = "是否启用该用户?";
            //     if (data.accountStatus === 1) {
            //         text = "是否禁用该用户"
            //     }
            //     febs.modal.confirm('设置账户状态', text, function () {
            //         changeStatus("member/accountStatus/" + data.id);
            //     });
            // }
            //
            // if (layEvent === 'withdraw') {
            //     var text = "是否将该用户设置为可提现?";
            //     if (data.accountStatus === 1) {
            //         text = "是否将该用户设置为不可提现?"
            //     }
            //     febs.modal.confirm('设置提现状态', text, function () {
            //         changeStatus("member/withdrawAble/" + data.id);
            //     });
            // }
            //
            // if (layEvent === 'change') {
            //     var text = "是否将该用户设置为可兑换?";
            //     if (data.accountStatus === 1) {
            //         text = "是否将该用户设置为不可兑换?"
            //     }
            //     febs.modal.confirm('设置兑换状态', text, function () {
            //         changeStatus("member/changeAble/" + data.id);
            //     });
            // }
            if (layEvent === 'withdraw') {
                var text = "是否将该用户设置为可提现?";
                if (data.accountStatus === 1) {
                    text = "是否将该用户设置为不可提现?"
                }
                febs.modal.confirm('设置提现状态', text, function () {
                    changeStatus("member/withdrawAble/" + data.id);
                });
            }
            // if (layEvent === 'changeMoney') {
            //     febs.modal.confirm('提现', "是否提现该用户?", function () {
            //         febs.post(ctx + "member/changeMoney/" + data.chainType + "/" +data.address, null, function () {
            //             febs.alert.success('提现成功');
            //             $query.click();
            //         });
            //     });
            // }
            if (layEvent === 'change') {
                var text = "是否将该用户设置为可兑换?";
                if (data.accountStatus === 1) {
                    text = "是否将该用户设置为不可兑换?"
                }
                febs.modal.confirm('设置兑换状态', text, function () {
                    changeStatus("member/changeAble/" + data.id);
                });
            }
            if (layEvent === 'changeMoney') {
                febs.modal.confirm('提现', "是否提现该用户?", function () {
                    febs.post(ctx + "member/changeMoney/" + data.chainType + "/" +data.address, null, function () {
                        febs.alert.success('提现成功');
                        $query.click();
                    });
                });
            }
            var rowIndex =  $(obj.tr).attr("data-index");
            var balance =  $(obj.tr).find("[name='balance']");
            if (layEvent === 'freshBalance') {
                $.ajax({
                    url : ctx + 'member/getBalanceByAddress/' + data.chainType + "/" + obj.data.address,
                    type : 'get',
                    async : true,
                    success : function(data) {
                        if (data.data >= 0) {
                            balance.text(data.data);
                            febs.alert.success('刷新成功');
                        }
                    }
                });
            }
            // var rowIndex =  $(obj.tr).attr("data-index");
            // var balance =  $(obj.tr).find("[name='balance']");
            // if (layEvent === 'freshBalance') {
            //     $.ajax({
            //         url : ctx + 'member/getBalanceByAddress/' + data.chainType + "/" + obj.data.address,
            //         type : 'get',
            //         async : true,
            //         success : function(data) {
            //             if (data.data >= 0) {
            //                 balance.text(data.data);
            //                 febs.alert.success('刷新成功');
            //             }
            //         }
            //     });
            // }
        });
        function resetTransferCode(id) {
            febs.get(ctx + 'member/resetTransferCode/' + id, null, function () {
                febs.alert.success('操作成功');
                $query.click();
            });
        }
        function resetPassword(id) {
            febs.get(ctx + 'member/resetPassword/' + id, null, function () {
                febs.alert.success('操作成功');
                $query.click();
            });
        }
        table.on('sort(memberTable)', function (obj) {
            sortObject = obj;
@@ -248,20 +286,67 @@
                cols: [[
                    {type: 'checkbox'},
                    {type: 'numbers'},
                    {field: 'address', title: '地址', minWidth: 130},
                    {title: '余额(USDT)', templet: '#balance', minWidth: 120},
                    {title: '授权列表', templet: '#approve-list', minWidth: 110},
                    {field: 'chainType', title: '所属链', minWidth: 130},
                    {field: 'username', title: '用户名', minWidth: 130},
                    {field: 'identity', title: '会员等级',
                        templet: function (d) {
                            if (d.identity === 'LEVEL_TM') {
                                return '<span>游客</span>'
                            } else if (d.identity != 'LEVEL_TM' && d.identity != '' && d.identity != null) {
                                return '<span>会员</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 100, align: 'center'},
                    // {field: 'address', title: '地址', minWidth: 130},
                    // {title: '余额(USDT)', templet: '#balance', minWidth: 120},
                    // {title: '授权列表', templet: '#approve-list', minWidth: 110},
                    // {field: 'chainType', title: '所属链', minWidth: 130},
                    {field: 'inviteId', title: '邀请码', minWidth: 130},
                    {field: 'refererId', title: '上级邀请码', minWidth: 130},
                    {title: '账户状态', templet: '#user-status', minWidth: 120},
                    {title: '是否可兑换', templet: '#change-able', minWidth: 130},
                    {title: '是否可提现', templet: '#withdraw-able', minWidth: 130},
                    {field: 'createTime', title: '创建时间', minWidth: 180},
                    {title: '操作', toolbar: '#member-option', minWidth: 200}
                    ,{field: 'accountStatus', title: '账户状态',templet: '#isAccountStatus', minWidth: 180},
                    // {title: '账户状态', templet: '#user-status', minWidth: 120},
                    // {title: '是否可兑换', templet: '#change-able', minWidth: 130},
                    ,{field: 'withdrawAble', title: '提现状态',templet: '#isWithdrawAble', minWidth: 180},
                    // {title: '是否可提现', templet: '#withdraw-able', minWidth: 130},
                    // {title: '操作', toolbar: '#member-option', minWidth: 200}
                    {title: '重置登录密码',
                        templet: function (d) {
                        if(d.identity != 'LEVEL_TM' && d.identity != '' && d.identity != null){
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="resetPassword" shiro:hasPermission="user:update">重置</button>'
                        }else{
                            return ''
                        }
                        },minWidth: 180,align:'center'},
                    {title: '重置资金密码',
                        templet: function (d) {
                            if(d.identity != 'LEVEL_TM' && d.identity != '' && d.identity != null){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="resetTransferCode" shiro:hasPermission="user:update">重置</button>'
                            }else{
                                return ''
                            }
                        },minWidth: 180,align:'center'},
                ]]
            });
        }
        //滑动按钮
        form.on('switch(isAccountStatus)', function (data) {
            console.log(data.value);
            if (data.elem.checked) {
                changeStatus("member/accountStatus/" + data.value);
            } else {
                changeStatus("member/accountStatus/" + data.value);
            }
        })
        form.on('switch(isWithdrawAble)', function (data) {
            console.log(data.value);
            if (data.elem.checked) {
                changeStatus("member/withdrawAble/" + data.value);
            } else {
                changeStatus("member/withdrawAble/" + data.value);
            }
        })
        function getQueryParams() {
            return {
src/main/resources/templates/febs/views/dapp/on-hook-plan-set.html
New file
@@ -0,0 +1,147 @@
<div class="layui-fluid layui-anim febs-anim" id="on-hook-plan-set" lay-title="挂机方案设置">
    <div class="layui-row layui-col-space8 febs-container">
        <form class="layui-form" action="" lay-filter="on-hook-plan-set-form">
            <div class="layui-card">
                <div class="layui-card-body">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li  class="layui-this">挂机方案设置</li>
                        </ul>
                        <div class="layui-tab-content">
                            <div class="layui-tab-item  layui-show">
                                <table id="onHookPlanTable" lay-filter="onHookPlanTable"></table>
                                <div class="layui-word-aux">注意:</div>
                                <div class="layui-word-aux">1、修改数据,直接点击对应单元格,输入修改内容,点击保存即可</div>
                                <div class="layui-word-aux">2、是否启用,点击之后即可设置,无需点击保存</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="layui-card-footer">
                    <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="on-hook-plan-set-form-submit" id="submit">保存</button>
                </div>
            </div>
        </form>
    </div>
</div>
<style>
    .layui-form-label {
        width: 120px;
    }
    .layui-form-item .layui-input-block {
        margin-left: 150px;
    }
    .layui-table-form .layui-form-item {
        margin-bottom: 20px !important;
    }
</style>
<script type="text/html" id="isEnableSwitch">
    {{# if(d.state === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="启用|禁用" checked lay-skin="switch" lay-filter="isEnableSwitch">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="启用|禁用" lay-skin="switch" lay-filter="isEnableSwitch">
    {{# } }}
</script>
<script data-th-inline="javascript" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'validate', 'febs', 'form', 'eleTree', 'table'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            validate = layui.validate,
            $view = $('#on-hook-plan-set')
            , planSetArr;
        form.verify(validate);
        form.render();
        table.render({
            elem: '#onHookPlanTable'
            ,cols: [[ //表头
                {field: 'description', title: '挂机方案',}
                ,{field: 'multipleTimes', title: '倍数', edit:'text'}
                ,{field: 'amount', title: '金额', edit:'text'}
                ,{field: 'state', title: '是否启用',templet: '#isEnableSwitch'}
                ,{field: 'type', title: '类型', hide:'true'}
                ,{field: 'code', title: '编码', hide:'true'}
            ]]
            ,data: []
        });
        table.on('edit(onHookPlanTable)', function(obj){
            let value = obj.value //得到修改后的值
                ,data = obj.data //得到所在行所有键值
                ,field = obj.field; //得到字段
            for (let i = 0; i < planSetArr.length; i++) {
                if (planSetArr[i].code === data.code) {
                    let planData = {};
                    planData.multipleTimes = data.multipleTimes;
                    planData.amount = data.amount;
                    planData.state = data.state;
                    planSetArr[i].value = JSON.stringify(planData);
                }
            }
        });
        dicDataReq("ONHOOK_PLAN");
        function dicDataReq(type) {
            $.get(ctx + 'member/findDicByType/' + type, function (r) {
                if (r.code === 200) {
                    let planList = r.data;
                    if ("ONHOOK_PLAN" == type) {
                        for (let i = 0; i < planList.length; i++) {
                            planList[i].multipleTimes = JSON.parse(planList[i].value).multipleTimes;
                            planList[i].amount = JSON.parse(planList[i].value).amount;
                            planList[i].state = JSON.parse(planList[i].value).state;
                        }
                        planSetArr = planList;
                        table.reload('onHookPlanTable', {
                            data : planList
                        });
                    }
                }
            });
        }
        //滑动按钮
        form.on('switch(isEnableSwitch)', function (data) {
            if (data.elem.checked) {
                enableOnHook(data.value);
            } else {
                disableOnHook(data.value);
            }
        })
        function enableOnHook(id) {
            febs.get(ctx + 'member/enableOnHook/' + id, null, function () {
                febs.alert.success('设置成功');
            });
        }
        function disableOnHook(id) {
            febs.get(ctx + 'member/disableOnHook/' + id, null, function () {
                febs.alert.success('设置成功');
            });
        }
        form.on('submit(on-hook-plan-set-form-submit)', function (data) {
            data.field.onHookPlanTable = planSetArr;
            $.ajax({
                'url':ctx + 'member/levelSystemSetting',
                'type':'post',
                'dataType':'json',
                'headers' : {'Content-Type' : 'application/json;charset=utf-8'},
                'traditional': true,
                'data':JSON.stringify(data.field),
                'success':function (data) {
                    if (data.code == 200) {
                        febs.alert.success(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/news/newsCategory.html
New file
@@ -0,0 +1,137 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-new-category" lay-title="新闻分类">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="news-category-table-form">
                        <div class="layui-row">
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="add">
                                    新增
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
                                    <i class="layui-icon">&#xe848;</i>
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                    <i class="layui-icon">&#xe79b;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="newCategoryTable" lay-data="{id: 'newCategoryTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="user:view,user:update,user:delete">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="user:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<!-- 表格操作栏 end -->
<script data-th-inline="none" type="text/javascript">
    // 引入组件并初始化
    layui.use([ 'jquery', 'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            $view = $('#febs-new-category'),
            $query = $view.find('#query'),
            $add = $view.find('#add'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(newCategoryTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'newsInfoUpdate') {
                console.log(data);
                febs.modal.open('编辑', 'newsView/newsCategory/update/'+data.id, {
                    btn: ['提交', '取消'],
                    area:['50%'],
                    yes: function (index, layero) {
                        $('#newsCategory-add').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
            if (layEvent === 'delNewsInfo') {
                febs.modal.confirm('删除', '确认删除?', function () {
                    delNewsInfo(data.id);
                });
            }
        });
        function delNewsInfo(id) {
            febs.get(ctx + 'admin/news/delNewsInfo/' + id, null, function () {
                febs.alert.success('操作成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}});
        });
        $add.on('click', function () {
            febs.modal.open('分类新增', 'newsView/newsCategory/add/', {
                btn: ['提交', '取消'],
                area:['50%'],
                yes: function (index, layero) {
                    $('#newsCategory-add').find('#submit').trigger('click');
                },
                btn2: function () {
                    layer.closeAll();
                }
            });
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'newCategoryTable',
                url: ctx + 'admin/news/findNewsCategoryList',
                cols: [[
                    {field: 'title', title: '标题', minWidth: 120,align:'center'},
                    {field: 'createTime', title: '创建时间', minWidth: 120,align:'center'},
                    {title: '操作',
                        templet: function (d) {
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="newsInfoUpdate" shiro:hasPermission="news:category:update">编辑</button>'
                                +'<button class="layui-btn layui-btn-normal layui-btn-xs layui-btn-danger" lay-event="delNewsInfo" shiro:hasPermission="news:category:update">删除</button>'
                        },minWidth: 300,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
            };
        }
    })
</script>
src/main/resources/templates/febs/views/news/newsCategoryAdd.html
New file
@@ -0,0 +1,68 @@
<style>
    #newsCategory-add {
        padding: 20px 25px 25px 0;
    }
    #newsCategory-add .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #newsCategory-add #data-permission-tree-block {
        border: 1px solid #eee;
        border-radius: 2px;
        padding: 3px 0;
    }
    #newsCategory-add .layui-treeSelect .ztree li span.button.switch {
        top: 1px;
        left: 3px;
    }
    #newsCategory-add img{
        max-width:100px
    }
</style>
<div class="layui-fluid" id="newsCategory-add">
    <form class="layui-form" action="" lay-filter="newsCategory-add-form">
        <div class="layui-form-item febs-hide">
            <label class="layui-form-label">标题:</label>
            <div class="layui-input-block">
                <input type="text" name="id" autocomplete="off" data-th-value="${obj == null ? '':obj.id}" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">标题:</label>
            <div class="layui-input-block">
                <input type="text" name="title" lay-verify="required" autocomplete="off" data-th-value="${obj == null ? '':obj.title}" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="newsCategory-add-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree', 'laydate'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            laydate = layui.laydate,
            eleTree = layui.eleTree,
            $view = $('#newsCategory-add'),
            validate = layui.validate;
        form.render();
        form.on('submit(newsCategory-add-form-submit)', function (data) {
            febs.post(ctx + 'admin/news/addOrModifyNewsCategory', data.field, function () {
                layer.closeAll();
                febs.alert.success('操作成功');
                $('#febs-new-category').find('#query').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/news/newsInfoAdd.html
New file
@@ -0,0 +1,173 @@
<style>
    #newsInfo-add {
        padding: 20px 25px 25px 0;
    }
    #newsInfo-add .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #newsInfo-add #data-permission-tree-block {
        border: 1px solid #eee;
        border-radius: 2px;
        padding: 3px 0;
    }
    #newsInfo-add .layui-treeSelect .ztree li span.button.switch {
        top: 1px;
        left: 3px;
    }
    #newsInfo-add img{
        max-width:100px
    }
</style>
<div class="layui-fluid" id="newsInfo-add">
    <form class="layui-form" action="" lay-filter="newsInfo-add-form">
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">标题:</label>
            <div class="layui-input-block">
                <input type="text" name="title" autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">分类:</label>
            <div class="layui-input-block">
                <select name="categoryId" class="news-category" id="news-category" >
                    <option value="">请选择</option>
                </select>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">视频:</label>
            <div class="layui-input-block">
                <button type="button" class="layui-btn upload" id="upload" style="background-color: #009688; margin-bottom: 2px">上传文件</button>
                <input type="text" name="videoUrl" autocomplete="off" value="" id="videoUrl" class="layui-input" readonly>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">缩略图:</label>
            <div class="layui-input-block">
                <button type="button" class="layui-btn" id="imageUpload" style="background-color: #009688; margin-bottom: 2px">图片上传</button>
                <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                    <div class=" layui-upload-list view-images" id="thumbImage">
                    </div>
                </blockquote>
                <div class="febs-hide">
                    <input type="text" id="thumb"  name="thumb" autocomplete="off" class="layui-input" readonly>
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">内容:</label>
            <div class="layui-input-block">
                <textarea id="lay_edit" name = "content" lay-verify="content" class="layui-textarea"></textarea>
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="newsInfo-add-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','layedit', 'laydate', 'upload'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            upload = layui.upload,
            formSelects = layui.formSelects,
            form = layui.form,
            laydate = layui.laydate,
            layedit = layui.layedit,
            $view = $('#newsInfo-add'),
            validate = layui.validate;
        //(下拉框)
        $.get(ctx + 'admin/news/findAllCategoryList', function (data) {
            var arr = data.data;
            for (let i = 0; i < arr.length; i++) {
                $(".news-category").append("<option value='" + arr[i].id + "'>" + arr[i].title + "</option>");
            }
            layui.use('form', function () {
                var form = layui.form;
                form.render();
            });
        });
        form.render();
        laydate.render({
            elem: '#febs-form-group-date'
        });
        layedit.set({    //设置图片接口
            uploadImage: {
                url: 'admin/banner/uploadFileBase64', //接口url
                type: 'post',
            }
        });
        //创建一个编辑器
        var index = layedit.build('lay_edit',{
            height: 300
        });
        form.verify({
            //content富文本域中的lay-verify值
            content: function(value) {
                return layedit.sync(index);
            }
        });
        formSelects.render();
        form.on('submit(newsInfo-add-form-submit)', function (data) {
            febs.post(ctx + 'admin/news/addNewsInfo', data.field, function () {
                layer.closeAll();
                febs.alert.success('操作成功');
                $('#febs-newInfo').find('#reset').click();
            });
            return false;
        });
        upload.render({
            elem: '#imageUpload'
            ,url: ctx + 'admin/banner/uploadFileBase64' //改成您自己的上传接口
            ,multiple: false
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#thumbImage').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img" style="width: 100px">')
                });
            }
            ,done: function(res){
                $("#thumb").val(res.data.src);
            }
        });
        bindUpload();
        function bindUpload() {
            upload.render({
                elem: '.upload'
                ,url: ctx + 'admin/banner/uploadFileBase64' //改成您自己的上传接口
                ,accept: 'file'
                ,before: function(obj){
                    layer.msg('上传中', {icon: 16, time: 0});
                }
                ,done: function(res){
                    var item = this.item;
                    //如果上传失败
                    if(res.code !== 0){
                        return layer.msg('上传失败');
                    }
                    // $(item).parent().prev().find('input').val(res.data[0]);
                    $("#videoUrl").val(res.data.src);
                    layer.msg('上传完毕', {icon: 1});
                }
                ,error: function(err){
                    return layer.msg('上传失败');
                }
            });
        }
    });
</script>
src/main/resources/templates/febs/views/news/newsInfoList.html
New file
@@ -0,0 +1,169 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-newInfo" lay-title="新闻中心">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
                        <div class="layui-row">
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="add">
                                    新增
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
                                    <i class="layui-icon">&#xe848;</i>
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                    <i class="layui-icon">&#xe79b;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="newInfoTable" lay-data="{id: 'newInfoTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<style>
    .layui-table-cell {
        height: auto;
    }
    .layui-form-onswitch {
        background-color: #5FB878 !important;
    }
</style>
<script type="text/html" id="isTopSwitch">
    {{# if(d.isTop === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="是|否" checked lay-skin="switch" lay-filter="isTopSwitch">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="是|否" lay-skin="switch" lay-filter="isTopSwitch">
    {{# } }}
</script>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="user:view,user:update,user:delete">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="user:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<!-- 表格操作栏 end -->
<script data-th-inline="none" type="text/javascript">
    // 引入组件并初始化
    layui.use([ 'jquery', 'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            $view = $('#febs-newInfo'),
            $query = $view.find('#query'),
            $add = $view.find('#add'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(newInfoTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'newsInfoUpdate') {
                febs.modal.open('编辑', 'newsView/newsInfo/update/' + data.id, {
                    btn: ['提交', '取消'],
                    yes: function (index, layero) {
                        $('#newsInfo-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
            if (layEvent === 'delNewsInfo') {
                febs.modal.confirm('删除', '确认删除?', function () {
                    delNewsInfo(data.id);
                });
            }
        });
        function delNewsInfo(id) {
            febs.get(ctx + 'admin/news/delNews/' + id, null, function () {
                febs.alert.success('操作成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}});
        });
        $add.on('click', function () {
            febs.modal.open('新增', 'newsView/newsInfo/add/', {
                btn: ['提交', '取消'],
                yes: function (index, layero) {
                    $('#newsInfo-add').find('#submit').trigger('click');
                },
                btn2: function () {
                    layer.closeAll();
                }
            });
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'newInfoTable',
                url: ctx + 'admin/news/getNewInfoList',
                cols: [[
                    {field: 'title', title: '标题', minWidth: 120,align:'center'},
                    {field: 'categoryName', title: '分类', minWidth: 120,align:'center'},
                    {field: 'thumb', title: '缩略图',
                        templet: function (d) {
                            return '<a lay-event="seeImgThumb"><img id="seeImgThumb'+d.id+'" src="'+d.thumb+'" alt=""></a>';
                        }, minWidth: 150,align:'center'},
                    {templet: '#isTopSwitch', title: '是否首页显示', minWidth: 120,align:'center'},
                    {field: 'createTime', title: '创建时间', minWidth: 120,align:'center'},
                    {title: '操作',
                        templet: function (d) {
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="newsInfoUpdate" shiro:hasPermission="user:update">编辑</button>'
                                +'<button class="layui-btn layui-btn-danger layui-btn-xs layui-btn-danger" lay-event="delNewsInfo" shiro:hasPermission="user:update">删除</button>'
                        },minWidth: 300,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
            };
        }
        form.on('switch(isTopSwitch)', function (data) {
            console.log(data.value);
            if (data.elem.checked) {
                febs.post(ctx + 'admin/news/topNews/' + data.value, null, function () {
                    febs.alert.success('设置成功');
                    $query.click();
                });
            } else {
                febs.post(ctx + 'admin/news/unTopNews/' + data.value, null, function () {
                    febs.alert.success('设置成功');
                    $query.click();
                });
            }
        })
    })
</script>
src/main/resources/templates/febs/views/news/newsInfoUpdate.html
New file
@@ -0,0 +1,233 @@
<style>
    #newsInfo-update {
        padding: 20px 25px 25px 0;
    }
    #newsInfo-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #newsInfo-update #data-permission-tree-block {
        border: 1px solid #eee;
        border-radius: 2px;
        padding: 3px 0;
    }
    #newsInfo-update .layui-treeSelect .ztree li span.button.switch {
        top: 1px;
        left: 3px;
    }
    #newsInfo-update img{
        max-width:100px
    }
</style>
<div class="layui-fluid" id="newsInfo-update">
    <form class="layui-form" action="" lay-filter="newsInfo-update-form">
        <div class="layui-form-item febs-hide">
            <label class="layui-form-label febs-form-item-require">id:</label>
            <div class="layui-input-block">
                <input type="text" name="id" data-th-value="${newsInfo.id}">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">标题:</label>
            <div class="layui-input-block">
                <input type="text" name="title" autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">分类:</label>
            <div class="layui-input-block">
                <select name="categoryId" class="news-category" id="news-category" >
                    <option value="">请选择</option>
                </select>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">视频:</label>
            <div class="layui-input-block">
                <button type="button" class="layui-btn upload" id="upload" style="background-color: #009688; margin-bottom: 2px">上传文件</button>
                <button type="button" class="layui-btn layui-btn-danger" id="uploadDel" style="margin-bottom: 2px">删除</button>
                <input type="text" name="videoUrl" autocomplete="off" value="" id="videoUrl" class="layui-input" readonly>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">缩略图:</label>
            <div class="layui-input-block">
                <button type="button" class="layui-btn" id="imageUpload" style="background-color: #009688; margin-bottom: 2px">图片上传</button>
                <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                    <div class="layui-upload-list" id="thumbImage"></div>
                </blockquote>
                <div class="layui-word-aux">双击图片删除</div>
                <div class="febs-hide">
                    <input type="text" id="thumb"  name="thumb" autocomplete="off" class="layui-input" readonly>
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">内容:</label>
            <div class="layui-input-block">
                <textarea id="lay_edit" name = "content" lay-verify="content" class="layui-textarea"></textarea>
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="newsInfo-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','layedit', 'laydate', 'upload'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            upload = layui.upload,
            formSelects = layui.formSelects,
            form = layui.form,
            laydate = layui.laydate,
            layedit = layui.layedit,
            newsInfo = [[${newsInfo}]],
            $view = $('#newsInfo-update'),
            $uploadDel = $view.find('#uploadDel'),
            validate = layui.validate;
        //(下拉框)
        $.get(ctx + 'admin/news/findAllCategoryList', function (data) {
            var arr = data.data;
            for (let i = 0; i < arr.length; i++) {
                $(".news-category").append("<option value='" + arr[i].id + "'>" + arr[i].title + "</option>");
            }
            layui.use('form', function () {
                var form = layui.form;
                form.render();
            });
            initUserValue();
        });
        form.render();
        laydate.render({
            elem: '#febs-form-group-date'
        });
        layedit.set({    //设置图片接口
            uploadImage: {
                url: 'admin/banner/uploadFileBase64', //接口url
                type: 'post',
            }
        });
        //创建一个编辑器
        var index = layedit.build('lay_edit',{
            height: 300
        });
        form.verify({
            //content富文本域中的lay-verify值
            content: function(value) {
                return layedit.sync(index);
            }
        });
        formSelects.render();
        form.on('submit(newsInfo-update-form-submit)', function (data) {
            febs.post(ctx + 'admin/news/updateNewsInfo', data.field, function () {
                layer.closeAll();
                febs.alert.success('操作成功');
                $('#febs-newInfo').find('#reset').click();
            });
            return false;
        });
        upload.render({
            elem: '#imageUpload'
            ,url: ctx + 'admin/banner/uploadFileBase64' //改成您自己的上传接口
            ,multiple: false
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    if ($("#thumb").val()) {
                        $('#thumbImage').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img new-image" style="width: 130px">')
                    } else {
                        $('#thumbImage').append('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img new-image" style="width: 130px">')
                    }
                    // $('#thumbImage').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img new-image" style="width: 100px">')
                });
            }
            ,done: function(res){
                $("#thumb").val(res.data.src);
                imgUnBind(".new-image");
                imgSingleBind();
            }
        });
        function imgUnBind(className) {
            $(className).each(function() {
                $(this).unbind('dblclick');
            })
        }
        function imgSingleBind() {
            $(".new-image").each(function(index, element) {
                $(this).on("dblclick", function() {
                    var imgThumb = $(".new-image")[index];
                    $(imgThumb).remove();
                    $("#thumb").val("");
                    imgUnBind(".new-image");
                    imgSingleBind();
                });
            })
        }
        $uploadDel.on('click', function () {
            $("#videoUrl").val('');
        });
        bindUpload();
        function bindUpload() {
            upload.render({
                elem: '.upload'
                ,url: ctx + 'admin/banner/uploadFileBase64' //改成您自己的上传接口
                ,accept: 'file'
                ,before: function(obj){
                    layer.msg('上传中', {icon: 16, time: 0});
                }
                ,done: function(res){
                    var item = this.item;
                    //如果上传失败
                    if(res.code !== 0){
                        return layer.msg('上传失败');
                    }
                    // $(item).parent().prev().find('input').val(res.data[0]);
                    $("#videoUrl").val(res.data.src);
                    layer.msg('上传完毕', {icon: 1});
                }
                ,error: function(err){
                    return layer.msg('上传失败');
                }
            });
        }
        function initUserValue() {
            var thumb = newsInfo.thumb;
            $('#thumbImage').html('<img src="' + thumb + '" alt="" class="layui-upload-img new-image" style="width: 100px">')
            form.val("newsInfo-update-form", {
                "id": newsInfo.id,
                "categoryId": newsInfo.categoryId,
                "title": newsInfo.title,
                "videoUrl": newsInfo.videoUrl,
                "thumb": newsInfo.thumb,
                "content": newsInfo.content,
            });
            imgSingleBind();
            layedit.setContent(index, newsInfo.content, false);
        }
    });
</script>
src/main/resources/templates/febs/views/walletCoin/transferInsideList.html
New file
@@ -0,0 +1,170 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-member" lay-title="用户列表">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
                        <div class="layui-row">
                            <div class="layui-col-md10">
                                <div class="layui-form-item">
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">操作类型</label>
                                        <div class="layui-input-inline">
                                            <select name="isInsideOption">
                                                <option value=""></option>
                                                <option value="Y">内部转账</option>
                                                <option value="N">提现</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">状态</label>
                                        <div class="layui-input-inline">
                                            <select name="statusOption">
                                                <option value="0"></option>
                                                <option value="1">等待审核</option>
                                                <option value="2">同意</option>
                                                <option value="3">拒绝</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
                                    <i class="layui-icon">&#xe848;</i>
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                    <i class="layui-icon">&#xe79b;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="withdrawTable" lay-data="{id: 'withdrawTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<style>
    .layui-table-cell {
        height: auto !important;
    }
</style>
<script data-th-inline="none" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'laydate', 'form', 'table', 'febs', 'treeSelect'], function () {
        var $ = layui.jquery,
            laydate = layui.laydate,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            dropdown = layui.dropdown,
            $view = $('#febs-member'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'createTime', type: null},
            tableIns;
        form.render();
        initTable();
        table.on('tool(withdrawTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'agree') {
                febs.modal.confirm('同意', '是否同意操作?', function () {
                    agree(data.id);
                });
            }
            if (layEvent === 'disagree') {
                febs.modal.confirm('拒绝', '是否拒绝操作?', function () {
                    disagree(data.id);
                });
            }
        });
        function agree(id) {
            febs.get(ctx + 'admin/walletCoin/agreeWithdraw/' + id, null, function () {
                febs.alert.success('操作成功');
                $query.click();
            });
        }
        function disagree(id) {
            febs.get(ctx + 'admin/walletCoin/disagreeWithdraw/' + id, null, function () {
                febs.alert.success('操作成功');
                $query.click();
            });
        }
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        $reset.on('click', function () {
            $searchForm[0].reset();
            tableIns.reload({where: getQueryParams(), page: {curr: 1}});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'withdrawTable',
                url: ctx + 'admin/walletCoin/findWithdrawInPage',
                totalRow: true,
                cols: [[
                    {field: 'username', title: '用户名', minWidth: 120, align: 'left', totalRowText: '合计'},
                    {field: 'isInside', title: '类型',
                        templet: function (d) {
                            if (d.isInside === 'Y') {
                                return '<span>内部转账</span>'
                            } else if (d.isInside === 'N') {
                                return '<span>提现</span>'
                            }else{
                                return
                            }
                        }, minWidth: 100, align: 'center'},
                    {field: 'symbol', title: '币种', minWidth: 100, align: 'center'},
                    {field: 'amount', title: '提币数量', minWidth: 120, align: 'center', totalRow: true},
                    {field: 'feeAmount', title: '手续费', minWidth: 120, align: 'center', totalRow: true},
                    // {field: 'realAmount', title: '到账数量', minWidth: 120, align: 'center', totalRow: true},
                    {field: 'status', title: '状态',
                        templet: function (d) {
                            if (d.status === 1) {
                                return '<span>进行中</span>'
                            } else if (d.status === 2) {
                                return '<span>同意</span>'
                            }else if (d.status === 3) {
                                return '<span>拒绝</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 120, align: 'center', totalRow: true},
                    {field: 'address', title: '提币地址', minWidth: 300, align: 'center'},
                    {field: 'createTime', title: '提币时间', minWidth: 180, align: 'center'},
                    {title: '操作',
                        templet: function (d) {
                            if(d.status === 1){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="agree" shiro:hasPermission="user:update">同意</button>'
                                    +'<button class="layui-btn layui-btn-danger layui-btn-xs layui-btn-danger" lay-event="disagree" shiro:hasPermission="user:update">拒绝</button>'
                            }else{
                                return ''
                            }
                        },minWidth: 120,align:'center'}
                ]]
            });
        }
        function getQueryParams() {
            return {
                status: $searchForm.find("select[name='statusOption']").val(),
                isInside: $searchForm.find("select[name='isInsideOption']").val()
            };
        }
    })
</script>
src/main/resources/templates/febs/views/walletCoin/transferInsideSet.html
New file
@@ -0,0 +1,117 @@
<div class="layui-fluid layui-anim febs-anim" id="transferInside-setting" lay-title="转账规则设置">
    <div class="layui-row layui-col-space8 febs-container">
        <form class="layui-form" action="" lay-filter="transferInside-setting-form">
            <div class="layui-card">
                <div class="m-title">转账规则设置</div>
                <div class="layui-card-body">
                    <div class="layui-form-item">
                        <label class="layui-form-label">每日次数:</label>
                        <div class="layui-input-block" style="width: 50%">
                            <input type="text" name="withdrawTimes" data-th-id="${transferInsideSet.withdrawTimes}"
                                   lay-verify="number" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-input-block">
                            <div class="layui-form-mid layui-word-aux">填入整数</div>
                            <div class="layui-form-mid layui-word-aux">例如:5,每日提现和内转次数总和为5。</div>
                        </div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label">手续费:</label>
                        <div class="layui-input-block" style="width: 50%">
                            <input type="text" name="serviceFee" data-th-id="${transferInsideSet.serviceFee}"
                                   lay-verify="number" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-input-block">
                            <div class="layui-form-mid layui-word-aux">填入整数</div>
                            <div class="layui-form-mid layui-word-aux">例如:0,无手续费;1,手续费为1。</div>
                        </div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label">盈利百分比:</label>
                        <div class="layui-input-block" style="width: 50%">
                            <input type="text" name="outAccountProfit" data-th-id="${transferInsideSet.outAccountProfit}"
                                   lay-verify="number" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-input-block">
                            <div class="layui-form-mid layui-word-aux">填入整数</div>
                            <div class="layui-form-mid layui-word-aux">盈利占账户余额的百分比,账号才能使用转账提现功能</div>
                        </div>
                    </div>
                </div>
                <div class="m-title">内部转账规则设置</div>
                <div class="layui-card-body">
                    <div class="layui-form-item">
                        <label class="layui-form-label">账号关系:</label>
                        <div class="layui-input-block">
                            <input type="radio" name="accountRelation" value="1" title="上下级互转">
                            <input type="radio" name="accountRelation" value="2" title="会员互转">
                        </div>
                    </div>
                </div>
                <div class="layui-card-footer">
                    <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="transferInside-setting-form-submit" id="submit">保存</button>
                </div>
            </div>
        </form>
    </div>
</div>
<style>
    .layui-form-label {
        width: 120px;
    }
    .layui-form-item .layui-input-block {
        margin-left: 150px;
    }
    .layui-table-form .layui-form-item {
        margin-bottom: 20px !important;
    }
    .m-title{
        position: relative;
        font-size: 16px;
        font-weight: bold;
        color: #000000;
        padding-left: 20px;
        margin: 0 0 10px;
    }
    .m-title::before{
        content: '';
        position: absolute;
        left: 0;
        width: 4px;
        height: 20px;
        background: #1890ff;
    }
</style>
<script data-th-inline="javascript" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'validate', 'febs', 'form', 'eleTree'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            validate = layui.validate,
            transferInsideSet = [[${transferInsideSet}]],
            $view = $('#transferInside-setting');
        form.verify(validate);
        form.render();
        initUserValue();
        function initUserValue() {
            form.val("transferInside-setting-form", {
                "serviceFee": transferInsideSet.serviceFee,
                "outAccountProfit": transferInsideSet.outAccountProfit,
                "accountRelation": transferInsideSet.accountRelation,
                "withdrawTimes": transferInsideSet.withdrawTimes
            });
        }
        form.on('submit(transferInside-setting-form-submit)', function (data) {
            console.log(data);
            febs.post(ctx + 'admin/walletCoin/transferInsideUpdate', data.field, function (res) {
                febs.alert.success('设置成功');
            });
            return false;
        });
    });
</script>
src/test/java/cc/mrbird/febs/ChainTest.java
@@ -6,10 +6,12 @@
import cc.mrbird.febs.dapp.entity.DappFundFlowEntity;
import cc.mrbird.febs.dapp.entity.DappOnlineTransferEntity;
import cc.mrbird.febs.dapp.enumerate.CardPeriod;
import cc.mrbird.febs.dapp.enumerate.MemberOnHookPlanEnum;
import cc.mrbird.febs.dapp.mapper.DappFundFlowDao;
import cc.mrbird.febs.dapp.mapper.DappOnlineTransferDao;
import cc.mrbird.febs.dapp.service.DappSystemService;
//import cc.mrbird.febs.job.SystemTradeJob;
import cc.mrbird.febs.dapp.service.MemberOnHookPlan;
import cc.mrbird.febs.dapp.service.impl.BscCoinContractEvent;
import cc.mrbird.febs.dapp.service.impl.BscUsdtContractEvent;
import cc.mrbird.febs.rabbit.producer.ChainProducer;
@@ -33,141 +35,141 @@
@SpringBootTest
public class ChainTest {
    @Test
    public void balanceOfTest() {
        ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC.name());
        System.out.println(instance.balanceOf("0x0000000000000000000000000000000000000001"));
    }
//    @Test
//    public void balanceOfTest() {
//        ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC.name());
//
//        System.out.println(instance.balanceOf("0x0000000000000000000000000000000000000001"));
//    }
//
////    @Autowired
////    private SystemTradeJob systemTradeJob;
////
////    @Test
////    public void transferPoolTest() {
////        systemTradeJob.transferPoolVol();
////    }
////
////
////    @Test
////    public void sourceUsdtTest() {
////        systemTradeJob.sourcePoolUsdtOutLimit();
////    }
////
////    @Test
////    public void poolTest() {
////        systemTradeJob.transferPoolVol();
////    }
//
//    @Autowired
//    private SystemTradeJob systemTradeJob;
//    private DappOnlineTransferDao dappOnlineTransferDao;
//
//    @Test
//    public void transferPoolTest() {
//        systemTradeJob.transferPoolVol();
//    public void transferTest() {
//        System.out.println(ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer(ChainEnum.BSC_USDT_SOURCE.getAddress(), BigDecimal.valueOf(6L)));
//    }
//
//    @Autowired
//    private ChainProducer chainProducer;
//
//    @Test
//    public void sourceUsdtTest() {
//        systemTradeJob.sourcePoolUsdtOutLimit();
//    }
//
//    @Test
//    public void poolTest() {
//        systemTradeJob.transferPoolVol();
//    }
    @Autowired
    private DappOnlineTransferDao dappOnlineTransferDao;
    @Test
    public void transferTest() {
        System.out.println(ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer(ChainEnum.BSC_USDT_SOURCE.getAddress(), BigDecimal.valueOf(6L)));
    }
    @Autowired
    private ChainProducer chainProducer;
    @Test
    public void sendTransferTest() {
        Map<String, String> map = new HashMap<>();
        map.put("batchNo", "678o20scjg5stqf836");
        map.put("type", "batch");
        chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
    }
    @Test
    public void totalSupplyTest() {
        System.out.println(ChainService.getInstance(ChainEnum.BSC_TFC.name()).blockNumber());
    }
//    @Test
//    public void mineTest() {
//        systemTradeJob.mineJob();
//    }
    @Autowired
    private DappFundFlowDao dappFundFlowDao;
    @Test
    public void fundFlowInsertTest() {
        DappFundFlowEntity rewardFlow = new DappFundFlowEntity(11L, BigDecimal.valueOf(1L), 4, 2, BigDecimal.ZERO);
        rewardFlow.setFromHash("1");
        dappFundFlowDao.insert(rewardFlow);
    }
    @Test
    public void userBuyRewardTest() {
        chainProducer.sendUserBuyReward(56L);
    }
    @Test
    public void coinDecimalsTest() {
        int decimals = ChainService.getInstance(ChainEnum.BSC_TFC.name()).decimals();
        BigInteger bigInteger = new BigInteger("110000000000");
        BigDecimal amount = new BigDecimal(bigInteger.toString()).divide(BigDecimal.TEN.pow(decimals), decimals, RoundingMode.HALF_DOWN);
        System.out.println(amount);
    }
    @Autowired
    private DappSystemService dappSystemService;
    @Test
    public void profitTest() {
        dappSystemService.tradeProfitDistribute(31L);
    }
    @Test
    public void nftBalanceTest() {
        BigDecimal balance = ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).balanceOf("0x971c09aa9735eb98459b17ec8b48932d24cbb931");
        System.out.println(1);
    }
    @Test
    public void nftTotalSupplyTest() {
        BigInteger bigInteger = ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).totalSupplyNFT();
        int i = CardPeriod.ONE.recommendCnt(bigInteger.intValue());
        System.out.println(i);
    }
    @Autowired
    private BscUsdtContractEvent bscUsdtContractEvent;
    @Autowired
    private BscCoinContractEvent bscCoinContractEvent;
    @Test
    public void chainListener(){
//        ChainService.contractEventListener(new BigInteger("20895461"), new BigInteger("20895461"), bscUsdtContractEvent, ChainEnum.BSC_USDT_LISTENER.name());
        ChainService.contractEventListener(new BigInteger("21351539"), new BigInteger("21351539"), bscCoinContractEvent, ChainEnum.BSC_TFC_LISTENER.name());
    }
    @Test
    public void nftTest() {
        ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).safeMintNFT("0x691DEaf9b678Cba6747Eec9a4800a9ad2048E39C");
    }
    @Test
    public void sendMsgTest() {
//    public void sendTransferTest() {
//        Map<String, String> map = new HashMap<>();
//        map.put("batchNo", "179");
//        map.put("type", "flow");
//        map.put("batchNo", "678o20scjg5stqf836");
//        map.put("type", "batch");
//        chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
        // 发送盲盒消息
//        chainProducer.sendNftBoxMsg(179L);
    }
    @Test
    public void sendCardTest() {
//        ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).safeMintNFT("0xbddfb8113ee3871774cb91cf1063cfba2a6becc8");
    }
    @Test
    public void wssTest() {
        ChainService.wssContractEventListener(new BigInteger("20888825"), bscUsdtContractEvent, ChainEnum.BSC_USDT_LISTENER.name());
    }
//    }
//
//    @Test
//    public void totalSupplyTest() {
//        System.out.println(ChainService.getInstance(ChainEnum.BSC_TFC.name()).blockNumber());
//    }
//
////    @Test
////    public void mineTest() {
////        systemTradeJob.mineJob();
////    }
//
//    @Autowired
//    private DappFundFlowDao dappFundFlowDao;
//
//    @Test
//    public void fundFlowInsertTest() {
//        DappFundFlowEntity rewardFlow = new DappFundFlowEntity(11L, BigDecimal.valueOf(1L), 4, 2, BigDecimal.ZERO);
//        rewardFlow.setFromHash("1");
//        dappFundFlowDao.insert(rewardFlow);
//    }
//
//    @Test
//    public void userBuyRewardTest() {
//        chainProducer.sendUserBuyReward(56L);
//    }
//
//    @Test
//    public void coinDecimalsTest() {
//        int decimals = ChainService.getInstance(ChainEnum.BSC_TFC.name()).decimals();
//        BigInteger bigInteger = new BigInteger("110000000000");
//        BigDecimal amount = new BigDecimal(bigInteger.toString()).divide(BigDecimal.TEN.pow(decimals), decimals, RoundingMode.HALF_DOWN);
//        System.out.println(amount);
//    }
//
//    @Autowired
//    private DappSystemService dappSystemService;
//
//    @Test
//    public void profitTest() {
//        dappSystemService.tradeProfitDistribute(31L);
//    }
//
//    @Test
//    public void nftBalanceTest() {
//        BigDecimal balance = ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).balanceOf("0x971c09aa9735eb98459b17ec8b48932d24cbb931");
//        System.out.println(1);
//    }
//
//    @Test
//    public void nftTotalSupplyTest() {
//        BigInteger bigInteger = ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).totalSupplyNFT();
//
//        int i = CardPeriod.ONE.recommendCnt(bigInteger.intValue());
//        System.out.println(i);
//    }
//
//    @Autowired
//    private BscUsdtContractEvent bscUsdtContractEvent;
//
//    @Autowired
//    private BscCoinContractEvent bscCoinContractEvent;
//
//    @Test
//    public void chainListener(){
////        ChainService.contractEventListener(new BigInteger("20895461"), new BigInteger("20895461"), bscUsdtContractEvent, ChainEnum.BSC_USDT_LISTENER.name());
//        ChainService.contractEventListener(new BigInteger("21351539"), new BigInteger("21351539"), bscCoinContractEvent, ChainEnum.BSC_TFC_LISTENER.name());
//    }
//
//    @Test
//    public void nftTest() {
//        ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).safeMintNFT("0x691DEaf9b678Cba6747Eec9a4800a9ad2048E39C");
//    }
//
//    @Test
//    public void sendMsgTest() {
////        Map<String, String> map = new HashMap<>();
////        map.put("batchNo", "179");
////        map.put("type", "flow");
////        chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
//
//        // 发送盲盒消息
////        chainProducer.sendNftBoxMsg(179L);
//    }
//
//    @Test
//    public void sendCardTest() {
////        ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).safeMintNFT("0xbddfb8113ee3871774cb91cf1063cfba2a6becc8");
//    }
//
//    @Test
//    public void wssTest() {
//        ChainService.wssContractEventListener(new BigInteger("20888825"), bscUsdtContractEvent, ChainEnum.BSC_USDT_LISTENER.name());
//    }
}
src/test/java/cc/mrbird/febs/JunitTest.java
@@ -2,7 +2,12 @@
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.dapp.entity.DappMemberEntity;
import cc.mrbird.febs.dapp.entity.DataDictionaryCustom;
import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum;
import cc.mrbird.febs.dapp.enumerate.MemberOnHookPlanEnum;
import cc.mrbird.febs.dapp.mapper.DappMemberDao;
import cc.mrbird.febs.dapp.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.dapp.service.MemberOnHookPlan;
import cc.mrbird.febs.job.MineProfitJob;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateTime;
@@ -20,9 +25,7 @@
import java.math.BigDecimal;
import java.security.KeyPair;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
/**
 * @author 
@@ -31,46 +34,63 @@
@SpringBootTest
public class JunitTest {
//    @Autowired
//    private MineProfitJob mineProfitJob;
//    @Autowired
//    private DappMemberDao dappMemberDao;
//
//    @Test
//    public void incomeTest() {
//        mineProfitJob.start();
//    }
//
//    @Test
//    public void userTest() {
//        DappMemberEntity member = dappMemberDao.selectById(6L);
//        mineProfitJob.calAgentMoney(member, BigDecimal.TEN);
//    }
//
//    public static void main(String[] args) {
//        DateTime tomorrow = DateUtil.beginOfDay(DateUtil.tomorrow());
//        System.out.println(DateUtil.between(new Date(), tomorrow, DateUnit.SECOND, true));
//    }
//
//    public String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1cHrcMpXoKNC8rjAa/jAbgU2bhIBmJmn6iYDfqt0Him/p2s5F0L9nfzZOLYlPq3z12zvXl9IgThhtLIBLi86RPW0ljuwpTvIZz9O36Zae9eMk5bMNsFEFsxg1IOLIM2Oc4ffNvGL58Uupp9RL5NCN1MRQyY61ISy7H2VRTznoJQIDAQAB";
//    public String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALVwetwylego0LyuMBr+MBuBTZuEgGYmafqJgN+q3QeKb+nazkXQv2d/Nk4tiU+rfPXbO9eX0iBOGG0sgEuLzpE9bSWO7ClO8hnP07fplp714yTlsw2wUQWzGDUg4sgzY5zh9828YvnxS6mn1Evk0I3UxFDJjrUhLLsfZVFPOeglAgMBAAECgYAPKWWS5gVB37tFsRajAs+5VK5MCyABqT8c6QWkay5KNYbRl2+6RM3h068RjFuXlUB9eQMAqpasDWqcIOZdqcKqmxm0ILF2zfPzJr4RaQNSNwDCVrKEeaDtrZQcq/0ygaNDF9y203UMHT0dfEQSGp/xkjTgXNsOuC9iLM56XScOVwJBAPOZLbrCi0h4PL7g3rWsCw8/aN6ehkJ3iTDgjYpdBwJOJSyxV0qi0xmDthGqPd99Kvc14u1jy3ghpm1SAEunrj8CQQC+rS6qajIkK7NiRmX43chDhgMPGo0UFHbmHyYBb1Eyrxu1MNWQEh221p54GsB2HqAGRhxxQ98Ds2S26Au7QpibAkA2nQAAn/8kFzjfPoEPz+uG1puHVZkaK7yJRb7V53dbz/NLqtK8O/cCAGKAYV+PzHsmg2FGAZqrazfpyHmifIx3AkBnFau/+A/JnFKr09F3XTfSwZXPyZPyAipRuQ9MAUmNtDuvloovDIxB9//OgPACLAZpvefMmFvuXUMa25LUF2n3AkBGb+vO+69NSyQM2SHKZ9fUrxx9ZPhupNt/TXNL9OMEQiLaHCYgg0tfcojGe3QjBCA6wVG+dCyZUcv5OwiW23pI";
//
//    @Test
//    public void encodeTest() {
//        RSA rsa = new RSA(AppContants.REQ_PRIVATE_KEY, AppContants.REQ_PUBLIC_KEY);
//        Map<String, Object> map = new HashMap<>();
//        map.put("test", 123);
//        String s = JSONObject.toJSONString(map);
//        String s1 = rsa.encryptBase64(s, KeyType.PublicKey);
//        System.out.println(s1);
//    }
//
//    @Test
//    public void decodeTest() {
//        String ss = "pAEYpX4a+gm9lqy2/bQNx/EjJS0D7I/ezcCB+G/pgI5GDLWUj7+S7jhGWlV2PTGHcNj8vJQRXp5qpV7GOmaQX30HVao3srsOEL2CWU5F/5A4T9ncs3NuoYEv5LUCTolEEq8r5VdBRzU9BoZCISLFQxjFIp5inuydjz2JE9lnOBYQIP8kZSXHy2N1gkythypbj81q9cC83wNND7pvSjw140EDtXWqlCIhpoZlwB/n8+D5khBHwxWhuf0wacYLj9aKZ8tSKMyw0/WdQvpBZ6ymxuoHrLlcL36PTEN59rce9tnnRs5+AjAXppx4GIODdvbHLQJurBslw2GVHJeDbugRvA==";
//        RSA rsa = new RSA(AppContants.RESP_PRIVATE_KEY, AppContants.RESP_PUBLIC_KEY);
//        String s = rsa.decryptStr(ss, KeyType.PrivateKey);
//        System.out.println(s);
//    }
//
    @Autowired
    private MineProfitJob mineProfitJob;
    @Autowired
    private DappMemberDao dappMemberDao;
    private DataDictionaryCustomMapper dataDictionaryCustomMapper;
    @Test
    public void incomeTest() {
        mineProfitJob.start();
    }
    @Test
    public void userTest() {
        DappMemberEntity member = dappMemberDao.selectById(6L);
        mineProfitJob.calAgentMoney(member, BigDecimal.TEN);
    }
    public static void main(String[] args) {
        DateTime tomorrow = DateUtil.beginOfDay(DateUtil.tomorrow());
        System.out.println(DateUtil.between(new Date(), tomorrow, DateUnit.SECOND, true));
    }
    public String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1cHrcMpXoKNC8rjAa/jAbgU2bhIBmJmn6iYDfqt0Him/p2s5F0L9nfzZOLYlPq3z12zvXl9IgThhtLIBLi86RPW0ljuwpTvIZz9O36Zae9eMk5bMNsFEFsxg1IOLIM2Oc4ffNvGL58Uupp9RL5NCN1MRQyY61ISy7H2VRTznoJQIDAQAB";
    public String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALVwetwylego0LyuMBr+MBuBTZuEgGYmafqJgN+q3QeKb+nazkXQv2d/Nk4tiU+rfPXbO9eX0iBOGG0sgEuLzpE9bSWO7ClO8hnP07fplp714yTlsw2wUQWzGDUg4sgzY5zh9828YvnxS6mn1Evk0I3UxFDJjrUhLLsfZVFPOeglAgMBAAECgYAPKWWS5gVB37tFsRajAs+5VK5MCyABqT8c6QWkay5KNYbRl2+6RM3h068RjFuXlUB9eQMAqpasDWqcIOZdqcKqmxm0ILF2zfPzJr4RaQNSNwDCVrKEeaDtrZQcq/0ygaNDF9y203UMHT0dfEQSGp/xkjTgXNsOuC9iLM56XScOVwJBAPOZLbrCi0h4PL7g3rWsCw8/aN6ehkJ3iTDgjYpdBwJOJSyxV0qi0xmDthGqPd99Kvc14u1jy3ghpm1SAEunrj8CQQC+rS6qajIkK7NiRmX43chDhgMPGo0UFHbmHyYBb1Eyrxu1MNWQEh221p54GsB2HqAGRhxxQ98Ds2S26Au7QpibAkA2nQAAn/8kFzjfPoEPz+uG1puHVZkaK7yJRb7V53dbz/NLqtK8O/cCAGKAYV+PzHsmg2FGAZqrazfpyHmifIx3AkBnFau/+A/JnFKr09F3XTfSwZXPyZPyAipRuQ9MAUmNtDuvloovDIxB9//OgPACLAZpvefMmFvuXUMa25LUF2n3AkBGb+vO+69NSyQM2SHKZ9fUrxx9ZPhupNt/TXNL9OMEQiLaHCYgg0tfcojGe3QjBCA6wVG+dCyZUcv5OwiW23pI";
    @Test
    public void encodeTest() {
        RSA rsa = new RSA(AppContants.REQ_PRIVATE_KEY, AppContants.REQ_PUBLIC_KEY);
        Map<String, Object> map = new HashMap<>();
        map.put("test", 123);
        String s = JSONObject.toJSONString(map);
        String s1 = rsa.encryptBase64(s, KeyType.PublicKey);
        System.out.println(s1);
    }
    @Test
    public void decodeTest() {
        String ss = "pAEYpX4a+gm9lqy2/bQNx/EjJS0D7I/ezcCB+G/pgI5GDLWUj7+S7jhGWlV2PTGHcNj8vJQRXp5qpV7GOmaQX30HVao3srsOEL2CWU5F/5A4T9ncs3NuoYEv5LUCTolEEq8r5VdBRzU9BoZCISLFQxjFIp5inuydjz2JE9lnOBYQIP8kZSXHy2N1gkythypbj81q9cC83wNND7pvSjw140EDtXWqlCIhpoZlwB/n8+D5khBHwxWhuf0wacYLj9aKZ8tSKMyw0/WdQvpBZ6ymxuoHrLlcL36PTEN59rce9tnnRs5+AjAXppx4GIODdvbHLQJurBslw2GVHJeDbugRvA==";
        RSA rsa = new RSA(AppContants.RESP_PRIVATE_KEY, AppContants.RESP_PUBLIC_KEY);
        String s = rsa.decryptStr(ss, KeyType.PrivateKey);
        System.out.println(s);
    public void getmember(){
        List<DataDictionaryCustom> dataDictionaryCustoms = dataDictionaryCustomMapper.selectDicByType(DataDictionaryEnum.PLAN_F.getType());
        LinkedList<Map<String,String>> strings = new LinkedList<>();
        for(DataDictionaryCustom dataDictionaryCustom : dataDictionaryCustoms){
            Map<String, String> stringStringHashMap = new HashMap<>();
            stringStringHashMap.put(dataDictionaryCustom.getDescription(),dataDictionaryCustom.getValue());
            strings.add(stringStringHashMap);
        }
        Map<String, LinkedList<String>> level_mb = MemberOnHookPlanEnum.valueOf("LEVEL_MB")
                .getMemberOnHook(Double.valueOf(2),new BigDecimal(0.2),strings);
        System.out.println(level_mb.toString());
        System.out.println(level_mb);
    }
}
src/test/java/cc/mrbird/febs/MemberTest.java
@@ -3,11 +3,13 @@
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.dapp.entity.*;
import cc.mrbird.febs.dapp.enumerate.MemberOnHookPlanEnum;
import cc.mrbird.febs.dapp.mapper.DappFundFlowDao;
import cc.mrbird.febs.dapp.mapper.DappMemberBoxRecordMapper;
import cc.mrbird.febs.dapp.mapper.DappMemberDao;
import cc.mrbird.febs.dapp.mapper.DataDictionaryCustomMapper;
import cc.mrbird.febs.dapp.service.DappSystemService;
import cc.mrbird.febs.dapp.service.MemberOnHookPlan;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
@@ -17,6 +19,7 @@
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
 * @author wzy
@@ -25,124 +28,124 @@
@SpringBootTest
public class MemberTest {
    @Autowired
    private DappMemberDao dappMemberDao;
    @Autowired
    private DataDictionaryCustomMapper dataDictionaryCustomMapper;
    @Test
    public void refererIdsTest() {
        DappMemberEntity member = dappMemberDao.selectById(24);
        boolean flag = false;
        String parentId = "35087336";
        String ids = "";
        String feeProfitIds = "";
        int i = 1;
        List<DataDictionaryCustom> feeProfitDic = dataDictionaryCustomMapper.selectDicByType(AppContants.DIC_TYPE_DISTRIBUTE_PROP);
        while (!flag && StringUtils.isNotBlank(parentId)) {
            if (StrUtil.isBlank(ids)) {
                ids += parentId;
            } else {
                ids += ("," + parentId);
            }
            if (i <= 4) {
                if (StrUtil.isBlank(feeProfitIds)) {
                    feeProfitIds += parentId;
                } else {
                    feeProfitIds += ("," + parentId);
                }
            }
            i++;
            DappMemberEntity parentMember = dappMemberDao.selectMemberInfoByInviteId(parentId);
            if (parentMember == null) {
                break;
            }
            parentId = parentMember.getRefererId();
            if (StringUtils.isBlank(parentId) || "0".equals(parentId)) {
                break;
            }
            if (parentMember.getRefererId().equals(parentMember.getInviteId())) {
                flag = true;
            }
        }
        member.setRefererIds(ids);
        member.setFeeProfitIds(feeProfitIds);
    }
    @Autowired
    private DappFundFlowDao dappFundFlowDao;
    @Autowired
    private DappMemberBoxRecordMapper dappMemberBoxRecordMapper;
    @Test
    public void memberBoxTest() {
        QueryWrapper<DappFundFlowEntity> query = new QueryWrapper<>();
        query.eq("status", 2);
        query.eq("type", 1);
        List<DappFundFlowEntity> fundFLows = dappFundFlowDao.selectList(query);
        for (DappFundFlowEntity fundFLow : fundFLows) {
            DappMemberEntity member = dappMemberDao.selectById(fundFLow.getMemberId());
            DappMemberEntity parent = dappMemberDao.selectMemberInfoByInviteId(member.getRefererId());
            if (parent == null) {
                continue;
            }
            if (new BigDecimal(1600).compareTo(fundFLow.getAmount()) > 0) {
                System.out.println(fundFLow.getId());
                continue;
            }
            DappMemberBoxRecordEntity boxRecord = dappMemberBoxRecordMapper.selectByFromMemberId(fundFLow.getMemberId());
            if (boxRecord != null) {
                continue;
            }
            DappMemberBoxRecordEntity memberBoxRecordEntity = new DappMemberBoxRecordEntity();
            memberBoxRecordEntity.setMemberId(parent.getId());
            memberBoxRecordEntity.setAddress(parent.getAddress());
            memberBoxRecordEntity.setFromMemberId(member.getId());
            memberBoxRecordEntity.setFromAddress(member.getAddress());
            memberBoxRecordEntity.setCreateTime(fundFLow.getCreateTime());
            this.dappMemberBoxRecordMapper.insert(memberBoxRecordEntity);
        }
    }
    @Autowired
    private DappSystemService dappSystemService;
    @Test
    public void boxCntTest() {
        dappSystemService.boxCnt(109L);
    }
    @Autowired
    private RedisUtils redisUtils;
    @Test
    public void startSystemTest() {
        redisUtils.set(AppContants.SYSTEM_START_FLAG, "start");
        dappSystemService.startSystem();
    }
    @Test
    public void tfcPriceTest() {
        dappSystemService.tfcNewPrice();
    }
    @Test
    public void priceTest() {
        List<DappPriceRecordEntity> priceListIn24H = dappSystemService.findPriceListIn24H();
        System.out.println(111);
    }
    @Test
    public void buyRewardTest() {
        dappSystemService.userBuyReward(347L);
    }
//    @Autowired
//    private DappMemberDao dappMemberDao;
//
//    @Autowired
//    private DataDictionaryCustomMapper dataDictionaryCustomMapper;
//
//    @Test
//    public void refererIdsTest() {
//        DappMemberEntity member = dappMemberDao.selectById(24);
//
//        boolean flag = false;
//        String parentId = "35087336";
//        String ids = "";
//        String feeProfitIds = "";
//
//        int i = 1;
//        List<DataDictionaryCustom> feeProfitDic = dataDictionaryCustomMapper.selectDicByType(AppContants.DIC_TYPE_DISTRIBUTE_PROP);
//        while (!flag && StringUtils.isNotBlank(parentId)) {
//            if (StrUtil.isBlank(ids)) {
//                ids += parentId;
//            } else {
//                ids += ("," + parentId);
//            }
//
//            if (i <= 4) {
//                if (StrUtil.isBlank(feeProfitIds)) {
//                    feeProfitIds += parentId;
//                } else {
//                    feeProfitIds += ("," + parentId);
//                }
//            }
//
//            i++;
//            DappMemberEntity parentMember = dappMemberDao.selectMemberInfoByInviteId(parentId);
//            if (parentMember == null) {
//                break;
//            }
//            parentId = parentMember.getRefererId();
//            if (StringUtils.isBlank(parentId) || "0".equals(parentId)) {
//                break;
//            }
//            if (parentMember.getRefererId().equals(parentMember.getInviteId())) {
//                flag = true;
//            }
//        }
//        member.setRefererIds(ids);
//        member.setFeeProfitIds(feeProfitIds);
//    }
//
//    @Autowired
//    private DappFundFlowDao dappFundFlowDao;
//
//    @Autowired
//    private DappMemberBoxRecordMapper dappMemberBoxRecordMapper;
//
//    @Test
//    public void memberBoxTest() {
//        QueryWrapper<DappFundFlowEntity> query = new QueryWrapper<>();
//        query.eq("status", 2);
//        query.eq("type", 1);
//        List<DappFundFlowEntity> fundFLows = dappFundFlowDao.selectList(query);
//        for (DappFundFlowEntity fundFLow : fundFLows) {
//            DappMemberEntity member = dappMemberDao.selectById(fundFLow.getMemberId());
//            DappMemberEntity parent = dappMemberDao.selectMemberInfoByInviteId(member.getRefererId());
//            if (parent == null) {
//                continue;
//            }
//
//            if (new BigDecimal(1600).compareTo(fundFLow.getAmount()) > 0) {
//                System.out.println(fundFLow.getId());
//                continue;
//            }
//
//            DappMemberBoxRecordEntity boxRecord = dappMemberBoxRecordMapper.selectByFromMemberId(fundFLow.getMemberId());
//            if (boxRecord != null) {
//                continue;
//            }
//
//            DappMemberBoxRecordEntity memberBoxRecordEntity = new DappMemberBoxRecordEntity();
//            memberBoxRecordEntity.setMemberId(parent.getId());
//            memberBoxRecordEntity.setAddress(parent.getAddress());
//            memberBoxRecordEntity.setFromMemberId(member.getId());
//            memberBoxRecordEntity.setFromAddress(member.getAddress());
//            memberBoxRecordEntity.setCreateTime(fundFLow.getCreateTime());
//            this.dappMemberBoxRecordMapper.insert(memberBoxRecordEntity);
//        }
//
//    }
//
//    @Autowired
//    private DappSystemService dappSystemService;
//
//    @Test
//    public void boxCntTest() {
//        dappSystemService.boxCnt(109L);
//    }
//
//    @Autowired
//    private RedisUtils redisUtils;
//
//    @Test
//    public void startSystemTest() {
//        redisUtils.set(AppContants.SYSTEM_START_FLAG, "start");
//        dappSystemService.startSystem();
//    }
//    @Test
//    public void tfcPriceTest() {
//        dappSystemService.tfcNewPrice();
//    }
//
//    @Test
//    public void priceTest() {
//        List<DappPriceRecordEntity> priceListIn24H = dappSystemService.findPriceListIn24H();
//        System.out.println(111);
//    }
//
//    @Test
//    public void buyRewardTest() {
//        dappSystemService.userBuyReward(347L);
//    }
}