1
zj
2026-04-23 a15e0b30a6bd4b18354f903ea9a51a6552b1e732
1
6 files modified
184 ■■■■■ changed files
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiUserController.java 2 ●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/PromoteController.java 139 ●●●●● patch | view | raw | blame | history
trading-order-bean/src/main/java/com/yami/trading/bean/user/dto/UserAllRecomDto.java 6 ●●●●● patch | view | raw | blame | history
trading-order-common/src/main/java/com/yami/trading/common/constants/Constants.java 20 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/user/impl/QRGenerateServiceImpl.java 8 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/resources/mapper/user/UserRecomMapper.xml 9 ●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiUserController.java
@@ -615,7 +615,7 @@
                map.put("url", "");
                map.put("usercode_qr", "");
            } else {
                map.put("url", Constants.WEB_URL + "/register.html?usercode=" + party.getUserCode());
                map.put("url", Constants.buildRegisterInviteLink(party.getUserCode()));
                // 生成二维码图片
                qrGenerateService.generate(party.getUserCode());
                map.put("usercode_qr", Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=/qr/" + party.getUserCode() + ".png");
trading-order-admin/src/main/java/com/yami/trading/api/controller/PromoteController.java
@@ -1,7 +1,10 @@
package com.yami.trading.api.controller;
import com.yami.trading.bean.model.UserData;
import com.yami.trading.bean.model.User;
import com.yami.trading.bean.model.UserRecom;
import com.yami.trading.bean.user.dto.ChildrenLever;
import com.yami.trading.common.constants.Constants;
import com.yami.trading.common.domain.Result;
import com.yami.trading.common.exception.BusinessException;
import com.yami.trading.common.exception.YamiShopBindException;
@@ -21,6 +24,7 @@
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 我的推广
@@ -38,8 +42,68 @@
    @Autowired
    protected SysparaService sysparaService;
    @RequestMapping("api/promote!getInviteSummary.action")
    public Result<?> getInviteSummary() {
        String userId = SecurityUtils.getUser().getUserId();
        Map<String, Object> data = buildInviteSummary(userId);
        return Result.succeed(data);
    }
    @RequestMapping("api/promote!getInviteChildren.action")
    public Result<?> getInviteChildren(HttpServletRequest request) {
        String levelRaw = request.getParameter("level");
        int level = StringUtils.isInteger(levelRaw) ? Integer.parseInt(levelRaw) : 1;
        if (level < 1 || level > 2) {
            throw new YamiShopBindException("代理层级错误");
        }
        String pageNoRaw = request.getParameter("page_no");
        String pageSizeRaw = request.getParameter("page_size");
        int pageNo = StringUtils.isInteger(pageNoRaw) && Integer.parseInt(pageNoRaw) > 0 ? Integer.parseInt(pageNoRaw) : 1;
        int pageSize = StringUtils.isInteger(pageSizeRaw) && Integer.parseInt(pageSizeRaw) > 0 ? Integer.parseInt(pageSizeRaw) : 10;
        pageSize = Math.min(pageSize, 100);
        String userId = SecurityUtils.getUser().getUserId();
        List<String> level1Ids = getDirectChildIds(userId);
        List<String> targetIds;
        if (level == 1) {
            targetIds = level1Ids;
        } else {
            targetIds = new ArrayList<>();
            for (String id : level1Ids) {
                targetIds.addAll(getDirectChildIds(id));
            }
        }
        List<Map<String, Object>> fullList = targetIds.stream().map(id -> {
            User child = partyService.getById(id);
            if (child == null) {
                return null;
            }
            Map<String, Object> item = new HashMap<>();
            item.put("user_id", child.getUserId());
            item.put("username", maskUsername(child.getUserName()));
            item.put("user_code", child.getUserCode());
            item.put("create_time", child.getCreateTime());
            item.put("direct_children_count", getDirectChildIds(child.getUserId()).size());
            return item;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        int total = fullList.size();
        int from = Math.max((pageNo - 1) * pageSize, 0);
        int to = Math.min(from + pageSize, total);
        List<Map<String, Object>> pageList = from >= total ? Collections.emptyList() : fullList.subList(from, to);
        Map<String, Object> data = new HashMap<>();
        data.put("total", total);
        data.put("level", level);
        data.put("page_no", pageNo);
        data.put("page_size", pageSize);
        data.put("list", pageList);
        return Result.succeed(data);
    }
    @RequestMapping("api/promote!getPromote.action")
    public Result getPromote(HttpServletRequest request) {
    public Result<?> getPromote(HttpServletRequest request) {
        // 层级 1为第一级 1,2,3,4总共4级代理
        String  level_temp= request.getParameter("level");
        if (StringUtils.isNullOrEmpty(level_temp)
@@ -89,7 +153,7 @@
     * 交易所-数据总览-PC端
     */
    @RequestMapping( "api/promote!getPromoteData.action")
    public Result getPromoteData(HttpServletRequest request) {
    public Result<?> getPromoteData(HttpServletRequest request) {
        String partyId = SecurityUtils.getUser().getUserId();
        Map<String, String> dataMap = new HashMap<>();
        try {
@@ -145,4 +209,75 @@
            }
        }
    }
    private Map<String, Object> buildInviteSummary(String userId) {
        User currentUser = partyService.getById(userId);
        List<String> level1Ids = getDirectChildIds(userId);
        List<String> level2Ids = new ArrayList<>();
        for (String level1Id : level1Ids) {
            level2Ids.addAll(getDirectChildIds(level1Id));
        }
        Map<String, Object> data = new HashMap<>();
        String code = currentUser != null ? currentUser.getUserCode() : "";
        data.put("invite_code", code);
        data.put("invite_link", Constants.buildRegisterInviteLink(code));
        data.put("total_count", level1Ids.size() + level2Ids.size());
        data.put("tree", buildInviteTree(userId));
        return data;
    }
    /**
     * 两级邀请关系树:直接下级及其各自的下级(嵌套在 children 中)。
     */
    private List<Map<String, Object>> buildInviteTree(String rootUserId) {
        List<Map<String, Object>> tree = new ArrayList<>();
        for (String childId : getDirectChildIds(rootUserId)) {
            User u = partyService.getById(childId);
            if (u == null) {
                continue;
            }
            Map<String, Object> node = inviteUserNode(u);
            List<Map<String, Object>> children = new ArrayList<>();
            for (String gcId : getDirectChildIds(childId)) {
                User g = partyService.getById(gcId);
                if (g != null) {
                    children.add(inviteUserNode(g));
                }
            }
            node.put("children", children);
            tree.add(node);
        }
        return tree;
    }
    private Map<String, Object> inviteUserNode(User u) {
        Map<String, Object> item = new HashMap<>();
        item.put("user_id", u.getUserId());
        item.put("username", maskUsername(u.getUserName()));
        item.put("user_code", u.getUserCode());
        item.put("create_time", u.getCreateTime());
        return item;
    }
    private List<String> getDirectChildIds(String userId) {
        List<UserRecom> list = userRecomService.findRecoms(userId);
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        return list.stream().map(UserRecom::getRecomUserId).filter(Objects::nonNull).collect(Collectors.toList());
    }
    private String maskUsername(String username) {
        if (username == null) {
            return "";
        }
        int len = username.length();
        if (len <= 2) {
            return username;
        }
        if (len <= 6) {
            return username.substring(0, 1) + "***" + username.substring(len - 1);
        }
        return username.substring(0, 3) + "***" + username.substring(len - 2);
    }
}
trading-order-bean/src/main/java/com/yami/trading/bean/user/dto/UserAllRecomDto.java
@@ -26,5 +26,11 @@
    @ApiModelProperty("推荐用户code")
    private  String recomUserCode;
    @ApiModelProperty("一级下级人数")
    private Integer level1Count;
    @ApiModelProperty("二级下级人数")
    private Integer level2Count;
    private  String roleNameDesc;
}
trading-order-common/src/main/java/com/yami/trading/common/constants/Constants.java
@@ -18,6 +18,26 @@
//
    public static final String WEB_URL = ApplicationUtil.getProperty("web_url");
    /**
     * H5/PC 哈希路由注册页邀请链接,避免 web_url 尾斜杠与路径拼接出现双斜杠。
     */
    public static String normalizeWebUrl(String url) {
        if (url == null) {
            return "";
        }
        String s = url.trim();
        while (s.endsWith("/")) {
            s = s.substring(0, s.length() - 1);
        }
        return s;
    }
    public static String buildRegisterInviteLink(String userCode) {
        String base = normalizeWebUrl(WEB_URL);
        String code = userCode == null ? "" : String.valueOf(userCode).trim();
        return base + "/#/register?usercode=" + code;
    }
    public static final String IMAGES_DIR = ApplicationUtil.getProperty("images.dir");
    public static final String IMAGES_HTTP = ApplicationUtil.getProperty("images_http");
trading-order-service/src/main/java/com/yami/trading/service/user/impl/QRGenerateServiceImpl.java
@@ -33,10 +33,12 @@
    @Override
    public String generate(String content) {
        String image_name = "/qr/" + content + ".png";
        content = Constants.WEB_URL + "/register.html?usercode=" + content;
        final String userCode = content;
        content = Constants.buildRegisterInviteLink(userCode);
        boolean openButton = sysparaService.find("short_url_open_button").getBoolean() ;
        if(openButton) {
            content = sysparaService.find("agent_qr_url").getSvalue() + "/register.html?usercode=" + content;
            String agentBase = Constants.normalizeWebUrl(sysparaService.find("agent_qr_url").getSvalue());
            content = agentBase + "/#/register?usercode=" + userCode;
            boolean isCn = sysparaService.find("short_url_cn_button").getBoolean() ;
            if(isCn) {
                content = shortUrlCn(content);
@@ -105,7 +107,7 @@
    @Override
    public String generate185(String content) {
        String image_name = "/qr/" + content + "2.png";
        content = Constants.WEB_URL + "/register.html?usercode=" + content;
        content = Constants.buildRegisterInviteLink(content);
        // String image_name = "/qr/" + UUIDGenerator.getUUID() + ".png";
        String filepath = Constants.IMAGES_DIR + image_name;
        File file = new File(filepath);
trading-order-service/src/main/resources/mapper/user/UserRecomMapper.xml
@@ -31,7 +31,14 @@
    <select id="listUserAll" resultType="com.yami.trading.bean.user.dto.UserAllRecomDto">
        SELECT u.user_id,u.user_name,u.user_code,u.role_name,ur.user_name AS 'recomUserName',
        ur.user_code AS 'recomUserCode'  FROM tz_user u
        ur.user_code AS 'recomUserCode',
        (SELECT COUNT(1) FROM tz_user_recom r1 WHERE r1.user_id = u.user_id) AS level1Count,
        (
            SELECT COUNT(1)
            FROM tz_user_recom r2
            WHERE r2.user_id IN (SELECT r3.recom_user_id FROM tz_user_recom r3 WHERE r3.user_id = u.user_id)
        ) AS level2Count
        FROM tz_user u
        LEFT JOIN tz_user ur ON u.user_recom=ur.user_id
        where 1=1