商城业务--> 认证服务

短信验证码在控制台打印。
微博登陆请扫码登陆。账号密码登陆可能报错,但不影响结果,直接返回即可
This commit is contained in:
Kirk Lin 2021-07-09 20:01:01 +08:00
parent 57119140f0
commit 5782c0679a
53 changed files with 2230 additions and 520 deletions

View file

@ -30,6 +30,17 @@
</exclusion>
</exclusions>
</dependency>
<!-- 整合Spring-seesion -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
@ -51,7 +62,7 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 自定义配置文件带提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>

View file

@ -0,0 +1,20 @@
package name.lkk.kkmall.authserver.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author: kirklin
* @date: 2021/7/9 4:28 下午
* @description:
*/
@Configuration
public class AuthServerWebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("/reg.html").setViewName("reg");
}
}

View file

@ -0,0 +1,35 @@
package name.lkk.kkmall.authserver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* 设置Session作用域自定义cookie序列化机制
*
* @author kirklin
*/
@Configuration
public class KkMallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 明确的指定Cookie的作用域
cookieSerializer.setDomainName("kkmall.com");
cookieSerializer.setCookieName("MALLSESSION");
return cookieSerializer;
}
/**
* 自定义序列化机制
* 这里方法名必须是springSessionDefaultRedisSerializer
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}

View file

@ -1,25 +1,163 @@
package name.lkk.kkmall.authserver.controller;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import name.lkk.common.constant.AuthServerConstant;
import name.lkk.common.exception.BizCodeEnum;
import name.lkk.common.utils.R;
import name.lkk.common.vo.MemberRsepVo;
import name.lkk.kkmall.authserver.feign.MemberFeignService;
import name.lkk.kkmall.authserver.feign.ThirdServicesFeignService;
import name.lkk.kkmall.authserver.vo.UserLoginVo;
import name.lkk.kkmall.authserver.vo.UserRegisterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpSession;
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;
/**
* @author: kirklin
* @date: 2021/6/26 3:21 下午
* @description:
*/
@SuppressWarnings("HttpUrlsUsage")
@Controller
@Slf4j
public class LoginController {
@GetMapping({"/login.html","/","/index","/index.html"})
public String loginPage(){
@Autowired
private ThirdServicesFeignService thirdServicesFeignService;
@Autowired
private MemberFeignService memberFeignService;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping({"/login.html", "/", "/index", "/index.html"})
public String loginPage(HttpSession session) {
Object attribute = session.getAttribute(AuthServerConstant.LOGIN_USER);
if (attribute == null) {
return "login";
}
log.info(attribute.toString());
return "redirect:http://kkmall.com";
}
@GetMapping({"/reg.html"})
public String regPage(){
return "reg";
@PostMapping("/login")
public String login(UserLoginVo userLoginVo, RedirectAttributes redirectAttributes, HttpSession session) {
// 远程登录
R r = memberFeignService.login(userLoginVo);
if (r.getCode() == 0) {
// 登录成功
MemberRsepVo rsepVo = r.getData("data", new TypeReference<MemberRsepVo>() {
});
session.setAttribute(AuthServerConstant.LOGIN_USER, rsepVo);
log.info("\n欢迎 [" + rsepVo.getUsername() + "] 登录");
return "redirect:http://kkmall.com";
} else {
HashMap<String, String> error = new HashMap<>();
// 获取错误信息
error.put("msg", r.getData("msg", new TypeReference<String>() {
}));
redirectAttributes.addFlashAttribute("errors", error);
return "redirect:http://auth.kkmall.com/login.html";
}
}
@ResponseBody
@GetMapping("/sms/regsendcode")
public R sendCode(@RequestParam("phone") String phone) {
// TODO 接口防刷
String redisCode = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
if (null != redisCode && redisCode.length() > 0) {
long CuuTime = Long.parseLong(redisCode.split("_")[1]);
if (System.currentTimeMillis() - CuuTime < 60 * 1000) {
return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(), BizCodeEnum.SMS_CODE_EXCEPTION.getMsg());
}
}
String code = UUID.randomUUID().toString().substring(0, 6);
String redis_code = code + "_" + System.currentTimeMillis();
// 缓存验证码
stringRedisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone, redis_code, 10, TimeUnit.MINUTES);
try {
return thirdServicesFeignService.sendCode(phone, code);
} catch (Exception e) {
log.warn("远程调用不知名错误 [无需解决]");
}
return R.ok();
}
/**
* TODO 重定向携带数据,利用session原理 将数据放在sessoin中 取一次之后删掉
* <p>
* TODO 1. 分布式下的session问题
* 校验
* RedirectAttributes redirectAttributes 模拟重定向带上数据
*/
@PostMapping("/register")
public String register(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
// 将错误属性与错误信息一一封装
Map<String, String> errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, fieldError -> fieldError.getDefaultMessage()));
// addFlashAttribute 这个数据只取一次
redirectAttributes.addFlashAttribute("errors", errors);
return "redirect:http://auth.kkmall.com/reg.html";
}
// 开始注册 调用远程服务
// 1.校验验证码
String code = vo.getCode();
String redis_code = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
if (!ObjectUtils.isEmpty(redis_code)) {
// 验证码通过
if (code.equals(redis_code.split("_")[0])) {
// 删除验证码
stringRedisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
// 调用远程服务进行注册
R r = memberFeignService.register(vo);
if (r.getCode() == 0) {
// 成功
return "redirect:http://auth.kkmall.com/login.html";
} else {
Map<String, String> errors = new HashMap<>();
errors.put("msg", r.getData("msg", new TypeReference<String>() {
}));
redirectAttributes.addFlashAttribute("errors", errors);
return "redirect:http://auth.kkmall.com/reg.html";
}
} else {
Map<String, String> errors = new HashMap<>();
errors.put("code", "验证码错误");
// addFlashAttribute 这个数据只取一次
redirectAttributes.addFlashAttribute("errors", errors);
return "redirect:http://auth.kkmall.com/reg.html";
}
} else {
Map<String, String> errors = new HashMap<>();
errors.put("code", "验证码错误");
// addFlashAttribute 这个数据只取一次
redirectAttributes.addFlashAttribute("errors", errors);
return "redirect:http://auth.kkmall.com/reg.html";
}
}
}

View file

