购物车缓存
parent
c58caef95f
commit
a896d1361f
|
@ -0,0 +1,38 @@
|
|||
package com.muyu.common.cache;
|
||||
|
||||
import com.muyu.common.cache.decoration.DecorationKey;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 原子序列缓存基准
|
||||
* @author YunFei.Du
|
||||
* @date 9:38 2024/4/2
|
||||
*/
|
||||
public interface AtomicSequenceCache<K> extends DecorationKey<K> {
|
||||
|
||||
/**
|
||||
* 获取存储的值
|
||||
*/
|
||||
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);
|
||||
}
|
|
@ -3,8 +3,8 @@ package com.muyu.common.cache;
|
|||
import com.muyu.common.cache.decoration.DecorationKey;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 缓存接口基类
|
||||
* dyf
|
||||
* 缓存接口基类
|
||||
* @Date 2024-3-26 下午 03:25
|
||||
*/
|
||||
public interface Cache <K, V> extends DecorationKey<K> {
|
||||
|
|
|
@ -7,8 +7,8 @@ import java.util.Map;
|
|||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: Hash缓存基准
|
||||
* dyf
|
||||
* Hash缓存基准
|
||||
* @Date 2024-3-29 下午 03:16
|
||||
*/
|
||||
public interface HashCache <K, HK, HV> extends DecorationKey<K> {
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
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 YunFei.Du
|
||||
* @date 15:29 2024/4/2
|
||||
*/
|
||||
public abstract class AtomicSequenceCacheAbs<K> implements AtomicSequenceCache<K> {
|
||||
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
|
||||
/**
|
||||
* 获取存储的值
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
@Override
|
||||
public Long get(K key) {
|
||||
return this.redisService.getCacheObject ( encode ( key ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long increment(K key) {
|
||||
return this.increment ( key,1L );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long decrement(K key) {
|
||||
return this.decrement ( key,1L );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long increment(K key, Long number) {
|
||||
Long numberValue = redisService.getCacheObject ( encode ( key ) );
|
||||
if (numberValue==null){
|
||||
Long data=getData ( key );
|
||||
data= data== null ? 0L :data;
|
||||
redisService.setCacheObject ( encode ( key ),data );
|
||||
}
|
||||
return redisService.increment(encode ( key ),number);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long decrement(K key, Long number) {
|
||||
Long numberValue = redisService.getCacheObject ( encode ( key ) );
|
||||
if (numberValue== null){
|
||||
Long data=getData ( key );
|
||||
data= data== null ? 0L :data;
|
||||
redisService.setCacheObject ( encode ( key ),data );
|
||||
}
|
||||
return redisService.decrement(encode ( key ),number);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(K key) {
|
||||
return keyPre ()+key;
|
||||
}
|
||||
|
||||
public abstract Long getData(K key);
|
||||
}
|
|
@ -7,8 +7,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 缓存抽象类
|
||||
* dyf
|
||||
* 缓存抽象类
|
||||
* @Date 2024-3-27 下午 03:10
|
||||
*/
|
||||
public abstract class CacheAbs<K, V> implements Cache<K, V> {
|
||||
|
|
|
@ -8,8 +8,8 @@ import java.util.*;
|
|||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: hash缓存抽象类
|
||||
* dyf
|
||||
* hash缓存抽象类
|
||||
* @Date 2024-3-29 下午 07:40
|
||||
*/
|
||||
public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
||||
|
@ -41,13 +41,25 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
}
|
||||
|
||||
/**
|
||||
* 通过Key获取所有的map
|
||||
* @param key 数据库键
|
||||
* @return 所有集合Map
|
||||
* 通过给定的键从Redis获取所有关联的值,并将其组织成一个Map返回。
|
||||
* @param key 用于在Redis中检索数据的键。
|
||||
* @return 一个Map,其中包含与给定键相关联的所有值,键类型为HK,值类型为HV。
|
||||
*/
|
||||
@Override
|
||||
public Map<HK, HV> get (K key) {
|
||||
return decodeMap(redisService.getCacheMap(encode(key)));
|
||||
// // 从Redis获取通过键编码后的缓存Map
|
||||
Map< String, HV > cacheMap = redisService.getCacheMap ( encode ( key ) );
|
||||
if (cacheMap==null || cacheMap.isEmpty ( )){
|
||||
Map< HK, HV > dataMap = getData ( key );
|
||||
if (dataMap!=null && !dataMap.isEmpty ()){
|
||||
cacheMap=encodeMap ( dataMap );
|
||||
}else {
|
||||
cacheMap=encodeMap ( defaultValue () );
|
||||
}
|
||||
redisService.setCacheMap ( encode ( key ),cacheMap );
|
||||
}
|
||||
return decodeMap ( cacheMap );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,7 +72,13 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
*/
|
||||
@Override
|
||||
public HV get (K key, HK hashKey) {
|
||||
return redisService.getCacheMapValue(encode(key), encodeHashKey(hashKey));
|
||||
HV hashValue = redisService.getCacheMapValue ( encode ( key ), encodeHashKey ( hashKey ) );
|
||||
if (hashValue==null){
|
||||
HV dataValue = getData ( key, hashKey );
|
||||
hashValue= dataValue!=null ? dataValue:defaultHashValue();
|
||||
put ( key,hashKey,hashValue );
|
||||
}
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,6 +91,7 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
*/
|
||||
@Override
|
||||
public List<HV> get (K key, HK... hashKeyList) {
|
||||
// (this::encodeHashKey) ===>引用了当前类(即 this 指代的对象)中的 encodeHashKey 方法
|
||||
List<String> encodeHashKeyList = Arrays.stream(hashKeyList).map(this::encodeHashKey).toList();
|
||||
return redisService.getMultiCacheMapValue(encode(key), encodeHashKeyList);
|
||||
}
|
||||
|
@ -110,7 +129,9 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
*/
|
||||
@Override
|
||||
public void put (K key, List<HV> dataList, Function<HV, HK> hashKey) {
|
||||
|
||||
Map<HK, HV> dataMap = new HashMap<>();
|
||||
dataList.forEach((data) -> dataMap.put(hashKey.apply(data), data));
|
||||
redisService.setCacheMap(encode(key), encodeMap(dataMap));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,7 +143,7 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
*/
|
||||
@Override
|
||||
public void put (K key, HK hashKey, HV hashValue) {
|
||||
|
||||
redisService.setCacheMapValue ( encode ( key ),encodeHashKey ( hashKey ),hashValue );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,7 +153,7 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
*/
|
||||
@Override
|
||||
public void remove (K key) {
|
||||
|
||||
redisService.deleteObject ( encode ( key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,7 +164,7 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
*/
|
||||
@Override
|
||||
public void remove (K key, HK hashKey) {
|
||||
|
||||
redisService.deleteCacheMapValue ( encode ( key ),encodeHashKey ( hashKey ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,13 +179,53 @@ public abstract class HashCacheAbs<K, HK, HV> implements HashCache<K, HK, HV> {
|
|||
}
|
||||
|
||||
/**
|
||||
* 编码数据转原始数据
|
||||
* @param encodeDataMap 编码数据
|
||||
* @return 原始数据
|
||||
* 将编码后的数据映射转换为原始数据映射。
|
||||
* @param encodeDataMap 编码后的数据映射,其中键为字符串类型,值为泛型HV。
|
||||
* @return 原始数据映射,其中键为泛型HK,值为泛型HV。
|
||||
*/
|
||||
private Map<HK, HV> decodeMap(Map<String, HV> encodeDataMap){
|
||||
|
||||
// 初始化一个空的HashMap,用于存放解码后的键值对
|
||||
Map<HK, HV> dataMap = new HashMap<>();
|
||||
// 遍历编码后的数据映射,对每个键进行解码,并将解码后的键值对添加到dataMap中
|
||||
encodeDataMap.forEach((hashKey, hashValue) -> dataMap.put(decodeHashKey(hashKey), hashValue));
|
||||
return dataMap;
|
||||
}
|
||||
// getData
|
||||
|
||||
/**
|
||||
* 根据键获取数据。
|
||||
*
|
||||
* @param key 主键,用于查找数据。
|
||||
* @return 返回一个映射,其中包含与主键相关联的所有数据。
|
||||
*/
|
||||
public abstract Map<HK,HV> getData(K key);
|
||||
/**
|
||||
* 根据主键和哈希键获取数据。
|
||||
*
|
||||
* @param key 主键,用于定位数据。
|
||||
* @param hashKey 哈希键,用于进一步筛选数据。
|
||||
* @return 返回与指定主键和哈希键相关联的数据项。
|
||||
*/
|
||||
public abstract HV getData(K key,HK hashKey);
|
||||
|
||||
/**
|
||||
* 获取默认的映射数据。
|
||||
* 此方法提供一个默认的、预先定义好的键值对集合(Map)。
|
||||
*
|
||||
* @return 一个抽象定义的、类型为<HK, HV>的映射,包含了默认的键值对数据。
|
||||
*/
|
||||
public abstract Map<HK,HV> defaultValue();
|
||||
|
||||
/**
|
||||
* 获取默认的哈希值数据。
|
||||
* 此方法提供一个默认的、预先定义好的哈希值(HV)。
|
||||
*
|
||||
* @return 一个抽象定义的、类型为HV的默认哈希值数据。
|
||||
*/
|
||||
public abstract HV defaultHashValue();
|
||||
|
||||
public boolean hasKey(K key, HK hashKey){
|
||||
return redisService.hasKey ( encode ( key ),encodeHashKey ( hashKey ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.muyu.common.cache.decoration;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 装饰Key
|
||||
* dyf
|
||||
* 装饰Key
|
||||
* @Date 2024-3-29 下午 03:19
|
||||
*/
|
||||
public interface DecorationKey <K>{
|
||||
|
|
|
@ -5,8 +5,8 @@ import org.apache.commons.lang3.ObjectUtils;
|
|||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 对象工具类
|
||||
* dyf
|
||||
* 对象工具类
|
||||
* @Date 2023-10-9 下午 04:56
|
||||
*/
|
||||
public class ObjUtils {
|
||||
|
|
|
@ -12,15 +12,27 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
/**
|
||||
* spring redis 工具类
|
||||
*
|
||||
* @author muyu
|
||||
**/
|
||||
* @author YunFei.Du
|
||||
* @date 10:08 2024/4/2
|
||||
*/
|
||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
@Component
|
||||
public class RedisService {
|
||||
@Autowired
|
||||
public RedisTemplate redisTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* 判断redis 中 的hashKey 是否存在
|
||||
* @param key
|
||||
* @param hashKey
|
||||
* @return
|
||||
*/
|
||||
public Boolean hasKey(final String key,final String hashKey){
|
||||
return this.redisTemplate.opsForHash ().hasKey ( key,hashKey );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 缓存基本的对象,Integer、String、实体类等
|
||||
*
|
||||
|
@ -233,6 +245,7 @@ public class RedisService {
|
|||
return redisTemplate.opsForHash().multiGet(key, hKeys);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除Hash中的某条数据
|
||||
*
|
||||
|
@ -255,4 +268,14 @@ public class RedisService {
|
|||
public Collection<String> keys (final String pattern) {
|
||||
return redisTemplate.keys(pattern);
|
||||
}
|
||||
|
||||
|
||||
public Long increment(String encode, Long number) {
|
||||
return redisTemplate.opsForValue ().increment ( encode,number );
|
||||
}
|
||||
|
||||
public Long decrement(String encode, Long number) {
|
||||
return redisTemplate.opsForValue ().decrement ( encode,number );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ import lombok.Data;
|
|||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 验证码
|
||||
* dyf
|
||||
* 验证码
|
||||
* @Date 2023-11-12 下午 03:36
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -14,13 +14,13 @@ import java.util.List;
|
|||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品缓存
|
||||
* 商品缓存
|
||||
* @Date 2024-3-27 下午 03:30
|
||||
*/
|
||||
@Component
|
||||
public class ProjectInfoCache extends CacheAbs<Long, ProjectInfo> {
|
||||
|
||||
|
||||
public static void main (String[] args) {
|
||||
Long projectId = 10L;
|
||||
HashCache<Long, Long, ProjectSkuInfo> hashCache = null;
|
||||
|
@ -33,12 +33,12 @@ public class ProjectInfoCache extends CacheAbs<Long, ProjectInfo> {
|
|||
hashCache.get(projectId, longArr);
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
private ProjectInfoData projectInfoData;
|
||||
|
||||
/**
|
||||
* key前缀
|
||||
*
|
||||
* @return key前缀
|
||||
*/
|
||||
@Override
|
||||
|
@ -57,7 +57,6 @@ public class ProjectInfoCache extends CacheAbs<Long, ProjectInfo> {
|
|||
public Long decode (String redisKey) {
|
||||
return Convert.toLong(redisKey.replace(keyPre(),""), 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库获取数据
|
||||
*
|
||||
|
@ -65,6 +64,7 @@ public class ProjectInfoCache extends CacheAbs<Long, ProjectInfo> {
|
|||
*
|
||||
* @return 缓存对象
|
||||
*/
|
||||
|
||||
@Override
|
||||
public ProjectInfo getData (Long key) {
|
||||
return projectInfoData.getData(key);
|
||||
|
@ -72,6 +72,10 @@ public class ProjectInfoCache extends CacheAbs<Long, ProjectInfo> {
|
|||
|
||||
|
||||
|
||||
public ProjectInfo defaultValue (Long key) {
|
||||
return projectInfoData.getData(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 默认值
|
||||
|
|
|
@ -1,9 +1,70 @@
|
|||
package com.muyu.product.cache;
|
||||
|
||||
import com.muyu.common.cache.abs.HashCacheAbs;
|
||||
import com.muyu.common.core.text.Convert;
|
||||
import com.muyu.product.cache.datasource.ProjectSkuData;
|
||||
import com.muyu.product.domain.ProjectSkuInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品sku基本信息
|
||||
* 商品sku缓存
|
||||
* @Date 2024-3-29 下午 03:06
|
||||
*/
|
||||
public class ProjectSkuCache {
|
||||
|
||||
@Component
|
||||
public class ProjectSkuCache extends HashCacheAbs<Long,String, ProjectSkuInfo > {
|
||||
|
||||
|
||||
@Autowired
|
||||
private ProjectSkuData projectSkuData;
|
||||
@Override
|
||||
public String keyPre() {
|
||||
return "project:sku:";
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Redis键中解码并转换为Long类型数值。
|
||||
*
|
||||
* @param redisKey 存储在Redis中的键,键名前缀将被移除以便解码。
|
||||
* @return 解码后的Long数值,如果解码失败或redisKey为空,则返回0L作为默认值。
|
||||
*/
|
||||
@Override
|
||||
public Long decode(String redisKey) {
|
||||
// 使用Convert工具类将处理过的Redis键转换为Long类型数值,原始键通过调用keyPre()方法移除了前缀
|
||||
// 若转换过程中出现异常或无法转换时,返回默认值0L
|
||||
return Convert.toLong ( redisKey.replace ( keyPre (),"" ),0L );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String decodeHashKey(String redisHashKey) {
|
||||
return Convert.toStr ( redisHashKey, "" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map< String, ProjectSkuInfo > getData(Long key) {
|
||||
return projectSkuData.getData ( key );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectSkuInfo getData(Long key, String hashKey) {
|
||||
return projectSkuData.getData ( key,hashKey );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map< String, ProjectSkuInfo > defaultValue() {
|
||||
return new HashMap<> ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectSkuInfo defaultHashValue() {
|
||||
return new ProjectSkuInfo ();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,62 @@
|
|||
package com.muyu.product.cache;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.muyu.common.cache.abs.AtomicSequenceCacheAbs;
|
||||
import com.muyu.common.cache.abs.HashCacheAbs;
|
||||
import com.muyu.common.core.text.Convert;
|
||||
import com.muyu.product.cache.datasource.ProjectSkuData;
|
||||
import com.muyu.product.cache.datasource.ProjectSkuStockData;
|
||||
import com.muyu.product.cache.key.SkuStockKey;
|
||||
import com.muyu.product.domain.ProjectSkuInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品SKU库存缓存
|
||||
* dyf
|
||||
* 商品SKU库存缓存
|
||||
* @Date 2024-3-29 下午 03:06
|
||||
*/
|
||||
public class ProjectSkuStockCache {
|
||||
@Component
|
||||
public class ProjectSkuStockCache extends AtomicSequenceCacheAbs< SkuStockKey > {
|
||||
|
||||
|
||||
@Autowired
|
||||
private ProjectSkuStockData projectSkuStockData;
|
||||
|
||||
@Override
|
||||
public String keyPre() {
|
||||
return "project:sku:stock";
|
||||
}
|
||||
/**
|
||||
* 编码
|
||||
* @param skuStockKey ID
|
||||
* @return 键
|
||||
*/
|
||||
@Override
|
||||
public String encode(SkuStockKey skuStockKey) {
|
||||
return keyPre ()+skuStockKey.getProjectId ()+":"+skuStockKey.getSku ();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
* @param redisKey 数据库键
|
||||
* @return ID
|
||||
*/
|
||||
@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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@ package com.muyu.product.cache.datasource;
|
|||
import com.muyu.product.domain.ProjectInfo;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 缓存数据获取
|
||||
* 缓存数据获取
|
||||
* @Date 2024-3-27 下午 03:34
|
||||
*/
|
||||
public interface ProjectInfoData {
|
||||
|
@ -16,5 +15,4 @@ public interface ProjectInfoData {
|
|||
*/
|
||||
public ProjectInfo getData (Long key);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.muyu.product.cache.datasource;
|
||||
|
||||
import com.muyu.product.domain.ProjectSkuInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品SKU数据库读取
|
||||
* @author YunFei.Du
|
||||
* @date 14:14 2024/4/1
|
||||
*/
|
||||
public interface ProjectSkuData {
|
||||
/**
|
||||
* 通过键获取所有的hash数据
|
||||
* @param projectId 商品ID
|
||||
* @return
|
||||
*/
|
||||
public Map<String, ProjectSkuInfo > getData (Long projectId) ;
|
||||
|
||||
/**
|
||||
* 通过缓存键和hash键获取hash值
|
||||
* @param projectId 商品ID
|
||||
* @param projectSku 商品SKU
|
||||
*
|
||||
* @return hash值
|
||||
*/
|
||||
public ProjectSkuInfo getData (Long projectId, String projectSku);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.muyu.product.cache.datasource;
|
||||
|
||||
|
||||
import com.muyu.product.cache.key.SkuStockKey;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* SKU库存
|
||||
* @author YunFei.Du
|
||||
* @date 16:07 2024/4/2
|
||||
*/
|
||||
public interface ProjectSkuStockData {
|
||||
|
||||
public Long getData (SkuStockKey key);
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.muyu.product.cache.key;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @ClassName SkuStockKey
|
||||
* @Description 描述
|
||||
* @Author YunFei.Du
|
||||
* @Date 2024/4/2 16:08
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class SkuStockKey {
|
||||
/**
|
||||
* 商品id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* sku
|
||||
*/
|
||||
private String sku;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
com.muyu.product.cache.ProjectInfoCache
|
||||
com.muyu.product.cache.ProjectSkuCache
|
||||
com.muyu.product.cache.ProjectSkuStockCache
|
|
@ -1,8 +1,8 @@
|
|||
package com.muyu.product.domain.base;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: attribute基础方法
|
||||
* dyf
|
||||
* attribute基础方法
|
||||
* @Date 2024-3-1 下午 02:28
|
||||
*/
|
||||
public interface CategoryBase {
|
||||
|
|
|
@ -6,8 +6,8 @@ import lombok.Data;
|
|||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品属性
|
||||
* dyf
|
||||
* 商品属性
|
||||
* @Date 2024-3-22 上午 10:53
|
||||
*/
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.util.List;
|
|||
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 属性组添加模型
|
||||
* dyf
|
||||
* 属性组添加模型
|
||||
* @Date 2024-2-28 下午 03:16
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -10,8 +10,8 @@ import lombok.NoArgsConstructor;
|
|||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品Sku
|
||||
* dyf
|
||||
* 商品Sku
|
||||
* @Date 2024-3-22 上午 10:54
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -6,8 +6,8 @@ import lombok.*;
|
|||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品添加模型
|
||||
* dyf
|
||||
* 商品添加模型
|
||||
* @Date 2024-3-22 上午 10:50
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.util.List;
|
|||
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 规格属性,添加模型
|
||||
* dyf
|
||||
* 规格属性,添加模型
|
||||
* @Date 2024-3-4 下午 02:28
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -12,8 +12,8 @@ import lombok.experimental.SuperBuilder;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 规格保存模型
|
||||
* dyf
|
||||
* 规格保存模型
|
||||
* @Date 2024-3-4 下午 02:33
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.util.function.Function;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 共有属性组
|
||||
* dyf
|
||||
* 共有属性组
|
||||
* @Date 2024-3-6 下午 02:29
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -9,8 +9,8 @@ import lombok.NoArgsConstructor;
|
|||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 共有属性
|
||||
* dyf
|
||||
* 共有属性
|
||||
* @Date 2024-3-6 下午 02:30
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -13,8 +13,8 @@ import java.util.List;
|
|||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 属性组列表对象
|
||||
* dyf
|
||||
* 属性组列表对象
|
||||
* @Date 2024-2-28 下午 04:15
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -9,8 +9,8 @@ import lombok.experimental.SuperBuilder;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品类别公共元素
|
||||
* dyf
|
||||
* 商品类别公共元素
|
||||
* @Date 2024-3-6 下午 02:25
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -11,8 +11,8 @@ import lombok.NoArgsConstructor;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 类别父通用元素
|
||||
* dyf
|
||||
* 类别父通用元素
|
||||
* @Date 2024-3-1 上午 11:02
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -12,8 +12,8 @@ import lombok.NoArgsConstructor;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品详情信息
|
||||
* dyf
|
||||
* 商品详情信息
|
||||
* @Date 2024-3-25 上午 10:46
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -13,8 +13,8 @@ import java.util.List;
|
|||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 规格返回结果集
|
||||
* dyf
|
||||
* 规格返回结果集
|
||||
* @Date 2024-3-4 下午 04:08
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -6,9 +6,11 @@ import com.muyu.common.swagger.annotation.EnableCustomSwagger2;
|
|||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品启动类
|
||||
* dyf
|
||||
* 商品启动类
|
||||
* @Date 2024-2-26 下午 04:07
|
||||
*/
|
||||
@EnableCustomConfig
|
||||
|
@ -17,6 +19,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||
@SpringBootApplication
|
||||
public class MuYuProductApplication {
|
||||
public static void main (String[] args) {
|
||||
|
||||
|
||||
ArrayList< Long > objects = new ArrayList<> ( );
|
||||
objects.add ( 1L );
|
||||
SpringApplication.run(MuYuProductApplication.class, args);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 商品缓存数据获取
|
||||
* 商品实现类
|
||||
* @Date 2024-3-27 下午 03:37
|
||||
*/
|
||||
@Service
|
||||
|
@ -26,4 +25,6 @@ public class ProjectInfoDataImpl implements ProjectInfoData {
|
|||
public ProjectInfo getData (Long key) {
|
||||
return projectInfoService.getById(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.muyu.product.cache.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.muyu.product.cache.datasource.ProjectSkuData;
|
||||
import com.muyu.product.domain.ProjectSkuInfo;
|
||||
import com.muyu.product.service.ProjectSkuInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 商品SKU实现类
|
||||
* @author YunFei.Du
|
||||
* @date 14:20 2024/4/1
|
||||
*/
|
||||
@Service
|
||||
public class ProjectSkuDataImpl implements ProjectSkuData {
|
||||
|
||||
@Autowired
|
||||
private ProjectSkuInfoService projectSkuInfoService;
|
||||
|
||||
@Override
|
||||
public Map< String, ProjectSkuInfo > getData(Long projectId) {
|
||||
|
||||
LambdaQueryWrapper< ProjectSkuInfo > queryWrapper = new LambdaQueryWrapper< ProjectSkuInfo > ( )
|
||||
.eq ( ProjectSkuInfo::getProjectId, projectId );
|
||||
|
||||
List< ProjectSkuInfo > projectSkuInfoList = projectSkuInfoService.list ( queryWrapper );
|
||||
|
||||
Map< String, ProjectSkuInfo > map = new HashMap<> ( );
|
||||
projectSkuInfoList.stream ().map (
|
||||
projectSkuInfo -> {
|
||||
map.put ( projectSkuInfo.getSku (),projectSkuInfo );
|
||||
return projectSkuInfo;
|
||||
}
|
||||
).collect( Collectors.toList());
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectSkuInfo getData(Long projectId, String projectSku) {
|
||||
LambdaQueryWrapper< ProjectSkuInfo > queryWrapper = new LambdaQueryWrapper< ProjectSkuInfo > ( )
|
||||
.eq ( ProjectSkuInfo::getProjectId, projectId )
|
||||
.eq ( ProjectSkuInfo::getSku, projectSku );
|
||||
return projectSkuInfoService.getOne ( queryWrapper );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.muyu.product.cache.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: sku库存实现类
|
||||
* @Date 2024-4-2 上午 10:53
|
||||
*/
|
||||
@Service
|
||||
public class ProjectSkuStockDataImpl implements ProjectSkuStockData {
|
||||
|
||||
@Autowired
|
||||
private ProjectSkuInfoService projectSkuInfoService;
|
||||
|
||||
@Override
|
||||
public Long getData (SkuStockKey key) {
|
||||
LambdaQueryWrapper<ProjectSkuInfo> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ProjectSkuInfo::getProjectId, key.getProjectId());
|
||||
queryWrapper.eq(ProjectSkuInfo::getSku, key.getSku());
|
||||
ProjectSkuInfo projectSkuInfo = projectSkuInfoService.getOne(queryWrapper);
|
||||
return projectSkuInfo.getStock();
|
||||
}
|
||||
|
||||
}
|
|
@ -55,7 +55,6 @@ public class ProjectInfoController extends BaseController {
|
|||
List<ProjectInfo> list = projectInfoService.list(ProjectInfo.queryBuild(projectInfoQueryReq));
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出商品信息列表
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?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>
|
||||
|
||||
<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,107 @@
|
|||
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 org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 购物车缓存
|
||||
* @Date 2024-4-2 上午 11:23
|
||||
*/
|
||||
@Component
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 购物车HashKey
|
||||
* @Date 2024-4-2 上午 11:25
|
||||
*/
|
||||
@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 DongZl
|
||||
* @description: 购物车源数据获取
|
||||
* @Date 2024-4-2 上午 11:49
|
||||
*/
|
||||
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);
|
||||
}
|
|
@ -15,6 +15,8 @@ import com.muyu.shop.cart.domain.req.CartInfoSaveReq;
|
|||
import com.muyu.shop.cart.domain.req.CartInfoEditReq;
|
||||
import com.muyu.common.core.web.domain.BaseEntity;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 购物车对象 cart_info
|
||||
*
|
||||
|
|
|
@ -23,6 +23,7 @@ public class CartInfoQueryReq extends BaseEntity {
|
|||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/** 商品 */
|
||||
@ApiModelProperty(name = "商品", value = "商品")
|
||||
private Long projectId;
|
||||
|
|
|
@ -87,6 +87,26 @@
|
|||
<version>${muyu.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 购物车模块 缓存 依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-shop-cart-cache</artifactId>
|
||||
<version>${muyu.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-product-cache</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>muyu-product-server</artifactId>
|
||||
<version>3.6.3</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package com.muyu.shop.cart.cache.impl;
|
||||
|
||||
/**
|
||||
* @ClassName CartInfoDataImpl
|
||||
* @Description 描述
|
||||
* @Author YunFei.Du
|
||||
* @Date 2024/3/31 10:35
|
||||
*/
|
||||
public interface CartInfoDataImpl {
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.muyu.shop.cart.cache.impl;
|
||||
|
||||
import com.muyu.product.cache.datasource.ProjectInfoData;
|
||||
import com.muyu.product.domain.ProjectInfo;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 商品实现类
|
||||
* @Date 2024-3-27 下午 03:37
|
||||
*/
|
||||
@Service
|
||||
public class ProjectInfoDataImpl implements ProjectInfoData {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 从数据库获取数据
|
||||
* @param key ID
|
||||
* @return 缓存对象
|
||||
*/
|
||||
@Override
|
||||
public ProjectInfo getData (Long key) {
|
||||
return new ProjectInfo ();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.muyu.shop.cart.cache.impl;
|
||||
|
||||
|
||||
import com.muyu.product.cache.datasource.ProjectSkuData;
|
||||
import com.muyu.product.domain.ProjectSkuInfo;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 商品SKU实现类
|
||||
* @author YunFei.Du
|
||||
* @date 14:20 2024/4/1
|
||||
*/
|
||||
@Service
|
||||
public class ProjectSkuDataImpl implements ProjectSkuData {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Map< String, ProjectSkuInfo > getData(Long projectId) {
|
||||
|
||||
return new HashMap<> ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectSkuInfo getData(Long projectId, String projectSku) {
|
||||
return new ProjectSkuInfo ();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.muyu.shop.cart.cache.impl;
|
||||
|
||||
import com.muyu.product.cache.datasource.ProjectSkuStockData;
|
||||
import com.muyu.product.cache.key.SkuStockKey;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: sku库存实现类
|
||||
* @Date 2024-4-2 上午 10:53
|
||||
*/
|
||||
@Service
|
||||
public class ProjectSkuStockDataImpl implements ProjectSkuStockData {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Long getData (SkuStockKey key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -51,6 +51,7 @@ public class CartInfoController extends BaseController {
|
|||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出购物车列表
|
||||
*/
|
||||
|
@ -60,7 +61,7 @@ public class CartInfoController extends BaseController {
|
|||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, CartInfo cartInfo) {
|
||||
List<CartInfo> list = cartInfoService.list(cartInfo);
|
||||
ExcelUtil<CartInfo> util = new ExcelUtil<CartInfo>(CartInfo.class);
|
||||
ExcelUtil<CartInfo> util = new ExcelUtil<>(CartInfo.class);
|
||||
util.exportExcel(response, list, "购物车数据");
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,7 @@ public class CartInfoController extends BaseController {
|
|||
@PostMapping
|
||||
@ApiOperation("新增购物车")
|
||||
public Result<String> add(@RequestBody CartInfoSaveReq cartInfoSaveReq) {
|
||||
return toAjax(cartInfoService.save(CartInfo.saveBuild(cartInfoSaveReq)));
|
||||
return toAjax(cartInfoService.add(CartInfo.saveBuild (cartInfoSaveReq)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.muyu.shop.cart.service;
|
|||
import java.util.List;
|
||||
import com.muyu.shop.cart.domain.CartInfo;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.muyu.shop.cart.domain.req.CartInfoSaveReq;
|
||||
|
||||
/**
|
||||
* 购物车Service接口
|
||||
|
@ -11,6 +12,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||
* @date 2024-03-29
|
||||
*/
|
||||
public interface CartInfoService extends IService<CartInfo> {
|
||||
|
||||
|
||||
/**
|
||||
* 查询购物车列表
|
||||
*
|
||||
|
@ -19,4 +22,14 @@ public interface CartInfoService extends IService<CartInfo> {
|
|||
*/
|
||||
public List<CartInfo> list(CartInfo cartInfo);
|
||||
|
||||
|
||||
boolean insertCartInfo (CartInfoSaveReq cartInfoSaveReq);
|
||||
|
||||
|
||||
/**
|
||||
* 添加购物车
|
||||
* @param cartInfo
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
boolean add(CartInfo cartInfo);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
package com.muyu.shop.cart.service.impl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.muyu.common.core.constant.UserConstants;
|
||||
import com.muyu.common.core.exception.ServiceException;
|
||||
import com.muyu.common.core.text.Convert;
|
||||
import com.muyu.common.core.utils.ObjUtils;
|
||||
import com.muyu.common.security.utils.SecurityUtils;
|
||||
import com.muyu.product.cache.ProjectSkuStockCache;
|
||||
import com.muyu.product.cache.key.SkuStockKey;
|
||||
import com.muyu.shop.cart.cache.CartCache;
|
||||
import com.muyu.shop.cart.cache.key.CartHashKey;
|
||||
import com.muyu.shop.cart.domain.req.CartInfoSaveReq;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.catalina.security.SecurityUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.muyu.shop.cart.mapper.CartInfoMapper;
|
||||
import com.muyu.shop.cart.domain.CartInfo;
|
||||
|
@ -21,6 +35,59 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||
@Service
|
||||
public class CartInfoServiceImpl extends ServiceImpl<CartInfoMapper, CartInfo> implements CartInfoService {
|
||||
|
||||
@Autowired
|
||||
private CartCache cartCache;
|
||||
|
||||
@Autowired
|
||||
private ProjectSkuStockCache projectSkuStockCache;
|
||||
|
||||
@Override
|
||||
public boolean add(CartInfo cartInfo) {
|
||||
Long userId=SecurityUtils.getUserId ();
|
||||
CartHashKey cartHashKey = CartHashKey.builder ( )
|
||||
.projectId ( cartInfo.getProjectId ( ) )
|
||||
.projectSku ( cartInfo.getProjectSku ( ) )
|
||||
.build ( );
|
||||
|
||||
|
||||
|
||||
SkuStockKey skuStockKey = SkuStockKey.builder ( )
|
||||
.projectId ( cartInfo.getProjectId () )
|
||||
.sku ( cartInfo.getProjectSku () )
|
||||
.build ();
|
||||
// Long skuStock = projectSkuStockCache.get ( skuStockKey );
|
||||
Long skuStock = Convert.toLong ( projectSkuStockCache.get ( skuStockKey ) ,-1L);
|
||||
|
||||
|
||||
|
||||
if (cartCache.hasKey(userId,cartHashKey)){
|
||||
CartInfo cartInfoCache = cartCache.get ( userId, cartHashKey );
|
||||
cartInfoCache.setNum ( cartInfoCache.getNum ()+cartInfo.getNum () );
|
||||
|
||||
if (skuStock>cartInfoCache.getNum ()){
|
||||
throw new ServiceException ( "库存不足" );
|
||||
}
|
||||
|
||||
LambdaUpdateWrapper< CartInfo > updateWrapper = new LambdaUpdateWrapper<> ( );
|
||||
updateWrapper.set ( CartInfo::getNum,cartInfoCache.getNum () );
|
||||
updateWrapper.eq ( CartInfo::getId,cartInfoCache.getId () );
|
||||
this.update ( updateWrapper );
|
||||
this.cartCache.put ( userId,cartHashKey,cartInfoCache );
|
||||
}else {
|
||||
if (skuStock>cartInfo.getNum ()){
|
||||
throw new ServiceException ( "库存不足" );
|
||||
}
|
||||
|
||||
cartInfo.setUserId ( userId );
|
||||
cartInfo.setIsSelected ( "Y" );
|
||||
cartInfo.setCreateBy ( SecurityUtils.getUsername () );
|
||||
cartInfo.setCreateTime ( new Date () );
|
||||
this.save ( cartInfo );
|
||||
this.cartCache.put ( userId,cartHashKey,cartInfo );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询购物车列表
|
||||
*
|
||||
|
@ -53,9 +120,27 @@ public class CartInfoServiceImpl extends ServiceImpl<CartInfoMapper, CartInfo>
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertCartInfo(CartInfoSaveReq cartInfoSaveReq) {
|
||||
cartInfoSaveReq.setUserId ( SecurityUtils.getUserId () );
|
||||
|
||||
LambdaQueryWrapper< CartInfo > queryWrapper = new LambdaQueryWrapper<> ( ) {{
|
||||
eq ( CartInfo::getProjectSku, cartInfoSaveReq.getProjectSku ( ) );
|
||||
}};
|
||||
|
||||
CartInfo one = this.getOne ( queryWrapper );
|
||||
|
||||
if (one==null){
|
||||
this.save ( CartInfo.saveBuild(cartInfoSaveReq) );
|
||||
}
|
||||
LambdaUpdateWrapper< CartInfo > updateWrapper = new LambdaUpdateWrapper< CartInfo > ( )
|
||||
.eq ( CartInfo::getProjectSku, cartInfoSaveReq.getProjectSku ( ) )
|
||||
.setSql ( "num = num +" + cartInfoSaveReq.getNum ( ) );
|
||||
boolean update = this.update ( updateWrapper );
|
||||
|
||||
return update;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
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 YunFei.Du
|
||||
* @date 14:43 2024/4/2
|
||||
*/
|
||||
@Service
|
||||
public class CartDataImpl implements CartData {
|
||||
@Autowired
|
||||
private CartInfoService cartInfoService;
|
||||
/**
|
||||
* 通过键获取所有的hash数据
|
||||
*
|
||||
* @param key 键
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map< CartHashKey, CartInfo > getData (Long key) {
|
||||
|
||||
|
||||
|
||||
LambdaQueryWrapper<CartInfo> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CartInfo::getUserId, key);
|
||||
List<CartInfo> cartInfoList = cartInfoService.list(queryWrapper);
|
||||
|
||||
// Map<CartHashKey, CartInfo> map=new HashMap<> ( );
|
||||
// if (cartInfoList!=null&&cartInfoList.size ()>0){
|
||||
// for (CartInfo cartInfo : cartInfoList) {
|
||||
// map.put ( new CartHashKey ( cartInfo.getProjectId (),cartInfo.getProjectSku () ),cartInfo );
|
||||
// }
|
||||
// }
|
||||
// return map;
|
||||
|
||||
return cartInfoList.stream ()
|
||||
.collect( Collectors.toMap ( cartInfo ->CartHashKey.builder ( ).projectId ( cartInfo.getProjectId () ).projectSku ( cartInfo.getProjectSku () ).build (), cartInfo -> cartInfo ));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过缓存键和hash键获取hash值
|
||||
*
|
||||
* @param key 缓存键
|
||||
* @param hashKey hash键
|
||||
*
|
||||
* @return hash值
|
||||
*/
|
||||
@Override
|
||||
public CartInfo getData (Long key, CartHashKey hashKey) {
|
||||
CartInfo cartInfo = cartInfoService.getOne(new LambdaQueryWrapper<CartInfo>()
|
||||
.eq(CartInfo::getUserId, key)
|
||||
.eq(CartInfo::getProjectId, hashKey.getProjectId())
|
||||
.eq(CartInfo::getProjectSku, hashKey.getProjectSku()));
|
||||
return cartInfo;
|
||||
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@ server:
|
|||
|
||||
# Spring
|
||||
spring:
|
||||
main:
|
||||
allow-circular-references: true
|
||||
application:
|
||||
# 应用名称
|
||||
name: muyu-shop-cart
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -11,8 +11,8 @@ import lombok.experimental.SuperBuilder;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 授权角色返回结果集
|
||||
* dyf
|
||||
* 授权角色返回结果集
|
||||
* @Date 2023-6-19 下午 02:50
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -10,8 +10,8 @@ import lombok.experimental.SuperBuilder;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 部门树返回结果集
|
||||
* dyf
|
||||
* 部门树返回结果集
|
||||
* @Date 2023-6-19 下午 02:52
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -7,8 +7,8 @@ import lombok.NoArgsConstructor;
|
|||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 个人信息模型对象
|
||||
* dyf
|
||||
* 个人信息模型对象
|
||||
* @Date 2023-6-19 下午 02:05
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -9,8 +9,8 @@ import lombok.experimental.SuperBuilder;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 角色返回菜单树
|
||||
* dyf
|
||||
* 角色返回菜单树
|
||||
* @Date 2023-6-19 下午 02:40
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -10,8 +10,8 @@ import lombok.experimental.SuperBuilder;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 用户详细信息
|
||||
* dyf
|
||||
* 用户详细信息
|
||||
* @Date 2023-6-19 下午 02:45
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -9,8 +9,8 @@ import lombok.experimental.SuperBuilder;
|
|||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 用户信息结果集
|
||||
* dyf
|
||||
* 用户信息结果集
|
||||
* @Date 2023-6-19 下午 02:42
|
||||
*/
|
||||
@Data
|
||||
|
|
|
@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|||
import com.muyu.system.domain.SysConfig;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 配置mybatis配置
|
||||
* dyf
|
||||
* 配置mybatis配置
|
||||
* @Date 2023-11-13 上午 10:05
|
||||
*/
|
||||
public interface SysConfigMapper extends BaseMapper<SysConfig> {
|
||||
|
|
|
@ -6,8 +6,8 @@ import com.muyu.system.domain.SysConfig;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 配置plus业务层
|
||||
* dyf
|
||||
* 配置plus业务层
|
||||
* @Date 2023-11-13 上午 10:06
|
||||
*/
|
||||
public interface SysConfigService extends IService<SysConfig> {
|
||||
|
|
|
@ -18,8 +18,8 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 配置plus业务实现层
|
||||
* dyf
|
||||
* 配置plus业务实现层
|
||||
* @Date 2023-11-13 上午 10:06
|
||||
*/
|
||||
@Service
|
||||
|
|
Loading…
Reference in New Issue