Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.Service/ProductService.cs
glz 1d86580db7 refactor: 重构状态更新接口,新增商品管理与勋章规则配置
1. 重构用户、宠物模板、勋章、管理员状态更新接口,移除冗余参数改为自动切换状态
2. 重命名宠物背景枚举为宠物皮肤,调整商品状态字段为枚举类型
3. 新增商品上下架状态管理接口与对应逻辑
4. 新增勋章规则配置系统,支持动态加载可用表和字段
5. 优化商品查询与展示逻辑,适配新的状态字段
2026-06-09 11:41:28 +08:00

288 lines
9.8 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 Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;
namespace QYZH.InteractiveMagazine.Service;
/// <summary>
/// 商品服务实现
/// </summary>
public class ProductService(BaseRepository<Product> productRepository, ILogger<ProductService> logger) : BaseRepository<Product>, IProductService
{
/// <summary>
/// 创建商品
/// </summary>
public async Task<ProductOutput> CreateAsync(ProductInput input)
{
logger.LogInformation("正在创建商品,商品名称: {Name}", input.Name);
if (string.IsNullOrWhiteSpace(input.Name))
{
throw new BusinessException("商品名称不能为空", 400);
}
if (string.IsNullOrWhiteSpace(input.Type))
{
throw new BusinessException("商品类型不能为空", 400);
}
if (input.Price < 0)
{
throw new BusinessException("商品价格不能为负数", 400);
}
var product = new Product
{
Name = input.Name.Trim(),
Description = input.Description,
ImageUrl = input.ImageUrl,
Price = input.Price,
Type = Enum.Parse<ProductTypeEnum>(input.Type, true),
Status = (int)input.Status,
MetaData = input.MetaData,
IsActive = input.IsActive,
Stock = input.Stock,
CreatedBy = "System",
UpdatedBy = "System",
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
IsDeleted = false
};
var result = await productRepository.InsertAsync(product);
if (!result)
{
logger.LogError("商品创建失败,商品名称: {Name}", input.Name);
throw new BusinessException("创建商品失败", 500);
}
logger.LogInformation("商品创建成功,商品名称: {Name}, ID: {Id}", input.Name, product.Id);
return new ProductOutput
{
Id = product.Id,
Name = product.Name,
Description = product.Description,
ImageUrl = product.ImageUrl,
Price = product.Price,
Type = product.Type.ToString(),
Status = product.Status.ToString(),
MetaData = product.MetaData,
IsActive = product.IsActive,
Stock = product.Stock,
CreatedBy = product.CreatedBy,
CreatedAt = product.CreatedAt,
UpdatedBy = product.UpdatedBy,
UpdatedAt = product.UpdatedAt
};
}
/// <summary>
/// 更新商品
/// </summary>
public async Task<ProductOutput> UpdateAsync(long id, ProductInput input)
{
logger.LogInformation("正在更新商品ID: {Id}", id);
var product = await productRepository.GetByIdAsync(id);
if (product == null)
{
logger.LogWarning("未找到要更新的商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404);
}
if (string.IsNullOrWhiteSpace(input.Name))
{
throw new BusinessException("商品名称不能为空", 400);
}
if (string.IsNullOrWhiteSpace(input.Type))
{
throw new BusinessException("商品类型不能为空", 400);
}
if (input.Price < 0)
{
throw new BusinessException("商品价格不能为负数", 400);
}
product.Name = input.Name.Trim();
product.Description = input.Description;
product.ImageUrl = input.ImageUrl;
product.Price = input.Price;
product.Type = Enum.Parse<ProductTypeEnum>(input.Type, true);
product.Status = (int)input.Status;
product.MetaData = input.MetaData;
product.IsActive = input.IsActive;
product.Stock = input.Stock;
product.UpdatedBy = "System";
product.UpdatedAt = DateTime.Now;
var result = await productRepository.UpdateAsync(product);
if (!result)
{
logger.LogError("商品更新失败ID: {Id}", id);
throw new BusinessException("更新商品失败", 500);
}
logger.LogInformation("商品更新成功ID: {Id}", id);
return new ProductOutput
{
Id = product.Id,
Name = product.Name,
Description = product.Description,
ImageUrl = product.ImageUrl,
Price = product.Price,
Type = product.Type.ToString(),
Status = product.Status.ToString(),
MetaData = product.MetaData,
IsActive = product.IsActive,
Stock = product.Stock,
CreatedBy = product.CreatedBy,
CreatedAt = product.CreatedAt,
UpdatedBy = product.UpdatedBy,
UpdatedAt = product.UpdatedAt
};
}
/// <summary>
/// 删除商品(软删除)
/// </summary>
public async Task DeleteAsync(long id)
{
logger.LogInformation("正在删除商品ID: {Id}", id);
var product = await productRepository.GetByIdAsync(id);
if (product == null)
{
logger.LogWarning("未找到要删除的商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404);
}
var result = await productRepository.DeleteByIdAsync(id);
if (!result)
{
logger.LogError("商品删除失败ID: {Id}", id);
throw new BusinessException("删除商品失败", 500);
}
logger.LogInformation("商品删除成功ID: {Id}", id);
}
/// <summary>
/// 根据ID获取商品
/// </summary>
public async Task<ProductOutput> GetByIdAsync(long id)
{
logger.LogInformation("正在获取商品信息ID: {Id}", id);
var product = await productRepository.GetByIdAsync(id);
if (product == null)
{
logger.LogWarning("未找到商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404);
}
return new ProductOutput
{
Id = product.Id,
Name = product.Name,
Description = product.Description,
ImageUrl = product.ImageUrl,
Price = product.Price,
Type = product.Type.ToString(),
Status = product.Status.ToString(),
MetaData = product.MetaData,
IsActive = product.IsActive,
Stock = product.Stock,
CreatedBy = product.CreatedBy,
CreatedAt = product.CreatedAt,
UpdatedBy = product.UpdatedBy,
UpdatedAt = product.UpdatedAt
};
}
/// <summary>
/// 分页查询商品列表
/// </summary>
public async Task<PageListModel<ProductOutput>> GetListAsync(ProductQueryInput input)
{
logger.LogInformation("正在查询商品列表,页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);
if (input.PageIndex <= 0)
{
throw new BusinessException("页码必须大于0", 400);
}
if (input.PageSize <= 0 || input.PageSize > 100)
{
throw new BusinessException("每页条数必须在1-100之间", 400);
}
RefAsync<int> totalNumber = 0;
var pageResult = await productRepository.Queryable()
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), p => p.Name.Contains(input.Name))
.WhereIF(!string.IsNullOrWhiteSpace(input.Type), p => p.Type.ToString() == input.Type)
.WhereIF(input.Status.HasValue, p => p.Status == (int)input.Status)
.WhereIF(input.IsActive.HasValue, p => p.IsActive == input.IsActive.Value)
.OrderByDescending(p => p.CreatedAt)
.Select(p => new ProductOutput
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
ImageUrl = p.ImageUrl,
Price = p.Price,
Type = p.Type.ToString(),
Status = p.Status.ToString(),
MetaData = p.MetaData,
IsActive = p.IsActive,
Stock = p.Stock,
CreatedBy = p.CreatedBy,
CreatedAt = p.CreatedAt,
UpdatedBy = p.UpdatedBy,
UpdatedAt = p.UpdatedAt
}, true)
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
return new PageListModel<ProductOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
}
/// <summary>
/// 更新商品上架/下架状态(取反)
/// </summary>
public async Task UpdateSaleStatusAsync(long id)
{
logger.LogInformation("正在更新商品上下架状态ID: {Id}", id);
var product = await productRepository.GetByIdAsync(id);
if (product == null)
{
logger.LogWarning("未找到要更新状态的商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404);
}
product.Status = product.Status == (int)ProductStatusEnum.OnSale
? (int)ProductStatusEnum.OffSale
: (int)ProductStatusEnum.OnSale;
product.UpdatedBy = "System";
product.UpdatedAt = DateTime.Now;
var result = await productRepository.UpdateAsync(product);
if (!result)
{
logger.LogError("商品状态更新失败ID: {Id}", id);
throw new BusinessException("更新商品状态失败", 500);
}
logger.LogInformation("商品上下架状态更新成功ID: {Id}, SaleStatus: {SaleStatus}", id, product.Status);
}
}