用户在未登录状态下可以查看商品列别以及秒杀商品详情,但不可以在未登录状态进行秒杀商品的操作,当用户点击开始秒杀时,进行登陆验证
DOCTYPE html>
<head>
<title>商品详情title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="/js/jquery.min.js">script>
<link rel="stylesheet" type="text/css" href="/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js">script>
<script type="text/javascript" src="/jquery-validation/jquery.validate.min.js">script>
<script type="text/javascript" src="/jquery-validation/localization/messages_zh.min.js">script>
<script type="text/javascript" src="/layer/layer.js">script>
<script type="text/javascript" src="/js/md5.min.js">script>
<script type="text/javascript" src="/js/common.js">script>
<script type="text/javascript" src="/js/socket.js">script>
head>
<body>
<div class="panel panel-default">
<div class="panel-heading">秒杀商品详情div>
<div class="panel-body">
<div id="userTip" style="display: none">
<span> 您还没有登录,请<a href="/login.html">登陆a>后再操作<br/>span>
div>
<span>没有收货地址的提示。。。span>
div>
<table class="table">
<tr>
<td>商品名称td>
<td colspan="3" id="goodName">td>
tr>
<tr>
<td>商品图片td>
<td colspan="3"><img id="goodImg" width="200" height="200" />td>
tr>
<tr>
<td>秒杀开始时间td>
<td id="startDate">td>
<td id="seckillTip">
td>
<td>
<img id="verifyCodeImg" width="80" height="32" onclick="initVerifyCodeImg()" style="display: none">
<input id="verifyCode" style="display: none">
<button class="btn btn-primary btn-block" type="button" id="buyButton" onclick="">立即秒杀button>
td>
tr>
<tr>
<td>商品原价td>
<td colspan="3" id="goodPrice">td>
tr>
<tr>
<td>秒杀价td>
<td colspan="3" id="seckillPrice">td>
tr>
<tr>
<td>库存数量td>
<td colspan="3" id="stockCount">td>
tr>
table>
div>
<script type="text/javascript">
var seckillId;
$(function () {
seckillId = getQueryString("seckillId");
initGood();
initUser();
});
function initGood(){
$(function () {
$.ajax({
url: "http://localhost:9000/seckill/seckillGood/find?seckillId="+seckillId,
type: "get",
xhrFields: {withCredentials: true}, //启用cookie
success:function (data) {
if(data.code==200){
//填充表格中的数据
renderGood(data.data);
}else{
layer.msg(data.msg)
}
}
});
});
}
function renderGood(good) {
$("#goodName").html(good.goodName);
$("#goodImg").prop("src",good.goodImg);
$("#startDate").html(good.startDate);
$("#goodPrice").html(good.goodPrice);
$("#stockCount").html(good.stockCount);
$("#seckillPrice").html(good.seckillPrice);
//调用时间
renderDate(good.startDate,good.endDate);
}
//定义秒杀的三个阶段
var timer; //计时器
//距离抢购开始还有多久
var remainStartSeconds;
//距离结束还有多久
var remainEndSeconds;
function renderDate(sDate,eDate) {
var startTime = new Date(sDate); // 2023-11-25 16:00
var endTime = new Date(eDate); // 2023-11-25 18:00
var now = new Date(); // 2023-11-25 14:37
remainStartSeconds=parseInt((startTime.getTime()-now.getTime())/1000);//秒
remainEndSeconds=parseInt((endTime.getTime()-now.getTime())/1000);//秒
timer=window.setInterval(showSeckillTip,1000);
}
function showSeckillTip() {
remainStartSeconds--;
remainEndSeconds--;
if(remainStartSeconds>0){
$("#seckillTip").html("距离本场秒杀开始还有"+remainStartSeconds+"秒");
//禁用按钮
$("#buyButton").prop("disabled",true);
}else{
if(remainEndSeconds>0){
//秒杀中
$("#seckillTip").html("秒杀进行中....");
//禁用按钮
$("#buyButton").prop("disabled",false);
}else{
$("#seckillTip").html("秒杀结束了");
//禁用按钮
$("#buyButton").prop("disabled",true);
window.clearInterval(timer);//取消计时器
}
}
}
function initUser(){
$(function () {
$.ajax({
url: "http://localhost:9000/member/token/getCurrent",
type: "get",
xhrFields: {withCredentials: true}, //启用cookie
success:function (data) {
if(data.code==200){
//填充表格中的数据
renderUser(data.data);
}else{
layer.msg(data.msg)
}
}
});
});
}
var user;
function renderUser(u){
if(u){
user=u;
}else{
//没有数据
$("#userTip").show();
}
}
script>
body>
html>
public User getUserByToken(String token);
实现类
/**
* 根据token查询用户
* @param token
* @return
*/
@Override
public User getUserByToken(String token) {
return myRedisTemplate.get(MemberServerKeyPrefix.USER_TOKEN, token, User.class);
}
/**
* 获取当前用户
* @param token 利用cookie中存储的token来判断用户
* @return
*/
@GetMapping("/getCurrent")
public Result<User> getCurrent(@CookieValue(value = CookieUtil.TOKEN_COOKIE_NAME, required = false) String token){
User user = userService.getUserByToken(token);
return Result.success(user);
}
/**
* 获取cookie
* @param request
* @param tokenCookieName
* @return
*/
public static String getCookie(HttpServletRequest request, String tokenCookieName) {
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0){
for (Cookie cookie : cookies) {
//找到cookie
if (cookie.getName().equals(tokenCookieName)){
return cookie.getValue();
}
}
}
return null;
}
public class UserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private MyRedisTemplate myRedisTemplate;
/**
* 判断参数类型是否为User
* @param methodParameter
* @return
*/
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType() == User.class &&
methodParameter.getParameterAnnotation(RedisValue.class) != null;
}
/**
* 自定义参数解析器
* @param parameter
* @param mavContainer
* @param webRequest
* @param binderFactory
* @return
* @throws Exception
*/
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
//获取请求对象
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
//获取cookie
String token = CookieUtil.getCookie(request, CookieUtil.TOKEN_COOKIE_NAME);
if (StringUtils.isEmpty(token)){
return null;
}
return myRedisTemplate.get(MemberServerKeyPrefix.USER_TOKEN, token, User.class);
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
//注入参数解析器
@Autowired
private UserMethodArgumentResolver userMethodArgumentResolver;
/**
* 添加参数解析器
* @param resolvers
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userMethodArgumentResolver);
}
@Bean
public UserMethodArgumentResolver userMethodArgumentResolver() {
return new UserMethodArgumentResolver();
}
}
@Target(ElementType.PARAMETER) //定义该注解应用于方法参数上
@Retention(RetentionPolicy.RUNTIME) //不仅保存在class中,JVM加载时也存在
public @interface RedisValue {
}
@RequestMapping("/getCurrent")
public Result<User> getCurrent(@RedisValue User user){
return Result.success(user);
}
实现流程: