refactor: 重构项目基础架构与实体体系
- 替换原有自定义生命周期接口为通用基础服务体系 - 将所有实体基类替换为带雪花ID的SqlSugarBaseEntity - 迁移DTO到Models项目并统一管理 - 移除冗余的Repository层实现,改用通用基础服务 - 添加Yitter.IdGenerator雪花ID生成支持 - 重构SqlSugar数据库上下文与依赖注入配置 - 新增微信用户、用户勋章、背包等实体与配套服务 - 整理分页查询与结果封装类 - 优化WebApi控制器结构
This commit is contained in:
37
QYZH.InteractiveMagazine.Common/Helpers/JsonConverterUtil.cs
Normal file
37
QYZH.InteractiveMagazine.Common/Helpers/JsonConverterUtil.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.Common.Helpers
|
||||||
|
{
|
||||||
|
public class JsonConverterUtil
|
||||||
|
{
|
||||||
|
public class DateTimeNullConverter : JsonConverter<DateTime?>
|
||||||
|
{
|
||||||
|
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
=> string.IsNullOrEmpty(reader.GetString()) ? default : ParseDateTime(reader.GetString());
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
|
||||||
|
=> writer.WriteStringValue(value?.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DateTimeConverter : JsonConverter<DateTime>
|
||||||
|
{
|
||||||
|
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
var dateTime = ParseDateTime(reader.GetString());
|
||||||
|
return dateTime == null ? DateTime.MinValue : dateTime.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
|
||||||
|
=> writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime? ParseDateTime(string dateStr)
|
||||||
|
{
|
||||||
|
if (System.Text.RegularExpressions.Regex.IsMatch(dateStr, @"^\d{4}[/-]") && DateTime.TryParse(dateStr, null, System.Globalization.DateTimeStyles.AssumeLocal, out var dateVal))
|
||||||
|
return dateVal;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,93 +0,0 @@
|
|||||||
namespace QYZH.InteractiveMagazine.IService.Dto;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 登录输入
|
|
||||||
/// </summary>
|
|
||||||
public class LoginInput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 账号
|
|
||||||
/// </summary>
|
|
||||||
public string Account { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 密码
|
|
||||||
/// </summary>
|
|
||||||
public string Password { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册输入
|
|
||||||
/// </summary>
|
|
||||||
public class RegisterInput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 账号
|
|
||||||
/// </summary>
|
|
||||||
public string Account { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 密码
|
|
||||||
/// </summary>
|
|
||||||
public string Password { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户名
|
|
||||||
/// </summary>
|
|
||||||
public string UserName { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 登录输出
|
|
||||||
/// </summary>
|
|
||||||
public class LoginOutput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 访问令牌
|
|
||||||
/// </summary>
|
|
||||||
public string Token { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户ID
|
|
||||||
/// </summary>
|
|
||||||
public long UserId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户名
|
|
||||||
/// </summary>
|
|
||||||
public string UserName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 刷新令牌
|
|
||||||
/// </summary>
|
|
||||||
public string RefreshToken { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AdminLoginInput
|
|
||||||
{
|
|
||||||
public string UserName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string Password { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AdminLoginOutput
|
|
||||||
{
|
|
||||||
public string Token { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public long UserId { get; set; }
|
|
||||||
|
|
||||||
public string UserName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string Type { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AdminUserInfoOutput
|
|
||||||
{
|
|
||||||
public long UserId { get; set; }
|
|
||||||
|
|
||||||
public string UserName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string Type { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string Status { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
namespace QYZH.InteractiveMagazine.IService.Dto;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 微信登录输出
|
|
||||||
/// </summary>
|
|
||||||
public class WeChatLoginOutput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 访问令牌
|
|
||||||
/// </summary>
|
|
||||||
public string Token { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户ID
|
|
||||||
/// </summary>
|
|
||||||
public long UserId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户名
|
|
||||||
/// </summary>
|
|
||||||
public string UserName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 微信OpenId
|
|
||||||
/// </summary>
|
|
||||||
public string OpenId { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 微信手机号获取输出
|
|
||||||
/// </summary>
|
|
||||||
public class WeChatPhoneNumberOutput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 手机号
|
|
||||||
/// </summary>
|
|
||||||
public string PhoneNumber { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@ -1,8 +1,10 @@
|
|||||||
using QYZH.InteractiveMagazine.IService.Dto;
|
using QYZH.InteractiveMagazine.IService.Dto;
|
||||||
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.IService;
|
namespace QYZH.InteractiveMagazine.IService;
|
||||||
|
|
||||||
public interface IAdminAuthService
|
public interface IAdminAuthService : IBaseService<AdminUser>
|
||||||
{
|
{
|
||||||
Task<AdminLoginOutput> LoginAsync(AdminLoginInput input);
|
Task<AdminLoginOutput> LoginAsync(AdminLoginInput input);
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
using QYZH.InteractiveMagazine.IService.Dto;
|
using QYZH.InteractiveMagazine.IService.Dto;
|
||||||
using QYZH.InteractiveMagazine.Models.Dto;
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.IService;
|
namespace QYZH.InteractiveMagazine.IService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 管理员用户服务接口
|
/// 管理员用户服务接口
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAdminUserService
|
public interface IAdminUserService : IBaseService<AdminUser>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建管理员
|
/// 创建管理员
|
||||||
|
|||||||
@ -1,51 +1,39 @@
|
|||||||
using QYZH.InteractiveMagazine.Models.Dto;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.IService;
|
namespace QYZH.InteractiveMagazine.IService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 基础服务接口
|
/// 基础服务定义
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">实体类型</typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public interface IBaseService<T> where T : class, new()
|
public interface IBaseService<T> where T : class, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
Task<T> GetFirstAsync(Expression<Func<T, bool>> whereExpression);
|
||||||
/// 根据ID获取实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">实体ID</param>
|
|
||||||
/// <returns>实体对象</returns>
|
|
||||||
Task<T?> GetByIdAsync(long id);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取所有实体列表
|
/// 根据条件表达式查询单条数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>实体列表</returns>
|
/// <param name="expression">表达式</param>
|
||||||
Task<List<T>> GetListAsync();
|
/// <returns>泛型实体</returns>
|
||||||
|
Task<R> GetByIdAsync<R>(Expression<Func<T, bool>> expression) where R : class;
|
||||||
|
|
||||||
/// <summary>
|
Task<R> GetByExpressionAsync<R>(Expression<Func<T, bool>> expression) where R : class;
|
||||||
/// 获取分页列表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pageQuery">分页查询参数</param>
|
|
||||||
/// <returns>分页数据</returns>
|
|
||||||
Task<PageListModel<T>> GetPageListAsync(PageQueryModel pageQuery);
|
|
||||||
|
|
||||||
/// <summary>
|
Task<List<T2>> GetListByExpression<T2>(Expression<Func<T, bool>> expression) where T2 : class;
|
||||||
/// 新增实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">实体对象</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
Task<bool> InsertAsync(T entity);
|
|
||||||
|
|
||||||
/// <summary>
|
Task<bool> UpdateAsync(T updateObj);
|
||||||
/// 更新实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">实体对象</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
Task<bool> UpdateAsync(T entity);
|
|
||||||
|
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// 根据ID删除实体
|
///// 根据指定条件更新指定列 eg:Update(new SysUser(){ Status = 1 }, it => new { it.Status }, f => f.Userid == 1));
|
||||||
/// </summary>
|
///// 只更新Status列,条件是包含
|
||||||
/// <param name="id">实体ID</param>
|
///// </summary>
|
||||||
/// <returns>是否成功</returns>
|
///// <param name="entity">实体类</param>
|
||||||
Task<bool> DeleteByIdAsync(long id);
|
///// <param name="expression">要更新列的表达式</param>
|
||||||
|
///// <param name="where">where表达式</param>
|
||||||
|
///// <returns></returns>
|
||||||
|
//Task<bool> UpdateAsync(T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where);
|
||||||
|
|
||||||
|
Task<bool> UpdateAsync(Expression<Func<T, T>> columns, Expression<Func<T, bool>> whereExpression);
|
||||||
|
|
||||||
|
Task<bool> UpdateAsync(Expression<Func<T, bool>> columns, Expression<Func<T, bool>> where);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
namespace QYZH.InteractiveMagazine.IService;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 单例生命周期标记接口
|
|
||||||
/// </summary>
|
|
||||||
public interface ISingletonDependency
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 瞬时生命周期标记接口
|
|
||||||
/// </summary>
|
|
||||||
public interface ITransientDependency
|
|
||||||
{
|
|
||||||
}
|
|
||||||
33
QYZH.InteractiveMagazine.IService/IWxUserService.cs
Normal file
33
QYZH.InteractiveMagazine.IService/IWxUserService.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
@ -17,17 +17,8 @@ namespace QYZH.InteractiveMagazine.Infrastructure.Autofacs
|
|||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
protected override void Load(ContainerBuilder builder)
|
protected override void Load(ContainerBuilder builder)
|
||||||
{
|
{
|
||||||
//注册Repository(只注册接口,遵循依赖倒置原则)
|
|
||||||
builder.RegisterAssemblyTypes(GetAssemblyByName($"{_assemblyName}.Repository"))
|
|
||||||
.Where(t => t.Name.EndsWith("Repository") && !t.IsAbstract)
|
|
||||||
.AsImplementedInterfaces()
|
|
||||||
.InstancePerLifetimeScope();
|
|
||||||
|
|
||||||
//注册Service
|
//注册Service
|
||||||
builder.RegisterAssemblyTypes(GetAssemblyByName($"{_assemblyName}.Service"))
|
builder.RegisterAssemblyTypes(GetAssemblyByName($"{_assemblyName}.Service")).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();
|
||||||
.Where(t => t.Name.EndsWith("Service") && !t.IsAbstract)
|
|
||||||
.AsImplementedInterfaces()
|
|
||||||
.InstancePerLifetimeScope();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -0,0 +1,75 @@
|
|||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.Infrastructure.Context
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 应用程序上下文
|
||||||
|
/// </summary>
|
||||||
|
public static class ServiceContext
|
||||||
|
{
|
||||||
|
public static IServiceProvider ServiceProvider;
|
||||||
|
|
||||||
|
public static void UseServiceContext(this IApplicationBuilder applicationBuilder)
|
||||||
|
{
|
||||||
|
ServiceProvider = applicationBuilder.ApplicationServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UseServiceContext(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
ServiceProvider = services.BuildServiceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对象实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T GetService<T>()
|
||||||
|
{
|
||||||
|
return ServiceProvider.GetService<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取Scope对象实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T GetScopeService<T>()
|
||||||
|
{
|
||||||
|
var scope = ServiceProvider.CreateScope();
|
||||||
|
return scope.ServiceProvider.GetService<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对象实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T GetRequiredService<T>()
|
||||||
|
{
|
||||||
|
return ServiceProvider.GetRequiredService<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对象实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T GetOptionsMonitor<T>()
|
||||||
|
{
|
||||||
|
return ServiceProvider.GetService<IOptionsMonitor<T>>().CurrentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对象实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T GetOptions<T>() where T : class, new()
|
||||||
|
{
|
||||||
|
return ServiceProvider.GetService<IOptions<T>>().Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using QYZH.InteractiveMagazine.Models.Dto;
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.IService.Dto;
|
namespace QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 管理员创建/更新输入
|
/// 管理员创建/更新输入
|
||||||
40
QYZH.InteractiveMagazine.Models/Dto/Admin/AuthDto.cs
Normal file
40
QYZH.InteractiveMagazine.Models/Dto/Admin/AuthDto.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
namespace QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 管理员登录输入
|
||||||
|
/// </summary>
|
||||||
|
public class AdminLoginInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名
|
||||||
|
/// </summary>
|
||||||
|
public string UserName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码
|
||||||
|
/// </summary>
|
||||||
|
public string Password { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AdminLoginOutput
|
||||||
|
{
|
||||||
|
public string Token { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public long UserId { get; set; }
|
||||||
|
|
||||||
|
public string UserName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Type { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AdminUserInfoOutput
|
||||||
|
{
|
||||||
|
public long UserId { get; set; }
|
||||||
|
|
||||||
|
public string UserName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Type { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Status { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@ -1,33 +1,73 @@
|
|||||||
namespace QYZH.InteractiveMagazine.Models.Dto;
|
namespace QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分页输出
|
/// 通用分页信息类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">数据类型</typeparam>
|
|
||||||
public class PageListModel<T>
|
public class PageListModel<T>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 页码
|
/// 每页行数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int PageIndex { get; set; }
|
public int PageSize { get; set; } = 10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 每页条数
|
/// 当前页
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int PageSize { get; set; }
|
public int PageIndex { get; set; } = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 总记录数
|
/// 总记录数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long TotalCount { get; set; }
|
public int TotalNum { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 总页数
|
/// 总页数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)TotalCount / PageSize) : 0;
|
public int TotalPage
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (TotalNum > 0)
|
||||||
|
return TotalNum % PageSize == 0 ? TotalNum / PageSize : TotalNum / PageSize + 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> Result { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据列表
|
/// 额外数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<T>? List { get; set; }
|
public Dictionary<string, object> Extra { get; set; } = new Dictionary<string, object>();
|
||||||
|
/// <summary>
|
||||||
|
/// 是否有上一页
|
||||||
|
/// </summary>
|
||||||
|
public bool HasPrev
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return PageIndex > 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下一页是否可用
|
||||||
|
/// </summary>
|
||||||
|
public bool HasNext
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return TotalPage > PageIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageListModel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageListModel(List<T> result, int pageIndex, int pageSize, int totalNum)
|
||||||
|
{
|
||||||
|
PageIndex = pageIndex;
|
||||||
|
PageSize = pageSize;
|
||||||
|
TotalNum = totalNum;
|
||||||
|
Result = result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,57 @@
|
|||||||
namespace QYZH.InteractiveMagazine.Models.Dto;
|
namespace QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分页查询输入
|
/// 通用分页查询类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PageQueryModel
|
public class PageQueryModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 页码,默认1
|
///当前页
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int PageIndex { get; set; } = 1;
|
public int PageIndex { get; set; } = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 每页条数,默认10
|
///每页条数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int PageSize { get; set; } = 10;
|
public int PageSize { get; set; } = 10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 排序字段
|
/// 排序字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? SortField { get; set; }
|
public string Sort { get; set; } = string.Empty;
|
||||||
|
/// <summary>
|
||||||
|
/// 排序类型,前端传入的是"ascending","descending"
|
||||||
|
/// </summary>
|
||||||
|
public string SortType { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 排序方式(asc/desc)
|
/// 关键字
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? SortOrder { get; set; }
|
public string? KeyWord { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分页查询泛型类
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">查询参数类型</typeparam>
|
||||||
|
public class PageQueryModel<T> : PageQueryModel where T : class, new()
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 查询参数
|
||||||
|
/// </summary>
|
||||||
|
public T Params { get; set; } = new T();
|
||||||
|
|
||||||
|
public TP ConvertTo<TP>() where TP : class
|
||||||
|
{
|
||||||
|
if (Params != null)
|
||||||
|
{
|
||||||
|
return Params as TP;
|
||||||
|
}
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Start => (PageIndex - 1) * PageSize + 1;
|
||||||
|
|
||||||
|
public int End => PageIndex * PageSize;
|
||||||
}
|
}
|
||||||
|
|||||||
198
QYZH.InteractiveMagazine.Models/Dto/WeChat/WeChatDto.cs
Normal file
198
QYZH.InteractiveMagazine.Models/Dto/WeChat/WeChatDto.cs
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.IService.Dto;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信登录输出
|
||||||
|
/// </summary>
|
||||||
|
public class WeChatLoginOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 访问令牌
|
||||||
|
/// </summary>
|
||||||
|
public string Token { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户ID
|
||||||
|
/// </summary>
|
||||||
|
public long UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名
|
||||||
|
/// </summary>
|
||||||
|
public string UserName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信OpenId
|
||||||
|
/// </summary>
|
||||||
|
public string OpenId { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信用户创建/更新输入
|
||||||
|
/// </summary>
|
||||||
|
public class WxUserInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 微信OpenId
|
||||||
|
/// </summary>
|
||||||
|
public string OpenId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信UnionId
|
||||||
|
/// </summary>
|
||||||
|
public string? UnionId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 昵称
|
||||||
|
/// </summary>
|
||||||
|
public string? NickName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 头像地址
|
||||||
|
/// </summary>
|
||||||
|
public string? AvatarUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 手机号
|
||||||
|
/// </summary>
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 积分余额
|
||||||
|
/// </summary>
|
||||||
|
public int Points { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户类型: Normal, VIP
|
||||||
|
/// </summary>
|
||||||
|
public string Type { get; set; } = "Normal";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态: Active, Disabled
|
||||||
|
/// </summary>
|
||||||
|
public string Status { get; set; } = "Active";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码,默认手机后4位
|
||||||
|
/// </summary>
|
||||||
|
public string? Pwd { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前成长值
|
||||||
|
/// </summary>
|
||||||
|
public int GrowthPoints { get; set; } = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信用户输出
|
||||||
|
/// </summary>
|
||||||
|
public class WxUserOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键ID
|
||||||
|
/// </summary>
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信OpenId
|
||||||
|
/// </summary>
|
||||||
|
public string OpenId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信UnionId
|
||||||
|
/// </summary>
|
||||||
|
public string? UnionId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 昵称
|
||||||
|
/// </summary>
|
||||||
|
public string? NickName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 头像地址
|
||||||
|
/// </summary>
|
||||||
|
public string? AvatarUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 手机号
|
||||||
|
/// </summary>
|
||||||
|
public string? Phone { 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>
|
||||||
|
/// 创建人
|
||||||
|
/// </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 WxUserQueryInput : PageQueryModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 昵称(模糊查询)
|
||||||
|
/// </summary>
|
||||||
|
public string? NickName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 手机号(模糊查询)
|
||||||
|
/// </summary>
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户类型
|
||||||
|
/// </summary>
|
||||||
|
public string? Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态
|
||||||
|
/// </summary>
|
||||||
|
public string? Status { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信手机号获取输出
|
||||||
|
/// </summary>
|
||||||
|
public class WeChatPhoneNumberOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 手机号
|
||||||
|
/// </summary>
|
||||||
|
public string PhoneNumber { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@ -6,19 +6,12 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///后台管理员表
|
///后台管理员表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("AdminUser")]
|
[SugarTable("AdminUser")]
|
||||||
public partial class AdminUser : BaseEntity
|
public partial class AdminUser : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public AdminUser(){
|
public AdminUser(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:主键
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:False
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsPrimaryKey=true,IsIdentity=true)]
|
|
||||||
public new int Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:用户名
|
/// Desc:用户名
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
using SqlSugar;
|
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Models.Entity;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 基础实体类
|
|
||||||
/// </summary>
|
|
||||||
public abstract class BaseEntity
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 主键Id
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
|
||||||
public long Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否已删除
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsIgnore = false)]
|
|
||||||
public bool IsDeleted { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建人
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(Length = 50)]
|
|
||||||
public string? CreatedBy { get; set; } = "System";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建时间
|
|
||||||
/// </summary>
|
|
||||||
public DateTime CreatedAt { get; set; } = DateTime.Now;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新人
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(Length = 50)]
|
|
||||||
public string? UpdatedBy { get; set; } = "System";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新时间
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? UpdatedAt { get; set; } = DateTime.Now;
|
|
||||||
}
|
|
||||||
@ -6,19 +6,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///签到配置表
|
///签到配置表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("CheckInConfig")]
|
[SugarTable("CheckInConfig")]
|
||||||
public partial class CheckInConfig : BaseEntity
|
public partial class CheckInConfig : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public CheckInConfig(){
|
public CheckInConfig(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:主键
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:False
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsPrimaryKey=true,IsIdentity=true)]
|
|
||||||
public new int Id {get;set;}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:连续签到天数
|
/// Desc:连续签到天数
|
||||||
|
|||||||
@ -6,18 +6,18 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///签到记录表
|
///签到记录表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("CheckInRecord")]
|
[SugarTable("CheckInRecord")]
|
||||||
public partial class CheckInRecord : BaseEntity
|
public partial class CheckInRecord : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public CheckInRecord(){
|
public CheckInRecord(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:用户Id
|
/// Desc:用户Id
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long UserId {get;set;}
|
public long UserId {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:签到日期
|
/// Desc:签到日期
|
||||||
|
|||||||
@ -6,18 +6,19 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///社区预置消息表
|
///社区预置消息表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("CommunityMessage")]
|
[SugarTable("CommunityMessage")]
|
||||||
public partial class CommunityMessage : BaseEntity
|
public partial class CommunityMessage : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public CommunityMessage(){
|
public CommunityMessage(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:期刊Id
|
/// <summary>
|
||||||
/// Default:
|
/// Desc:期刊Id
|
||||||
/// Nullable:False
|
/// Default:
|
||||||
/// </summary>
|
/// Nullable:False
|
||||||
public long JournalId {get;set;}
|
/// </summary>
|
||||||
|
public long JournalId {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:消息内容
|
/// Desc:消息内容
|
||||||
|
|||||||
@ -6,18 +6,18 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///期刊表
|
///期刊表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("Journal")]
|
[SugarTable("Journal")]
|
||||||
public partial class Journal : BaseEntity
|
public partial class Journal : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public Journal(){
|
public Journal(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:期刊号
|
/// Desc:期刊号
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int IssueNumber {get;set;}
|
public int IssueNumber {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:期刊标题
|
/// Desc:期刊标题
|
||||||
|
|||||||
@ -6,74 +6,68 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///勋章定义表
|
///勋章定义表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("Medal")]
|
[SugarTable("Medal")]
|
||||||
public partial class Medal : BaseEntity
|
public partial class Medal : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public Medal(){
|
public Medal()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:主键
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:False
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsPrimaryKey=true,IsIdentity=true)]
|
|
||||||
public new int Id {get;set;}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:勋章名称
|
/// Desc:勋章名称
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name {get;set;}
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:获得条件描述
|
/// Desc:获得条件描述
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:True
|
/// Nullable:True
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Description {get;set;}
|
public string Description { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:图片地址
|
/// Desc:图片地址
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:True
|
/// Nullable:True
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ImageUrl {get;set;}
|
public string ImageUrl { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:条件类型: EvolutionCount, FeedingCount等
|
/// Desc:条件类型: EvolutionCount, FeedingCount等
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ConditionType {get;set;}
|
public string ConditionType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:条件阈值
|
/// Desc:条件阈值
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ConditionValue {get;set;}
|
public int ConditionValue { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:排序
|
/// Desc:排序
|
||||||
/// Default:0
|
/// Default:0
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int SortOrder {get;set;}
|
public int SortOrder { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:勋章的类型: Pet, Community
|
/// Desc:勋章的类型: Pet, Community
|
||||||
/// Default:Pet
|
/// Default:Pet
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Type {get;set;}
|
public string Type { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:状态: Active, Inactive
|
/// Desc:状态: Active, Inactive
|
||||||
/// Default:Active
|
/// Default:Active
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Status {get;set;}
|
public string Status { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,18 +6,19 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///模板评论表
|
///模板评论表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("MessageComment")]
|
[SugarTable("MessageComment")]
|
||||||
public partial class MessageComment : BaseEntity
|
public partial class MessageComment : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public MessageComment(){
|
public MessageComment(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:用户Id
|
/// <summary>
|
||||||
/// Default:
|
/// Desc:用户Id
|
||||||
/// Nullable:False
|
/// Default:
|
||||||
/// </summary>
|
/// Nullable:False
|
||||||
public long UserId {get;set;}
|
/// </summary>
|
||||||
|
public long UserId {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:消息Id
|
/// Desc:消息Id
|
||||||
|
|||||||
@ -6,18 +6,18 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///点赞记录表
|
///点赞记录表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("MessageLike")]
|
[SugarTable("MessageLike")]
|
||||||
public partial class MessageLike : BaseEntity
|
public partial class MessageLike : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public MessageLike(){
|
public MessageLike(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:用户Id
|
/// Desc:用户Id
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long UserId {get;set;}
|
public long UserId {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:消息Id
|
/// Desc:消息Id
|
||||||
|
|||||||
@ -6,18 +6,18 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///宠物实例表
|
///宠物实例表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("Pet")]
|
[SugarTable("Pet")]
|
||||||
public partial class Pet : BaseEntity
|
public partial class Pet : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public Pet(){
|
public Pet(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:用户Id
|
/// Desc:用户Id
|
||||||
/// Default:
|
/// Default:
|
||||||
/// Nullable:False
|
/// Nullable:False
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long UserId {get;set;}
|
public long UserId {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:宠物昵称
|
/// Desc:宠物昵称
|
||||||
|
|||||||
@ -6,19 +6,12 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///宠物进化链定义表
|
///宠物进化链定义表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("PetEvolution")]
|
[SugarTable("PetEvolution")]
|
||||||
public partial class PetEvolution : BaseEntity
|
public partial class PetEvolution : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public PetEvolution(){
|
public PetEvolution(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:主键
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:False
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsPrimaryKey=true,IsIdentity=true)]
|
|
||||||
public new int Id {get;set;}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:阶段名称
|
/// Desc:阶段名称
|
||||||
|
|||||||
@ -6,18 +6,19 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///宠物喂养记录表
|
///宠物喂养记录表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("PetFeedingRecord")]
|
[SugarTable("PetFeedingRecord")]
|
||||||
public partial class PetFeedingRecord : BaseEntity
|
public partial class PetFeedingRecord : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public PetFeedingRecord(){
|
public PetFeedingRecord(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:宠物Id
|
/// <summary>
|
||||||
/// Default:
|
/// Desc:宠物Id
|
||||||
/// Nullable:False
|
/// Default:
|
||||||
/// </summary>
|
/// Nullable:False
|
||||||
public long PetId {get;set;}
|
/// </summary>
|
||||||
|
public long PetId {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:用户Id
|
/// Desc:用户Id
|
||||||
|
|||||||
@ -6,18 +6,19 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///积分流水记录表
|
///积分流水记录表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("PointsRecord")]
|
[SugarTable("PointsRecord")]
|
||||||
public partial class PointsRecord : BaseEntity
|
public partial class PointsRecord : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public PointsRecord(){
|
public PointsRecord(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:用户Id
|
/// <summary>
|
||||||
/// Default:
|
/// Desc:用户Id
|
||||||
/// Nullable:False
|
/// Default:
|
||||||
/// </summary>
|
/// Nullable:False
|
||||||
public long UserId {get;set;}
|
/// </summary>
|
||||||
|
public long UserId {get;set;}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:变动数值
|
/// Desc:变动数值
|
||||||
|
|||||||
@ -6,19 +6,12 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///虚拟商品表
|
///虚拟商品表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("Product")]
|
[SugarTable("Product")]
|
||||||
public partial class Product : BaseEntity
|
public partial class Product : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public Product(){
|
public Product(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:主键
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:False
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsPrimaryKey=true,IsIdentity=true)]
|
|
||||||
public new int Id {get;set;}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:商品名称
|
/// Desc:商品名称
|
||||||
|
|||||||
63
QYZH.InteractiveMagazine.Models/Entity/SqlSugarBaseEntity.cs
Normal file
63
QYZH.InteractiveMagazine.Models/Entity/SqlSugarBaseEntity.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using SqlSugar;
|
||||||
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.Models.Entity
|
||||||
|
{
|
||||||
|
public class SqlSugarBaseEntity
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:主键
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
public long Id { get; set; } = YitIdHelper.NextId();
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:状态 0禁用 1启用
|
||||||
|
/// Default:1
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "Status")]
|
||||||
|
public string Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:是否删除
|
||||||
|
/// Default:b'0'
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "IsDeleted")]
|
||||||
|
public bool IsDeleted { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:创建人
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "CreatedBy", IsOnlyIgnoreUpdate = true)]
|
||||||
|
public string CreatedBy { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:创建时间
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "CreatedAt", IsOnlyIgnoreUpdate = true)]
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:修改人
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:True
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "updatedBy", IsOnlyIgnoreInsert = true)]
|
||||||
|
public string UpdatedBy { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:修改时间
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:True
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "UpdatedAt", IsOnlyIgnoreInsert = true)]
|
||||||
|
public DateTime? UpdatedAt { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,19 +6,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///固定模板言论表
|
///固定模板言论表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("TemplateSentence")]
|
[SugarTable("TemplateSentence")]
|
||||||
public partial class TemplateSentence : BaseEntity
|
public partial class TemplateSentence : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public TemplateSentence(){
|
public TemplateSentence(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Desc:主键
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:False
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(IsPrimaryKey=true,IsIdentity=true)]
|
|
||||||
public new int Id {get;set;}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:模板内容
|
/// Desc:模板内容
|
||||||
|
|||||||
@ -1,71 +0,0 @@
|
|||||||
using SqlSugar;
|
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Models.Entity
|
|
||||||
{
|
|
||||||
///<summary>
|
|
||||||
///用户表
|
|
||||||
///</summary>
|
|
||||||
[SugarTable("User")]
|
|
||||||
public partial class User : BaseEntity
|
|
||||||
{
|
|
||||||
public User(){
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <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;}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Desc:头像地址
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:True
|
|
||||||
/// </summary>
|
|
||||||
public string AvatarUrl {get;set;}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Desc:手机号
|
|
||||||
/// Default:
|
|
||||||
/// Nullable:True
|
|
||||||
/// </summary>
|
|
||||||
public string Phone {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;}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
80
QYZH.InteractiveMagazine.Models/Entity/WxUser.cs
Normal file
80
QYZH.InteractiveMagazine.Models/Entity/WxUser.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using SqlSugar;
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.Models.Entity
|
||||||
|
{
|
||||||
|
///<summary>
|
||||||
|
///用户表
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("WxUser")]
|
||||||
|
public partial class WxUser : 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; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:头像地址
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:True
|
||||||
|
/// </summary>
|
||||||
|
public string AvatarUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:手机号
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:True
|
||||||
|
/// </summary>
|
||||||
|
public string Phone { 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; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:密码,默认手机后4位
|
||||||
|
/// Default:Active
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
public string Pwd { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:当前成长值
|
||||||
|
/// Default:0
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
public int GrowthPoints { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,10 +5,10 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///<summary>
|
///<summary>
|
||||||
///用户背包表
|
///用户背包表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("UserBag")]
|
[SugarTable("WxUserBag")]
|
||||||
public partial class UserBag : BaseEntity
|
public partial class WxUserBag : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public UserBag(){
|
public WxUserBag(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5,10 +5,10 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
///<summary>
|
///<summary>
|
||||||
///用户勋章表
|
///用户勋章表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("UserMedal")]
|
[SugarTable("WxUserMedal")]
|
||||||
public partial class UserMedal : BaseEntity
|
public partial class WxUserMedal : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public UserMedal(){
|
public WxUserMedal(){
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -8,7 +8,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.166" />
|
<PackageReference Include="SqlSugarCore" Version="5.1.4.166" />
|
||||||
|
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Repository;
|
|
||||||
|
|
||||||
public class AdminUserRepository : BaseRepository<AdminUser>, IAdminUserRepository
|
|
||||||
{
|
|
||||||
public async Task<AdminUser?> GetByUserNameAsync(string userName)
|
|
||||||
{
|
|
||||||
return await Db.Queryable<AdminUser>()
|
|
||||||
.Where(x => x.UserName == userName)
|
|
||||||
.FirstAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,154 +1,293 @@
|
|||||||
|
using Mapster;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using QYZH.InteractiveMagazine.Infrastructure.Context;
|
||||||
using QYZH.InteractiveMagazine.Models.Dto;
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using SqlSugar.IOC;
|
||||||
|
using System.Data;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Repository;
|
|
||||||
|
|
||||||
/// <summary>
|
namespace QYZH.InteractiveMagazine.Repository
|
||||||
/// 基础仓储实现
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">实体类型</typeparam>
|
|
||||||
public class BaseRepository<T> : IBaseRepository<T> where T : class, new()
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SqlSugar 数据库实例
|
/// 数据仓库类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected SqlSugarClient Db => SqlSugarDbContext.GetDb();
|
/// <typeparam name="T"></typeparam>
|
||||||
|
public class BaseRepository<T> : SimpleClient<T> where T : class, new()
|
||||||
/// <summary>
|
|
||||||
/// 根据Id获取实体(自动过滤已删除数据)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">主键Id</param>
|
|
||||||
/// <returns>实体对象</returns>
|
|
||||||
public async Task<T?> GetByIdAsync(long id)
|
|
||||||
{
|
{
|
||||||
return await Db.Queryable<T>().In(id).FirstAsync();
|
private readonly ILogger<BaseRepository<T>> _logger;
|
||||||
}
|
public BaseRepository(ISqlSugarClient context = null) : base(context)
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有列表(自动过滤已删除数据)
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>实体列表</returns>
|
|
||||||
public async Task<List<T>> GetListAsync()
|
|
||||||
{
|
|
||||||
return await Db.Queryable<T>().ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据条件获取列表(自动过滤已删除数据)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="where">查询条件</param>
|
|
||||||
/// <returns>实体列表</returns>
|
|
||||||
public async Task<List<T>> GetListByWhereAsync(Expression<Func<T, bool>> where)
|
|
||||||
{
|
|
||||||
return await Db.Queryable<T>().Where(where).ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 分页查询(自动过滤已删除数据)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="where">查询条件</param>
|
|
||||||
/// <param name="pageQuery">分页参数</param>
|
|
||||||
/// <returns>分页结果</returns>
|
|
||||||
public async Task<PageListModel<T>> GetPageListAsync(Expression<Func<T, bool>> where, PageQueryModel pageQuery)
|
|
||||||
{
|
|
||||||
RefAsync<int> total = 0;
|
|
||||||
|
|
||||||
var query = Db.Queryable<T>().Where(where);
|
|
||||||
|
|
||||||
// 处理排序
|
|
||||||
if (!string.IsNullOrEmpty(pageQuery.SortField))
|
|
||||||
{
|
{
|
||||||
var isAsc = string.IsNullOrEmpty(pageQuery.SortOrder) ||
|
Context = DbScoped.SugarScope;
|
||||||
pageQuery.SortOrder.ToLower() == "asc";
|
_logger = ServiceContext.GetService<ILogger<BaseRepository<T>>>();
|
||||||
query = isAsc
|
|
||||||
? query.OrderBy($"{pageQuery.SortField} asc")
|
|
||||||
: query.OrderBy($"{pageQuery.SortField} desc");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var list = await query.ToPageListAsync(pageQuery.PageIndex, pageQuery.PageSize, total);
|
#region add
|
||||||
|
|
||||||
return new PageListModel<T>
|
public IInsertable<T> Insertable(T t)
|
||||||
{
|
{
|
||||||
PageIndex = pageQuery.PageIndex,
|
return Context.Insertable(t);
|
||||||
PageSize = pageQuery.PageSize,
|
}
|
||||||
TotalCount = total,
|
|
||||||
List = list
|
#endregion add
|
||||||
};
|
|
||||||
|
#region update
|
||||||
|
public IUpdateable<T> Updateable(T t)
|
||||||
|
{
|
||||||
|
return Context.Updateable(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUpdateable<T> Updateable()
|
||||||
|
{
|
||||||
|
return Context.Updateable<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUpdateable<T1> Updateable<T1>() where T1 : class, new()
|
||||||
|
{
|
||||||
|
return Context.Updateable<T1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据指定条件更新指定列 eg:Update(new SysUser(){ Status = 1 }, it => new { it.Status }, f => f.Userid == 1));
|
||||||
|
/// 只更新Status列,条件是包含
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">实体类</param>
|
||||||
|
/// <param name="expression">要更新列的表达式</param>
|
||||||
|
/// <param name="where">where表达式</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> UpdateAsync(Expression<Func<T, bool>> columns, Expression<Func<T, bool>> where)
|
||||||
|
{
|
||||||
|
return await Context.Updateable<T>().SetColumns(columns).Where(where).ExecuteCommandAsync() > 0;
|
||||||
|
}
|
||||||
|
#endregion update
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 事务 异步 无返回值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task UseTranAsync(Func<Task> action)
|
||||||
|
{
|
||||||
|
Context.Ado.BeginTran();//using不能少
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
Context.Ado.CommitTran();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Context.Ado.RollbackTran();
|
||||||
|
_logger.LogError($"UseTran 异常:{ex.StackTrace},{ex.Message}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 事务 异步 返回bool
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> UseTranAsync(Func<Task<bool>> action)
|
||||||
|
{
|
||||||
|
Context.Ado.BeginTran();//using不能少
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await action();
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
Context.Ado.CommitTran();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Context.Ado.RollbackTran();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Context.Ado.RollbackTran();
|
||||||
|
_logger.LogError($"UseTran 异常:{ex.StackTrace},{ex.Message}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region delete
|
||||||
|
public IDeleteable<T> Deleteable()
|
||||||
|
{
|
||||||
|
return Context.Deleteable<T>();
|
||||||
|
}
|
||||||
|
#endregion delete
|
||||||
|
|
||||||
|
#region query
|
||||||
|
|
||||||
|
public bool Any(Expression<Func<T, bool>> expression)
|
||||||
|
{
|
||||||
|
return Context.Queryable<T>().Any(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISugarQueryable<T> Queryable()
|
||||||
|
{
|
||||||
|
return Context.Queryable<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISugarQueryable<T1> Queryable<T1>()
|
||||||
|
{
|
||||||
|
return Context.Queryable<T1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据条件表达式查询单条数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="expression">表达式</param>
|
||||||
|
/// <returns>泛型实体</returns>
|
||||||
|
public Task<R> GetByIdAsync<R>(Expression<Func<T, bool>> expression) where R : class
|
||||||
|
{
|
||||||
|
return Context.Queryable<T>().Where(expression).Select<R>().FirstAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<R> GetByExpressionAsync<R>(Expression<Func<T, bool>> expression) where R : class
|
||||||
|
{
|
||||||
|
return Context.Queryable<T>().Where(expression).Select<R>().FirstAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<List<T2>> GetListByExpression<T2>(Expression<Func<T, bool>> expression) where T2 : class
|
||||||
|
{
|
||||||
|
return Context.Queryable<T>().Where(expression).Select<T2>().ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据条件查询分页数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="where"></param>
|
||||||
|
/// <param name="parm"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public PageListModel<T> GetPages(Expression<Func<T, bool>> where, PageQueryModel parm)
|
||||||
|
{
|
||||||
|
var source = Context.Queryable<T>().Where(where);
|
||||||
|
|
||||||
|
return source.ToPage(parm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分页获取数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="where">条件表达式</param>
|
||||||
|
/// <param name="parm"></param>
|
||||||
|
/// <param name="order"></param>
|
||||||
|
/// <param name="orderEnum"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public PageListModel<T> GetPages(Expression<Func<T, bool>> where, PageQueryModel parm, Expression<Func<T, object>> order, OrderByType orderEnum = OrderByType.Asc)
|
||||||
|
{
|
||||||
|
var source = Context
|
||||||
|
.Queryable<T>()
|
||||||
|
.Where(where)
|
||||||
|
.OrderByIF(orderEnum == OrderByType.Asc, order, OrderByType.Asc)
|
||||||
|
.OrderByIF(orderEnum == OrderByType.Desc, order, OrderByType.Desc);
|
||||||
|
|
||||||
|
return source.ToPage(parm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageListModel<T> GetPages(Expression<Func<T, bool>> where, PageQueryModel parm, Expression<Func<T, object>> order, string orderByType)
|
||||||
|
{
|
||||||
|
return GetPages(where, parm, order, orderByType == "desc" ? OrderByType.Desc : OrderByType.Asc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询所有数据(无分页,请慎用)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<T> GetAll(bool useCache = false, int cacheSecond = 3600)
|
||||||
|
{
|
||||||
|
return Context.Queryable<T>().WithCacheIF(useCache, cacheSecond).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion query
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 此方法不带output返回值
|
||||||
|
/// var list = new List<SugarParameter>();
|
||||||
|
/// list.Add(new SugarParameter(ParaName, ParaValue)); input
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="procedureName"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public DataTable UseStoredProcedureToDataTable(string procedureName, List<SugarParameter> parameters)
|
||||||
|
{
|
||||||
|
return Context.Ado.UseStoredProcedure().GetDataTable(procedureName, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 带output返回值
|
||||||
|
/// var list = new List<SugarParameter>();
|
||||||
|
/// list.Add(new SugarParameter(ParaName, ParaValue, true)); output
|
||||||
|
/// list.Add(new SugarParameter(ParaName, ParaValue)); input
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="procedureName"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public (DataTable, List<SugarParameter>) UseStoredProcedureToTuple(string procedureName, List<SugarParameter> parameters)
|
||||||
|
{
|
||||||
|
var result = (Context.Ado.UseStoredProcedure().GetDataTable(procedureName, parameters), parameters);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 插入单条记录
|
/// 分页查询扩展
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">实体对象</param>
|
public static class QueryableExtension
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> InsertAsync(T entity)
|
|
||||||
{
|
{
|
||||||
return await Db.Insertable(entity).ExecuteCommandAsync() > 0;
|
/// <summary>
|
||||||
}
|
/// 读取列表
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="source">查询表单式</param>
|
||||||
|
/// <param name="parm">分页参数</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static PageListModel<T> ToPage<T>(this ISugarQueryable<T> source, PageQueryModel parm)
|
||||||
|
{
|
||||||
|
var page = new PageListModel<T>();
|
||||||
|
var total = 0;
|
||||||
|
page.PageSize = parm.PageSize;
|
||||||
|
page.PageIndex = parm.PageIndex;
|
||||||
|
if (string.IsNullOrEmpty(parm.Sort))
|
||||||
|
{
|
||||||
|
source.OrderByPropertyName(parm.Sort, parm.SortType.Contains("desc") ? OrderByType.Desc : OrderByType.Asc);
|
||||||
|
}
|
||||||
|
page.Result = source
|
||||||
|
//.OrderByIF(parm.Sort.IsNotEmpty(), $"{parm.Sort.ToSqlFilter()} {(!string.IsNullOrWhiteSpace(parm.SortType) && parm.SortType.Contains("desc") ? "desc" : "asc")}")
|
||||||
|
.ToPageList(parm.PageIndex, parm.PageSize, ref total);
|
||||||
|
page.TotalNum = total;
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 批量插入记录
|
/// 转指定实体类Dto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">实体列表</param>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <returns>是否成功</returns>
|
/// <typeparam name="T2"></typeparam>
|
||||||
public async Task<bool> InsertRangeAsync(List<T> entities)
|
/// <param name="source"></param>
|
||||||
{
|
/// <param name="parm"></param>
|
||||||
return await Db.Insertable(entities).ExecuteCommandAsync() > 0;
|
/// <returns></returns>
|
||||||
}
|
public static PageListModel<T2> ToPage<T, T2>(this ISugarQueryable<T> source, PageQueryModel parm)
|
||||||
|
{
|
||||||
|
var page = new PageListModel<T2>();
|
||||||
|
var total = 0;
|
||||||
|
page.PageSize = parm.PageSize;
|
||||||
|
page.PageIndex = parm.PageIndex;
|
||||||
|
if (string.IsNullOrEmpty(parm.Sort))
|
||||||
|
{
|
||||||
|
source.OrderByPropertyName(parm.Sort, parm.SortType.Contains("desc") ? OrderByType.Desc : OrderByType.Asc);
|
||||||
|
}
|
||||||
|
var result = source
|
||||||
|
//.OrderByIF(parm.Sort.IsNotEmpty(), $"{parm.Sort.ToSqlFilter()} {(!string.IsNullOrWhiteSpace(parm.SortType) && parm.SortType.Contains("desc") ? "desc" : "asc")}")
|
||||||
|
.ToPageList(parm.PageIndex, parm.PageSize, ref total);
|
||||||
|
|
||||||
/// <summary>
|
page.TotalNum = total;
|
||||||
/// 更新单条记录
|
page.Result = result.Adapt<List<T2>>();
|
||||||
/// </summary>
|
return page;
|
||||||
/// <param name="entity">实体对象</param>
|
}
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> UpdateAsync(T entity)
|
|
||||||
{
|
|
||||||
return await Db.Updateable(entity).ExecuteCommandAsync() > 0;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
|
||||||
/// 批量更新记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entities">实体列表</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> UpdateRangeAsync(List<T> entities)
|
|
||||||
{
|
|
||||||
return await Db.Updateable(entities).ExecuteCommandAsync() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据Id删除记录(软删除,设置 IsDeleted = true)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">主键Id</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> DeleteByIdAsync(long id)
|
|
||||||
{
|
|
||||||
return await Db.Deleteable<T>().In(id).IsLogic().ExecuteCommandAsync() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据条件删除记录(软删除,设置 IsDeleted = true)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="where">删除条件</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> DeleteByWhereAsync(Expression<Func<T, bool>> where)
|
|
||||||
{
|
|
||||||
return await Db.Deleteable<T>().Where(where).IsLogic().ExecuteCommandAsync() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据条件获取记录数(自动过滤已删除数据)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="where">查询条件</param>
|
|
||||||
/// <returns>记录数</returns>
|
|
||||||
public async Task<int> GetCountAsync(Expression<Func<T, bool>> where)
|
|
||||||
{
|
|
||||||
return await Db.Queryable<T>().Where(where).CountAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ISugarQueryable<T> Queryable()
|
|
||||||
{
|
|
||||||
return Db.Queryable<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
160
QYZH.InteractiveMagazine.Repository/Core/SqlSugarExtension.cs
Normal file
160
QYZH.InteractiveMagazine.Repository/Core/SqlSugarExtension.cs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
|
using SqlSugar;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.Repository.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// sql sugar 管理器
|
||||||
|
/// </summary>
|
||||||
|
public static class SqlSugarExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 生成类文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
/// <param name="directoryPath">生成路径</param>
|
||||||
|
/// <param name="nameSpace">名称空间</param>
|
||||||
|
public static ISqlSugarClient CreateClassFile(this ISqlSugarClient db, string directoryPath, string nameSpace = "Models")
|
||||||
|
{
|
||||||
|
foreach (var item in db.DbMaintenance.GetTableInfoList())
|
||||||
|
{
|
||||||
|
string[] entityNameArray = item.Name.Split('_', StringSplitOptions.RemoveEmptyEntries).ToArray();
|
||||||
|
string entityName = string.Join("", entityNameArray.Select(c => c.ToCamelCase()));
|
||||||
|
db.MappingTables.Add(entityName, item.Name);
|
||||||
|
foreach (var col in db.DbMaintenance.GetColumnInfosByTableName(item.Name))
|
||||||
|
{
|
||||||
|
var columnNames = col.DbColumnName.ToLower().Split('_', StringSplitOptions.RemoveEmptyEntries).ToArray();
|
||||||
|
string columnName = string.Join("", columnNames.Select(c => c.ToCamelCase()));
|
||||||
|
db.MappingColumns.Add(columnName, col.DbColumnName, entityName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.DbFirst.IsCreateAttribute().CreateClassFile(directoryPath, nameSpace);
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加全局过滤器
|
||||||
|
/// IsDeleted
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db">数据库Client</param>
|
||||||
|
/// <param name="assemblyName">程序集名称</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ISqlSugarClient SetQueryFilter(this ISqlSugarClient db, string assemblyName)
|
||||||
|
{
|
||||||
|
var assembly = Assembly.Load(assemblyName);
|
||||||
|
|
||||||
|
var modelBaseType = typeof(SqlSugarBaseEntity);
|
||||||
|
var repoBaseType = typeof(SqlSugarBaseEntity);
|
||||||
|
|
||||||
|
var types = assembly.ExportedTypes
|
||||||
|
.Where(t => (modelBaseType.IsAssignableFrom(t) || repoBaseType.IsAssignableFrom(t))
|
||||||
|
&& t != modelBaseType && t != repoBaseType
|
||||||
|
&& !t.IsGenericTypeDefinition)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var entityType in types)
|
||||||
|
{
|
||||||
|
var property = entityType.GetProperty("IsDeleted", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
|
||||||
|
if (property == null)
|
||||||
|
{
|
||||||
|
var baseType = entityType.BaseType;
|
||||||
|
while (baseType != null && baseType != typeof(object))
|
||||||
|
{
|
||||||
|
property = baseType.GetProperty("IsDeleted", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
|
||||||
|
if (property != null) break;
|
||||||
|
baseType = baseType.BaseType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (property == null) continue;
|
||||||
|
|
||||||
|
var propertyType = property.PropertyType;
|
||||||
|
|
||||||
|
Expression filterExpression;
|
||||||
|
var param = Expression.Parameter(entityType, "it");
|
||||||
|
var propertyAccess = Expression.Property(param, property);
|
||||||
|
|
||||||
|
if (propertyType == typeof(bool))
|
||||||
|
{
|
||||||
|
filterExpression = Expression.Equal(propertyAccess, Expression.Constant(false, typeof(bool)));
|
||||||
|
}
|
||||||
|
else if (propertyType == typeof(bool?))
|
||||||
|
{
|
||||||
|
filterExpression = Expression.Equal(propertyAccess, Expression.Constant(false, typeof(bool?)));
|
||||||
|
}
|
||||||
|
else if (propertyType == typeof(byte))
|
||||||
|
{
|
||||||
|
filterExpression = Expression.Equal(propertyAccess, Expression.Constant((byte)0, typeof(byte)));
|
||||||
|
}
|
||||||
|
else if (propertyType == typeof(byte?))
|
||||||
|
{
|
||||||
|
filterExpression = Expression.Equal(propertyAccess, Expression.Constant((byte)0, typeof(byte?)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lambda = Expression.Lambda(filterExpression, param);
|
||||||
|
db.QueryFilter.AddTableFilter(entityType, lambda);
|
||||||
|
}
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加创建人 创建时间 更新人 更新时间 默认值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db"></param>
|
||||||
|
public static ISqlSugarClient SetDefaultValue(this ISqlSugarClient db)
|
||||||
|
{
|
||||||
|
#region 创建人 创建时间 更新人 更新时间 默认值
|
||||||
|
db.Aop.DataExecuting = (oldValue, entityInfo) =>
|
||||||
|
{
|
||||||
|
var entityValue = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue)?.ToString();
|
||||||
|
var currnetUserName = "";
|
||||||
|
/*** inset生效 ***/
|
||||||
|
if (entityInfo.OperationType == DataFilterType.InsertByObject)
|
||||||
|
{
|
||||||
|
if (entityInfo.PropertyName == "CreatedAt" && (string.IsNullOrWhiteSpace(entityValue) || entityValue == DateTime.MinValue.ToString()))
|
||||||
|
entityInfo.SetValue(DateTime.Now);//修改CreateTime字段
|
||||||
|
else if (entityInfo.PropertyName == "CreatedBy" && (string.IsNullOrWhiteSpace(entityValue)))
|
||||||
|
entityInfo.SetValue(currnetUserName);//修改创建人字段
|
||||||
|
else if (entityInfo.PropertyName == "IsDeleted" && string.IsNullOrWhiteSpace(entityValue))
|
||||||
|
entityInfo.SetValue("0");//修改CreateTime字段
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** update生效 ***/
|
||||||
|
if (entityInfo.OperationType == DataFilterType.UpdateByObject)
|
||||||
|
{
|
||||||
|
if (entityInfo.PropertyName == "UpdatedAt" && (string.IsNullOrWhiteSpace(entityValue) || entityValue == DateTime.MinValue.ToString()))
|
||||||
|
entityInfo.SetValue(DateTime.Now);//修改UpdatedTime字段
|
||||||
|
else if (entityInfo.PropertyName == "UpdatedBy" && (string.IsNullOrWhiteSpace(entityValue) || entityValue == "0"))
|
||||||
|
entityInfo.SetValue(currnetUserName);//修改更新人字段
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return db;
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把一个字符串转成驼峰规则的字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ToCamelCase(this string str)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(str) && str.Length > 1)
|
||||||
|
{
|
||||||
|
return char.ToUpperInvariant(str[0]) + str.Substring(1);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
QYZH.InteractiveMagazine.Repository/Core/SqlSugarManager.cs
Normal file
51
QYZH.InteractiveMagazine.Repository/Core/SqlSugarManager.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using QYZH.InteractiveMagazine.Repository.Core;
|
||||||
|
using Serilog;
|
||||||
|
using SqlSugar;
|
||||||
|
using SqlSugar.IOC;
|
||||||
|
|
||||||
|
namespace QYZH.InteractiveMagazine.Repository.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// sql sugar 管理器
|
||||||
|
/// </summary>
|
||||||
|
public static class SqlSugarManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获基础信息库对象 (用IOC这块代码不能写到IOC里面)
|
||||||
|
/// </summary>
|
||||||
|
public static void InitSqlSugarDb(this WebApplicationBuilder builder, IocConfig config)
|
||||||
|
{
|
||||||
|
builder.Services.AddSqlSugar(config);
|
||||||
|
//配置参数
|
||||||
|
SugarIocServices.ConfigurationSugar(db =>
|
||||||
|
{
|
||||||
|
db.Aop.OnLogExecuting = (sql, pars) =>
|
||||||
|
{
|
||||||
|
//var param = db.GetConnectionScope(0).Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));
|
||||||
|
Log.Information($"【sql语句】{UtilMethods.GetSqlString((DbType)config.DbType, sql, pars)}\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
db.Aop.OnError = (ex) =>
|
||||||
|
{
|
||||||
|
string sql = $"【错误SQL】{UtilMethods.GetSqlString((DbType)config.DbType, ex.Sql, (SugarParameter[])ex.Parametres)}\r\n";
|
||||||
|
Log.Error(ex, $"{sql}\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||||
|
};
|
||||||
|
//SQL执行完
|
||||||
|
db.Aop.OnLogExecuted = (sql, pars) =>
|
||||||
|
{
|
||||||
|
//执行完了可以输出SQL执行时间 (OnLogExecutedDelegate)
|
||||||
|
};
|
||||||
|
db.SetDefaultValue().SetQueryFilter(GetAssemblyNames());//.CreateClassFile("C:\\Model");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetAssemblyNames()
|
||||||
|
{
|
||||||
|
string friendlyName = AppDomain.CurrentDomain.FriendlyName;
|
||||||
|
string[] source = friendlyName.Split('.');
|
||||||
|
string assemblyNames = string.Join(".", source.Take(source.Count() - 1)) + ".Models";
|
||||||
|
return assemblyNames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +0,0 @@
|
|||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Repository;
|
|
||||||
|
|
||||||
public interface IAdminUserRepository : IBaseRepository<AdminUser>
|
|
||||||
{
|
|
||||||
Task<AdminUser?> GetByUserNameAsync(string userName);
|
|
||||||
}
|
|
||||||
@ -1,88 +1,102 @@
|
|||||||
|
|
||||||
using QYZH.InteractiveMagazine.Models.Dto;
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
|
using SqlSugar;
|
||||||
|
using System.Data;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Repository;
|
namespace QYZH.InteractiveMagazine.Repository
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 基础仓储接口
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">实体类型</typeparam>
|
|
||||||
public interface IBaseRepository<T> where T : class, new()
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IBaseRepository<T> : ISimpleClient<T> where T : class, new()
|
||||||
/// 根据Id获取实体
|
{
|
||||||
/// </summary>
|
#region add
|
||||||
/// <param name="id">主键Id</param>
|
int Add(T t, bool ignoreNull = true);
|
||||||
/// <returns>实体对象</returns>
|
|
||||||
Task<T?> GetByIdAsync(long id);
|
|
||||||
|
|
||||||
/// <summary>
|
int Insert(List<T> t);
|
||||||
/// 获取所有列表
|
int Insert(T parm, Expression<Func<T, object>> iClumns = null, bool ignoreNull = true);
|
||||||
/// </summary>
|
|
||||||
/// <returns>实体列表</returns>
|
|
||||||
Task<List<T>> GetListAsync();
|
|
||||||
|
|
||||||
/// <summary>
|
IInsertable<T> Insertable(T t);
|
||||||
/// 根据条件获取列表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="where">查询条件</param>
|
|
||||||
/// <returns>实体列表</returns>
|
|
||||||
Task<List<T>> GetListByWhereAsync(Expression<Func<T, bool>> where);
|
|
||||||
|
|
||||||
/// <summary>
|
IUpdateable<T> Updateable();
|
||||||
/// 分页查询
|
#endregion add
|
||||||
/// </summary>
|
|
||||||
/// <param name="where">查询条件</param>
|
|
||||||
/// <param name="pageQuery">分页参数</param>
|
|
||||||
/// <returns>分页结果</returns>
|
|
||||||
Task<PageListModel<T>> GetPageListAsync(Expression<Func<T, bool>> where, PageQueryModel pageQuery);
|
|
||||||
|
|
||||||
/// <summary>
|
#region update
|
||||||
/// 插入单条记录
|
int Update(T entity, bool ignoreNullColumns = false, object data = null);
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">实体对象</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
Task<bool> InsertAsync(T entity);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 批量插入记录
|
/// 只更新表达式的值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">实体列表</param>
|
/// <param name="entity"></param>
|
||||||
/// <returns>是否成功</returns>
|
/// <param name="expression"></param>
|
||||||
Task<bool> InsertRangeAsync(List<T> entities);
|
/// <returns></returns>
|
||||||
|
int Update(T entity, Expression<Func<T, object>> expression, bool ignoreAllNull = false);
|
||||||
|
|
||||||
/// <summary>
|
int Update(T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where);
|
||||||
/// 更新单条记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">实体对象</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
Task<bool> UpdateAsync(T entity);
|
|
||||||
|
|
||||||
/// <summary>
|
int Update(Expression<Func<T, T>> columns, Expression<Func<T, bool>> where);
|
||||||
/// 批量更新记录
|
Task<int> UpdateAsync(Expression<Func<T, T>> columns, Expression<Func<T, bool>> where);
|
||||||
/// </summary>
|
|
||||||
/// <param name="entities">实体列表</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
Task<bool> UpdateRangeAsync(List<T> entities);
|
|
||||||
|
|
||||||
/// <summary>
|
#endregion update
|
||||||
/// 根据Id删除记录(软删除)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">主键Id</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
Task<bool> DeleteByIdAsync(long id);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据条件删除记录(软删除)
|
/// 事务 同步
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="where">删除条件</param>
|
/// <param name="action"></param>
|
||||||
/// <returns>是否成功</returns>
|
/// <returns></returns>
|
||||||
Task<bool> DeleteByWhereAsync(Expression<Func<T, bool>> where);
|
Task UseTranAsync(Func<Task> action);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据条件获取记录数
|
/// 事务 异步
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="where">查询条件</param>
|
/// <param name="action"></param>
|
||||||
/// <returns>记录数</returns>
|
/// <returns></returns>
|
||||||
Task<int> GetCountAsync(Expression<Func<T, bool>> where);
|
Task<bool> UseTranAsync(Func<Task<bool>> action);
|
||||||
|
|
||||||
|
#region delete
|
||||||
|
IDeleteable<T> Deleteable();
|
||||||
|
int Delete(object id, string title = "");
|
||||||
|
int DeleteTable();
|
||||||
|
bool Truncate();
|
||||||
|
|
||||||
|
#endregion delete
|
||||||
|
|
||||||
|
#region query
|
||||||
|
/// <summary>
|
||||||
|
/// 根据条件查询分页数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="where"></param>
|
||||||
|
/// <param name="parm"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
PageListModel<T> GetPages(Expression<Func<T, bool>> where, PageQueryModel parm);
|
||||||
|
|
||||||
|
PageListModel<T> GetPages(Expression<Func<T, bool>> where, PageQueryModel parm, Expression<Func<T, object>> order, OrderByType orderEnum = OrderByType.Asc);
|
||||||
|
PageListModel<T> GetPages(Expression<Func<T, bool>> where, PageQueryModel parm, Expression<Func<T, object>> order, string orderByType);
|
||||||
|
|
||||||
|
bool Any(Expression<Func<T, bool>> expression);
|
||||||
|
|
||||||
|
ISugarQueryable<T> Queryable();
|
||||||
|
List<T> GetAll(bool useCache = false, int cacheSecond = 3600);
|
||||||
|
|
||||||
|
List<T> SqlQueryToList(string sql, object obj = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据主值查询单条数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pkValue">主键值</param>
|
||||||
|
/// <returns>泛型实体</returns>
|
||||||
|
R GetById<R>(object pkValue) where R : class;
|
||||||
|
|
||||||
|
Task<R> GetByExpression<R>(Expression<Func<T, bool>> expression) where R : class;
|
||||||
|
|
||||||
|
Task<List<T2>> GetListByExpression<T2>(Expression<Func<T, bool>> expression) where T2 : class;
|
||||||
|
|
||||||
|
#endregion query
|
||||||
|
|
||||||
|
#region Procedure
|
||||||
|
|
||||||
|
DataTable UseStoredProcedureToDataTable(string procedureName, List<SugarParameter> parameters);
|
||||||
|
|
||||||
|
(DataTable, List<SugarParameter>) UseStoredProcedureToTuple(string procedureName, List<SugarParameter> parameters);
|
||||||
|
|
||||||
|
#endregion Procedure
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\QYZH.InteractiveMagazine.Common\QYZH.InteractiveMagazine.Common.csproj" />
|
<ProjectReference Include="..\QYZH.InteractiveMagazine.Common\QYZH.InteractiveMagazine.Common.csproj" />
|
||||||
|
<ProjectReference Include="..\QYZH.InteractiveMagazine.Infrastructure\QYZH.InteractiveMagazine.Infrastructure.csproj" />
|
||||||
<ProjectReference Include="..\QYZH.InteractiveMagazine.Models\QYZH.InteractiveMagazine.Models.csproj" />
|
<ProjectReference Include="..\QYZH.InteractiveMagazine.Models\QYZH.InteractiveMagazine.Models.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
|
||||||
<PackageReference Include="MySqlConnector" Version="2.5.0" />
|
<PackageReference Include="MySqlConnector" Version="2.5.0" />
|
||||||
|
<PackageReference Include="SqlSugar.IOC" Version="2.0.1" />
|
||||||
|
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.213" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@ -1,99 +0,0 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
|
||||||
using SqlSugar;
|
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Repository;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SqlSugar 数据库上下文封装(静态类)
|
|
||||||
/// </summary>
|
|
||||||
public static class SqlSugarDbContext
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// SqlSugarClient 实例
|
|
||||||
/// </summary>
|
|
||||||
private static SqlSugarClient? _db;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 配置对象
|
|
||||||
/// </summary>
|
|
||||||
private static IConfiguration? _configuration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化数据库上下文(在应用启动时调用一次)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="configuration">配置对象</param>
|
|
||||||
public static void Init(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取 SqlSugarClient 实例
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>SqlSugarClient 实例</returns>
|
|
||||||
public static SqlSugarClient GetDb()
|
|
||||||
{
|
|
||||||
if (_configuration == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("请先调用 SqlSugarDbContext.Init(configuration) 进行初始化");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_db == null)
|
|
||||||
{
|
|
||||||
lock (typeof(SqlSugarDbContext))
|
|
||||||
{
|
|
||||||
if (_db == null)
|
|
||||||
{
|
|
||||||
var connectionString = _configuration.GetConnectionString("DefaultConnection");
|
|
||||||
if (string.IsNullOrWhiteSpace(connectionString))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("未找到连接字符串 DefaultConnection");
|
|
||||||
}
|
|
||||||
|
|
||||||
_db = new SqlSugarClient(new ConnectionConfig
|
|
||||||
{
|
|
||||||
ConnectionString = connectionString,
|
|
||||||
DbType = DbType.MySql,
|
|
||||||
IsAutoCloseConnection = true,
|
|
||||||
InitKeyType = InitKeyType.Attribute
|
|
||||||
},
|
|
||||||
db =>
|
|
||||||
{
|
|
||||||
// 配置软删除全局过滤(继承 BaseEntity 的实体都有效)
|
|
||||||
db.QueryFilter.AddTableFilter<BaseEntity>(it => it.IsDeleted == false);
|
|
||||||
|
|
||||||
// 开启日志打印
|
|
||||||
db.Aop.OnLogExecuting = (sql, pars) =>
|
|
||||||
{
|
|
||||||
Console.WriteLine($"[SQL执行] {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
||||||
Console.WriteLine($"[SQL语句] {sql}");
|
|
||||||
Console.WriteLine($"[SQL参数] {string.Join(", ", pars.Select(p => $"{p.ParameterName}={p.Value}"))}");
|
|
||||||
Console.WriteLine(new string('-', 50));
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _db;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 代码优先初始化(可选)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entityTypes">实体类型数组</param>
|
|
||||||
public static void InitializeCodeFirst(params Type[] entityTypes)
|
|
||||||
{
|
|
||||||
var db = GetDb();
|
|
||||||
|
|
||||||
// 创建数据库(如果不存在)
|
|
||||||
db.DbMaintenance.CreateDatabase();
|
|
||||||
|
|
||||||
// 初始化表结构
|
|
||||||
if (entityTypes != null && entityTypes.Length > 0)
|
|
||||||
{
|
|
||||||
db.CodeFirst.InitTables(entityTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -6,31 +6,23 @@ using QYZH.InteractiveMagazine.Infrastructure.Cache;
|
|||||||
using QYZH.InteractiveMagazine.IService;
|
using QYZH.InteractiveMagazine.IService;
|
||||||
using QYZH.InteractiveMagazine.IService.Dto;
|
using QYZH.InteractiveMagazine.IService.Dto;
|
||||||
using QYZH.InteractiveMagazine.Models.Common;
|
using QYZH.InteractiveMagazine.Models.Common;
|
||||||
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
using QYZH.InteractiveMagazine.Models.Settings;
|
using QYZH.InteractiveMagazine.Models.Settings;
|
||||||
using QYZH.InteractiveMagazine.Repository;
|
using QYZH.InteractiveMagazine.Repository;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Service;
|
namespace QYZH.InteractiveMagazine.Service;
|
||||||
|
|
||||||
public class AdminAuthService : IAdminAuthService
|
public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, IConfiguration configuration, ILogger<AdminAuthService> logger) : BaseRepository<AdminUser>, IAdminAuthService
|
||||||
{
|
{
|
||||||
private readonly IAdminUserRepository _adminUserRepository;
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
private readonly ILogger<AdminAuthService> _logger;
|
|
||||||
|
|
||||||
private const string TokenKeyPrefix = "InteractiveMagazine:AdminAuth:Token";
|
private const string TokenKeyPrefix = "InteractiveMagazine:AdminAuth:Token";
|
||||||
private const string UserInfoKeyPrefix = "InteractiveMagazine:AdminAuth:UserInfo";
|
private const string UserInfoKeyPrefix = "InteractiveMagazine:AdminAuth:UserInfo";
|
||||||
|
|
||||||
public AdminAuthService(IAdminUserRepository adminUserRepository, IConfiguration configuration, ILogger<AdminAuthService> logger)
|
|
||||||
{
|
|
||||||
_adminUserRepository = adminUserRepository;
|
|
||||||
_configuration = configuration;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<AdminLoginOutput> LoginAsync(AdminLoginInput input)
|
public async Task<AdminLoginOutput> LoginAsync(AdminLoginInput input)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("管理员登录尝试,用户名: {UserName}", input.UserName);
|
logger.LogInformation("管理员登录尝试,用户名: {UserName}", input.UserName);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(input.UserName))
|
if (string.IsNullOrWhiteSpace(input.UserName))
|
||||||
{
|
{
|
||||||
@ -42,22 +34,22 @@ public class AdminAuthService : IAdminAuthService
|
|||||||
throw new BusinessException("密码不能为空", 400);
|
throw new BusinessException("密码不能为空", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
var adminUser = await _adminUserRepository.GetByUserNameAsync(input.UserName);
|
var adminUser = await adminUserRepository.GetFirstAsync(a => a.UserName == input.UserName);
|
||||||
if (adminUser == null)
|
if (adminUser == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("管理员登录失败,用户名不存在: {UserName}", input.UserName);
|
logger.LogWarning("管理员登录失败,用户名不存在: {UserName}", input.UserName);
|
||||||
throw new BusinessException("用户名或密码错误", 401);
|
throw new BusinessException("用户名或密码错误", 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BCrypt.Net.BCrypt.Verify(input.Password, adminUser.PasswordHash))
|
if (!BCrypt.Net.BCrypt.Verify(input.Password, adminUser.PasswordHash))
|
||||||
{
|
{
|
||||||
_logger.LogWarning("管理员登录失败,密码错误: {UserName}", input.UserName);
|
logger.LogWarning("管理员登录失败,密码错误: {UserName}", input.UserName);
|
||||||
throw new BusinessException("用户名或密码错误", 401);
|
throw new BusinessException("用户名或密码错误", 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adminUser.Status != "Active")
|
if (adminUser.Status != "Active")
|
||||||
{
|
{
|
||||||
_logger.LogWarning("管理员登录失败,账号已禁用: {UserName}", input.UserName);
|
logger.LogWarning("管理员登录失败,账号已禁用: {UserName}", input.UserName);
|
||||||
throw new BusinessException("账号已被禁用,请联系系统管理员", 403);
|
throw new BusinessException("账号已被禁用,请联系系统管理员", 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +59,7 @@ public class AdminAuthService : IAdminAuthService
|
|||||||
|
|
||||||
await RedisHelper.StringSetAsync($"{TokenKeyPrefix}:{adminUser.Id}", token, TimeSpan.FromMinutes(jwtSettings.ExpiryMinutes));
|
await RedisHelper.StringSetAsync($"{TokenKeyPrefix}:{adminUser.Id}", token, TimeSpan.FromMinutes(jwtSettings.ExpiryMinutes));
|
||||||
|
|
||||||
_logger.LogInformation("管理员登录成功,用户名: {UserName}, ID: {UserId}", input.UserName, adminUser.Id);
|
logger.LogInformation("管理员登录成功,用户名: {UserName}, ID: {UserId}", input.UserName, adminUser.Id);
|
||||||
|
|
||||||
return new AdminLoginOutput
|
return new AdminLoginOutput
|
||||||
{
|
{
|
||||||
@ -80,21 +72,21 @@ public class AdminAuthService : IAdminAuthService
|
|||||||
|
|
||||||
public async Task LogoutAsync(long userId)
|
public async Task LogoutAsync(long userId)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("管理员登出,ID: {UserId}", userId);
|
logger.LogInformation("管理员登出,ID: {UserId}", userId);
|
||||||
|
|
||||||
await RedisHelper.KeyDeleteAsync($"{TokenKeyPrefix}:{userId}");
|
await RedisHelper.KeyDeleteAsync($"{TokenKeyPrefix}:{userId}");
|
||||||
|
|
||||||
_logger.LogInformation("管理员登出成功,ID: {UserId}", userId);
|
logger.LogInformation("管理员登出成功,ID: {UserId}", userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AdminUserInfoOutput> GetAdminInfoAsync(long userId)
|
public async Task<AdminUserInfoOutput> GetAdminInfoAsync(long userId)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("获取管理员信息,ID: {UserId}", userId);
|
logger.LogInformation("获取管理员信息,ID: {UserId}", userId);
|
||||||
|
|
||||||
var adminUser = await _adminUserRepository.GetByIdAsync(userId);
|
var adminUser = await adminUserRepository.GetByIdAsync(userId);
|
||||||
if (adminUser == null)
|
if (adminUser == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("未找到管理员,ID: {UserId}", userId);
|
logger.LogWarning("未找到管理员,ID: {UserId}", userId);
|
||||||
throw new BusinessException("用户不存在", 404);
|
throw new BusinessException("用户不存在", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +101,7 @@ public class AdminAuthService : IAdminAuthService
|
|||||||
|
|
||||||
public async Task ChangePasswordAsync(long userId, string oldPassword, string newPassword)
|
public async Task ChangePasswordAsync(long userId, string oldPassword, string newPassword)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("管理员修改密码尝试,ID: {UserId}", userId);
|
logger.LogInformation("管理员修改密码尝试,ID: {UserId}", userId);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(oldPassword))
|
if (string.IsNullOrWhiteSpace(oldPassword))
|
||||||
{
|
{
|
||||||
@ -121,22 +113,22 @@ public class AdminAuthService : IAdminAuthService
|
|||||||
throw new BusinessException("新密码不能为空", 400);
|
throw new BusinessException("新密码不能为空", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
var adminUser = await _adminUserRepository.GetByIdAsync(userId);
|
var adminUser = await adminUserRepository.GetByIdAsync(userId);
|
||||||
if (adminUser == null)
|
if (adminUser == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("未找到管理员,ID: {UserId}", userId);
|
logger.LogWarning("未找到管理员,ID: {UserId}", userId);
|
||||||
throw new BusinessException("用户不存在", 404);
|
throw new BusinessException("用户不存在", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BCrypt.Net.BCrypt.Verify(oldPassword, adminUser.PasswordHash))
|
if (!BCrypt.Net.BCrypt.Verify(oldPassword, adminUser.PasswordHash))
|
||||||
{
|
{
|
||||||
_logger.LogWarning("管理员修改密码失败,原密码错误,ID: {UserId}", userId);
|
logger.LogWarning("管理员修改密码失败,原密码错误,ID: {UserId}", userId);
|
||||||
throw new BusinessException("原密码错误", 400);
|
throw new BusinessException("原密码错误", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
adminUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newPassword);
|
adminUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newPassword);
|
||||||
|
|
||||||
var result = await _adminUserRepository.UpdateAsync(adminUser);
|
var result = await adminUserRepository.UpdateAsync(adminUser);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
throw new BusinessException("修改密码失败", 500);
|
throw new BusinessException("修改密码失败", 500);
|
||||||
@ -144,12 +136,12 @@ public class AdminAuthService : IAdminAuthService
|
|||||||
|
|
||||||
await RedisHelper.KeyDeleteAsync($"{TokenKeyPrefix}:{userId}");
|
await RedisHelper.KeyDeleteAsync($"{TokenKeyPrefix}:{userId}");
|
||||||
|
|
||||||
_logger.LogInformation("管理员修改密码成功,ID: {UserId}", userId);
|
logger.LogInformation("管理员修改密码成功,ID: {UserId}", userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JwtSettings GetJwtSettings()
|
private JwtSettings GetJwtSettings()
|
||||||
{
|
{
|
||||||
var jwtSettings = _configuration.GetSection("JwtSettings").Get<JwtSettings>()
|
var jwtSettings = configuration.GetSection("JwtSettings").Get<JwtSettings>()
|
||||||
?? new JwtSettings
|
?? new JwtSettings
|
||||||
{
|
{
|
||||||
Issuer = "QYZH.InteractiveMagazine",
|
Issuer = "QYZH.InteractiveMagazine",
|
||||||
|
|||||||
@ -7,29 +7,22 @@ using QYZH.InteractiveMagazine.Models.Common;
|
|||||||
using QYZH.InteractiveMagazine.Models.Dto;
|
using QYZH.InteractiveMagazine.Models.Dto;
|
||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
using QYZH.InteractiveMagazine.Repository;
|
using QYZH.InteractiveMagazine.Repository;
|
||||||
|
using SqlSugar;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Service;
|
namespace QYZH.InteractiveMagazine.Service;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 管理员用户服务实现
|
/// 管理员用户服务实现
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AdminUserService : IAdminUserService
|
public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILogger<AdminUserService> logger) : BaseRepository<AdminUser>, IAdminUserService
|
||||||
{
|
{
|
||||||
private readonly IAdminUserRepository _adminUserRepository;
|
|
||||||
private readonly ILogger<AdminUserService> _logger;
|
|
||||||
|
|
||||||
public AdminUserService(IAdminUserRepository adminUserRepository, ILogger<AdminUserService> logger)
|
|
||||||
{
|
|
||||||
_adminUserRepository = adminUserRepository;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建管理员
|
/// 创建管理员
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<AdminUserOutput> CreateAsync(AdminUserInput input)
|
public async Task<AdminUserOutput> CreateAsync(AdminUserInput input)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("正在创建管理员,用户名: {UserName}", input.UserName);
|
logger.LogInformation("正在创建管理员,用户名: {UserName}", input.UserName);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(input.UserName))
|
if (string.IsNullOrWhiteSpace(input.UserName))
|
||||||
{
|
{
|
||||||
@ -42,10 +35,10 @@ public class AdminUserService : IAdminUserService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户名是否已存在
|
// 检查用户名是否已存在
|
||||||
var existingUser = await _adminUserRepository.GetByUserNameAsync(input.UserName);
|
var existingUser = await adminUserRepository.GetFirstAsync(a => a.UserName == input.UserName);
|
||||||
if (existingUser != null)
|
if (existingUser != null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("创建管理员失败,用户名已存在: {UserName}", input.UserName);
|
logger.LogWarning("创建管理员失败,用户名已存在: {UserName}", input.UserName);
|
||||||
throw new BusinessException("用户名已存在", 400);
|
throw new BusinessException("用户名已存在", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,14 +55,14 @@ public class AdminUserService : IAdminUserService
|
|||||||
IsDeleted = false
|
IsDeleted = false
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await _adminUserRepository.InsertAsync(adminUser);
|
var result = await adminUserRepository.InsertAsync(adminUser);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
_logger.LogError("管理员创建失败,用户名: {UserName}", input.UserName);
|
logger.LogError("管理员创建失败,用户名: {UserName}", input.UserName);
|
||||||
throw new BusinessException("创建管理员失败", 500);
|
throw new BusinessException("创建管理员失败", 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("管理员创建成功,用户名: {UserName}, ID: {Id}", input.UserName, adminUser.Id);
|
logger.LogInformation("管理员创建成功,用户名: {UserName}, ID: {Id}", input.UserName, adminUser.Id);
|
||||||
|
|
||||||
return MapToOutput(adminUser);
|
return MapToOutput(adminUser);
|
||||||
}
|
}
|
||||||
@ -79,22 +72,22 @@ public class AdminUserService : IAdminUserService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<AdminUserOutput> UpdateAsync(long id, AdminUserInput input)
|
public async Task<AdminUserOutput> UpdateAsync(long id, AdminUserInput input)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("正在更新管理员,ID: {Id}", id);
|
logger.LogInformation("正在更新管理员,ID: {Id}", id);
|
||||||
|
|
||||||
var adminUser = await _adminUserRepository.GetByIdAsync(id);
|
var adminUser = await adminUserRepository.GetByIdAsync(id);
|
||||||
if (adminUser == null)
|
if (adminUser == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("未找到要更新的管理员,ID: {Id}", id);
|
logger.LogWarning("未找到要更新的管理员,ID: {Id}", id);
|
||||||
throw new BusinessException("管理员不存在", 404);
|
throw new BusinessException("管理员不存在", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果用户名有变更,检查是否与其他用户重复
|
// 如果用户名有变更,检查是否与其他用户重复
|
||||||
if (!string.IsNullOrWhiteSpace(input.UserName) && input.UserName != adminUser.UserName)
|
if (!string.IsNullOrWhiteSpace(input.UserName) && input.UserName != adminUser.UserName)
|
||||||
{
|
{
|
||||||
var existingUser = await _adminUserRepository.GetByUserNameAsync(input.UserName.Trim());
|
var existingUser = await adminUserRepository.GetFirstAsync(a => a.UserName == input.UserName.Trim());
|
||||||
if (existingUser != null && existingUser.Id != id)
|
if (existingUser != null && existingUser.Id != id)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("更新管理员失败,用户名已存在: {UserName}", input.UserName);
|
logger.LogWarning("更新管理员失败,用户名已存在: {UserName}", input.UserName);
|
||||||
throw new BusinessException("用户名已存在", 400);
|
throw new BusinessException("用户名已存在", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,14 +113,14 @@ public class AdminUserService : IAdminUserService
|
|||||||
adminUser.UpdatedBy = "System";
|
adminUser.UpdatedBy = "System";
|
||||||
adminUser.UpdatedAt = DateTime.Now;
|
adminUser.UpdatedAt = DateTime.Now;
|
||||||
|
|
||||||
var result = await _adminUserRepository.UpdateAsync(adminUser);
|
var result = await adminUserRepository.UpdateAsync(adminUser);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
_logger.LogError("管理员更新失败,ID: {Id}", id);
|
logger.LogError("管理员更新失败,ID: {Id}", id);
|
||||||
throw new BusinessException("更新管理员失败", 500);
|
throw new BusinessException("更新管理员失败", 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("管理员更新成功,ID: {Id}", id);
|
logger.LogInformation("管理员更新成功,ID: {Id}", id);
|
||||||
|
|
||||||
return MapToOutput(adminUser);
|
return MapToOutput(adminUser);
|
||||||
}
|
}
|
||||||
@ -137,23 +130,23 @@ public class AdminUserService : IAdminUserService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task DeleteAsync(long id)
|
public async Task DeleteAsync(long id)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("正在删除管理员,ID: {Id}", id);
|
logger.LogInformation("正在删除管理员,ID: {Id}", id);
|
||||||
|
|
||||||
var adminUser = await _adminUserRepository.GetByIdAsync(id);
|
var adminUser = await adminUserRepository.GetByIdAsync(id);
|
||||||
if (adminUser == null)
|
if (adminUser == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("未找到要删除的管理员,ID: {Id}", id);
|
logger.LogWarning("未找到要删除的管理员,ID: {Id}", id);
|
||||||
throw new BusinessException("管理员不存在", 404);
|
throw new BusinessException("管理员不存在", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await _adminUserRepository.DeleteByIdAsync(id);
|
var result = await adminUserRepository.DeleteByIdAsync(id);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
_logger.LogError("管理员删除失败,ID: {Id}", id);
|
logger.LogError("管理员删除失败,ID: {Id}", id);
|
||||||
throw new BusinessException("删除管理员失败", 500);
|
throw new BusinessException("删除管理员失败", 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("管理员删除成功,ID: {Id}", id);
|
logger.LogInformation("管理员删除成功,ID: {Id}", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -161,12 +154,12 @@ public class AdminUserService : IAdminUserService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<AdminUserOutput> GetByIdAsync(long id)
|
public async Task<AdminUserOutput> GetByIdAsync(long id)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("正在获取管理员信息,ID: {Id}", id);
|
logger.LogInformation("正在获取管理员信息,ID: {Id}", id);
|
||||||
|
|
||||||
var adminUser = await _adminUserRepository.GetByIdAsync(id);
|
var adminUser = await adminUserRepository.GetByIdAsync(id);
|
||||||
if (adminUser == null)
|
if (adminUser == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("未找到管理员,ID: {Id}", id);
|
logger.LogWarning("未找到管理员,ID: {Id}", id);
|
||||||
throw new BusinessException("管理员不存在", 404);
|
throw new BusinessException("管理员不存在", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +171,7 @@ public class AdminUserService : IAdminUserService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<PageListModel<AdminUserOutput>> GetListAsync(AdminUserQueryInput input)
|
public async Task<PageListModel<AdminUserOutput>> GetListAsync(AdminUserQueryInput input)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("正在查询管理员列表,页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);
|
logger.LogInformation("正在查询管理员列表,页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);
|
||||||
|
|
||||||
if (input.PageIndex <= 0)
|
if (input.PageIndex <= 0)
|
||||||
{
|
{
|
||||||
@ -189,62 +182,13 @@ public class AdminUserService : IAdminUserService
|
|||||||
{
|
{
|
||||||
throw new BusinessException("每页条数必须在1-100之间", 400);
|
throw new BusinessException("每页条数必须在1-100之间", 400);
|
||||||
}
|
}
|
||||||
|
RefAsync<int> totalNumber = 0;
|
||||||
var pageResult = await _adminUserRepository.GetPageListAsync(
|
var pageResult = await adminUserRepository.Queryable()
|
||||||
BuildQueryExpression(input),
|
.WhereIF(!string.IsNullOrWhiteSpace(input.UserName), a => a.UserName == input.UserName)
|
||||||
input
|
.OrderByDescending(a => a.CreatedAt)
|
||||||
);
|
.Select(a => MapToOutput(a), true)
|
||||||
|
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
|
||||||
// 转换为输出DTO
|
return new PageListModel<AdminUserOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
||||||
var outputList = pageResult.List?.Select(MapToOutput).ToList() ?? new List<AdminUserOutput>();
|
|
||||||
|
|
||||||
return new PageListModel<AdminUserOutput>
|
|
||||||
{
|
|
||||||
List = outputList,
|
|
||||||
TotalCount = pageResult.TotalCount,
|
|
||||||
PageIndex = pageResult.PageIndex,
|
|
||||||
PageSize = pageResult.PageSize
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构建查询表达式
|
|
||||||
/// </summary>
|
|
||||||
private static Expression<Func<AdminUser, bool>> BuildQueryExpression(AdminUserQueryInput input)
|
|
||||||
{
|
|
||||||
Expression<Func<AdminUser, bool>> where = x => !x.IsDeleted;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(input.UserName))
|
|
||||||
{
|
|
||||||
var userName = input.UserName;
|
|
||||||
Expression<Func<AdminUser, bool>> userNameCondition = x => x.UserName.Contains(userName);
|
|
||||||
where = Expression.Lambda<Func<AdminUser, bool>>(
|
|
||||||
Expression.AndAlso(where.Body,
|
|
||||||
Expression.Invoke(userNameCondition, where.Parameters[0])),
|
|
||||||
where.Parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(input.Type))
|
|
||||||
{
|
|
||||||
var type = input.Type;
|
|
||||||
Expression<Func<AdminUser, bool>> typeCondition = x => x.Type == type;
|
|
||||||
where = Expression.Lambda<Func<AdminUser, bool>>(
|
|
||||||
Expression.AndAlso(where.Body,
|
|
||||||
Expression.Invoke(typeCondition, where.Parameters[0])),
|
|
||||||
where.Parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(input.Status))
|
|
||||||
{
|
|
||||||
var status = input.Status;
|
|
||||||
Expression<Func<AdminUser, bool>> statusCondition = x => x.Status == status;
|
|
||||||
where = Expression.Lambda<Func<AdminUser, bool>>(
|
|
||||||
Expression.AndAlso(where.Body,
|
|
||||||
Expression.Invoke(statusCondition, where.Parameters[0])),
|
|
||||||
where.Parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
return where;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -1,201 +0,0 @@
|
|||||||
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;
|
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Service;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 基础服务实现
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">实体类型</typeparam>
|
|
||||||
public class BaseService<T> : IBaseService<T> where T : class, new()
|
|
||||||
{
|
|
||||||
protected readonly IBaseRepository<T> _repository;
|
|
||||||
protected readonly ILogger<BaseService<T>> _logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造函数
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="repository">基础仓储</param>
|
|
||||||
/// <param name="logger">日志记录器</param>
|
|
||||||
public BaseService(IBaseRepository<T> repository, ILogger<BaseService<T>> logger)
|
|
||||||
{
|
|
||||||
_repository = repository;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据ID获取实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">实体ID</param>
|
|
||||||
/// <returns>实体对象</returns>
|
|
||||||
public async Task<T?> GetByIdAsync(long id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("正在获取实体,ID: {Id}", id);
|
|
||||||
|
|
||||||
var entity = await _repository.GetByIdAsync(id);
|
|
||||||
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("未找到实体,ID: {Id}", id);
|
|
||||||
throw new BusinessException($"未找到ID为{id}的记录", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有实体列表
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>实体列表</returns>
|
|
||||||
public async Task<List<T>> GetListAsync()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("正在获取所有实体列表");
|
|
||||||
return await _repository.GetListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取分页列表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pageQuery">分页查询参数</param>
|
|
||||||
/// <returns>分页数据</returns>
|
|
||||||
public async Task<PageListModel<T>> GetPageListAsync(PageQueryModel pageQuery)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("正在获取分页列表,页码: {PageIndex}, 每页条数: {PageSize}", pageQuery.PageIndex, pageQuery.PageSize);
|
|
||||||
|
|
||||||
if (pageQuery.PageIndex <= 0)
|
|
||||||
{
|
|
||||||
throw new BusinessException("页码必须大于0", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pageQuery.PageSize <= 0 || pageQuery.PageSize > 100)
|
|
||||||
{
|
|
||||||
throw new BusinessException("每页条数必须在1-100之间", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await _repository.GetPageListAsync(x => true, pageQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 新增实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">实体对象</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> InsertAsync(T entity)
|
|
||||||
{
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
throw new BusinessException("实体对象不能为空", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("正在新增实体,类型: {EntityType}", typeof(T).Name);
|
|
||||||
|
|
||||||
SetAuditFieldsOnInsert(entity);
|
|
||||||
|
|
||||||
var result = await _repository.InsertAsync(entity);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("实体新增成功");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogError("实体新增失败");
|
|
||||||
throw new BusinessException("新增记录失败", 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">实体对象</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> UpdateAsync(T entity)
|
|
||||||
{
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
throw new BusinessException("实体对象不能为空", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("正在更新实体,类型: {EntityType}", typeof(T).Name);
|
|
||||||
|
|
||||||
SetAuditFieldsOnUpdate(entity);
|
|
||||||
|
|
||||||
var result = await _repository.UpdateAsync(entity);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("实体更新成功");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogError("实体更新失败");
|
|
||||||
throw new BusinessException("更新记录失败", 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据ID删除实体
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">实体ID</param>
|
|
||||||
/// <returns>是否成功</returns>
|
|
||||||
public async Task<bool> DeleteByIdAsync(long id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("正在删除实体,ID: {Id}", id);
|
|
||||||
|
|
||||||
var entity = await _repository.GetByIdAsync(id);
|
|
||||||
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("未找到要删除的实体,ID: {Id}", id);
|
|
||||||
throw new BusinessException($"未找到ID为{id}的记录", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = await _repository.DeleteByIdAsync(id);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("实体删除成功,ID: {Id}", id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogError("实体删除失败,ID: {Id}", id);
|
|
||||||
throw new BusinessException("删除记录失败", 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置插入时的审计字段
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">实体对象</param>
|
|
||||||
private static void SetAuditFieldsOnInsert(T entity)
|
|
||||||
{
|
|
||||||
if (entity is BaseEntity baseEntity)
|
|
||||||
{
|
|
||||||
var now = DateTime.Now;
|
|
||||||
baseEntity.CreatedAt = now;
|
|
||||||
baseEntity.UpdatedAt = now;
|
|
||||||
baseEntity.CreatedBy = baseEntity.CreatedBy ?? "system";
|
|
||||||
baseEntity.UpdatedBy = baseEntity.UpdatedBy ?? "system";
|
|
||||||
baseEntity.IsDeleted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetAuditFieldsOnUpdate(T entity)
|
|
||||||
{
|
|
||||||
if (entity is BaseEntity baseEntity)
|
|
||||||
{
|
|
||||||
baseEntity.UpdatedAt = DateTime.Now;
|
|
||||||
baseEntity.UpdatedBy = baseEntity.UpdatedBy ?? "system";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
191
QYZH.InteractiveMagazine.Service/WxUserService.cs
Normal file
191
QYZH.InteractiveMagazine.Service/WxUserService.cs
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
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,
|
||||||
|
Points = input.Points,
|
||||||
|
Type = input.Type,
|
||||||
|
Status = input.Status,
|
||||||
|
Pwd = input.Pwd ?? string.Empty,
|
||||||
|
GrowthPoints = input.GrowthPoints,
|
||||||
|
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 MapToOutput(wxUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.Points = input.Points;
|
||||||
|
wxUser.Type = input.Type ?? wxUser.Type;
|
||||||
|
wxUser.Status = input.Status ?? wxUser.Status;
|
||||||
|
wxUser.Pwd = input.Pwd ?? wxUser.Pwd;
|
||||||
|
wxUser.GrowthPoints = input.GrowthPoints;
|
||||||
|
|
||||||
|
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 MapToOutput(wxUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("正在获取微信用户信息,ID: {Id}", id);
|
||||||
|
|
||||||
|
var wxUser = await wxUserRepository.GetByIdAsync(id);
|
||||||
|
if (wxUser == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("未找到微信用户,ID: {Id}", id);
|
||||||
|
throw new BusinessException("微信用户不存在", 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MapToOutput(wxUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PageListModel<WxUserOutput>> GetListAsync(WxUserQueryInput 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 wxUserRepository.Queryable()
|
||||||
|
.WhereIF(!string.IsNullOrWhiteSpace(input.NickName), a => a.NickName == input.NickName)
|
||||||
|
.OrderByDescending(a => a.CreatedAt)
|
||||||
|
.Select(a => MapToOutput(a), true)
|
||||||
|
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
|
||||||
|
|
||||||
|
return new PageListModel<WxUserOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WxUserOutput MapToOutput(WxUser wxUser)
|
||||||
|
{
|
||||||
|
return new WxUserOutput
|
||||||
|
{
|
||||||
|
Id = wxUser.Id,
|
||||||
|
OpenId = wxUser.OpenId,
|
||||||
|
UnionId = wxUser.UnionId,
|
||||||
|
NickName = wxUser.NickName,
|
||||||
|
AvatarUrl = wxUser.AvatarUrl,
|
||||||
|
Phone = wxUser.Phone,
|
||||||
|
Points = wxUser.Points,
|
||||||
|
Type = wxUser.Type,
|
||||||
|
Status = wxUser.Status,
|
||||||
|
GrowthPoints = wxUser.GrowthPoints,
|
||||||
|
CreatedBy = wxUser.CreatedBy,
|
||||||
|
CreatedAt = wxUser.CreatedAt,
|
||||||
|
UpdatedBy = wxUser.UpdatedBy,
|
||||||
|
UpdatedAt = wxUser.UpdatedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,11 @@ public class AdminController : BaseController
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">登录输入</param>
|
||||||
|
/// <returns>登录结果</returns>
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[HttpPost("login")]
|
[HttpPost("login")]
|
||||||
public async Task<BaseResponse<AdminLoginOutput>> LoginAsync([FromBody] AdminLoginInput input)
|
public async Task<BaseResponse<AdminLoginOutput>> LoginAsync([FromBody] AdminLoginInput input)
|
||||||
@ -31,6 +36,10 @@ public class AdminController : BaseController
|
|||||||
return Success(result);
|
return Success(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登出
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>登出结果</returns>
|
||||||
[HttpPost("logout")]
|
[HttpPost("logout")]
|
||||||
public async Task<BaseResponse<object>> LogoutAsync()
|
public async Task<BaseResponse<object>> LogoutAsync()
|
||||||
{
|
{
|
||||||
@ -44,6 +53,10 @@ public class AdminController : BaseController
|
|||||||
return Success(new object(), "登出成功");
|
return Success(new object(), "登出成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取管理员信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>管理员信息</returns>
|
||||||
[HttpGet("info")]
|
[HttpGet("info")]
|
||||||
public async Task<BaseResponse<AdminUserInfoOutput>> GetAdminInfoAsync()
|
public async Task<BaseResponse<AdminUserInfoOutput>> GetAdminInfoAsync()
|
||||||
{
|
{
|
||||||
@ -57,6 +70,11 @@ public class AdminController : BaseController
|
|||||||
return Success(result);
|
return Success(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改密码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">修改密码输入</param>
|
||||||
|
/// <returns>修改密码结果</returns>
|
||||||
[HttpPost("changePassword")]
|
[HttpPost("changePassword")]
|
||||||
public async Task<BaseResponse<object>> ChangePasswordAsync([FromBody] ChangePasswordInput input)
|
public async Task<BaseResponse<object>> ChangePasswordAsync([FromBody] ChangePasswordInput input)
|
||||||
{
|
{
|
||||||
|
|||||||
121
QYZH.InteractiveMagazine.WebApi/Controllers/WxUserController.cs
Normal file
121
QYZH.InteractiveMagazine.WebApi/Controllers/WxUserController.cs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
[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;
|
||||||
|
}
|
||||||
|
|
||||||
|
[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, ex.Code);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "创建微信用户系统异常,参数:{Input}", input);
|
||||||
|
return BaseResponse<WxUserOutput>.Fail("创建微信用户失败,请稍后重试", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[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, ex.Code);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "更新微信用户系统异常,ID:{Id},参数:{Input}", id, input);
|
||||||
|
return BaseResponse<WxUserOutput>.Fail("更新微信用户失败,请稍后重试", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[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, ex.Code);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "删除微信用户系统异常,ID:{Id}", id);
|
||||||
|
return BaseResponse<object>.Fail("删除微信用户失败,请稍后重试", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[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, ex.Code);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "获取微信用户系统异常,ID:{Id}", id);
|
||||||
|
return BaseResponse<WxUserOutput>.Fail("获取微信用户信息失败,请稍后重试", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[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, ex.Code);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "查询微信用户列表系统异常,参数:{Input}", input);
|
||||||
|
return BaseResponse<PageListModel<WxUserOutput>>.Fail("查询微信用户列表失败,请稍后重试", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,21 +4,38 @@ using BCrypt.Net;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.OpenApi;
|
using Microsoft.OpenApi;
|
||||||
using QYZH.InteractiveMagazine.Common.Extensions;
|
using QYZH.InteractiveMagazine.Common.Extensions;
|
||||||
|
using QYZH.InteractiveMagazine.Common.Helpers;
|
||||||
|
using QYZH.InteractiveMagazine.Infrastructure.Autofacs;
|
||||||
|
using QYZH.InteractiveMagazine.Infrastructure.Context;
|
||||||
using QYZH.InteractiveMagazine.Infrastructure.Extensions;
|
using QYZH.InteractiveMagazine.Infrastructure.Extensions;
|
||||||
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
|
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
|
||||||
using QYZH.InteractiveMagazine.Models.Entity;
|
using QYZH.InteractiveMagazine.Models.Entity;
|
||||||
using QYZH.InteractiveMagazine.Models.Enum;
|
using QYZH.InteractiveMagazine.Models.Enum;
|
||||||
using QYZH.InteractiveMagazine.Repository;
|
using QYZH.InteractiveMagazine.Repository;
|
||||||
|
using QYZH.InteractiveMagazine.Repository.Core;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
using SqlSugar.IOC;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||||
using QYZH.InteractiveMagazine.Infrastructure.Autofacs;
|
using System.Text.Json.Serialization;
|
||||||
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// 初始化雪花ID生成器
|
||||||
|
YitIdHelper.SetIdGenerator(new IdGeneratorOptions() { WorkerId = 1 });
|
||||||
// autofac注入 允许使用autofac作为DI容器
|
// autofac注入 允许使用autofac作为DI容器
|
||||||
builder.UseAutofac();
|
builder.UseAutofac();
|
||||||
|
|
||||||
|
builder.InitSqlSugarDb(new IocConfig()
|
||||||
|
{
|
||||||
|
ConfigId = 0,
|
||||||
|
DbType = IocDbType.MySql,
|
||||||
|
ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"),
|
||||||
|
IsAutoCloseConnection = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// 配置Serilog
|
// 配置Serilog
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.ReadFrom.Configuration(builder.Configuration)
|
.ReadFrom.Configuration(builder.Configuration)
|
||||||
@ -26,13 +43,22 @@ Log.Logger = new LoggerConfiguration()
|
|||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
|
||||||
builder.Host.UseSerilog();
|
builder.Host.UseSerilog();
|
||||||
|
builder.Services.AddControllers(options =>
|
||||||
builder.Services.AddControllers();
|
{
|
||||||
|
options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;//Required 不作为必填
|
||||||
|
})
|
||||||
|
.AddJsonOptions(options =>
|
||||||
|
{
|
||||||
|
// 配置返回时间格式转换
|
||||||
|
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeConverter());
|
||||||
|
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
|
||||||
|
}).ConfigureApiBehaviorOptions(opt => opt.SuppressModelStateInvalidFilter = true);//关闭默认模型验证
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
|
||||||
// 跨域配置
|
// 跨域配置
|
||||||
builder.AddCorsRegister();
|
builder.AddCorsRegister();
|
||||||
|
//builder.Services.AddSession();
|
||||||
|
builder.Services.AddHttpClient();
|
||||||
// 注册 Swagger 文档
|
// 注册 Swagger 文档
|
||||||
builder.Services.AddSwaggerGen(option =>
|
builder.Services.AddSwaggerGen(option =>
|
||||||
{
|
{
|
||||||
@ -88,10 +114,9 @@ builder.Services.AddSwaggerGen(option =>
|
|||||||
|
|
||||||
builder.Services.AddInfrastructureServices(builder.Configuration);
|
builder.Services.AddInfrastructureServices(builder.Configuration);
|
||||||
|
|
||||||
|
//注册 HttpContextAccessor
|
||||||
// 初始化SqlSugar
|
builder.Services.AddHttpContextAccessor();
|
||||||
SqlSugarDbContext.Init(builder.Configuration);
|
builder.Services.AddScoped(typeof(BaseRepository<>));
|
||||||
|
|
||||||
|
|
||||||
// 添加CORS
|
// 添加CORS
|
||||||
builder.Services.AddCors(options =>
|
builder.Services.AddCors(options =>
|
||||||
@ -118,7 +143,7 @@ var app = builder.Build();
|
|||||||
c.DocExpansion(DocExpansion.None); // ->修改界面打开时自动折叠
|
c.DocExpansion(DocExpansion.None); // ->修改界面打开时自动折叠
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
app.UseServiceContext();
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
app.UseCors("AllowAll");
|
app.UseCors("AllowAll");
|
||||||
app.UseMiddleware<GlobalExceptionMiddleware>();
|
app.UseMiddleware<GlobalExceptionMiddleware>();
|
||||||
|
|||||||
Reference in New Issue
Block a user