@ -0,0 +1,93 @@
package name.lkk.kkmall.authserver.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import name.lkk.common.constant.AuthServerConstant;
import name.lkk.common.utils.HttpUtils;
import name.lkk.common.utils.R;
import name.lkk.common.vo.MemberRsepVo;
import name.lkk.kkmall.authserver.feign.MemberFeignService;
import name.lkk.kkmall.authserver.vo.SocialUser;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Controller
@RequestMapping("/oauth2.0")
public class Oath2Controller {
@Autowired
private MemberFeignService memberFeignService;
@GetMapping("/logout")
public String login(HttpSession session) {
if (session.getAttribute(AuthServerConstant.LOGIN_USER) != null) {
log.info("\n[" + ((MemberRsepVo) session.getAttribute(AuthServerConstant.LOGIN_USER)).getUsername() + "] 已下线");
}
session.invalidate();
return "redirect:http://auth.kkmall.com/login.html";
}
/**
* 登录成功回调
* {
* "access_token": "2.00snwAOGOmJAkBcc03bd161bXVD78C",
* "remind_in": "157679999",
* "expires_in": 157679999,
* "uid": "5703891740",
* "isRealName": "true"
* }
* 汀西氟的我是你 --- 2.00snwAOGOmJAkBcc03bd161bXVD78C
*/
@GetMapping("/weibo/success")
public String weiBo(@RequestParam("code") String code, HttpSession session) throws Exception {
// 根据code换取 Access Token
Map<String, String> map = new HashMap<>();
map.put("client_id", "1595881874");
map.put("client_secret", "862fbfacc15324b3f2f6e485d49fd546");
map.put("grant_type", "authorization_code");
map.put("redirect_uri", "http://auth.kkmall.com/oauth2.0/weibo/success");
map.put("code", code);
Map<String, String> headers = new HashMap<>();
HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", "post", headers, null, map);
if (response.getStatusLine().getStatusCode() == 200) {
// 获取到了 Access Token
String json = EntityUtils.toString(response.getEntity());
SocialUser socialUser = JSON.parseObject(json, SocialUser.class);
// 相当于我们知道了当前是那个用户
// 1.如果用户是第一次进来 自动注册进来(为当前社交用户生成一个会员信息 以后这个账户就会关联这个账号)
R login = memberFeignService.login(socialUser);
if (login.getCode() == 0) {
MemberRsepVo rsepVo = login.getData("data", new TypeReference<MemberRsepVo>() {
});
log.info("\n欢迎 [" + rsepVo.getUsername() + "] 使用社交账号登录");
// 第一次使用session 命令浏览器保存这个用户信息 JESSIONSEID 每次只要访问这个网站就会带上这个cookie
// 在发卡的时候扩大session作用域 (指定域名为父域名)
// TODO 1.默认发的当前域的session (需要解决子域session共享问题)
// TODO 2.使用JSON的方式序列化到redis
// new Cookie("JSESSIONID","").setDomain("kkmall.com");
session.setAttribute(AuthServerConstant.LOGIN_USER, rsepVo);
// 登录成功 跳回首页
return "redirect:http://kkmall.com";
} else {
return "redirect:http://auth.kkmall.com/login.html";
}
} else {
return "redirect:http://auth.kkmall.com/login.html";
}
}
}

View file

@ -0,0 +1,24 @@
package name.lkk.kkmall.authserver.feign;
import name.lkk.common.utils.R;
import name.lkk.kkmall.authserver.vo.SocialUser;
import name.lkk.kkmall.authserver.vo.UserLoginVo;
import name.lkk.kkmall.authserver.vo.UserRegisterVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient("kkmall-member")
public interface MemberFeignService {
@PostMapping("/member/member/register")
R register(@RequestBody UserRegisterVo userRegisterVo);
@PostMapping("/member/member/login")
R login(@RequestBody UserLoginVo vo);
@PostMapping("/member/member/oauth2/login")
R login(@RequestBody SocialUser socialUser);
}

View file

@ -0,0 +1,17 @@
package name.lkk.kkmall.authserver.feign;
import name.lkk.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 远程调用第三方服务
*/
@FeignClient("kkmall-third-server")
public interface ThirdServicesFeignService {
@GetMapping("/sms/sendcode")
R sendCode(@RequestParam("phone") String phone, @RequestParam("code") String code);
}

View file

@ -0,0 +1,17 @@
package name.lkk.kkmall.authserver.vo;
import lombok.Data;
@Data
public class SocialUser {
private String accessToken;
private String remindIn;
private String expiresIn;
private String uid;
private String isrealname;
}

View file

@ -0,0 +1,12 @@
package name.lkk.kkmall.authserver.vo;
import lombok.Data;
@Data
public class UserLoginVo {
private String loginacct;
private String password;
}

View file

@ -0,0 +1,27 @@
package name.lkk.kkmall.authserver.vo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
@Data
public class UserRegisterVo {
@Length(min = 6, max = 20, message = "用户名长度必须在6-20之间")
@NotEmpty(message = "用户名必须提交")
private String userName;
@Length(min = 6, max = 20, message = "用户名长度必须在6-20之间")
@NotEmpty(message = "密码必须提交")
private String password;
@NotEmpty(message = "手机号不能为空")
@Pattern(regexp = "^[1]([3-9])[0-9]{9}$", message = "手机号格式不正确")
private String phone;
@NotEmpty(message = "验证码必须填写")
private String code;
}

View file

