mirror of
https://github.com/qiurunze123/miaosha.git
synced 2023-11-19 22:41:03 +08:00
lua+redis
This commit is contained in:
parent
42d4bb2bd0
commit
0f92dcce51
|
@ -82,7 +82,7 @@
|
||||||
| 028 |项目进行dubbo + zk 改造 (已完成dubbo嵌入--springboot 与dubbo结合xml版本)?|[解决思路](/docs/code-solve.md) |
|
| 028 |项目进行dubbo + zk 改造 (已完成dubbo嵌入--springboot 与dubbo结合xml版本)?|[解决思路](/docs/code-solve.md) |
|
||||||
| 029 |dubbo客户端 dubbo-admin管理平台 搭建安装|[解决思路](/docs/dubbo-admin.md) |
|
| 029 |dubbo客户端 dubbo-admin管理平台 搭建安装|[解决思路](/docs/dubbo-admin.md) |
|
||||||
| 030 |如何利用dubbo 的mock 来进行服务降级本地伪装 ?? (有更好的方式进群@我)|[解决思路](/docs/dubbo-zk.md) |
|
| 030 |如何利用dubbo 的mock 来进行服务降级本地伪装 ?? (有更好的方式进群@我)|[解决思路](/docs/dubbo-zk.md) |
|
||||||
| 027 |*** 如何利用lua + redis 取代 nigix + lua 脚本进行分布式限流 ? *** |[解决思路](/docs/redis-good.md) |
|
| 027 |*** 如何利用lua + redis 取代 nigix + lua 脚本进行分布式限流 (请看miaosha-2version) ? *** |[解决思路](/docs/redis-good.md) |
|
||||||
|
|
||||||
|
|
||||||
#### [分布式系统发展历程(已更新)](/docs/fenbushi.md)
|
#### [分布式系统发展历程(已更新)](/docs/fenbushi.md)
|
||||||
|
|
|
@ -8,6 +8,7 @@ public class AbstractResult {
|
||||||
private int code;
|
private int code;
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
|
AbstractResult() {}
|
||||||
protected AbstractResult(ResultStatus status, String message) {
|
protected AbstractResult(ResultStatus status, String message) {
|
||||||
this.code = status.getCode();
|
this.code = status.getCode();
|
||||||
this.status = status;
|
this.status = status;
|
||||||
|
|
|
@ -10,6 +10,8 @@ public class ResultGeekQ<T> extends AbstractResult implements Serializable {
|
||||||
private T data;
|
private T data;
|
||||||
private Integer count;
|
private Integer count;
|
||||||
|
|
||||||
|
protected ResultGeekQ() {
|
||||||
|
}
|
||||||
protected ResultGeekQ(ResultStatus status, String message) {
|
protected ResultGeekQ(ResultStatus status, String message) {
|
||||||
super(status, message);
|
super(status, message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.geekq.miasha.vo;
|
package com.geekq.miasha.vo;
|
||||||
|
|
||||||
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
import com.geekq.miasha.entity.MiaoshaUser;
|
import com.geekq.miasha.entity.MiaoshaUser;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -14,7 +15,7 @@ import lombok.Setter;
|
||||||
public class GoodsDetailVo {
|
public class GoodsDetailVo {
|
||||||
private int miaoshaStatus = 0;
|
private int miaoshaStatus = 0;
|
||||||
private int remainSeconds = 0;
|
private int remainSeconds = 0;
|
||||||
private GoodsVo goods ;
|
private GoodsVoOrder goods ;
|
||||||
private MiaoshaUser user;
|
private MiaoshaUser user;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,12 @@
|
||||||
|
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -16,6 +16,6 @@ public interface MiaoShaUserMapper {
|
||||||
|
|
||||||
public void insertMiaoShaUser(MiaoshaUser miaoshaUser);
|
public void insertMiaoShaUser(MiaoshaUser miaoshaUser);
|
||||||
|
|
||||||
public int getCountByUserName(@Param("userName")String userName , @Param("userType")int userType);
|
public int getCountByUserName(@Param("userName") String userName, @Param("userType") int userType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
package com.geekq.miaosha.rabbitmq;
|
package com.geekq.miaosha.rabbitmq;
|
||||||
|
|
||||||
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
|
import com.geekq.api.utils.AbstractResultOrder;
|
||||||
|
import com.geekq.api.utils.ResultGeekQOrder;
|
||||||
import com.geekq.miaosha.redis.RedisService;
|
import com.geekq.miaosha.redis.RedisService;
|
||||||
import com.geekq.miaosha.service.GoodsService;
|
import com.geekq.miaosha.service.GoodsService;
|
||||||
import com.geekq.miaosha.service.MiaoShaMessageService;
|
|
||||||
import com.geekq.miaosha.service.MiaoshaService;
|
import com.geekq.miaosha.service.MiaoshaService;
|
||||||
import com.geekq.miaosha.service.OrderService;
|
import com.geekq.miaosha.service.OrderService;
|
||||||
import com.geekq.miasha.entity.MiaoshaOrder;
|
import com.geekq.miasha.entity.MiaoshaOrder;
|
||||||
import com.geekq.miasha.entity.MiaoshaUser;
|
import com.geekq.miasha.entity.MiaoshaUser;
|
||||||
import com.geekq.miasha.vo.GoodsVo;
|
import com.geekq.miasha.enums.enums.ResultStatus;
|
||||||
import com.geekq.miasha.vo.MiaoShaMessageVo;
|
import com.geekq.miasha.exception.GlobleException;
|
||||||
import com.rabbitmq.client.Channel;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.amqp.core.Message;
|
|
||||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MQReceiver {
|
public class MQReceiver {
|
||||||
|
|
||||||
|
@ -36,6 +34,9 @@ public class MQReceiver {
|
||||||
@Autowired
|
@Autowired
|
||||||
MiaoshaService miaoshaService;
|
MiaoshaService miaoshaService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private com.geekq.api.service.GoodsService goodsServiceRpc;
|
||||||
|
|
||||||
// @Autowired
|
// @Autowired
|
||||||
// MiaoShaMessageService messageService ;
|
// MiaoShaMessageService messageService ;
|
||||||
|
|
||||||
|
@ -46,7 +47,13 @@ public class MQReceiver {
|
||||||
MiaoshaUser user = mm.getUser();
|
MiaoshaUser user = mm.getUser();
|
||||||
long goodsId = mm.getGoodsId();
|
long goodsId = mm.getGoodsId();
|
||||||
|
|
||||||
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
// GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
||||||
|
ResultGeekQOrder<GoodsVoOrder> goodsVoOrderResultGeekQOrder = goodsServiceRpc.getGoodsVoByGoodsId(goodsId);
|
||||||
|
if(!AbstractResultOrder.isSuccess(goodsVoOrderResultGeekQOrder)){
|
||||||
|
throw new GlobleException(ResultStatus.SESSION_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
GoodsVoOrder goods= goodsVoOrderResultGeekQOrder.getData();
|
||||||
int stock = goods.getStockCount();
|
int stock = goods.getStockCount();
|
||||||
if(stock <= 0) {
|
if(stock <= 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.geekq.miaosha.redis.redismanager;
|
||||||
|
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
public class RedisLimitRateWithLUA {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
System.out.println("请求是否被执行:"+accquire());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean accquire() throws IOException, URISyntaxException {
|
||||||
|
Jedis jedis = new Jedis("39.107.245.253");
|
||||||
|
|
||||||
|
String lua =
|
||||||
|
"local key = KEYS[1] " +
|
||||||
|
" local limit = tonumber(ARGV[1]) " +
|
||||||
|
" local current = tonumber(redis.call('get', key) or '0')" +
|
||||||
|
" if current + 1 > limit " +
|
||||||
|
" then return 0 " +
|
||||||
|
" else "+
|
||||||
|
" redis.call('INCRBY', key,'1')" +
|
||||||
|
" redis.call('expire', key,'2') " +
|
||||||
|
" end return 1 ";
|
||||||
|
|
||||||
|
String key = "ip:" + System.currentTimeMillis()/1000; // 当前秒
|
||||||
|
String limit = "3"; // 最大限制
|
||||||
|
List<String> keys = new ArrayList<String>();
|
||||||
|
keys.add(key);
|
||||||
|
List<String> args = new ArrayList<String>();
|
||||||
|
args.add(limit);
|
||||||
|
jedis.auth("youxin11");
|
||||||
|
String luaScript = jedis.scriptLoad(lua);
|
||||||
|
Long result = (Long)jedis.evalsha(luaScript, keys, args);
|
||||||
|
return result == 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ import redis.clients.jedis.Jedis;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static redis.clients.jedis.Protocol.Command.INCRBY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lua脚本使用
|
* lua脚本使用
|
||||||
*/
|
*/
|
||||||
|
@ -92,4 +94,37 @@ public class RedisLua {
|
||||||
logger.error("统计访问次数失败!!!",e);
|
logger.error("统计访问次数失败!!!",e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void currentlimitMinute() {
|
||||||
|
|
||||||
|
Jedis jedis = null;
|
||||||
|
try {
|
||||||
|
jedis = RedisManager.getJedis();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String lua =
|
||||||
|
"local key = KEYS[1] " +
|
||||||
|
"local limit = tonumber(ARGV[1]) " +
|
||||||
|
"local current = tonumber(redis.call('get', key) or '0') " +
|
||||||
|
"if current + 1 > limit then return 0 " +
|
||||||
|
"else redis.call('INCRBY', key,'1')" +
|
||||||
|
" redis.call('expire', key,'2') " +
|
||||||
|
"end return 1";
|
||||||
|
|
||||||
|
List<String> keys = new ArrayList<String>();
|
||||||
|
keys.add("ip:limit:127.0.0.1");
|
||||||
|
List<String> argves = new ArrayList<String>();
|
||||||
|
argves.add("6000");
|
||||||
|
argves.add("5");
|
||||||
|
jedis.auth("xxxx");
|
||||||
|
|
||||||
|
// Object evalSha = jedis.evalsha(lua);
|
||||||
|
String luaScript = jedis.scriptLoad(lua);
|
||||||
|
System.out.println(luaScript);
|
||||||
|
Object object = jedis.evalsha(luaScript, keys, argves);
|
||||||
|
System.out.println(object);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
local key = KEYS[1] --限流KEY(一秒一个)
|
||||||
|
local limit = tonumber(ARGV[1]) --限流大小
|
||||||
|
local current = tonumber(redis.call('get', key) or "0")
|
||||||
|
if current + 1 > limit then --如果超出限流大小
|
||||||
|
return 0
|
||||||
|
else --请求数+1,并设置2秒过期
|
||||||
|
redis.call("INCRBY", key,"1")
|
||||||
|
redis.call("expire", key,"2")
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- ip限流
|
||||||
|
|
||||||
|
|
||||||
|
local key = "rate.limit:" .. KEYS[1]
|
||||||
|
local limit = tonumber(ARGV[1])
|
||||||
|
local expire_time = ARGV[2]
|
||||||
|
|
||||||
|
local is_exists = redis.call("EXISTS", key)
|
||||||
|
if is_exists == 1 then
|
||||||
|
if redis.call("INCR", key) > limit then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
redis.call("SET", key, 1)
|
||||||
|
redis.call("EXPIRE", key, expire_time)
|
||||||
|
return 1
|
||||||
|
end
|
|
@ -1,5 +1,7 @@
|
||||||
package com.geekq.miaosha.service;
|
package com.geekq.miaosha.service;
|
||||||
|
|
||||||
|
import com.alibaba.dubbo.config.annotation.Reference;
|
||||||
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
import com.geekq.miaosha.redis.MiaoshaKey;
|
import com.geekq.miaosha.redis.MiaoshaKey;
|
||||||
import com.geekq.miaosha.redis.RedisService;
|
import com.geekq.miaosha.redis.RedisService;
|
||||||
import com.geekq.miasha.entity.MiaoshaOrder;
|
import com.geekq.miasha.entity.MiaoshaOrder;
|
||||||
|
@ -29,10 +31,14 @@ public class MiaoshaService {
|
||||||
@Autowired
|
@Autowired
|
||||||
RedisService redisService;
|
RedisService redisService;
|
||||||
|
|
||||||
|
@Reference(version = "${demo.service.version}",retries = 3,timeout = 6000)
|
||||||
|
private com.geekq.api.service.GoodsService goodsServiceRpc;
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {
|
public OrderInfo miaosha(MiaoshaUser user, GoodsVoOrder goods) {
|
||||||
//减库存 下订单 写入秒杀订单
|
//减库存 下订单 写入秒杀订单
|
||||||
boolean success = goodsService.reduceStock(goods);
|
// boolean success = goodsService.reduceStock(goods);
|
||||||
|
boolean success =goodsServiceRpc.reduceStock(goods);
|
||||||
if(success){
|
if(success){
|
||||||
return orderService.createOrder(user,goods) ;
|
return orderService.createOrder(user,goods) ;
|
||||||
}else {
|
}else {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.geekq.miaosha.service;
|
package com.geekq.miaosha.service;
|
||||||
|
|
||||||
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
import com.geekq.miaosha.mapper.OrderMapper;
|
import com.geekq.miaosha.mapper.OrderMapper;
|
||||||
import com.geekq.miaosha.redis.OrderKey;
|
import com.geekq.miaosha.redis.OrderKey;
|
||||||
import com.geekq.miaosha.redis.RedisService;
|
import com.geekq.miaosha.redis.RedisService;
|
||||||
|
@ -37,7 +38,7 @@ public class OrderService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public OrderInfo createOrder(MiaoshaUser user, GoodsVo goods) {
|
public OrderInfo createOrder(MiaoshaUser user, GoodsVoOrder goods) {
|
||||||
OrderInfo orderInfo = new OrderInfo();
|
OrderInfo orderInfo = new OrderInfo();
|
||||||
orderInfo.setCreateDate(new Date());
|
orderInfo.setCreateDate(new Date());
|
||||||
orderInfo.setDeliveryAddrId(0L);
|
orderInfo.setDeliveryAddrId(0L);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
local key = KEYS[1] --限流KEY(一秒一个)
|
||||||
|
local limit = tonumber(ARGV[1]) --限流大小
|
||||||
|
local current = tonumber(redis.call('get', key) or "0")
|
||||||
|
if current + 1 > limit then --如果超出限流大小
|
||||||
|
return 0
|
||||||
|
else --请求数+1,并设置2秒过期
|
||||||
|
redis.call("INCRBY", key,"1")
|
||||||
|
redis.call("expire", key,"2")
|
||||||
|
end
|
||||||
|
return 1
|
|
@ -1,16 +1,19 @@
|
||||||
package com.geekq.miaosha;
|
package com.geekq.miaosha;
|
||||||
|
|
||||||
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
|
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.ImportResource;
|
||||||
|
|
||||||
@EnableDubbo
|
@ImportResource(value={"classpath:consumer.xml"})
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@MapperScan("com.geekq.miaosha.mapper")
|
@MapperScan("com.geekq.miaosha.mapper")
|
||||||
public class GeekQMainApplication {
|
public class GeekQMainApplication {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
// RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
|
||||||
|
// Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://localhost:2181"));
|
||||||
|
// registry.register(URL.valueOf("override://0.0.0.0/com.geekq.api.service.GoodsService?category=configurators&dynamic=false&application=dubbo-consumer2.0&mock=fail:return+444"));
|
||||||
SpringApplication.run(GeekQMainApplication.class, args);
|
SpringApplication.run(GeekQMainApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
package com.geekq.miaosha.controller;
|
package com.geekq.miaosha.controller;
|
||||||
|
|
||||||
import com.alibaba.dubbo.config.annotation.Reference;
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
|
import com.geekq.api.utils.AbstractResultOrder;
|
||||||
|
import com.geekq.api.utils.ResultGeekQOrder;
|
||||||
|
import com.geekq.miaosha.interceptor.RequireLogin;
|
||||||
import com.geekq.miaosha.redis.GoodsKey;
|
import com.geekq.miaosha.redis.GoodsKey;
|
||||||
import com.geekq.miaosha.redis.RedisService;
|
import com.geekq.miaosha.redis.RedisService;
|
||||||
import com.geekq.miaosha.service.GoodsService;
|
import com.geekq.miaosha.service.GoodsService;
|
||||||
import com.geekq.miaosha.service.MiaoShaUserService;
|
import com.geekq.miaosha.service.MiaoShaUserService;
|
||||||
import com.geekq.miasha.entity.MiaoshaUser;
|
import com.geekq.miasha.entity.MiaoshaUser;
|
||||||
|
import com.geekq.miasha.enums.enums.ResultStatus;
|
||||||
import com.geekq.miasha.enums.resultbean.ResultGeekQ;
|
import com.geekq.miasha.enums.resultbean.ResultGeekQ;
|
||||||
|
import com.geekq.miasha.exception.GlobleException;
|
||||||
import com.geekq.miasha.vo.GoodsDetailVo;
|
import com.geekq.miasha.vo.GoodsDetailVo;
|
||||||
import com.geekq.miasha.vo.GoodsVo;
|
import com.geekq.miasha.vo.GoodsVo;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -40,7 +45,7 @@ public class GoodsController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private GoodsService goodsService;
|
private GoodsService goodsService;
|
||||||
|
|
||||||
@Reference(version = "${demo.service.version}")
|
@Autowired
|
||||||
private com.geekq.api.service.GoodsService goodsServiceRpc;
|
private com.geekq.api.service.GoodsService goodsServiceRpc;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -54,12 +59,19 @@ public class GoodsController extends BaseController {
|
||||||
* 5000 * 10
|
* 5000 * 10
|
||||||
* QPS:2884, load:5
|
* QPS:2884, load:5
|
||||||
* */
|
* */
|
||||||
|
@RequireLogin(seconds = 5, maxCount = 5, needLogin = true)
|
||||||
@RequestMapping(value="/to_list", produces="text/html")
|
@RequestMapping(value="/to_list", produces="text/html")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String list(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user) {
|
public String list(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user) {
|
||||||
model.addAttribute("user", user);
|
model.addAttribute("user", user);
|
||||||
// ResultGeekQ<List<com.geekq.api.entity.GoodsVo>> goodsList1 = goodsServiceRpc.listGoodsVo();
|
|
||||||
List<GoodsVo> goodsList = goodsService.listGoodsVo();
|
//订单服务化接口 miaosha-order
|
||||||
|
ResultGeekQOrder<List<GoodsVoOrder>> resultGoods = goodsServiceRpc.listGoodsVo();
|
||||||
|
|
||||||
|
if(!AbstractResultOrder.isSuccess(resultGoods)){
|
||||||
|
throw new GlobleException(ResultStatus.SYSTEM_ERROR);
|
||||||
|
}
|
||||||
|
List<GoodsVoOrder> goodsList = resultGoods.getData();
|
||||||
model.addAttribute("goodsList", goodsList);
|
model.addAttribute("goodsList", goodsList);
|
||||||
return render(request,response,model,"goods_list", GoodsKey.getGoodsList,"");
|
return render(request,response,model,"goods_list", GoodsKey.getGoodsList,"");
|
||||||
}
|
}
|
||||||
|
@ -77,6 +89,13 @@ public class GoodsController extends BaseController {
|
||||||
}
|
}
|
||||||
//手动渲染
|
//手动渲染
|
||||||
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
||||||
|
/**
|
||||||
|
* rpc服务化接口
|
||||||
|
*/
|
||||||
|
ResultGeekQOrder<GoodsVoOrder> goodsVoOrderResultGeekQOrder = goodsServiceRpc.getGoodsVoByGoodsId(goodsId);
|
||||||
|
if(!AbstractResultOrder.isSuccess(goodsVoOrderResultGeekQOrder)){
|
||||||
|
throw new GlobleException(ResultStatus.SESSION_ERROR);
|
||||||
|
}
|
||||||
model.addAttribute("goods", goods);
|
model.addAttribute("goods", goods);
|
||||||
|
|
||||||
long startAt = goods.getStartDate().getTime();
|
long startAt = goods.getStartDate().getTime();
|
||||||
|
@ -126,7 +145,16 @@ public class GoodsController extends BaseController {
|
||||||
public ResultGeekQ<GoodsDetailVo> detail(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user,
|
public ResultGeekQ<GoodsDetailVo> detail(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user,
|
||||||
@PathVariable("goodsId")long goodsId) {
|
@PathVariable("goodsId")long goodsId) {
|
||||||
ResultGeekQ<GoodsDetailVo> result = ResultGeekQ.build();
|
ResultGeekQ<GoodsDetailVo> result = ResultGeekQ.build();
|
||||||
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
|
|
||||||
|
/**
|
||||||
|
* 服务化rpc接口
|
||||||
|
*/
|
||||||
|
ResultGeekQOrder<GoodsVoOrder> goodsVoOrderResultGeekQOrder = goodsServiceRpc.getGoodsVoByGoodsId(goodsId);
|
||||||
|
if(!AbstractResultOrder.isSuccess(goodsVoOrderResultGeekQOrder)){
|
||||||
|
throw new GlobleException(ResultStatus.SESSION_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
GoodsVoOrder goods = goodsVoOrderResultGeekQOrder.getData();
|
||||||
long startAt = goods.getStartDate().getTime();
|
long startAt = goods.getStartDate().getTime();
|
||||||
long endAt = goods.getEndDate().getTime();
|
long endAt = goods.getEndDate().getTime();
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
|
@ -30,21 +30,20 @@ public class LoginController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private MiaoShaUserService userService;
|
private MiaoShaUserService userService;
|
||||||
|
|
||||||
@Reference(version = "${demo.service.version}")
|
@Reference(version = "${demo.service.version}",mock = "return null")
|
||||||
private DemoService demoService;
|
private DemoService demoService;
|
||||||
|
|
||||||
@RequestMapping("/sayHello/{name}")
|
@RequestMapping("/sayHello")
|
||||||
@ResponseBody
|
public String sayHello() throws Exception {
|
||||||
public String sayHello(@PathVariable("name") String name) {
|
return "login222";
|
||||||
|
|
||||||
return demoService.sayHello(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping("/to_login")
|
@RequestMapping("/to_login")
|
||||||
public String tologin(LoginVo loginVo, Model model) {
|
public String tologin(LoginVo loginVo, Model model) {
|
||||||
logger.info(loginVo.toString());
|
logger.info(loginVo.toString());
|
||||||
|
|
||||||
//未完成
|
//未完成
|
||||||
RedisLua.vistorCount(COUNTLOGIN);
|
RedisLua.vistorCount(COUNTLOGIN);
|
||||||
String count = RedisLua.getVistorCount(COUNTLOGIN).toString();
|
String count = RedisLua.getVistorCount(COUNTLOGIN).toString();
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.geekq.miaosha.rabbitmq.MQSender;
|
||||||
import com.geekq.miaosha.rabbitmq.MiaoshaMessage;
|
import com.geekq.miaosha.rabbitmq.MiaoshaMessage;
|
||||||
import com.geekq.miaosha.redis.GoodsKey;
|
import com.geekq.miaosha.redis.GoodsKey;
|
||||||
import com.geekq.miaosha.redis.RedisService;
|
import com.geekq.miaosha.redis.RedisService;
|
||||||
|
import com.geekq.miaosha.redis.redismanager.RedisLimitRateWithLUA;
|
||||||
import com.geekq.miaosha.service.GoodsService;
|
import com.geekq.miaosha.service.GoodsService;
|
||||||
import com.geekq.miaosha.service.MiaoShaUserService;
|
import com.geekq.miaosha.service.MiaoShaUserService;
|
||||||
import com.geekq.miaosha.service.MiaoshaService;
|
import com.geekq.miaosha.service.MiaoshaService;
|
||||||
|
@ -25,7 +26,9 @@ import javax.imageio.ImageIO;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -89,6 +92,19 @@ public class MiaoshaController implements InitializingBean {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分布式限流
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
RedisLimitRateWithLUA.accquire();
|
||||||
|
} catch (IOException e) {
|
||||||
|
result.withError(EXCEPTION.getCode(), REPEATE_MIAOSHA.getMessage());
|
||||||
|
return result;
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
result.withError(EXCEPTION.getCode(), REPEATE_MIAOSHA.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//是否已经秒杀到
|
//是否已经秒杀到
|
||||||
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(Long.valueOf(user.getNickname()), goodsId);
|
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(Long.valueOf(user.getNickname()), goodsId);
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
|
|
|
@ -68,18 +68,16 @@ spring.rabbitmq.publisher-confirms=true
|
||||||
spring.rabbitmq.listener.direct.acknowledge-mode=manual
|
spring.rabbitmq.listener.direct.acknowledge-mode=manual
|
||||||
spring.rabbitmq.listener.simple.acknowledge-mode=manual
|
spring.rabbitmq.listener.simple.acknowledge-mode=manual
|
||||||
|
|
||||||
spring.application.name = dubbo-consumer
|
|
||||||
server.port = 9091
|
server.port = 9091
|
||||||
|
#spring.application.name = dubbo-consumer
|
||||||
dubbo.application.name = dubbo-consumer
|
#
|
||||||
|
#dubbo.application.name = dubbo-consumer
|
||||||
demo.service.version = 1.0.0
|
#demo.service.version = 1.0.0
|
||||||
|
#dubbo.protocol.name = dubbo
|
||||||
dubbo.protocol.name = dubbo
|
#dubbo.protocol.port = 20880
|
||||||
dubbo.protocol.port = 20880
|
#dubbo.registry.address = zookeeper://localhost:2181
|
||||||
|
#dubbo.consumer.timeout = 5000
|
||||||
dubbo.registry.address = zookeeper://localhost:2181
|
#dubbo.consumer.mock= true
|
||||||
|
|
||||||
dubbo.consumer.timeout = 5000
|
|
||||||
## maven隔离
|
## maven隔离
|
||||||
#spring.profiles.active=dev
|
#spring.profiles.active=dev
|
17
miaosha-2version/miaosha-web/src/main/resources/consumer.xml
Normal file
17
miaosha-2version/miaosha-web/src/main/resources/consumer.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||||
|
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||||
|
|
||||||
|
<!-- 为当前服务提供者取个名字,并且提供给注册中心 -->
|
||||||
|
<dubbo:application name="dubbo-consumer3"></dubbo:application>
|
||||||
|
|
||||||
|
<!-- 注册中心的配置,用于消费者的监听 -->
|
||||||
|
<dubbo:registry protocol="zookeeper" address="localhost:2181"></dubbo:registry>
|
||||||
|
|
||||||
|
<!--<!– 监听服务,通过注册中心去进行查找,查找到后进行服务调用 –>-->
|
||||||
|
<dubbo:reference id="goodsServiceRpc" interface="com.geekq.api.service.GoodsService"
|
||||||
|
retries="3" check="false" init="true" timeout="3000" group="goods2"></dubbo:reference>
|
||||||
|
</beans>
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
www.coedq.net
|
||||||
|
|
||||||
|
www.xttblog.com
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#slider {
|
||||||
|
|
||||||
|
margin: 100px auto;
|
||||||
|
|
||||||
|
width: 300px;
|
||||||
|
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
background-color: #dae2d0;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
-moz-user-select: none;
|
||||||
|
|
||||||
|
-webkit-user-select: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#slider_bg {
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: #7AC23C;
|
||||||
|
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#label {
|
||||||
|
|
||||||
|
width: 46px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
height: 38px;
|
||||||
|
|
||||||
|
line-height: 38px;
|
||||||
|
|
||||||
|
border: 1px solid #cccccc;
|
||||||
|
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
z-index: 3;
|
||||||
|
|
||||||
|
cursor: move;
|
||||||
|
|
||||||
|
color: #ff9e77;
|
||||||
|
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
font-weight: 900;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#labelTip {
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
font-family: 'Microsoft Yahei', serif;
|
||||||
|
|
||||||
|
color: #787878;
|
||||||
|
|
||||||
|
line-height: 38px;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
www.coedq.net
|
||||||
|
|
||||||
|
www.xttblog.com
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
www.coedq.net
|
||||||
|
|
||||||
|
www.xttblog.com
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#slider {
|
||||||
|
|
||||||
|
margin: 100px auto;
|
||||||
|
|
||||||
|
width: 300px;
|
||||||
|
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
background-color: #dae2d0;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
-moz-user-select: none;
|
||||||
|
|
||||||
|
-webkit-user-select: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#slider_bg {
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: #7AC23C;
|
||||||
|
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#label {
|
||||||
|
|
||||||
|
width: 46px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
height: 38px;
|
||||||
|
|
||||||
|
line-height: 38px;
|
||||||
|
|
||||||
|
border: 1px solid #cccccc;
|
||||||
|
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
z-index: 3;
|
||||||
|
|
||||||
|
cursor: move;
|
||||||
|
|
||||||
|
color: #ff9e77;
|
||||||
|
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
font-weight: 900;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#labelTip {
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
font-family: 'Microsoft Yahei', serif;
|
||||||
|
|
||||||
|
color: #787878;
|
||||||
|
|
||||||
|
line-height: 38px;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
www.coedq.net
|
||||||
|
|
||||||
|
www.xttblog.com
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,64 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>登录界面</title>
|
||||||
|
<link rel="stylesheet" href="css/reset.css" />
|
||||||
|
<link rel="stylesheet" href="css/common.css" />
|
||||||
|
<link rel="stylesheet" href="css/font-awesome.min.css" />
|
||||||
|
<script type="text/javascript" src="js/jquery.min.js" ></script>
|
||||||
|
<script type="text/javascript" src="js/common.js" ></script>
|
||||||
|
<script type="text/javascript" src="js/md5.min.js"></script>
|
||||||
|
<script type="text/javascript" src="jquery-validation/jquery.validate.min.js"></script>
|
||||||
|
<script type="text/javascript" src="layer/layer.js"></script>
|
||||||
|
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
<script type="text/javascript" src="layer/layer.js"></script>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="/css/slide-unlock.css" type="text/css" />
|
||||||
|
<script type="text/javascript" src="js/slideunlock/slideunlock.js"></script>
|
||||||
|
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body, h1 {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: #393939;
|
||||||
|
color: #d5d4ff;
|
||||||
|
overflow: hidden
|
||||||
|
}
|
||||||
|
#demo {
|
||||||
|
width: 600px;
|
||||||
|
margin: 150px auto;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px dashed #d5d4ff;
|
||||||
|
border-radius: 10px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
-webkit-border-radius: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
var slider = new SliderUnlock("#slider",{
|
||||||
|
successLabelTip : "欢迎访问业余草网站"
|
||||||
|
},function(){
|
||||||
|
alert("验证成功,即将跳转至业余草首页");
|
||||||
|
//window.location.href="http://www.xttblog.com"
|
||||||
|
});
|
||||||
|
slider.init();
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="demo">
|
||||||
|
<div id="slider">
|
||||||
|
<div id="slider_bg"></div>
|
||||||
|
<span id="label">>></span> <span id="labelTip">拖动滑块验证</span> </div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,378 @@
|
||||||
|
|
||||||
|
;(function ($,window,document,undefined) {
|
||||||
|
|
||||||
|
function SliderUnlock(elm, options, success){
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
var $elm = me.checkElm(elm) ? $(elm) : $;
|
||||||
|
|
||||||
|
success = me.checkFn(success) ? success : function(){};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
|
||||||
|
successLabelTip: "Successfully Verified",
|
||||||
|
|
||||||
|
duration: 200,
|
||||||
|
|
||||||
|
swipestart: false,
|
||||||
|
|
||||||
|
min: 0,
|
||||||
|
|
||||||
|
max: $elm.width(),
|
||||||
|
|
||||||
|
index: 0,
|
||||||
|
|
||||||
|
IsOk: false,
|
||||||
|
|
||||||
|
lableIndex: 0
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
opts = $.extend(opts, options||{});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//$elm
|
||||||
|
|
||||||
|
me.elm = $elm;
|
||||||
|
|
||||||
|
//opts
|
||||||
|
|
||||||
|
me.opts = opts;
|
||||||
|
|
||||||
|
//是否开始滑动
|
||||||
|
|
||||||
|
me.swipestart = opts.swipestart;
|
||||||
|
|
||||||
|
//最小值
|
||||||
|
|
||||||
|
me.min = opts.min;
|
||||||
|
|
||||||
|
//最大值
|
||||||
|
|
||||||
|
me.max = opts.max;
|
||||||
|
|
||||||
|
//当前滑动条所处的位置
|
||||||
|
|
||||||
|
me.index = opts.index;
|
||||||
|
|
||||||
|
//是否滑动成功
|
||||||
|
|
||||||
|
me.isOk = opts.isOk;
|
||||||
|
|
||||||
|
//滑块宽度
|
||||||
|
|
||||||
|
me.labelWidth = me.elm.find('#label').width();
|
||||||
|
|
||||||
|
//滑块背景
|
||||||
|
|
||||||
|
me.sliderBg = me.elm.find('#slider_bg');
|
||||||
|
|
||||||
|
//鼠标在滑动按钮的位置
|
||||||
|
|
||||||
|
me.lableIndex = opts.lableIndex;
|
||||||
|
|
||||||
|
//success
|
||||||
|
|
||||||
|
me.success = success;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SliderUnlock.prototype.init = function () {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
me.updateView();
|
||||||
|
|
||||||
|
me.elm.find("#label").on("mousedown", function (event) {
|
||||||
|
|
||||||
|
var e = event || window.event;
|
||||||
|
|
||||||
|
me.lableIndex = e.clientX - this.offsetLeft;
|
||||||
|
|
||||||
|
me.handerIn();
|
||||||
|
|
||||||
|
}).on("mousemove", function (event) {
|
||||||
|
|
||||||
|
me.handerMove(event);
|
||||||
|
|
||||||
|
}).on("mouseup", function (event) {
|
||||||
|
|
||||||
|
me.handerOut();
|
||||||
|
|
||||||
|
}).on("mouseout", function (event) {
|
||||||
|
|
||||||
|
me.handerOut();
|
||||||
|
|
||||||
|
}).on("touchstart", function (event) {
|
||||||
|
|
||||||
|
var e = event || window.event;
|
||||||
|
|
||||||
|
me.lableIndex = e.originalEvent.touches[0].pageX - this.offsetLeft;
|
||||||
|
|
||||||
|
me.handerIn();
|
||||||
|
|
||||||
|
}).on("touchmove", function (event) {
|
||||||
|
|
||||||
|
me.handerMove(event, "mobile");
|
||||||
|
|
||||||
|
}).on("touchend", function (event) {
|
||||||
|
|
||||||
|
me.handerOut();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 鼠标/手指接触滑动按钮
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.handerIn = function () {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
me.swipestart = true;
|
||||||
|
|
||||||
|
me.min = 0;
|
||||||
|
|
||||||
|
me.max = me.elm.width();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 鼠标/手指移出
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.handerOut = function () {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
//停止
|
||||||
|
|
||||||
|
me.swipestart = false;
|
||||||
|
|
||||||
|
//me.move();
|
||||||
|
|
||||||
|
if (me.index < me.max) {
|
||||||
|
|
||||||
|
me.reset();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 鼠标/手指移动
|
||||||
|
|
||||||
|
* @param event
|
||||||
|
|
||||||
|
* @param type
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.handerMove = function (event, type) {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (me.swipestart) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
event = event || window.event;
|
||||||
|
|
||||||
|
if (type == "mobile") {
|
||||||
|
|
||||||
|
me.index = event.originalEvent.touches[0].pageX - me.lableIndex;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
me.index = event.clientX - me.lableIndex;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
me.move();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 鼠标/手指移动过程
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.move = function () {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if ((me.index + me.labelWidth) >= me.max) {
|
||||||
|
|
||||||
|
me.index = me.max - me.labelWidth -2;
|
||||||
|
|
||||||
|
//停止
|
||||||
|
|
||||||
|
me.swipestart = false;
|
||||||
|
|
||||||
|
//解锁
|
||||||
|
|
||||||
|
me.isOk = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me.index < 0) {
|
||||||
|
|
||||||
|
me.index = me.min;
|
||||||
|
|
||||||
|
//未解锁
|
||||||
|
|
||||||
|
me.isOk = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me.index+me.labelWidth+2 == me.max && me.max > 0 && me.isOk) {
|
||||||
|
|
||||||
|
//解锁默认操作
|
||||||
|
|
||||||
|
$('#label').unbind().next('#labelTip').
|
||||||
|
|
||||||
|
text(me.opts.successLabelTip).css({'color': '#fff'});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
me.success();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
me.updateView();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 更新视图
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.updateView = function () {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
me.sliderBg.css('width', me.index);
|
||||||
|
|
||||||
|
me.elm.find("#label").css("left", me.index + "px")
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 重置slide的起点
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.reset = function () {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
me.index = 0;
|
||||||
|
|
||||||
|
me.sliderBg .animate({'width':0},me.opts.duration);
|
||||||
|
|
||||||
|
me.elm.find("#label").animate({left: me.index}, me.opts.duration)
|
||||||
|
|
||||||
|
.next("#lableTip").animate({opacity: 1}, me.opts.duration);
|
||||||
|
|
||||||
|
me.updateView();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 检测元素是否存在
|
||||||
|
|
||||||
|
* @param elm
|
||||||
|
|
||||||
|
* @returns {boolean}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.checkElm = function (elm) {
|
||||||
|
|
||||||
|
if($(elm).length > 0){
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
throw "this element does not exist.";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* 检测传入参数是否是function
|
||||||
|
|
||||||
|
* @param fn
|
||||||
|
|
||||||
|
* @returns {boolean}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SliderUnlock.prototype.checkFn = function (fn) {
|
||||||
|
|
||||||
|
if(typeof fn === "function"){
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
throw "the param is not a function.";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
window['SliderUnlock'] = SliderUnlock;
|
||||||
|
|
||||||
|
})(jQuery, window, document);
|
|
@ -0,0 +1,73 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<title>登录</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<link rel="stylesheet" href="css/reset.css" />
|
||||||
|
<link rel="stylesheet" href="css/common.css" />
|
||||||
|
<link rel="stylesheet" href="css/font-awesome.min.css" />
|
||||||
|
<!-- jquery -->
|
||||||
|
<script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>
|
||||||
|
<!-- bootstrap -->
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/bootstrap.min.css}" />
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/js/bootstrap-3.3.2-dist/css/bootstrap.css}" />
|
||||||
|
<script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script>
|
||||||
|
<!-- jquery-validator -->
|
||||||
|
<script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.min.js}"></script>
|
||||||
|
<script type="text/javascript" th:src="@{/jquery-validation/localization/messages_zh.min.js}"></script>
|
||||||
|
<!-- layer -->
|
||||||
|
<script type="text/javascript" th:src="@{/layer/layer.js}"></script>
|
||||||
|
<!-- md5.js -->
|
||||||
|
<script type="text/javascript" th:src="@{/js/md5.min.js}"></script>
|
||||||
|
<!-- common.js -->
|
||||||
|
<script type="text/javascript" th:src="@{/js/common.js}"></script>
|
||||||
|
<script type="text/javascript" th:src="@{/js/bootstrap-3.3.2-dist/js/bootstrap.js}"></script>
|
||||||
|
<script type="text/javascript" th:src="@{/js/plugins/jquery-validation/jquery.validate.js}"></script>
|
||||||
|
<script type="text/javascript" th:src="@{/js/plugins/jquery-validation/localization/messages_zh.js}"></script>
|
||||||
|
<script type="text/javascript" th:src="@{/js/plugins/jquery.form.js}"></script>
|
||||||
|
<script type="text/javascript" th:src="@{/js/jquery.bootstrap.min.js}"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/css/slide-unlock.css}" />
|
||||||
|
<script type="text/javascript" th:src="@{/js/slideunlock/slideunlock.js}"></script>
|
||||||
|
<style>
|
||||||
|
html, body, h1 {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: #393939;
|
||||||
|
color: #d5d4ff;
|
||||||
|
overflow: hidden
|
||||||
|
}
|
||||||
|
#demo {
|
||||||
|
width: 600px;
|
||||||
|
margin: 150px auto;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px dashed #d5d4ff;
|
||||||
|
border-radius: 10px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
-webkit-border-radius: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="demo">
|
||||||
|
<div id="slider">
|
||||||
|
<div id="slider_bg"></div>
|
||||||
|
<span id="label">>></span> <span id="labelTip">拖动滑块验证</span> </div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
var slider = new SliderUnlock("#slider",{
|
||||||
|
successLabelTip : "欢迎访问业余草网站"
|
||||||
|
},function(){
|
||||||
|
alert("验证成功,即将跳转至业余草首页");
|
||||||
|
//window.location.href="http://www.xttblog.com"
|
||||||
|
});
|
||||||
|
slider.init();
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</html>
|
|
@ -0,0 +1,53 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>拖拽滑动验证码插件 slideunlock.js</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE-edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="/css/slide-unlock.css" type="text/css" />
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/slideunlock/slideunlock.js"></script>
|
||||||
|
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body, h1 {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: #393939;
|
||||||
|
color: #d5d4ff;
|
||||||
|
overflow: hidden
|
||||||
|
}
|
||||||
|
#demo {
|
||||||
|
width: 600px;
|
||||||
|
margin: 150px auto;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px dashed #d5d4ff;
|
||||||
|
border-radius: 10px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
-webkit-border-radius: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="demo">
|
||||||
|
<div id="slider">
|
||||||
|
<div id="slider_bg"></div>
|
||||||
|
<span id="label">>></span> <span id="labelTip">拖动滑块验证</span> </div>
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
var slider = new SliderUnlock("#slider",{
|
||||||
|
successLabelTip : "欢迎访问业余草网站"
|
||||||
|
},function(){
|
||||||
|
alert("验证成功,即将跳转至业余草首页");
|
||||||
|
//window.location.href="http://www.xttblog.com"
|
||||||
|
});
|
||||||
|
slider.init();
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -6,14 +6,15 @@ import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.apache.ibatis.type.Alias;
|
import org.apache.ibatis.type.Alias;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Alias("goodsVo")
|
@Alias("goodsVoOrder")
|
||||||
public class GoodsVo {
|
public class GoodsVoOrder implements Serializable {
|
||||||
private Long id;
|
private Long id;
|
||||||
private String goodsName;
|
private String goodsName;
|
||||||
private String goodsTitle;
|
private String goodsTitle;
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.geekq.api.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.ibatis.type.Alias;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Alias("MiaoshaGoods")
|
||||||
|
public class MiaoshaGoods implements Serializable {
|
||||||
|
private Long id;
|
||||||
|
private Long goodsId;
|
||||||
|
private Integer stockCount;
|
||||||
|
private Date startDate;
|
||||||
|
private Date endDate;
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
package com.geekq.api.service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DemoService
|
|
||||||
* 服务Api接口类
|
|
||||||
* @author geekq
|
|
||||||
* @date 2018/6/6
|
|
||||||
*/
|
|
||||||
public interface DemoService {
|
|
||||||
|
|
||||||
String sayHello(String name);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.geekq.api.service;
|
package com.geekq.api.service;
|
||||||
|
|
||||||
import com.geekq.api.entity.GoodsVo;
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
import com.geekq.common.utils.resultbean.ResultGeekQ;
|
import com.geekq.api.utils.ResultGeekQOrder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -10,5 +10,22 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface GoodsService {
|
public interface GoodsService {
|
||||||
|
|
||||||
public ResultGeekQ<List<GoodsVo>> listGoodsVo();
|
/**
|
||||||
|
* 查询获取全部信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商品id查询货物信息
|
||||||
|
* @param goodsId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 减库存
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean reduceStock(GoodsVoOrder goods);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.geekq.api.service;
|
||||||
|
|
||||||
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
|
import com.geekq.api.service.GoodsService;
|
||||||
|
import com.geekq.api.utils.ResultGeekQOrder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 邱润泽
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class GoodsServiceMock implements GoodsService {
|
||||||
|
@Override
|
||||||
|
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo() {
|
||||||
|
List<GoodsVoOrder> list1 = new ArrayList<>();
|
||||||
|
ResultGeekQOrder<List<GoodsVoOrder>> list = ResultGeekQOrder.build();
|
||||||
|
list.setData(list1);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean reduceStock(GoodsVoOrder goods) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.geekq.api.utils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class AbstractResultOrder {
|
||||||
|
private ResultStatusOrder status;
|
||||||
|
private int code;
|
||||||
|
private String message;
|
||||||
|
protected AbstractResultOrder() {
|
||||||
|
}
|
||||||
|
protected AbstractResultOrder(ResultStatusOrder status, String message) {
|
||||||
|
this.code = status.getCode();
|
||||||
|
this.status = status;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractResultOrder(ResultStatusOrder status) {
|
||||||
|
this.code = status.getCode();
|
||||||
|
this.message = status.getMessage();
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSuccess(AbstractResultOrder result) {
|
||||||
|
return result != null && result.status == ResultStatusOrder.SUCCESS && result.getCode() == ResultStatusOrder.SUCCESS.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractResultOrder withError(ResultStatusOrder status) {
|
||||||
|
this.status = status;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractResultOrder withError(String message) {
|
||||||
|
this.status = ResultStatusOrder.SYSTEM_ERROR;
|
||||||
|
this.message = message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractResultOrder withError(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractResultOrder success() {
|
||||||
|
this.status = ResultStatusOrder.SUCCESS;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public ResultStatusOrder getStatus() {
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return this.message == null ? this.status.getMessage() : this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return this.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.geekq.api.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class ResultGeekQOrder<T> extends AbstractResultOrder implements Serializable {
|
||||||
|
private static final long serialVersionUID = 867933019328199779L;
|
||||||
|
private T data;
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
protected ResultGeekQOrder() {
|
||||||
|
}
|
||||||
|
protected ResultGeekQOrder(ResultStatusOrder status, String message) {
|
||||||
|
super(status, message);
|
||||||
|
}
|
||||||
|
protected ResultGeekQOrder(ResultStatusOrder status) {
|
||||||
|
super(status);
|
||||||
|
}
|
||||||
|
public static <T> ResultGeekQOrder<T> build() {
|
||||||
|
return new ResultGeekQOrder(ResultStatusOrder.SUCCESS, (String)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ResultGeekQOrder<T> build(String message) {
|
||||||
|
return new ResultGeekQOrder(ResultStatusOrder.SUCCESS, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ResultGeekQOrder<T> error(ResultStatusOrder status) {
|
||||||
|
return new ResultGeekQOrder<T>(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(T data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCount() {
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(Integer count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void success(T value) {
|
||||||
|
this.success();
|
||||||
|
this.data = value;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.geekq.api.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普通返回类
|
||||||
|
* 1打头 系统系列错误
|
||||||
|
* 2 注册登录系列错误
|
||||||
|
* 3 check 系列错误
|
||||||
|
* 4 秒杀错误
|
||||||
|
* 5 商品错误
|
||||||
|
* 6 订单错误
|
||||||
|
* @author qiurunze
|
||||||
|
*/
|
||||||
|
public enum ResultStatusOrder {
|
||||||
|
SUCCESS(0, "成功"),
|
||||||
|
FAILD(-1, "失败"),
|
||||||
|
EXCEPTION(-1, "系统异常"),
|
||||||
|
PARAM_ERROR(10000, "参数错误"),
|
||||||
|
SYSTEM_ERROR(10001, "系统错误"),
|
||||||
|
FILE_NOT_EXIST(10002, "文件不存在"),
|
||||||
|
FILE_NOT_DOWNLOAD(10003, "文件没有下载"),
|
||||||
|
FILE_NOT_GENERATE(10004, "文件没有生成"),
|
||||||
|
FILE_NOT_STORAGE(10005, "文件没有入库"),
|
||||||
|
SYSTEM_DB_ERROR(10006, "数据库系统错误"),
|
||||||
|
FILE_ALREADY_DOWNLOAD(10007, "文件已经下载"),
|
||||||
|
DATA_ALREADY_PEXISTS(10008, "数据已经存在"),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册登录
|
||||||
|
*/
|
||||||
|
RESIGETR_SUCCESS(20000,"注册成功!"),
|
||||||
|
RESIGETER_FAIL(200001,"注册失败!"),
|
||||||
|
CODE_FAIL(200002,"验证码不一致!"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check
|
||||||
|
*/
|
||||||
|
BIND_ERROR (30001,"参数校验异常:%s"),
|
||||||
|
ACCESS_LIMIT_REACHED (30002,"请求非法!"),
|
||||||
|
REQUEST_ILLEGAL (30004,"访问太频繁!"),
|
||||||
|
SESSION_ERROR (30005,"Session不存在或者已经失效!"),
|
||||||
|
PASSWORD_EMPTY (30006,"登录密码不能为空!"),
|
||||||
|
MOBILE_EMPTY (30007,"手机号不能为空!"),
|
||||||
|
MOBILE_ERROR (30008,"手机号格式错误!"),
|
||||||
|
MOBILE_NOT_EXIST (30009,"账号不存在!"),
|
||||||
|
PASSWORD_ERROR (30010,"密码错误!"),
|
||||||
|
USER_NOT_EXIST(30011,"用户不存在!"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单模块
|
||||||
|
*/
|
||||||
|
ORDER_NOT_EXIST(60001,"订单不存在"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀模块
|
||||||
|
*/
|
||||||
|
MIAO_SHA_OVER(40001,"商品已经秒杀完毕"),
|
||||||
|
REPEATE_MIAOSHA(40002,"不能重复秒杀"),
|
||||||
|
MIAOSHA_FAIL(40003,"秒杀失败"),
|
||||||
|
ORDER_GET_FAIL(40004,"订单获取失败");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品模块
|
||||||
|
*/
|
||||||
|
private int code;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private ResultStatusOrder(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return this.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOutputName() {
|
||||||
|
return this.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultStatusOrder(Object... args) {
|
||||||
|
this.message = String.format(this.message, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,32 @@
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/java</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.properties</include>
|
||||||
|
<include>**/*.xml</include>
|
||||||
|
</includes>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<!--<includes>-->
|
||||||
|
<!--<include>**/*.properties</include>-->
|
||||||
|
<!--<include>**/*.xml</include>-->
|
||||||
|
<!--<include>**/*.ini</include>-->
|
||||||
|
<!--</includes>-->
|
||||||
|
<filtering>false</filtering>
|
||||||
|
</resource>
|
||||||
|
<resource> <!--配置文件路径 -->
|
||||||
|
<directory>src/main/resources</directory> <!--这里对应项目存放配置文件的目录--> <!--开启filtering功能 -->
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<!--<include>application-${activatedProperties}.properties</include>-->
|
||||||
|
<include>application.properties</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package com.geekq.provider;
|
package com.geekq.provider;
|
||||||
|
|
||||||
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
|
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.ImportResource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DubboProviderApplication
|
* DubboProviderApplication
|
||||||
|
@ -11,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
* @author geekq
|
* @author geekq
|
||||||
* @date 2018/6/7
|
* @date 2018/6/7
|
||||||
*/
|
*/
|
||||||
@EnableDubbo
|
@ImportResource(value={"classpath:provider.xml"})
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@MapperScan("com.geekq.provider.mapper")
|
@MapperScan("com.geekq.provider.mapper")
|
||||||
public class DubboProviderApplication {
|
public class DubboProviderApplication {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.geekq.provider.mapper;
|
package com.geekq.provider.mapper;
|
||||||
|
|
||||||
import com.geekq.api.entity.GoodsVo;
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
|
import com.geekq.api.entity.MiaoshaGoods;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -10,9 +11,10 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface GoodsMapper {
|
public interface GoodsMapper {
|
||||||
|
|
||||||
public List<GoodsVo> listGoodsVo();
|
public List<GoodsVoOrder> listGoodsVo();
|
||||||
|
|
||||||
public GoodsVo getGoodsVoByGoodsId(@Param("goodsId") long goodsId);
|
public GoodsVoOrder getGoodsVoByGoodsId(@Param("goodsId") long goodsId);
|
||||||
|
|
||||||
|
public int reduceStock(MiaoshaGoods g);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
<mapper namespace="com.geekq.provider.mapper.GoodsMapper" >
|
<mapper namespace="com.geekq.provider.mapper.GoodsMapper" >
|
||||||
|
|
||||||
<resultMap id="BaseResultMap" type="goodsVo" >
|
<resultMap id="BaseResultMap" type="goodsVoOrder" >
|
||||||
<id column="id" property="id" jdbcType="BIGINT" />
|
<id column="id" property="id" jdbcType="BIGINT" />
|
||||||
<result column="goods_name" property="goodsName" jdbcType="VARCHAR" />
|
<result column="goods_name" property="goodsName" jdbcType="VARCHAR" />
|
||||||
<result column="goods_title" property="goodsTitle" jdbcType="VARCHAR" />
|
<result column="goods_title" property="goodsTitle" jdbcType="VARCHAR" />
|
||||||
|
@ -32,4 +32,8 @@
|
||||||
WHERE miaosha_goods.goods_id = #{goodsId,jdbcType=BIGINT}
|
WHERE miaosha_goods.goods_id = #{goodsId,jdbcType=BIGINT}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<update id="reduceStock" >
|
||||||
|
update miaosha_goods set stock_count = stock_count - 1
|
||||||
|
where goods_id = #{goodsId} and stock_count > 0
|
||||||
|
</update>
|
||||||
</mapper>
|
</mapper>
|
|
@ -1,20 +0,0 @@
|
||||||
package com.geekq.provider.service.impl;
|
|
||||||
|
|
||||||
import com.alibaba.dubbo.config.annotation.Service;
|
|
||||||
import com.geekq.api.service.DemoService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DemoServiceImpl
|
|
||||||
* 服务提供类
|
|
||||||
* @author geekq
|
|
||||||
* @date 2018/6/7
|
|
||||||
*/
|
|
||||||
@Service(version = "${demo.service.version}")
|
|
||||||
public class DemoServiceImpl implements DemoService {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String sayHello(String name) {
|
|
||||||
System.out.println("2321121212312312");
|
|
||||||
return "Hello, " + name + " (from Spring Boot)";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.geekq.provider.service.impl;
|
||||||
|
|
||||||
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
|
import com.geekq.api.service.GoodsService;
|
||||||
|
import com.geekq.api.utils.ResultGeekQOrder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 邱润泽
|
||||||
|
*/
|
||||||
|
@Service("goodGroupService")
|
||||||
|
public class GoodsGroupServiceImpl implements GoodsService {
|
||||||
|
@Override
|
||||||
|
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo() {
|
||||||
|
|
||||||
|
System.out.println("测试 group!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId) {
|
||||||
|
System.out.println("测试 group!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean reduceStock(GoodsVoOrder goods) {
|
||||||
|
System.out.println("测试 group!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,33 +1,64 @@
|
||||||
package com.geekq.provider.service.impl;
|
package com.geekq.provider.service.impl;
|
||||||
|
|
||||||
import com.alibaba.dubbo.config.annotation.Service;
|
import com.geekq.api.entity.GoodsVoOrder;
|
||||||
import com.geekq.api.entity.GoodsVo;
|
import com.geekq.api.entity.MiaoshaGoods;
|
||||||
import com.geekq.api.service.GoodsService;
|
import com.geekq.api.service.GoodsService;
|
||||||
import com.geekq.common.enums.ResultStatus;
|
import com.geekq.api.utils.ResultGeekQOrder;
|
||||||
import com.geekq.common.utils.resultbean.ResultGeekQ;
|
import com.geekq.api.utils.ResultStatusOrder;
|
||||||
import com.geekq.provider.mapper.GoodsMapper;
|
import com.geekq.provider.mapper.GoodsMapper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 邱润泽
|
* @author 邱润泽
|
||||||
*/
|
*/
|
||||||
@Service(version = "${demo.service.version}")
|
@Service("goodsService")
|
||||||
public class GoodsServiceImpl implements GoodsService {
|
public class GoodsServiceImpl implements GoodsService {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(GoodsServiceImpl.class);
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
GoodsMapper goodsMapper;
|
GoodsMapper goodsMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultGeekQ<List<GoodsVo>> listGoodsVo() {
|
public ResultGeekQOrder<List<GoodsVoOrder>> listGoodsVo() {
|
||||||
ResultGeekQ resultGeekQ = ResultGeekQ.build();
|
|
||||||
|
|
||||||
|
ResultGeekQOrder<List<GoodsVoOrder>> resultGeekQ = ResultGeekQOrder.build();
|
||||||
try {
|
try {
|
||||||
resultGeekQ.setData(goodsMapper.listGoodsVo());
|
resultGeekQ.setData(goodsMapper.listGoodsVo());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
resultGeekQ.withError(ResultStatus.SYSTEM_ERROR);
|
logger.error("获取订单数据失败!",e);
|
||||||
|
resultGeekQ.withError(ResultStatusOrder.ORDER_GET_FAIL);
|
||||||
|
}
|
||||||
|
return resultGeekQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultGeekQOrder<GoodsVoOrder> getGoodsVoByGoodsId(long goodsId) {
|
||||||
|
ResultGeekQOrder<GoodsVoOrder> resultGeekQ = ResultGeekQOrder.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
GoodsVoOrder goodsVoOrder = goodsMapper.getGoodsVoByGoodsId(goodsId);
|
||||||
|
resultGeekQ.setData(goodsVoOrder);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取单个订单失败!",e);
|
||||||
|
resultGeekQ.withError(ResultStatusOrder.ORDER_GET_FAIL);
|
||||||
}
|
}
|
||||||
return resultGeekQ;
|
return resultGeekQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean reduceStock(GoodsVoOrder goods) {
|
||||||
|
MiaoshaGoods g = new MiaoshaGoods();
|
||||||
|
g.setGoodsId(goods.getId());
|
||||||
|
int ret = goodsMapper.reduceStock(g);
|
||||||
|
return ret > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
spring.application.name = miaosha-order-provider
|
#spring.application.name = miaosha-order-provider
|
||||||
server.port = 9090
|
#server.port = 9090
|
||||||
|
#dubbo.application.name = miaosha-order-provider
|
||||||
|
#demo.service.version = 1.0.0
|
||||||
|
#dubbo.protocol.name = dubbo
|
||||||
|
#dubbo.protocol.port = 20880
|
||||||
|
#dubbo.registry.address = zookeeper://localhost:2181
|
||||||
|
#dubbo.provider.timeout = 1000
|
||||||
|
|
||||||
dubbo.application.name = miaosha-order-provider
|
|
||||||
|
|
||||||
demo.service.version = 1.0.0
|
|
||||||
|
|
||||||
dubbo.protocol.name = dubbo
|
|
||||||
dubbo.protocol.port = 20880
|
|
||||||
|
|
||||||
dubbo.registry.address = zookeeper://localhost:2181
|
|
||||||
|
|
||||||
dubbo.provider.timeout = 1000
|
|
||||||
|
|
||||||
|
|
||||||
mybatis.type-aliases-package=com.geekq.api.entity
|
mybatis.type-aliases-package=com.geekq.api.entity
|
||||||
|
@ -33,4 +29,6 @@ spring.datasource.testWhileIdle=true
|
||||||
spring.datasource.testOnBorrow=false
|
spring.datasource.testOnBorrow=false
|
||||||
spring.datasource.testOnReturn=false
|
spring.datasource.testOnReturn=false
|
||||||
spring.datasource.poolPreparedStatements=true
|
spring.datasource.poolPreparedStatements=true
|
||||||
spring.datasource.maxOpenPreparedStatements=20
|
spring.datasource.maxOpenPreparedStatements=20
|
||||||
|
|
||||||
|
server.port = 9090
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||||
|
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||||
|
|
||||||
|
<!-- 为当前服务提供者取个名字,并且提供给注册中心 -->
|
||||||
|
<dubbo:application name="miaosha-order-service"></dubbo:application>
|
||||||
|
|
||||||
|
<!-- 注册中心的配置,使用zk暴露服务 -->
|
||||||
|
<dubbo:registry protocol="zookeeper" address="localhost:2181"></dubbo:registry>
|
||||||
|
|
||||||
|
<!-- 定义暴露服务的端口号 -->
|
||||||
|
<dubbo:protocol name="dubbo" port="20880" ></dubbo:protocol>
|
||||||
|
|
||||||
|
<!-- 暴露具体的服务接口 本地伪装-->
|
||||||
|
<dubbo:service retries="3" interface="com.geekq.api.service.GoodsService"
|
||||||
|
ref="goodsService" group="goods2" timeout="6000" mock="true">
|
||||||
|
<dubbo:method name="listGoodsVo" timeout="3000" ></dubbo:method>
|
||||||
|
</dubbo:service>
|
||||||
|
|
||||||
|
<dubbo:service interface="com.geekq.api.service.GoodsService" ref="goodGroupService" group="goods1"></dubbo:service>
|
||||||
|
|
||||||
|
|
||||||
|
</beans>
|
|
@ -47,17 +47,18 @@
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
<version>${org.mybatis.version}</version>
|
<version>${org.mybatis.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<!--<dependency>-->
|
||||||
<groupId>com.geekq</groupId>
|
<!--<groupId>com.geekq</groupId>-->
|
||||||
<artifactId>miaosha-common</artifactId>
|
<!--<artifactId>miaosha-common</artifactId>-->
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<!--<version>0.0.1-SNAPSHOT</version>-->
|
||||||
</dependency>
|
<!--</dependency>-->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.boot</groupId>
|
<groupId>com.alibaba.boot</groupId>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user