refactor: 重构用户与商品模块,统一业务模型与服务

1.  新增用户状态枚举UserStatusEnum,统一用户状态定义
2.  重构用户体系:合并WxUser与User实体为Users实体,统一用户管理
3.  新增微信小程序认证相关服务与控制器,实现一键登录功能
4.  新增商品管理完整服务与控制器,修复商品表字段映射问题
5.  删除冗余的WxUser相关服务与控制器代码
6.  新增Newtonsoft.Json依赖用于微信接口响应解析
7.  清理无用的文件夹引用配置
This commit is contained in:
glz
2026-06-03 16:09:56 +08:00
parent 0a32754740
commit 32989e1fa0
22 changed files with 1200 additions and 491 deletions

View File

@ -0,0 +1,45 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
namespace QYZH.InteractiveMagazine.IService;
/// <summary>
/// 商品服务接口
/// </summary>
public interface IProductService : IBaseService<Product>
{
/// <summary>
/// 创建商品
/// </summary>
/// <param name="input">商品输入</param>
/// <returns>创建的商品信息</returns>
Task<ProductOutput> CreateAsync(ProductInput input);
/// <summary>
/// 更新商品
/// </summary>
/// <param name="id">商品ID</param>
/// <param name="input">商品输入</param>
/// <returns>更新后的商品信息</returns>
Task<ProductOutput> UpdateAsync(long id, ProductInput input);
/// <summary>
/// 删除商品(软删除)
/// </summary>
/// <param name="id">商品ID</param>
Task DeleteAsync(long id);
/// <summary>
/// 根据ID获取商品
/// </summary>
/// <param name="id">商品ID</param>
/// <returns>商品信息</returns>
Task<ProductOutput> GetByIdAsync(long id);
/// <summary>
/// 分页查询商品列表
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>分页结果</returns>
Task<PageListModel<ProductOutput>> GetListAsync(ProductQueryInput input);
}

View File

@ -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<Users>
{
/// <summary>
/// 分页查询用户列表
/// </summary>
Task<BaseResponse<PageListModel<UsersOutput>>> GetListAsync(UsersQueryInput input);
/// <summary>
/// 获取用户详情
/// </summary>
Task<BaseResponse<UsersOutput>> GetDetailAsync(long id);
/// <summary>
/// 更新用户状态
/// </summary>
Task<BaseResponse> UpdateStatusAsync(long id, UpdateUserStatusInput input);
}

View File

@ -0,0 +1,17 @@
using QYZH.InteractiveMagazine.IService.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
namespace QYZH.InteractiveMagazine.IService;
/// <summary>
/// 微信小程序认证服务
/// </summary>
public interface IWeChatAuthService : IBaseService<Users>
{
/// <summary>
/// 微信小程序一键登录
/// </summary>
/// <param name="input">登录输入(含微信 code</param>
/// <returns>登录结果(含 Token 和用户信息)</returns>
Task<WeChatLoginOutput> LoginAsync(WeChatLoginInput input);
}

View File

@ -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<WxUser>
{
/// <summary>
/// 创建微信用户
/// </summary>
Task<WxUserOutput> CreateAsync(WxUserInput input);
/// <summary>
/// 更新微信用户
/// </summary>
Task<WxUserOutput> UpdateAsync(long id, WxUserInput input);
/// <summary>
/// 删除微信用户(软删除)
/// </summary>
Task DeleteAsync(long id);
/// <summary>
/// 根据ID获取微信用户
/// </summary>
Task<WxUserOutput> GetByIdAsync(long id);
/// <summary>
/// 分页查询微信用户列表
/// </summary>
Task<PageListModel<WxUserOutput>> GetListAsync(WxUserQueryInput input);
}

View File