@ -1,3 +1,5 @@
ipAddr: localhost
server:
port: 20000
@ -8,6 +10,13 @@ spring:
server-addr: localhost:8848
application:
name: kkmall-auth-server
session:
store-type: redis
redis:
host: ${ipAddr}
port: 6379
password: linkekun
mvc:
static-path-pattern: /static/**
thymeleaf:

View file

@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="/static/login/JD_sass/JD1.css" />
<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>谷粒商城登录页面</title>
<title>KK商城登录页面</title>
</head>
<body>
<!--顶部logo-->
@ -18,8 +18,8 @@
<div class="top-2">
<div class="top-2a">
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_11.png" />
<p>依据《网络安全法》,为保障您的账户安全和正常使用,请尽快完成手机号验证!新版《<span>谷粒商城隐私政策</span>》已上线,将更有利于保护您的个人隐私。</p>
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_11.png"/>
<p>依据《网络安全法》,为保障您的账户安全和正常使用,请尽快完成手机号验证!新版《<span>KK商城隐私政策</span>》已上线,将更有利于保护您的个人隐私。</p>
</div>
</div>
@ -31,8 +31,8 @@
<div id="sign">
<div class="si_top">
<p>
<span>谷粒商城不会以任何理由要求您转账汇款,谨防诈骗。</span>
<span style="color:red;" th:if="${session.msg!=null}"><br/>[[${session.msg}]]</span>
<span>KK商城不会以任何理由要求您转账汇款,谨防诈骗。</span>
<span style="color:red;" th:if="${session.msg!=null}"><br/>[[${session.msg}]]</span>
</p>
</div>
<div class="si_cen">
@ -41,15 +41,15 @@
<h2 class="btn1">账户登录</h2>
</div>
<div class="si_bom tab">
<img src="/static/login/JD_img/show.png" class="bom_1" />
<a href="/"><img src="/static/login/JD_img/phone-orange.png" class="bom_2" /></a>
<h6>打开<span class="red">手机谷粒商城</span> 扫描二维码</h6>
<img src="/static/login/JD_img/show.png" class="bom_1"/>
<a href="/"><img src="/static/login/JD_img/phone-orange.png" class="bom_2"/></a>
<h6>打开<span class="red">手机KK商城</span> 扫描二维码</h6>
<p>
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_15.png" />
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_15.png"/>
<span><a href="/">免输入</a></span>
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_17.png" />
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_17.png"/>
<span><a href="/">更快</a></span>
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_19.png" />
<img src="/static/login/JD_img/4de5019d2404d347897dee637895d02b_19.png"/>
<span><a href="/">更安全</a></span>
</p>
</div>
@ -80,8 +80,8 @@
<div class="si_out">
<ul>
<li>
<a href="https://api.weibo.com/oauth2/authorize?client_id=1294828100&response_type=code&redirect_uri=http://auth.kkmall.com/oauth2.0/weibo/success">
<img style="width: 50px; height: 18px" src="/static/login/JD_img/weibo.png" />
<a href="https://api.weibo.com/oauth2/authorize?client_id=1595881874&response_type=code&redirect_uri=http://auth.kkmall.com/oauth2.0/weibo/success">
<img style="width: 50px; height: 18px" src="/static/login/JD_img/weibo.png"/>
</a>
</li>
<li class="f4"> | </li>
@ -112,19 +112,19 @@
<li class="little">|</li>
<li><a href="/">广告服务</a></li>
<li class="little">|</li>
<li><a href="/">手机谷粒商城</a></li>
<li><a href="/">手机KK商城</a></li>
<li class="little">|</li>
<li><a href="/">友情链接</a></li>
<li class="little">|</li>
<li><a href="/">销售联盟</a></li>
<li class="little">|</li>
<li><a href="/">谷粒商城社区</a></li>
<li><a href="/">KK商城社区</a></li>
<li class="little">|</li>
<li><a href="/">谷粒商城公益</a></li>
<li><a href="/">KK商城公益</a></li>
<li class="little">|</li>
<li><a href="/">English Site</a></li>
</ul>
<span>Copyright &copy; 2020-2020 谷粒商城kkmall.com 版权所有</span>
<span>Copyright &copy; 2020-2020 KK商城kkmall.com 版权所有</span>
</footer>
</body>

File diff suppressed because it is too large Load diff

View file

@ -30,10 +30,16 @@
</exclusion>
</exclusions>
</dependency>
<!-- 使用Redis-->
<!-- 整合Spring-seesion -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View file

@ -0,0 +1,35 @@
package name.lkk.kkmall.cart.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* 设置Session作用域自定义cookie序列化机制
*
* @author kirklin
*/
@Configuration
public class KkMallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 明确的指定Cookie的作用域
cookieSerializer.setDomainName("kkmall.com");
cookieSerializer.setCookieName("MALLSESSION");
return cookieSerializer;
}
/**
* 自定义序列化机制
* 这里方法名必须是springSessionDefaultRedisSerializer
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}

View file

@ -18,7 +18,8 @@ spring:
cache: false
suffix: .html
prefix: classpath:/templates/
session:
store-type: redis
redis:
host: ${ipAddr}
port: 6379

View file

@ -19,7 +19,7 @@
<div class="hd_wrap_top">
<ul class="hd_wrap_left">
<li class="hd_home"><i class="glyphicon glyphicon-home"></i>
<a href="http://kkmall.com">谷粒商城首页</a>
<a href="http://kkmall.com">KK商城首页</a>
</li>
</ul>
<ul class="hd_wrap_right">

View file

@ -1,9 +1,7 @@
package name.lkk.common.constant;
/**
* <p>Title: AuthServerConstant</p>
* Description
* date2020/6/25 16:03
* 认证服务常量
*/
public class AuthServerConstant {
public static final String SMS_CODE_CACHE_PREFIX = "sms:code:";

View file

@ -21,28 +21,28 @@ package name.lkk.common.exception;
public enum BizCodeEnum {
UNKNOW_EXCEPTION(10000, "系统未知异常"),
VAILD_EXCEPTION(10001, "参数格式校验失败"),
SMS_CODE_EXCEPTION(10002, "验证码获取频率太高,稍后再试"),
TO_MANY_REQUEST(10003, "请求流量过大"),
SMS_SEND_CODE_EXCEPTION(10403, "短信发送失败"),
USER_EXIST_EXCEPTION(15001, "用户已经存在"),
PHONE_EXIST_EXCEPTION(15002, "手机号已经存在"),
LOGINACTT_PASSWORD_ERROR(15003, "账号或密码错误"),
SOCIALUSER_LOGIN_ERROR(15004, "社交账号登录失败"),
NOT_STOCK_EXCEPTION(21000, "商品库存不足"),
PRODUCT_UP_EXCEPTION(11000,"商品上架异常");
SMS_CODE_EXCEPTION(10002, "验证码获取频率太高,稍后再试"),
TO_MANY_REQUEST(10003, "请求流量过大"),
SMS_SEND_CODE_EXCEPTION(10403, "短信发送失败"),
USER_EXIST_EXCEPTION(15001, "用户已经存在"),
PHONE_EXIST_EXCEPTION(15002, "手机号已经存在"),
LOGINACTT_PASSWORD_ERROR(15003, "账号或密码错误"),
SOCIALUSER_LOGIN_ERROR(15004, "社交账号登录失败"),
NOT_STOCK_EXCEPTION(21000, "商品库存不足"),
PRODUCT_UP_EXCEPTION(11000, "商品上架异常");
private int code;
private final int code;
private String msg;
private final String msg;
BizCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
BizCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;

View file

@ -0,0 +1,319 @@
package name.lkk.common.utils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HttpUtils {
/**
* get
*
* @param host
* @param path
* @param method
* @param headers
* @param querys
* @return
* @throws Exception
*/
public static HttpResponse doGet(String host, String path, String method,
Map<String, String> headers,
Map<String, String> querys)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpGet request = new HttpGet(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
return httpClient.execute(request);
}
/**
* post form
*
* @param host
* @param path
* @param method
* @param headers
* @param querys
* @param bodys
* @return
* @throws Exception
*/
public static HttpResponse doPost(String host, String path, String method,
Map<String, String> headers,
Map<String, String> querys,
Map<String, String> bodys)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (bodys != null) {
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
for (String key : bodys.keySet()) {
nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
request.setEntity(formEntity);
}
return httpClient.execute(request);
}
/**
* Post String
*
* @param host
* @param path
* @param method
* @param headers
* @param querys
* @param body
* @return
* @throws Exception
*/
public static HttpResponse doPost(String host, String path, String method,
Map<String, String> headers,
Map<String, String> querys,
String body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (StringUtils.isNotBlank(body)) {
request.setEntity(new StringEntity(body, "utf-8"));
}
return httpClient.execute(request);
}
/**
* Post stream
*
* @param host
* @param path
* @param method
* @param headers
* @param querys
* @param body
* @return
* @throws Exception
*/
public static HttpResponse doPost(String host, String path, String method,
Map<String, String> headers,
Map<String, String> querys,
byte[] body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (body != null) {
request.setEntity(new ByteArrayEntity(body));
}
return httpClient.execute(request);
}
/**
* Put String
*
* @param host
* @param path
* @param method
* @param headers
* @param querys
* @param body
* @return
* @throws Exception
*/
public static HttpResponse doPut(String host, String path, String method,
Map<String, String> headers,
Map<String, String> querys,
String body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPut request = new HttpPut(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (StringUtils.isNotBlank(body)) {
request.setEntity(new StringEntity(body, "utf-8"));
}
return httpClient.execute(request);
}
/**
* Put stream
*
* @param host
* @param path
* @param method
* @param headers
* @param querys
* @param body
* @return
* @throws Exception
*/
public static HttpResponse doPut(String host, String path, String method,
Map<String, String> headers,
Map<String, String> querys,
byte[] body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPut request = new HttpPut(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (body != null) {
request.setEntity(new ByteArrayEntity(body));
}
return httpClient.execute(request);
}
/**
* Delete
*
* @param host
* @param path
* @param method
* @param headers
* @param querys
* @return
* @throws Exception
*/
public static HttpResponse doDelete(String host, String path, String method,
Map<String, String> headers,
Map<String, String> querys)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
return httpClient.execute(request);
}
private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(host);
if (!StringUtils.isBlank(path)) {
sbUrl.append(path);
}
if (null != querys) {
StringBuilder sbQuery = new StringBuilder();
for (Map.Entry<String, String> query : querys.entrySet()) {
if (0 < sbQuery.length()) {
sbQuery.append("&");
}
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
sbQuery.append(query.getValue());
}
if (!StringUtils.isBlank(query.getKey())) {
sbQuery.append(query.getKey());
if (!StringUtils.isBlank(query.getValue())) {
sbQuery.append("=");
sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
}
}
}
if (0 < sbQuery.length()) {
sbUrl.append("?").append(sbQuery);
}
}
return sbUrl.toString();
}
private static HttpClient wrapClient(String host) {
HttpClient httpClient = new DefaultHttpClient();
if (host.startsWith("https://")) {
sslClient(httpClient);
}
return httpClient;
}
private static void sslClient(HttpClient httpClient) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry registry = ccm.getSchemeRegistry();
registry.register(new Scheme("https", 443, ssf));
} catch (KeyManagementException ex) {
throw new RuntimeException(ex);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -0,0 +1,94 @@
package name.lkk.common.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
/**
*
*/
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Data
public class MemberRsepVo implements Serializable {
private Long id;
/**
* 会员等级id
*/
private Long levelId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 昵称
*/
private String nickname;
/**
* 手机号码
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 头像
*/
private String header;
/**
* 性别
*/
private Integer gender;
/**
* 生日
*/
private Date birth;
/**
* 所在城市
*/
private String city;
/**
* 职业
*/
private String job;
/**
* 个性签名
*/
private String sign;
/**
* 用户来源
*/
private Integer sourceType;
/**
* 积分
*/
private Integer integration;
/**
* 成长值
*/
private Integer growth;
/**
* 启用状态
*/
private Integer status;
/**
* 注册时间
*/
private Date createTime;
private String socialUid;
private String accessToken;
private Long expiresIn;
}

View file

@ -1 +1 @@
com.firenay.common.valid.ListValue.message=\u5FC5\u987B\u63D0\u4EA4\u6307\u5B9A\u7684\u503C [0,1]
name.lkk.common.valid.ListValue.message=\u5FC5\u987B\u63D0\u4EA4\u6307\u5B9A\u7684\u503C [0,1]

View file

@ -24,7 +24,17 @@
<artifactId>kkmall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 整合Spring-seesion -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

View file

@ -0,0 +1,35 @@
package name.lkk.kkmall.member.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* 设置Session作用域自定义cookie序列化机制
*
* @author kirklin
*/
@Configuration
public class KkMallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 明确的指定Cookie的作用域
cookieSerializer.setDomainName("kkmall.com");
cookieSerializer.setCookieName("MALLSESSION");
return cookieSerializer;
}
/**
* 自定义序列化机制
* 这里方法名必须是springSessionDefaultRedisSerializer
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}

View file

@ -1,23 +1,22 @@
package name.lkk.kkmall.member.controller;
import name.lkk.common.exception.BizCodeEnum;
import name.lkk.common.utils.PageUtils;
import name.lkk.common.utils.R;
import name.lkk.kkmall.member.entity.MemberEntity;
import name.lkk.kkmall.member.exception.PhoneExistException;
import name.lkk.kkmall.member.exception.UserNameExistException;
import name.lkk.kkmall.member.feign.CouponFeignService;
import name.lkk.kkmall.member.service.MemberService;
import name.lkk.kkmall.member.vo.MemberLoginVo;
import name.lkk.kkmall.member.vo.SocialUser;
import name.lkk.kkmall.member.vo.UserRegisterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.Map;
import name.lkk.kkmall.member.feign.CouponFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import name.lkk.kkmall.member.entity.MemberEntity;
import name.lkk.kkmall.member.service.MemberService;
import name.lkk.common.utils.PageUtils;
import name.lkk.common.utils.R;
import javax.annotation.Resource;
/**
* 会员
@ -35,8 +34,43 @@ public class MemberController {
@Autowired
private CouponFeignService couponFeignService;
@PostMapping("/oauth2/login")
public R login(@RequestBody SocialUser socialUser) throws Exception {
MemberEntity memberEntity = memberService.login(socialUser);
if (memberEntity != null) {
return R.ok().setData(memberEntity);
} else {
return R.error(BizCodeEnum.SOCIALUSER_LOGIN_ERROR.getCode(), BizCodeEnum.SOCIALUSER_LOGIN_ERROR.getMsg());
}
}
@PostMapping("/login")
public R login(@RequestBody MemberLoginVo vo) {
MemberEntity memberEntity = memberService.login(vo);
if (memberEntity != null) {
return R.ok().setData(memberEntity);
} else {
return R.error(BizCodeEnum.LOGINACTT_PASSWORD_ERROR.getCode(), BizCodeEnum.LOGINACTT_PASSWORD_ERROR.getMsg());
}
}
@PostMapping("/register")
public R register(@RequestBody UserRegisterVo userRegisterVo) {
try {
memberService.register(userRegisterVo);
} catch (PhoneExistException e) {
return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(), BizCodeEnum.PHONE_EXIST_EXCEPTION.getMsg());
} catch (UserNameExistException e) {
return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(), BizCodeEnum.USER_EXIST_EXCEPTION.getMsg());
}
return R.ok();
}
@RequestMapping("/coupons")
public R test(){
public R test() {
MemberEntity memberEntity = new MemberEntity();
memberEntity.setNickname("fireNay");
// 远程调用

View file

@ -1,7 +1,7 @@
package name.lkk.kkmall.member.dao;
import name.lkk.kkmall.member.entity.MemberLevelEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import name.lkk.kkmall.member.entity.MemberLevelEntity;
import org.apache.ibatis.annotations.Mapper;
/**
@ -13,5 +13,5 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface MemberLevelDao extends BaseMapper<MemberLevelEntity> {
MemberLevelEntity getDefaultLevel();
}

View file

@ -0,0 +1,8 @@
package name.lkk.kkmall.member.exception;
public class PhoneExistException extends RuntimeException {
public PhoneExistException() {
super("手机号存在");
}
}

View file

@ -0,0 +1,8 @@
package name.lkk.kkmall.member.exception;
public class UserNameExistException extends RuntimeException {
public UserNameExistException() {
super("用户名存在");
}
}

View file

@ -3,6 +3,11 @@ package name.lkk.kkmall.member.service;
import com.baomidou.mybatisplus.extension.service.IService;
import name.lkk.common.utils.PageUtils;
import name.lkk.kkmall.member.entity.MemberEntity;
import name.lkk.kkmall.member.exception.PhoneExistException;
import name.lkk.kkmall.member.exception.UserNameExistException;
import name.lkk.kkmall.member.vo.MemberLoginVo;
import name.lkk.kkmall.member.vo.SocialUser;
import name.lkk.kkmall.member.vo.UserRegisterVo;
import java.util.Map;
@ -16,5 +21,21 @@ import java.util.Map;
public interface MemberService extends IService<MemberEntity> {
PageUtils queryPage(Map<String, Object> params);
void register(UserRegisterVo userRegisterVo) throws PhoneExistException, UserNameExistException;
void checkPhone(String phone) throws PhoneExistException;
void checkUserName(String username) throws UserNameExistException;
/**
* 普通登录
*/
MemberEntity login(MemberLoginVo vo);
/**
* 社交登录
*/
MemberEntity login(SocialUser socialUser);
}

