diff --git a/game-dao/src/main/java/awesome/group/game/dao/bean/MatrixUser.java b/game-dao/src/main/java/awesome/group/game/dao/bean/MatrixUser.java index a0ed33d..4bddf9c 100644 --- a/game-dao/src/main/java/awesome/group/game/dao/bean/MatrixUser.java +++ b/game-dao/src/main/java/awesome/group/game/dao/bean/MatrixUser.java @@ -12,7 +12,11 @@ public class MatrixUser { private Integer appId; private String name; private String aliPayAccount; + private String nickname; + private String avatar; + private Integer money;//分,已提现金额 private String pwd; private String inviteCode; private Integer upUid; + private Long income; } diff --git a/game-service/pom.xml b/game-service/pom.xml index 601d700..b4787b0 100644 --- a/game-service/pom.xml +++ b/game-service/pom.xml @@ -95,6 +95,10 @@ redis.clients jedis + + com.alipay.sdk + alipay-sdk-java + diff --git a/game-service/src/main/java/awesome/group/game/service/SmsService.java b/game-service/src/main/java/awesome/group/game/service/SmsService.java index f665302..d2bcf1a 100644 --- a/game-service/src/main/java/awesome/group/game/service/SmsService.java +++ b/game-service/src/main/java/awesome/group/game/service/SmsService.java @@ -52,7 +52,7 @@ public class SmsService { } public void sendCaptcha(String phone, String scene) { - List sceneList = Arrays.asList("register"); + List sceneList = Arrays.asList("register", "login", "reset_pwd"); if (!sceneList.contains(scene)) { throw new PaganiException(PaganiExceptionCode.GENERAL_ERROR, "非法scene"); } diff --git a/game-service/src/main/java/awesome/group/game/service/bo/citrus/LoginReq.java b/game-service/src/main/java/awesome/group/game/service/bo/citrus/LoginReq.java new file mode 100644 index 0000000..f6c8754 --- /dev/null +++ b/game-service/src/main/java/awesome/group/game/service/bo/citrus/LoginReq.java @@ -0,0 +1,9 @@ +package awesome.group.game.service.bo.citrus; + +public class LoginReq { + public String mobile; + public String pwd; + public String appCode; + public String code;//验证码 + +} diff --git a/game-service/src/main/java/awesome/group/game/service/bo/citrus/UserBo.java b/game-service/src/main/java/awesome/group/game/service/bo/citrus/UserBo.java new file mode 100644 index 0000000..217f059 --- /dev/null +++ b/game-service/src/main/java/awesome/group/game/service/bo/citrus/UserBo.java @@ -0,0 +1,32 @@ +package awesome.group.game.service.bo.citrus; + +import awesome.group.game.dao.bean.MatrixUser; + +public class UserBo { + public Integer id; + public String mobile; + public String name; + public String nickname; + public String avatar; + public Integer money;//分,已提现金额 + public String aliPayAccount; + public Long income;//ecpm和,分 + public String inviteCode; + public String inviteUrl; + + public UserBo() { + } + + public UserBo(MatrixUser u) { + this.id = u.getId(); + this.mobile = u.getMobile(); + this.name = u.getName(); + this.aliPayAccount = u.getAliPayAccount(); + this.income = u.getIncome(); + this.inviteCode = u.getInviteCode(); + this.inviteUrl = String.format("https://pomelo.bzgames.cn/register/%s", u.getInviteCode()); + this.nickname = u.getNickname(); + this.avatar = u.getAvatar(); + this.money = u.getMoney(); + } +} diff --git a/game-service/src/main/java/awesome/group/game/service/RegisterService.java b/game-service/src/main/java/awesome/group/game/service/citrus/RegisterService.java similarity index 89% rename from game-service/src/main/java/awesome/group/game/service/RegisterService.java rename to game-service/src/main/java/awesome/group/game/service/citrus/RegisterService.java index b9d4ad7..1bdab25 100644 --- a/game-service/src/main/java/awesome/group/game/service/RegisterService.java +++ b/game-service/src/main/java/awesome/group/game/service/citrus/RegisterService.java @@ -1,9 +1,10 @@ -package awesome.group.game.service; +package awesome.group.game.service.citrus; import awesome.group.game.dao.bean.MatrixApp; import awesome.group.game.dao.bean.MatrixUser; import awesome.group.game.dao.mapper.MatrixAppMapper; import awesome.group.game.dao.mapper.MatrixUserMapper; +import awesome.group.game.service.SmsService; import awesome.group.game.service.bo.MatrixAppBo; import awesome.group.game.service.bo.RegisterBo; import awesome.group.game.service.common.exception.PaganiException; @@ -38,6 +39,12 @@ public class RegisterService { return new MatrixAppBo(app); } + public MatrixAppBo getAppByAppCode(String appCode) { + MatrixApp app = appMapper.queryByCode(appCode); + Assert.isTrue(app != null, "参数非法"); + return new MatrixAppBo(app); + } + public void register(RegisterBo bo) { Assert.isTrue(StringUtils.hasText(bo.mobile), "手机号不能为空"); Assert.isTrue(StringUtils.hasText(bo.inviteCode), "邀请码不能为空"); diff --git a/game-service/src/main/java/awesome/group/game/service/citrus/UserService.java b/game-service/src/main/java/awesome/group/game/service/citrus/UserService.java new file mode 100644 index 0000000..50d68b6 --- /dev/null +++ b/game-service/src/main/java/awesome/group/game/service/citrus/UserService.java @@ -0,0 +1,63 @@ +package awesome.group.game.service.citrus; + +import awesome.group.game.dao.bean.MatrixApp; +import awesome.group.game.dao.bean.MatrixUser; +import awesome.group.game.dao.mapper.MatrixAppMapper; +import awesome.group.game.dao.mapper.MatrixUserMapper; +import awesome.group.game.service.SmsService; +import awesome.group.game.service.bo.citrus.LoginReq; +import awesome.group.game.service.bo.citrus.UserBo; +import awesome.group.game.service.common.exception.PaganiException; +import awesome.group.game.service.common.exception.PaganiExceptionCode; +import awesome.group.game.service.util.EncryptUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +@Service +public class UserService { + @Autowired + private MatrixUserMapper userMapper; + + @Autowired + private MatrixAppMapper appMapper; + + @Autowired + private SmsService smsService; + + public MatrixUser login(LoginReq req) { + Assert.isTrue(req != null, "非法请求"); + Assert.isTrue(StringUtils.hasText(req.mobile), "非法请求"); + Assert.isTrue(StringUtils.hasText(req.pwd), "非法请求"); + Assert.isTrue(StringUtils.hasText(req.appCode), "appCode不能为空"); + MatrixApp app = appMapper.queryByCode(req.appCode); + Assert.isTrue(StringUtils.hasText(req.appCode), "appCode非法"); + MatrixUser user = userMapper.selectByAppIdAndMobile(app.getId(), req.mobile); + Assert.isTrue(user != null, "用户不存在"); + String str = EncryptUtil.sha1(req.pwd); + Assert.isTrue(user.getPwd().equals(str), "密码错误"); + return user; + } + + public MatrixUser loginByCode(LoginReq req) { + Assert.isTrue(req != null, "非法请求"); + Assert.isTrue(StringUtils.hasText(req.mobile), "非法请求"); + Assert.isTrue(StringUtils.hasText(req.code), "非法请求"); + Assert.isTrue(StringUtils.hasText(req.appCode), "appCode不能为空"); + MatrixApp app = appMapper.queryByCode(req.appCode); + Assert.isTrue(StringUtils.hasText(req.appCode), "appCode非法"); + if (!smsService.verifyAndUseCaptcha(req.mobile, "login", req.code)) { + throw new PaganiException(PaganiExceptionCode.GENERAL_ERROR, "验证码错误"); + } + + MatrixUser user = userMapper.selectByAppIdAndMobile(app.getId(), req.mobile); + Assert.isTrue(user != null, "用户不存在"); + return user; + } + + public UserBo getUser(Integer uid) { + MatrixUser u = userMapper.selectById(uid); + return new UserBo(u); + } +} diff --git a/game-service/src/test/resources/application-default.yml b/game-service/src/test/resources/application-default.yml index 897d1f5..9909d10 100644 --- a/game-service/src/test/resources/application-default.yml +++ b/game-service/src/test/resources/application-default.yml @@ -9,6 +9,14 @@ spring: proxy-target-class: true pid: file: pid #pid文件名 + redis: + host: 127.0.0.1 + port: 6379 + password: + maxTotal: 128 + poolMaxWaitMs: 50 + timeOutMs: 100 + datasource: game: type: com.zaxxer.hikari.HikariDataSource diff --git a/game-web/src/main/java/awesome/group/game/web/RequestContext.java b/game-web/src/main/java/awesome/group/game/web/RequestContext.java index 7765410..e76c60f 100644 --- a/game-web/src/main/java/awesome/group/game/web/RequestContext.java +++ b/game-web/src/main/java/awesome/group/game/web/RequestContext.java @@ -17,6 +17,7 @@ public class RequestContext { private static final String KEY_UID = "uid"; public static final String ADMIN_ID = "adminId"; + public static final String CITRUS_UID = "citrusUid"; private static final ThreadLocal> THREAD_LOCAL = new ThreadLocal<>(); @@ -37,6 +38,14 @@ public class RequestContext { THREAD_LOCAL.set(context); } + public static void initCitrus(HttpServletRequest request, HttpServletResponse response, Integer userId) { + Map context = new HashMap<>(); + context.put(KEY_REQUEST, request); + context.put(KEY_RESPONSE, response); + context.put(CITRUS_UID, userId); + THREAD_LOCAL.set(context); + } + public static HttpServletRequest getRequest() { return (HttpServletRequest) THREAD_LOCAL.get().get(KEY_REQUEST); @@ -78,6 +87,13 @@ public class RequestContext { return (Integer) THREAD_LOCAL.get().get(ADMIN_ID); } + public static Integer getCitrusUid() { + if (THREAD_LOCAL.get() == null) { + return null; + } + return (Integer) THREAD_LOCAL.get().get(CITRUS_UID); + } + public static void clear() { THREAD_LOCAL.remove(); } diff --git a/game-web/src/main/java/awesome/group/game/web/aop/RestApiAop.java b/game-web/src/main/java/awesome/group/game/web/aop/RestApiAop.java index 02d313e..ed480a0 100644 --- a/game-web/src/main/java/awesome/group/game/web/aop/RestApiAop.java +++ b/game-web/src/main/java/awesome/group/game/web/aop/RestApiAop.java @@ -1,12 +1,11 @@ package awesome.group.game.web.aop; -import awesome.group.game.web.RequestContext; - import awesome.group.game.service.common.exception.PaganiException; import awesome.group.game.service.common.exception.PaganiExceptionCode; import awesome.group.game.service.common.log.L; import awesome.group.game.service.common.log.Status; import awesome.group.game.service.common.response.R; +import awesome.group.game.web.RequestContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.aspectj.lang.ProceedingJoinPoint; @@ -40,6 +39,8 @@ public class RestApiAop { exception = e; if (e instanceof PaganiException) { ret = new R<>(((PaganiException) e).getCode(), e.getMessage(), null); + } else if (e instanceof IllegalArgumentException) { + ret = new R<>(PaganiExceptionCode.GENERAL_ERROR, e.getMessage(), null); } else { status = Status.FAILED; ret = new R<>(PaganiExceptionCode.GENERAL_ERROR, "服务器错误,请稍后重试", null); diff --git a/game-web/src/main/java/awesome/group/game/web/filter/CitrusLoginFilter.java b/game-web/src/main/java/awesome/group/game/web/filter/CitrusLoginFilter.java new file mode 100644 index 0000000..c0b9b1a --- /dev/null +++ b/game-web/src/main/java/awesome/group/game/web/filter/CitrusLoginFilter.java @@ -0,0 +1,89 @@ +package awesome.group.game.web.filter; + +import awesome.group.game.service.common.log.L; +import awesome.group.game.service.common.response.R; +import awesome.group.game.service.util.JwtUtils; +import awesome.group.game.web.RequestContext; +import com.auth0.jwt.exceptions.TokenExpiredException; +import com.google.gson.Gson; +import jakarta.servlet.*; +import jakarta.servlet.annotation.WebFilter; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.util.StringUtils; + +import java.io.IOException; +import java.util.List; + +/** + * @author nidaren + */ +@WebFilter(filterName = "CitrusLoginFilter", urlPatterns = {"/api/citrus/*"}) +public class CitrusLoginFilter implements Filter { + + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + try { + HttpServletRequest httpRequest = (HttpServletRequest) request; + String token = ""; + if(httpRequest.getCookies() != null) { + for (Cookie c : httpRequest.getCookies()) { + if (c.getName().equals("CitrusToken")) { + token = c.getValue(); + } + } + } + List openApi = List.of( + "/api/citrus/register", + "/api/citrus/login" + ); + boolean pass = false; + Integer userId = null; + try { + if (StringUtils.hasText(token)) { + userId = JwtUtils.parseToken(token); + pass = true; + } + } catch (TokenExpiredException e) { + //忽略 + } catch (Exception e) { + L.trace("parseTokenError", "token:" + token, e); + } + String path = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()).replaceAll("[/]+$", ""); + for (String s : openApi) { + if (path.startsWith(s)) { + pass = true; + } + } + if (pass) { + RequestContext.initCitrus(httpRequest, (HttpServletResponse) response, userId); + chain.doFilter(request, response); + } else { + authFail(response); + } + } finally { + RequestContext.clear(); + } + } + + private void authFail(ServletResponse response) throws IOException { + R res = new R<>(-88888, "not login ", null); + Gson gson = new Gson(); + response.setContentType("application/json;charset=UTF-8"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().write(gson.toJson(res)); + response.getWriter().flush(); + } + + @Override + public void destroy() { + + } +} diff --git a/game-web/src/main/java/awesome/group/game/web/rest/citrus/OpenController.java b/game-web/src/main/java/awesome/group/game/web/rest/citrus/OpenController.java new file mode 100644 index 0000000..2fa0c15 --- /dev/null +++ b/game-web/src/main/java/awesome/group/game/web/rest/citrus/OpenController.java @@ -0,0 +1,78 @@ +package awesome.group.game.web.rest.citrus; + +import awesome.group.game.dao.bean.MatrixUser; +import awesome.group.game.service.bo.citrus.LoginReq; +import awesome.group.game.service.citrus.RegisterService; +import awesome.group.game.service.SmsService; +import awesome.group.game.service.bo.MatrixAppBo; +import awesome.group.game.service.bo.RegisterBo; +import awesome.group.game.service.citrus.UserService; +import awesome.group.game.service.common.response.R; +import awesome.group.game.service.util.JwtUtils; +import awesome.group.game.web.RequestContext; +import awesome.group.game.web.aop.RestApi; +import jakarta.servlet.http.Cookie; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/citrus") +public class OpenController { + + @Autowired + private RegisterService registerService; + + @Autowired + private UserService userService; + + @Autowired + private SmsService smsService; + + @PostMapping("/register/sendCode") + @RestApi + public R sendCode(@RequestParam String mobile, @RequestParam String scene) { + smsService.sendCaptcha(mobile, scene); + return new R<>(null); + } + + @GetMapping("/register/getApp") + @RestApi + public R getApp(@RequestParam(required = false) String inviteCode, @RequestParam(required = false) String appCode) { + if (StringUtils.hasText(appCode)) { + return new R<>(registerService.getAppByAppCode(appCode)); + } + if (StringUtils.hasText(inviteCode)) { + return new R<>(registerService.getApp(inviteCode)); + } + return new R<>(null); + } + + @PostMapping("/register/submitRegister") + @RestApi + public R submitRegister(@RequestBody RegisterBo bo) { + registerService.register(bo); + return new R<>(null); + } + + @PostMapping("/loginByPwd") + @RestApi + public R loginByPwd(@RequestBody LoginReq req) { + MatrixUser u = userService.login(req); + String token = JwtUtils.generatorToken(u.getId() + "", 15 * 86400); + Cookie cookie = new Cookie("CitrusToken", token); + RequestContext.getResponse().addCookie(cookie); + return new R<>(R.CODE_SUCCESS, "ok", token); + } + + @PostMapping("/loginByCode") + @RestApi + public R loginByCode(@RequestBody LoginReq req) { + MatrixUser u = userService.loginByCode(req); + String token = JwtUtils.generatorToken(u.getId() + "", 15 * 86400); + Cookie cookie = new Cookie("CitrusToken", token); + RequestContext.getResponse().addCookie(cookie); + return new R<>(R.CODE_SUCCESS, "ok", token); + } + +} diff --git a/game-web/src/main/java/awesome/group/game/web/rest/citrus/RegisterController.java b/game-web/src/main/java/awesome/group/game/web/rest/citrus/RegisterController.java deleted file mode 100644 index a3b9a37..0000000 --- a/game-web/src/main/java/awesome/group/game/web/rest/citrus/RegisterController.java +++ /dev/null @@ -1,42 +0,0 @@ -package awesome.group.game.web.rest.citrus; - -import awesome.group.game.service.RegisterService; -import awesome.group.game.service.SmsService; -import awesome.group.game.service.bo.MatrixAppBo; -import awesome.group.game.service.bo.RegisterBo; -import awesome.group.game.service.common.response.R; -import awesome.group.game.web.aop.RestApi; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("/api/citrus/register") -public class RegisterController { - - @Autowired - private RegisterService registerService; - - @Autowired - private SmsService smsService; - - @PostMapping("/sendCode") - @RestApi - public R sendCode(@RequestParam String mobile) { - smsService.sendCaptcha(mobile, "register"); - return new R<>(null); - } - - @GetMapping("/getApp") - @RestApi - public R getApp(@RequestParam String inviteCode) { - return new R<>(registerService.getApp(inviteCode)); - } - - @PostMapping("/submitRegister") - @RestApi - public R submitRegister(@RequestBody RegisterBo bo) { - registerService.register(bo); - return new R<>(null); - } - -} diff --git a/game-web/src/main/java/awesome/group/game/web/rest/citrus/UserController.java b/game-web/src/main/java/awesome/group/game/web/rest/citrus/UserController.java new file mode 100644 index 0000000..9ce0dd9 --- /dev/null +++ b/game-web/src/main/java/awesome/group/game/web/rest/citrus/UserController.java @@ -0,0 +1,25 @@ +package awesome.group.game.web.rest.citrus; + +import awesome.group.game.service.bo.citrus.UserBo; +import awesome.group.game.service.citrus.UserService; +import awesome.group.game.service.common.response.R; +import awesome.group.game.web.RequestContext; +import awesome.group.game.web.aop.RestApi; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/citrus/user") +public class UserController { + + @Autowired + private UserService userService; + + @GetMapping("/current") + @RestApi + public R currentUser() { + return new R<>(userService.getUser(RequestContext.getCitrusUid())); + } +} diff --git a/pom.xml b/pom.xml index 4bca45e..5b8d240 100644 --- a/pom.xml +++ b/pom.xml @@ -89,6 +89,11 @@ aliyun-sdk-oss 3.10.2 + + com.alipay.sdk + alipay-sdk-java + 4.39.68.ALL + redis.clients jedis