feat: 添加商城每日购买次数限制功能 (exchange_times)
This commit is contained in:
parent
dca7ba7b1c
commit
66135678d3
|
|
@ -35,8 +35,7 @@ public class GoodsService : IGoodsService
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存过期时间
|
// 缓存过期时间(商品详情仍使用缓存)
|
||||||
private static readonly TimeSpan GoodsListCacheExpiry = TimeSpan.FromSeconds(30);
|
|
||||||
private static readonly TimeSpan GoodsDetailCacheExpiry = TimeSpan.FromMinutes(5);
|
private static readonly TimeSpan GoodsDetailCacheExpiry = TimeSpan.FromMinutes(5);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -52,30 +51,7 @@ public class GoodsService : IGoodsService
|
||||||
pageSize = 999;
|
pageSize = 999;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试从缓存获取 - 缓存键格式与PHP一致: {type}_{userId}_{page}
|
// 商品列表不使用缓存,确保库存数据实时更新
|
||||||
var cacheKey = $"{type}_{userId}_{page}";
|
|
||||||
var cachedData = await _cacheService.GetGoodsListCacheAsync(cacheKey);
|
|
||||||
if (!string.IsNullOrEmpty(cachedData))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var cachedResult = JsonSerializer.Deserialize<PageResponse<GoodsListDto>>(cachedData);
|
|
||||||
if (cachedResult != null)
|
|
||||||
{
|
|
||||||
// 更新参与次数(从缓存获取最新值)
|
|
||||||
foreach (var item in cachedResult.Data)
|
|
||||||
{
|
|
||||||
item.JoinCount = await GetJoinCountAsync(item.Id, item.Type);
|
|
||||||
}
|
|
||||||
_logger.LogDebug("商品列表从缓存获取: CacheKey={CacheKey}", cacheKey);
|
|
||||||
return cachedResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (JsonException ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "商品列表缓存反序列化失败: CacheKey={CacheKey}", cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建基础查询 - 排除已删除的商品
|
// 构建基础查询 - 排除已删除的商品
|
||||||
var query = _dbContext.Goods
|
var query = _dbContext.Goods
|
||||||
|
|
@ -205,18 +181,6 @@ public class GoodsService : IGoodsService
|
||||||
LastPage = lastPage
|
LastPage = lastPage
|
||||||
};
|
};
|
||||||
|
|
||||||
// 写入缓存
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var jsonData = JsonSerializer.Serialize(response);
|
|
||||||
await _cacheService.SetGoodsListCacheAsync(cacheKey, jsonData, GoodsListCacheExpiry);
|
|
||||||
_logger.LogDebug("商品列表已缓存: CacheKey={CacheKey}", cacheKey);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "商品列表缓存写入失败: CacheKey={CacheKey}", cacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -573,6 +573,40 @@ public class OrderService : IOrderService
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取商城每日购买次数限制
|
||||||
|
/// </summary>
|
||||||
|
private async Task<int> GetExchangeTimesLimitAsync()
|
||||||
|
{
|
||||||
|
var config = await _dbContext.Configs
|
||||||
|
.Where(c => c.ConfigKey == "app_setting")
|
||||||
|
.Select(c => c.ConfigValue)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(config))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var configObj = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(config);
|
||||||
|
if (configObj != null && configObj.TryGetValue("exchange_times", out var limitObj))
|
||||||
|
{
|
||||||
|
if (int.TryParse(limitObj?.ToString(), out var limit))
|
||||||
|
{
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 解析失败返回0
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 格式化图片URL
|
/// 格式化图片URL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2276,6 +2310,29 @@ public class OrderService : IOrderService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5.1 验证全局商城每日购买次数限制
|
||||||
|
var exchangeTimes = await GetExchangeTimesLimitAsync();
|
||||||
|
if (exchangeTimes > 0)
|
||||||
|
{
|
||||||
|
var todayStart2 = DateTime.Today;
|
||||||
|
var todayStartTimestamp2 = new DateTimeOffset(todayStart2).ToUnixTimeSeconds();
|
||||||
|
var todayEndTimestamp2 = new DateTimeOffset(todayStart2.AddDays(1)).ToUnixTimeSeconds();
|
||||||
|
|
||||||
|
// 统计用户今日在商城(type=10)的购买次数
|
||||||
|
var todayMallBuyCount = await _dbContext.Orders
|
||||||
|
.Where(o => o.UserId == userId
|
||||||
|
&& o.OrderType == 10
|
||||||
|
&& o.Status == 1
|
||||||
|
&& o.Addtime >= todayStartTimestamp2
|
||||||
|
&& o.Addtime < todayEndTimestamp2)
|
||||||
|
.CountAsync();
|
||||||
|
|
||||||
|
if (todayMallBuyCount >= exchangeTimes)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"商城每日限购{exchangeTimes}次,今日已购买{todayMallBuyCount}次");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 6. 验证抽奖次数
|
// 6. 验证抽奖次数
|
||||||
if (request.PrizeNum != 1 && request.PrizeNum != 3 && request.PrizeNum != 5 && request.PrizeNum != 10 && request.PrizeNum != 50)
|
if (request.PrizeNum != 1 && request.PrizeNum != 3 && request.PrizeNum != 5 && request.PrizeNum != 10 && request.PrizeNum != 50)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
<a href="https://market.aliyun.com/products/57126001/cmapi021863.html?#sku=yuncode1586300000" target="_blank" class="layui-btn layui-btn-primary layui-btn-sm">购买链接</a>
|
<a href="https://market.aliyun.com/products/57126001/cmapi021863.html?#sku=yuncode1586300000" target="_blank" class="layui-btn layui-btn-primary layui-btn-sm">购买链接</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item" style="display: none;">
|
||||||
<label class="layui-form-label">连击赏最大抽取次数</label>
|
<label class="layui-form-label">连击赏最大抽取次数</label>
|
||||||
<div class="layui-input-inline">
|
<div class="layui-input-inline">
|
||||||
<input type="text" name="lianji_max_num" value="{$data.lianji_max_num ? $data.lianji_max_num : 0}" lay-verify="required" class="layui-input">
|
<input type="text" name="lianji_max_num" value="{$data.lianji_max_num ? $data.lianji_max_num : 0}" lay-verify="required" class="layui-input">
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>分类</th>
|
<th>分类</th>
|
||||||
<th>名称</th>
|
<th>名称</th>
|
||||||
<th>奖品概率</th>
|
<!-- <th>奖品概率</th> -->
|
||||||
<th>时间</th>
|
<th>时间</th>
|
||||||
<th>操作</th>
|
<th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -58,11 +58,11 @@
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
<td>{$vo['title']}</td>
|
<td>{$vo['title']}</td>
|
||||||
<td>
|
<!-- <td>
|
||||||
{if condition="$vo['type'] eq 2"}
|
{if condition="$vo['type'] eq 2"}
|
||||||
{$vo['probability']}
|
{$vo['probability']}
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td> -->
|
||||||
<td>{$vo['addtime']|date="Y-m-d H:i"}</td>
|
<td>{$vo['addtime']|date="Y-m-d H:i"}</td>
|
||||||
<td>
|
<td>
|
||||||
<a style="text-decoration:none" title="编辑" href="{:url('/admin/qy_level_jiang_edit',['id'=>$vo['id']])}" class="layui-btn layui-btn-normal layui-btn-xs">
|
<a style="text-decoration:none" title="编辑" href="{:url('/admin/qy_level_jiang_edit',['id'=>$vo['id']])}" class="layui-btn layui-btn-normal layui-btn-xs">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user