xiaoyong931011
2021-12-14 649d980913fc93b05b6fd47439ac0bbf87e8129e
20211214
11 files added
2 files modified
1140 ■■■■■ changed files
pom.xml 7 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java 94 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/utils/AppContants.java 70 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/utils/RedisUtils.java 548 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java 110 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/video/controller/ApiLoginController.java 36 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/video/dto/LoginDto.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/video/dto/RegisterDto.java 32 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/video/entity/VideoMemberEntity.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/video/mapper/VideoMemberMapper.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/video/service/IApiVideoMemberService.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/video/service/impl/ApiVideoMemberServiceImpl.java 151 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/VideoMemberMapper.xml 17 ●●●●● patch | view | raw | blame | history
pom.xml
@@ -19,11 +19,18 @@
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <mybatis.plus.version>3.3.1</mybatis.plus.version>
        <hutool.version>5.3.1</hutool.version>
        <swagger.ui>2.9.2</swagger.ui>
        <tomcat.version>9.0.31</tomcat.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
        <!-- Spring系列 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java
New file
@@ -0,0 +1,94 @@
package cc.mrbird.febs.common.interceptor;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.utils.AppContants;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.common.utils.SpringContextUtil;
import cc.mrbird.febs.video.entity.VideoMemberEntity;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    private final RedisUtils redisUtils = SpringContextUtil.getBean(RedisUtils.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String headerToken = request.getHeader("token");
        if (StringUtils.isBlank(headerToken)) {
            responseUnAuth(response);
            return false;
        }
        String token = resolveToken(headerToken);
        if (token == null || AppContants.TIME_OUT.equals(token)) {
            responseUnAuth(response);
            return false;
        }
        String userJsonStr = redisUtils.getString(token);
        if (StringUtils.isBlank(userJsonStr)) {
            responseUnAuth(response);
            return false;
        }
        VideoMemberEntity member = JSON.parseObject(userJsonStr, VideoMemberEntity.class);
        request.getSession().setAttribute("member", member);
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
    private void responseUnAuth(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.getWriter().write(new ObjectMapper().writeValueAsString(new FebsResponse().code(HttpStatus.UNAUTHORIZED)));
    }
    private String resolveToken(String token) {
        try {
            RSA rsa = new RSA(AppContants.PRIVATE_KEY, null);
            String[] tokens = StrUtil.split(rsa.decryptStr(token, KeyType.PrivateKey), "_");
            if (verifyTokenExpired(Long.parseLong(tokens[1]))) {
                return tokens[0];
            } else {
                return AppContants.TIME_OUT;
            }
        } catch (Exception e) {
            log.error("#解析token异常#", e);
            return null;
        }
    }
    private Boolean verifyTokenExpired(Long time) {
        boolean isDebug = true;
        if (!isDebug) {
            long currentTime = System.currentTimeMillis();
            return currentTime - time <= 30000;
        }
        return true;
    }
}
src/main/java/cc/mrbird/febs/common/utils/AppContants.java
New file
@@ -0,0 +1,70 @@
package cc.mrbird.febs.common.utils;
public class AppContants {
    /**
     * 系统用户
     */
    public static final String SYSTEM_USER = "system";
    public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzIfAF0gZs9zn9ENRtz6ocHa8MGljmMmCsjLsRvTIAilBMypMJz/VNooAOhd8GTdsWm8FNGVhRauv7RfxorFJ4Um2UbweUQBIZP2pzZMnclHxhUmYZsn/6IaPzijiUNfEjygtE7ezvso/67ecZJwqfrtlbEjqUbRgo17Qj23suwQIDAQAB";
    public static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALMh8AXSBmz3Of0Q1G3PqhwdrwwaWOYyYKyMuxG9MgCKUEzKkwnP9U2igA6F3wZN2xabwU0ZWFFq6/tF/GisUnhSbZRvB5RAEhk/anNkydyUfGFSZhmyf/oho/OKOJQ18SPKC0Tt7O+yj/rt5xknCp+u2VsSOpRtGCjXtCPbey7BAgMBAAECgYAAgn+23IalJ7z0AejA2T7wLotxet+24/zPcOUVY1bxlnMtDMSHWh6mFmjL4cilMXKGqXHO4NwV+zppsCTMPXVMniI1IhfcyECgFjUrpWNCk30DlqhKePtIUCHdyLrc21mMLLMOQD/Hbga5kHZpR8r5poUAJ5Tnm5rjeyggwDj3MwJBAOnY+dyd39cRPtNLH0ANuR0Hd/WuA/RSRNbBTlXIVlc0hF1QXkgIWT2zA4uvwrFsz3F11YdPdfLgUhkFHlQuhVMCQQDEGhJELXqZ3AMlE9ykhUgv9HaCofGuCvzJnBGDKh4B3ufWG728gCNruoaRmzU8TOeVCABIQ2Un3SAenq0ylYUbAkB1y9PJm0lneAtyulPKm18VTW7TNk5No6eDmqqQMbO0iALpUpO7q2Dw4J03n1jusUYp/FaMq61ZpEAW1Go7s5d7AkEArgsJjTLj7ewDaoPfPrD/6XfJOpVqPvKHepOmQ0g9C6H/FtrWIZeEWFdamZ4ruFH08yL/xSLzg1bQ6/wecZecYwJALY4OP1Z81fhNjzg1AQd1CQQJJXUIkQpxXD/zAS5Cgf7XWfELIA4+86WA8qU1ILYHClFuV0SfxyGvI4ZEmpFosg==";
    /**
     * app用户登陆redis前缀
     */
    public static final String APP_LOGIN_PREFIX = "app_";
    public static final String PC_LOGIN_PREFIX = "pc_";
    /**
     * token头部
     */
    public static final String TOKEN_HEADER = "Authorization";
    /**
     * token start with
     */
    public static final String TOKEN_START_WITH = "Bearer ";
    /**
     * 账号类型-手机号
     */
    public static final String ACCOUNT_TYPE_MOBILE = "1";
    /**
     * 账号类型-邮箱
     */
    public static final String ACCOUNT_TYPE_EMAIL = "2";
    /**
     * 系统推荐人id
     */
    public static final String SYSTEM_REFERER = "rxadr3";
    /**
     * 验证码前缀 手机
     */
    public static final String VERIFY_CODE_PREFIX = "CODE_SMS_";
    /**
     * 图片后缀
     */
    public static final String UPLOAD_IMAGE_SUFFIX = ".jpg";
    public static final String TIME_OUT = "time_out";
    public static final int DEL_FLAG_Y = 1;
    public static final int DEL_FLAG_N = 2;
    public static final String REDIS_ORDER_OVERTIME_PREFIX = "order_overtime_";
    public static final String REDIS_ORDER_OVERTIME = "order_overtime_{}_{}";
    public static final String AGENT_LEVEL = "AGENT_LEVEL";
    public static final String AGENT_LEVEL_REQUIRE = "AGENT_LEVEL_REQUIRE";
}
src/main/java/cc/mrbird/febs/common/utils/RedisUtils.java
New file
@@ -0,0 +1,548 @@
package cc.mrbird.febs.common.utils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtils {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    // =============================common============================
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据key 获取过期时间
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断key是否存在
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除缓存
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }
    // ============================String=============================
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public String getString(String key) {
        Object obj = key == null ? null : redisTemplate.opsForValue().get(key);
        if(obj!=null){
            return obj.toString();
        }
        return null;
    }
    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    public boolean setNotExist(String key, Object value, long time) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);
    }
    /**
     * 递增
     * @param key 键
     * @param delta 要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     * @param key 键
     * @param delta 要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    // ================================Map=================================
    /**
     * HashGet
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取hashKey对应的所有键值
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * HashSet 并设置时间
     * @param key 键
     * @param map 应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据,如果不存在将创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据,如果不存在将创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除hash表中的值
     * @param key 键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断hash表中是否有该项的值
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     * @param key 键
     * @param item 项
     * @param by 要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }
    /**
     * hash递减
     * @param key 键
     * @param item 项
     * @param by 要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
    // ============================set=============================
    /**
     * 根据key获取Set中的所有值
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 根据value从一个set中查询,是否存在
     * @param key 键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将数据放入set缓存
     * @param key 键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     336
     * 将set数据放入缓存
     337
     * @param key 键
     * @param time 时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0)
                expire(key, time);
            return count;
        }catch(Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 获取set缓存的长度
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除值为value的
     * @param key 键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ===============================list=================================
    /**
     * 获取list缓存的内容     * @param key 键
     * @param start 开始
     * @param end 结束 0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取list缓存的长度
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {        try {
        return redisTemplate.opsForList().size(key);
    } catch (Exception e) {
        e.printStackTrace();
        return 0;
    }
    }    /**
     * 通过索引 获取list中的值
     * @param key 键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据索引修改list中的某条数据
     * @param key 键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 移除N个值为value
     * @param key 键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}
src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java
New file
@@ -0,0 +1,110 @@
package cc.mrbird.febs.common.utils;
import java.util.Random;
public class ShareCodeUtil {
    /**
     * 自定义进制(0,1没有加入,容易与o,l混淆)
     */
