xiaoyong931011
2022-03-10 030e1cca0b8103662a182a4dbe801c063b342630
20211201  fish
18 files modified
45 files added
4363 ■■■■■ changed files
src/main/java/com/xcong/excoin/common/utils/BigDecimalSerialize.java 31 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/controller/DocumentaryController.java 122 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/controller/ViewController.java 82 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dto/FollowTraderInfoDto.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dto/ModifyProfitRatioDto.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowFollowerProfitEntity.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderInfoEntity.java 41 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderLabelEntity.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderProfitInfoEntity.java 62 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowFollowerProfitMapper.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowTraderInfoMapper.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowTraderLabelMapper.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowTraderProfitInfoMapper.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/service/DocumentaryService.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/service/impl/DocumentaryServiceImpl.java 264 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/SeeFollowerInfoVo.java 30 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java 7 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/mapper/MemberMapper.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/mapper/MemberWalletCoinMapper.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/controller/OtcController.java 163 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/controller/ViewController.java 132 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/entity/OtcEntrustOrderEntity.java 70 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/entity/OtcMarketBussinessEntity.java 69 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/entity/OtcOrderAppealEntity.java 46 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/entity/OtcOrderEntity.java 81 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/entity/OtcSettingEntity.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcEntrustOrderMapper.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcMarketBussinessMapper.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcOrderAppealMapper.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcOrderMapper.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcSettingMapper.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/service/OtcService.java 49 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/service/impl/OtcServiceImpl.java 360 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/otc/vo/OtcAppealInfoVo.java 59 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/FollowFollowerProfitMapper.xml 9 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/FollowTraderInfoMapper.xml 30 ●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/FollowTraderLabelMapper.xml 9 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/FollowTraderProfitInfoMapper.xml 15 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MemberMapper.xml 10 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MemberWalletCoinMapper.xml 16 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/OtcEntrustOrderMapper.xml 29 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/OtcMarketBussinessMapper.xml 26 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/OtcOrderAppealMapper.xml 27 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/OtcOrderMapper.xml 31 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/OtcSettingMapper.xml 12 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/followLabelSet.html 127 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/followLabelSetAdd.html 67 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/followLabelSetDetail.html 77 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/modifyProfitRatio.html 122 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/seeFollowerInfo.html 58 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/traderDetail.html 9 ●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/traderProfit.html 209 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/documentary/traderUpdate.html 104 ●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcAppealInfo.html 140 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcAppealList.html 173 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcEntrustList.html 211 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcEntrustListUpdate.html 126 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcHuiKuan.html 93 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcOrderInfo.html 109 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcOrderList.html 175 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcSettingList.html 126 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcSettingUpdate.html 109 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/otc/otcShopList.html 177 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/utils/BigDecimalSerialize.java
New file
@@ -0,0 +1,31 @@
package com.xcong.excoin.common.utils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
/**
 * BigDecimal保留两位小数
 *
 */
