Browse Source

change share code

Mr.qian 1 tuần trước cách đây
mục cha
commit
2beb08542b

+ 115 - 0
cif-service/src/main/java/com/txz/cif/util/ShareCodeUtils.java

@@ -0,0 +1,115 @@
+package com.txz.cif.util;
+
+import java.util.Random;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/9/1
+ */
+
+public class ShareCodeUtils {
+    
+    /**
+     * 自定义进制字符数组(不包含0,1,容易与o,l混淆)
+     * 数组顺序可进行调整增加反推难度,A用来补位因此此数组不包含A,共32个字符。
+     */
+    private static final char[] BASE = new char[]{'H', 'V', 'E', '8', 'S', '2', 'D', 'Z', 'X', '9', 'C', '7', 'P',
+            '5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'W', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'Q'};
+    
+    /**
+     * A补位字符,不能与自定义重复
+     */
+    private static final char SUFFIX_CHAR = 'A';
+    
+    /**
+     * 进制长度
+     */
+    private static final int BIN_LEN = BASE.length;
+    
+    /**
+     * 邀请码默认长度
+     */
+    private static final int INVITATION_CODE_LEN = 6;
+    
+    /**
+     * 将邀请码解码为ID
+     */
+    public static Long codeToId(String code) {
+        if (code == null || code.isEmpty()) {
+            return 0L;
+        }
+        
+        char[] charArray = code.toCharArray();
+        long result = 0L;
+        
+        for (int i = 0; i < charArray.length; i++) {
+            if (charArray[i] == SUFFIX_CHAR) {
+                break;
+            }
+            
+            int index = -1;
+            for (int j = 0; j < BIN_LEN; j++) {
+                if (charArray[i] == BASE[j]) {
+                    index = j;
+                    break;
+                }
+            }
+            
+            if (index == -1) {
+                return 0L;
+            }
+            
+            if (i > 0) {
+                result = result * BIN_LEN + index;
+            } else {
+                result = index;
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * 将ID编码为6位邀请码
+     */
+    public static String idToInvitationCode(Long id) {
+        return idToInvitationCode(id, INVITATION_CODE_LEN);
+    }
+    
+    /**
+     * 将ID编码为指定长度的邀请码
+     */
+    public static String idToInvitationCode(Long id, int codeLen) {
+        if (id == null || id <= 0) {
+            return null;
+        }
+        
+        char[] buf = new char[Math.max(codeLen, BIN_LEN)];
+        int charPos = buf.length;
+        
+        long workId = id;
+        while (workId >= BIN_LEN) {
+            int index = (int) (workId % BIN_LEN);
+            buf[--charPos] = BASE[index];
+            workId /= BIN_LEN;
+        }
+        buf[--charPos] = BASE[(int) (workId % BIN_LEN)];
+        
+        String result = new String(buf, charPos, buf.length - charPos);
+        int len = result.length();
+        
+        if (len < codeLen) {
+            StringBuilder sb = new StringBuilder(codeLen);
+            sb.append(SUFFIX_CHAR);
+            Random random = new Random();
+            
+            for (int i = 0; i < codeLen - len - 1; i++) {
+                sb.append(BASE[random.nextInt(BIN_LEN)]);
+            }
+            
+            result += sb.toString();
+        }
+        
+        return result;
+    }
+    
+}

+ 129 - 122
cif-service/src/main/java/com/txz/cif/web/UserApiController.java

@@ -1,27 +1,26 @@
 package com.txz.cif.web;
 
-import java.lang.reflect.Member;
-import java.math.BigDecimal;
-import java.util.*;
-import java.util.stream.Collectors;
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.crypto.SecureUtil;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.txz.cif.core.*;
 import com.txz.cif.dubbo.client.OperatingConfigDubboServiceClient;
 import com.txz.cif.enums.BizTypeEnum;
 import com.txz.cif.enums.RechargeStatusEnum;
 import com.txz.cif.enums.RedEnvelopeStatusEnum;
 import com.txz.cif.enums.WithdrawStatusEnum;
-import com.txz.cif.util.IpUtils;
+import com.txz.cif.model.ConfigMember;
+import com.txz.cif.model.User;
+import com.txz.cif.service.ConfigMemberService;
+import com.txz.cif.service.RedEnvelopeService;
+import com.txz.cif.service.SequenceService;
+import com.txz.cif.service.UserService;
+import com.txz.cif.util.ShareCodeUtils;
 import com.txz.cif.web.bo.EnumBo;
 import com.txz.cif.web.bo.UserBo;
 import com.txz.cif.web.bo.UserInfoBO;
@@ -29,53 +28,57 @@ import com.txz.cif.web.para.LoginAccountParameters;
 import com.txz.cif.web.para.MyUserParam;
 import com.txz.cif.web.para.RegisterAccountParameters;
 import com.txz.cif.web.para.UserInfoForm;
-import com.txz.cif.core.*;
-import com.txz.cif.model.*;
-import com.txz.cif.service.*;
-import com.txz.cif.core.AuthService;
 import com.txz.operating.dto.ConfigDTO;
-import io.swagger.annotations.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.*;
-import lombok.extern.slf4j.Slf4j;
 import tk.mybatis.mapper.entity.Condition;
 import tk.mybatis.mapper.entity.Example;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
 @RestController
 @RequestMapping(value = "/api/user")
 @Api(tags = "[API]用户相关操作")
 @Slf4j
 public class UserApiController extends AbstractApiController {
-
+    
     @Resource
     private RedisUtil redisUtil;
-
+    
     @Resource
     private UserService userService;
-
+    
     @Resource
     private ConfigMemberService configMemberService;
-
+    
     @Resource
     private AuthService authService;
-
+    
     @Resource
     private SequenceService sequenceService;
-
-
+    
+    
     @Resource
     private RedEnvelopeService redEnvelopeService;
-
+    
     @Resource
     private OperatingConfigDubboServiceClient configDubboServiceClient;
-
+    
     @GetMapping("/getEnum")
-    @ApiOperation(value = "获取枚举(1业务类型 2充值状态 3提现状态 4收益状态 5收益业务类型)",httpMethod = "GET")
+    @ApiOperation(value = "获取枚举(1业务类型 2充值状态 3提现状态 4收益状态 5收益业务类型)", httpMethod = "GET")
     public Result<List<EnumBo>> getEnum(@RequestParam Integer id) {
-        if(id == null){
+        if (id == null) {
             id = 1;
         }
-        switch (id){
+        switch (id) {
             case 1:
                 return ResultGenerator.genSuccessResult(Arrays.stream(BizTypeEnum.values())
                         .map(temp -> EnumBo.builder().code(temp.getKey()).name(temp.getValue()).build()).collect(Collectors.toList()));
@@ -94,14 +97,14 @@ public class UserApiController extends AbstractApiController {
         }
         return ResultGenerator.genSuccessResult();
     }
-
-
-    @ApiOperation(value = "用户登陆", notes = "",httpMethod = "POST")
+    
+    
+    @ApiOperation(value = "用户登陆", notes = "", httpMethod = "POST")
     @PostMapping("/login")
-    public Result<UserBo> login(@RequestBody LoginAccountParameters loginPara ,
-                                @RequestHeader(value = "version",defaultValue = "1.0.1") String version ,
+    public Result<UserBo> login(@RequestBody LoginAccountParameters loginPara,
+                                @RequestHeader(value = "version", defaultValue = "1.0.1") String version,
                                 HttpServletRequest request) {
-        if (StrUtil.isBlank(loginPara.getAccount())){
+        if (StrUtil.isBlank(loginPara.getAccount())) {
             return ResultGenerator.genFailResult(ResultCode.ACCOUNT_IS_NULL);
         }
         if (StringUtils.isBlank(loginPara.getPwd())) {
@@ -120,12 +123,12 @@ public class UserApiController extends AbstractApiController {
                 user = operators.get(0);
             }
             String pwd2 = SecureUtil.md5(loginPara.getPwd() + user.getSalt());
-            log.info("用户:"+loginPara.getAccount()+"登录密码:"+loginPara.getPwd() +"加密后:"+pwd2);
+            log.info("用户:" + loginPara.getAccount() + "登录密码:" + loginPara.getPwd() + "加密后:" + pwd2);
             if (StrUtil.equals(user.getPwd().toUpperCase(), pwd2.toUpperCase())) {
                 if (user == null) {
                     return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
                 }
-                if (user.getStatus() != 1){
+                if (user.getStatus() != 1) {
                     return ResultGenerator.genFailResult(ResultCode.USER_STATUS_IS_ERROR);
                 }
                 String token = authService.buildJwtToken(user.getId());
@@ -134,121 +137,119 @@ public class UserApiController extends AbstractApiController {
             } else {
                 return ResultGenerator.genFailResult(ResultCode.UNLOGIN_PWD_ERROR);
             }
-
+            
             return ResultGenerator.genSuccessResult(UserBo.builder().token(user.getLastToken())
-                            .userId(user.getId()).icon(user.getHeadPic()).name(user.getName())
-                            .sseId(SecureUtil.md5("sse"+user.getId())).build());
-        } catch (Exception e){
-            log.error("登录异常:",e);
+                    .userId(user.getId()).icon(user.getHeadPic()).name(user.getName())
+                    .sseId(SecureUtil.md5("sse" + user.getId())).build());
+        } catch (Exception e) {
+            log.error("登录异常:", e);
             return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
         }
-
+        
     }
-
-
-    @ApiOperation(value = "获取Token内的参数", notes = "",httpMethod = "GET")
+    
+    
+    @ApiOperation(value = "获取Token内的参数", notes = "", httpMethod = "GET")
     @GetMapping("/getTokenParam")
     public Result getTokenParam(@RequestParam String authentication) {
         return ResultGenerator.genSuccessResult(authService.getClaimsFromToken(authentication));
     }
-
-
-    @ApiOperation(value = "获取验证码", notes = "",httpMethod = "GET")
+    
+    
+    @ApiOperation(value = "获取验证码", notes = "", httpMethod = "GET")
     @GetMapping("/getCode")
     public Result<UserInfoBO> getCode(@RequestParam String phoneNo) {
-//        Long userId = authService.getTokenUserId(request);
-        //TODO 发送短信
+        //        Long userId = authService.getTokenUserId(request);
+        // TODO 发送短信
         Result<Object> result = userService.sendCode(phoneNo);
         return ResultGenerator.genSuccessResult(result.getData().toString());
     }
-
-    @ApiOperation(value = "获取会员等级配置", notes = "",httpMethod = "GET")
+    
+    @ApiOperation(value = "获取会员等级配置", notes = "", httpMethod = "GET")
     @GetMapping("/memberConfigs")
     public Result<List<ConfigMember>> memberConfigs() {
         List<ConfigMember> result = configMemberService.findAll();
         return ResultGenerator.genSuccessResult(result);
     }
-
-
-
-
-    @ApiOperation(value = "查询用户资料", notes = "",httpMethod = "GET")
+    
+    
+    @ApiOperation(value = "查询用户资料", notes = "", httpMethod = "GET")
     @GetMapping("/getUserInfo")
     public Result<UserInfoBO> getUserInfo(HttpServletRequest request) {
-
+        
         Long userId = authService.getTokenUserId(request);
-        if (userId == null ){
+        if (userId == null) {
             ResultGenerator.genFailResult(ResultCode.OAUTH_INVALID_ACCESS_TOKEN);
         }
         User user = userService.findById(userId);
-        if (user == null){
+        if (user == null) {
             return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
         }
-        if (StrUtil.isBlank(user.getHeadPic())){
-            String zm = user.getName().substring(0,1).toUpperCase();
+        if (StrUtil.isBlank(user.getHeadPic())) {
+            String zm = user.getName().substring(0, 1).toUpperCase();
             Integer index = RandomUtil.randomInt(10);
             com.txz.operating.result.Result<ConfigDTO> defaultAvatar = configDubboServiceClient.getConfigByCode("default_avatar");
-            String headPic = defaultAvatar.getData().getValueInfo()+ zm +"/"+zm+"_gradient_"+index+".png" ;
+            String headPic = defaultAvatar.getData().getValueInfo() + zm + "/" + zm + "_gradient_" + index + ".png";
             user.setHeadPic(headPic);
             userService.update(User.builder().id(userId).headPic(headPic).build());
         }
         UserInfoBO bo = user.generator();
         Condition c = new Condition(User.class);
-        c.createCriteria().andEqualTo("pid",user.getId());
+        c.createCriteria().andEqualTo("pid", user.getId());
         Integer invited = userService.countByCondition(c);
         bo.setInvitedNo(invited);
-        //下级要人数
+        // 下级要人数
         ConfigMember nextLevel = configMemberService.findBy("level", user.getVipLevel() + 1);
-        if (nextLevel == null){
+        if (nextLevel == null) {
             bo.setNextInvitedNo(invited);
         } else {
             bo.setNextInvitedNo(nextLevel.getInvitedNo());
         }
         c = new Condition(User.class);
-        c.createCriteria().andEqualTo("ppid",user.getId());
+        c.createCriteria().andEqualTo("ppid", user.getId());
         Integer invited2 = userService.countByCondition(c);
-        bo.setTeamNo(invited+invited2);
-        //7日收益
-        BigDecimal amount = redEnvelopeService.sumWithDay(7,user.getId(),3);
+        bo.setTeamNo(invited + invited2);
+        // 7日收益
+        BigDecimal amount = redEnvelopeService.sumWithDay(7, user.getId(), 3);
         bo.setL7DEarnings(amount);
         return ResultGenerator.genSuccessResult(bo);
     }
-
-    @ApiOperation(value = "更新用户", notes = "",httpMethod = "POST")
+    
+    @ApiOperation(value = "更新用户", notes = "", httpMethod = "POST")
     @PostMapping("/updateUser")
-    public Result<UserInfoBO> updateUser(@RequestBody UserInfoForm userForm,HttpServletRequest request) {
+    public Result<UserInfoBO> updateUser(@RequestBody UserInfoForm userForm, HttpServletRequest request) {
         Long userId = authService.getTokenUserId(request);
-        if (userId == null ){
+        if (userId == null) {
             ResultGenerator.genFailResult(ResultCode.OAUTH_INVALID_ACCESS_TOKEN);
         }
         User user = userService.findById(userId);
-        if (user == null){
+        if (user == null) {
             return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
         }
-        User temp = BeanUtil.toBean(userForm,User.class);
+        User temp = BeanUtil.toBean(userForm, User.class);
         temp.setId(userId);
         userService.update(temp);
         user = userService.findById(userId);
-        if (StrUtil.isNotBlank(userForm.getPhoneNo())){
-            userService.resetPhoneNo(userId,userForm.getPhoneNo());
+        if (StrUtil.isNotBlank(userForm.getPhoneNo())) {
+            userService.resetPhoneNo(userId, userForm.getPhoneNo());
         }
         return ResultGenerator.genSuccessResult(user.generator());
     }
-
-
+    
+    
     @PostMapping("/register")
-    @ApiOperation(value = "注册",httpMethod = "POST")
+    @ApiOperation(value = "注册", httpMethod = "POST")
     public Result register(@RequestBody RegisterAccountParameters params) {
-        if(params == null){
+        if (params == null) {
             return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
         }
-        if(StrUtil.isBlank(params.getPhone())){
+        if (StrUtil.isBlank(params.getPhone())) {
             return ResultGenerator.genFailResult(ResultCode.ACCOUNT_IS_NULL);
         }
         Condition condition = new Condition(User.class);
-        condition.createCriteria().andEqualTo("phoneNo",params.getPhone());
+        condition.createCriteria().andEqualTo("phoneNo", params.getPhone());
         List<User> users = userService.findByCondition(condition);
-        if(CollUtil.isNotEmpty(users)){
+        if (CollUtil.isNotEmpty(users)) {
             return ResultGenerator.genFailResult(ResultCode.USER_IS_EXIST);
         }
         if (!userService.checkCode(params.getPhone(), params.getVerifyCode())) {
@@ -256,94 +257,100 @@ public class UserApiController extends AbstractApiController {
         }
         String salt = RandomUtil.randomString(4);
         String pwd2 = SecureUtil.md5(params.getPwd() + salt).toUpperCase();
-        log.error("[密码]"+params.getPhone() + " :"+pwd2);
-
+        log.error("[密码]" + params.getPhone() + " :" + pwd2);
+        
         String code = getInviteCode(0);
-        if (code == null){
+        if (code == null) {
             return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
         }
         User parent = userService.findBy("invitedCode", params.getCode());
-        String userNo = sequenceService.genSerialNumber("register_rule",null);
+        // String userNo = sequenceService.genSerialNumber("register_rule",null);
         User user = User.builder().createTime(DateUtil.date()).invitedCode(code)
-                .name(params.getName()).userNo(userNo).isDelete((byte)1).createUser("sys")
-                .status((byte)1).phoneNo(params.getPhone()).pwd(pwd2).salt(salt).build();
-        if (parent != null){
+                .name(params.getName())
+                // .userNo(userNo)
+                .isDelete((byte) 1).createUser("sys")
+                .status((byte) 1).phoneNo(params.getPhone()).pwd(pwd2).salt(salt).build();
+        if (parent != null) {
             user.setPid(parent.getId());
-            if (parent.getPid() != null){
+            if (parent.getPid() != null) {
                 user.setPpid(parent.getPid());
             }
         }
-        if (StrUtil.isBlank(user.getHeadPic())){
-            String zm = user.getName().substring(0,1).toUpperCase();
+        if (StrUtil.isBlank(user.getHeadPic())) {
+            String zm = user.getName().substring(0, 1).toUpperCase();
             Integer index = RandomUtil.randomInt(10);
             com.txz.operating.result.Result<ConfigDTO> defaultAvatar = configDubboServiceClient.getConfigByCode("default_avatar");
-            String headPic = defaultAvatar.getData().getValueInfo()+ zm +"/"+zm+"_gradient_"+index+".png" ;
+            String headPic = defaultAvatar.getData().getValueInfo() + zm + "/" + zm + "_gradient_" + index + ".png";
             user.setHeadPic(headPic);
         }
         user.setVipLevel(1);
         userService.add(user);
+        user.setUserNo(ShareCodeUtils.idToInvitationCode(user.getId()));
+        userService.update(user);
         user.setPwd("***");
         user.setSalt("***");
         return ResultGenerator.genSuccessResult(user);
     }
-
+    
     private String getInviteCode(int index) {
-        if (index > 10000){
+        if (index > 10000) {
             return null;
         }
         String s = RandomUtil.randomString(8);
         User inviteCode = userService.findBy("invitedCode", s);
-        if (inviteCode == null){
+        if (inviteCode == null) {
             return s;
         }
         return getInviteCode(index + 1);
     }
-
+    
     /**
      * 通过旧密码设置密码
      *
-     * @param userId       用户 UID
-     * @return          执行结果
+     * @param userId 用户 UID
+     *
+     * @return 执行结果
      */
-    @ApiOperation(value = "通过旧密码设置密码", notes = "",httpMethod = "GET")
+    @ApiOperation(value = "通过旧密码设置密码", notes = "", httpMethod = "GET")
     @GetMapping("/resetPwd")
-    public Result<Object> resetPwd(@RequestHeader(value = X_CLIENT_TOKEN_USERID,required = false) Long userId,
+    public Result<Object> resetPwd(@RequestHeader(value = X_CLIENT_TOKEN_USERID, required = false) Long userId,
                                    @RequestParam("pwd") String pwd,
                                    @RequestParam("newPwd") String newPwd
-                                   ) {
-        return userService.resetPwd(userId,pwd,newPwd);
+    ) {
+        return userService.resetPwd(userId, pwd, newPwd);
     }
-
+    
     /**
      * 通过旧密码设置密码
      *
-     * @param phoneNo       用户 UID
-     * @return          执行结果
+     * @param phoneNo 用户 UID
+     *
+     * @return 执行结果
      */
-    @ApiOperation(value = "通过验证码设置密码", notes = "",httpMethod = "GET")
+    @ApiOperation(value = "通过验证码设置密码", notes = "", httpMethod = "GET")
     @GetMapping("/resetPwdByCode")
     public Result<Object> resetPwdByCode(@RequestParam("phoneNo") String phoneNo,
-                                   @RequestParam("verifyCode") String verifyCode,
-                                   @RequestParam("newPwd") String newPwd
+                                         @RequestParam("verifyCode") String verifyCode,
+                                         @RequestParam("newPwd") String newPwd
     ) {
-        return userService.resetPwdByCode(phoneNo,verifyCode,newPwd);
+        return userService.resetPwdByCode(phoneNo, verifyCode, newPwd);
     }
-
-
+    
+    
     @PostMapping("/myUsers")
-    @ApiOperation(value = "获取我的邀请的用户",httpMethod = "POST")
+    @ApiOperation(value = "获取我的邀请的用户", httpMethod = "POST")
     public Result<List<User>> myUsers(@RequestBody MyUserParam param, HttpServletRequest request) {
         Long userId = authService.getTokenUserId(request);
-        if (userId == null ){
+        if (userId == null) {
             ResultGenerator.genFailResult(ResultCode.OAUTH_INVALID_ACCESS_TOKEN);
         }
         PageHelper.startPage(param.getPage(), param.getSize());
         Condition condition = new Condition(User.class);
         Example.Criteria criteria = condition.createCriteria();
-        if (param.getType() != null && param.getType() == 1){
-            criteria.andEqualTo("pid",userId);
+        if (param.getType() != null && param.getType() == 1) {
+            criteria.andEqualTo("pid", userId);
         } else {
-            criteria.andEqualTo("ppid",userId);
+            criteria.andEqualTo("ppid", userId);
         }
         if (StrUtil.isNotBlank(param.getName())) {
             criteria.andLike("name", "%" + param.getName() + "%");
@@ -357,7 +364,7 @@ public class UserApiController extends AbstractApiController {
         if (StrUtil.isNotBlank(param.getEndTime())) {
             criteria.andLessThanOrEqualTo("createTime", param.getEndTime());
         }
-
+        
         PageInfo pageInfo = null;
         try {
             List<User> list = userService.findByCondition(condition);
@@ -372,6 +379,6 @@ public class UserApiController extends AbstractApiController {
         }
         return ResultGenerator.genSuccessResult(pageInfo);
     }
-
-
+    
+    
 }