From 649d980913fc93b05b6fd47439ac0bbf87e8129e Mon Sep 17 00:00:00 2001 From: xiaoyong931011 <15274802129@163.com> Date: Tue, 14 Dec 2021 11:53:43 +0800 Subject: [PATCH] 20211214 --- src/main/java/cc/mrbird/febs/video/dto/LoginDto.java | 20 + pom.xml | 7 src/main/java/cc/mrbird/febs/common/utils/RedisUtils.java | 548 ++++++++++++++++++++++++++++ src/main/java/cc/mrbird/febs/video/entity/VideoMemberEntity.java | 26 + src/main/java/cc/mrbird/febs/common/utils/AppContants.java | 70 +++ src/main/java/cc/mrbird/febs/video/controller/ApiLoginController.java | 36 + src/main/java/cc/mrbird/febs/video/service/IApiVideoMemberService.java | 14 src/main/java/cc/mrbird/febs/video/dto/RegisterDto.java | 32 + src/main/java/cc/mrbird/febs/video/mapper/VideoMemberMapper.java | 15 src/main/java/cc/mrbird/febs/video/service/impl/ApiVideoMemberServiceImpl.java | 151 +++++++ src/main/resources/mapper/modules/VideoMemberMapper.xml | 17 src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java | 94 ++++ src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java | 110 +++++ 13 files changed, 1,140 insertions(+), 0 deletions(-) diff --git a/pom.xml b/pom.xml index 551d1cd..0af040f 100644 --- a/pom.xml +++ b/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> diff --git a/src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java b/src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java new file mode 100644 index 0000000..c14164d --- /dev/null +++ b/src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java @@ -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; + } +} + diff --git a/src/main/java/cc/mrbird/febs/common/utils/AppContants.java b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java new file mode 100644 index 0000000..a2abac1 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java @@ -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"; + + +} diff --git a/src/main/java/cc/mrbird/febs/common/utils/RedisUtils.java b/src/main/java/cc/mrbird/febs/common/utils/RedisUtils.java new file mode 100644 index 0000000..7637e04 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/common/utils/RedisUtils.java @@ -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; + } + } +} diff --git a/src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java b/src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java new file mode 100644 index 0000000..5381938 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/cc/mrbird/febs/video/controller/ApiLoginController.java b/src/main/java/cc/mrbird/febs/video/controller/ApiLoginController.java new file mode 100644 index 0000000..e4bff9e --- /dev/null +++ b/src/main/java/cc/mrbird/febs/video/controller/ApiLoginController.java @@ -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); + } + +} diff --git a/src/main/java/cc/mrbird/febs/video/dto/LoginDto.java b/src/main/java/cc/mrbird/febs/video/dto/LoginDto.java new file mode 100644 index 0000000..ef7e64a --- /dev/null +++ b/src/main/java/cc/mrbird/febs/video/dto/LoginDto.java @@ -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; +} diff --git a/src/main/java/cc/mrbird/febs/video/dto/RegisterDto.java b/src/main/java/cc/mrbird/febs/video/dto/RegisterDto.java new file mode 100644 index 0000000..c2d6a1f --- /dev/null +++ b/src/main/java/cc/mrbird/febs/video/dto/RegisterDto.java @@ -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; + +} diff --git a/src/main/java/cc/mrbird/febs/video/entity/VideoMemberEntity.java b/src/main/java/cc/mrbird/febs/video/entity/VideoMemberEntity.java index db571e2..c018e54 100644 --- a/src/main/java/cc/mrbird/febs/video/entity/VideoMemberEntity.java +++ b/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; } diff --git a/src/main/java/cc/mrbird/febs/video/mapper/VideoMemberMapper.java b/src/main/java/cc/mrbird/febs/video/mapper/VideoMemberMapper.java new file mode 100644 index 0000000..1ac1464 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/video/mapper/VideoMemberMapper.java @@ -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); + +} diff --git a/src/main/java/cc/mrbird/febs/video/service/IApiVideoMemberService.java b/src/main/java/cc/mrbird/febs/video/service/IApiVideoMemberService.java new file mode 100644 index 0000000..36a707d --- /dev/null +++ b/src/main/java/cc/mrbird/febs/video/service/IApiVideoMemberService.java @@ -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); +} diff --git a/src/main/java/cc/mrbird/febs/video/service/impl/ApiVideoMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/video/service/impl/ApiVideoMemberServiceImpl.java new file mode 100644 index 0000000..57c6e7e --- /dev/null +++ b/src/main/java/cc/mrbird/febs/video/service/impl/ApiVideoMemberServiceImpl.java @@ -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); + } +} diff --git a/src/main/resources/mapper/modules/VideoMemberMapper.xml b/src/main/resources/mapper/modules/VideoMemberMapper.xml new file mode 100644 index 0000000..aa36d31 --- /dev/null +++ b/src/main/resources/mapper/modules/VideoMemberMapper.xml @@ -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> \ No newline at end of file -- Gitblit v1.9.1