@ -0,0 +1,156 @@
using QYZH.InteractiveMagazine.Models.Dto;
namespace QYZH.InteractiveMagazine.Models.Dto;
/// <summary>
/// 商品创建/更新输入
/// </summary>
public class ProductInput
{
/// <summary>
/// 商品名称
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 商品图片
/// </summary>
public string? ImageUrl { get; set; }
/// <summary>
/// 所需积分
/// </summary>
public int Price { get; set; }
/// <summary>
/// 商品类型: MakeUpCard, PetBg
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// 售卖状态: OnSale, OffSale
/// </summary>
public string SaleStatus { get; set; } = "OnSale";
/// <summary>
/// 扩展数据
/// </summary>
public string? MetaData { get; set; }
/// <summary>
/// 是否上架
/// </summary>
public bool IsActive { get; set; } = true;
/// <summary>
/// 库存(-1无限)
/// </summary>
public int Stock { get; set; } = -1;
}
/// <summary>
/// 商品输出
/// </summary>
public class ProductOutput
{
/// <summary>
/// 主键ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 商品名称
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 商品图片
/// </summary>
public string? ImageUrl { get; set; }
/// <summary>
/// 所需积分
/// </summary>
public int Price { get; set; }
/// <summary>
/// 商品类型
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// 售卖状态
/// </summary>
public string SaleStatus { get; set; } = string.Empty;
/// <summary>
/// 扩展数据
/// </summary>
public string? MetaData { get; set; }
/// <summary>
/// 是否上架
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// 库存(-1无限)
/// </summary>
public int Stock { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string? CreatedBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 更新人
/// </summary>
public string? UpdatedBy { get; set; }
/// <summary>
/// 更新时间
/// </summary>
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// 商品分页查询输入
/// </summary>
public class ProductQueryInput : PageQueryModel
{
/// <summary>
/// 商品名称(模糊查询)
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 商品类型
/// </summary>
public string? Type { get; set; }
/// <summary>
/// 售卖状态: OnSale, OffSale
/// </summary>
public string? SaleStatus { get; set; }
/// <summary>
/// 是否上架
/// </summary>
public bool? IsActive { get; set; }
}

View File

@ -0,0 +1,71 @@
using QYZH.InteractiveMagazine.Models.Dto;
namespace QYZH.InteractiveMagazine.IService.Dto;
/// <summary>
/// Users查询输入DTO
/// </summary>
public class UsersQueryInput : PageQueryModel
{
/// <summary>
/// 微信用户ID
/// </summary>
public string? WxUserId { get; set; }
}
/// <summary>
/// Users输出DTO (基本信息)
/// </summary>
public class UsersOutput
{
/// <summary>
/// 主键ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 微信用户ID
/// </summary>
public string WxUserId { get; set; } = string.Empty;
/// <summary>
/// 昵称
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 头像地址
/// </summary>
public string? AvatarUrl { get; set; }
/// <summary>
/// 积分余额
/// </summary>
public int Points { get; set; }
/// <summary>
/// 用户类型
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// 状态
/// </summary>
public string Status { get; set; } = string.Empty;
/// <summary>
/// 当前成长值
/// </summary>
public int GrowthPoints { get; set; }
}
/// <summary>
/// 更新用户状态输入DTO
/// </summary>
public class UpdateUserStatusInput
{
/// <summary>
/// 用户状态: 1-启用, 2-冻结
/// </summary>
public int Status { get; set; }
}

View File

@ -1,7 +1,19 @@
using QYZH.InteractiveMagazine.Models.Dto;
using Newtonsoft.Json;
namespace QYZH.InteractiveMagazine.IService.Dto;
/// <summary>
/// 微信小程序登录输入
/// </summary>
public class WeChatLoginInput
{
/// <summary>
/// 微信登录凭证wx.login 获取的 code
/// </summary>
public string Code { get; set; } = string.Empty;
}
/// <summary>
/// 微信登录输出
/// </summary>
@ -177,3 +189,39 @@ public class WxUserQueryInput : PageQueryModel
}
/// <summary>
/// 微信 code2session 接口响应
/// </summary>
public class WxCode2SessionResponse
{
/// <summary>
/// 用户唯一标识
/// </summary>
[JsonProperty("openid")]
public string? OpenId { get; set; }
/// <summary>
/// 会话密钥
/// </summary>
[JsonProperty("session_key")]
public string? SessionKey { get; set; }
/// <summary>
/// 用户统一标识(在开放平台绑定了多个应用时使用)
/// </summary>
[JsonProperty("unionid")]
public string? UnionId { get; set; }
/// <summary>
/// 错误码
/// </summary>
[JsonProperty("errcode")]
public int ErrCode { get; set; }
/// <summary>
/// 错误信息
/// </summary>
[JsonProperty("errmsg")]
public string? ErrMsg { get; set; }
}

View File

@ -49,11 +49,12 @@ namespace QYZH.InteractiveMagazine.Models.Entity
public string Type {get;set;}
/// <summary>
/// Desc:状态: OnSale, OffSale
/// Desc:售卖状态: OnSale, OffSale
/// Default:OnSale
/// Nullable:False
/// </summary>
public string Status {get;set;}
[SugarColumn(ColumnName = "SaleStatus")]
public string SaleStatus {get;set;}
/// <summary>
/// Desc:扩展数据

View File

@ -1,58 +0,0 @@
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity
{
///<summary>
///用户表
///</summary>
[SugarTable("User")]
public partial class User : SqlSugarBaseEntity
{
/// <summary>
/// Desc:微信用户ID
/// Default:
/// Nullable:True
/// </summary>
public string WxUserId { get; set; }
/// <summary>
/// Desc:昵称
/// Default:
/// Nullable:True
/// </summary>
public string Name { get; set; }
/// <summary>
/// Desc:当前成长值
/// Default:0
/// Nullable:False
/// </summary>
public int GrowthPoints { get; set; }
/// <summary>
/// Desc:头像地址
/// Default:
/// Nullable:True
/// </summary>
public string AvatarUrl { get; set; }
/// <summary>
/// Desc:积分余额
/// Default:0
/// Nullable:False
/// </summary>
public int Points { get; set; }
/// <summary>
/// Desc:用户类型: Normal, VIP
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
/// <summary>
/// Desc:状态: Active, Disabled
/// Default:Active
/// Nullable:False
/// </summary>
public string Status { get; set; }
}
}

View File

@ -5,44 +5,34 @@ namespace QYZH.InteractiveMagazine.Models.Entity
///<summary>
///用户表
///</summary>
[SugarTable("WxUser")]
public partial class WxUser : SqlSugarBaseEntity
[SugarTable("Users")]
public partial class Users : SqlSugarBaseEntity
{
/// <summary>
/// Desc:微信OpenId
/// Default:
/// Nullable:False
/// </summary>
public string OpenId { get; set; }
/// <summary>
/// Desc:微信UnionId
/// Default:
/// Nullable:True
/// </summary>
public string UnionId { get; set; }
/// <summary>
/// Desc:昵称
/// Default:
/// Nullable:True
/// </summary>
public string NickName { get; set; }
public string Name { get; set; }
/// <summary>
/// Desc:当前成长值
/// Default:0
/// Nullable:False
/// </summary>
public int GrowthPoints { get; set; }
/// <summary>
/// Desc:头像地址
/// Default:
/// Nullable:True
/// </summary>
public string AvatarUrl { get; set; }
/// <summary>
/// Desc:手机号
/// Default:
/// Nullable:True
/// Desc:积分余额
/// Default:0
/// Nullable:False
/// </summary>
public string Phone { get; set; }
public int Points { get; set; }
/// <summary>
/// Desc:用户类型: Normal, VIP
@ -57,12 +47,25 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Nullable:False
/// </summary>
public string Status { get; set; }
/// <summary>
/// Desc:密码默认手机后4位
/// Default:Active
/// Desc:微信OpenId
/// Default:
/// Nullable:False
/// </summary>
public string Pwd { get; set; }
public string OpenId { get; set; }
/// <summary>
/// Desc:微信UnionId
/// Default:
/// Nullable:True
/// </summary>
public string UnionId { get; set; }
/// <summary>
/// Desc:手机号
/// Default:
/// Nullable:True
/// </summary>
public string Phone { get; set; }
}
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户状态枚举
/// </summary>
public enum UserStatusEnum
{
/// <summary>
/// 启用
/// </summary>
Active = 1,
/// <summary>
/// 冻结
/// </summary>
Frozen = 2
}

View File

@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Mapster" Version="7.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.166" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup>

View File

@ -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;
/// <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 = 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
};
}
/// <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 = 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
};
}
/// <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,
SaleStatus = product.SaleStatus,
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 == 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<ProductOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
}
}