View file

@ -1,21 +1,40 @@
package name.lkk.kkmall.member.service.impl;
import org.springframework.stereotype.Service;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import name.lkk.common.utils.HttpUtils;
import name.lkk.common.utils.PageUtils;
import name.lkk.common.utils.Query;
import name.lkk.kkmall.member.dao.MemberDao;
import name.lkk.kkmall.member.dao.MemberLevelDao;
import name.lkk.kkmall.member.entity.MemberEntity;
import name.lkk.kkmall.member.entity.MemberLevelEntity;
import name.lkk.kkmall.member.exception.PhoneExistException;
import name.lkk.kkmall.member.exception.UserNameExistException;
import name.lkk.kkmall.member.service.MemberService;
import name.lkk.kkmall.member.vo.MemberLoginVo;
import name.lkk.kkmall.member.vo.SocialUser;
import name.lkk.kkmall.member.vo.UserRegisterVo;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
@Autowired
private MemberLevelDao memberLevelDao;
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<MemberEntity> page = this.page(
@ -26,4 +45,128 @@ public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> impl
return new PageUtils(page);
}
@Override
public void register(UserRegisterVo userRegisterVo) throws PhoneExistException, UserNameExistException {
MemberEntity entity = new MemberEntity();
// 设置默认等级
MemberLevelEntity memberLevelEntity = memberLevelDao.getDefaultLevel();
entity.setLevelId(memberLevelEntity.getId());
// 检查手机号 用户名是否唯一
checkPhone(userRegisterVo.getPhone());
checkUserName(userRegisterVo.getUserName());
entity.setMobile(userRegisterVo.getPhone());
entity.setUsername(userRegisterVo.getUserName());
// 密码要加密存储
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
entity.setPassword(bCryptPasswordEncoder.encode(userRegisterVo.getPassword()));
// 其他的默认信息
entity.setCity("福建 福州");
entity.setCreateTime(new Date());
entity.setStatus(0);
entity.setNickname(userRegisterVo.getUserName());
entity.setBirth(new Date());
entity.setEmail("xxx@gmail.com");
entity.setGender(1);
entity.setJob("JAVA");
baseMapper.insert(entity);
}
@Override
public void checkPhone(String phone) throws PhoneExistException {
if (this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone)) > 0) {
throw new PhoneExistException();
}
}
@Override
public void checkUserName(String username) throws UserNameExistException {
if (this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username)) > 0) {
throw new UserNameExistException();
}
}
@Override
public MemberEntity login(MemberLoginVo vo) {
String loginacct = vo.getLoginacct();
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
// 去数据库查询
MemberEntity entity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", loginacct).or().eq("mobile", loginacct));
if (entity == null) {
// 登录失败
return null;
} else {
// 前面传一个明文密码 后面传一个编码后的密码
boolean matches = bCryptPasswordEncoder.matches(vo.getPassword(), entity.getPassword());
if (matches) {
entity.setPassword(null);
return entity;
} else {
return null;
}
}
}
@Override
public MemberEntity login(SocialUser socialUser) {
// 微博的uid
String uid = socialUser.getUid();
// 1.判断社交用户登录过系统
MemberDao dao = this.baseMapper;
MemberEntity entity = dao.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid));
MemberEntity memberEntity = new MemberEntity();
if (entity != null) {
// 说明这个用户注册过, 修改它的资料
memberEntity.setId(entity.getId());
memberEntity.setAccessToken(socialUser.getAccessToken());
memberEntity.setExpiresIn(socialUser.getExpiresIn());
// 更新
dao.updateById(memberEntity);
entity.setAccessToken(socialUser.getAccessToken());
entity.setExpiresIn(socialUser.getExpiresIn());
entity.setPassword(null);
return entity;
} else {
// 2. 没有查到当前社交用户对应的记录 我们就需要注册一个
HashMap<String, String> map = new HashMap<>();
map.put("access_token", socialUser.getAccessToken());
map.put("uid", socialUser.getUid());
try {
HttpResponse response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", "get", new HashMap<String, String>(), map);
// 3. 查询当前社交用户账号信息(昵称性别等)
if (response.getStatusLine().getStatusCode() == 200) {
// 查询成功
String json = EntityUtils.toString(response.getEntity());
// 这个JSON对象什么样的数据都可以直接获取
JSONObject jsonObject = JSON.parseObject(json);
memberEntity.setNickname(jsonObject.getString("name"));
memberEntity.setUsername(jsonObject.getString("name"));
memberEntity.setGender("m".equals(jsonObject.getString("gender")) ? 1 : 0);
memberEntity.setCity(jsonObject.getString("location"));
memberEntity.setJob("IT");
memberEntity.setEmail(jsonObject.getString("email"));
}
} catch (Exception e) {
log.warn("社交登录时远程调用出错 [尝试修复]");
}
memberEntity.setStatus(0);
memberEntity.setCreateTime(new Date());
memberEntity.setBirth(new Date());
memberEntity.setLevelId(1L);
memberEntity.setSocialUid(socialUser.getUid());
memberEntity.setAccessToken(socialUser.getAccessToken());
memberEntity.setExpiresIn(socialUser.getExpiresIn());
// 注册 -- 登录成功
dao.insert(memberEntity);
memberEntity.setPassword(null);
return memberEntity;
}
}
}