//    private static final char[] r=new char[]{'q', 'w', 'e', '8', 'a', 's', '2', 'd', 'z', 'x', '9', 'c', '7', 'p', '5', 'i', 'k', '3', 'm', 'j', 'u', 'f', 'r', '4', 'v', 'y', 'l', 't', 'n', '6', 'b', 'g', 'h'};
    private static final char[] r = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9'};
    /**
     * (不能与自定义进制有重复)
     */
    private static final char b = '0';
    /**
     * 进制长度
     */
    private static final int binLen = r.length;
    /**
     * 序列最小长度
     */
    private static final int s = 8;
    /**
     * 根据ID生成六位随机码
     *
     * @param id ID
     * @return 随机码
     */
    public static String toSerialCode(long id) {
        char[] buf = new char[32];
        int charPos = 32;
        while ((id / binLen) > 0) {
            int ind = (int) (id % binLen);
            buf[--charPos] = r[ind];
            id /= binLen;
        }
        buf[--charPos] = r[(int) (id % binLen)];
        String str = new String(buf, charPos, (32 - charPos));
        // 不够长度的自动随机补全
        if (str.length() < s) {
            StringBuilder sb = new StringBuilder();
            sb.append(b);
            Random rnd = new Random();
            for (int i = 1; i < s - str.length(); i++) {
                sb.append(r[rnd.nextInt(binLen)]);
            }
            str += sb.toString();
        }
        return str;
    }
    /**
     * 根据ID生成六位随机码
     *
     * @param id ID
     * @return 随机码
     */
    public static String toSerialNumberCode(long id) {
        char[] buf = new char[32];
        int charPos = 32;
        while ((id / binLen) > 0) {
            int ind = (int) (id % binLen);
            buf[--charPos] = r[ind];
            id /= binLen;
        }
        buf[--charPos] = r[(int) (id % binLen)];
        String str = new String(buf, charPos, (32 - charPos));
        // 不够长度的自动随机补全
        if (str.length() < s) {
            StringBuilder sb = new StringBuilder();
            sb.append(b);
            Random rnd = new Random();
            for (int i = 1; i < s - str.length(); i++) {
                sb.append(r[rnd.nextInt(binLen)]);
            }
            str += sb.toString();
        }
        return str;
    }
    public static long codeToId(String code) {
        char chs[] = code.toCharArray();
        long res = 0L;
        for (int i = 0; i < chs.length; i++) {
            int ind = 0;
            for (int j = 0; j < binLen; j++) {
                if (chs[i] == r[j]) {
                    ind = j;
                    break;
                }
            }
            if (chs[i] == b) {
                break;
            }
            if (i > 0) {
                res = res * binLen + ind;
            } else {
                res = ind;
            }
        }
        return res;
    }
}
src/main/java/cc/mrbird/febs/video/controller/ApiLoginController.java
New file
@@ -0,0 +1,36 @@
package cc.mrbird.febs.video.controller;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.video.dto.LoginDto;
import cc.mrbird.febs.video.dto.RegisterDto;
import cc.mrbird.febs.video.service.IApiVideoMemberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@Slf4j
@CrossOrigin("*")
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/api/login")
@Api(value = "ApiLoginController", tags = "登录注册类")
public class ApiLoginController {
    private final IApiVideoMemberService memberService;
    @ApiOperation(value = "app注册接口", notes = "app注册接口")
    @PostMapping(value = "/register")
    public FebsResponse register(@RequestBody RegisterDto registerDto) {
        return memberService.register(registerDto);
    }
    @ApiOperation(value = "账号密码登录接口", notes = "账号密码登录接口")
    @PostMapping(value = "/toLogin")
    public FebsResponse login(@RequestBody LoginDto loginDto) {
        return memberService.toLogin(loginDto);
    }
}
src/main/java/cc/mrbird/febs/video/dto/LoginDto.java
New file
@@ -0,0 +1,20 @@
package cc.mrbird.febs.video.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel(value = "LoginDto", description = "登录接口参数接收类")
public class LoginDto {
    @NotBlank(message = "账号不能为空")
    @ApiModelProperty(value = "账号", example = "15773001234")
    private String account;
    @NotBlank(message = "密码不能为空")
    @ApiModelProperty(value = "密码", example = "123456")
    private String password;
}
src/main/java/cc/mrbird/febs/video/dto/RegisterDto.java
New file
@@ -0,0 +1,32 @@
package cc.mrbird.febs.video.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel(value = "RegisterDto", description = "用户注册参数接收类")
public class RegisterDto {
    @NotBlank(message = "账号不能为空")
    @ApiModelProperty(value = "手机号", example = "15773001234")
    private String account;
    @NotBlank(message = "密码不能为空")
    @ApiModelProperty(value = "密码", example = "123456")
    private String password;
    @ApiModelProperty(value = "类型 1-手机号 2-邮箱", example = "1")
    private String type = "1";
//    @NotBlank(message = "验证码不能为空")
//    @ApiModelProperty(value = "验证码", example = "123456")
//    private String code;
//    @NotBlank(message = "邀请码不能为空")
//    @ApiModelProperty(value = "邀请码")
//    private String inviteId;
}
src/main/java/cc/mrbird/febs/video/entity/VideoMemberEntity.java
@@ -59,12 +59,38 @@
    private Integer isVip;
    /**
     * 是
     */
    public static final Integer ISVIP_STATUS_YES = 1;
    /**
     * 否
     */
    public static final Integer ISVIP_STATUS_NO = 2;
    /**
     * 账号状态 1/正常 2/禁用
     */
    private Integer accountStatus;
    /**
     * 启用
     */
    public static final Integer ACCOUNT_STATUS_ENABLE = 1;
    /**
     * 禁用
     */
    public static final Integer ACCOUNT_STATUS_DISABLED = 2;
    /**
     * 账号类型 1/正常 2/测试
     */
    private Integer accountType;
    /**
     * 正常账号
     */
    public static final Integer ACCOUNT_TYPE_NORMAL = 1;
    /**
     * 测试账号
     */
    public static final Integer ACCOUNT_TYPE_TEST = 2;
}
src/main/java/cc/mrbird/febs/video/mapper/VideoMemberMapper.java
New file
@@ -0,0 +1,15 @@
package cc.mrbird.febs.video.mapper;
import cc.mrbird.febs.video.entity.VideoMemberEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
public interface VideoMemberMapper extends BaseMapper<VideoMemberEntity> {
    VideoMemberEntity selectInfoByAccount(@Param("account") String account);
    VideoMemberEntity selectInfoByInviteId(@Param("inviteId")String parentId);
    VideoMemberEntity selectInfoByAccountAndPwd(@Param("account") String account, @Param("password") String password);
}
src/main/java/cc/mrbird/febs/video/service/IApiVideoMemberService.java
New file
@@ -0,0 +1,14 @@
package cc.mrbird.febs.video.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.video.dto.LoginDto;
import cc.mrbird.febs.video.dto.RegisterDto;
import cc.mrbird.febs.video.entity.VideoMemberEntity;
import com.baomidou.mybatisplus.extension.service.IService;
public interface IApiVideoMemberService extends IService<VideoMemberEntity> {
    FebsResponse register(RegisterDto registerDto);
    FebsResponse toLogin(LoginDto loginDto);
}
src/main/java/cc/mrbird/febs/video/service/impl/ApiVideoMemberServiceImpl.java
New file
@@ -0,0 +1,151 @@
package cc.mrbird.febs.video.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.AppContants;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.common.utils.ShareCodeUtil;
import cc.mrbird.febs.video.dto.LoginDto;
import cc.mrbird.febs.video.dto.RegisterDto;
import cc.mrbird.febs.video.entity.VideoMemberEntity;
import cc.mrbird.febs.video.mapper.VideoMemberMapper;
import cc.mrbird.febs.video.service.IApiVideoMemberService;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiVideoMemberServiceImpl extends ServiceImpl<VideoMemberMapper, VideoMemberEntity> implements IApiVideoMemberService {
    private final RedisUtils redisUtils;
    @Override
    public FebsResponse register(RegisterDto registerDto) {
        VideoMemberEntity videoMember = this.baseMapper.selectInfoByAccount(registerDto.getAccount());
        if (videoMember != null) {
            throw new FebsException("该账号已被占用");
        }
//        String account = registerDto.getAccount();
//        String code = registerDto.getCode();
//        boolean flags = commonService.verifyCode(account, code);
//        if(!flags) {
//            throw new FebsException("验证码错误");
//        }
        videoMember = new VideoMemberEntity();
        videoMember.setPassword(SecureUtil.md5(registerDto.getPassword()));
        // 判断账号类型
        if (AppContants.ACCOUNT_TYPE_MOBILE.equals(registerDto.getType())) {
            videoMember.setPhone(registerDto.getAccount());
        } else {
            videoMember.setEmail(registerDto.getAccount());
        }
//        Integer count = this.baseMapper.selectCount(null);
//        if (count != null && count != 0) {
//            MallMember inviteMember = this.baseMapper.selectInfoByInviteId(registerDto.getInviteId());
//            if (inviteMember == null) {
//                throw new FebsException("邀请码不存在");
//            }
//
//            mallMember.setReferrerId(registerDto.getInviteId());
//
//        }
        videoMember.setName(registerDto.getAccount());
        videoMember.setAccountStatus(VideoMemberEntity.ACCOUNT_STATUS_ENABLE);
        videoMember.setAccountType(VideoMemberEntity.ACCOUNT_TYPE_NORMAL);
        videoMember.setIsVip(VideoMemberEntity.ISVIP_STATUS_NO);
        this.baseMapper.insert(videoMember);
        String inviteId = ShareCodeUtil.toSerialCode(videoMember.getId());
        videoMember.setInviteId(inviteId);
        //推荐人和推荐人链
        boolean flag = false;
        String parentId = videoMember.getRefererId();
        if (StrUtil.isBlank(parentId)) {
            flag = true;
        }
        String ids = "";
        while (!flag) {
            if (StrUtil.isBlank(ids)) {
                ids += parentId;
            } else {
                ids += ("," + parentId);
            }
            VideoMemberEntity parentMember = this.baseMapper.selectInfoByInviteId(parentId);
            if (parentMember == null) {
                break;
            }
            parentId = parentMember.getRefererId();
            if (StrUtil.isBlank(parentMember.getRefererId())) {
                flag = true;
            }
        }
        if (StrUtil.isNotBlank(ids)) {
            videoMember.setRefererIds(ids);
        }
        this.baseMapper.updateById(videoMember);
//        MallMemberWallet wallet = new MallMemberWallet();
//        wallet.setBalance(BigDecimal.ZERO);
//        wallet.setMemberId(mallMember.getId());
//        mallMemberWalletMapper.insert(wallet);
        return new FebsResponse().success().message("注册成功");
    }
    @Override
    public FebsResponse toLogin(LoginDto loginDto) {
        String md5Pwd = SecureUtil.md5(loginDto.getPassword());
        VideoMemberEntity videoMember = this.baseMapper.selectInfoByAccountAndPwd(loginDto.getAccount(), md5Pwd);
        if (videoMember == null) {
            throw new FebsException("用户不存在或账号密码错误");
        }
        if (videoMember.ACCOUNT_STATUS_DISABLED.equals(videoMember.getAccountStatus())) {
            throw new FebsException("该账号存在异常, 暂限制登录");
        }
        String redisKey = AppContants.APP_LOGIN_PREFIX + videoMember.getId();
        String existToken = redisUtils.getString(redisKey);
        if (StrUtil.isNotBlank(existToken)) {
            Object o = redisUtils.get(existToken);
            if (ObjectUtil.isNotEmpty(o)) {
                redisUtils.del(existToken);
            }
        }
        String token = IdUtil.simpleUUID();
        redisUtils.set(token, JSONObject.toJSONString(videoMember), 360000);
        redisUtils.set(redisKey, token, 360000);
        Map<String, Object> authInfo = new HashMap<>();
        authInfo.put("token", token);
        authInfo.put("rasToken", generateAsaToken(token));
        return new FebsResponse().success().data(authInfo);
    }
    public String generateAsaToken(String token) {
        RSA rsa = new RSA(null, AppContants.PUBLIC_KEY);
        return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey);
    }
}
src/main/resources/mapper/modules/VideoMemberMapper.xml
New file
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cc.mrbird.febs.video.mapper.VideoMemberMapper">
    <select id="selectInfoByAccount" resultType="cc.mrbird.febs.video.entity.VideoMemberEntity">
        select * from video_member where phone=#{account} or email=#{account} or invite_id=#{account}
    </select>
    <select id="selectInfoByInviteId" resultType="cc.mrbird.febs.video.entity.VideoMemberEntity">
        select * from video_member where invite_id=#{inviteId}
    </select>
    <select id="selectInfoByAccountAndPwd" resultType="cc.mrbird.febs.video.entity.VideoMemberEntity">
        select * from mall_member where (phone=#{account} or email=#{account}) and password=#{password}
    </select>
</mapper>