<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8" /> <link rel="stylesheet" type="text/css" href="/static/login/JD_sass/JD1.css" /> <script src="/static/login/JD_js/jquery-3.1.1.min.js" type="text/javascript" charset="utf-8"></script> <title>gulimall</title> </head> <body> <!--顶部logo--> <header> <a href="http://alatusmall.com"><img src="/static/login/JD_img/logo.jpg" /></a> <p>欢迎登录</p> <div class="top-1"> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_06.png" /><span>登录页面,调查问卷</span> </div> </header> <div class="top-2"> <div class="top-2a"> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_11.png" /> <p>依据《网络安全法》,为保障您的账户安全和正常使用,请尽快完成手机号验证!新版《<span>谷粒商城隐私政策</span>》已上线,将更有利于保护您的个人隐私。</p> </div> </div> <!--大图--> <div class="top-3"> <div class="img_1"> <img src="/static/login/JD_img/5731485aN1134b4f0.png" /> </div> <div id="sign"> <div class="si_top"> <p> <span>谷粒商城不会以任何理由要求您转账汇款,谨防诈骗。</span> </p> </div> <div class="si_cen"> <h2 class="act btn1">扫码登录</h2> <span>|</span> <h2 class="btn1">账户登录</h2> </div> <div class="si_bom tab"> <img src="/static/login/JD_img/show.png" class="bom_1" /> <a href="/static/login/#"><img src="/static/login/JD_img/phone-orange.png" class="bom_2" /></a> <h6>打开<span class="red">手机谷粒商城</span> 扫描二维码</h6> <p> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_15.png" /> <span><a href="/static/login/#">免输入</a></span> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_17.png" /> <span><a href="/static/login/#">更快</a></span> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_19.png" /> <span><a href="/static/login/#">更安全</a></span> </p> </div> <div class="si_bom1 tab" style="display: none;"> <div class="error"> <div></div> 请输入账户名和密码 </div> <form action="/login" method="post"> <div style="color: red" th:if="${errors!=null?(#maps.containsKey(errors,'msg')?errors.msg:''):''}"></div> <ul> <li class="top_1"> <img src="/static/login/JD_img/user_03.png" class="err_img1" /> <input name="loginAccount" type="text" placeholder=" 邮箱/用户名/已验证手机" class="user" /> </li> <li> <img src="/static/login/JD_img/user_06.png" class="err_img2" /> <input name="password" type="password" placeholder=" 密码" class="password" /> </li> <li class="bri"> <a href="/static/login/">忘记密码</a> </li> <li class="ent"><button type="submit" class="btn2"><a class="a">登 录</a></button></li> </ul> </form> </div> <div class="si_out"> <ul> <li> <a href="/static/login/#"> <img src="/static/login/JD_img/qq.png" /> <span>QQ</span> </a> </li> <li class="f4"> | </li> <li> <a href="/static/login/"> <img src="/static/login/JD_img/weixin.png" /> <span>微信</span> </a> </li> </ul> <h5 class="rig"> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_25.png" /> <span><a href="http://auth.alatusmall.com/reg.html">立即注册</a></span> </h5> </div> </div> </div> <!--底部--> <footer> <ul> <li><a href="/static/login/#">关于我们</a></li> <li class="little">|</li> <li><a href="/static/login/#">联系我们</a></li> <li class="little">|</li> <li><a href="/static/login/#">人才招聘</a></li> <li class="little">|</li> <li><a href="/static/login/#">商家入驻</a></li> <li class="little">|</li> <li><a href="/static/login/#">广告服务</a></li> <li class="little">|</li> <li><a href="/static/login/#">手机谷粒商城</a></li> <li class="little">|</li> <li><a href="/static/login/#">友情链接</a></li> <li class="little">|</li> <li><a href="/static/login/#">销售联盟</a></li> <li class="little">|</li> <li><a href="/static/login/#">谷粒商城社区</a></li> <li class="little">|</li> <li><a href="/static/login/#">谷粒商城公益</a></li> <li class="little">|</li> <li><a href="/static/login/#">English Site</a></li> </ul> <span>Copyright © 2004-2017 谷粒商城gulimall.com 版权所有</span> </footer> </body> <script type="text/javascript"> var alDiv = document.getElementsByClassName('tab'); var alBtn = document.getElementsByTagName('h2'); alDiv[0].style.display = 'block'; var act = alBtn[0] for (var i = 0; i < alBtn.length; i++) { alBtn[i].indent = i; alBtn[i].onclick = function() { act.className = ''; alDiv[act.indent].style.display = 'none'; this.className = 'act' alDiv[this.indent].style.display = 'block' act = this } } var btn2 = document.getElementsByClassName('btn2')[0]; var user = document.getElementsByClassName('user')[0]; var pass = document.getElementsByClassName('password')[0]; var err = document.getElementsByClassName('error')[0]; var err_img1 = document.getElementsByClassName('err_img1')[0]; var err_img2 = document.getElementsByClassName('err_img2')[0]; btn2.onclick = function() { if (user.value === '' || pass.value === '') { err.style.display = 'block'; user.style.border = '1px solid red'; pass.style.border = '1px solid red'; err_img1.src = 'JD_img/img11.png'; err_img2.src = 'JD_img/img22.png'; } user.onfocus = function() { err_img1.src = 'JD_img/grow1.png'; user.style.border = '1px solid #999'; } pass.onfocus = function() { err_img2.src = 'JD_img/grow2.png'; pass.style.border = '1px solid #999'; } user.onblur = function() { err_img1.src = 'JD_img/img11.png'; user.style.border = '1px solid red'; } pass.onblur = function() { err_img2.src = 'JD_img/img22.png'; pass.style.border = '1px solid red'; } } </script> </html>
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8" /> <link rel="stylesheet" type="text/css" href="/static/login/JD_sass/JD1.css" /> <script src="/static/login/JD_js/jquery-3.1.1.min.js" type="text/javascript" charset="utf-8"></script> <title>gulimall</title> </head> <body> <!--顶部logo--> <header> <a href="http://alatusmall.com"><img src="/static/login/JD_img/logo.jpg" /></a> <p>欢迎登录</p> <div class="top-1"> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_06.png" /><span>登录页面,调查问卷</span> </div> </header> <div class="top-2"> <div class="top-2a"> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_11.png" /> <p>依据《网络安全法》,为保障您的账户安全和正常使用,请尽快完成手机号验证!新版《<span>谷粒商城隐私政策</span>》已上线,将更有利于保护您的个人隐私。</p> </div> </div> <!--大图--> <div class="top-3"> <div class="img_1"> <img src="/static/login/JD_img/5731485aN1134b4f0.png" /> </div> <div id="sign"> <div class="si_top"> <p> <span>谷粒商城不会以任何理由要求您转账汇款,谨防诈骗。</span> </p> </div> <div class="si_cen"> <h2 class="act btn1">扫码登录</h2> <span>|</span> <h2 class="btn1">账户登录</h2> </div> <div class="si_bom tab"> <img src="/static/login/JD_img/show.png" class="bom_1" /> <a href="/static/login/#"><img src="/static/login/JD_img/phone-orange.png" class="bom_2" /></a> <h6>打开<span class="red">手机谷粒商城</span> 扫描二维码</h6> <p> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_15.png" /> <span><a href="/static/login/#">免输入</a></span> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_17.png" /> <span><a href="/static/login/#">更快</a></span> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_19.png" /> <span><a href="/static/login/#">更安全</a></span> </p> </div> <div class="si_bom1 tab" style="display: none;"> <div class="error"> <div></div> 请输入账户名和密码 </div> <form action="/login" method="post"> <div style="color: red" th:if="${errors!=null?(#maps.containsKey(errors,'msg')?errors.msg:''):''}"></div> <ul> <li class="top_1"> <img src="/static/login/JD_img/user_03.png" class="err_img1" /> <input name="loginAccount" type="text" placeholder=" 邮箱/用户名/已验证手机" class="user" /> </li> <li> <img src="/static/login/JD_img/user_06.png" class="err_img2" /> <input name="password" type="password" placeholder=" 密码" class="password" /> </li> <li class="bri"> <a href="/static/login/">忘记密码</a> </li> <li class="ent"><button type="submit" class="btn2"><a class="a">登 录</a></button></li> </ul> </form> </div> <div class="si_out"> <ul> <li> <a href="/static/login/#"> <img src="/static/login/JD_img/qq.png" /> <span>QQ</span> </a> </li> <li class="f4"> | </li> <li> <a href="/static/login/"> <img src="/static/login/JD_img/weixin.png" /> <span>微信</span> </a> </li> </ul> <h5 class="rig"> <img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_25.png" /> <span><a href="http://auth.alatusmall.com/reg.html">立即注册</a></span> </h5> </div> </div> </div> <!--底部--> <footer> <ul> <li><a href="/static/login/#">关于我们</a></li> <li class="little">|</li> <li><a href="/static/login/#">联系我们</a></li> <li class="little">|</li> <li><a href="/static/login/#">人才招聘</a></li> <li class="little">|</li> <li><a href="/static/login/#">商家入驻</a></li> <li class="little">|</li> <li><a href="/static/login/#">广告服务</a></li> <li class="little">|</li> <li><a href="/static/login/#">手机谷粒商城</a></li> <li class="little">|</li> <li><a href="/static/login/#">友情链接</a></li> <li class="little">|</li> <li><a href="/static/login/#">销售联盟</a></li> <li class="little">|</li> <li><a href="/static/login/#">谷粒商城社区</a></li> <li class="little">|</li> <li><a href="/static/login/#">谷粒商城公益</a></li> <li class="little">|</li> <li><a href="/static/login/#">English Site</a></li> </ul> <span>Copyright © 2004-2017 谷粒商城gulimall.com 版权所有</span> </footer> </body> <script type="text/javascript"> var alDiv = document.getElementsByClassName('tab'); var alBtn = document.getElementsByTagName('h2'); alDiv[0].style.display = 'block'; var act = alBtn[0] for (var i = 0; i < alBtn.length; i++) { alBtn[i].indent = i; alBtn[i].onclick = function() { act.className = ''; alDiv[act.indent].style.display = 'none'; this.className = 'act' alDiv[this.indent].style.display = 'block' act = this } } var btn2 = document.getElementsByClassName('btn2')[0]; var user = document.getElementsByClassName('user')[0]; var pass = document.getElementsByClassName('password')[0]; var err = document.getElementsByClassName('error')[0]; var err_img1 = document.getElementsByClassName('err_img1')[0]; var err_img2 = document.getElementsByClassName('err_img2')[0]; btn2.onclick = function() { if (user.value === '' || pass.value === '') { err.style.display = 'block'; user.style.border = '1px solid red'; pass.style.border = '1px solid red'; err_img1.src = 'JD_img/img11.png'; err_img2.src = 'JD_img/img22.png'; } user.onfocus = function() { err_img1.src = 'JD_img/grow1.png'; user.style.border = '1px solid #999'; } pass.onfocus = function() { err_img2.src = 'JD_img/grow2.png'; pass.style.border = '1px solid #999'; } user.onblur = function() { err_img1.src = 'JD_img/img11.png'; user.style.border = '1px solid red'; } pass.onblur = function() { err_img2.src = 'JD_img/img22.png'; pass.style.border = '1px solid red'; } } </script> </html>
package com.alatus.mall.auth.vo; import lombok.Data; @Data public class UserLoginVo { private String loginAccount; private String password; }
package com.alatus.mall.auth.vo; import lombok.Data; @Data public class UserLoginVo { private String loginAccount; private String password; }
package com.alatus.mall.auth.app; import com.alatus.common.constant.AuthServerConstant; import com.alatus.common.exception.BizCodeEnum; import com.alatus.common.utils.R; import com.alatus.mall.auth.feign.MemberFeignService; import com.alatus.mall.auth.feign.ThirdPartFeignService; import com.alatus.mall.auth.vo.UserLoginVo; import com.alatus.mall.auth.vo.UserRegisterVo; import com.alibaba.fastjson.TypeReference; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Controller public class LoginController { @Autowired private ThirdPartFeignService thirdPartFeignService; @Autowired private StringRedisTemplate redisTemplate; @Autowired private MemberFeignService memberFeignService; @GetMapping("/sms/sendCode") @ResponseBody public R sendCode(@RequestParam("phone") String phone){ R checkPhone = memberFeignService.checkPhone(phone); if(checkPhone.getCode()==0){ // TODO 接口防刷 // 防止反复刷验证码 String value = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone); if(value!=null&&!StringUtils.isEmpty(value)){ long time = Long.parseLong(value.split("_")[1]); if(System.currentTimeMillis() - time < 60000){ // 60秒内不能再发 return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(),BizCodeEnum.SMS_CODE_EXCEPTION.getMsg()); } } String code = UUID.randomUUID().toString().substring(0, 5); R sendCode = thirdPartFeignService.sendCode(phone, code); // 缓存验证码 redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+phone,code+"_"+System.currentTimeMillis(),10, TimeUnit.MINUTES); if(sendCode.getCode()==0){ return R.ok(); } else{ return R.error(); } } else{ return checkPhone; } } //RedirectAttributes redirectAttributes模拟重定向携带数据 // TODO 重定向携带数据,利用session原理,将数据放在session中 // 只要跳到下一个页面取出这个数据后,session的数据就被删掉了 // TODO 分布式Session问题解决!!! @PostMapping("/register") public String register(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes){ if(result.hasErrors()){ // 收集错误信息返回 Map<String, String> collect = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage)); redirectAttributes.addFlashAttribute("errors",collect); // 原请求是post请求,当我们失败以后,在这里转发,转发是会保持请求方式不变的,但是路径访问默认是get // 就会出现错误 // 原理是使用了HttpSession的底层实现 return "redirect:http://auth.alatusmall.com/reg.html"; } else{ // 校验验证码 String code = vo.getCode(); String codeValue = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); if(codeValue!=null&&!StringUtils.isEmpty(codeValue)){ // 截串获取验证码信息 String redisCode = codeValue.split("_")[0]; if(redisCode.equals(code)){ // 验证码通过以后,删除验证码,令牌机制,验证码用过就不再可用了 redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); // 调用远程服务进行注册 R register = memberFeignService.register(vo); if(register.getCode()==0){ return "redirect:http://auth.alatusmall.com/login.html"; } else{ Error(redirectAttributes,"msg",register.get("msg",new TypeReference<String>(){})); return "redirect:http://auth.alatusmall.com/reg.html"; } } else{ // 验证码错误 Error(redirectAttributes,"code","验证码错误"); return "redirect:http://auth.alatusmall.com/reg.html"; } } else{ // 没有验证码 Error(redirectAttributes,"code","验证码错误"); return "redirect:http://auth.alatusmall.com/reg.html"; } } } private void Error(RedirectAttributes redirectAttributes,String msg,String error){ Map<String,String> errors = new HashMap<>(); errors.put(msg,error); redirectAttributes.addFlashAttribute("errors",errors); } @PostMapping("/login") public String login(UserLoginVo userLoginVo,RedirectAttributes redirectAttributes){ R login = memberFeignService.login(userLoginVo); if (login.getCode()==0) { // 登陆成功 return "redirect:http://alatusmall.com"; } else{ // 登陆失败 Error(redirectAttributes,"msg",login.get("msg",new TypeReference<String>(){})); return "redirect:http://auth.alatusmall.com/login.html"; } } }
package com.alatus.mall.auth.app; import com.alatus.common.constant.AuthServerConstant; import com.alatus.common.exception.BizCodeEnum; import com.alatus.common.utils.R; import com.alatus.mall.auth.feign.MemberFeignService; import com.alatus.mall.auth.feign.ThirdPartFeignService; import com.alatus.mall.auth.vo.UserLoginVo; import com.alatus.mall.auth.vo.UserRegisterVo; import com.alibaba.fastjson.TypeReference; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Controller public class LoginController { @Autowired private ThirdPartFeignService thirdPartFeignService; @Autowired private StringRedisTemplate redisTemplate; @Autowired private MemberFeignService memberFeignService; @GetMapping("/sms/sendCode") @ResponseBody public R sendCode(@RequestParam("phone") String phone){ R checkPhone = memberFeignService.checkPhone(phone); if(checkPhone.getCode()==0){ // TODO 接口防刷 // 防止反复刷验证码 String value = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone); if(value!=null&&!StringUtils.isEmpty(value)){ long time = Long.parseLong(value.split("_")[1]); if(System.currentTimeMillis() - time < 60000){ // 60秒内不能再发 return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(),BizCodeEnum.SMS_CODE_EXCEPTION.getMsg()); } } String code = UUID.randomUUID().toString().substring(0, 5); R sendCode = thirdPartFeignService.sendCode(phone, code); // 缓存验证码 redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+phone,code+"_"+System.currentTimeMillis(),10, TimeUnit.MINUTES); if(sendCode.getCode()==0){ return R.ok(); } else{ return R.error(); } } else{ return checkPhone; } } //RedirectAttributes redirectAttributes模拟重定向携带数据 // TODO 重定向携带数据,利用session原理,将数据放在session中 // 只要跳到下一个页面取出这个数据后,session的数据就被删掉了 // TODO 分布式Session问题解决!!! @PostMapping("/register") public String register(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes){ if(result.hasErrors()){ // 收集错误信息返回 Map<String, String> collect = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage)); redirectAttributes.addFlashAttribute("errors",collect); // 原请求是post请求,当我们失败以后,在这里转发,转发是会保持请求方式不变的,但是路径访问默认是get // 就会出现错误 // 原理是使用了HttpSession的底层实现 return "redirect:http://auth.alatusmall.com/reg.html"; } else{ // 校验验证码 String code = vo.getCode(); String codeValue = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); if(codeValue!=null&&!StringUtils.isEmpty(codeValue)){ // 截串获取验证码信息 String redisCode = codeValue.split("_")[0]; if(redisCode.equals(code)){ // 验证码通过以后,删除验证码,令牌机制,验证码用过就不再可用了 redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone()); // 调用远程服务进行注册 R register = memberFeignService.register(vo); if(register.getCode()==0){ return "redirect:http://auth.alatusmall.com/login.html"; } else{ Error(redirectAttributes,"msg",register.get("msg",new TypeReference<String>(){})); return "redirect:http://auth.alatusmall.com/reg.html"; } } else{ // 验证码错误 Error(redirectAttributes,"code","验证码错误"); return "redirect:http://auth.alatusmall.com/reg.html"; } } else{ // 没有验证码 Error(redirectAttributes,"code","验证码错误"); return "redirect:http://auth.alatusmall.com/reg.html"; } } } private void Error(RedirectAttributes redirectAttributes,String msg,String error){ Map<String,String> errors = new HashMap<>(); errors.put(msg,error); redirectAttributes.addFlashAttribute("errors",errors); } @PostMapping("/login") public String login(UserLoginVo userLoginVo,RedirectAttributes redirectAttributes){ R login = memberFeignService.login(userLoginVo); if (login.getCode()==0) { // 登陆成功 return "redirect:http://alatusmall.com"; } else{ // 登陆失败 Error(redirectAttributes,"msg",login.get("msg",new TypeReference<String>(){})); return "redirect:http://auth.alatusmall.com/login.html"; } } }
package com.alatus.mall.member.controller; import java.util.Arrays; import java.util.Map; import com.alatus.common.exception.BizCodeEnum; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberLoginVo; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.R; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ @RestController @RequestMapping("member/member") public class MemberController { @Autowired private MemberService memberService; @PostMapping("register") public R register(@RequestBody MemberRegisterVo memberRegisterVo){ try{ memberService.register(memberRegisterVo); } catch (UsernameExistException e){ return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(), BizCodeEnum.USER_EXIST_EXCEPTION.getMsg()); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } @PostMapping("/login") public R login(@RequestBody MemberLoginVo memberLoginVo){ MemberEntity member = memberService.login(memberLoginVo); if(member!=null){ return R.ok(); } else{ return R.error(BizCodeEnum.LOGINACCTOUNT_PASSWORD_INVALID_EXCEPTION.getCode(),BizCodeEnum.LOGINACCTOUNT_PASSWORD_INVALID_EXCEPTION.getMsg()); } } /** * 列表 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = memberService.queryPage(params); return R.ok().put("page", page); } /** * 验证手机号是否已被使用 */ @GetMapping("/checkPhone/{phone}") public R checkPhone(@PathVariable("phone")String phone){ try{ memberService.checkPhoneUnique(phone); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } /** * 信息 */ @RequestMapping("/info/{id}") public R info(@PathVariable("id") Long id){ MemberEntity member = memberService.getById(id); return R.ok().put("member", member); } /** * 保存 */ @RequestMapping("/save") public R save(@RequestBody MemberEntity member){ memberService.save(member); return R.ok(); } /** * 修改 */ @RequestMapping("/update") public R update(@RequestBody MemberEntity member){ memberService.updateById(member); return R.ok(); } /** * 删除 */ @RequestMapping("/delete") public R delete(@RequestBody Long[] ids){ memberService.removeByIds(Arrays.asList(ids)); return R.ok(); } }
package com.alatus.mall.member.controller; import java.util.Arrays; import java.util.Map; import com.alatus.common.exception.BizCodeEnum; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberLoginVo; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.R; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ @RestController @RequestMapping("member/member") public class MemberController { @Autowired private MemberService memberService; @PostMapping("register") public R register(@RequestBody MemberRegisterVo memberRegisterVo){ try{ memberService.register(memberRegisterVo); } catch (UsernameExistException e){ return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(), BizCodeEnum.USER_EXIST_EXCEPTION.getMsg()); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } @PostMapping("/login") public R login(@RequestBody MemberLoginVo memberLoginVo){ MemberEntity member = memberService.login(memberLoginVo); if(member!=null){ return R.ok(); } else{ return R.error(BizCodeEnum.LOGINACCTOUNT_PASSWORD_INVALID_EXCEPTION.getCode(),BizCodeEnum.LOGINACCTOUNT_PASSWORD_INVALID_EXCEPTION.getMsg()); } } /** * 列表 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = memberService.queryPage(params); return R.ok().put("page", page); } /** * 验证手机号是否已被使用 */ @GetMapping("/checkPhone/{phone}") public R checkPhone(@PathVariable("phone")String phone){ try{ memberService.checkPhoneUnique(phone); } catch (PhoneExistException e){ return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg()); } return R.ok(); } /** * 信息 */ @RequestMapping("/info/{id}") public R info(@PathVariable("id") Long id){ MemberEntity member = memberService.getById(id); return R.ok().put("member", member); } /** * 保存 */ @RequestMapping("/save") public R save(@RequestBody MemberEntity member){ memberService.save(member); return R.ok(); } /** * 修改 */ @RequestMapping("/update") public R update(@RequestBody MemberEntity member){ memberService.updateById(member); return R.ok(); } /** * 删除 */ @RequestMapping("/delete") public R delete(@RequestBody Long[] ids){ memberService.removeByIds(Arrays.asList(ids)); return R.ok(); } }
package com.alatus.mall.auth.feign; import com.alatus.common.utils.R; import com.alatus.mall.auth.vo.UserLoginVo; import com.alatus.mall.auth.vo.UserRegisterVo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @FeignClient(name = "Mall-member") public interface MemberFeignService { @PostMapping("/member/member/register") R register(@RequestBody UserRegisterVo memberRegisterVo); @GetMapping("/member/member/checkPhone/{phone}") R checkPhone(@PathVariable("phone")String phone); @PostMapping("/member/member/login") R login(@RequestBody UserLoginVo userLoginVo); }
package com.alatus.mall.auth.feign; import com.alatus.common.utils.R; import com.alatus.mall.auth.vo.UserLoginVo; import com.alatus.mall.auth.vo.UserRegisterVo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @FeignClient(name = "Mall-member") public interface MemberFeignService { @PostMapping("/member/member/register") R register(@RequestBody UserRegisterVo memberRegisterVo); @GetMapping("/member/member/checkPhone/{phone}") R checkPhone(@PathVariable("phone")String phone); @PostMapping("/member/member/login") R login(@RequestBody UserLoginVo userLoginVo); }
package com.alatus.common.exception; import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter public enum BizCodeEnum { UNKNOW_EXCEPTION(10000,"系统未知异常"), VALID_EXCEPTION(10001,"参数校验失败"), SMS_CODE_EXCEPTION(10002,"短信验证码获取频率太高,请稍后再试"), USER_EXIST_EXCEPTION(15001,"用户名存在异常"), PHONE_EXIST_EXCEPTION(15002,"手机号存在异常"), LOGINACCTOUNT_PASSWORD_INVALID_EXCEPTION(15003,"账号或密码错误"), PRODUCT_UP_EXCEPTION(11000,"商品上架异常"); private int code; private String msg; }
package com.alatus.common.exception; import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter public enum BizCodeEnum { UNKNOW_EXCEPTION(10000,"系统未知异常"), VALID_EXCEPTION(10001,"参数校验失败"), SMS_CODE_EXCEPTION(10002,"短信验证码获取频率太高,请稍后再试"), USER_EXIST_EXCEPTION(15001,"用户名存在异常"), PHONE_EXIST_EXCEPTION(15002,"手机号存在异常"), LOGINACCTOUNT_PASSWORD_INVALID_EXCEPTION(15003,"账号或密码错误"), PRODUCT_UP_EXCEPTION(11000,"商品上架异常"); private int code; private String msg; }
package com.alatus.mall.member.service; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberLoginVo; import com.alatus.mall.member.vo.MemberRegisterVo; import com.baomidou.mybatisplus.extension.service.IService; import com.alatus.common.utils.PageUtils; import com.alatus.mall.member.entity.MemberEntity; import java.util.Map; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ public interface MemberService extends IService<MemberEntity> { PageUtils queryPage(Map<String, Object> params); void register(MemberRegisterVo memberRegisterVo); void checkPhoneUnique(String phone) throws PhoneExistException; void checkUsernameUnique(String username) throws UsernameExistException; MemberEntity login(MemberLoginVo memberLoginVo); }
package com.alatus.mall.member.service; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.vo.MemberLoginVo; import com.alatus.mall.member.vo.MemberRegisterVo; import com.baomidou.mybatisplus.extension.service.IService; import com.alatus.common.utils.PageUtils; import com.alatus.mall.member.entity.MemberEntity; import java.util.Map; /** * 会员 * * @author alatus * @email 1571345941@qq.com * @date 2024-03-12 13:40:22 */ public interface MemberService extends IService<MemberEntity> { PageUtils queryPage(Map<String, Object> params); void register(MemberRegisterVo memberRegisterVo); void checkPhoneUnique(String phone) throws PhoneExistException; void checkUsernameUnique(String username) throws UsernameExistException; MemberEntity login(MemberLoginVo memberLoginVo); }
package com.alatus.mall.member.service.impl; import com.alatus.mall.member.entity.MemberLevelEntity; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.service.MemberLevelService; import com.alatus.mall.member.vo.MemberLoginVo; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import java.util.Map; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.Query; import com.alatus.mall.member.dao.MemberDao; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; @Service("memberService") public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService { @Autowired private MemberLevelService memberLevelService; @Override public PageUtils queryPage(Map<String, Object> params) { IPage<MemberEntity> page = this.page( new Query<MemberEntity>().getPage(params), new QueryWrapper<MemberEntity>() ); return new PageUtils(page); } @Override public void register(MemberRegisterVo memberRegisterVo) { // 检查用户名和手机号是否唯一(为了能让上层感知异常,我们这里抛出去)采用异常机制 checkPhoneUnique(memberRegisterVo.getPhone()); checkUsernameUnique(memberRegisterVo.getUsername()); MemberEntity memberEntity = new MemberEntity(); // 设置默认等级 MemberLevelEntity memberLevelEntity = memberLevelService.getDefaultLevel(); memberEntity.setLevelId(memberLevelEntity.getId()); // 密码绝对不能传递明文,一旦数据库泄露,就会导致所有数据曝光,我们应该存储MD5加密后的数据 // MD5任何长度大小的数据,算出的值都是固定的,源数据哪怕任何改动,得到的MD5值都会不同 // 百度网盘的秒传功能本质上就是MD5值相同,在这个情况下,不同文件就不需要再次上传,达到了秒传效果 // MD5的最大特点就说不可逆,无法通过MD5获取源数据的值 // MD5抗修改性意味着MD5的数据可以通过暴力算或者字典查的穷举法获得,网上有一大堆对应的彩虹表 // 因此MD5不能直接用来加密,必须加盐存储 // 使用Spring原生的加密器实现 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); memberEntity.setPassword(passwordEncoder.encode(memberRegisterVo.getPassword())); // 用户名 memberEntity.setUsername(memberRegisterVo.getUsername()); // 手机号 memberEntity.setMobile(memberRegisterVo.getPhone()); this.baseMapper.insert(memberEntity); } @Override public void checkPhoneUnique(String phone) throws PhoneExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone)); if(count>0){ throw new PhoneExistException(); } } @Override public void checkUsernameUnique(String username) throws UsernameExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username)); if(count>0){ throw new UsernameExistException(); } } @Override public MemberEntity login(MemberLoginVo memberLoginVo) { String loginAccount = memberLoginVo.getLoginAccount(); String password = memberLoginVo.getPassword();; // 去数据库查询 MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", loginAccount) .or().eq("mobile", loginAccount)); if(memberEntity==null){ // 登陆失败 return null; } else{ String memberEntityPassword = memberEntity.getPassword(); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // 进行密码匹配 boolean matches = passwordEncoder.matches(password, memberEntityPassword); if(matches){ return memberEntity; } else{ return null; } } } }
package com.alatus.mall.member.service.impl; import com.alatus.mall.member.entity.MemberLevelEntity; import com.alatus.mall.member.exception.PhoneExistException; import com.alatus.mall.member.exception.UsernameExistException; import com.alatus.mall.member.service.MemberLevelService; import com.alatus.mall.member.vo.MemberLoginVo; import com.alatus.mall.member.vo.MemberRegisterVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import java.util.Map; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.Query; import com.alatus.mall.member.dao.MemberDao; import com.alatus.mall.member.entity.MemberEntity; import com.alatus.mall.member.service.MemberService; @Service("memberService") public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService { @Autowired private MemberLevelService memberLevelService; @Override public PageUtils queryPage(Map<String, Object> params) { IPage<MemberEntity> page = this.page( new Query<MemberEntity>().getPage(params), new QueryWrapper<MemberEntity>() ); return new PageUtils(page); } @Override public void register(MemberRegisterVo memberRegisterVo) { // 检查用户名和手机号是否唯一(为了能让上层感知异常,我们这里抛出去)采用异常机制 checkPhoneUnique(memberRegisterVo.getPhone()); checkUsernameUnique(memberRegisterVo.getUsername()); MemberEntity memberEntity = new MemberEntity(); // 设置默认等级 MemberLevelEntity memberLevelEntity = memberLevelService.getDefaultLevel(); memberEntity.setLevelId(memberLevelEntity.getId()); // 密码绝对不能传递明文,一旦数据库泄露,就会导致所有数据曝光,我们应该存储MD5加密后的数据 // MD5任何长度大小的数据,算出的值都是固定的,源数据哪怕任何改动,得到的MD5值都会不同 // 百度网盘的秒传功能本质上就是MD5值相同,在这个情况下,不同文件就不需要再次上传,达到了秒传效果 // MD5的最大特点就说不可逆,无法通过MD5获取源数据的值 // MD5抗修改性意味着MD5的数据可以通过暴力算或者字典查的穷举法获得,网上有一大堆对应的彩虹表 // 因此MD5不能直接用来加密,必须加盐存储 // 使用Spring原生的加密器实现 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); memberEntity.setPassword(passwordEncoder.encode(memberRegisterVo.getPassword())); // 用户名 memberEntity.setUsername(memberRegisterVo.getUsername()); // 手机号 memberEntity.setMobile(memberRegisterVo.getPhone()); this.baseMapper.insert(memberEntity); } @Override public void checkPhoneUnique(String phone) throws PhoneExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone)); if(count>0){ throw new PhoneExistException(); } } @Override public void checkUsernameUnique(String username) throws UsernameExistException{ Integer count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username)); if(count>0){ throw new UsernameExistException(); } } @Override public MemberEntity login(MemberLoginVo memberLoginVo) { String loginAccount = memberLoginVo.getLoginAccount(); String password = memberLoginVo.getPassword();; // 去数据库查询 MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", loginAccount) .or().eq("mobile", loginAccount)); if(memberEntity==null){ // 登陆失败 return null; } else{ String memberEntityPassword = memberEntity.getPassword(); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // 进行密码匹配 boolean matches = passwordEncoder.matches(password, memberEntityPassword); if(matches){ return memberEntity; } else{ return null; } } } }
package com.alatus.mall.member.vo; import lombok.Data; @Data public class MemberLoginVo { private String loginAccount; private String password; }
package com.alatus.mall.member.vo; import lombok.Data; @Data public class MemberLoginVo { private String loginAccount; private String password; }