View file

@ -0,0 +1,12 @@
package name.lkk.kkmall.member.vo;
import lombok.Data;
@Data
public class MemberLoginVo {
private String loginacct;
private String password;
}

View file

@ -0,0 +1,17 @@
package name.lkk.kkmall.member.vo;
import lombok.Data;
@Data
public class SocialUser {
private String accessToken;
private String remindIn;
private String expiresIn;
private String uid;
private String isrealname;
}

View file

@ -0,0 +1,14 @@
package name.lkk.kkmall.member.vo;
import lombok.Data;
@Data
public class UserRegisterVo {
private String userName;
private String password;
private String phone;
}

View file

@ -1,3 +1,4 @@
ipAddr: localhost
spring:
datasource:
#MySQL配置
@ -13,6 +14,13 @@ spring:
application:
name: kkmall-member
session:
store-type: redis
redis:
host: ${ipAddr}
port: 6379
password: linkekun
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:

View file

@ -16,6 +16,11 @@
<result property="priviledgeBirthday" column="priviledge_birthday"/>
<result property="note" column="note"/>
</resultMap>
<select id="getDefaultLevel" resultType="name.lkk.kkmall.member.entity.MemberLevelEntity">
SELECT *
FROM `ums_member_level`
WHERE default_status = 1
</select>
</mapper>

