购物车缓存
parent
d244618ff0
commit
65384d0cc7
|
@ -0,0 +1,39 @@
|
|||
package com.muyu.common.cache;
|
||||
|
||||
import com.muyu.common.cache.decoration.DecorationKey;
|
||||
|
||||
/**
|
||||
* 原子序列缓存基准
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
public interface AtomicSequenceCache<K> extends DecorationKey<K> {
|
||||
|
||||
/**
|
||||
* 获取存储的值
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Long get(K key);
|
||||
|
||||
/**
|
||||
* 自增
|
||||
*/
|
||||
public Long increment(K key);
|
||||
|
||||
/**
|
||||
* 自减
|
||||
*/
|
||||
public Long decrement(K key);
|
||||
|
||||
/**
|
||||
* 增加数值
|
||||
*/
|
||||
public Long increment(K key, Long number);
|
||||
|
||||
/**
|
||||
* 减少数值
|
||||
*/
|
||||
public Long decrement(K key, Long number);
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.muyu.common.cache.abs;
|
||||
|
||||
import com.muyu.common.cache.AtomicSequenceCache;
|
||||
import com.muyu.common.redis.service.RedisService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* 原子序列缓存抽象类
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
public abstract class AtomicSequenceCacheAbs<K> implements AtomicSequenceCache<K> {
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@Override
|
||||
public String encode(K key) {
|
||||
return keyPre() + key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long get(K key) {
|
||||
return this.redisService.getCacheObject(encode(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 自增
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
@Override
|
||||
public Long increment(K key) {
|
||||
return this.increment(key, 1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自减
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
@Override
|
||||
public Long decrement(K key) {
|
||||
return this.decrement(key, 1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加数值
|
||||
*
|
||||
* @param key
|
||||
* @param number
|
||||
*/
|
||||
@Override
|
||||
public Long increment(K key, Long number) {
|
||||
// Long numberValue = redisService.getCacheObject(encode(key));
|
||||
Long numberValue = get(key);
|
||||
if (numberValue == null) {
|
||||
Long data = getData(key);
|
||||
data = data == null ? 0L : data;
|
||||
redisService.setCacheObject(encode(key), data);
|
||||
}
|
||||
return redisService.increment(encode(key), number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少数值
|
||||
*
|
||||
* @param key
|
||||
* @param number
|
||||
*/
|
||||
@Override
|
||||
public Long decrement(K key, Long number) {
|
||||
// Long numberValue = redisService.getCacheObject(encode(key));
|
||||
Long numberValue = get(key);
|
||||
if (numberValue == null) {
|
||||
Long data = getData(key);
|
||||
data = data == null ? 0L : data;
|
||||
redisService.setCacheObject(encode(key), data);
|
||||
}
|
||||
return redisService.decrement(encode(key), number);
|
||||
}
|
||||
|
||||
public abstract Long getData(K key);
|
||||
}
|
|
@ -39,61 +39,64 @@ public class Result<T> implements Serializable {
|
|||
|
||||
private T data;
|
||||
|
||||
public static <T> Result<T> success () {
|
||||
public static <T> Result<T> buildCode(int code, String msg, T data) {
|
||||
return restResult(data, code, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success() {
|
||||
return restResult(null, SUCCESS, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success (T data) {
|
||||
public static <T> Result<T> success(T data) {
|
||||
return restResult(data, SUCCESS, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success (T data, String msg) {
|
||||
public static <T> Result<T> success(T data, String msg) {
|
||||
return restResult(data, SUCCESS, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error () {
|
||||
public static <T> Result<T> error() {
|
||||
return restResult(null, FAIL, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error (String msg) {
|
||||
public static <T> Result<T> error(String msg) {
|
||||
return restResult(null, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error (T data) {
|
||||
public static <T> Result<T> error(T data) {
|
||||
return restResult(data, FAIL, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error (T data, String msg) {
|
||||
public static <T> Result<T> error(T data, String msg) {
|
||||
return restResult(data, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error (int code, String msg) {
|
||||
public static <T> Result<T> error(int code, String msg) {
|
||||
return restResult(null, code, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> Result<T> warn () {
|
||||
public static <T> Result<T> warn() {
|
||||
return restResult(null, WARN, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> warn (String msg) {
|
||||
public static <T> Result<T> warn(String msg) {
|
||||
return restResult(null, WARN, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> warn (T data) {
|
||||
public static <T> Result<T> warn(T data) {
|
||||
return restResult(data, WARN, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> warn (T data, String msg) {
|
||||
public static <T> Result<T> warn(T data, String msg) {
|
||||
return restResult(data, WARN, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> warn (int code, String msg) {
|
||||
public static <T> Result<T> warn(int code, String msg) {
|
||||
return restResult(null, code, msg);
|
||||
}
|
||||
|
||||
private static <T> Result<T> restResult (T data, int code, String msg) {
|
||||
private static <T> Result<T> restResult(T data, int code, String msg) {
|
||||
return Result.<T>builder()
|
||||
.code(code)
|
||||
.data(data)
|
||||
|
@ -101,11 +104,11 @@ public class Result<T> implements Serializable {
|
|||
.build();
|
||||
}
|
||||
|
||||
public static <T> Boolean isError (Result<T> ret) {
|
||||
public static <T> Boolean isError(Result<T> ret) {
|
||||
return !isSuccess(ret);
|
||||
}
|
||||
|
||||
public static <T> Boolean isSuccess (Result<T> ret) {
|
||||
public static <T> Boolean isSuccess(Result<T> ret) {
|
||||
return Result.SUCCESS == ret.getCode();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public class RedisService {
|
|||
* @param key 缓存的键值
|
||||
* @param value 缓存的值
|
||||
*/
|
||||
public <T> void setCacheObject (final String key, final T value) {
|
||||
public <T> void setCacheObject(final String key, final T value) {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ public class RedisService {
|
|||
* @param timeout 时间
|
||||
* @param timeUnit 时间颗粒度
|
||||
*/
|
||||
public <T> void setCacheObject (final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
|
||||
public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
|
||||
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
|
||||
}
|
||||
|
||||
|
@ -48,10 +48,9 @@ public class RedisService {
|
|||
*
|
||||
* @param key Redis键
|
||||
* @param timeout 超时时间
|
||||
*
|
||||
* @return true=设置成功;false=设置失败
|
||||
*/
|
||||
public boolean expire (final String key, final long timeout) {
|
||||
public boolean expire(final String key, final long timeout) {
|
||||
return expire(key, timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
@ -61,10 +60,9 @@ public class RedisService {
|
|||
* @param key Redis键
|
||||
* @param timeout 超时时间
|
||||
* @param unit 时间单位
|
||||
*
|
||||
* @return true=设置成功;false=设置失败
|
||||
*/
|
||||
public boolean expire (final String key, final long timeout, final TimeUnit unit) {
|
||||
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
|
||||
return redisTemplate.expire(key, timeout, unit);
|
||||
}
|
||||
|
||||
|
@ -72,10 +70,9 @@ public class RedisService {
|
|||
* 获取有效时间
|
||||
*
|
||||
* @param key Redis键
|
||||
*
|
||||
* @return 有效时间
|
||||
*/
|
||||
public long getExpire (final String key) {
|
||||
public long getExpire(final String key) {
|
||||
return redisTemplate.getExpire(key);
|
||||
}
|
||||
|
||||
|
@ -83,10 +80,9 @@ public class RedisService {
|
|||
* 判断 key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
*
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public Boolean hasKey (String key) {
|
||||
public Boolean hasKey(String key) {
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
|
@ -94,10 +90,9 @@ public class RedisService {
|
|||
* 获得缓存的基本对象。
|
||||
*
|
||||
* @param key 缓存键值
|
||||
*
|
||||
* @return 缓存键值对应的数据
|
||||
*/
|
||||
public <T> T getCacheObject (final String key) {
|
||||
public <T> T getCacheObject(final String key) {
|
||||
ValueOperations<String, T> operation = redisTemplate.opsForValue();
|
||||
return operation.get(key);
|
||||
}
|
||||
|
@ -107,7 +102,7 @@ public class RedisService {
|
|||
*
|
||||
* @param key
|
||||
*/
|
||||
public boolean deleteObject (final String key) {
|
||||
public boolean deleteObject(final String key) {
|
||||
return redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
|
@ -115,10 +110,9 @@ public class RedisService {
|
|||
* 删除集合对象
|
||||
*
|
||||
* @param collection 多个对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean deleteObject (final Collection collection) {
|
||||
public boolean deleteObject(final Collection collection) {
|
||||
return redisTemplate.delete(collection) > 0;
|
||||
}
|
||||
|
||||
|
@ -127,10 +121,9 @@ public class RedisService {
|
|||
*
|
||||
* @param key 缓存的键值
|
||||
* @param dataList 待缓存的List数据
|
||||
*
|
||||
* @return 缓存的对象
|
||||
*/
|
||||
public <T> long setCacheList (final String key, final List<T> dataList) {
|
||||
public <T> long setCacheList(final String key, final List<T> dataList) {
|
||||
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
|
||||
return count == null ? 0 : count;
|
||||
}
|
||||
|
@ -139,10 +132,9 @@ public class RedisService {
|
|||
* 获得缓存的list对象
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
*
|
||||
* @return 缓存键值对应的数据
|
||||
*/
|
||||
public <T> List<T> getCacheList (final String key) {
|
||||
public <T> List<T> getCacheList(final String key) {
|
||||
return redisTemplate.opsForList().range(key, 0, -1);
|
||||
}
|
||||
|
||||
|
@ -151,10 +143,9 @@ public class RedisService {
|
|||
*
|
||||
* @param key 缓存键值
|
||||
* @param dataSet 缓存的数据
|
||||
*
|
||||
* @return 缓存数据的对象
|
||||
*/
|
||||
public <T> BoundSetOperations<String, T> setCacheSet (final String key, final Set<T> dataSet) {
|
||||
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
|
||||
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
|
||||
Iterator<T> it = dataSet.iterator();
|
||||
while (it.hasNext()) {
|
||||
|
@ -167,10 +158,9 @@ public class RedisService {
|
|||
* 获得缓存的set
|
||||
*
|
||||
* @param key
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public <T> Set<T> getCacheSet (final String key) {
|
||||
public <T> Set<T> getCacheSet(final String key) {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
}
|
||||
|
||||
|
@ -180,7 +170,7 @@ public class RedisService {
|
|||
* @param key
|
||||
* @param dataMap
|
||||
*/
|
||||
public <T> void setCacheMap (final String key, final Map<String, T> dataMap) {
|
||||
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
|
||||
if (dataMap != null) {
|
||||
redisTemplate.opsForHash().putAll(key, dataMap);
|
||||
}
|
||||
|
@ -190,10 +180,9 @@ public class RedisService {
|
|||
* 获得缓存的Map
|
||||
*
|
||||
* @param key
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public <T> Map<String, T> getCacheMap (final String key) {
|
||||
public <T> Map<String, T> getCacheMap(final String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
|
@ -204,7 +193,7 @@ public class RedisService {
|
|||
* @param hKey Hash键
|
||||
* @param value 值
|
||||
*/
|
||||
public <T> void setCacheMapValue (final String key, final String hKey, final T value) {
|
||||
public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
|
||||
redisTemplate.opsForHash().put(key, hKey, value);
|
||||
}
|
||||
|
||||
|
@ -213,10 +202,9 @@ public class RedisService {
|
|||
*
|
||||
* @param key Redis键
|
||||
* @param hKey Hash键
|
||||
*
|
||||
* @return Hash中的对象
|
||||
*/
|
||||
public <T> T getCacheMapValue (final String key, final String hKey) {
|
||||
public <T> T getCacheMapValue(final String key, final String hKey) {
|
||||
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
|
||||
return opsForHash.get(key, hKey);
|
||||
}
|
||||
|
@ -226,10 +214,9 @@ public class RedisService {
|
|||
*
|
||||
* @param key Redis键
|
||||
* @param hKeys Hash键集合
|
||||
*
|
||||
* @return Hash对象集合
|
||||
*/
|
||||
public <T> List<T> getMultiCacheMapValue (final String key, final Collection<?> hKeys) {
|
||||
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<?> hKeys) {
|
||||
return redisTemplate.opsForHash().multiGet(key, hKeys);
|
||||
}
|
||||
|
||||
|
@ -238,10 +225,9 @@ public class RedisService {
|
|||
*
|
||||
* @param key Redis键
|
||||
* @param hKey Hash键
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean deleteCacheMapValue (final String key, final String hKey) {
|
||||
public boolean deleteCacheMapValue(final String key, final String hKey) {
|
||||
return redisTemplate.opsForHash().delete(key, hKey) > 0;
|
||||
}
|
||||
|
||||
|
@ -249,10 +235,27 @@ public class RedisService {
|
|||
* 获得缓存的基本对象列表
|
||||
*
|
||||
* @param pattern 字符串前缀
|
||||
*
|
||||
* @return 对象列表
|
||||
*/
|
||||
public Collection<String> keys (final String pattern) {
|
||||
public Collection<String> keys(final String pattern) {
|
||||
return redisTemplate.keys(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加序列值
|
||||
* @param key
|
||||
* @param number
|
||||
*/
|
||||
public <K> Long increment(final String key, final Long number) {
|
||||
return redisTemplate.opsForValue().increment(key, number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少序列值
|
||||
* @param key
|
||||
* @param number
|
||||
*/
|
||||
public <K> Long decrement(final String key, final Long number) {
|
||||
return redisTemplate.opsForValue().decrement(key, number);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class GlobalExceptionHandler {
|
|||
* 权限码异常
|
||||
*/
|
||||
@ExceptionHandler(NotPermissionException.class)
|
||||
public Result handleNotPermissionException (NotPermissionException e, HttpServletRequest request) {
|
||||
public Result handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
|
||||
return Result.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
|
||||
|
@ -43,7 +43,7 @@ public class GlobalExceptionHandler {
|
|||
* 角色权限异常
|
||||
*/
|
||||
@ExceptionHandler(NotRoleException.class)
|
||||
public Result handleNotRoleException (NotRoleException e, HttpServletRequest request) {
|
||||
public Result handleNotRoleException(NotRoleException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());
|
||||
return Result.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
|
||||
|
@ -53,7 +53,7 @@ public class GlobalExceptionHandler {
|
|||
* 请求方式不支持
|
||||
*/
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
public Result handleHttpRequestMethodNotSupported (HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
|
||||
public Result handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
|
||||
return Result.error(e.getMessage());
|
||||
|
@ -63,17 +63,17 @@ public class GlobalExceptionHandler {
|
|||
* 业务异常
|
||||
*/
|
||||
@ExceptionHandler(ServiceException.class)
|
||||
public Result handleServiceException (ServiceException e, HttpServletRequest request) {
|
||||
public Result handleServiceException(ServiceException e, HttpServletRequest request) {
|
||||
log.error(e.getMessage(), e);
|
||||
Integer code = e.getCode();
|
||||
return StringUtils.isNotNull(code) ? Result.error(code, e.getMessage()) : Result.error(e.getMessage());
|
||||
return StringUtils.isNotNull(code) ? Result.buildCode(code, e.getMessage(), null) : Result.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求路径中缺少必需的路径变量
|
||||
*/
|
||||
@ExceptionHandler(MissingPathVariableException.class)
|
||||
public Result handleMissingPathVariableException (MissingPathVariableException e, HttpServletRequest request) {
|
||||
public Result handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
|
||||
return Result.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
|
||||
|
@ -83,7 +83,7 @@ public class GlobalExceptionHandler {
|
|||
* 请求参数类型不匹配
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||
public Result handleMethodArgumentTypeMismatchException (MethodArgumentTypeMismatchException e, HttpServletRequest request) {
|
||||
public Result handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
|
||||
return Result.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()));
|
||||
|
@ -93,7 +93,7 @@ public class GlobalExceptionHandler {
|
|||
* 拦截未知的运行时异常
|
||||
*/
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public Result handleRuntimeException (RuntimeException e, HttpServletRequest request) {
|
||||
public Result handleRuntimeException(RuntimeException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生未知异常.", requestURI, e);
|
||||
return Result.error(e.getMessage());
|
||||
|
@ -103,7 +103,7 @@ public class GlobalExceptionHandler {
|
|||
* 系统异常
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result handleException (Exception e, HttpServletRequest request) {
|
||||
public Result handleException(Exception e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生系统异常.", requestURI, e);
|
||||
return Result.error(e.getMessage());
|
||||
|
@ -113,7 +113,7 @@ public class GlobalExceptionHandler {
|
|||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
public Result handleBindException (BindException e) {
|
||||
public Result handleBindException(BindException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
String message = e.getAllErrors().get(0).getDefaultMessage();
|
||||
return Result.error(message);
|
||||
|
@ -123,7 +123,7 @@ public class GlobalExceptionHandler {
|
|||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Object handleMethodArgumentNotValidException (MethodArgumentNotValidException e) {
|
||||
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
String message = e.getBindingResult().getFieldError().getDefaultMessage();
|
||||
return Result.error(message);
|
||||
|
@ -133,7 +133,7 @@ public class GlobalExceptionHandler {
|
|||
* 内部认证异常
|
||||
*/
|
||||
@ExceptionHandler(InnerAuthException.class)
|
||||
public Result handleInnerAuthException (InnerAuthException e) {
|
||||
public Result handleInnerAuthException(InnerAuthException e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ public class GlobalExceptionHandler {
|
|||
* 演示模式异常
|
||||
*/
|
||||
@ExceptionHandler(DemoModeException.class)
|
||||
public Result handleDemoModeException (DemoModeException e) {
|
||||
public Result handleDemoModeException(DemoModeException e) {
|
||||
return Result.error("演示模式,不允许操作");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package com.muyu.product.cache;
|
||||
|
||||
import com.muyu.common.cache.abs.AtomicSequenceCacheAbs;
|
||||
import com.muyu.common.core.text.Convert;
|
||||
import com.muyu.product.cache.datasource.ProjectSkuStockData;
|
||||
import com.muyu.product.cache.key.SkuStockKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 商品SKU库存缓存
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
@Service
|
||||
public class ProjectSkuStockCache extends AtomicSequenceCacheAbs<SkuStockKey> {
|
||||
|
||||
@Autowired
|
||||
private ProjectSkuStockData projectSkuStockData;
|
||||
|
||||
@Override
|
||||
public String keyPre() {
|
||||
return "project:sku:stock:";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(SkuStockKey skuStockKey) {
|
||||
return keyPre() + skuStockKey.getProjectId() + ":" + skuStockKey.getSku();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkuStockKey decode(String redisKey) {
|
||||
String[] split = redisKey.replace(keyPre(), "").split(":");
|
||||
return SkuStockKey.builder()
|
||||
.projectId(Convert.toLong(split[0]))
|
||||
.sku(split[1])
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getData(SkuStockKey key) {
|
||||
return projectSkuStockData.getData(key);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.muyu.product.cache.datasource;
|
||||
|
||||
import com.muyu.product.cache.key.SkuStockKey;
|
||||
|
||||
/**
|
||||
* sku库存
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
public interface ProjectSkuStockData {
|
||||
public Long getData(SkuStockKey key);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.muyu.product.cache.key;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 商品sku库存key
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SkuStockKey {
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* sku
|
||||
*/
|
||||
private String sku;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.muyu.product.cache.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.muyu.product.cache.ProjectSkuStockCache;
|
||||
import com.muyu.product.cache.datasource.ProjectSkuStockData;
|
||||
import com.muyu.product.cache.key.SkuStockKey;
|
||||
import com.muyu.product.domain.ProjectSkuInfo;
|
||||
import com.muyu.product.service.ProjectSkuInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* sku库存实现类
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
@Service
|
||||
public class ProjectSkuStockDataImpl implements ProjectSkuStockData {
|
||||
|
||||
@Autowired
|
||||
private ProjectSkuInfoService projectSkuInfoService;
|
||||
|
||||
@Override
|
||||
public Long getData(SkuStockKey key) {
|
||||
ProjectSkuInfo projectSkuInfo = projectSkuInfoService.getOne(new LambdaQueryWrapper<>() {{
|
||||
eq(ProjectSkuInfo::getProjectId, key.getProjectId());
|
||||
eq(ProjectSkuInfo::getSku, key.getSku());
|
||||
}});
|
||||
return projectSkuInfo.getStock();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-shop-cart</artifactId>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>muyu-shop-cart-cache</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- 商品服务 公共依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-shop-cart-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 缓存基准依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-common-cache</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,104 @@
|
|||
package com.muyu.shop.cart.cache;
|
||||
|
||||
import com.muyu.common.cache.abs.HashCacheAbs;
|
||||
import com.muyu.common.core.domain.Result;
|
||||
import com.muyu.common.core.exception.ServiceException;
|
||||
import com.muyu.common.core.text.Convert;
|
||||
import com.muyu.shop.cart.cache.key.CartHashKey;
|
||||
import com.muyu.shop.cart.cache.sourcedata.CartData;
|
||||
import com.muyu.shop.cart.domain.CartInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 购物车缓存
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
public class CartCache extends HashCacheAbs<Long, CartHashKey, CartInfo> {
|
||||
|
||||
@Autowired
|
||||
private CartData cartData;
|
||||
|
||||
/**
|
||||
* key前缀
|
||||
*
|
||||
* @return key前缀
|
||||
*/
|
||||
@Override
|
||||
public String keyPre() {
|
||||
return "cart:info:";
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param redisKey 数据库键
|
||||
* @return ID
|
||||
*/
|
||||
@Override
|
||||
public Long decode(String redisKey) {
|
||||
return Convert.toLong(redisKey.replace(keyPre(), ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*
|
||||
* @param hashKey ID
|
||||
* @return 键
|
||||
*/
|
||||
@Override
|
||||
public String encodeHashKey(CartHashKey hashKey) {
|
||||
return hashKey.getProjectId() + ":" + hashKey.getProjectSku();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*
|
||||
* @param redisHashKey 数据库键
|
||||
* @return ID
|
||||
*/
|
||||
@Override
|
||||
public CartHashKey decodeHashKey(String redisHashKey) {
|
||||
String[] split = redisHashKey.split(":");
|
||||
return CartHashKey.builder()
|
||||
.projectId(Convert.toLong(split[0]))
|
||||
.projectSku(split[1])
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过键获取所有的hash数据
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<CartHashKey, CartInfo> getData(Long key) {
|
||||
return cartData.getData(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过缓存键和hash键获取hash值
|
||||
*
|
||||
* @param key 缓存键
|
||||
* @param hashKey hash键
|
||||
* @return hash值
|
||||
*/
|
||||
@Override
|
||||
public CartInfo getData(Long key, CartHashKey hashKey) {
|
||||
return cartData.getData(key, hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<CartHashKey, CartInfo> defaultValue() {
|
||||
throw new ServiceException("购物车无数据", Result.SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CartInfo defaultHashValue() {
|
||||
throw new ServiceException("购物车无数据", Result.SUCCESS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.muyu.shop.cart.cache.key;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 购物车HashKey
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CartHashKey {
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 商品SKU
|
||||
*/
|
||||
private String projectSku;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.muyu.shop.cart.cache.sourcedata;
|
||||
|
||||
import com.muyu.shop.cart.cache.key.CartHashKey;
|
||||
import com.muyu.shop.cart.domain.CartInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 购物车源数据获取
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
public interface CartData {
|
||||
|
||||
/**
|
||||
* 通过键获取所有的hash数据
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public Map<CartHashKey, CartInfo> getData(Long key);
|
||||
|
||||
/**
|
||||
* 通过缓存键和hash键获取hash值
|
||||
* @param key 缓存键
|
||||
* @param hashKey hash键
|
||||
* @return hash值
|
||||
*/
|
||||
public CartInfo getData(Long key, CartHashKey hashKey);
|
||||
|
||||
}
|
|
@ -84,7 +84,12 @@
|
|||
<dependency>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-shop-cart-common</artifactId>
|
||||
<version>${muyu.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 购物车模块 缓存依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-shop-cart-cache</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package com.muyu.shop.cart.service.sourcedata;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.muyu.shop.cart.cache.key.CartHashKey;
|
||||
import com.muyu.shop.cart.cache.sourcedata.CartData;
|
||||
import com.muyu.shop.cart.domain.CartInfo;
|
||||
import com.muyu.shop.cart.service.CartInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 缓存实现
|
||||
*
|
||||
* @author CHX
|
||||
* on 2024/4/2 0002
|
||||
*/
|
||||
@Service
|
||||
public class CartDataImpl implements CartData {
|
||||
|
||||
@Autowired
|
||||
private CartInfoService cartInfoService;
|
||||
|
||||
@Override
|
||||
public Map<CartHashKey, CartInfo> getData(Long key) {
|
||||
List<CartInfo> cartInfoList = cartInfoService.list(new LambdaQueryWrapper<>() {{
|
||||
eq(CartInfo::getUserId, key);
|
||||
}});
|
||||
return cartInfoList.stream()
|
||||
.collect(Collectors.toMap(cartInfo -> CartHashKey.builder()
|
||||
.projectId(cartInfo.getProjectId())
|
||||
.projectSku(cartInfo.getProjectSku())
|
||||
.build(), cartInfo -> cartInfo));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CartInfo getData(Long key, CartHashKey hashKey) {
|
||||
return cartInfoService.getOne(new LambdaQueryWrapper<>(){{
|
||||
eq(CartInfo::getUserId,key);
|
||||
eq(CartInfo::getProjectId,hashKey.getProjectId());
|
||||
eq(CartInfo::getProjectSku,hashKey.getProjectSku());
|
||||
}});
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
<module>muyu-shop-cart-common</module>
|
||||
<module>muyu-shop-cart-remote</module>
|
||||
<module>muyu-shop-cart-server</module>
|
||||
<module>muyu-shop-cart-cache</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
Loading…
Reference in New Issue