View File

@ -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<Users> usersRepository, ILogger<UsersService> _logger) : BaseRepository<Users>, IUsersService
{
/// <summary>
/// 分页查询用户列表
/// </summary>
public async Task<BaseResponse<PageListModel<UsersOutput>>> GetListAsync(UsersQueryInput input)
{
var page = Queryable()
.WhereIF(!string.IsNullOrEmpty(input.WxUserId), u => u.OpenId == input.WxUserId)
.OrderBy(u => u.Id, OrderByType.Desc)
.ToPage<Users, UsersOutput>(input);
return BaseResponse<PageListModel<UsersOutput>>.Success(page);
}
/// <summary>
/// 获取用户详情
/// </summary>
public async Task<BaseResponse<UsersOutput>> GetDetailAsync(long id)
{
var user = await GetByIdAsync<UsersOutput>(u => u.Id == id);
if (user == null)
{
return BaseResponse<UsersOutput>.Fail("用户不存在");
}
return BaseResponse<UsersOutput>.Success(user);
}
/// <summary>
/// 更新用户状态
/// </summary>
public async Task<BaseResponse> 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("更新失败");
}
}

View File

@ -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;
/// <summary>
/// 微信小程序认证服务实现
/// </summary>
public class WeChatAuthService(BaseRepository<Users> usersRepository, IConfiguration configuration, ILogger<WeChatAuthService> logger) : BaseRepository<Users>, 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";
/// <summary>
/// 微信小程序一键登录
/// </summary>
/// <param name="input">登录输入(含微信 code</param>
/// <returns>登录结果(含 Token 和用户信息)</returns>
public async Task<WeChatLoginOutput> 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
};
}
/// <summary>
/// 调用微信 code2session 接口
/// </summary>
private async Task<WxCode2SessionResponse?> CallCode2SessionAsync(WeChatSettings settings, string code)
{
var url = string.Format(Code2SessionUrl, settings.AppId, settings.AppSecret, code);
try
{
return await HttpHelper.GetAsync<WxCode2SessionResponse>(url);
}
catch (Exception ex)
{
logger.LogError(ex, "调用微信 code2session 接口异常URL: {Url}", url);
throw new BusinessException("微信服务请求失败,请稍后重试", 500);
}
}
/// <summary>
/// 获取微信配置
/// </summary>
private WeChatSettings GetWeChatSettings()
{
var settings = configuration.GetSection("WeChatSettings").Get<WeChatSettings>();
if (settings == null || string.IsNullOrWhiteSpace(settings.AppId) || string.IsNullOrWhiteSpace(settings.AppSecret))
{
logger.LogError("微信配置不完整,请检查 appsettings.json 中的 WeChatSettings 节点");
throw new BusinessException("微信配置不完整,请联系系统管理员", 500);
}
return settings;
}
/// <summary>
/// 获取 JWT 配置
/// </summary>
private JwtSettings GetJwtSettings()
{
var jwtSettings = configuration.GetSection("JwtSettings").Get<JwtSettings>()
?? 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;
}
}