View file

@ -24,7 +24,17 @@
<artifactId>kkmall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 整合Spring-seesion -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

View file

@ -0,0 +1,35 @@
package name.lkk.kkmall.order.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* 设置Session作用域自定义cookie序列化机制
*
* @author kirklin
*/
@Configuration
public class KkMallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 明确的指定Cookie的作用域
cookieSerializer.setDomainName("kkmall.com");
cookieSerializer.setCookieName("MALLSESSION");
return cookieSerializer;
}
/**
* 自定义序列化机制
* 这里方法名必须是springSessionDefaultRedisSerializer
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}

View file

@ -1,3 +1,4 @@
ipAddr: localhost
spring:
datasource:
#MySQL配置
@ -12,6 +13,12 @@ spring:
server-addr: localhost:8848
application:
name: kkmall-order
session:
store-type: redis
redis:
host: ${ipAddr}
port: 6379
password: linkekun
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml

View file

@ -24,7 +24,17 @@
<artifactId>kkmall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 整合Spring-seesion -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

View file

@ -0,0 +1,35 @@
package name.lkk.kkmall.product.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* 设置Session作用域自定义cookie序列化机制
*
* @author kirklin
*/
@Configuration
public class KkMallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 明确的指定Cookie的作用域
cookieSerializer.setDomainName("kkmall.com");
cookieSerializer.setCookieName("MALLSESSION");
return cookieSerializer;
}
/**
* 自定义序列化机制
* 这里方法名必须是springSessionDefaultRedisSerializer
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}

View file

@ -21,7 +21,8 @@ spring:
cache: true
suffix: .html
prefix: classpath:/templates/
session:
store-type: redis
redis:
host: ${ipAddr}
port: 6379

View file

@ -93,7 +93,7 @@
<ul>
<li th:if="${session.loginUser} !=null">
<a>欢迎,[[${session.loginUser.username}]]</a>
<!-- <a th:href="'http://member.kkmall.com/user/' + ${session.loginUser.id}+ '.html'">你好,[[${session.loginUser.username}]]</a>-->
<a th:href="'http://member.kkmall.com/user/' + ${session.loginUser.id}+ '.html'">你好,[[${session.loginUser.username}]]</a>
</li>
<li th:if="${session.loginUser} !=null">
<a href="http://auth.kkmall.com/oauth2.0/logout">退出登录</a>

View file

@ -577,7 +577,7 @@
</div>
<div class="box-summary clear">
<ul>
<li>谷粒商城价</li>
<li>KK商城价</li>
<li>
<span></span>
<span th:text="${#numbers.formatDecimal(item.info.price,3,2)}">4499.00</span>

View file

@ -31,6 +31,17 @@
</exclusion>
</exclusions>
</dependency>
<!-- 整合Spring-seesion -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>

View file

@ -0,0 +1,35 @@
package name.lkk.kkmall.search.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* 设置Session作用域自定义cookie序列化机制
*
* @author kirklin
*/
@Configuration
public class KkMallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 明确的指定Cookie的作用域
cookieSerializer.setDomainName("kkmall.com");
cookieSerializer.setCookieName("MALLSESSION");
return cookieSerializer;
}
/**
* 自定义序列化机制
* 这里方法名必须是springSessionDefaultRedisSerializer
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}

View file

@ -18,7 +18,7 @@
<b class="header_head_p">
<div style="overflow: hidden">
<a href="http://kkmall.com" class="header_head_p_a1" style="width:73px;">
谷粒商城首页
KK商城首页
</a>
<a href="/list.html" class="header_head_p_a">
<!--<img src="/static/search/img/img_05.png" style="border-radius: 50%;"/>-->
@ -76,7 +76,7 @@
</li>
<span>|</span>
<li class="header_wdjd" style="width:80px;">
<a href="/list.html">我的谷粒商城</a>
<a href="/list.html">我的KK商城</a>
<img src="/static/search/image/down-@1x.png"/>
<!--<b class="glyphicon glyphicon-menu-down"></b>-->
<div class="header_wdjd_txt">
@ -118,7 +118,7 @@
</li>
<span>|</span>
<li>
<a href="/list.html">谷粒商城会员</a>
<a href="/list.html">KK商城会员</a>
</li>
<span>|</span>
<li>
@ -189,10 +189,10 @@
<ul style="width: 25%;">
<p style="width:100%;">特色主题</p>
<li>
<a href="/list.html">谷粒商城试用</a>
<a href="/list.html">KK商城试用</a>
</li>
<li>
<a href="/list.html">谷粒商城金融</a>
<a href="/list.html">KK商城金融</a>
</li>
<li>
<a href="/list.html">全球售</a>
@ -201,10 +201,10 @@
<a href="/list.html">国际站</a>
</li>
<li>
<a href="/list.html">谷粒商城会员</a>
<a href="/list.html">KK商城会员</a>
</li>
<li>
<a href="/list.html">谷粒商城预售</a>
<a href="/list.html">KK商城预售</a>
</li>
<li>
<a href="/list.html">买什么</a>
@ -237,7 +237,7 @@
<a href="/list.html">印尼站</a>
</li>
<li>
<a href="/list.html">谷粒商城金融科技</a>
<a href="/list.html">KK商城金融科技</a>
</li>
<li>
<a href="/list.html">In货推荐</a>
@ -267,7 +267,7 @@
<a href="/list.html">家用电器</a>
</li>
<li>
<a href="/list.html">谷粒商城智能</a>
<a href="/list.html">KK商城智能</a>
</li>
<li>
<a href="/list.html">服装城</a>
@ -303,10 +303,10 @@
<a href="/list.html">白条</a>
</li>
<li>
<a href="/list.html">谷粒商城金融App</a>
<a href="/list.html">KK商城金融App</a>
</li>
<li>
<a href="/list.html">谷粒商城小金库</a>
<a href="/list.html">KK商城小金库</a>
</li>
<li>
<a href="/list.html">理财</a>
@ -333,10 +333,10 @@
<a href="/list.html">电影票</a>
</li>
<li>
<a href="/list.html">谷粒商城到家</a>
<a href="/list.html">KK商城到家</a>
</li>
<li>
<a href="/list.html">谷粒商城众测</a>
<a href="/list.html">KK商城众测</a>
</li>
<li>
<a href="/list.html">游戏</a>
@ -348,10 +348,10 @@
<a href="/list.html">合作招商</a>
</li>
<li>
<a href="/list.html">谷粒商城通信</a>
<a href="/list.html">KK商城通信</a>
</li>
<li>
<a href="/list.html">谷粒商城E卡</a>
<a href="/list.html">KK商城E卡</a>
</li>
<li>
<a href="/list.html">企业采购</a>
@ -372,7 +372,7 @@
<a href="/list.html">京友帮</a>
</li>
<li>
<a href="/list.html">谷粒商城社区</a>
<a href="/list.html">KK商城社区</a>
</li>
<li>
<a href="/list.html">智能社区</a>
@ -388,7 +388,7 @@
</li>
<span>|</span>
<li class="header_sjjd">
<a href="/list.html">手机谷粒商城</a>
<a href="/list.html">手机KK商城</a>
<div class="header_sjjd_div">
<img src="/static/search/img/01.png"/>
</div>
@ -419,10 +419,10 @@
<div class="header_form_nav">
<ul>
<li>
<a href="/list.html">谷粒商城之家</a>
<a href="/list.html">KK商城之家</a>
</li>
<li>
<a href="/list.html">谷粒商城专卖店</a>
<a href="/list.html">KK商城专卖店</a>
</li>
<li>
<a href="/list.html">平板</a>
@ -506,7 +506,7 @@
<a href="/list.html" style="color: #999;">中国电信</a>
<a href="/list.html" style="color: #999;">中国移动</a>
<a href="/list.html" style="color: #999;">中国联通</a>
<a href="/list.html" style="color: #999;">谷粒商城通信</a>
<a href="/list.html" style="color: #999;">KK商城通信</a>
<a href="/list.html" style="color: #999;">170选号</a>
</li>
<a href="/list.html" style="color: #111;" class="aaa">手机配件 ></a>
@ -1176,7 +1176,7 @@
<li>
<a href="/list.html">
<i></i>
谷粒商城配送
KK商城配送
</a>
</li>
<li>
@ -1233,15 +1233,15 @@
<p class="tab_PI">已有<span>11万+</span>热门评价
<a href="/list.html">二手有售</a>
</p>
<p class="tab_CP"><a href="/list.html" title="谷粒商城Apple产品专营店">谷粒商城Apple产品...</a>
<a href='#' title="联系供应商进行咨询">
<img src="/static/search/img/xcxc.png">
</a>
</p>
<p class="tab_CP"><a href="/list.html" title="KK商城Apple产品专营店">KK商城Apple产品...</a>
<a href='#' title="联系供应商进行咨询">
<img src="/static/search/img/xcxc.png">
</a>
</p>
<div class="tab_FO">
<div class="FO_one">
<p>自营
<span>谷粒商城自营,品质保证</span>
<span>KK商城自营,品质保证</span>
</p>
<p>满赠
<span>该商品参加满赠活动</span>
@ -1736,19 +1736,19 @@
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">延保服务</a>
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">谷粒商城E卡</a>
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">谷粒商城通信</a>
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">谷粒商城kkmall+</a>
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">KK商城E卡</a>
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">KK商城通信</a>
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">KK商城kkmall+</a>
</li>
</ol>
<ol>
<li>谷粒商城自营覆盖区域</li>
<li>
谷粒商城已向全国2661个区县提供自<br> 营配送服务,支持货到付款、
<br> POS机刷卡和售后上门服务。
</li>
<li>KK商城自营覆盖区域</li>
<li>
KK商城已向全国2661个区县提供自<br> 营配送服务,支持货到付款、
<br> POS机刷卡和售后上门服务。
</li>
<li><a href="/list.html" style="color: rgb(114, 114, 114);">查看详情&gt;</a>
</li>
</ol>
@ -1767,19 +1767,19 @@
<span></span>
<a href="/list.html" style="color: rgb(114, 114, 114);">营销中心</a>
<span></span>
<a href="/list.html" style="color: rgb(114, 114, 114);">手机谷粒商城</a>
<a href="/list.html" style="color: rgb(114, 114, 114);">手机KK商城</a>
<span></span>
<a href="/list.html" style="color: rgb(114, 114, 114);">友情链接</a>
<span></span>
<a href="/list.html" style="color: rgb(114, 114, 114);">销售联盟</a>
<span></span>
<a href="/list.html" style="color: rgb(114, 114, 114);">谷粒商城社区</a>
<a href="/list.html" style="color: rgb(114, 114, 114);">KK商城社区</a>
<span></span>
<a href="/list.html" style="color: rgb(114, 114, 114);">风险监测</a>
<span></span>
<a href="/list.html">隐私政策</a>
<span></span>
<a href="/list.html">谷粒商城公益</a>
<a href="/list.html">KK商城公益</a>
<span></span>
<a href="/list.html" style="color: rgb(114, 114, 114);">English Site</a>
<span></span>
@ -1804,17 +1804,17 @@
<a href="/list.html">违法和不良信息举报电话4006561155</a>
</p>
<p class="footer_p">
<a href="/list.html">Copyright © 2004 - 2017 谷粒商城JD.com 版权所有</a>
<a href="/list.html">Copyright © 2004 - 2017 KK商城JD.com 版权所有</a>
<span></span>
<a href="/list.html">消费者维权热线4006067733</a>
<a href="/list.html">经营证照</a>
</p>
<p class="footer_p">
<a href="/list.html">谷粒商城旗下网站:</a>
<a href="/list.html">谷粒商城支付</a>
<span></span>
<a href="/list.html">谷粒商城云</a>
</p>
<p class="footer_p">
<a href="/list.html">KK商城旗下网站:</a>
<a href="/list.html">KK商城支付</a>
<span></span>
<a href="/list.html">KK商城云</a>
</p>
<ul>
<li></li>
<li></li>
@ -1833,7 +1833,7 @@
<li>
<a href="/list.html"><img src="/static/search/img/wo.png"/></a>
<div class="div">
<a href="/list.html">谷粒商城会员</a>
<a href="/list.html">KK商城会员</a>
</div>
</li>
<li>

View file

@ -47,6 +47,12 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 自定义配置文件带提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>

View file

@ -0,0 +1,75 @@
package name.lkk.kkmall.thirdserver.component;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import name.lkk.common.utils.HttpUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@ConfigurationProperties(prefix = "spring.cloud.alicloud.sms")
@Data
@Slf4j
@Component
public class SmsComponent {
private final int PHONE_LENGTH = 11;
private String host;
private String path;
private String skin;
private String sign;
private String appcode;
public String mockSendCode(String phone, String code) {
if (phone != null && phone.length() == PHONE_LENGTH) {
log.info("模拟短信发送成功手机号:{},验证码{}", phone, code);
return "success_" + "code:" + code;
}
log.error("模拟短信发送失败,请输入正确的手机号 ");
return "fail_" + code;
}
public String sendCode(String phone, String code) {
String method = "GET";
Map<String, String> headers = new HashMap<String, String>();
//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
headers.put("Authorization", "APPCODE " + appcode);
Map<String, String> querys = new HashMap<String, String>();
querys.put("code", code);
querys.put("phone", phone);
querys.put("skin", skin);
querys.put("sign", sign);
//JDK 1.8示例代码请在这里下载 http://code.fegine.com/Tools.zip
HttpResponse response = null;
try {
/**
* 重要提示如下:
* HttpUtils请从
* https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
* 或者直接下载
* http://code.fegine.com/HttpUtils.zip
* 下载
*
* 相应的依赖请参照
* https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
* 相关jar包非pom直接下载
* http://code.fegine.com/aliyun-jar.zip
*/
response = HttpUtils.doGet(host, path, method, headers, querys);
//System.out.println(response.toString());如不输出json, 请打开这行代码打印调试头部状态码
//状态码: 200 正常400 URL无效401 appCode错误 403 次数用完 500 API网管错误
//获取response的body
if (response.getStatusLine().getStatusCode() == 200) {
return EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return "fail_" + response.getStatusLine().getStatusCode();
}
}