public class BigDecimalSerialize extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value != null && !"".equals(value)) {
            gen.writeString(((BigDecimal) value).setScale(2, BigDecimal.ROUND_HALF_DOWN) + "");
        } else {
            gen.writeString(value + "");
        }
    }
}
src/main/java/com/xcong/excoin/modules/documentary/controller/DocumentaryController.java
@@ -5,20 +5,24 @@
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity;
import com.xcong.excoin.modules.trademanage.entity.ContractOrderEntity;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.xcong.excoin.common.annotation.ControllerEndpoint;
import com.xcong.excoin.common.controller.BaseController;
import com.xcong.excoin.common.entity.FebsResponse;
import com.xcong.excoin.common.entity.QueryRequest;
import com.xcong.excoin.modules.documentary.dto.FollowTraderInfoDto;
import com.xcong.excoin.modules.documentary.dto.ModifyProfitRatioDto;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderLabelEntity;
import com.xcong.excoin.modules.documentary.service.DocumentaryService;
import com.xcong.excoin.modules.systemSetting.entity.PlatformBannerEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -29,10 +33,50 @@
@RequiredArgsConstructor
@RequestMapping(value = "/documentary")
public class DocumentaryController extends BaseController {
    private final DocumentaryService documentaryService;
    /**
    private final DocumentaryService documentaryService;
    /**
     * 标签---列表
     * @return
     */
    @GetMapping("traderLabelList")
    public FebsResponse traderLabelList(FollowTraderLabelEntity followTraderLabelEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(documentaryService.traderLabelList(followTraderLabelEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 标签---删除
     * @return
     */
    @GetMapping("traderLabelDelete/{id}")
    @ControllerEndpoint(operation = "标签---删除", exceptionMessage = "删除失败")
    public FebsResponse traderLabelDelete(@NotNull(message = "{required}") @PathVariable Long id) {
        return documentaryService.traderLabelDelete(id);
    }
    /**
     * 标签---新增
     */
    @PostMapping("followLabelSetAdd")
    @ControllerEndpoint(operation = "标签---新增", exceptionMessage = "新增失败")
    public FebsResponse followLabelSetAdd(@Valid FollowTraderLabelEntity followTraderLabelEntity) {
        documentaryService.followLabelSetAdd(followTraderLabelEntity);
        return new FebsResponse().success();
    }
    /**
     * 标签---修改
     */
    @PostMapping("followLabelSetUpdate")
    @ControllerEndpoint(operation = "标签---修改", exceptionMessage = "修改失败")
    public FebsResponse followLabelSetUpdate(@Valid FollowTraderLabelEntity followTraderLabelEntity) {
        documentaryService.followLabelSetUpdate(followTraderLabelEntity);
        return new FebsResponse().success();
    }
    /**
     * 交易员申请---列表
     * @return
     */
@@ -41,7 +85,7 @@
        Map<String, Object> data = getDataTable(documentaryService.findTraderListInPage(followTraderInfoEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 交易员申请---确认
     * @return
@@ -51,7 +95,17 @@
    public FebsResponse traderConfirm(@Valid FollowTraderInfoDto followTraderInfoDto) {
        return documentaryService.traderConfirm(followTraderInfoDto);
    }
    /**
     * 交易员收益率修改---确认
     * @return
     */
    @PostMapping("modifyProfitRatio")
    @ControllerEndpoint(operation = "交易员收益率修改---确认", exceptionMessage = "修改失败")
    public FebsResponse modifyProfitRatio(@Valid ModifyProfitRatioDto modifyProfitRatioDto) {
        return documentaryService.modifyProfitRatio(modifyProfitRatioDto);
    }
    /**
     * 踢出交易员
     * @param id
@@ -62,7 +116,27 @@
    public FebsResponse traderGetOut(@NotNull(message = "{required}") @PathVariable Long id) {
        return documentaryService.traderGetOut(id);
    }
    /**
     * 设置成首页交易员
     * @param id
     * @return
     */
    @GetMapping("traderGetOn/{id}")
    @ControllerEndpoint(operation = "设置成首页交易员", exceptionMessage = "设置失败")
    public FebsResponse traderGetOn(@NotNull(message = "{required}") @PathVariable Long id) {
        return documentaryService.traderGetOn(id);
    }
    /**
     * 设置成首页交易员---取消
     * @param id
     * @return
     */
    @GetMapping("traderGetOutFrist/{id}")
    @ControllerEndpoint(operation = "设置成首页交易员", exceptionMessage = "设置失败")
    public FebsResponse traderGetOutFrist(@NotNull(message = "{required}") @PathVariable Long id) {
        return documentaryService.traderGetOutFrist(id);
    }
    /**
     * 设置成【满员】状态
     * @param id
@@ -71,7 +145,29 @@
    @GetMapping("traderGetFull/{id}")
    @ControllerEndpoint(operation = "设置成【满员】状态", exceptionMessage = "设置失败")
    public FebsResponse traderGetFull(@NotNull(message = "{required}") @PathVariable Long id) {
        return documentaryService.traderGetFull(id);
        return documentaryService.traderGetFull(id);
    }
    /**
     * 交易员数据---列表---交易员利润分成
     */
    @GetMapping("traderProfitInfo")
    public FebsResponse traderProfitInfo(FollowTraderProfitInfoEntity followTraderProfitInfoEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(documentaryService.findTraderProfitInfoInfoInPage(followTraderProfitInfoEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 交易员数据---列表---跟单数据详情
     */
    @GetMapping("/seeFollowerInfo")
    public FebsResponse seeFollowerInfo(QueryRequest request, FollowTraderProfitInfoEntity followTraderProfitInfoEntity,Integer parentId) {
        if(parentId==null){
            ViewController.idFromMember=0;
        }
        followTraderProfitInfoEntity.setId(ViewController.idFromMember);
        Map<String, Object> dataTable = getDataTable(documentaryService.findlistSeeFollowerInfo(request, followTraderProfitInfoEntity));
        return new FebsResponse().success().data(dataTable);
    }
}
src/main/java/com/xcong/excoin/modules/documentary/controller/ViewController.java
@@ -11,18 +11,64 @@
import com.xcong.excoin.common.entity.FebsConstant;
import com.xcong.excoin.common.utils.FebsUtil;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderLabelEntity;
import com.xcong.excoin.modules.documentary.mapper.FollowTraderLabelMapper;
import com.xcong.excoin.modules.documentary.service.DocumentaryService;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.systemSetting.entity.PlatformTradeSettingEntity;
import lombok.RequiredArgsConstructor;
@Controller("documentaryView")
@RequestMapping(FebsConstant.VIEW_PREFIX + "modules/documentary")
@RequiredArgsConstructor
public class ViewController extends BaseController{
    private final DocumentaryService documentaryService;
    /**
    private final DocumentaryService documentaryService;
    private final FollowTraderLabelMapper followTraderLabelMapper;
    public static long idFromMember;
    /**
     *交易员利润分成---详情
     */
    @GetMapping("seeFollowerInfo/{id}")
    public String seeFollowerInfo(@PathVariable long id, Model model) {
        idFromMember = id;
        return FebsUtil.view("modules/documentary/seeFollowerInfo");
    }
    /**
     * 标签设置
     * @return
     */
    @GetMapping("followLabelSet")
    @RequiresPermissions("followLabelSet:view")
    public String followLabelSet() {
        return FebsUtil.view("modules/documentary/followLabelSet");
    }
    /**
     * 标签设置---修改
     */
    @GetMapping("followLabelSetUpdate/{id}")
    @RequiresPermissions("followLabelSetUpdate:update")
    public String followLabelSetUpdate(@PathVariable long id, Model model) {
        FollowTraderLabelEntity data = followTraderLabelMapper.selectById(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/documentary/followLabelSetDetail");
    }
    /**
     * 标签设置---新增
     */
    @GetMapping("followLabelSetAdd")
    @RequiresPermissions("followLabelSetAdd:add")
    public String noticeManageAdd() {
        return FebsUtil.view("modules/documentary/followLabelSetAdd");
    }
    /**
     * 交易员申请
     * @return
     */
@@ -31,7 +77,7 @@
    public String traderUpdate() {
        return FebsUtil.view("modules/documentary/traderUpdate");
    }
    /**
     * 交易员申请--审核
     * @return
@@ -39,9 +85,31 @@
    @GetMapping("traderDetail/{id}")
    @RequiresPermissions("traderDetail:update")
    public String traderDetail(@PathVariable long id, Model model) {
        FollowTraderInfoEntity data = documentaryService.selectTraderDetailByid(id);
        model.addAttribute("member", data);
        FollowTraderInfoEntity data = documentaryService.selectTraderDetailByid(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/documentary/traderDetail");
    }
    /**
     * 交易员收益率修改
     * @return
     */
    @GetMapping("modifyProfitRatio/{id}")
    @RequiresPermissions("modifyProfitRatio:update")
    public String modifyProfitRatio(@PathVariable long id, Model model) {
        FollowTraderInfoEntity data = documentaryService.selectTraderDetailByid(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/documentary/modifyProfitRatio");
    }
    /**
     * 交易员利润分成
     * @return
     */
    @GetMapping("traderProfit")
    @RequiresPermissions("traderProfit:view")
    public String traderProfit() {
        return FebsUtil.view("modules/documentary/traderProfit");
    }
}
src/main/java/com/xcong/excoin/modules/documentary/dto/FollowTraderInfoDto.java
@@ -6,11 +6,13 @@
@Data
public class FollowTraderInfoDto {
    @NotNull(message = "ID不能为空")
    private Long id;
    @NotNull(message = "ID不能为空")
    private String isok;
    private String profitRatio;
}
src/main/java/com/xcong/excoin/modules/documentary/dto/ModifyProfitRatioDto.java
New file
@@ -0,0 +1,16 @@
package com.xcong.excoin.modules.documentary.dto;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
public class ModifyProfitRatioDto {
    @NotNull(message = "ID不能为空")
    private Long id;
    private String profitRatio;
    private String followNum;
}
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowFollowerProfitEntity.java
New file
@@ -0,0 +1,48 @@
package com.xcong.excoin.modules.documentary.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.xcong.excoin.common.entity.BaseEntity;
import com.xcong.excoin.common.utils.BigDecimalSerialize;
import lombok.Data;
@Data
@TableName("follow_follower_profit")
public class FollowFollowerProfitEntity extends BaseEntity{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    public static final Integer IS_FOLLOW_Y = 1;
    public static final Integer IS_FOLLOW_N = 2;
    /**
     * 跟随者ID
     */
    private Long memberId;
    /**
     * 交易员ID
     */
    private Long tradeId;
    /**
     * 交易员会员ID
     */
    private Long tradeMemberId;
    /**
     * 累计跟随本金
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal totalPrincipal;
    /**
     * 累计收益
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal totalProfit;
    /**
     * 是否跟随 1-是 2-否
     */
    private Integer isFollow;
}
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderInfoEntity.java
@@ -1,10 +1,14 @@
package com.xcong.excoin.modules.documentary.entity;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.xcong.excoin.common.entity.BaseEntity;
import com.xcong.excoin.common.utils.BigDecimalSerialize;
import lombok.Data;
@@ -14,12 +18,14 @@
@Data
@TableName("follow_trader_info")
public class FollowTraderInfoEntity extends BaseEntity{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
     /**
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date entryTime;
    /**
     * 会员ID
     */
    private Long memberId;
@@ -42,8 +48,15 @@
    public static final Integer IS_ALL_Y = 1;
    public static final Integer IS_ALL_N = 2;
    /**
     * 设置成首页
     */
    private Integer isSetFrist;
    public static final Integer IS_SETFRIST_Y = 1;
    public static final Integer IS_SETFRIST_N = 0;
    /**
     * 利润
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal profitRatio;
    /**
     * 审核状态 1通过2不通过3待审核
@@ -58,10 +71,15 @@
    private Integer isOpen;
    public static final Integer ISOPEN_Y = 1;
    public static final Integer ISOPEN_N = 2;
    /**
     * 最大跟随人数
     */
    private Integer followNum;
    @TableField(exist = false)
    private String account;
    @TableField(exist = false)
    private String realName;
    @TableField(exist = false)
@@ -72,7 +90,7 @@
    private String inviteId;
    @TableField(exist = false)
    private int accountType;
    @TableField(exist = false)
    private double walletNum;
    @TableField(exist = false)
@@ -81,6 +99,9 @@
    private double agentNum;
    @TableField(exist = false)
    private String isok;
    //当前跟随人数
    @TableField(exist = false)
    private String followNumNow;
}
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderLabelEntity.java
New file
@@ -0,0 +1,26 @@
package com.xcong.excoin.modules.documentary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.entity.BaseEntity;
import lombok.Data;
@Data
@TableName("follow_trader_label")
public class FollowTraderLabelEntity{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    @TableId(value = "id",type = IdType.AUTO)
    private Long id;
    /**
     * 标签
     */
    private String labels;
}
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderProfitInfoEntity.java
@@ -1,20 +1,24 @@
package com.xcong.excoin.modules.documentary.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.xcong.excoin.common.entity.BaseEntity;
import com.xcong.excoin.common.utils.BigDecimalSerialize;
import lombok.Data;
@Data
@TableName("follow_trader_profit_info")
public class FollowTraderProfitInfoEntity extends BaseEntity{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    /**
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    /**
     * 交易员ID
     */
    private Long traderId;
@@ -25,28 +29,72 @@
    /**
     * 累计收益率
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal totalProfitRatio;
    /**
     * 带单总收益
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal totalProfit;
    /**
     * 跟随者总收益
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal followerTotalProfit;
    /**
     * 胜率
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal winRate;
    /**
     * 累计跟随人数
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal totalFollowerCnt;
    /**
     * 交易笔数
     */
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal totalOrderCnt;
    @TableField(exist = false)
    private String account;
    @TableField(exist = false)
    private String realName;
    /**
     * 手机号(包含国际手机号)
     */
    @TableField(exist = false)
    private String phone;
    /**
     * 邮箱
     */
    @TableField(exist = false)
    private String email;
    /**
     * 邀请码
     */
    @TableField(exist = false)
    private String inviteId;
    /**
     * 账号类型
     */
    @TableField(exist = false)
    private int accountType;
    /**
     * 利润率
     */
    @TableField(exist = false)
    private BigDecimal profitRatio;
    /**
     * 总返利
     */
    @TableField(exist = false)
    private BigDecimal profitRatioTotal;
}
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowFollowerProfitMapper.java
New file
@@ -0,0 +1,17 @@
package com.xcong.excoin.modules.documentary.mapper;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.documentary.vo.SeeFollowerInfoVo;
public interface FollowFollowerProfitMapper extends BaseMapper<FollowFollowerProfitEntity> {
    IPage<SeeFollowerInfoVo> findFollowFollowerProfitInfo(Page<SeeFollowerInfoVo> page,
            @Param("record") FollowTraderInfoEntity followTraderInfo);
}
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowTraderInfoMapper.java
@@ -12,4 +12,10 @@
    IPage<FollowTraderInfoEntity> findTraderListInPage(Page<FollowTraderInfoEntity> page, @Param("record") FollowTraderInfoEntity followTraderInfoEntity);
    String selectProfitRatioTotal(@Param("memberId") Long memberId);
    String selectAllProfitByMemberIdAndTraderMemberId(@Param("memberId")long memberId, @Param("traderMemberId")Long traderMemberId);
    String selectFollowNowBytraderId(@Param("traderId")Long traderId);
}
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowTraderLabelMapper.java
New file
@@ -0,0 +1,15 @@
package com.xcong.excoin.modules.documentary.mapper;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.documentary.entity.FollowTraderLabelEntity;
public interface FollowTraderLabelMapper extends BaseMapper<FollowTraderLabelEntity> {
    IPage<FollowTraderLabelEntity> findFollowTraderLabelEntitysInPage(Page<FollowTraderLabelEntity> page,
            @Param("record")FollowTraderLabelEntity followTraderLabelEntity);
}
src/main/java/com/xcong/excoin/modules/documentary/mapper/FollowTraderProfitInfoMapper.java
@@ -1,8 +1,15 @@
package com.xcong.excoin.modules.documentary.mapper;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity;
public interface FollowTraderProfitInfoMapper extends BaseMapper<FollowTraderProfitInfoEntity> {
    IPage<FollowTraderProfitInfoEntity> findTraderProfitInfoInfoInPage(Page<FollowTraderProfitInfoEntity> page,
                                                                       @Param("record")FollowTraderProfitInfoEntity followTraderProfitInfoEntity);
}
src/main/java/com/xcong/excoin/modules/documentary/service/DocumentaryService.java
@@ -8,7 +8,11 @@
import com.xcong.excoin.common.entity.FebsResponse;
import com.xcong.excoin.common.entity.QueryRequest;
import com.xcong.excoin.modules.documentary.dto.FollowTraderInfoDto;
import com.xcong.excoin.modules.documentary.dto.ModifyProfitRatioDto;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderLabelEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity;
import com.xcong.excoin.modules.documentary.vo.SeeFollowerInfoVo;
public interface DocumentaryService extends IService<FollowTraderInfoEntity> {
@@ -22,4 +26,22 @@
    FebsResponse traderGetFull(@NotNull(message = "{required}") Long id);
    IPage<FollowTraderLabelEntity> traderLabelList(FollowTraderLabelEntity followTraderLabelEntity, QueryRequest request);
    FebsResponse traderLabelDelete(@NotNull(message = "{required}") Long id);
    void followLabelSetAdd(@Valid FollowTraderLabelEntity followTraderLabelEntity);
    void followLabelSetUpdate(@Valid FollowTraderLabelEntity followTraderLabelEntity);
    FebsResponse modifyProfitRatio(@Valid ModifyProfitRatioDto modifyProfitRatioDto);
    FebsResponse traderGetOn(@NotNull(message = "{required}") Long id);
    FebsResponse traderGetOutFrist(@NotNull(message = "{required}")Long id);
    IPage<FollowTraderProfitInfoEntity> findTraderProfitInfoInfoInPage(FollowTraderProfitInfoEntity followTraderProfitInfoEntity,
                                                                       QueryRequest request);
    IPage<SeeFollowerInfoVo> findlistSeeFollowerInfo(QueryRequest request, FollowTraderProfitInfoEntity followTraderProfitInfoEntity);
}
src/main/java/com/xcong/excoin/modules/documentary/service/impl/DocumentaryServiceImpl.java
@@ -1,16 +1,21 @@
package com.xcong.excoin.modules.documentary.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import com.alibaba.fastjson.JSONObject;
import com.xcong.excoin.common.utils.CoinTypeConvert;
import com.xcong.excoin.common.utils.RedisUtils;
import com.xcong.excoin.modules.documentary.vo.SeeFollowerInfoVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -20,9 +25,14 @@
import com.xcong.excoin.common.entity.FebsResponse;
import com.xcong.excoin.common.entity.QueryRequest;
import com.xcong.excoin.modules.documentary.dto.FollowTraderInfoDto;
import com.xcong.excoin.modules.documentary.dto.ModifyProfitRatioDto;
import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderLabelEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity;
import com.xcong.excoin.modules.documentary.mapper.FollowFollowerProfitMapper;
import com.xcong.excoin.modules.documentary.mapper.FollowTraderInfoMapper;
import com.xcong.excoin.modules.documentary.mapper.FollowTraderLabelMapper;
import com.xcong.excoin.modules.documentary.mapper.FollowTraderProfitInfoMapper;
import com.xcong.excoin.modules.documentary.service.DocumentaryService;
import com.xcong.excoin.modules.member.entity.MemberAuthenticationEntity;
@@ -32,6 +42,7 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -39,25 +50,34 @@
@Service
@RequiredArgsConstructor
public class DocumentaryServiceImpl extends ServiceImpl<FollowTraderInfoMapper, FollowTraderInfoEntity> implements DocumentaryService {
    private final FollowTraderInfoMapper followTraderInfoMapper;
    private final FollowFollowerProfitMapper followFollowerProfitMapper;
    private final FollowTraderLabelMapper followTraderLabelMapper;
    private final MemberAuthenticationMapper memberAuthenticationMapper;
    private final MemberMapper memberMapper;
    private final FollowTraderProfitInfoMapper followTraderProfitInfoMapper;
    private final RedisUtils redisUtils;
    @Override
    public IPage<FollowTraderInfoEntity> findTraderListInPage(FollowTraderInfoEntity followTraderInfoEntity,
            QueryRequest request) {
                                                              QueryRequest request) {
        Page<FollowTraderInfoEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<FollowTraderInfoEntity> followTraderInfoEntitys = followTraderInfoMapper.findTraderListInPage(page, followTraderInfoEntity);
        List<FollowTraderInfoEntity> records = followTraderInfoEntitys.getRecords();
        if(CollUtil.isNotEmpty(records)) {
            for(FollowTraderInfoEntity followTraderInfo : records) {
                //获取当前跟单人数
                Long traderId = followTraderInfo.getId();
                String followNowNumString = followTraderInfoMapper.selectFollowNowBytraderId(traderId);
                followTraderInfo.setFollowNumNow(followNowNumString);
                Long memberId = followTraderInfo.getMemberId();
                Map<String, Object> columnMap = new HashMap<>();
                columnMap.put("member_id", memberId);
@@ -88,7 +108,7 @@
        Integer accountType = memberEntity.getAccountType();
        followTraderInfoEntity.setAccountType(accountType);
        //币币账户
        String walletNum = memberMapper.selectBBZCForBasicRealDataBymemberId(memberId,"USDT");
        String walletNum = memberMapper.selectBBZCForBasicRealDataBymemberId(memberId, "USDT");
        followTraderInfoEntity.setWalletNum(walletNum == null ? 0 : Double.parseDouble(walletNum));
        //合约账户
        String walletCoinNum = memberMapper.selectHYZCForBasicRealDataBymemberId(memberId);
@@ -96,7 +116,7 @@
        //代理账户
        String agentNum = memberMapper.selectDLZCForBasicRealDataBymemberId(memberId);
        followTraderInfoEntity.setAgentNum(agentNum == null ? 0 : Double.parseDouble(agentNum));
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("member_id", memberId);
        List<MemberAuthenticationEntity> selectByMap = memberAuthenticationMapper.selectByMap(columnMap );
@@ -107,7 +127,7 @@
            String realName = firstName + secondName;
            followTraderInfoEntity.setRealName(realName);
        }
        return followTraderInfoEntity;
    }
@@ -118,6 +138,14 @@
        FollowTraderInfoEntity selectById = followTraderInfoMapper.selectById(id);
        if(ObjectUtil.isEmpty(selectById)) {
            return new FebsResponse().fail().message("交易员信息不存在");
        }
        BigDecimal profitRatio = BigDecimal.ZERO;
        String profitRatioStr = followTraderInfoDto.getProfitRatio();
        if(StrUtil.isNotEmpty(profitRatioStr)) {
            profitRatio = new BigDecimal(profitRatioStr);
        }
        if(profitRatio.compareTo(BigDecimal.ZERO) < 0 || profitRatio.compareTo(BigDecimal.ONE) >= 0){
            return new FebsResponse().fail().message("利润率设置规则:只允许0到1之间的小数");
        }
        String isok = followTraderInfoDto.getIsok();
        if("1".equals(isok)) {
@@ -130,6 +158,8 @@
            memberEntity.setIsTrader(1);
            memberMapper.updateById(memberEntity);
            //更新【交易员信息表】数据
            selectById.setProfitRatio(profitRatio);
            selectById.setEntryTime(new Date());
            selectById.setVerifyStatus(FollowTraderInfoEntity.VERIFYSTATUS_Y);
            followTraderInfoMapper.updateById(selectById);
            //新增【交易员收益信息 】数据
@@ -152,6 +182,7 @@
            redisUtils.set("app_" + token, JSONObject.toJSONString(memberEntity), 36000);
        }else {
            //更新【交易员信息表】数据
            selectById.setEntryTime(new Date());
            selectById.setVerifyStatus(FollowTraderInfoEntity.VERIFYSTATUS_N);
            followTraderInfoMapper.updateById(selectById);
        }
@@ -159,12 +190,25 @@
    }
    @Override
    @Transactional
    public FebsResponse traderGetOut(@NotNull(message = "{required}") Long id) {
        FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoMapper.selectById(id);
        if(ObjectUtil.isEmpty(followTraderInfoEntity)) {
            return new FebsResponse().fail().message("交易员信息不存在");
        }
        Long memberId = followTraderInfoEntity.getMemberId();
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("trade_member_id", memberId);
        List<FollowFollowerProfitEntity> selectByMap = followFollowerProfitMapper.selectByMap(columnMap);
        if(CollUtil.isNotEmpty(selectByMap)) {
            for(FollowFollowerProfitEntity FollowFollowerProfitEntity : selectByMap ) {
                FollowFollowerProfitEntity.setIsFollow(FollowFollowerProfitEntity.IS_FOLLOW_N);
                followFollowerProfitMapper.updateById(FollowFollowerProfitEntity);
            }
        }
        followTraderInfoEntity.setVerifyStatus(FollowTraderInfoEntity.VERIFYSTATUS_N);
        followTraderInfoMapper.updateById(followTraderInfoEntity);
        MemberEntity memberEntity = memberMapper.selectById(memberId);
        memberEntity.setIsTrader(2);
        memberMapper.updateById(memberEntity);
@@ -183,4 +227,206 @@
        return new FebsResponse().success();
    }
    @Override
    public IPage<FollowTraderLabelEntity> traderLabelList(FollowTraderLabelEntity followTraderLabelEntity,
                                                          QueryRequest request) {
        Page<FollowTraderLabelEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<FollowTraderLabelEntity> followTraderLabelEntitys = followTraderLabelMapper.findFollowTraderLabelEntitysInPage(page, followTraderLabelEntity);
        return followTraderLabelEntitys;
    }
    @Override
    public FebsResponse traderLabelDelete(@NotNull(message = "{required}") Long id) {
        followTraderLabelMapper.deleteById(id);
        return new FebsResponse().success();
    }
    @Override
    public void followLabelSetAdd(@Valid FollowTraderLabelEntity followTraderLabelEntity) {
        followTraderLabelMapper.insert(followTraderLabelEntity);
    }
    @Override
    public void followLabelSetUpdate(@Valid FollowTraderLabelEntity followTraderLabelEntity) {
        followTraderLabelMapper.updateById(followTraderLabelEntity);
    }
    @Override
    @Transactional
    public FebsResponse modifyProfitRatio(@Valid ModifyProfitRatioDto modifyProfitRatioDto) {
        Long id = modifyProfitRatioDto.getId();
        FollowTraderInfoEntity selectById = followTraderInfoMapper.selectById(id);
        if(ObjectUtil.isEmpty(selectById)) {
            return new FebsResponse().fail().message("交易员信息不存在");
        }
        BigDecimal profitRatio = BigDecimal.ZERO;
        String profitRatioStr = modifyProfitRatioDto.getProfitRatio();
        if(StrUtil.isNotEmpty(profitRatioStr)) {
            profitRatio = new BigDecimal(profitRatioStr);
        }
        if(profitRatio.compareTo(BigDecimal.ZERO) < 0 || profitRatio.compareTo(BigDecimal.ONE) >= 0){
            return new FebsResponse().fail().message("利润率设置规则:只允许0到1之间的小数");
        }
        //最大跟随人数
        boolean matches = isMatches(modifyProfitRatioDto.getFollowNum());
        if(!matches) {
            return new FebsResponse().fail().message("最大跟随人数只能输入正整数");
        }
        Integer followNum = Integer.parseInt(modifyProfitRatioDto.getFollowNum());
        if(ObjectUtil.isEmpty(followNum) || followNum == 0) {
            return new FebsResponse().fail().message("最大跟随人数不能为0");
        }
        String followNumNow = followTraderInfoMapper.selectFollowNowBytraderId(id);
        int parseInt = Integer.parseInt(followNumNow);
        if(parseInt > followNum){
            return new FebsResponse().fail().message("请填写大于当前跟随人数"+parseInt+"的整数");
        }
        //更新【交易员信息表】数据
        selectById.setProfitRatio(profitRatio);
        selectById.setFollowNum(followNum);
        followTraderInfoMapper.updateById(selectById);
        return new FebsResponse().success();
    }
    public boolean isMatches(String bot){
        boolean flag=false;
        try{
            String regex="^[1-9]+[0-9]*$";
            //^[1-9]+\\d*$
            Pattern p=Pattern.compile(regex);
            Matcher m=p.matcher(bot);
            if(m.find()){
                System.out.println("successss");
                return true;
            }else{
                System.out.println("falsss");
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return flag;
    }
    @Override
    public FebsResponse traderGetOn(@NotNull(message = "{required}") Long id) {
        FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoMapper.selectById(id);
        if(ObjectUtil.isEmpty(followTraderInfoEntity)) {
            return new FebsResponse().fail().message("交易员信息不存在");
        }
        followTraderInfoEntity.setIsSetFrist(FollowTraderInfoEntity.IS_SETFRIST_Y);
        followTraderInfoMapper.updateById(followTraderInfoEntity);
        return new FebsResponse().success();
    }
    @Override
    public FebsResponse traderGetOutFrist(@NotNull(message = "{required}") Long id) {
        FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoMapper.selectById(id);
        if(ObjectUtil.isEmpty(followTraderInfoEntity)) {
            return new FebsResponse().fail().message("交易员信息不存在");
        }
        followTraderInfoEntity.setIsSetFrist(FollowTraderInfoEntity.IS_SETFRIST_N);
        followTraderInfoMapper.updateById(followTraderInfoEntity);
        return new FebsResponse().success();
    }
    @Override
    public IPage<FollowTraderProfitInfoEntity> findTraderProfitInfoInfoInPage(
            FollowTraderProfitInfoEntity followTraderProfitInfoEntity, QueryRequest request) {
        Page<FollowTraderProfitInfoEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<FollowTraderProfitInfoEntity> FollowTraderProfitInfoEntitys = followTraderProfitInfoMapper.findTraderProfitInfoInfoInPage(page, followTraderProfitInfoEntity);
        List<FollowTraderProfitInfoEntity> records = FollowTraderProfitInfoEntitys.getRecords();
        if(CollUtil.isNotEmpty(records)) {
            for(FollowTraderProfitInfoEntity followTraderProfitInfo : records) {
                Long traderId = followTraderProfitInfo.getTraderId();
                FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoMapper.selectById(traderId);
                //利润率
                BigDecimal profitRatio = BigDecimal.ZERO;
                //总返利
                BigDecimal profitRatioTotal = BigDecimal.ZERO;
                if(ObjectUtil.isNotEmpty(followTraderInfoEntity)) {
                    profitRatio = followTraderInfoEntity.getProfitRatio();
                    profitRatioTotal = new BigDecimal(followTraderInfoMapper.selectProfitRatioTotal(followTraderInfoEntity.getMemberId())).setScale(2, RoundingMode.HALF_UP);
                }
                followTraderProfitInfo.setProfitRatio(profitRatio);
                followTraderProfitInfo.setProfitRatioTotal(profitRatioTotal);
                Long memberId = followTraderProfitInfo.getMemberId();
                Map<String, Object> columnMap = new HashMap<>();
                columnMap.put("member_id", memberId);
                List<MemberAuthenticationEntity> selectByMap = memberAuthenticationMapper.selectByMap(columnMap );
                if(CollUtil.isNotEmpty(selectByMap)) {
                    MemberAuthenticationEntity memberAuthenticationEntity = selectByMap.get(0);
                    String firstName = memberAuthenticationEntity.getFirstName();
                    String secondName = memberAuthenticationEntity.getSecondName();
                    String realName = firstName + secondName;
                    followTraderProfitInfo.setRealName(realName);
                }
            }
        }
        return FollowTraderProfitInfoEntitys;
    }
    @Override
    public IPage<SeeFollowerInfoVo> findlistSeeFollowerInfo(QueryRequest request, FollowTraderProfitInfoEntity followTraderProfitInfoEntity) {
        Long id = followTraderProfitInfoEntity.getId();
        if(ObjectUtil.isEmpty(id)) {
            return null;
        }
        //获取交易员信息
        FollowTraderProfitInfoEntity FollowTraderProfitInfo = followTraderProfitInfoMapper.selectById(id);
        if(ObjectUtil.isEmpty(FollowTraderProfitInfo)) {
            return null;
        }
        Long traderId = FollowTraderProfitInfo.getTraderId();
        Long traderMemberId = FollowTraderProfitInfo.getMemberId();
        FollowTraderInfoEntity FollowTraderInfo = followTraderInfoMapper.selectById(traderId);
        if(ObjectUtil.isEmpty(FollowTraderInfo)) {
            return null;
        }
        //获取当前的跟随者
        Page<SeeFollowerInfoVo> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<SeeFollowerInfoVo> seeFollowerInfoVos = followFollowerProfitMapper.findFollowFollowerProfitInfo(page, FollowTraderInfo);
        List<SeeFollowerInfoVo> records = seeFollowerInfoVos.getRecords();
        if(CollUtil.isNotEmpty(records)) {
            for(SeeFollowerInfoVo seeFollowerInfoVo : records) {
                long memberId = seeFollowerInfoVo.getMemberId();
                MemberEntity memberEntity = memberMapper.selectById(memberId);
                if(ObjectUtil.isNotEmpty(memberEntity)) {
                    String phone = memberEntity.getPhone();
                    String email = memberEntity.getEmail();
                    String inviteId = memberEntity.getInviteId();
                    seeFollowerInfoVo.setPhone(phone);
                    seeFollowerInfoVo.setEmail(email);
                    seeFollowerInfoVo.setInviteId(inviteId);
                    //合约账户总资产
                    String totalString = memberMapper.selectMemberWalletContractByMemberId(memberId);
                    BigDecimal contractTotal = new BigDecimal(totalString);
                    seeFollowerInfoVo.setContractTotal(contractTotal);
                    //总返利
                    String totalProfitStr = followTraderInfoMapper.selectAllProfitByMemberIdAndTraderMemberId(memberId,traderMemberId);
                    BigDecimal totalProfit = new BigDecimal(totalProfitStr);
                    seeFollowerInfoVo.setProfitTotal(totalProfit);
                    Map<String, Object> columnMap = new HashMap<>();
                    columnMap.put("member_id", memberId);
                    List<MemberAuthenticationEntity> selectByMap = memberAuthenticationMapper.selectByMap(columnMap );
                    if(CollUtil.isNotEmpty(selectByMap)) {
                        MemberAuthenticationEntity memberAuthenticationEntity = selectByMap.get(0);
                        String firstName = memberAuthenticationEntity.getFirstName();
                        String secondName = memberAuthenticationEntity.getSecondName();
                        String realName = firstName + secondName;
                        seeFollowerInfoVo.setRealName(realName);
                    }
                }
            }
        }
        return seeFollowerInfoVos;
    }
}
src/main/java/com/xcong/excoin/modules/documentary/vo/SeeFollowerInfoVo.java
New file
@@ -0,0 +1,30 @@
package com.xcong.excoin.modules.documentary.vo;
import java.math.BigDecimal;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.xcong.excoin.common.utils.BigDecimalSerialize;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "SeeFollowerInfoVo", description = "参数返回类")
public class SeeFollowerInfoVo {
    private long memberId;
    //手机号
    private String phone;
    //邮箱
    private String email;
    //邀请码
    private String inviteId;
    //合约账户总资产
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal contractTotal;
    //总返利
    @JsonSerialize(using = BigDecimalSerialize.class)
    private BigDecimal profitTotal;
    //姓名
    public String realName;
}
src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java
@@ -71,6 +71,12 @@
    public static final int IS_PROFIT_N = 0;
    /**
     * 是否是商户1是2否
     */
    public static final int ISTRADER_Y = 1;
    public static final int ISTRADER_N = 2;
    /**
     * 手机号(包含国际手机号)
     */
    private String phone;
@@ -143,7 +149,6 @@
    /**
     * 是否是交易员1是2否
     */
    @TableField(exist = false)
    private Integer isTrader;
    /**
src/main/java/com/xcong/excoin/modules/member/mapper/MemberMapper.java
@@ -232,4 +232,6 @@
    IPage<MemberEntity> selectDataInfoListSearchs(Page<MemberEntity> page, @Param("record")MemberEntity member);
    MemberEntity selectMemberByAddress(@Param("address")String address);
    String selectMemberWalletContractByMemberId(@Param("memberId")long memberId);
}
src/main/java/com/xcong/excoin/modules/member/mapper/MemberWalletCoinMapper.java
@@ -5,8 +5,12 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity;
import java.math.BigDecimal;
public interface MemberWalletCoinMapper extends BaseMapper<MemberWalletCoinEntity> {
    MemberWalletCoinEntity findWalletCoinByMemberIdAndWalletCode(@Param("memberId")Long memberId, @Param("walletCode")String walletCode);
    int updateBlockBalance(@Param("availableBalance") BigDecimal availableBalance, @Param("id") Long id);
    int reduceFrozenBalance(@Param("amount") BigDecimal amount, @Param("id") Long id);
}
src/main/java/com/xcong/excoin/modules/otc/controller/OtcController.java
New file
@@ -0,0 +1,163 @@
package com.xcong.excoin.modules.otc.controller;
import com.xcong.excoin.common.annotation.ControllerEndpoint;
import com.xcong.excoin.common.controller.BaseController;
import com.xcong.excoin.common.entity.FebsResponse;
import com.xcong.excoin.common.entity.QueryRequest;
import com.xcong.excoin.modules.member.entity.MemberAccountMoneyChangeEntity;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.otc.entity.*;
import com.xcong.excoin.modules.otc.service.OtcService;
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.Map;
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/otc")
public class OtcController extends BaseController {
    private final OtcService otcService;
    /**
     * 获取商户审核列表
     */
    @GetMapping("otcShopList")
    public FebsResponse otcShopList(OtcMarketBussinessEntity otcMarketBussinessEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(otcService.otcShopList(otcMarketBussinessEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 商户审核---通过
     * @return
     */
    @GetMapping("agreeShop/{id}")
    @ControllerEndpoint(operation = "商户审核---通过", exceptionMessage = "通过失败")
    public FebsResponse agreeShop(@NotNull(message = "{required}") @PathVariable Long id) {
        return otcService.agreeShop(id);
    }
    /**
     * 商户审核---拒绝
     * @return
     */
    @GetMapping("disagreeShop/{id}")
    @ControllerEndpoint(operation = "商户审核---通过", exceptionMessage = "通过失败")
    public FebsResponse disagreeShop(@NotNull(message = "{required}") @PathVariable Long id) {
        return otcService.disagreeShop(id);
    }
    /**
     * 订单申诉列表
     */
    @GetMapping("otcAppealList")
    public FebsResponse otcAppealList(OtcOrderAppealEntity otcOrderAppealEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(otcService.otcAppealList(otcOrderAppealEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 申诉---处理中
     * @return
     */
    @GetMapping("dealIng/{id}")
    @ControllerEndpoint(operation = "申诉---处理中", exceptionMessage = "失败")
    public FebsResponse dealIng(@NotNull(message = "{required}") @PathVariable Long id) {
        return otcService.dealIng(id);
    }
    /**
     * 申诉---处理完
     * @return
     */
    @GetMapping("dealDone/{id}")
    @ControllerEndpoint(operation = "申诉---处理完", exceptionMessage = "失败")
    public FebsResponse dealDone(@NotNull(message = "{required}") @PathVariable Long id) {
        return otcService.dealDone(id);
    }
    /**
     * 委托单列表
     */
    @GetMapping("otcEntrustList")
    public FebsResponse otcEntrustList(OtcEntrustOrderEntity otcEntrustOrderEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(otcService.otcEntrustList(otcEntrustOrderEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     *委托单--更新
     * @return
     */
    @PostMapping("otcEntrustConfirm")
    @ControllerEndpoint(operation = "委托单--更新", exceptionMessage = "失败")
    public FebsResponse otcEntrustConfirm(@Valid OtcEntrustOrderEntity otcEntrustOrderEntity) {
        return otcService.otcEntrustConfirm(otcEntrustOrderEntity);
    }
    /**
     * 订单列表
     */
    @GetMapping("otcOrderList")
    public FebsResponse otcOrderList(OtcOrderEntity otcOrderEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(otcService.otcOrderList(otcOrderEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     *订单列表---付款人
     * @return
     */
    @PostMapping("updateOrderInfo")
    @ControllerEndpoint(operation = "订单列表---付款人", exceptionMessage = "失败")
    public FebsResponse updateOrderInfo(@Valid OtcOrderEntity otcOrderEntity) {
        return otcService.updateOrderInfo(otcOrderEntity);
    }
    /**
     *回款
     * @return
     */
    @PostMapping("otcHuiKuan")
    @ControllerEndpoint(operation = "订单列表---付款人", exceptionMessage = "失败")
    public FebsResponse otcHuiKuan(@Valid OtcMarketBussinessEntity otcMarketBussinessEntity) {
        return otcService.otcHuiKuan(otcMarketBussinessEntity);
    }
    /**
     * 设置列表
     */
    @GetMapping("otcSettingList")
    public FebsResponse otcSettingList(OtcSettingEntity otcSettingEntity, QueryRequest request) {
        Map<String, Object> data = getDataTable(otcService.otcSettingList(otcSettingEntity, request));
        return new FebsResponse().success().data(data);
    }
    /**
     *设置列表--更新
     * @return
     */
    @PostMapping("updateOtcSetting")
    @ControllerEndpoint(operation = "设置列表--更新", exceptionMessage = "失败")
    public FebsResponse updateOtcSetting(@Valid OtcSettingEntity otcSettingEntity) {
        return otcService.updateOtcSetting(otcSettingEntity);
    }
    /**
     * 放币
     */
    @PostMapping("/reduceCoin/{id}")
    @ControllerEndpoint(operation = "放币", exceptionMessage = "失败")
    public FebsResponse reduceCoin(@PathVariable("id") Long id) {
        otcService.reduceCoin(id);
        return new FebsResponse().success();
    }
}
src/main/java/com/xcong/excoin/modules/otc/controller/ViewController.java
New file
@@ -0,0 +1,132 @@
package com.xcong.excoin.modules.otc.controller;
import com.xcong.excoin.common.entity.FebsConstant;
import com.xcong.excoin.common.utils.FebsUtil;
import com.xcong.excoin.modules.member.vo.MemberAuthenticationVo;
import com.xcong.excoin.modules.otc.entity.OtcEntrustOrderEntity;
import com.xcong.excoin.modules.otc.entity.OtcMarketBussinessEntity;
import com.xcong.excoin.modules.otc.entity.OtcOrderEntity;
import com.xcong.excoin.modules.otc.entity.OtcSettingEntity;
import com.xcong.excoin.modules.otc.service.OtcService;
import com.xcong.excoin.modules.otc.vo.OtcAppealInfoVo;
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("otcView")
@RequestMapping(FebsConstant.VIEW_PREFIX + "modules/otc")
@RequiredArgsConstructor
public class ViewController {
    private final OtcService otcService;
    /**
     * 获取商户审核列表
     */
    @GetMapping("otcShopList")
    @RequiresPermissions("otcShopList:view")
    public String otcShopList() {
        return FebsUtil.view("modules/otc/otcShopList");
    }
    /**
     * 获取委托单列表
     */
    @GetMapping("otcEntrustList")
    @RequiresPermissions("otcEntrustList:view")
    public String otcEntrustList() {
        return FebsUtil.view("modules/otc/otcEntrustList");
    }
    /**
     * 获取委托单列表--详情
     */
    @GetMapping("otcEntrustListUpdate/{id}")
    @RequiresPermissions("otcEntrustListUpdate:update")
    public String otcEntrustListUpdate(@PathVariable long id, Model model) {
        OtcEntrustOrderEntity data = otcService.otcEntrustListUpdate(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/otc/otcEntrustListUpdate");
    }
    /**
     * 获取订单列表
     */
    @GetMapping("otcOrderList")
    @RequiresPermissions("otcOrderList:view")
    public String otcOrderList() {
        return FebsUtil.view("modules/otc/otcOrderList");
    }
    /**
     * 获取订单列表--详情
     */
    @GetMapping("otcOrderInfo/{id}")
    @RequiresPermissions("otcOrderInfo:update")
    public String otcOrderInfo(@PathVariable long id, Model model) {
        OtcOrderEntity data = otcService.otcOrderInfo(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/otc/otcOrderInfo");
    }
    /**
     * 获取申诉列表
     */
    @GetMapping("otcAppealList")
    @RequiresPermissions("otcAppealList:view")
    public String otcAppealList() {
        return FebsUtil.view("modules/otc/otcAppealList");
    }
    /**
     * 获取申诉列表--详情
     */
    @GetMapping("otcAppealInfo/{id}")
    @RequiresPermissions("otcAppealInfo:update")
    public String otcAppealInfo(@PathVariable long id, Model model) {
        OtcAppealInfoVo data = otcService.otcAppealInfo(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/otc/otcAppealInfo");
    }
    /**
     * 商户回款
     */
    @GetMapping("otcHuiKuan/{id}")
    @RequiresPermissions("otcHuiKuan:update")
    public String otcHuiKuan(@PathVariable long id, Model model) {
        OtcMarketBussinessEntity data = otcService.otcHuiKuan(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/otc/otcHuiKuan");
    }
    /**
     * 获取OTC设置
     */
    @GetMapping("otcSettingList")
    @RequiresPermissions("otcSettingList:view")
    public String otcSettingList() {
        return FebsUtil.view("modules/otc/otcSettingList");
    }
    /**
     * OTC设置--详情
     */
    @GetMapping("otcSettingUpdate/{id}")
    @RequiresPermissions("otcSettingUpdate:update")
    public String otcSettingUpdate(@PathVariable long id, Model model) {
        OtcSettingEntity data = otcService.otcSettingUpdate(id);
        model.addAttribute("member", data);
        return FebsUtil.view("modules/otc/otcSettingUpdate");
    }
}
src/main/java/com/xcong/excoin/modules/otc/entity/OtcEntrustOrderEntity.java
New file
@@ -0,0 +1,70 @@
package com.xcong.excoin.modules.otc.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.entity.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
//otc委托单
@Data
@TableName("otc_entrust_order")
public class OtcEntrustOrderEntity  extends BaseEntity {
    //会员ID
    private long memberId;
    //委托单号
    private String entrustOrderNo;
    //市商ID
    private long mbId;
    //单价
    private BigDecimal unitPrice;
    //数量
    private BigDecimal coinAmount;
    //剩余数量
    private BigDecimal remainCoinAmount;
    //最小限额
    private BigDecimal limitMinAmount;
    //最大限额
    private BigDecimal limitMaxAmount;
    //委托单类型 B-买S-卖
    private String orderType;
    public static final String ORDERTYPE_B = "B";
    public static final String ORDERTYPE_S = "S";
    //上下线 1-上线2-下线 3-取消
    private Integer status;
    public static final Integer STATUS_ONE = 1;
    public static final Integer STATUS_TWO = 2;
    //是否市商 1-是 2-否
    private Integer isMb;
    //委托总金额
    private BigDecimal totalAmount;
    @TableField(exist = false)
    private String account;
    @TableField(exist = false)
    private String phone;
    @TableField(exist = false)
    private String inviteId;
    @TableField(exist = false)
    private String realName;
    @TableField(exist = false)
    private String nikename;
}
src/main/java/com/xcong/excoin/modules/otc/entity/OtcMarketBussinessEntity.java
New file
@@ -0,0 +1,69 @@
package com.xcong.excoin.modules.otc.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.entity.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
//市商信息表
@Data
@TableName("otc_market_bussiness")
public class OtcMarketBussinessEntity extends BaseEntity {
    //会员ID
    private long memberId;
    //昵称
    private String nikename;
    //宣言
    private String declaration;
    //审核状态 1-待审核2-审核通过3-审核拒绝
    private Integer status;
    public static final Integer STATUS_ONE = 1;
    public static final Integer STATUS_TWO = 2;
    public static final Integer STATUS_THREE = 3;
    //服务人数
    private Integer buyCnt;
    //总单数
    private Integer totalOrderCnt;
    //完成率
    private BigDecimal finishRatio;
    //待回款
    private BigDecimal waitBackMoney;
    //已回款
    private BigDecimal hasBackMoney;
    //平均付款时间
    private Integer avgPayTime;
    //平均放币时间
    private Integer avgCoinTime;
    @TableField(exist = false)
    private String account;
    @TableField(exist = false)
    private String phone;
    @TableField(exist = false)
    private String inviteId;
    @TableField(exist = false)
    private String realName;
    /**
     * 本次回款
     */
    @TableField(exist = false)
    private BigDecimal coinAmount;
}
src/main/java/com/xcong/excoin/modules/otc/entity/OtcOrderAppealEntity.java
New file
@@ -0,0 +1,46 @@
package com.xcong.excoin.modules.otc.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.entity.BaseEntity;
import lombok.Data;
//订单申诉表
@Data
@TableName("otc_order_appeal")
public class OtcOrderAppealEntity extends BaseEntity {
    //会员ID
    private long memberId;
    //订单ID
    private long orderId;
    //申诉原因
    private String reason;
    //申诉内容
    private String content;
    //申诉状态  1:待处理 2:处理中 3:已处理
    private Integer status;
    public static final Integer STATUS_ONE = 1;
    public static final Integer STATUS_TWO = 2;
    public static final Integer STATUS_THREE = 3;
    @TableField(exist = false)
    private String account;
    @TableField(exist = false)
    private String phone;
    @TableField(exist = false)
    private String inviteId;
    @TableField(exist = false)
    private String realName;
    @TableField(exist = false)
    private String orderNo;
}
src/main/java/com/xcong/excoin/modules/otc/entity/OtcOrderEntity.java
New file
@@ -0,0 +1,81 @@
package com.xcong.excoin.modules.otc.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.entity.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
//交易订单
@Data
@TableName("otc_order")
public class OtcOrderEntity extends BaseEntity {
    //会员ID
    private long memberId;
    //订单编号
    private String orderNo;
    //单价
    private BigDecimal unitPrice;
    //交易数量
    private BigDecimal coinAmount;
    //交易总额
    private BigDecimal totalAmount;
    //订单状态 1-已提交未付款2-已付款3-已完成4-已取消
    private Integer status;
    public static final Integer STATUS_ONE = 1;
    public static final Integer STATUS_TWO = 2;
    public static final Integer STATUS_THREE = 3;
    public static final Integer STATUS_FOUR = 4;
    //委托单类型 B-买S-卖
    private String orderType;
    public static final String ORDERTYPE_B = "B";
    public static final String ORDERTYPE_S = "S";
    //付款时间
    private Date payTime;
    //完成时间
    private Date finishTime;
    //委托单ID
    private long entrustOrderId;
    //市商ID
    private long mbId;
    //支付市商ID
    private long payMbId;
    //付款人姓名
    private String payName;
    @TableField(exist = false)
    private String account;
    @TableField(exist = false)
    private String phone;
    @TableField(exist = false)
    private String inviteId;
    @TableField(exist = false)
    private String realName;
    @TableField(exist = false)
    private String nickname;
    /**
     * 对面的用户ID
     */
    private Long oppositeMemberId;
}
src/main/java/com/xcong/excoin/modules/otc/entity/OtcSettingEntity.java
New file
@@ -0,0 +1,28 @@
package com.xcong.excoin.modules.otc.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.entity.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
//条件设置
@Data
@TableName("otc_setting")
public class OtcSettingEntity {
    private long id;
    //商家入驻总单数
    private Integer orderNum;
    //商家入驻完成率
    private BigDecimal completionRate;
    //商家入驻总金额
    private BigDecimal totalAmount;
    //今日累计取消次数
    private Integer cancellNum;
}
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcEntrustOrderMapper.java
New file
@@ -0,0 +1,14 @@
package com.xcong.excoin.modules.otc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.otc.entity.OtcEntrustOrderEntity;
import org.apache.ibatis.annotations.Param;
public interface OtcEntrustOrderMapper extends BaseMapper<OtcEntrustOrderEntity> {
    IPage<OtcEntrustOrderEntity> otcEntrustList(Page<OtcEntrustOrderEntity> page,
                                                @Param("record")OtcEntrustOrderEntity otcEntrustOrderEntity);
}
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcMarketBussinessMapper.java
New file
@@ -0,0 +1,14 @@
package com.xcong.excoin.modules.otc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.otc.entity.OtcMarketBussinessEntity;
import org.apache.ibatis.annotations.Param;
public interface OtcMarketBussinessMapper extends BaseMapper<OtcMarketBussinessEntity> {
    IPage<OtcMarketBussinessEntity> otcShopList(Page<OtcMarketBussinessEntity> page,
                                                @Param("record")OtcMarketBussinessEntity otcMarketBussinessEntity);
}
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcOrderAppealMapper.java
New file
@@ -0,0 +1,15 @@
package com.xcong.excoin.modules.otc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.otc.entity.OtcMarketBussinessEntity;
import com.xcong.excoin.modules.otc.entity.OtcOrderAppealEntity;
import org.apache.ibatis.annotations.Param;
public interface OtcOrderAppealMapper extends BaseMapper<OtcOrderAppealEntity> {
    IPage<OtcOrderAppealEntity> otcAppealList(Page<OtcOrderAppealEntity> page,
                                              @Param("record")OtcOrderAppealEntity otcOrderAppealEntity);
}
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcOrderMapper.java
New file
@@ -0,0 +1,15 @@
package com.xcong.excoin.modules.otc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.otc.entity.OtcOrderEntity;
import org.apache.ibatis.annotations.Param;
public interface OtcOrderMapper extends BaseMapper<OtcOrderEntity> {
    IPage<OtcOrderEntity> otcOrderList(Page<OtcOrderEntity> page,
                                       @Param("record")OtcOrderEntity otcOrderEntity);
    int updateOrderStatusByOrderNo(@Param("status") Integer status, @Param("orderNo") String orderNo);
}
src/main/java/com/xcong/excoin/modules/otc/mapper/OtcSettingMapper.java
New file
@@ -0,0 +1,14 @@
package com.xcong.excoin.modules.otc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xcong.excoin.modules.otc.entity.OtcSettingEntity;
import org.apache.ibatis.annotations.Param;
public interface OtcSettingMapper extends BaseMapper<OtcSettingEntity> {
    IPage<OtcSettingEntity> otcSettingList(Page<OtcSettingEntity> page,
                                           @Param("record")OtcSettingEntity otcSettingEntity);
}
src/main/java/com/xcong/excoin/modules/otc/service/OtcService.java
New file
@@ -0,0 +1,49 @@
package com.xcong.excoin.modules.otc.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xcong.excoin.common.entity.FebsResponse;
import com.xcong.excoin.common.entity.QueryRequest;
import com.xcong.excoin.modules.otc.entity.*;
import com.xcong.excoin.modules.otc.vo.OtcAppealInfoVo;
public interface OtcService extends IService<OtcMarketBussinessEntity> {
    IPage<OtcMarketBussinessEntity> otcShopList(OtcMarketBussinessEntity otcMarketBussinessEntity, QueryRequest request);
    FebsResponse agreeShop(Long id);
    FebsResponse disagreeShop(Long id);
    IPage<OtcOrderAppealEntity> otcAppealList(OtcOrderAppealEntity otcOrderAppealEntity, QueryRequest request);
    FebsResponse dealDone(Long id);
    FebsResponse dealIng(Long id);
    IPage<OtcEntrustOrderEntity> otcEntrustList(OtcEntrustOrderEntity otcEntrustOrderEntity, QueryRequest request);
    IPage<OtcOrderEntity> otcOrderList(OtcOrderEntity otcOrderEntity, QueryRequest request);
    OtcAppealInfoVo otcAppealInfo(long id);
    OtcOrderEntity otcOrderInfo(long id);
    FebsResponse updateOrderInfo(OtcOrderEntity otcOrderEntity);
    OtcMarketBussinessEntity otcHuiKuan(long id);
    FebsResponse otcHuiKuan(OtcMarketBussinessEntity otcMarketBussinessEntity);
    IPage<OtcSettingEntity> otcSettingList(OtcSettingEntity otcSettingEntity, QueryRequest request);
    OtcSettingEntity otcSettingUpdate(long id);
    FebsResponse updateOtcSetting(OtcSettingEntity otcSettingEntity);
    int reduceCoin(Long id);
    OtcEntrustOrderEntity otcEntrustListUpdate(long id);
    FebsResponse otcEntrustConfirm(OtcEntrustOrderEntity otcEntrustOrderEntity);
}
src/main/java/com/xcong/excoin/modules/otc/service/impl/OtcServiceImpl.java
New file
@@ -0,0 +1,360 @@
package com.xcong.excoin.modules.otc.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
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 com.xcong.excoin.common.entity.FebsResponse;
import com.xcong.excoin.common.entity.QueryRequest;
import com.xcong.excoin.modules.member.entity.MemberAccountMoneyChangeEntity;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity;
import com.xcong.excoin.modules.member.mapper.MemberMapper;
import com.xcong.excoin.modules.member.mapper.MemberWalletCoinMapper;
import com.xcong.excoin.modules.otc.entity.*;
import com.xcong.excoin.modules.otc.mapper.*;
import com.xcong.excoin.modules.otc.service.OtcService;
import com.xcong.excoin.modules.otc.vo.OtcAppealInfoVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@Service
@RequiredArgsConstructor
public class OtcServiceImpl extends ServiceImpl<OtcMarketBussinessMapper, OtcMarketBussinessEntity> implements OtcService {
    @Resource
    private OtcMarketBussinessMapper otcMarketBussinessMapper;
    @Resource
    private OtcOrderAppealMapper otcOrderAppealMapper;
    @Resource
    private OtcEntrustOrderMapper otcEntrustOrderMapper;
    @Resource
    private OtcOrderMapper otcOrderMapper;
    @Resource
    private OtcSettingMapper otcSettingMapper;
    @Resource
    private MemberWalletCoinMapper memberWalletCoinMapper;
    @Resource
    private MemberMapper memberMapper;
    @Override
    public IPage<OtcMarketBussinessEntity> otcShopList(OtcMarketBussinessEntity otcMarketBussinessEntity, QueryRequest request) {
        Page<OtcMarketBussinessEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<OtcMarketBussinessEntity> otcMarketBussinessEntitys = otcMarketBussinessMapper.otcShopList(page, otcMarketBussinessEntity);
        return otcMarketBussinessEntitys;
    }
    @Override
    @Transactional
    public FebsResponse agreeShop(Long id) {
        OtcMarketBussinessEntity otcMarketBussinessEntity = otcMarketBussinessMapper.selectById(id);
        Integer status = otcMarketBussinessEntity.getStatus();
        if(OtcMarketBussinessEntity.STATUS_ONE != status){
            return new FebsResponse().fail().message("当前状态不是待审核");
        }
        otcMarketBussinessEntity.setStatus(OtcMarketBussinessEntity.STATUS_TWO);
        otcMarketBussinessMapper.updateById(otcMarketBussinessEntity);
        long memberId = otcMarketBussinessEntity.getMemberId();
        MemberEntity memberEntity = memberMapper.selectById(memberId);
        memberEntity.setIsTrader(MemberEntity.ISTRADER_Y);
        memberMapper.updateById(memberEntity);
        return new FebsResponse().success();
    }
    @Override
    @Transactional
    public FebsResponse disagreeShop(Long id) {
        OtcMarketBussinessEntity otcMarketBussinessEntity = otcMarketBussinessMapper.selectById(id);
        Integer status = otcMarketBussinessEntity.getStatus();
        if(OtcMarketBussinessEntity.STATUS_ONE != status){
            return new FebsResponse().fail().message("当前状态不是待审核");
        }
        otcMarketBussinessEntity.setStatus(OtcMarketBussinessEntity.STATUS_THREE);
        otcMarketBussinessMapper.updateById(otcMarketBussinessEntity);
        long memberId = otcMarketBussinessEntity.getMemberId();
        MemberEntity memberEntity = memberMapper.selectById(memberId);
        memberEntity.setIsTrader(MemberEntity.ISTRADER_Y);
        memberMapper.updateById(memberEntity);
        return new FebsResponse().success();
    }
    @Override
    public IPage<OtcOrderAppealEntity> otcAppealList(OtcOrderAppealEntity otcOrderAppealEntity, QueryRequest request) {
        Page<OtcOrderAppealEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<OtcOrderAppealEntity> otcOrderAppealEntitys = otcOrderAppealMapper.otcAppealList(page, otcOrderAppealEntity);
        return otcOrderAppealEntitys;
    }
    @Override
    @Transactional
    public FebsResponse dealDone(Long id) {
        OtcOrderAppealEntity otcOrderAppealEntity = otcOrderAppealMapper.selectById(id);
        Integer status = otcOrderAppealEntity.getStatus();
        if(OtcOrderAppealEntity.STATUS_TWO != status){
            return new FebsResponse().fail().message("当前状态不是处理中");
        }
        otcOrderAppealEntity.setStatus(OtcOrderAppealEntity.STATUS_THREE);
        otcOrderAppealMapper.updateById(otcOrderAppealEntity);
        return new FebsResponse().success();
    }
    @Override
    @Transactional
    public FebsResponse dealIng(Long id) {
        OtcOrderAppealEntity otcOrderAppealEntity = otcOrderAppealMapper.selectById(id);
        Integer status = otcOrderAppealEntity.getStatus();
        if(OtcOrderAppealEntity.STATUS_ONE != status){
            return new FebsResponse().fail().message("当前状态不是待处理");
        }
        otcOrderAppealEntity.setStatus(OtcOrderAppealEntity.STATUS_TWO);
        otcOrderAppealMapper.updateById(otcOrderAppealEntity);
        return new FebsResponse().success();
    }
    @Override
    public IPage<OtcEntrustOrderEntity> otcEntrustList(OtcEntrustOrderEntity otcEntrustOrderEntity, QueryRequest request) {
        Page<OtcEntrustOrderEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<OtcEntrustOrderEntity> otcEntrustOrderEntitys = otcEntrustOrderMapper.otcEntrustList(page, otcEntrustOrderEntity);
        return otcEntrustOrderEntitys;
    }
    @Override
    public IPage<OtcOrderEntity> otcOrderList(OtcOrderEntity otcOrderEntity, QueryRequest request) {
        Page<OtcOrderEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<OtcOrderEntity> otcOrderEntitys = otcOrderMapper.otcOrderList(page, otcOrderEntity);
        return otcOrderEntitys;
    }
    @Override
    public OtcAppealInfoVo otcAppealInfo(long id) {
        OtcAppealInfoVo otcAppealInfoVo = new OtcAppealInfoVo();
        OtcOrderAppealEntity otcOrderAppealEntity = otcOrderAppealMapper.selectById(id);
        otcAppealInfoVo.setId(id);
        if(ObjectUtil.isNotEmpty(otcOrderAppealEntity)){
            String reason = otcOrderAppealEntity.getReason();
            otcAppealInfoVo.setReason(reason);
            String content = otcOrderAppealEntity.getContent();
            List arr = Arrays.asList(content.split(","));
            otcAppealInfoVo.setContent(arr);
        }
        //获取对应的订单详情
        long orderId = otcOrderAppealEntity.getOrderId();
        OtcOrderEntity otcOrderEntity = otcOrderMapper.selectById(orderId);
        if(ObjectUtil.isNotEmpty(otcOrderEntity)){
            String orderNo = otcOrderEntity.getOrderNo();
            otcAppealInfoVo.setOrderNo(orderNo);
            BigDecimal unitPrice = otcOrderEntity.getUnitPrice();
            otcAppealInfoVo.setUnitPrice(unitPrice);
            BigDecimal coinAmount = otcOrderEntity.getCoinAmount();
            otcAppealInfoVo.setCoinAmount(coinAmount);
            BigDecimal totalAmount = otcOrderEntity.getTotalAmount();
            otcAppealInfoVo.setTotalAmount(totalAmount);
            Integer status = otcOrderEntity.getStatus();
            otcAppealInfoVo.setStatus(status);
            Date payTime = otcOrderEntity.getPayTime();
            otcAppealInfoVo.setPayTime(payTime);
            Date finishTime = otcOrderEntity.getFinishTime();
            otcAppealInfoVo.setFinishTime(finishTime);
        }
        //获取对应的商户信息
        long payMdId = otcOrderEntity.getPayMbId();
        OtcMarketBussinessEntity otcMarketBussinessEntity = otcMarketBussinessMapper.selectById(payMdId);
        if(ObjectUtil.isNotEmpty(otcMarketBussinessEntity)){
            String nikename = otcMarketBussinessEntity.getNikename();
            otcAppealInfoVo.setNikename(nikename);
        }
        return otcAppealInfoVo;
    }
    @Override
    public OtcOrderEntity otcOrderInfo(long id) {
        OtcOrderEntity otcOrderEntity = otcOrderMapper.selectById(id);
        return otcOrderEntity;
    }
    @Override
    @Transactional
    public FebsResponse updateOrderInfo(OtcOrderEntity otcOrderEntity) {
        Long id = otcOrderEntity.getId();
        OtcOrderEntity otcOrder = otcOrderMapper.selectById(id);
        if(ObjectUtil.isEmpty(otcOrder)){
            return new FebsResponse().fail().message("连接超时,请刷新页面重试");
        }
        Integer status = otcOrder.getStatus();
        if(OtcOrderEntity.STATUS_ONE != status){
            return new FebsResponse().fail().message("当前订单不是待付款状态");
        }
        String payName = otcOrderEntity.getPayName();
        if(StrUtil.isEmpty(payName)){
            return new FebsResponse().fail().message("请输入付款人");
        }
        BigDecimal coinAmount = otcOrderEntity.getCoinAmount();
        /**
         * 获取订单信息--订单编号
         *      获取买单和买单
         *      更新payName字段
         *      更新订单状态
         */
        QueryWrapper<OtcOrderEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no",otcOrder.getOrderNo());
        List<OtcOrderEntity> list = otcOrderMapper.selectList(queryWrapper);
        if(CollUtil.isNotEmpty(list)){
            for(OtcOrderEntity order : list){
                order.setStatus(OtcOrderEntity.STATUS_TWO);
                order.setPayName(payName);
                order.setPayTime(DateUtil.date());
                otcOrderMapper.updateById(order);
            }
        }
        return new FebsResponse().success();
    }
    @Override
    public OtcMarketBussinessEntity otcHuiKuan(long id) {
        return otcMarketBussinessMapper.selectById(id);
    }
    @Override
    @Transactional
    public FebsResponse otcHuiKuan(OtcMarketBussinessEntity otcMarketBussinessEntity) {
        Long id = otcMarketBussinessEntity.getId();
        OtcMarketBussinessEntity otcMarketBussiness = otcMarketBussinessMapper.selectById(id);
        if(ObjectUtil.isNotEmpty(otcMarketBussiness)){
            return new FebsResponse().fail().message("连接超时,请刷新页面重试");
        }
        BigDecimal coinAmount = otcMarketBussinessEntity.getCoinAmount();
        if(coinAmount.compareTo(BigDecimal.ZERO) <= 0){
            return new FebsResponse().fail().message("请输入正确的回款金额");
        }
        BigDecimal waitBackMoney = otcMarketBussiness.getWaitBackMoney();
        if(coinAmount.compareTo(waitBackMoney) > 0){
            return new FebsResponse().fail().message("请输入正确的回款金额");
        }
        /**
         * 增加已回款金额
         * 减少待回款金额
         * 增加汇款记录
         */
        BigDecimal hasBackMoney = otcMarketBussiness.getHasBackMoney();
        BigDecimal add = hasBackMoney.add(coinAmount);
        otcMarketBussiness.setHasBackMoney(add);
        BigDecimal subtract = waitBackMoney.subtract(coinAmount);
        otcMarketBussiness.setWaitBackMoney(subtract);
        otcMarketBussinessMapper.updateById(otcMarketBussiness);
        return new FebsResponse().success();
    }
    @Override
    public IPage<OtcSettingEntity> otcSettingList(OtcSettingEntity otcSettingEntity, QueryRequest request) {
        Page<OtcSettingEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<OtcSettingEntity> otcSettingEntitys = otcSettingMapper.otcSettingList(page, otcSettingEntity);
        return otcSettingEntitys;
    }
    @Override
    public OtcSettingEntity otcSettingUpdate(long id) {
        return otcSettingMapper.selectById(id);
    }
    @Override
    public FebsResponse updateOtcSetting(OtcSettingEntity otcSettingEntity) {
        Integer orderNum = otcSettingEntity.getOrderNum();
        if(ObjectUtil.isEmpty(orderNum) || orderNum < 0){
            return new FebsResponse().fail().message("请设置正确的总单数");
        }
        BigDecimal completionRate = otcSettingEntity.getCompletionRate();
        if(ObjectUtil.isEmpty(completionRate) || completionRate.compareTo(BigDecimal.ZERO) < 0){
            return new FebsResponse().fail().message("请设置正确的完成率");
        }
        BigDecimal totalAmount = otcSettingEntity.getTotalAmount();
        if(ObjectUtil.isEmpty(totalAmount) || totalAmount.compareTo(BigDecimal.ZERO) < 0){
            return new FebsResponse().fail().message("请设置正确的总金额");
        }
        Integer cancellNum = otcSettingEntity.getCancellNum();
        if(ObjectUtil.isEmpty(cancellNum) || cancellNum < 0){
            return new FebsResponse().fail().message("请设置正确的取消次数");
        }
        otcSettingMapper.updateById(otcSettingEntity);
        return new FebsResponse().success();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int reduceCoin(Long id) {
        OtcOrderEntity order = otcOrderMapper.selectById(id);
        MemberWalletCoinEntity saleWallet = memberWalletCoinMapper.findWalletCoinByMemberIdAndWalletCode(order.getMemberId(), "USDT");
        MemberWalletCoinEntity buyWallet = memberWalletCoinMapper.findWalletCoinByMemberIdAndWalletCode(order.getOppositeMemberId(), "USDT");
        memberWalletCoinMapper.updateBlockBalance(order.getCoinAmount(), buyWallet.getId());
        memberWalletCoinMapper.reduceFrozenBalance(order.getCoinAmount(), saleWallet.getId());
        otcOrderMapper.updateOrderStatusByOrderNo(OtcOrderEntity.STATUS_THREE, order.getOrderNo());
        return 1;
    }
    @Override
    public OtcEntrustOrderEntity otcEntrustListUpdate(long id) {
        return otcEntrustOrderMapper.selectById(id);
    }
    @Override
    public FebsResponse otcEntrustConfirm(OtcEntrustOrderEntity otcEntrustOrderEntity) {
        Long id = otcEntrustOrderEntity.getId();
        OtcEntrustOrderEntity otcEntrustOrder = otcEntrustOrderMapper.selectById(id);
        BigDecimal unitPrice = otcEntrustOrderEntity.getUnitPrice();
        if(ObjectUtil.isEmpty(unitPrice) || unitPrice.compareTo(BigDecimal.ZERO) < 0){
            return new FebsResponse().fail().message("请设置正确的单价");
        }
        otcEntrustOrder.setUnitPrice(unitPrice);
        BigDecimal coinAmount = otcEntrustOrderEntity.getCoinAmount();
        if(ObjectUtil.isEmpty(coinAmount) || coinAmount.compareTo(BigDecimal.ZERO) < 0){
            return new FebsResponse().fail().message("请设置正确的数量");
        }
        otcEntrustOrder.setCoinAmount(coinAmount);
        BigDecimal totalAmount = coinAmount.multiply(unitPrice);
        otcEntrustOrder.setTotalAmount(totalAmount);
        BigDecimal remainCoinAmount = otcEntrustOrderEntity.getRemainCoinAmount();
        if(ObjectUtil.isEmpty(remainCoinAmount) || remainCoinAmount.compareTo(BigDecimal.ZERO) < 0
                || totalAmount.compareTo(remainCoinAmount) < 0){
            return new FebsResponse().fail().message("请设置正确的剩余数量");
        }
        otcEntrustOrder.setRemainCoinAmount(remainCoinAmount);
        BigDecimal limitMinAmount = otcEntrustOrderEntity.getLimitMinAmount();
        if(ObjectUtil.isEmpty(limitMinAmount) || limitMinAmount.compareTo(BigDecimal.ZERO) < 0){
            return new FebsResponse().fail().message("请设置正确的最小限额");
        }
        otcEntrustOrder.setLimitMinAmount(limitMinAmount);
        BigDecimal limitMaxAmount = otcEntrustOrderEntity.getLimitMaxAmount();
        if(ObjectUtil.isEmpty(limitMaxAmount) || limitMaxAmount.compareTo(BigDecimal.ZERO) < 0
                || limitMaxAmount.compareTo(limitMinAmount) < 0 || totalAmount.compareTo(limitMaxAmount) < 0){
            return new FebsResponse().fail().message("请设置正确的最大限额");
        }
        otcEntrustOrder.setLimitMaxAmount(limitMaxAmount);
        otcEntrustOrder.setStatus(otcEntrustOrderEntity.getStatus());
        otcEntrustOrderMapper.updateById(otcEntrustOrder);
        return new FebsResponse().success();
    }
}
src/main/java/com/xcong/excoin/modules/otc/vo/OtcAppealInfoVo.java
New file
@@ -0,0 +1,59 @@
package com.xcong.excoin.modules.otc.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
@ApiModel(value = "OtcAppealInfoVo", description = "参数返回类")
public class OtcAppealInfoVo {
    private long id;
    //订单编号
    private String orderNo;
    //单价
    private BigDecimal unitPrice;
    //交易数量
    private BigDecimal coinAmount;
    //交易总额
    private BigDecimal totalAmount;
    //订单状态 1-已提交未付款2-已付款3-已完成4-已取消
    private Integer status;
    public static final Integer STATUS_ONE = 1;
    public static final Integer STATUS_TWO = 2;
    public static final Integer STATUS_THREE = 3;
    public static final Integer STATUS_FOUR = 4;
    //付款时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date payTime;
    //完成时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date finishTime;
    //昵称
    private String nikename;
    //申诉原因
    private String reason;
    //申诉图片
    private List<String> content;
}
src/main/resources/mapper/modules/FollowFollowerProfitMapper.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="com.xcong.excoin.modules.documentary.mapper.FollowFollowerProfitMapper">
    <select id="findFollowFollowerProfitInfo" resultType="com.xcong.excoin.modules.documentary.vo.SeeFollowerInfoVo">
        select * from follow_follower_profit s left join member m on m.id = s.member_id
        where s.trade_id = #{record.id} and s.trade_member_id = #{record.memberId}
        order by s.create_time desc
    </select>
</mapper>
src/main/resources/mapper/modules/FollowTraderInfoMapper.xml
@@ -2,19 +2,31 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.modules.documentary.mapper.FollowTraderInfoMapper">
    <select id="findTraderListInPage" resultType="com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity">
         select * from follow_trader_info s left join member m on m.id = s.member_id
         <where>
            <if test="record != null" >
    <select id="findTraderListInPage" resultType="com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity">
        select * from follow_trader_info s left join member m on m.id = s.member_id
        <where>
            <if test="record != null" >
                <if test="record.account!=null and record.account!=''">
                     and (m.phone = #{record.account} or m.email = #{record.account} or m.invite_id=#{record.account})
                    and (m.phone = #{record.account} or m.email = #{record.account} or m.invite_id=#{record.account})
                </if>
                <if test="record.verifyStatus!=null and record.verifyStatus!=''">
                    and s.verify_status= #{record.verifyStatus}
                </if>
            </if>
        </where>
        order by s.create_time desc
    </select>
        </where>
        order by s.create_time desc
    </select>
    <select id="selectFollowNowBytraderId" resultType="java.lang.String">
        select COUNT(a.id) from follow_follower_setting a where a.trader_id = #{traderId}
    </select>
    <select id="selectProfitRatioTotal" resultType="java.lang.String">
        select IFNULL(SUM(f.amount),'0') as amount from follow_trader_profit_detail f where f.member_id = #{memberId}
    </select>
    <select id="selectAllProfitByMemberIdAndTraderMemberId" resultType="java.lang.String">
        select IFNULL(SUM(f.amount),'0') as amount from follow_trader_profit_detail f where f.member_id = #{traderMemberId} and f.follow_member_id = #{memberId}
    </select>
</mapper>
src/main/resources/mapper/modules/FollowTraderLabelMapper.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="com.xcong.excoin.modules.documentary.mapper.FollowTraderLabelMapper">
    <select id="findFollowTraderLabelEntitysInPage" resultType="com.xcong.excoin.modules.documentary.entity.FollowTraderLabelEntity">
         select * from follow_trader_label s
    </select>
</mapper>
src/main/resources/mapper/modules/FollowTraderProfitInfoMapper.xml
@@ -2,5 +2,18 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.modules.documentary.mapper.FollowTraderProfitInfoMapper">
    <select id="findTraderProfitInfoInfoInPage" resultType="com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity">
        select * from follow_trader_profit_info t
        left join follow_trader_info s on s.id = t.trader_id
        left join member m on m.id = t.member_id
        <where>
            <if test="record != null" >
                <if test="record.account!=null and record.account!=''">
                    and (m.phone = #{record.account} or m.email = #{record.account} or m.invite_id=#{record.account})
                </if>
            </if>
        </where>
        order by s.create_time desc
    </select>
</mapper>
src/main/resources/mapper/modules/MemberMapper.xml
@@ -1512,5 +1512,13 @@
                        or m.phone = #{address}
                        or m.email = #{address}
    </select>
    <select id="selectMemberWalletContractByMemberId" resultType="java.lang.String">
        SELECT
            total_balance
        FROM
            member_wallet_contract where member_id = #{memberId}
    </select>
</mapper>
src/main/resources/mapper/modules/MemberWalletCoinMapper.xml
@@ -7,4 +7,20 @@
        select * from member_wallet_coin where member_id = #{memberId} and wallet_code = #{walletCode}
    </select>
    <update id="updateBlockBalance">
        update member_wallet_coin
        set
            available_balance = IFNULL(available_balance, 0) + #{availableBalance},
            total_balance = IFNULL(total_balance, 0) + #{availableBalance}
        where id=#{id}
    </update>
    <update id="reduceFrozenBalance">
        update member_wallet_coin
        set frozen_balance = frozen_balance - #{amount},
            total_balance = total_balance - #{amount}
        where id=#{id}
    </update>
</mapper>
src/main/resources/mapper/modules/OtcEntrustOrderMapper.xml
New file
@@ -0,0 +1,29 @@
<?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="com.xcong.excoin.modules.otc.mapper.OtcEntrustOrderMapper">
    <select id="otcEntrustList" resultType="com.xcong.excoin.modules.otc.entity.OtcEntrustOrderEntity">
        SELECT
        *,
        concat(b.first_name,b.second_name) realName
        FROM
        otc_entrust_order a
        LEFT JOIN member m ON m.id = a.member_id
        LEFT JOIN member_authentication b ON b.member_id = a.member_id
        <where>
            <if test="record != null" >
                <if test="record.account!=null and record.account!=''">
                    and (m.phone = #{record.account} or m.email = #{record.account} or m.invite_id=#{record.account})
                </if>
                <if test="record.orderType!=null and record.orderType!=''">
                    and a.order_type= #{record.orderType}
                </if>
                <if test="record.status!=null and record.status!=''">
                    and a.status= #{record.status}
                </if>
            </if>
        </where>
        order by m.create_time desc
    </select>
</mapper>
src/main/resources/mapper/modules/OtcMarketBussinessMapper.xml
New file
@@ -0,0 +1,26 @@
<?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="com.xcong.excoin.modules.otc.mapper.OtcMarketBussinessMapper">
    <select id="otcShopList" resultType="com.xcong.excoin.modules.otc.entity.OtcMarketBussinessEntity">
        SELECT
        *,
        concat(b.first_name,b.second_name) realName
        FROM
        otc_market_bussiness a
        LEFT JOIN member m ON m.id = a.member_id
        LEFT JOIN member_authentication b ON b.member_id = a.member_id
        <where>
            <if test="record != null" >
                <if test="record.account!=null and record.account!=''">
                    and (m.phone = #{record.account} or m.email = #{record.account} or m.invite_id=#{record.account})
                </if>
                <if test="record.status!=null and record.status!=''">
                    and a.status= #{record.status}
                </if>
            </if>
        </where>
        order by m.create_time desc
    </select>
</mapper>
src/main/resources/mapper/modules/OtcOrderAppealMapper.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="com.xcong.excoin.modules.otc.mapper.OtcOrderAppealMapper">
    <select id="otcAppealList" resultType="com.xcong.excoin.modules.otc.entity.OtcOrderAppealEntity">
        SELECT
        *,
        concat(b.first_name,b.second_name) realName
        FROM
        otc_order_appeal a
        LEFT JOIN member m ON m.id = a.member_id
        LEFT JOIN member_authentication b ON b.member_id = a.member_id
        LEFT JOIN otc_order c ON c.id = a.order_id
        <where>
            <if test="record != null" >
                <if test="record.account!=null and record.account!=''">
                    and (m.phone = #{record.account} or m.email = #{record.account} or m.invite_id=#{record.account})
                </if>
                <if test="record.status!=null and record.status!=''">
                    and a.status= #{record.status}
                </if>
            </if>
        </where>
        order by m.create_time desc
    </select>
</mapper>
src/main/resources/mapper/modules/OtcOrderMapper.xml
New file
@@ -0,0 +1,31 @@
<?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="com.xcong.excoin.modules.otc.mapper.OtcOrderMapper">
    <select id="otcOrderList" resultType="com.xcong.excoin.modules.otc.entity.OtcOrderEntity">
        SELECT
        *,
        concat(b.first_name,b.second_name) realName
        FROM
        otc_order a
        LEFT JOIN member m ON m.id = a.member_id
        LEFT JOIN member_authentication b ON b.member_id = a.member_id
        <where>
            <if test="record != null" >
                <if test="record.account!=null and record.account!=''">
                    and (m.phone = #{record.account} or m.email = #{record.account} or m.invite_id=#{record.account})
                </if>
                <if test="record.status!=null and record.status!=''">
                    and a.status= #{record.status}
                </if>
            </if>
        </where>
        order by a.create_time desc
    </select>
    <update id="updateOrderStatusByOrderNo">
        update otc_order
            set status=#{status}
        where order_no=#{orderNo}
    </update>
</mapper>
src/main/resources/mapper/modules/OtcSettingMapper.xml
New file
@@ -0,0 +1,12 @@
<?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="com.xcong.excoin.modules.otc.mapper.OtcSettingMapper">
    <select id="otcSettingList" resultType="com.xcong.excoin.modules.otc.entity.OtcSettingEntity">
        SELECT
        *
        FROM
        otc_setting
    </select>
</mapper>
src/main/resources/templates/febs/views/modules/documentary/followLabelSet.html
New file
@@ -0,0 +1,127 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-user" 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="userTable" lay-data="{id: 'userTable'}"></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>
    <button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit" shiro:hasPermission="user:update">编辑
        <i class="layui-icon febs-edit-area febs-blue"></i>
    </button>
    <button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="delete" shiro:hasPermission="user:update">删除
        <i class="layui-icon febs-edit-area febs-blue"></i>
    </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-user'),
            $reset = $view.find('#reset'),
            $add = $view.find('#add'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'title', type: null},
            tableIns
            ;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'edit') {
                febs.modal.open('修改', 'modules/documentary/followLabelSetUpdate/' + data.id, {
                    btn: ['提交', '取消'],
                    yes: function (index, layero) {
                        $('#user-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 + 'documentary/traderLabelDelete/' + 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('新增', 'modules/documentary/followLabelSetAdd/', {
                btn: ['提交', '取消'],
                yes: function (index, layero) {
                    $('#user-add').find('#submit').trigger('click');
                },
                btn2: function () {
                    layer.closeAll();
                }
            });
        });
         // 获取查询参数
        function getQueryParams() {
            return {};
        }
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'userTable',
                url: ctx + 'documentary/traderLabelList',
                cols: [[
                    {field: 'id', title: '', minWidth: 10,align:'center'},
                    {field: 'labels', title: '更新内容', minWidth: 120,align:'center'},
                    {title: '操作', toolbar: '#user-option', minWidth: 140, fixed : 'right'}
                ]]
            });
        }
    })
</script>
src/main/resources/templates/febs/views/modules/documentary/followLabelSetAdd.html
New file
@@ -0,0 +1,67 @@
<style>
    #user-add {
        padding: 20px 25px 25px 0;
    }
    #user-add .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-add #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="user-add">
    <form class="layui-form" action="" lay-filter="user-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="labels" lay-verify="range|labels"
                        autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="user-add-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            $view = $('#user-add'),
            validate = layui.validate,
            _deptTree;
        form.render();
        formSelects.render();
        form.on('submit(user-add-form-submit)', function (data) {
            febs.post(ctx + 'documentary/followLabelSetAdd', data.field, function () {
                layer.closeAll();
                febs.alert.success('新增成功');
                $('#febs-user').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/documentary/followLabelSetDetail.html
New file
@@ -0,0 +1,77 @@
<style>
    #user-update {
        padding: 20px 25px 25px 0;
    }
    #user-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-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="user-update">
    <form class="layui-form" action="" lay-filter="user-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="labels" data-th-id="${member.labels}"  lay-verify="range|labels"
                        autocomplete="off" class="layui-input" >
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="user-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#user-update'),
            validate = layui.validate,
            _deptTree;
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            form.val("user-update-form", {
                "labels": member.labels,
                "id": member.id
            });
        }
        form.on('submit(user-update-form-submit)', function (data) {
            febs.post(ctx + 'documentary/followLabelSetUpdate', data.field, function () {
                layer.closeAll();
                febs.alert.success('设置成功');
                $('#febs-user').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/documentary/modifyProfitRatio.html
New file
@@ -0,0 +1,122 @@
<style>
    #user-update {
        padding: 20px 25px 25px 0;
    }
    #user-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-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="user-update">
    <form class="layui-form" action="" lay-filter="user-update-form">
        <div class="layui-form-item">
            <div style="text-align: center;color:red">
                利润率设置规则:只允许0到1之间的小数
            </div>
        </div>
        <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">利润率:</label>
            <div class="layui-input-block">
                <input type="text" name="profitRatio" data-th-id="${member.profitRatio}"
                       lay-verify="range|profitRatio" autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <div style="text-align: center;color:red">
                最大跟随人数规则:请填写大于0的整数
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">跟随人数:</label>
            <div class="layui-input-block">
                <input type="text" name="followNum" data-th-id="${member.followNum}"
                       lay-verify="range|followNum" autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">币币账户总余额:</label>
            <div class="layui-input-block">
                <input type="text" name="walletNum" minlength="4" maxlength="10" data-th-id="${member.walletNum}"
                       lay-verify="range|walletNum" autocomplete="off" class="layui-input" readonly>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">合约账户总余额:</label>
            <div class="layui-input-block">
                <input type="text" name="walletCoinNum" minlength="4" maxlength="10" data-th-id="${member.walletCoinNum}"
                       lay-verify="range|walletCoinNum" autocomplete="off" class="layui-input" readonly>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">币币账户总余额:</label>
            <div class="layui-input-block">
                <input type="text" name="agentNum" minlength="4" maxlength="10" data-th-id="${member.agentNum}"
                       lay-verify="range|agentNum" autocomplete="off" class="layui-input" readonly>
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="user-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#user-update'),
            validate = layui.validate,
            _deptTree;
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            form.val("user-update-form", {
                "id": member.id,
                "profitRatio": member.profitRatio,
                "realName": member.realName,
                "phone": member.phone,
                "email": member.email,
                "agentNum": member.agentNum,
                "walletCoinNum": member.walletCoinNum,
                "walletNum": member.walletNum,
                "followNum": member.followNum
            });
        }
        form.on('submit(user-update-form-submit)', function (data) {
            febs.post(ctx + 'documentary/modifyProfitRatio', data.field, function () {
                layer.closeAll();
                febs.alert.success('修改成功');
                $('#febs-user').find('#query').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/documentary/seeFollowerInfo.html
New file
@@ -0,0 +1,58 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-user-child" 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">
                    <table lay-filter="userTableChild" lay-data="{id: 'userTableChild'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<script data-th-inline="none" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'laydate', 'form', 'table', 'febs', 'treeSelect' ,'eleTree'], function () {
        var $ = layui.jquery,
            laydate = layui.laydate,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            treeSelect = layui.treeSelect,
            dropdown = layui.dropdown,
            $view = $('#febs-user-child'),
            $query = $view.find('#queryChild'),
            $searchForm = $view.find('formChild'),
            sortObject = {field: 'createTime', type: null},
            tableIns,
            createTimeFrom,
            createTimeTo;
        form.render();
        initTable();
        laydate.render({
            elem: '#user-createTime',
            range: true,
            trigger: 'click'
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'userTable',
                url: ctx + 'documentary/seeFollowerInfo?parentId=1',
                cols: [[
                    {field: 'phone', title: '手机号', minWidth: 100,align:'left'},
                    {field: 'email', title: '邮箱', minWidth: 100,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 100,align:'left'},
                    {field: 'inviteId', title: '邀请码UID', minWidth: 80,align:'center'},
                    {field: 'contractTotal', title: '合约账户总资产', minWidth: 150,align:'left'},
                    {field: 'profitTotal', title: '总返利金额', minWidth: 150,align:'center'},
                ]]
            });
        }
    })
</script>
src/main/resources/templates/febs/views/modules/documentary/traderDetail.html
@@ -19,6 +19,11 @@
</style>
<div class="layui-fluid" id="user-update">
    <form class="layui-form" action="" lay-filter="user-update-form">
        <div class="layui-form-item">
            <div style="text-align: center;color:red">
                利润率设置规则:只允许0到1之间的小数
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <label class="layui-form-label febs-form-item-require">用户id:</label>
            <div class="layui-input-block">
@@ -28,8 +33,8 @@
        <div class="layui-form-item">
            <label class="layui-form-label">利润率:</label>
            <div class="layui-input-block">
                <input type="text" name="profitRatio" minlength="4" maxlength="10" data-th-id="${member.profitRatio}"
                       lay-verify="range|profitRatio" autocomplete="off" class="layui-input" readonly>
                <input type="text" name="profitRatio" data-th-id="${member.profitRatio}"
                       lay-verify="range|profitRatio" autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
src/main/resources/templates/febs/views/modules/documentary/traderProfit.html
New file
@@ -0,0 +1,209 @@
<div class="layui-fluid layui-anim febs-anim" id="trader-profit" 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">
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="手机号/邮箱/邀请码" name="account" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-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="userTable" lay-data="{id: 'userTable'}"></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 = $('#trader-profit'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'edit') {
                febs.modal.open('交易员审核', 'modules/documentary/traderDetail/' + data.id, {
                    btn: ['确认', '取消'],
                    yes: function (index, layero) {
                        $('#user-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
            if (layEvent === 'seeFollowerInfo') {
                febs.modal.open('跟随者详情', 'modules/documentary/seeFollowerInfo/' + data.id, {
                    area: $(window).width() <= 750 ? '90%' : '80%',
                    offset: '30px',
                    btn2: function () {
                        layer.closeAll();
                    },
                    cancel: function(){
                        var index=parent.layer.getFrameIndex(window.name); //获取当前窗口的name
                        parent.layer.close(index);//关闭当前窗口
                        window.parent.location.reload();//刷新
                    }
                });
                $query.click();
            }
            if (layEvent === 'modifyProfitRatio') {
                febs.modal.open('收益率修改', 'modules/documentary/modifyProfitRatio/' + data.id, {
                    btn: ['确认', '取消'],
                    yes: function (index, layero) {
                        $('#user-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
                $query.click();
            }
            if (layEvent === 'getOut') {
                febs.modal.confirm('确认', '您是否要踢出该交易员?', function () {
                    confirmUsers(data.id);
                });
            }
            if (layEvent === 'getOn') {
                febs.modal.confirm('确认', '您是否推荐当前交易员?', function () {
                    confirmUsersGetOn(data.id);
                });
            }
            if (layEvent === 'getOutFrist') {
                febs.modal.confirm('确认', '您是否取消推荐当前交易员?', function () {
                    confirmUsersGetOutFrist(data.id);
                });
            }
            if (layEvent === 'getFull') {
                febs.modal.confirm('确认', '您是否要设置成【满员】状态?', function () {
                    cancelUsers(data.id);
                });
            }
        });
        function confirmUsers(id) {
            febs.get(ctx + 'documentary/traderGetOut/' + id, null, function () {
                febs.alert.success('踢出成功');
                $query.click();
            });
        }
        function confirmUsersGetOn(id) {
            febs.get(ctx + 'documentary/traderGetOn/' + id, null, function () {
                febs.alert.success('设置成功');
                $query.click();
            });
        }
        function confirmUsersGetOutFrist(id) {
            febs.get(ctx + 'documentary/traderGetOutFrist/' + id, null, function () {
                febs.alert.success('设置成功');
                $query.click();
            });
        }
        function cancelUsers(id) {
            febs.get(ctx + 'documentary/traderGetFull/' + 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: 'userTable',
                url: ctx + 'documentary/traderProfitInfo',
                cols: [[
                    {field: 'phone', title: '手机号', minWidth: 100,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 100,align:'left'},
                    {field: 'inviteId', title: '邀请码UID', minWidth: 80,align:'center'},
                    {field: 'profitRatio', title: '利润率', minWidth: 80,align:'center'},
                    {field: 'profitRatioTotal', title: '总返利润', minWidth: 80,align:'center'},
                    {title: '利润详情',
                        templet: function (d) {
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="seeFollowerInfo" shiro:hasPermission="user:update">查看</button>'
                        }, minWidth: 100,align:'center'},
                    {field: 'totalProfitRatio', title: '累计收益率', minWidth: 80,align:'center'},
                    {field: 'totalProfit', title: '带单总收益', minWidth: 80,align:'center'},
                    {field: 'followerTotalProfit', title: '跟随者总收益', minWidth: 80,align:'center'},
                    {field: 'winRate', title: '胜率', minWidth: 80,align:'center'},
                    {field: 'totalFollowerCnt', title: '累计跟随人数', minWidth: 80,align:'center'},
                    {field: 'totalOrderCnt', title: '交易笔数', minWidth: 80,align:'center'},
                    {field: 'accountType', title: '账号类型',
                        templet: function (d) {
                            if (d.accountType === 2) {
                                return '<span style="color:green;">测试账号</span>'
                            } else if (d.accountType === 1) {
                                return '<span style="color:red;">正常账号</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'email', title: '邮箱', minWidth: 100,align:'left'},
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
                account: $searchForm.find('input[name="account"]').val().trim(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/documentary/traderUpdate.html
@@ -17,8 +17,9 @@
                                        <div class="layui-input-inline">
                                            <select name="verifyStatus">
                                                <option value="">请选择</option>
                                                <option value="1">待审核</option>
                                                <option value="2">审核通过</option>
                                                <option value="1">审核通过</option>
                                                <option value="2">审核不通过</option>
                                                <option value="3">待审核</option>
                                            </select>
                                        </div>
                                    </div>
@@ -72,7 +73,7 @@
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'edit') {
                febs.modal.open('交易员审核', 'modules/documentary/traderDetail/' + data.id, {
                    btn: ['确认', '取消'],
@@ -84,31 +85,64 @@
                    }
                });
            }
            if (layEvent === 'modifyProfitRatio') {
                febs.modal.open('修改', 'modules/documentary/modifyProfitRatio/' + data.id, {
                    btn: ['确认', '取消'],
                    yes: function (index, layero) {
                        $('#user-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
            if (layEvent === 'getOut') {
                febs.modal.confirm('确认', '您是否要踢出该交易员?', function () {
                    confirmUsers(data.id);
                    confirmUsers(data.id);
                });
            }
            if (layEvent === 'getOn') {
                febs.modal.confirm('确认', '您是否推荐当前交易员?', function () {
                    confirmUsersGetOn(data.id);
                });
            }
            if (layEvent === 'getOutFrist') {
                febs.modal.confirm('确认', '您是否取消推荐当前交易员?', function () {
                    confirmUsersGetOutFrist(data.id);
                });
            }
            if (layEvent === 'getFull') {
                febs.modal.confirm('确认', '您是否要设置成【满员】状态?', function () {
                    cancelUsers(data.id);
                    cancelUsers(data.id);
                });
            }
        });
        function confirmUsers(id) {
            febs.get(ctx + 'documentary/traderGetOut/' + id, null, function () {
                febs.alert.success('踢出成功');
                febs.alert.success('踢出成功');
                $query.click();
            });
        }
        function confirmUsersGetOn(id) {
            febs.get(ctx + 'documentary/traderGetOn/' + id, null, function () {
                febs.alert.success('设置成功');
                $query.click();
            });
        }
        function confirmUsersGetOutFrist(id) {
            febs.get(ctx + 'documentary/traderGetOutFrist/' + id, null, function () {
                febs.alert.success('设置成功');
                $query.click();
            });
        }
        function cancelUsers(id) {
            febs.get(ctx + 'documentary/traderGetFull/' + id, null, function () {
                febs.alert.success('设置成功');
                febs.alert.success('设置成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
@@ -129,12 +163,15 @@
                url: ctx + 'documentary/traderList',
                cols: [[
                    {field: 'phone', title: '手机号', minWidth: 100,align:'left'},
                    {field: 'email', title: '邮箱', minWidth: 200,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 200,align:'left'},
                    {field: 'email', title: '邮箱', minWidth: 100,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 100,align:'left'},
                    {field: 'nickname', title: '昵称', minWidth: 100,align:'left'},
                    {field: 'inviteId', title: '邀请码UID', minWidth: 80,align:'center'},
                    {field: 'profitRatio', title: '利润率', minWidth: 80,align:'center'},
                    {field: 'followNumNow', title: '当前跟随人数', minWidth: 120,align:'center'},
                    {field: 'followNum', title: '最大跟随人数', minWidth: 120,align:'center'},
                    {field: 'accountType', title: '账号类型',
                        templet: function (d) {
                        templet: function (d) {
                            if (d.accountType === 2) {
                                return '<span style="color:green;">测试账号</span>'
                            } else if (d.accountType === 1) {
@@ -144,29 +181,36 @@
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'verifyStatus', title: '审核状态',
                                templet: function (d) {
                                    if (d.verifyStatus === 1) {
                                        return '<span style="color:blue;">审核通过</span>'
                                    } else if (d.verifyStatus === 2) {
                                        return '<span style="color:green;">不通过</span>'
                                    } else if (d.verifyStatus === 3) {
                                        return '<span>待审核</span>'
                                    }else{
                                        return ''
                                    }
                                }, minWidth: 80,align:'center'},
                        templet: function (d) {
                            if (d.verifyStatus === 1) {
                                return '<span style="color:blue;">审核通过</span>'
                            } else if (d.verifyStatus === 2) {
                                return '<span style="color:green;">不通过</span>'
                            } else if (d.verifyStatus === 3) {
                                return '<span>待审核</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'createTime', title: '注册时间', minWidth: 180,align:'center'},
                    {title: '操作',
                        templet: function (d) {
                    {title: '操作',
                        templet: function (d) {
                            if (d.verifyStatus === 3) {
                                return '<a lay-event="edit" shiro:hasPermission="user:update">审核</a>'
                            }else if(d.verifyStatus === 1){
                                return '<a lay-event="getOut" shiro:hasPermission="user:update">踢出</a>'
                                return '<a lay-event="getFull" shiro:hasPermission="user:update">满员</a>'
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit" shiro:hasPermission="user:update">审核</button>'
                            }else if(d.verifyStatus === 1 && d.isSetFrist ===1){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="modifyProfitRatio" shiro:hasPermission="user:update">修改</button>'
                                    + '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="getOut" shiro:hasPermission="user:update">踢出</button>'
                                    + '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="getFull" shiro:hasPermission="user:update">满员</button>'
                                    + '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="getOutFrist" shiro:hasPermission="user:update">取消推荐</button>'
                            }else if(d.verifyStatus === 1 && d.isSetFrist !=1){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="modifyProfitRatio" shiro:hasPermission="user:update">修改</button>'
                                    + '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="getOut" shiro:hasPermission="user:update">踢出</button>'
                                    + '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="getFull" shiro:hasPermission="user:update">满员</button>'
                                    + '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="getOn" shiro:hasPermission="user:update">推荐首页</button>'
                            }else {
                                return ''
                            }
                        },minWidth: 200,align:'center'}
                        },minWidth: 300,align:'center'}
                ]]
            });
        }
src/main/resources/templates/febs/views/modules/otc/otcAppealInfo.html
New file
@@ -0,0 +1,140 @@
<style>
    #user-update {
        padding: 20px 25px 25px 0;
    }
    #user-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-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="user-update">
    <form class="layui-form" action="" lay-filter="user-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="orderNo"data-th-id="${member.orderNo}"
                       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="number" name="unitPrice"data-th-id="${member.unitPrice}"
                       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="number" name="coinAmount"data-th-id="${member.coinAmount}"
                       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="number" name="totalAmount"data-th-id="${member.totalAmount}"
                       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="radio" name="status" value="1" title="未付款" readonly>
                <input type="radio" name="status" value="2" title="已付款" readonly>
                <input type="radio" name="status" value="3" title="已完成" readonly>
                <input type="radio" name="status" value="4" title="已取消" 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="payTime"data-th-id="${member.payTime}"
                       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="finishTime"data-th-id="${member.finishTime}"
                       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="nikename"data-th-id="${member.nikename}"
                       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="reason"data-th-id="${member.reason}"
                       autocomplete="off" class="layui-input" readonly>
            </div>
        </div>
<!--        <div class="layui-form-item">-->
<!--            <label class="layui-form-label febs-form-item-require">申诉图片:</label>-->
<!--            <div style="padding: 10px;">-->
<!--            @foreach($member.content as $content)-->
<!--            <img layer-src={{$content}} src={{$content}}-->
<!--                 width="400px" height="224px" style="margin: 3px; border: black 2px"  ;/>-->
<!--            @endforeach-->
<!--        </div>-->
<!--        </div>-->
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#user-update'),
            validate = layui.validate,
            _deptTree;
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            form.val("user-update-form", {
                "orderNo": member.orderNo,
                "unitPrice": member.unitPrice,
                "coinAmount": member.coinAmount,
                "totalAmount": member.totalAmount,
                "status": member.status,
                "payTime": member.payTime,
                "finishTime": member.finishTime,
                "nikename": member.nikename,
                "reason": member.reason,
                "content": member.content
            });
        }
    });
</script>
src/main/resources/templates/febs/views/modules/otc/otcAppealList.html
New file
@@ -0,0 +1,173 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-user" lay-title="OTC订单申诉">
    <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">
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="手机号/邀请码" name="account" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">状态</label>
                                        <div class="layui-input-inline">
                                            <select name="status">
                                                <option value="">请选择</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="userTable" lay-data="{id: 'userTable'}"></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>
<script id="showScreenhost" type="text/html">
    {{# var srr=d.content.split(",");
    for(var j in srr) { srr[j] }}
    <div style="margin:0 10px; display:inline-block !important; display:inline;  max-width:70px; max-height:50px;">
        <img style=" max-width:70px; max-height:50px;" src="{{srr[j]}}" />
    </div>
    {{# } }}
</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-user'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'dealIng') {
                // febs.modal.confirm('处理', '开始处理申诉?', function () {
                //     dealIng(data.id);
                // });
                febs.modal.open( '详情', 'modules/otc/otcAppealInfo/' + data.id, {
                    maxmin: true,
                });
            }
            if (layEvent === 'dealDone') {
                febs.modal.confirm('处理结束', '确认已处理结束?', function () {
                    dealDone(data.id);
                });
            }
        });
        function dealIng(id) {
            febs.get(ctx + 'otc/dealIng/' + id, null, function () {
                febs.alert.success('成功');
                $query.click();
            });
        }
        function dealDone(id) {
            febs.get(ctx + 'otc/dealDone/' + id, null, function () {
                febs.alert.success('成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'userTable',
                url: ctx + 'otc/otcAppealList',
                cols: [[
                    {field: 'phone', title: '手机号', minWidth: 150,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 100,align:'left'},
                    {field: 'inviteId', title: '邀请码', minWidth: 80,align:'center'},
                    {field: 'reason', title: '申诉原因', minWidth: 80,align:'center'},
                    {field: 'content', title: '申诉内容', minWidth: 80,templet: '#showScreenhost',align:'center'},
                    {field: 'status', title: '状态',
                        templet: function (d) {
                            if (d.status === 1) {
                                return '<span style="color:red;">待处理</span>'
                            } else if (d.status === 2) {
                                return '<span style="color:blue;">处理中</span>'
                            }  else if (d.status === 3) {
                                return '<span>已处理</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'orderNo', title: '订单编号',minWidth: 100,align:'center'},
                    // {field: 'nikename', title: '商户昵称',minWidth: 100,align:'center'},
                    {title: '操作',templet: function (d) {
                            if(d.status === 1){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealIng" shiro:hasPermission="user:update">查看详情</button>'
                            }else if(d.status === 2){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealIng" shiro:hasPermission="user:update">查看详情</button>'
                                +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealDone" shiro:hasPermission="user:update">已处理</button>'
                            }else{
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealIng" shiro:hasPermission="user:update">查看详情</button>'
                            }
                        },minWidth: 200,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
                account: $searchForm.find('input[name="account"]').val().trim(),
                status: $searchForm.find("select[name='status']").val(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/otc/otcEntrustList.html
New file
@@ -0,0 +1,211 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-user" 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">
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="手机号/邀请码" name="account" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">类型</label>
                                        <div class="layui-input-inline">
                                            <select name="orderType">
                                                <option value="">请选择</option>
                                                <option value="B">买入</option>
                                                <option value="S">卖出</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="status">
                                                <option value="">请选择</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="userTable" lay-data="{id: 'userTable'}"></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-user'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'dealIng') {
                febs.modal.confirm('处理', '开始处理申诉?', function () {
                    dealIng(data.id);
                });
            }
            if (layEvent === 'dealDone') {
                febs.modal.confirm('处理结束', '确认已处理结束?', function () {
                    dealDone(data.id);
                });
            }
            if (layEvent === 'editOrder') {
                febs.modal.open('详情修改', 'modules/otc/otcEntrustListUpdate/' + data.id, {
                    btn: ['提交', '取消'],
                    yes: function (index, layero) {
                        $('#user-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        function dealIng(id) {
            febs.get(ctx + 'otc/dealIng/' + id, null, function () {
                febs.alert.success('成功');
                $query.click();
            });
        }
        function dealDone(id) {
            febs.get(ctx + 'otc/dealDone/' + id, null, function () {
                febs.alert.success('成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'userTable',
                url: ctx + 'otc/otcEntrustList',
                cols: [[
                    {field: 'phone', title: '手机号', minWidth: 150,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 100,align:'left'},
                    {field: 'inviteId', title: '邀请码', minWidth: 80,align:'center'},
                    {field: 'entrustOrderNo', title: '编号', minWidth: 80,align:'center'},
                    {field: 'orderType', title: '类型',
                        templet: function (d) {
                            if (d.orderType === 'B') {
                                return '<span style="color:blue;">买入</span>'
                            } else if (d.orderType === 'S') {
                                return '<span style="color:green;">卖出</span>'
                            } else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'unitPrice', title: '单价',minWidth: 100,align:'center'},
                    {field: 'coinAmount', title: '数量',minWidth: 100,align:'center'},
                    {field: 'totalAmount', title: '委托总金额',minWidth: 100,align:'center'},
                    {field: 'nikename', title: '商户昵称',minWidth: 100,align:'center'},
                    {field: 'remainCoinAmount', title: '剩余数量',minWidth: 100,align:'center'},
                    {field: 'limitMinAmount', title: '最小限额',minWidth: 100,align:'center'},
                    {field: 'limitMaxAmount', title: '最大限额',minWidth: 100,align:'center'},
                    {field: 'status', title: '状态',
                        templet: function (d) {
                            if (d.status === 1) {
                                return '<span style="color:blue;">上线</span>'
                            } else if (d.status === 2) {
                                return '<span style="color:green;">下线</span>'
                            }else if (d.status === 3) {
                                return '<span>取消</span>'
                            } else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'isMb', title: '是否市商',
                        templet: function (d) {
                            if (d.isMb === 1) {
                                return '<span style="color:blue;">是</span>'
                            } else if (d.isMb === 2) {
                                return '<span style="color:green;">否</span>'
                            } else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {title: '操作',templet: function (d) {
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="editOrder" shiro:hasPermission="user:update">详情</button>'
                        },minWidth: 200,align:'center'}
                    // {title: '操作',templet: function (d) {
                    //         if(d.status === 1){
                    //             return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealIng" shiro:hasPermission="user:update">马上处理</button>'
                    //         }else if(d.status === 2){
                    //             return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealDone" shiro:hasPermission="user:update">已处理</button>'
                    //         }else{
                    //             return ''
                    //         }
                    //     },minWidth: 200,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
                account: $searchForm.find('input[name="account"]').val().trim(),
                orderType: $searchForm.find("select[name='orderType']").val(),
                status: $searchForm.find("select[name='status']").val(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/otc/otcEntrustListUpdate.html
New file
@@ -0,0 +1,126 @@
<style>
    #user-update {
        padding: 20px 25px 25px 0;
    }
    #user-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-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="user-update">
    <form class="layui-form" action="" lay-filter="user-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="number" name="unitPrice" data-th-id="${member.unitPrice}"
                       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="number" name="coinAmount" data-th-id="${member.coinAmount}"
                       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="number" name="remainCoinAmount" data-th-id="${member.remainCoinAmount}"
                       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="number" name="totalAmount" data-th-id="${member.totalAmount}"-->
<!--                       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="number" name="limitMinAmount" data-th-id="${member.limitMinAmount}"
                       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="number" name="limitMaxAmount" data-th-id="${member.limitMaxAmount}"
                       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="status" value="1" title="上线" checked="">
                <input type="radio" name="status" value="2" title="下线" >
                <input type="radio" name="status" value="3" title="取消" >
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="user-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#user-update'),
            validate = layui.validate,
            _deptTree;
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            form.val("user-update-form", {
                "id": member.id,
                "unitPrice": member.unitPrice,
                "coinAmount": member.coinAmount,
                "remainCoinAmount": member.remainCoinAmount,
                // "totalAmount": member.totalAmount,
                "limitMinAmount": member.limitMinAmount,
                "status": member.status,
                "limitMaxAmount": member.limitMaxAmount
            });
        }
        form.on('submit(user-update-form-submit)', function (data) {
            febs.post(ctx + 'otc/otcEntrustConfirm', data.field, function () {
                layer.closeAll();
                febs.alert.success('成功');
                $('#febs-user').find('#query').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/otc/otcHuiKuan.html
New file
@@ -0,0 +1,93 @@
<style>
    #user-update {
        padding: 20px 25px 25px 0;
    }
    #user-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-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="user-update">
    <form class="layui-form" action="" lay-filter="user-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="number" name="waitBackMoney"data-th-id="${member.waitBackMoney}"
                       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="number" name="hasBackMoney"data-th-id="${member.hasBackMoney}"
                       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="number" name="coinAmount"data-th-id="${member.coinAmount}"
                       autocomplete="off" class="layui-input" readonly>
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="user-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#user-update'),
            validate = layui.validate,
            _deptTree;
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            form.val("user-update-form", {
                "id": member.id,
                "waitBackMoney": member.waitBackMoney,
                "hasBackMoney": member.hasBackMoney,
                "coinAmount": member.coinAmount
            });
        }
        form.on('submit(user-update-form-submit)', function (data) {
            febs.post(ctx + 'otc/otcHuiKuan', data.field, function () {
                layer.closeAll();
                febs.alert.success('成功');
                $('#febs-user-shop').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/otc/otcOrderInfo.html
New file
@@ -0,0 +1,109 @@
<style>
    #user-update {
        padding: 20px 25px 25px 0;
    }
    #user-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-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="user-update">
    <form class="layui-form" action="" lay-filter="user-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="orderNo"data-th-id="${member.orderNo}"
                       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="number" name="unitPrice"data-th-id="${member.unitPrice}"
                       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="number" name="coinAmount"data-th-id="${member.coinAmount}"
                       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="number" name="totalAmount"data-th-id="${member.totalAmount}"
                       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="payName"data-th-id="${member.payName}"
                       autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="user-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#user-update'),
            validate = layui.validate,
            _deptTree;
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            form.val("user-update-form", {
                "id": member.id,
                "orderNo": member.orderNo,
                "unitPrice": member.unitPrice,
                "coinAmount": member.coinAmount,
                "totalAmount": member.totalAmount,
                "payName": member.payName
            });
        }
        form.on('submit(user-update-form-submit)', function (data) {
            febs.post(ctx + 'otc/updateOrderInfo', data.field, function () {
                layer.closeAll();
                febs.alert.success('成功');
                $('#febs-user-order').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/otc/otcOrderList.html
New file
@@ -0,0 +1,175 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-user-order" 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">
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="手机号/邀请码" name="account" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">订单状态</label>
                                        <div class="layui-input-inline">
                                            <select name="status">
                                                <option value="">请选择</option>
                                                <option value="1">未付款</option>
                                                <option value="2">已付款</option>
                                                <option value="3">已完成</option>
                                                <option value="4">已取消</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="userTable" lay-data="{id: 'userTable'}"></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-user-order'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'dealIng') {
                febs.modal.open('付款', 'modules/otc/otcOrderInfo/' + data.id, {
                    btn: ['提交', '取消'],
                    yes: function (index, layero) {
                        $('#user-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
            if (layEvent === 'reduceCoin') {
                febs.modal.confirm('放币', '确定直接放币?', function () {
                    febs.post(ctx + 'otc/reduceCoin/' + data.id, null, function () {
                        febs.alert.success('放币成功');
                        $query.click();
                    });
                });
            }
        });
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'userTable',
                url: ctx + 'otc/otcOrderList',
                cols: [[
                    {field: 'phone', title: '手机号', minWidth: 100,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 100,align:'left'},
                    {field: 'inviteId', title: '邀请码', minWidth: 80,align:'center'},
                    {field: 'orderNo', title: '订单编号', minWidth: 150,align:'center'},
                    {field: 'unitPrice', title: '单价',minWidth: 80,align:'center'},
                    {field: 'coinAmount', title: '数量',minWidth: 80,align:'center'},
                    {field: 'totalAmount', title: '委托总金额',minWidth: 100,align:'center'},
                    {field: 'orderType', title: '类型',
                        templet: function (d) {
                            if (d.orderType === 'B') {
                                return '<span style="color:green;">买入</span>'
                            } else if (d.orderType === 'S') {
                                return '<span style="color:blue;">卖出</span>'
                            } else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'status', title: '订单状态',
                        templet: function (d) {
                            if (d.status === 1) {
                                return '<span style="color:red;">未付款</span>'
                            } else if (d.status === 2) {
                                return '<span style="color:blue;">已付款</span>'
                            }else if (d.status === 3) {
                                return '<span style="color:green;">已完成</span>'
                            } else if (d.status === 4) {
                                return '<span>已取消</span>'
                            }  else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'payName', title: '付款人姓名',minWidth: 100,align:'center'},
                    {field: 'payTime', title: '付款时间',minWidth: 150,align:'center'},
                    {field: 'finishTime', title: '完成时间',minWidth: 150,align:'center'},
                    {title: '操作',templet: function (d) {
                            // return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealIng" shiro:hasPermission="user:update">付款</button>'
                            if(d.status === 1){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="dealIng" shiro:hasPermission="user:update">付款</button>'
                            }else if (d.status === 2 && d.orderType === 'S'){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="reduceCoin">放币</button>'
                            } else {
                                return '';
                            }
                        },minWidth: 100,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
                account: $searchForm.find('input[name="account"]').val().trim(),
                status: $searchForm.find("select[name='status']").val(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/otc/otcSettingList.html
New file
@@ -0,0 +1,126 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-user-set" 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">-->
<!--                                        <div class="layui-input-inline">-->
<!--                                            <input type="text" placeholder="手机号/邀请码" name="account" autocomplete="off" class="layui-input">-->
<!--                                        </div>-->
<!--                                    </div>-->
<!--                                    <div class="layui-inline">-->
<!--                                        <label class="layui-form-label layui-form-label-sm">订单状态</label>-->
<!--                                        <div class="layui-input-inline">-->
<!--                                            <select name="status">-->
<!--                                                <option value="">请选择</option>-->
<!--                                                <option value="1">未付款</option>-->
<!--                                                <option value="2">已付款</option>-->
<!--                                                <option value="3">已完成</option>-->
<!--                                                <option value="4">已取消</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="userTable" lay-data="{id: 'userTable'}"></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-user-set'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'otcSettingUpdate') {
                febs.modal.open('付款', 'modules/otc/otcSettingUpdate/' + data.id, {
                    btn: ['提交', '取消'],
                    yes: function (index, layero) {
                        $('#user-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'userTable',
                url: ctx + 'otc/otcSettingList',
                cols: [[
                    {field: 'orderNum', title: '商家入驻总单数', minWidth: 100,align:'left'},
                    {field: 'completionRate', title: '商家入驻完成率', minWidth: 100,align:'left'},
                    {field: 'totalAmount', title: '商家入驻总金额', minWidth: 80,align:'center'},
                    {field: 'cancellNum', title: '今日累计取消次数', minWidth: 150,align:'center'},
                    {title: '操作',templet: function (d) {
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="otcSettingUpdate" shiro:hasPermission="user:update">修改</button>'
                        },minWidth: 100,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {};
        }
    })
</script>
src/main/resources/templates/febs/views/modules/otc/otcSettingUpdate.html
New file
@@ -0,0 +1,109 @@
<style>
    #user-update {
        padding: 20px 25px 25px 0;
    }
    #user-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #user-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="user-update">
    <form class="layui-form" action="" lay-filter="user-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>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">总单数:</label>
            <div class="layui-input-block">
                <input type="number" name="orderNum"data-th-id="${member.orderNum}"
                       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="number" name="completionRate"data-th-id="${member.completionRate}"
                       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="number" name="totalAmount"data-th-id="${member.totalAmount}"
                       autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">今日累计:</label>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">取消次数:</label>
            <div class="layui-input-block">
                <input type="number" name="cancellNum"data-th-id="${member.cancellNum}"
                       autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="user-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            eleTree = layui.eleTree,
            member = [[${member}]],
            $view = $('#user-update'),
            validate = layui.validate,
            _deptTree;
        form.render();
        initUserValue();
        formSelects.render();
        function initUserValue() {
            form.val("user-update-form", {
                "id": member.id,
                "orderNum": member.orderNum,
                "completionRate": member.completionRate,
                "totalAmount": member.totalAmount,
                "cancellNum": member.cancellNum
            });
        }
        form.on('submit(user-update-form-submit)', function (data) {
            febs.post(ctx + 'otc/updateOtcSetting', data.field, function () {
                layer.closeAll();
                febs.alert.success('成功');
                $('#febs-user-set').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/otc/otcShopList.html
New file
@@ -0,0 +1,177 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-user-shop" lay-title="OTC商户">
    <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">
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="手机号/邀请码" name="account" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">审核状态</label>
                                        <div class="layui-input-inline">
                                            <select name="status">
                                                <option value="">请选择</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="userTable" lay-data="{id: 'userTable'}"></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-user-shop'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(userTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'agreeShop') {
                febs.modal.confirm('通过', '确认通过该商户的审核?', function () {
                    agreeShop(data.id);
                });
            }
            if (layEvent === 'disagreeShop') {
                febs.modal.confirm('拒绝', '确认拒绝该商户的审核?', function () {
                    disagreeShop(data.id);
                });
            }
            if (layEvent === 'huikuan') {
                febs.modal.open('回款', 'modules/otc/huikuan/' + data.id, {
                    btn: ['提交', '取消'],
                    yes: function (index, layero) {
                        $('#user-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        function agreeShop(id) {
            febs.get(ctx + 'otc/agreeShop/' + id, null, function () {
                febs.alert.success('通过成功');
                $query.click();
            });
        }
        function disagreeShop(id) {
            febs.get(ctx + 'otc/disagreeShop/' + id, null, function () {
                febs.alert.success('拒绝成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'userTable',
                url: ctx + 'otc/otcShopList',
                cols: [[
                    {field: 'phone', title: '手机号', minWidth: 150,align:'left'},
                    {field: 'realName', title: '姓名', minWidth: 100,align:'left'},
                    {field: 'inviteId', title: '邀请码', minWidth: 80,align:'center'},
                    {field: 'nikename', title: '昵称', minWidth: 80,align:'center'},
                    {field: 'status', title: '审核状态',
                        templet: function (d) {
                            if (d.status === 1) {
                                return '<span style="color:blue;">待审核</span>'
                            } else if (d.status === 2) {
                                return '<span style="color:green;">审核通过</span>'
                            } else if (d.status === 3) {
                                return '<span>拒绝</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    // {field: 'waitBackMoney', title: '待回款',minWidth: 100,align:'center'},
                    // {field: 'hasBackMoney', title: '已回款',minWidth: 100,align:'center'},
                    {field: 'buyCnt', title: '服务人数',minWidth: 100,align:'center'},
                    {field: 'totalOrderCnt', title: '总单数',minWidth: 100,align:'center'},
                    {field: 'finishRatio', title: '完成率',minWidth: 100,align:'center'},
                    {field: 'avgPayTime', title: '平均付款时间',minWidth: 100,align:'center'},
                    {field: 'avgCoinTime', title: '平均放币时间',minWidth: 100,align:'center'},
                    {field: 'createTime', title: '注册时间', minWidth: 180,align:'center'},
                    {title: '操作',templet: function (d) {
                            // return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="huikuan" shiro:hasPermission="user:update">回款</button>'
                            if(d.status === 1){
                                return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="agreeShop" shiro:hasPermission="user:update">同意</button>'
                                        +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="disagreeShop" shiro:hasPermission="user:update">拒绝</button>'
                            }else{
                                return ''
                            }
                        },minWidth: 200,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
                account: $searchForm.find('input[name="account"]').val().trim(),
                status: $searchForm.find("select[name='status']").val(),
            };
        }
    })
</script>