View File

@ -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<WxUser> wxUserRepository, ILogger<WxUserService> _logger) : BaseRepository<WxUser>, IWxUserService
{
public async Task<WxUserOutput> 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<WxUserOutput> 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<WxUserOutput> 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<PageListModel<WxUserOutput>> 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<int> 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<WxUserOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
}
}

View File

@ -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;
/// <summary>
/// 商品管理控制器
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiExplorerSettings(GroupName = nameof(ApiVersionEnum.Platform))]
public class ProductController : BaseController
{
private readonly IProductService _productService;
private readonly ILogger<ProductController> _logger;
public ProductController(IProductService productService, ILogger<ProductController> logger)
{
_productService = productService;
_logger = logger;
}
/// <summary>
/// 创建商品
/// </summary>
/// <param name="input">商品信息</param>
/// <returns>创建的商品信息</returns>
[HttpPost]
public async Task<BaseResponse<ProductOutput>> 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<ProductOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "创建商品系统异常,参数:{Input}", input);
return BaseResponse<ProductOutput>.Fail("创建商品失败,请稍后重试");
}
}
/// <summary>
/// 更新商品
/// </summary>
/// <param name="id">商品ID</param>
/// <param name="input">商品信息</param>
/// <returns>更新后的商品信息</returns>
[HttpPut("{id}")]
public async Task<BaseResponse<ProductOutput>> 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<ProductOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "更新商品系统异常ID{Id},参数:{Input}", id, input);
return BaseResponse<ProductOutput>.Fail("更新商品失败,请稍后重试");
}
}
/// <summary>
/// 删除商品
/// </summary>
/// <param name="id">商品ID</param>
/// <returns>操作结果</returns>
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
try
{
await _productService.DeleteAsync(id);
return Success(new object(), "删除商品成功");
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "删除商品业务异常: {Message}", ex.Message);
return BaseResponse<object>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "删除商品系统异常ID{Id}", id);
return BaseResponse<object>.Fail("删除商品失败,请稍后重试");
}
}
/// <summary>
/// 根据ID获取商品
/// </summary>
/// <param name="id">商品ID</param>
/// <returns>商品信息</returns>
[HttpGet("{id}")]
public async Task<BaseResponse<ProductOutput>> GetByIdAsync(long id)
{
try
{
var result = await _productService.GetByIdAsync(id);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "获取商品业务异常: {Message}", ex.Message);
return BaseResponse<ProductOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取商品系统异常ID{Id}", id);
return BaseResponse<ProductOutput>.Fail("获取商品信息失败,请稍后重试");
}
}
/// <summary>
/// 分页查询商品列表
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>分页结果</returns>
[HttpPost("list")]
public async Task<BaseResponse<PageListModel<ProductOutput>>> GetListAsync([FromBody] ProductQueryInput input)
{
try
{
var result = await _productService.GetListAsync(input);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "查询商品列表业务异常: {Message}", ex.Message);
return BaseResponse<PageListModel<ProductOutput>>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "查询商品列表系统异常,参数:{Input}", input);
return BaseResponse<PageListModel<ProductOutput>>.Fail("查询商品列表失败,请稍后重试");
}
}
}