View file

@ -0,0 +1,32 @@
package name.lkk.kkmall.thirdserver.controller;
import name.lkk.common.exception.BizCodeEnum;
import name.lkk.common.utils.R;
import name.lkk.kkmall.thirdserver.component.SmsComponent;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: kirklin
* @date: 2021/7/9 3:09 下午
* @description:
*/
@RestController
@RequestMapping("sms")
public class SmsSendController {
@Autowired
SmsComponent smsComponent;
@GetMapping("sendcode")
public R sendCode(@RequestParam("phone") String phone, @RequestParam("code") String code) {
if (!"fail".equals(smsComponent.mockSendCode(phone, code).split("_")[0])) {
return R.ok();
}
return R.error(BizCodeEnum.SMS_SEND_CODE_EXCEPTION.getCode(), BizCodeEnum.SMS_SEND_CODE_EXCEPTION.getMsg());
}
}

View file

@ -11,5 +11,11 @@ spring:
bucket: mall-kk
access-key: LTAI5tCHtotRisgLvCsp5pv5
secret-key: zWiSQOcz5faTSkropwNssB7rqgMYmV
sms:
host: https://fesms.market.alicloudapi.com
path: /sms/
skin: 1
sign: 175622
appcode: b0563c23aff8428c97a54d4f7f9e28e5
server:
port: 30000

