115 lines
3.9 KiB
C#
115 lines
3.9 KiB
C#
using HoneyBox.Core.Interfaces;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace HoneyBox.Core.Services;
|
||
|
||
/// <summary>
|
||
/// 商品缓存服务实现
|
||
/// </summary>
|
||
public class GoodsCacheService : IGoodsCacheService
|
||
{
|
||
private readonly IRedisService _redisService;
|
||
private readonly ILogger<GoodsCacheService> _logger;
|
||
|
||
// 缓存键前缀 - 与PHP保持一致
|
||
private const string JoinCountKeyPrefix = "order_goods_count:";
|
||
private const string GoodsListKeyPrefix = "goods_list_";
|
||
private const string GoodsDetailKeyPrefix = "goods_detail_";
|
||
|
||
// 缓存过期时间
|
||
private static readonly TimeSpan JoinCountExpiry = TimeSpan.FromMinutes(5);
|
||
private static readonly TimeSpan GoodsListExpiry = TimeSpan.FromSeconds(30);
|
||
private static readonly TimeSpan GoodsDetailExpiry = TimeSpan.FromMinutes(5);
|
||
|
||
public GoodsCacheService(
|
||
IRedisService redisService,
|
||
ILogger<GoodsCacheService> logger)
|
||
{
|
||
_redisService = redisService;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<int> GetJoinCountAsync(int goodsId)
|
||
{
|
||
var key = $"{JoinCountKeyPrefix}{goodsId}";
|
||
var value = await _redisService.GetStringAsync(key);
|
||
|
||
if (int.TryParse(value, out var count))
|
||
{
|
||
return count;
|
||
}
|
||
|
||
// 返回-1表示缓存不存在
|
||
return -1;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task SetJoinCountAsync(int goodsId, int count)
|
||
{
|
||
var key = $"{JoinCountKeyPrefix}{goodsId}";
|
||
await _redisService.SetStringAsync(key, count.ToString(), JoinCountExpiry);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<int> IncrementJoinCountAsync(int goodsId)
|
||
{
|
||
var key = $"{JoinCountKeyPrefix}{goodsId}";
|
||
var currentValue = await GetJoinCountAsync(goodsId);
|
||
var newValue = currentValue > 0 ? currentValue + 1 : 1;
|
||
|
||
await _redisService.SetStringAsync(key, newValue.ToString(), JoinCountExpiry);
|
||
|
||
return newValue;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task InvalidateGoodsCacheAsync(int goodsId)
|
||
{
|
||
// 清除参与次数缓存
|
||
var joinCountKey = $"{JoinCountKeyPrefix}{goodsId}";
|
||
await _redisService.DeleteAsync(joinCountKey);
|
||
|
||
// 清除商品详情缓存 - 由于箱号可能有多个,这里清除所有可能的箱号缓存
|
||
// 注意:实际生产环境中可能需要使用Redis的SCAN命令来批量删除
|
||
// 这里简化处理,只清除常见的箱号范围(0-100)
|
||
var deleteTasks = new List<Task>();
|
||
for (int num = 0; num <= 100; num++)
|
||
{
|
||
var detailKey = $"{GoodsDetailKeyPrefix}{goodsId}_{num}";
|
||
deleteTasks.Add(_redisService.DeleteAsync(detailKey));
|
||
}
|
||
await Task.WhenAll(deleteTasks);
|
||
|
||
_logger.LogInformation("已清除商品 {GoodsId} 的所有缓存(参与次数、商品详情)", goodsId);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<string?> GetGoodsListCacheAsync(string cacheKey)
|
||
{
|
||
var key = $"{GoodsListKeyPrefix}{cacheKey}";
|
||
return await _redisService.GetStringAsync(key);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task SetGoodsListCacheAsync(string cacheKey, string data, TimeSpan expiry)
|
||
{
|
||
var key = $"{GoodsListKeyPrefix}{cacheKey}";
|
||
await _redisService.SetStringAsync(key, data, expiry);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<string?> GetGoodsDetailCacheAsync(int goodsId, int goodsNum)
|
||
{
|
||
var key = $"{GoodsDetailKeyPrefix}{goodsId}_{goodsNum}";
|
||
return await _redisService.GetStringAsync(key);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task SetGoodsDetailCacheAsync(int goodsId, int goodsNum, string data, TimeSpan expiry)
|
||
{
|
||
var key = $"{GoodsDetailKeyPrefix}{goodsId}_{goodsNum}";
|
||
await _redisService.SetStringAsync(key, data, expiry);
|
||
}
|
||
}
|