View File

@ -0,0 +1,51 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.IService.Dto;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
namespace QYZH.InteractiveMagazine.WebApi.Controllers;
/// <summary>
/// 用户控制器
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class UsersController : BaseController
{
private readonly IUsersService _usersService;
private readonly ILogger<UsersController> _logger;
public UsersController(IUsersService usersService, ILogger<UsersController> logger)
{
_usersService = usersService;
_logger = logger;
}
/// <summary>
/// 获取用户列表(分页)
/// </summary>
[HttpGet]
public async Task<BaseResponse<PageListModel<UsersOutput>>> GetList([FromQuery] UsersQueryInput input)
{
return await _usersService.GetListAsync(input);
}
/// <summary>
/// 获取用户详情
/// </summary>
[HttpGet("{id}")]
public async Task<BaseResponse<UsersOutput>> GetDetail(long id)
{
return await _usersService.GetDetailAsync(id);
}
/// <summary>
/// 更新用户状态
/// </summary>
[HttpPut("{id}/status")]
public async Task<BaseResponse> UpdateStatus(long id, [FromBody] UpdateUserStatusInput input)
{
return await _usersService.UpdateStatusAsync(id, input);
}
}

View File

@ -0,0 +1,49 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.IService.Dto;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
namespace QYZH.InteractiveMagazine.WebApi.Controllers.WeChat;
/// <summary>
/// 微信小程序认证控制器
/// </summary>
public class WeChatAuthController : WeChatBaseController
{
private readonly IWeChatAuthService _weChatAuthService;
private readonly ILogger<WeChatAuthController> _logger;
public WeChatAuthController(IWeChatAuthService weChatAuthService, ILogger<WeChatAuthController> logger)
{
_weChatAuthService = weChatAuthService;
_logger = logger;
}
/// <summary>
/// 微信小程序一键登录
/// </summary>
/// <param name="input">登录输入(含微信 code</param>
/// <returns>登录结果(含 Token 和用户信息)</returns>
[AllowAnonymous]
[HttpPost("login")]
public async Task<BaseResponse<WeChatLoginOutput>> LoginAsync([FromBody] WeChatLoginInput input)
{
try
{
var result = await _weChatAuthService.LoginAsync(input);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "微信登录业务异常: {Message}", ex.Message);
return BaseResponse<WeChatLoginOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "微信登录系统异常");
return BaseResponse<WeChatLoginOutput>.Fail("微信登录失败,请稍后重试");
}
}
}

View File

@ -0,0 +1,63 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Enum;
using System.Security.Claims;
namespace QYZH.InteractiveMagazine.WebApi.Controllers.WeChat;
/// <summary>
/// 小程序基础控制器
/// </summary>
[Authorize]
[ApiController]
[Route("api/[controller]")]
[ApiExplorerSettings(GroupName = nameof(ApiVersionEnum.Wechat))]
public abstract class WeChatBaseController : ControllerBase
{
/// <summary>
/// 获取当前用户ID
/// </summary>
/// <returns>用户ID</returns>
protected long? GetCurrentUserId()
{
var userIdClaim = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
if (userIdClaim != null && long.TryParse(userIdClaim.Value, out var userId))
{
return userId;
}
return null;
}
/// <summary>
/// 获取当前用户名
/// </summary>
/// <returns>用户名</returns>
protected string? GetCurrentUserName()
{
return User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
}
/// <summary>
/// 成功响应
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="data">数据</param>
/// <param name="message">提示信息</param>
/// <returns>统一响应对象</returns>
protected BaseResponse<T> Success<T>(T data, string message = "操作成功")
{
return BaseResponse<T>.Success(data, message);
}
/// <summary>
/// 失败响应
/// </summary>
/// <param name="message">提示信息</param>
/// <param name="code">状态码</param>
/// <returns>统一响应对象</returns>
protected BaseResponse<object> Fail(string message, int code = 500)
{
return BaseResponse<object>.Fail(ResultCode.GLOBAL_ERROR, message);
}
}

