From 32989e1fa0baabbed9be832d664bb2b118c108e7 Mon Sep 17 00:00:00 2001
From: glz <694770232@qq.com>
Date: Wed, 3 Jun 2026 16:09:56 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E7=94=A8?=
=?UTF-8?q?=E6=88=B7=E4=B8=8E=E5=95=86=E5=93=81=E6=A8=A1=E5=9D=97=EF=BC=8C?=
=?UTF-8?q?=E7=BB=9F=E4=B8=80=E4=B8=9A=E5=8A=A1=E6=A8=A1=E5=9E=8B=E4=B8=8E?=
=?UTF-8?q?=E6=9C=8D=E5=8A=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 新增用户状态枚举UserStatusEnum,统一用户状态定义
2. 重构用户体系:合并WxUser与User实体为Users实体,统一用户管理
3. 新增微信小程序认证相关服务与控制器,实现一键登录功能
4. 新增商品管理完整服务与控制器,修复商品表字段映射问题
5. 删除冗余的WxUser相关服务与控制器代码
6. 新增Newtonsoft.Json依赖用于微信接口响应解析
7. 清理无用的文件夹引用配置
---
.../IProductService.cs | 45 +++
.../IUsersService.cs | 23 ++
.../IWeChatAuthService.cs | 17 ++
.../IWxUserService.cs | 33 ---
.../Dto/Mall/ProductDto.cs | 156 +++++++++++
.../Dto/UsersDto.cs | 71 +++++
.../Dto/WeChat/WeChatDto.cs | 48 ++++
.../Entity/Product.cs | 5 +-
.../Entity/User .cs | 58 ----
.../Entity/{WxUser.cs => Users.cs} | 57 ++--
.../Enum/UserStatusEnum.cs | 17 ++
.../QYZH.InteractiveMagazine.Models.csproj | 1 +
.../ProductService.cs | 256 ++++++++++++++++++
.../UsersService.cs | 59 ++++
.../WeChatAuthService.cs | 160 +++++++++++
.../WxUserService.cs | 221 ---------------
.../Controllers/ProductController.cs | 151 +++++++++++
.../Controllers/UsersController.cs | 51 ++++
.../WeChat/WeChatAuthController.cs | 49 ++++
.../WeChat/WeChatBaseController.cs | 63 +++++
.../Controllers/WxUserController.cs | 147 ----------
.../QYZH.InteractiveMagazine.WebApi.csproj | 3 -
22 files changed, 1200 insertions(+), 491 deletions(-)
create mode 100644 QYZH.InteractiveMagazine.IService/IProductService.cs
create mode 100644 QYZH.InteractiveMagazine.IService/IUsersService.cs
create mode 100644 QYZH.InteractiveMagazine.IService/IWeChatAuthService.cs
delete mode 100644 QYZH.InteractiveMagazine.IService/IWxUserService.cs
create mode 100644 QYZH.InteractiveMagazine.Models/Dto/Mall/ProductDto.cs
create mode 100644 QYZH.InteractiveMagazine.Models/Dto/UsersDto.cs
delete mode 100644 QYZH.InteractiveMagazine.Models/Entity/User .cs
rename QYZH.InteractiveMagazine.Models/Entity/{WxUser.cs => Users.cs} (78%)
create mode 100644 QYZH.InteractiveMagazine.Models/Enum/UserStatusEnum.cs
create mode 100644 QYZH.InteractiveMagazine.Service/ProductService.cs
create mode 100644 QYZH.InteractiveMagazine.Service/UsersService.cs
create mode 100644 QYZH.InteractiveMagazine.Service/WeChatAuthService.cs
delete mode 100644 QYZH.InteractiveMagazine.Service/WxUserService.cs
create mode 100644 QYZH.InteractiveMagazine.WebApi/Controllers/ProductController.cs
create mode 100644 QYZH.InteractiveMagazine.WebApi/Controllers/UsersController.cs
create mode 100644 QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/WeChatAuthController.cs
create mode 100644 QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/WeChatBaseController.cs
delete mode 100644 QYZH.InteractiveMagazine.WebApi/Controllers/WxUserController.cs
diff --git a/QYZH.InteractiveMagazine.IService/IProductService.cs b/QYZH.InteractiveMagazine.IService/IProductService.cs
new file mode 100644
index 0000000..142059b
--- /dev/null
+++ b/QYZH.InteractiveMagazine.IService/IProductService.cs
@@ -0,0 +1,45 @@
+using QYZH.InteractiveMagazine.Models.Dto;
+using QYZH.InteractiveMagazine.Models.Entity;
+
+namespace QYZH.InteractiveMagazine.IService;
+
+///
+/// 商品服务接口
+///
+public interface IProductService : IBaseService
+{
+ ///
+ /// 创建商品
+ ///
+ /// 商品输入
+ /// 创建的商品信息
+ Task CreateAsync(ProductInput input);
+
+ ///
+ /// 更新商品
+ ///
+ /// 商品ID
+ /// 商品输入
+ /// 更新后的商品信息
+ Task UpdateAsync(long id, ProductInput input);
+
+ ///
+ /// 删除商品(软删除)
+ ///
+ /// 商品ID
+ Task DeleteAsync(long id);
+
+ ///
+ /// 根据ID获取商品
+ ///
+ /// 商品ID
+ /// 商品信息
+ Task GetByIdAsync(long id);
+
+ ///
+ /// 分页查询商品列表
+ ///
+ /// 查询条件
+ /// 分页结果
+ Task> GetListAsync(ProductQueryInput input);
+}
diff --git a/QYZH.InteractiveMagazine.IService/IUsersService.cs b/QYZH.InteractiveMagazine.IService/IUsersService.cs
new file mode 100644
index 0000000..70edd91
--- /dev/null
+++ b/QYZH.InteractiveMagazine.IService/IUsersService.cs
@@ -0,0 +1,23 @@
+using QYZH.InteractiveMagazine.IService.Dto;
+using QYZH.InteractiveMagazine.Models.Dto;
+using QYZH.InteractiveMagazine.Models.Entity;
+
+namespace QYZH.InteractiveMagazine.IService;
+
+public interface IUsersService : IBaseService
+{
+ ///
+ /// 分页查询用户列表
+ ///
+ Task>> GetListAsync(UsersQueryInput input);
+
+ ///
+ /// 获取用户详情
+ ///
+ Task> GetDetailAsync(long id);
+
+ ///
+ /// 更新用户状态
+ ///
+ Task UpdateStatusAsync(long id, UpdateUserStatusInput input);
+}
diff --git a/QYZH.InteractiveMagazine.IService/IWeChatAuthService.cs b/QYZH.InteractiveMagazine.IService/IWeChatAuthService.cs
new file mode 100644
index 0000000..b1a82b0
--- /dev/null
+++ b/QYZH.InteractiveMagazine.IService/IWeChatAuthService.cs
@@ -0,0 +1,17 @@
+using QYZH.InteractiveMagazine.IService.Dto;
+using QYZH.InteractiveMagazine.Models.Entity;
+
+namespace QYZH.InteractiveMagazine.IService;
+
+///
+/// 微信小程序认证服务
+///
+public interface IWeChatAuthService : IBaseService
+{
+ ///
+ /// 微信小程序一键登录
+ ///
+ /// 登录输入(含微信 code)
+ /// 登录结果(含 Token 和用户信息)
+ Task LoginAsync(WeChatLoginInput input);
+}
diff --git a/QYZH.InteractiveMagazine.IService/IWxUserService.cs b/QYZH.InteractiveMagazine.IService/IWxUserService.cs
deleted file mode 100644
index 3ed85e7..0000000
--- a/QYZH.InteractiveMagazine.IService/IWxUserService.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using QYZH.InteractiveMagazine.IService.Dto;
-using QYZH.InteractiveMagazine.Models.Dto;
-using QYZH.InteractiveMagazine.Models.Entity;
-
-namespace QYZH.InteractiveMagazine.IService;
-
-public interface IWxUserService : IBaseService
-{
- ///
- /// 创建微信用户
- ///
- Task CreateAsync(WxUserInput input);
-
- ///
- /// 更新微信用户
- ///
- Task UpdateAsync(long id, WxUserInput input);
-
- ///
- /// 删除微信用户(软删除)
- ///
- Task DeleteAsync(long id);
-
- ///
- /// 根据ID获取微信用户
- ///
- Task GetByIdAsync(long id);
-
- ///
- /// 分页查询微信用户列表
- ///
- Task> GetListAsync(WxUserQueryInput input);
-}
diff --git a/QYZH.InteractiveMagazine.Models/Dto/Mall/ProductDto.cs b/QYZH.InteractiveMagazine.Models/Dto/Mall/ProductDto.cs
new file mode 100644
index 0000000..3c4059f
--- /dev/null
+++ b/QYZH.InteractiveMagazine.Models/Dto/Mall/ProductDto.cs
@@ -0,0 +1,156 @@
+using QYZH.InteractiveMagazine.Models.Dto;
+
+namespace QYZH.InteractiveMagazine.Models.Dto;
+
+///
+/// 商品创建/更新输入
+///
+public class ProductInput
+{
+ ///
+ /// 商品名称
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// 描述
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// 商品图片
+ ///
+ public string? ImageUrl { get; set; }
+
+ ///
+ /// 所需积分
+ ///
+ public int Price { get; set; }
+
+ ///
+ /// 商品类型: MakeUpCard, PetBg
+ ///
+ public string Type { get; set; } = string.Empty;
+
+ ///
+ /// 售卖状态: OnSale, OffSale
+ ///
+ public string SaleStatus { get; set; } = "OnSale";
+
+ ///
+ /// 扩展数据
+ ///
+ public string? MetaData { get; set; }
+
+ ///
+ /// 是否上架
+ ///
+ public bool IsActive { get; set; } = true;
+
+ ///
+ /// 库存(-1无限)
+ ///
+ public int Stock { get; set; } = -1;
+}
+
+///
+/// 商品输出
+///
+public class ProductOutput
+{
+ ///
+ /// 主键ID
+ ///
+ public long Id { get; set; }
+
+ ///
+ /// 商品名称
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// 描述
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// 商品图片
+ ///
+ public string? ImageUrl { get; set; }
+
+ ///
+ /// 所需积分
+ ///
+ public int Price { get; set; }
+
+ ///
+ /// 商品类型
+ ///
+ public string Type { get; set; } = string.Empty;
+
+ ///
+ /// 售卖状态
+ ///
+ public string SaleStatus { get; set; } = string.Empty;
+
+ ///
+ /// 扩展数据
+ ///
+ public string? MetaData { get; set; }
+
+ ///
+ /// 是否上架
+ ///
+ public bool IsActive { get; set; }
+
+ ///
+ /// 库存(-1无限)
+ ///
+ public int Stock { get; set; }
+
+ ///
+ /// 创建人
+ ///
+ public string? CreatedBy { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime CreatedAt { get; set; }
+
+ ///
+ /// 更新人
+ ///
+ public string? UpdatedBy { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? UpdatedAt { get; set; }
+}
+
+///
+/// 商品分页查询输入
+///
+public class ProductQueryInput : PageQueryModel
+{
+ ///
+ /// 商品名称(模糊查询)
+ ///
+ public string? Name { get; set; }
+
+ ///
+ /// 商品类型
+ ///
+ public string? Type { get; set; }
+
+ ///
+ /// 售卖状态: OnSale, OffSale
+ ///
+ public string? SaleStatus { get; set; }
+
+ ///
+ /// 是否上架
+ ///
+ public bool? IsActive { get; set; }
+}
diff --git a/QYZH.InteractiveMagazine.Models/Dto/UsersDto.cs b/QYZH.InteractiveMagazine.Models/Dto/UsersDto.cs
new file mode 100644
index 0000000..50557ca
--- /dev/null
+++ b/QYZH.InteractiveMagazine.Models/Dto/UsersDto.cs
@@ -0,0 +1,71 @@
+using QYZH.InteractiveMagazine.Models.Dto;
+
+namespace QYZH.InteractiveMagazine.IService.Dto;
+
+///
+/// Users查询输入DTO
+///
+public class UsersQueryInput : PageQueryModel
+{
+ ///
+ /// 微信用户ID
+ ///
+ public string? WxUserId { get; set; }
+}
+
+///
+/// Users输出DTO (基本信息)
+///
+public class UsersOutput
+{
+ ///
+ /// 主键ID
+ ///
+ public long Id { get; set; }
+
+ ///
+ /// 微信用户ID
+ ///
+ public string WxUserId { get; set; } = string.Empty;
+
+ ///
+ /// 昵称
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// 头像地址
+ ///
+ public string? AvatarUrl { get; set; }
+
+ ///
+ /// 积分余额
+ ///
+ public int Points { get; set; }
+
+ ///
+ /// 用户类型
+ ///
+ public string Type { get; set; } = string.Empty;
+
+ ///
+ /// 状态
+ ///
+ public string Status { get; set; } = string.Empty;
+
+ ///
+ /// 当前成长值
+ ///
+ public int GrowthPoints { get; set; }
+}
+
+///
+/// 更新用户状态输入DTO
+///
+public class UpdateUserStatusInput
+{
+ ///
+ /// 用户状态: 1-启用, 2-冻结
+ ///
+ public int Status { get; set; }
+}
diff --git a/QYZH.InteractiveMagazine.Models/Dto/WeChat/WeChatDto.cs b/QYZH.InteractiveMagazine.Models/Dto/WeChat/WeChatDto.cs
index 9318662..54e06bd 100644
--- a/QYZH.InteractiveMagazine.Models/Dto/WeChat/WeChatDto.cs
+++ b/QYZH.InteractiveMagazine.Models/Dto/WeChat/WeChatDto.cs
@@ -1,7 +1,19 @@
using QYZH.InteractiveMagazine.Models.Dto;
+using Newtonsoft.Json;
namespace QYZH.InteractiveMagazine.IService.Dto;
+///
+/// 微信小程序登录输入
+///
+public class WeChatLoginInput
+{
+ ///
+ /// 微信登录凭证(wx.login 获取的 code)
+ ///
+ public string Code { get; set; } = string.Empty;
+}
+
///
/// 微信登录输出
///
@@ -177,3 +189,39 @@ public class WxUserQueryInput : PageQueryModel
}
+///
+/// 微信 code2session 接口响应
+///
+public class WxCode2SessionResponse
+{
+ ///
+ /// 用户唯一标识
+ ///
+ [JsonProperty("openid")]
+ public string? OpenId { get; set; }
+
+ ///
+ /// 会话密钥
+ ///
+ [JsonProperty("session_key")]
+ public string? SessionKey { get; set; }
+
+ ///
+ /// 用户统一标识(在开放平台绑定了多个应用时使用)
+ ///
+ [JsonProperty("unionid")]
+ public string? UnionId { get; set; }
+
+ ///
+ /// 错误码
+ ///
+ [JsonProperty("errcode")]
+ public int ErrCode { get; set; }
+
+ ///
+ /// 错误信息
+ ///
+ [JsonProperty("errmsg")]
+ public string? ErrMsg { get; set; }
+}
+
diff --git a/QYZH.InteractiveMagazine.Models/Entity/Product.cs b/QYZH.InteractiveMagazine.Models/Entity/Product.cs
index 0508825..aa882fe 100644
--- a/QYZH.InteractiveMagazine.Models/Entity/Product.cs
+++ b/QYZH.InteractiveMagazine.Models/Entity/Product.cs
@@ -49,11 +49,12 @@ namespace QYZH.InteractiveMagazine.Models.Entity
public string Type {get;set;}
///
- /// Desc:状态: OnSale, OffSale
+ /// Desc:售卖状态: OnSale, OffSale
/// Default:OnSale
/// Nullable:False
///
- public string Status {get;set;}
+ [SugarColumn(ColumnName = "SaleStatus")]
+ public string SaleStatus {get;set;}
///
/// Desc:扩展数据
diff --git a/QYZH.InteractiveMagazine.Models/Entity/User .cs b/QYZH.InteractiveMagazine.Models/Entity/User .cs
deleted file mode 100644
index ce975e9..0000000
--- a/QYZH.InteractiveMagazine.Models/Entity/User .cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using SqlSugar;
-
-namespace QYZH.InteractiveMagazine.Models.Entity
-{
- ///
- ///用户表
- ///
- [SugarTable("User")]
- public partial class User : SqlSugarBaseEntity
- {
- ///
- /// Desc:微信用户ID
- /// Default:
- /// Nullable:True
- ///
- public string WxUserId { get; set; }
- ///
- /// Desc:昵称
- /// Default:
- /// Nullable:True
- ///
- public string Name { get; set; }
- ///
- /// Desc:当前成长值
- /// Default:0
- /// Nullable:False
- ///
- public int GrowthPoints { get; set; }
- ///
- /// Desc:头像地址
- /// Default:
- /// Nullable:True
- ///
- public string AvatarUrl { get; set; }
- ///
- /// Desc:积分余额
- /// Default:0
- /// Nullable:False
- ///
- public int Points { get; set; }
-
- ///
- /// Desc:用户类型: Normal, VIP
- /// Default:Normal
- /// Nullable:False
- ///
- public string Type { get; set; }
-
- ///
- /// Desc:状态: Active, Disabled
- /// Default:Active
- /// Nullable:False
- ///
- public string Status { get; set; }
-
-
- }
-}
diff --git a/QYZH.InteractiveMagazine.Models/Entity/WxUser.cs b/QYZH.InteractiveMagazine.Models/Entity/Users.cs
similarity index 78%
rename from QYZH.InteractiveMagazine.Models/Entity/WxUser.cs
rename to QYZH.InteractiveMagazine.Models/Entity/Users.cs
index 79b985a..03b1fbb 100644
--- a/QYZH.InteractiveMagazine.Models/Entity/WxUser.cs
+++ b/QYZH.InteractiveMagazine.Models/Entity/Users.cs
@@ -5,44 +5,34 @@ namespace QYZH.InteractiveMagazine.Models.Entity
///
///用户表
///
- [SugarTable("WxUser")]
- public partial class WxUser : SqlSugarBaseEntity
+ [SugarTable("Users")]
+ public partial class Users : SqlSugarBaseEntity
{
- ///
- /// Desc:微信OpenId
- /// Default:
- /// Nullable:False
- ///
- public string OpenId { get; set; }
-
- ///
- /// Desc:微信UnionId
- /// Default:
- /// Nullable:True
- ///
- public string UnionId { get; set; }
///
/// Desc:昵称
/// Default:
/// Nullable:True
///
- public string NickName { get; set; }
-
+ public string Name { get; set; }
+ ///
+ /// Desc:当前成长值
+ /// Default:0
+ /// Nullable:False
+ ///
+ public int GrowthPoints { get; set; }
///
/// Desc:头像地址
/// Default:
/// Nullable:True
///
public string AvatarUrl { get; set; }
-
///
- /// Desc:手机号
- /// Default:
- /// Nullable:True
+ /// Desc:积分余额
+ /// Default:0
+ /// Nullable:False
///
- public string Phone { get; set; }
-
+ public int Points { get; set; }
///
/// Desc:用户类型: Normal, VIP
@@ -57,12 +47,25 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Nullable:False
///
public string Status { get; set; }
-
///
- /// Desc:密码,默认手机后4位
- /// Default:Active
+ /// Desc:微信OpenId
+ /// Default:
/// Nullable:False
///
- public string Pwd { get; set; }
+ public string OpenId { get; set; }
+
+ ///
+ /// Desc:微信UnionId
+ /// Default:
+ /// Nullable:True
+ ///
+ public string UnionId { get; set; }
+ ///
+ /// Desc:手机号
+ /// Default:
+ /// Nullable:True
+ ///
+ public string Phone { get; set; }
+
}
}
diff --git a/QYZH.InteractiveMagazine.Models/Enum/UserStatusEnum.cs b/QYZH.InteractiveMagazine.Models/Enum/UserStatusEnum.cs
new file mode 100644
index 0000000..f215f63
--- /dev/null
+++ b/QYZH.InteractiveMagazine.Models/Enum/UserStatusEnum.cs
@@ -0,0 +1,17 @@
+namespace QYZH.InteractiveMagazine.Models.Enum;
+
+///
+/// 用户状态枚举
+///
+public enum UserStatusEnum
+{
+ ///
+ /// 启用
+ ///
+ Active = 1,
+
+ ///
+ /// 冻结
+ ///
+ Frozen = 2
+}
diff --git a/QYZH.InteractiveMagazine.Models/QYZH.InteractiveMagazine.Models.csproj b/QYZH.InteractiveMagazine.Models/QYZH.InteractiveMagazine.Models.csproj
index f145742..e339258 100644
--- a/QYZH.InteractiveMagazine.Models/QYZH.InteractiveMagazine.Models.csproj
+++ b/QYZH.InteractiveMagazine.Models/QYZH.InteractiveMagazine.Models.csproj
@@ -9,6 +9,7 @@
+
diff --git a/QYZH.InteractiveMagazine.Service/ProductService.cs b/QYZH.InteractiveMagazine.Service/ProductService.cs
new file mode 100644
index 0000000..75dec02
--- /dev/null
+++ b/QYZH.InteractiveMagazine.Service/ProductService.cs
@@ -0,0 +1,256 @@
+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.Repository;
+using SqlSugar;
+
+namespace QYZH.InteractiveMagazine.Service;
+
+///
+/// 商品服务实现
+///
+public class ProductService(BaseRepository productRepository, ILogger logger) : BaseRepository, IProductService
+{
+
+ ///
+ /// 创建商品
+ ///
+ public async Task 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 = input.Type,
+ SaleStatus = input.SaleStatus,
+ 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,
+ SaleStatus = product.SaleStatus,
+ MetaData = product.MetaData,
+ IsActive = product.IsActive,
+ Stock = product.Stock,
+ CreatedBy = product.CreatedBy,
+ CreatedAt = product.CreatedAt,
+ UpdatedBy = product.UpdatedBy,
+ UpdatedAt = product.UpdatedAt
+ };
+ }
+
+ ///
+ /// 更新商品
+ ///
+ public async Task 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 = input.Type;
+ product.SaleStatus = input.SaleStatus;
+ 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,
+ SaleStatus = product.SaleStatus,
+ MetaData = product.MetaData,
+ IsActive = product.IsActive,
+ Stock = product.Stock,
+ CreatedBy = product.CreatedBy,
+ CreatedAt = product.CreatedAt,
+ UpdatedBy = product.UpdatedBy,
+ UpdatedAt = product.UpdatedAt
+ };
+ }
+
+ ///
+ /// 删除商品(软删除)
+ ///
+ 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);
+ }
+
+ ///
+ /// 根据ID获取商品
+ ///
+ public async Task 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,
+ SaleStatus = product.SaleStatus,
+ MetaData = product.MetaData,
+ IsActive = product.IsActive,
+ Stock = product.Stock,
+ CreatedBy = product.CreatedBy,
+ CreatedAt = product.CreatedAt,
+ UpdatedBy = product.UpdatedBy,
+ UpdatedAt = product.UpdatedAt
+ };
+ }
+
+ ///
+ /// 分页查询商品列表
+ ///
+ public async Task> 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 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 == input.Type)
+ .WhereIF(!string.IsNullOrWhiteSpace(input.SaleStatus), p => p.SaleStatus == input.SaleStatus)
+ .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,
+ SaleStatus = p.SaleStatus,
+ 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(pageResult, input.PageIndex, input.PageSize, totalNumber);
+ }
+}
diff --git a/QYZH.InteractiveMagazine.Service/UsersService.cs b/QYZH.InteractiveMagazine.Service/UsersService.cs
new file mode 100644
index 0000000..8d785d4
--- /dev/null
+++ b/QYZH.InteractiveMagazine.Service/UsersService.cs
@@ -0,0 +1,59 @@
+using Microsoft.Extensions.Logging;
+using QYZH.InteractiveMagazine.IService;
+using QYZH.InteractiveMagazine.IService.Dto;
+using QYZH.InteractiveMagazine.Models.Common;
+using QYZH.InteractiveMagazine.Models.Dto;
+using QYZH.InteractiveMagazine.Models.Entity;
+using QYZH.InteractiveMagazine.Repository;
+using SqlSugar;
+
+namespace QYZH.InteractiveMagazine.Service;
+
+public class UsersService(BaseRepository usersRepository, ILogger _logger) : BaseRepository, IUsersService
+{
+ ///
+ /// 分页查询用户列表
+ ///
+ public async Task>> GetListAsync(UsersQueryInput input)
+ {
+ var page = Queryable()
+ .WhereIF(!string.IsNullOrEmpty(input.WxUserId), u => u.OpenId == input.WxUserId)
+ .OrderBy(u => u.Id, OrderByType.Desc)
+ .ToPage(input);
+
+ return BaseResponse>.Success(page);
+ }
+
+ ///
+ /// 获取用户详情
+ ///
+ public async Task> GetDetailAsync(long id)
+ {
+ var user = await GetByIdAsync(u => u.Id == id);
+ if (user == null)
+ {
+ return BaseResponse.Fail("用户不存在");
+ }
+ return BaseResponse.Success(user);
+ }
+
+ ///
+ /// 更新用户状态
+ ///
+ public async Task UpdateStatusAsync(long id, UpdateUserStatusInput input)
+ {
+ var exists = await Queryable().AnyAsync(u => u.Id == id);
+ if (!exists)
+ {
+ return BaseResponse.Fail("用户不存在");
+ }
+
+ var statusValue = input.Status == 1 ? "Active" : "Disabled";
+ var result = await UpdateAsync(
+ u => new Users { Status = statusValue },
+ u => u.Id == id
+ );
+
+ return result ? BaseResponse.Success() : BaseResponse.Fail("更新失败");
+ }
+}
diff --git a/QYZH.InteractiveMagazine.Service/WeChatAuthService.cs b/QYZH.InteractiveMagazine.Service/WeChatAuthService.cs
new file mode 100644
index 0000000..93debec
--- /dev/null
+++ b/QYZH.InteractiveMagazine.Service/WeChatAuthService.cs
@@ -0,0 +1,160 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using QYZH.InteractiveMagazine.Common.Helpers;
+using QYZH.InteractiveMagazine.Infrastructure.Auth;
+using QYZH.InteractiveMagazine.Infrastructure.Cache;
+using QYZH.InteractiveMagazine.IService;
+using QYZH.InteractiveMagazine.IService.Dto;
+using QYZH.InteractiveMagazine.Models.Common;
+using QYZH.InteractiveMagazine.Models.Entity;
+using QYZH.InteractiveMagazine.Models.Settings;
+using QYZH.InteractiveMagazine.Repository;
+
+namespace QYZH.InteractiveMagazine.Service;
+
+///
+/// 微信小程序认证服务实现
+///
+public class WeChatAuthService(BaseRepository usersRepository, IConfiguration configuration, ILogger logger) : BaseRepository, IWeChatAuthService
+{
+ private const string TokenKeyPrefix = "InteractiveMagazine:WeChatAuth:Token";
+ private const string Code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
+
+ ///
+ /// 微信小程序一键登录
+ ///
+ /// 登录输入(含微信 code)
+ /// 登录结果(含 Token 和用户信息)
+ public async Task LoginAsync(WeChatLoginInput input)
+ {
+ logger.LogInformation("微信小程序登录尝试");
+
+ // 参数校验
+ if (string.IsNullOrWhiteSpace(input.Code))
+ {
+ throw new BusinessException("微信登录凭证 code 不能为空", 400);
+ }
+
+ // 获取微信配置
+ var weChatSettings = GetWeChatSettings();
+
+ // 调用微信 code2session 接口
+ var wxResponse = await CallCode2SessionAsync(weChatSettings, input.Code);
+ if (wxResponse == null || wxResponse.ErrCode != 0 || string.IsNullOrWhiteSpace(wxResponse.OpenId))
+ {
+ var errMsg = wxResponse?.ErrMsg ?? "未知错误";
+ logger.LogWarning("微信 code2session 接口调用失败,errcode: {ErrCode}, errmsg: {ErrMsg}", wxResponse?.ErrCode, errMsg);
+ throw new BusinessException($"微信登录失败:{errMsg}", 400);
+ }
+
+ logger.LogInformation("微信 code2session 成功,OpenId: {OpenId}", wxResponse.OpenId);
+
+ // 查询用户是否已存在
+ var user = await usersRepository.GetFirstAsync(u => u.OpenId == wxResponse.OpenId);
+ var isNewUser = user == null;
+
+ if (isNewUser)
+ {
+ // 首次登录,创建新用户
+ user = new Users
+ {
+ Name = $"wx_{wxResponse.OpenId[^8..]}",
+ OpenId = wxResponse.OpenId,
+ UnionId = wxResponse.UnionId,
+ Type = "Normal",
+ Status = "Active",
+ GrowthPoints = 0,
+ Points = 0
+ };
+
+ var insertResult = await usersRepository.Insertable(user).ExecuteReturnIdentityAsync();
+ if (insertResult <= 0)
+ {
+ logger.LogError("创建微信用户失败,OpenId: {OpenId}", wxResponse.OpenId);
+ throw new BusinessException("创建用户失败,请稍后重试", 500);
+ }
+
+ user.Id = insertResult;
+ logger.LogInformation("微信新用户创建成功,UserId: {UserId}, OpenId: {OpenId}", user.Id, wxResponse.OpenId);
+ }
+ else
+ {
+ // 已有用户,校验状态
+ if (user.Status == "Disabled")
+ {
+ logger.LogWarning("微信登录失败,用户已被禁用,UserId: {UserId}, OpenId: {OpenId}", user.Id, wxResponse.OpenId);
+ throw new BusinessException("账号已被禁用,请联系客服", 403);
+ }
+
+ logger.LogInformation("微信老用户登录,UserId: {UserId}, OpenId: {OpenId}", user.Id, wxResponse.OpenId);
+ }
+
+ // 生成 JWT Token
+ var jwtSettings = GetJwtSettings();
+ var token = JwtHelper.GenerateToken((long)user.Id, user.Name, jwtSettings);
+
+ // 缓存 Token 到 Redis
+ await RedisHelper.StringSetAsync($"{TokenKeyPrefix}:{user.Id}", token, TimeSpan.FromMinutes(jwtSettings.ExpiryMinutes));
+
+ return new WeChatLoginOutput
+ {
+ Token = token,
+ UserId = (long)user.Id,
+ UserName = user.Name,
+ OpenId = wxResponse.OpenId
+ };
+ }
+
+ ///
+ /// 调用微信 code2session 接口
+ ///
+ private async Task CallCode2SessionAsync(WeChatSettings settings, string code)
+ {
+ var url = string.Format(Code2SessionUrl, settings.AppId, settings.AppSecret, code);
+ try
+ {
+ return await HttpHelper.GetAsync(url);
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "调用微信 code2session 接口异常,URL: {Url}", url);
+ throw new BusinessException("微信服务请求失败,请稍后重试", 500);
+ }
+ }
+
+ ///
+ /// 获取微信配置
+ ///
+ private WeChatSettings GetWeChatSettings()
+ {
+ var settings = configuration.GetSection("WeChatSettings").Get();
+ if (settings == null || string.IsNullOrWhiteSpace(settings.AppId) || string.IsNullOrWhiteSpace(settings.AppSecret))
+ {
+ logger.LogError("微信配置不完整,请检查 appsettings.json 中的 WeChatSettings 节点");
+ throw new BusinessException("微信配置不完整,请联系系统管理员", 500);
+ }
+ return settings;
+ }
+
+ ///
+ /// 获取 JWT 配置
+ ///
+ private JwtSettings GetJwtSettings()
+ {
+ var jwtSettings = configuration.GetSection("JwtSettings").Get()
+ ?? new JwtSettings
+ {
+ Issuer = "QYZH.InteractiveMagazine",
+ Audience = "QYZH.InteractiveMagazine",
+ SecretKey = "your-256-bit-secret-key-here-change-in-production",
+ ExpiryMinutes = 120
+ };
+
+ if (string.IsNullOrWhiteSpace(jwtSettings.SecretKey))
+ {
+ throw new BusinessException("JWT 配置不完整", 500);
+ }
+
+ return jwtSettings;
+ }
+}
diff --git a/QYZH.InteractiveMagazine.Service/WxUserService.cs b/QYZH.InteractiveMagazine.Service/WxUserService.cs
deleted file mode 100644
index ab42cdb..0000000
--- a/QYZH.InteractiveMagazine.Service/WxUserService.cs
+++ /dev/null
@@ -1,221 +0,0 @@
-using Microsoft.Extensions.Logging;
-using QYZH.InteractiveMagazine.IService;
-using QYZH.InteractiveMagazine.IService.Dto;
-using QYZH.InteractiveMagazine.Models.Common;
-using QYZH.InteractiveMagazine.Models.Dto;
-using QYZH.InteractiveMagazine.Models.Entity;
-using QYZH.InteractiveMagazine.Repository;
-using SqlSugar;
-using System.Linq.Expressions;
-
-namespace QYZH.InteractiveMagazine.Service;
-
-public class WxUserService(BaseRepository wxUserRepository, ILogger _logger) : BaseRepository, IWxUserService
-{
-
- public async Task CreateAsync(WxUserInput input)
- {
- _logger.LogInformation("正在创建微信用户,OpenId: {OpenId}", input.OpenId);
-
- if (string.IsNullOrWhiteSpace(input.OpenId))
- {
- throw new BusinessException("OpenId不能为空", 400);
- }
-
- var existingUser = await wxUserRepository.GetFirstAsync(a => a.OpenId == input.OpenId);
- if (existingUser != null)
- {
- _logger.LogWarning("创建微信用户失败,OpenId已存在: {OpenId}", input.OpenId);
- throw new BusinessException("OpenId已存在", 400);
- }
-
- var wxUser = new WxUser
- {
-
- OpenId = input.OpenId.Trim(),
- UnionId = input.UnionId,
- NickName = input.NickName,
- AvatarUrl = input.AvatarUrl,
- Phone = input.Phone,
- Type = input.Type,
- Status = input.Status,
- Pwd = input.Pwd ?? string.Empty,
- CreatedBy = "System",
- UpdatedBy = "System",
- CreatedAt = DateTime.Now,
- UpdatedAt = DateTime.Now,
- IsDeleted = false
- };
-
- var result = await wxUserRepository.InsertAsync(wxUser);
- if (!result)
- {
- _logger.LogError("微信用户创建失败,OpenId: {OpenId}", input.OpenId);
- throw new BusinessException("创建微信用户失败", 500);
- }
-
- _logger.LogInformation("微信用户创建成功,OpenId: {OpenId}, ID: {Id}", input.OpenId, wxUser.Id);
-
- return new WxUserOutput
- {
- Id = wxUser.Id,
- OpenId = wxUser.OpenId,
- UnionId = wxUser.UnionId,
- NickName = wxUser.NickName,
- AvatarUrl = wxUser.AvatarUrl,
- Phone = wxUser.Phone,
- Type = wxUser.Type,
- Status = wxUser.Status,
- CreatedBy = wxUser.CreatedBy,
- CreatedAt = wxUser.CreatedAt,
- UpdatedBy = wxUser.UpdatedBy,
- UpdatedAt = wxUser.UpdatedAt
- };
- }
-
- public async Task UpdateAsync(long id, WxUserInput input)
- {
- _logger.LogInformation("正在更新微信用户,ID: {Id}", id);
-
- var wxUser = await wxUserRepository.GetByIdAsync(id);
- if (wxUser == null)
- {
- _logger.LogWarning("未找到要更新的微信用户,ID: {Id}", id);
- throw new BusinessException("微信用户不存在", 404);
- }
-
- if (!string.IsNullOrWhiteSpace(input.OpenId) && input.OpenId != wxUser.OpenId)
- {
- var existingUser = await wxUserRepository.GetFirstAsync(a => a.OpenId == input.OpenId.Trim());
- if (existingUser != null && existingUser.Id != id)
- {
- _logger.LogWarning("更新微信用户失败,OpenId已存在: {OpenId}", input.OpenId);
- throw new BusinessException("OpenId已存在", 400);
- }
-
- wxUser.OpenId = input.OpenId.Trim();
- }
-
- wxUser.UnionId = input.UnionId ?? wxUser.UnionId;
- wxUser.NickName = input.NickName ?? wxUser.NickName;
- wxUser.AvatarUrl = input.AvatarUrl ?? wxUser.AvatarUrl;
- wxUser.Phone = input.Phone ?? wxUser.Phone;
- wxUser.Type = input.Type ?? wxUser.Type;
- wxUser.Status = input.Status ?? wxUser.Status;
- wxUser.Pwd = input.Pwd ?? wxUser.Pwd;
-
- wxUser.UpdatedBy = "System";
- wxUser.UpdatedAt = DateTime.Now;
-
- var result = await wxUserRepository.UpdateAsync(wxUser);
- if (!result)
- {
- _logger.LogError("微信用户更新失败,ID: {Id}", id);
- throw new BusinessException("更新微信用户失败", 500);
- }
-
- _logger.LogInformation("微信用户更新成功,ID: {Id}", id);
-
- return new WxUserOutput
- {
- Id = wxUser.Id,
- OpenId = wxUser.OpenId,
- UnionId = wxUser.UnionId,
- NickName = wxUser.NickName,
- AvatarUrl = wxUser.AvatarUrl,
- Phone = wxUser.Phone,
- Type = wxUser.Type,
- Status = wxUser.Status,
- CreatedBy = wxUser.CreatedBy,
- CreatedAt = wxUser.CreatedAt,
- UpdatedBy = wxUser.UpdatedBy,
- UpdatedAt = wxUser.UpdatedAt
- };
- }
-
- public async Task DeleteAsync(long id)
- {
- _logger.LogInformation("正在删除微信用户,ID: {Id}", id);
-
- var wxUser = await wxUserRepository.GetByIdAsync(id);
- if (wxUser == null)
- {
- _logger.LogWarning("未找到要删除的微信用户,ID: {Id}", id);
- throw new BusinessException("微信用户不存在", 404);
- }
-
- var result = await wxUserRepository.DeleteByIdAsync(id);
- if (!result)
- {
- _logger.LogError("微信用户删除失败,ID: {Id}", id);
- throw new BusinessException("删除微信用户失败", 500);
- }
-
- _logger.LogInformation("微信用户删除成功,ID: {Id}", id);
- }
-
- public async Task GetByIdAsync(long id)
- {
- var wxUser = await wxUserRepository.GetByIdAsync(id);
- if (wxUser == null)
- {
-
- throw new BusinessException("微信用户不存在", 404);
- }
-
- return new WxUserOutput
- {
- Id = wxUser.Id,
- OpenId = wxUser.OpenId,
- UnionId = wxUser.UnionId,
- NickName = wxUser.NickName,
- AvatarUrl = wxUser.AvatarUrl,
- Phone = wxUser.Phone,
- Type = wxUser.Type,
- Status = wxUser.Status,
- CreatedBy = wxUser.CreatedBy,
- CreatedAt = wxUser.CreatedAt,
- UpdatedBy = wxUser.UpdatedBy,
- UpdatedAt = wxUser.UpdatedAt
- };
- }
-
- public async Task> GetListAsync(WxUserQueryInput input)
- {
-
- if (input.PageIndex <= 0)
- {
- throw new BusinessException("页码必须大于0", 400);
- }
-
- if (input.PageSize <= 0 || input.PageSize > 100)
- {
- throw new BusinessException("每页条数必须在1-100之间", 400);
- }
- RefAsync totalNumber = 0;
-
- var pageResult = await wxUserRepository.Queryable()
- .WhereIF(!string.IsNullOrWhiteSpace(input.NickName), a => a.NickName == input.NickName)
- .OrderByDescending(a => a.CreatedAt)
- .Select(wxUser => new WxUserOutput
- {
- Id = wxUser.Id,
- OpenId = wxUser.OpenId,
- UnionId = wxUser.UnionId,
- NickName = wxUser.NickName,
- AvatarUrl = wxUser.AvatarUrl,
- Phone = wxUser.Phone,
- Type = wxUser.Type,
- Status = wxUser.Status,
- CreatedBy = wxUser.CreatedBy,
- CreatedAt = wxUser.CreatedAt,
- UpdatedBy = wxUser.UpdatedBy,
- UpdatedAt = wxUser.UpdatedAt
- }, true)
- .ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
-
- return new PageListModel(pageResult, input.PageIndex, input.PageSize, totalNumber);
- }
-
-
-}
diff --git a/QYZH.InteractiveMagazine.WebApi/Controllers/ProductController.cs b/QYZH.InteractiveMagazine.WebApi/Controllers/ProductController.cs
new file mode 100644
index 0000000..a3d5beb
--- /dev/null
+++ b/QYZH.InteractiveMagazine.WebApi/Controllers/ProductController.cs
@@ -0,0 +1,151 @@
+using Microsoft.AspNetCore.Mvc;
+using QYZH.InteractiveMagazine.IService;
+using QYZH.InteractiveMagazine.Models.Common;
+using QYZH.InteractiveMagazine.Models.Dto;
+using QYZH.InteractiveMagazine.Models.Enum;
+
+namespace QYZH.InteractiveMagazine.WebApi.Controllers;
+
+///
+/// 商品管理控制器
+///
+[Route("api/[controller]")]
+[ApiController]
+[ApiExplorerSettings(GroupName = nameof(ApiVersionEnum.Platform))]
+public class ProductController : BaseController
+{
+ private readonly IProductService _productService;
+ private readonly ILogger _logger;
+
+ public ProductController(IProductService productService, ILogger logger)
+ {
+ _productService = productService;
+ _logger = logger;
+ }
+
+ ///
+ /// 创建商品
+ ///
+ /// 商品信息
+ /// 创建的商品信息
+ [HttpPost]
+ public async Task> CreateAsync([FromBody] ProductInput input)
+ {
+ try
+ {
+ var result = await _productService.CreateAsync(input);
+ return Success(result, "创建商品成功");
+ }
+ catch (BusinessException ex)
+ {
+ _logger.LogWarning(ex, "创建商品业务异常: {Message}", ex.Message);
+ return BaseResponse.Fail(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "创建商品系统异常,参数:{Input}", input);
+ return BaseResponse.Fail("创建商品失败,请稍后重试");
+ }
+ }
+
+ ///
+ /// 更新商品
+ ///
+ /// 商品ID
+ /// 商品信息
+ /// 更新后的商品信息
+ [HttpPut("{id}")]
+ public async Task> UpdateAsync(long id, [FromBody] ProductInput input)
+ {
+ try
+ {
+ var result = await _productService.UpdateAsync(id, input);
+ return Success(result, "更新商品成功");
+ }
+ catch (BusinessException ex)
+ {
+ _logger.LogWarning(ex, "更新商品业务异常: {Message}", ex.Message);
+ return BaseResponse.Fail(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "更新商品系统异常,ID:{Id},参数:{Input}", id, input);
+ return BaseResponse.Fail("更新商品失败,请稍后重试");
+ }
+ }
+
+ ///
+ /// 删除商品
+ ///
+ /// 商品ID
+ /// 操作结果
+ [HttpDelete("{id}")]
+ public async Task> DeleteAsync(long id)
+ {
+ try
+ {
+ await _productService.DeleteAsync(id);
+ return Success(new object(), "删除商品成功");
+ }
+ catch (BusinessException ex)
+ {
+ _logger.LogWarning(ex, "删除商品业务异常: {Message}", ex.Message);
+ return BaseResponse