View file

@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.0</version>
<version>2.5.2</version>
</parent>
<properties>

View file

@ -39,24 +39,24 @@
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.14" level="project" />
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.5.2" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.14.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.14.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.31" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.28" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.46" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.48" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.0.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.2.Final" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.4.7" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:2.4.7" level="project" />
@ -80,21 +80,21 @@
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.9.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.7" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.8" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.3.8" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.8.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.5.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.12.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.46" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.46" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.48" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.48" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
@ -104,39 +104,39 @@
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.5.1" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:10.12" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:10.12" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.0.3" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.6" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.7" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.5.2" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.9.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.10.0" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.6" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.7" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.8" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.65.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.65.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.65.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.65.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.65.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.65.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.5.2" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.3.1" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.3.1" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.3.1" level="project" />
@ -145,17 +145,17 @@
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.5.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.2" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.8" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.23" level="project" />
<orderEntry type="library" name="Maven: com.oracle:ojdbc6:11.2.0.3" level="project" />
<orderEntry type="library" name="Maven: com.microsoft.sqlserver:sqljdbc4:4.0" level="project" />
<orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.20" level="project" />
<orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.13" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.13" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.31" level="project" />
<orderEntry type="library" name="Maven: org.quartz-scheduler:quartz:2.3.0" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.11" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />

View file

@ -210,30 +210,37 @@ CREATE TABLE `sms_seckill_promotion` (
-- ----------------------------
DROP TABLE IF EXISTS `sms_seckill_session`;
CREATE TABLE `sms_seckill_session` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '场次名称',
`start_time` datetime(0) NULL DEFAULT NULL COMMENT '每日开始时间',
`end_time` datetime(0) NULL DEFAULT NULL COMMENT '每日结束时间',
`status` tinyint(1) NULL DEFAULT NULL COMMENT '启用状态',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '秒杀活动场次' ROW_FORMAT = Dynamic;
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '场次名称',
`start_time` datetime(0) NULL DEFAULT NULL COMMENT '每日开始时间',
`end_time` datetime(0) NULL DEFAULT NULL COMMENT '每日结束时间',
`status` tinyint(1) NULL DEFAULT NULL COMMENT '启用状态',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
AUTO_INCREMENT = 3
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci COMMENT = '秒杀活动场次'
ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sms_seckill_session
-- ----------------------------
INSERT INTO `sms_seckill_session` VALUES (1, '谷粒秒杀', '2020-07-10 00:15:00', '2020-07-10 15:59:59', 1, '2020-07-09 15:14:21');
INSERT INTO `sms_seckill_session` VALUES (2, '谷粒秒杀', '2020-07-09 05:15:00', '2020-07-09 15:59:59', 1, '2020-07-09 05:14:47');
INSERT INTO `sms_seckill_session`
VALUES (1, 'KK秒杀', '2020-07-10 00:15:00', '2020-07-10 15:59:59', 1, '2020-07-09 15:14:21');
INSERT INTO `sms_seckill_session`
VALUES (2, 'KK秒杀', '2020-07-09 05:15:00', '2020-07-09 15:59:59', 1, '2020-07-09 05:14:47');
-- ----------------------------
-- Table structure for sms_seckill_sku_notice
-- ----------------------------
DROP TABLE IF EXISTS `sms_seckill_sku_notice`;
CREATE TABLE `sms_seckill_sku_notice` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`member_id` bigint(20) NULL DEFAULT NULL COMMENT 'member_id',
`sku_id` bigint(20) NULL DEFAULT NULL COMMENT 'sku_id',
`session_id` bigint(20) NULL DEFAULT NULL COMMENT '活动场次id',
CREATE TABLE `sms_seckill_sku_notice`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`member_id` bigint(20) NULL DEFAULT NULL COMMENT 'member_id',
`sku_id` bigint(20) NULL DEFAULT NULL COMMENT 'sku_id',
`session_id` bigint(20) NULL DEFAULT NULL COMMENT '活动场次id',
`subcribe_time` datetime(0) NULL DEFAULT NULL COMMENT '订阅时间',
`send_time` datetime(0) NULL DEFAULT NULL COMMENT '发送时间',
`notice_type` tinyint(1) NULL DEFAULT NULL COMMENT '通知方式[0-短信1-邮件]',