View File

@ -1,147 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.IService.Dto;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
namespace QYZH.InteractiveMagazine.WebApi.Controllers;
/// <summary>
/// 微信用户控制器
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class WxUserController : BaseController
{
private readonly IWxUserService _wxUserService;
private readonly ILogger<WxUserController> _logger;
public WxUserController(IWxUserService wxUserService, ILogger<WxUserController> logger)
{
_wxUserService = wxUserService;
_logger = logger;
}
/// <summary>
/// 创建微信用户
/// </summary>
/// <param name="input">创建微信用户输入参数</param>
/// <returns>创建的微信用户输出参数</returns>
[HttpPost("users")]
public async Task<BaseResponse<WxUserOutput>> CreateUserAsync([FromBody] WxUserInput input)
{
try
{
var result = await _wxUserService.CreateAsync(input);
return Success(result, "创建微信用户成功");
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "创建微信用户业务异常: {Message}", ex.Message);
return BaseResponse<WxUserOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "创建微信用户系统异常,参数:{Input}", input);
return BaseResponse<WxUserOutput>.Fail("创建微信用户失败,请稍后重试");
}
}
/// <summary>
/// 更新微信用户
/// </summary>
/// <param name="id">微信用户ID</param>
/// <param name="input">更新微信用户输入参数</param>
/// <returns>更新的微信用户输出参数</returns>
[HttpPut("users/{id}")]
public async Task<BaseResponse<WxUserOutput>> UpdateUserAsync(long id, [FromBody] WxUserInput input)
{
try
{
var result = await _wxUserService.UpdateAsync(id, input);
return Success(result, "更新微信用户成功");
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "更新微信用户业务异常: {Message}", ex.Message);
return BaseResponse<WxUserOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "更新微信用户系统异常ID{Id},参数:{Input}", id, input);
return BaseResponse<WxUserOutput>.Fail("更新微信用户失败,请稍后重试");
}
}
/// <summary>
/// 删除微信用户
/// </summary>
/// <param name="id">微信用户ID</param>
/// <returns>删除的微信用户输出参数</returns>
[HttpDelete("users/{id}")]
public async Task<BaseResponse<object>> DeleteUserAsync(long id)
{
try
{
await _wxUserService.DeleteAsync(id);
return Success(new object(), "删除微信用户成功");
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "删除微信用户业务异常: {Message}", ex.Message);
return BaseResponse<object>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "删除微信用户系统异常ID{Id}", id);
return BaseResponse<object>.Fail("删除微信用户失败,请稍后重试");
}
}
/// <summary>
/// 获取微信用户信息
/// </summary>
/// <param name="id">微信用户ID</param>
/// <returns>微信用户信息输出参数</returns>
[HttpGet("users/{id}")]
public async Task<BaseResponse<WxUserOutput>> GetUserByIdAsync(long id)
{
try
{
var result = await _wxUserService.GetByIdAsync(id);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "获取微信用户业务异常: {Message}", ex.Message);
return BaseResponse<WxUserOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取微信用户系统异常ID{Id}", id);
return BaseResponse<WxUserOutput>.Fail("获取微信用户信息失败,请稍后重试");
}
}
/// <summary>
/// 获取微信用户列表
/// </summary>
/// <param name="input">查询微信用户列表输入参数</param>
/// <returns>微信用户列表输出参数</returns>
[HttpPost("users/list")]
public async Task<BaseResponse<PageListModel<WxUserOutput>>> GetUsersListAsync([FromBody] WxUserQueryInput input)
{
try
{
var result = await _wxUserService.GetListAsync(input);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "查询微信用户列表业务异常: {Message}", ex.Message);
return BaseResponse<PageListModel<WxUserOutput>>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "查询微信用户列表系统异常,参数:{Input}", input);
return BaseResponse<PageListModel<WxUserOutput>>.Fail("查询微信用户列表失败,请稍后重试");
}
}
}

View File

@ -22,8 +22,5 @@
<ProjectReference Include="..\QYZH.InteractiveMagazine.Models\QYZH.InteractiveMagazine.Models.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\WeChat\" />
</ItemGroup>
</Project>