云商品 增加分组
This commit is contained in:
1 parent
f4913b4fc2
commit
b18aad1f85
5 files changed
+200
-24
No files matched your search
@@ -96,7 +96,7 @@ namespace Store.Modules.CloudProduct.Controllers
|
||||
/// 创建收藏分组:创建成功返回 true,同名分组已存在返回 false。
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<bool> CreateGroup(CreateUserFavoriteGroupRequest request)
|
||||
public async Task<bool> CreateGroup(UserFavoriteGroupRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
@@ -121,7 +121,7 @@ namespace Store.Modules.CloudProduct.Controllers
|
||||
/// <summary>
|
||||
/// 查询用户的收藏分组(含默认分组)及分组下收藏数量。
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[HttpPost]
|
||||
public async Task<List<UserFavoriteGroupDto>> GetGroups(string? userName = null)
|
||||
{
|
||||
var resolved = ResolveUserName(userName);
|
||||
@@ -153,6 +153,41 @@ namespace Store.Modules.CloudProduct.Controllers
|
||||
|
||||
return await _favoritesService.GetFavoriteStatusAsync(request);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除分组
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<bool> DelGroup(UserFavoriteGroupRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new AppException("请求参数不能为空", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
request.UserName = ResolveUserName(request.UserName);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.UserName))
|
||||
{
|
||||
throw new AppException("用户名不能为空", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
return await _favoritesService.DelGroupAsync(request);
|
||||
}
|
||||
|
||||
/// <summary>将已收藏商品移动到指定分组。</summary>
|
||||
[HttpPost]
|
||||
public async Task<bool> SetFavoriteGroup(SetUserFavoriteGroupRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new AppException("请求参数不能为空", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
request.UserName = ResolveUserName(request.UserName);
|
||||
return await _favoritesService.SetFavoriteGroupAsync(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检索用户收藏的商品(标题、销量、价格、类目、分组)。
|
||||
@@ -274,4 +309,4 @@ namespace Store.Modules.CloudProduct.Controllers
|
||||
: userName.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ namespace Store.Modules.CloudProduct.Dtos
|
||||
/// <summary>
|
||||
/// 创建收藏分组请求
|
||||
/// </summary>
|
||||
public class CreateUserFavoriteGroupRequest
|
||||
public class UserFavoriteGroupRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户名(为空时取当前登录用户)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Store.Modules.CloudProduct.Dtos
|
||||
{
|
||||
/// <summary>将用户已收藏的商品移动到指定分组。</summary>
|
||||
public class SetUserFavoriteGroupRequest
|
||||
{
|
||||
/// <summary>用户名称,为空时由 API 使用当前登录用户。</summary>
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>商品编号集合。</summary>
|
||||
public List<long> GoodsIds { get; set; } = new();
|
||||
|
||||
/// <summary>目标分组 ID。</summary>
|
||||
public int GroupId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,6 @@ namespace Store.Modules.CloudProduct.Dtos
|
||||
public string GroupName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>该分组下的收藏数量</summary>
|
||||
public long FavoriteCount { get; set; }
|
||||
//public long FavoriteCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace Store.Modules.CloudProduct.Services
|
||||
Task<int> RemoveFavoritesAsync(RemoveUserFavoritesRequest request);
|
||||
|
||||
/// <summary>创建收藏分组:创建成功返回 true,同名分组已存在返回 false</summary>
|
||||
Task<bool> CreateGroupAsync(CreateUserFavoriteGroupRequest request);
|
||||
Task<bool> CreateGroupAsync(UserFavoriteGroupRequest request);
|
||||
|
||||
/// <summary>查询用户的收藏分组(含默认分组)及分组下收藏数量</summary>
|
||||
Task<List<UserFavoriteGroupDto>> GetGroupsAsync(string userName);
|
||||
@@ -40,6 +40,8 @@ namespace Store.Modules.CloudProduct.Services
|
||||
|
||||
/// <summary>移除所有用户收藏索引并按数据库数据全量重建,返回重建的文档数</summary>
|
||||
Task<long> RebuildSearchIndexAsync();
|
||||
Task<bool> DelGroupAsync(UserFavoriteGroupRequest request);
|
||||
Task<bool> SetFavoriteGroupAsync(SetUserFavoriteGroupRequest request);
|
||||
}
|
||||
|
||||
internal class UserFavoritesService : IUserFavoritesService
|
||||
@@ -298,7 +300,7 @@ namespace Store.Modules.CloudProduct.Services
|
||||
/// <summary>
|
||||
/// 创建收藏分组:创建成功返回 true,同一用户同名分组已存在返回 false。
|
||||
/// </summary>
|
||||
public async Task<bool> CreateGroupAsync(CreateUserFavoriteGroupRequest request)
|
||||
public async Task<bool> CreateGroupAsync(UserFavoriteGroupRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
@@ -356,36 +358,160 @@ namespace Store.Modules.CloudProduct.Services
|
||||
.OrderBy(x => x.Id)
|
||||
.ToListAsync();
|
||||
|
||||
var countList = await _favoriteRepository.Select
|
||||
.Where(x => x.UserName == userName)
|
||||
.GroupBy(x => x.GroupId)
|
||||
.ToListAsync(x => new { GroupId = x.Key, Count = x.Count() });
|
||||
//var countList = await _favoriteRepository.Select
|
||||
// .Where(x => x.UserName == userName)
|
||||
// .GroupBy(x => x.GroupId)
|
||||
// .ToListAsync(x => new { GroupId = x.Key, Count = x.Count() });
|
||||
|
||||
var countMap = countList.ToDictionary(x => x.GroupId, x => (long)x.Count);
|
||||
//var countMap = countList.ToDictionary(x => x.GroupId, x => (long)x.Count);
|
||||
|
||||
var result = new List<UserFavoriteGroupDto>();
|
||||
|
||||
if (countMap.TryGetValue(0, out var defaultCount) && defaultCount > 0)
|
||||
{
|
||||
result.Add(new UserFavoriteGroupDto
|
||||
{
|
||||
Id = 0,
|
||||
UserName = userName,
|
||||
GroupName = DefaultGroupName,
|
||||
FavoriteCount = defaultCount,
|
||||
});
|
||||
}
|
||||
//if (countMap.TryGetValue(0, out var defaultCount) && defaultCount > 0)
|
||||
//{
|
||||
// result.Add(new UserFavoriteGroupDto
|
||||
// {
|
||||
// Id = 0,
|
||||
// UserName = userName,
|
||||
// GroupName = DefaultGroupName,
|
||||
// FavoriteCount = defaultCount,
|
||||
// });
|
||||
//}
|
||||
|
||||
result.AddRange(groups.Select(x => new UserFavoriteGroupDto
|
||||
{
|
||||
Id = x.Id,
|
||||
UserName = x.UserName,
|
||||
GroupName = x.GroupName,
|
||||
FavoriteCount = countMap.TryGetValue((int)x.Id, out var count) ? count : 0,
|
||||
//FavoriteCount = countMap.TryGetValue((int)x.Id, out var count) ? count : 0,
|
||||
}));
|
||||
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除用户分组
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="AppException"></exception>
|
||||
public async Task<bool> DelGroupAsync(UserFavoriteGroupRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new AppException("请求参数不能为空", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
var userName = request.UserName?.Trim() ?? string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(userName))
|
||||
{
|
||||
throw new AppException("用户名不能为空", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
var groupName = request.GroupName?.Trim() ?? string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(groupName))
|
||||
{
|
||||
throw new AppException("分组名不能为空", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
if (groupName.Length > 255)
|
||||
{
|
||||
throw new AppException("分组名长度不能超过255个字符", ResultCode.ValidationError);
|
||||
}
|
||||
//_favoriteRepository.Select.Where(a=>a.Id)
|
||||
|
||||
var existing = await _groupRepository.Select
|
||||
.Where(x => x.UserName == userName && x.GroupName == groupName)
|
||||
.FirstAsync();
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
var favorites = await _favoriteRepository.Select
|
||||
.Where(x => x.UserName == userName && x.GroupId == existing.Id)
|
||||
.ToListAsync();
|
||||
var goodsIds = favorites.Select(x => x.GoodsId).ToList();
|
||||
var goodsMap = goodsIds.Count == 0
|
||||
? new Dictionary<long, GoodsEntity>()
|
||||
: (await _goodsRepository.Select.Where(x => goodsIds.Contains(x.GoodsId)).ToListAsync())
|
||||
.ToDictionary(x => x.GoodsId);
|
||||
|
||||
await _favoriteRepository.Orm.Update<UserGoodsFavoriteEntity>()
|
||||
.Set(a => a.GroupId, 0)
|
||||
.Where(a => a.UserName == userName && a.GroupId == existing.Id)
|
||||
.ExecuteAffrowsAsync();
|
||||
|
||||
foreach (var favorite in favorites)
|
||||
{
|
||||
favorite.GroupId = 0;
|
||||
}
|
||||
await _indexService.IndexDocumentsAsync(favorites
|
||||
.Where(x => goodsMap.ContainsKey(x.GoodsId))
|
||||
.Select(x => BuildDocument(x, goodsMap[x.GoodsId], DefaultGroupName)));
|
||||
}
|
||||
|
||||
var rows = await _groupRepository.DeleteAsync(a => a.UserName == userName && a.GroupName == groupName);
|
||||
if (rows != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>将用户已收藏的商品移动到其指定分组,并同步收藏索引。</summary>
|
||||
public async Task<bool> SetFavoriteGroupAsync(SetUserFavoriteGroupRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new AppException("请求参数不能为空", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
var userName = request.UserName?.Trim() ?? string.Empty;
|
||||
var goodsIds = request.GoodsIds?.Where(x => x > 0).Distinct().ToList() ?? new List<long>();
|
||||
if (string.IsNullOrWhiteSpace(userName) || goodsIds.Count == 0 || request.GroupId < 0)
|
||||
{
|
||||
throw new AppException("用户、商品或分组参数无效", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
var mainUser = await _queryService.GetMainUser(userName);
|
||||
userName = mainUser.UserName;
|
||||
await using var lease = await _indexLock.AcquireFavoritesAsync();
|
||||
|
||||
var favorites = await _favoriteRepository.Select
|
||||
.Where(x => x.UserName == userName && goodsIds.Contains(x.GoodsId))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
if (request.GroupId > 0 && await _groupRepository.Select
|
||||
.Where(x => x.Id == request.GroupId && x.UserName == userName)
|
||||
.FirstAsync() == null)
|
||||
{
|
||||
throw new AppException("收藏分组不存在或不属于该用户", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
var goodsList = await _goodsRepository.Select.Where(x => goodsIds.Contains(x.GoodsId)).ToListAsync();
|
||||
if (goodsList.Count != goodsIds.Count)
|
||||
{
|
||||
throw new AppException("部分商品不存在", ResultCode.ValidationError);
|
||||
}
|
||||
|
||||
var changedFavorites = favorites.Where(x => x.GroupId != request.GroupId).ToList();
|
||||
if (changedFavorites.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
await _favoriteRepository.Orm.Update<UserGoodsFavoriteEntity>()
|
||||
.Set(x => x.GroupId, request.GroupId)
|
||||
.Where(x => x.UserName == userName && goodsIds.Contains(x.GoodsId))
|
||||
.ExecuteAffrowsAsync();
|
||||
foreach (var favorite in changedFavorites)
|
||||
{
|
||||
favorite.GroupId = request.GroupId;
|
||||
}
|
||||
var goodsMap = goodsList.ToDictionary(x => x.GoodsId);
|
||||
var groupName = await ResolveGroupNameAsync(userName, request.GroupId);
|
||||
await _indexService.IndexDocumentsAsync(changedFavorites.Select(x => BuildDocument(x, goodsMap[x.GoodsId], groupName)));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按 GoodsIds 顺序返回每个商品是否已被该用户收藏(商品编号无效的返回 false)。
|
||||
@@ -640,4 +766,4 @@ namespace Store.Modules.CloudProduct.Services
|
||||
: UserFavoritesSortBy.CreatedTimeDesc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user