HaniBlindBox/server/HoneyBox/src/HoneyBox.Core/Services/GoodsCacheService.cs
2026-01-04 01:47:02 +08:00

115 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}