24 changed files with 751 additions and 138 deletions
@ -0,0 +1,28 @@ |
|||
package cc.hiver.mall.pojo.vo; |
|||
|
|||
import cc.hiver.core.entity.Worker; |
|||
import cc.hiver.mall.entity.WorkerRelaPrice; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
import lombok.experimental.Accessors; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 兼职缓存信息 |
|||
* @author 王富康 |
|||
*/ |
|||
@Data |
|||
@Accessors(chain = true) |
|||
public class WorkerRedisVo implements Serializable { |
|||
|
|||
@ApiModelProperty(value = " 配送员ID") |
|||
private String workerId; |
|||
|
|||
@ApiModelProperty(value = " 配送基本信息") |
|||
private Worker worker; |
|||
|
|||
@ApiModelProperty(value = " 配送规则") |
|||
private List<WorkerRelaPrice> workerRelaPriceList; |
|||
} |
|||
@ -0,0 +1,244 @@ |
|||
package cc.hiver.mall.utils; |
|||
|
|||
import cc.hiver.core.common.redis.RedisTemplateHelper; |
|||
import cc.hiver.mall.pojo.vo.WorkerRedisVo; |
|||
import cn.hutool.json.JSONUtil; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.LinkedHashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 配送员信息缓存工具类 |
|||
* <p> |
|||
* 底层使用 Redis Hash 结构,保证按 regionId + workerId 维度的 O(1) 读写效率。 |
|||
* <pre> |
|||
* Key = WORKER_REDIS:{regionId} |
|||
* Field = workerId |
|||
* Value = WorkerRedisVo 的 JSON 序列化 |
|||
* </pre> |
|||
* <p> |
|||
* 使用场景:状态发生变化时(创建、更新、取消、完成等), |
|||
* |
|||
* @author system |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
public class WorkerRedisCacheUtil { |
|||
|
|||
/** Redis Key 前缀 */ |
|||
private static final String KEY_PREFIX = "WORKER_REDIS:"; |
|||
|
|||
@Autowired |
|||
private RedisTemplateHelper redisTemplateHelper; |
|||
|
|||
// ================================================================
|
|||
// Key 构建
|
|||
// ================================================================
|
|||
|
|||
private String buildKey(String regionId) { |
|||
return KEY_PREFIX + regionId; |
|||
} |
|||
|
|||
// ================================================================
|
|||
// 存放(put)
|
|||
// ================================================================
|
|||
|
|||
/** |
|||
* 存放单个到缓存 |
|||
* |
|||
* @param regionId 区域ID |
|||
* @param workerVO VO(必须包含有效的 id) |
|||
*/ |
|||
public void put(String regionId, WorkerRedisVo workerVO) { |
|||
if (StringUtils.isBlank(regionId) || workerVO == null || StringUtils.isBlank(workerVO.getWorkerId())) { |
|||
log.info("WorkerRedisCacheUtil.put 参数无效, workerId={}, workerVO={}", regionId, workerVO); |
|||
return; |
|||
} |
|||
try { |
|||
String key = buildKey(regionId); |
|||
String json = JSONUtil.toJsonStr(workerVO); |
|||
redisTemplateHelper.hPut(key, workerVO.getWorkerId(), json); |
|||
log.info("缓存配送员: regionId={}, workerId={}", regionId, workerVO.getWorkerId()); |
|||
} catch (Exception e) { |
|||
log.info("缓存配送员失败: regionId={}, workerId={}", regionId, workerVO.getWorkerId(), e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取区域所有在线配送员 |
|||
* |
|||
* @param regionId |
|||
* @return |
|||
*/ |
|||
public List<WorkerRedisVo> getAll(String regionId) { |
|||
if (StringUtils.isBlank(regionId)) { |
|||
return null; |
|||
} |
|||
try { |
|||
String key = buildKey(regionId); |
|||
Map<Object, Object> entries = redisTemplateHelper.hGetAll(key); |
|||
if (entries == null || entries.isEmpty()) { |
|||
return null; |
|||
} |
|||
List<WorkerRedisVo> result = new ArrayList<>(entries.size()); |
|||
for (Object value : entries.values()) { |
|||
if (value != null) { |
|||
result.add(JSONUtil.toBean(value.toString(), WorkerRedisVo.class)); |
|||
} |
|||
} |
|||
return result; |
|||
} catch (Exception e) { |
|||
log.info("获取区域在线配送员缓存失败: regionId={}", regionId, e); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 批量存放到缓存(通常用于缓存预热 / 首次加载) |
|||
* |
|||
* @param regionId 区域ID |
|||
* @param orders 列表 |
|||
*/ |
|||
public void putAll(String regionId, List<WorkerRedisVo> orders) { |
|||
if (StringUtils.isBlank(regionId) || orders == null || orders.isEmpty()) { |
|||
return; |
|||
} |
|||
try { |
|||
String key = buildKey(regionId); |
|||
Map<String, String> map = new LinkedHashMap<>(orders.size()); |
|||
for (WorkerRedisVo order : orders) { |
|||
if (order != null && StringUtils.isNotBlank(order.getWorkerId())) { |
|||
map.put(order.getWorkerId(), JSONUtil.toJsonStr(order)); |
|||
} |
|||
} |
|||
if (!map.isEmpty()) { |
|||
redisTemplateHelper.hPutAll(key, map); |
|||
log.info("批量缓存配送员: regionId={}, count={}", regionId, map.size()); |
|||
} |
|||
} catch (Exception e) { |
|||
log.info("批量缓存配送员失败: regionId={}", regionId, e); |
|||
} |
|||
} |
|||
|
|||
// ================================================================
|
|||
// 删除(remove)
|
|||
// ================================================================
|
|||
|
|||
/** |
|||
* 根据 regionId 和 workerId 从缓存中删除指定 |
|||
* |
|||
* @param regionId 区域ID |
|||
* @param workerId ID |
|||
*/ |
|||
public void remove(String regionId, String workerId) { |
|||
if (StringUtils.isBlank(regionId) || StringUtils.isBlank(workerId)) { |
|||
log.info("UserPendingOrderCacheUtil.remove 参数无效, regionId={}, workerId={}", regionId, workerId); |
|||
return; |
|||
} |
|||
try { |
|||
String key = buildKey(regionId); |
|||
redisTemplateHelper.hDelete(key, workerId); |
|||
log.info("删除缓存: regionId={}, workerId={}", regionId, workerId); |
|||
} catch (Exception e) { |
|||
log.info("删除缓存失败: regionId={}, workerId={}", regionId, workerId, e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 清除指定配送员所有缓存 |
|||
* <p> |
|||
* 典型场景:需要强制刷新该配送员缓存时调用。 |
|||
* |
|||
* @param regionId 区域ID |
|||
*/ |
|||
public void removeAll(String regionId) { |
|||
if (StringUtils.isBlank(regionId)) { |
|||
return; |
|||
} |
|||
try { |
|||
redisTemplateHelper.delete(buildKey(regionId)); |
|||
log.info("清除配送员缓存: regionId={}", regionId); |
|||
} catch (Exception e) { |
|||
log.info("清除配送员缓存失败: regionId={}", regionId, e); |
|||
} |
|||
} |
|||
|
|||
// ================================================================
|
|||
// 更新(update)
|
|||
// ================================================================
|
|||
|
|||
/** |
|||
* 根据 regionId 和 workerId 更新缓存中的信息 |
|||
* <p> |
|||
* |
|||
* @param regionId 区域ID |
|||
* @param workerVO 更新后的VO |
|||
*/ |
|||
public void update(String regionId, WorkerRedisVo workerVO) { |
|||
if (StringUtils.isBlank(regionId) || workerVO == null || StringUtils.isBlank(workerVO.getWorkerId())) { |
|||
log.warn("UserPendingOrderCacheUtil.update 参数无效, regionId={}, workerVO={}", regionId, workerVO); |
|||
return; |
|||
} |
|||
try { |
|||
// 如果状态已不属于,直接删除
|
|||
/*if (!isTerminalStatus(workerVO.getStatus())) { |
|||
remove(regionId, workerVO.getWorkerId()); |
|||
log.debug("已终态,从缓存移除: regionId={}, workerId={}, status={}", |
|||
regionId, workerVO.getWorkerId(), workerVO.getStatus()); |
|||
return; |
|||
}*/ |
|||
// 覆盖更新
|
|||
put(regionId, workerVO); |
|||
log.info("更新配送员缓存: regionId={}, workerId={}, status={}", |
|||
regionId, workerVO.getWorkerId()); |
|||
} catch (Exception e) { |
|||
log.info("更新用户信息缓存失败: regionId={}, workerId={}", regionId, workerVO.getWorkerId(), e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取配送员缓存单个 |
|||
* |
|||
* @param regionId 区域ID |
|||
* @param workerId ID |
|||
* @return 缓存的VO,不存在时返回 null |
|||
*/ |
|||
public WorkerRedisVo get(String regionId, String workerId) { |
|||
if (StringUtils.isBlank(regionId) || StringUtils.isBlank(workerId)) { |
|||
return null; |
|||
} |
|||
try { |
|||
String key = buildKey(regionId); |
|||
Object value = redisTemplateHelper.hGet(key, workerId); |
|||
if (value == null) { |
|||
return null; |
|||
} |
|||
return JSONUtil.toBean(value.toString(), WorkerRedisVo.class); |
|||
} catch (Exception e) { |
|||
log.info("获取配送员单个缓存失败: regionId={}, workerId={}", regionId, workerId, e); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 判断该配送员的缓存是否已存在 |
|||
* |
|||
* @param regionId 区域ID |
|||
* @return true 表示缓存存在 |
|||
*/ |
|||
public boolean exists(String regionId) { |
|||
if (StringUtils.isBlank(regionId)) { |
|||
return false; |
|||
} |
|||
Boolean hasKey = redisTemplateHelper.hasKey(buildKey(regionId)); |
|||
return hasKey != null && hasKey; |
|||
} |
|||
|
|||
|
|||
} |
|||
Loading…
Reference in new issue