首次提交:本地项目同步到Gitea

This commit is contained in:
zhusenlin
2026-03-02 09:08:20 +08:00
commit 1fb681fb34
371 changed files with 31868 additions and 0 deletions

View File

@@ -0,0 +1,235 @@
using Cowain.Base.DBContext;
using Cowain.Base.Helpers;
using Cowain.Base.IServices;
using Cowain.Base.Models;
using Cowain.Base.Models.Admins;
using Cowain.Base.ViewModels;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.ObjectModel;
using System.Text.Json;
namespace Cowain.Base.Services;
public class AccountService : BaseService, IAccountService
{
private readonly PageViewMenuHelper _pageMenuHelper;
public AccountService(IDbContextFactory<SqlDbContext> dbContextFactory, PageViewMenuHelper pageMenuHelper) : base(dbContextFactory)
{
_pageMenuHelper = pageMenuHelper;
}
public async Task<ResultModel<LoginUserViewModel>> LoginAsync(string userName, string password)
{
using var dbContext = _dbContextFactory.CreateDbContext();
var userDbSet = dbContext.GetDbSet<UserDto>();
var userRoleDbSet = dbContext.GetDbSet<UserRoleDto>();
var data = await (from us in userDbSet
join ur in userRoleDbSet on us.RoleId equals ur.Id
where us.Name == userName && us.Password == DESHelper.Encrypt(password, "ZSL12345")
select new UserViewModel
{
Id = us.Id,
RoleId = us.RoleId,
IsValid = us.IsValid,
Name = us.Name,
Phone = us.Phone,
Sex = us.Sex,
UserNumber = us.UserNumber,
RoleName = ur.RoleName
}).FirstOrDefaultAsync();
//登录成功,需要获取用户菜单
if (data != null)
{
var jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
LoginUserViewModel loginUser = new LoginUserViewModel();
loginUser.User = data;
var userRoleMenus = dbContext.GetDbSet<UserRoleMenuDto>();
var menus = userRoleMenus.Where(x => x.RoleId == data.RoleId);
loginUser.Menus = new ObservableCollection<UserRoleMenuViewModel>(menus.Select(x => new UserRoleMenuViewModel
{
Id = x.Id,
RoleId = x.RoleId,
MenuKey = x.MenuKey,
MenuName = _pageMenuHelper.GetMenuName(x.MenuKey),
MenuActions = new ObservableCollection<string>(JsonSerializer.Deserialize<List<string>>(x.MenuActions ?? "[]", jsonSerializerOptions) ?? new List<string>())
}));
return ResultModel<LoginUserViewModel>.Success(loginUser);
}
return ResultModel<LoginUserViewModel>.Error("login err");
}
public async Task<ResultModel> CheckHealthAsync(CancellationToken cancellationToken = default)
{
using var dbContext = _dbContextFactory.CreateDbContext();
try
{
await dbContext.EnsureCreatedAsync();
var DbSet = dbContext.GetDbSet<UserDto>();
var isHealthy = await DbSet.ToListAsync(cancellationToken);
return ResultModel.Success("An healthy result.");
}
catch
{
return ResultModel.Error("An unhealthy result.");
}
}
public async Task<List<UserViewModel>> GetAllAsync()
{
using var dbContext = _dbContextFactory.CreateDbContext();
var userDbSet = dbContext.GetDbSet<UserDto>();
var userRoleDbSet = dbContext.GetDbSet<UserRoleDto>();
var data = await (from us in userDbSet
join ur in userRoleDbSet on us.RoleId equals ur.Id
select new UserViewModel
{
Id = us.Id,
RoleId = us.RoleId,
IsValid = us.IsValid,
Name = us.Name,
Password = DESHelper.Decrypt(us.Password, "ZSL12345"),
Phone = us.Phone,
Sex = us.Sex,
UserNumber = us.UserNumber,
RoleName = ur.RoleName
}).ToListAsync();
return data;
}
public async Task<(List<UserViewModel>, int totals)> GetAllAsync(int pageIndex, int pageSize)
{
using var dbContext = _dbContextFactory.CreateDbContext();
var userDbSet = dbContext.GetDbSet<UserDto>();
var userRoleDbSet = dbContext.GetDbSet<UserRoleDto>();
var data = (from us in userDbSet
join ur in userRoleDbSet on us.RoleId equals ur.Id
select new UserViewModel
{
Id = us.Id,
RoleId = us.RoleId,
IsValid = us.IsValid,
Name = us.Name,
Password = DESHelper.Decrypt(us.Password, "ZSL12345"),
Phone = us.Phone,
Sex = us.Sex,
UserNumber = us.UserNumber,
RoleName = ur.RoleName
});
var list = await data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
return (list, data.Count());
}
public async Task<ResultModel> AddUserAsync(UserViewModel? user)
{
if (user == null)
{
return ResultModel.Error("User cannot be null");
}
if (string.IsNullOrEmpty(user.Name))
{
return ResultModel.Error("UserName cannot be null");
}
if (user.RoleId == 0)
{
return ResultModel.Error("UserRole cannot be null");
}
if (string.IsNullOrEmpty(user.UserNumber))
{
return ResultModel.Error("UserNumber cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var users = dbContext.GetDbSet<UserDto>();
var existingUser = await users.FirstOrDefaultAsync(x => x.UserNumber == user.UserNumber);
if (existingUser != null)
{
return ResultModel.Error("UserNumber already exists");
}
var entity = new UserDto
{
RoleId = user.RoleId,
Name = user.Name,
Phone = user.Phone ?? string.Empty,
UserNumber = user.UserNumber,
Sex = user.Sex ?? SexMode.Other.ToString(),
Password = DESHelper.Encrypt(user.Password ?? "12345", "ZSL12345"),
IsValid = user.IsValid
};
await users.AddAsync(entity);
await dbContext.SaveChangesAsync();
return ResultModel.Success("User added successfully");
}
public async Task<ResultModel> EditUserAsync(UserViewModel? user)
{
if (user == null)
{
return ResultModel.Error("User cannot be null");
}
if (string.IsNullOrEmpty(user.Name))
{
return ResultModel.Error("UserName cannot be null");
}
if (user.RoleId == 0)
{
return ResultModel.Error("UserRole cannot be null");
}
if (string.IsNullOrEmpty(user.UserNumber))
{
return ResultModel.Error("UserNumber cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var users = dbContext.GetDbSet<UserDto>();
var existingUser = await users.FirstOrDefaultAsync(x => x.Id == user.Id);
if (existingUser == null)
{
return ResultModel.Error("User-id not find");
}
var duplicateUser = await users.FirstOrDefaultAsync(x => x.UserNumber == user.UserNumber && x.Id != user.Id);
if (duplicateUser != null)
{
return ResultModel.Error("UserNumber already exists");
}
existingUser.RoleId = user.RoleId;
existingUser.Name = user.Name;
existingUser.Phone = user.Phone ?? string.Empty;
existingUser.UserNumber = user.UserNumber;
existingUser.Sex = user.Sex ?? SexMode.Other.ToString();
existingUser.Password = DESHelper.Encrypt(user.Password ?? "12345", "ZSL12345");
existingUser.IsValid = user.IsValid;
existingUser.UpdateTime = DateTime.Now;
await dbContext.SaveChangesAsync();
return ResultModel.Success("User edit successfully");
}
public async Task<ResultModel> DelUserAsync(UserViewModel? user)
{
if (user == null)
{
return ResultModel.Error("User cannot be null");
}
if (string.IsNullOrEmpty(user.Name))
{
return ResultModel.Error("UserName cannot be null");
}
if (user.Id == 0)
{
return ResultModel.Error("User-id cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var users = dbContext.GetDbSet<UserDto>();
var existingUser = await users.FirstOrDefaultAsync(x => x.Id == user.Id);
if (existingUser == null)
{
return ResultModel.Error("User-id not find");
}
users.Remove(existingUser);
await dbContext.SaveChangesAsync();
return ResultModel.Success("User deleted successfully");
}
}

View File

@@ -0,0 +1,492 @@
using Cowain.Base.DBContext;
using Microsoft.EntityFrameworkCore;
using MySqlConnector;
using System.Data;
using System.Linq.Expressions;
using Dapper;
using Cowain.Base.IServices;
namespace Cowain.Base.Services;
public class BaseService : IBaseService
{
// 替换为 IDbContextFactory<SqlDbContext>
protected readonly IDbContextFactory<SqlDbContext> _dbContextFactory;
public BaseService(IDbContextFactory<SqlDbContext> dbContextFactory)
{
_dbContextFactory = dbContextFactory;
}
/// <summary>
/// 根据ID删除实体
/// </summary>
public int Delete<T>(int Id) where T : class
{
// 每次操作创建独立上下文using 自动释放
using var dbContext = _dbContextFactory.CreateDbContext();
T? t = dbContext.Set<T>().Find(Id);
if (t == null) throw new KeyNotFoundException($"未找到类型 {typeof(T).Name}Id={Id}");
dbContext.Set<T>().Remove(t);
return dbContext.SaveChanges();
}
/// <summary>
/// 根据ID异步删除实体支持取消
/// </summary>
public async Task<int> DeleteAsync<T>(int Id, CancellationToken cancellationToken = default) where T : class
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
var t = await dbContext.Set<T>().FindAsync(Id, cancellationToken).ConfigureAwait(false);
if (t == null) throw new KeyNotFoundException($"未找到类型 {typeof(T).Name}Id={Id}");
dbContext.Set<T>().Remove(t);
return await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 删除实体
/// </summary>
public int Delete<T>(T t) where T : class
{
ArgumentNullException.ThrowIfNull(t);
using var dbContext = _dbContextFactory.CreateDbContext();
var entry = dbContext.Entry(t);
if (entry.State == EntityState.Detached)
{
dbContext.Set<T>().Attach(t);
}
dbContext.Set<T>().Remove(t);
return dbContext.SaveChanges();
}
/// <summary>
/// 删除实体(异步,支持取消)
/// </summary>
public async Task<int> DeleteAsync<T>(T t, CancellationToken cancellationToken = default) where T : class
{
ArgumentNullException.ThrowIfNull(t);
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
var entry = dbContext.Entry(t);
if (entry.State == EntityState.Detached)
{
dbContext.Set<T>().Attach(t);
}
dbContext.Set<T>().Remove(t);
return await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 批量读取实体
/// </summary>
public List<T> Find<T>() where T : class
{
using var dbContext = _dbContextFactory.CreateDbContext();
return dbContext.Set<T>().ToList();
}
/// <summary>
/// 异步、安全的批量读取(支持取消)
/// </summary>
public async Task<List<T>> FindAsync<T>(CancellationToken cancellationToken = default) where T : class
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
return await dbContext.Set<T>().ToListAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 根据ID查询实体
/// </summary>
public T? Find<T>(int id) where T : class
{
using var dbContext = _dbContextFactory.CreateDbContext();
return dbContext.Set<T>().Find(id);
}
/// <summary>
/// 根据ID异步查询实体支持取消
/// </summary>
public async Task<T?> FindAsync<T>(int id, CancellationToken cancellationToken = default) where T : class
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
return await dbContext.Set<T>().FindAsync(new object[] { id }, cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 带表达式的异步查询(支持取消)
/// </summary>
public async Task<T?> FirstOrDefaultAsync<T>(Expression<Func<T, bool>> funcWhere, CancellationToken cancellationToken = default) where T : class
{
using var dbContext = _dbContextFactory.CreateDbContext();
return await dbContext.Set<T>().Where(funcWhere).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// 插入实体
/// </summary>
public int Insert<T>(T t) where T : class
{
ArgumentNullException.ThrowIfNull(t);
using var dbContext = _dbContextFactory.CreateDbContext();
dbContext.Set<T>().Add(t);
return dbContext.SaveChanges();
}
/// <summary>
/// 异步插入实体
/// </summary>
public async Task<int> InsertAsync<T>(T t, CancellationToken cancellationToken = default) where T : class
{
ArgumentNullException.ThrowIfNull(t);
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
dbContext.Set<T>().Add(t);
return await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 批量插入实体
/// </summary>
public int Insert<T>(IEnumerable<T> tList) where T : class
{
using var dbContext = _dbContextFactory.CreateDbContext();
dbContext.Set<T>().AddRange(tList);
return dbContext.SaveChanges();
}
/// <summary>
/// 批量异步插入实体
/// </summary>
public async Task<int> InsertAsync<T>(IEnumerable<T> tList, CancellationToken cancellationToken = default) where T : class
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
dbContext.Set<T>().AddRange(tList);
return await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 带表达式的查询
/// </summary>
public List<T> Query<T>(Expression<Func<T, bool>>? funcWhere = null) where T : class
{
// 注意Query 返回 IQueryable 时上下文生命周期需由调用方管理或改为立即执行ToList/First 等)
var dbContext = _dbContextFactory.CreateDbContext();
IQueryable<T> query = dbContext.Set<T>();
if (funcWhere is not null)
{
query = query.Where(funcWhere);
}
return query.ToList();
}
/// <summary>
/// 带表达式的异步查询(支持取消、空条件查全部)
/// </summary>
public async Task<List<T>> QueryAsync<T>(
Expression<Func<T, bool>>? funcWhere = null, // 设置默认值,调用更便捷
CancellationToken cancellationToken = default)
where T : class
{
using var dbContext = _dbContextFactory.CreateDbContext();
IQueryable<T> query = dbContext.Set<T>();
if (funcWhere is not null)
{
query = query.Where(funcWhere);
}
return await query.ToListAsync(cancellationToken);
}
/// <summary>
/// 基础版:返回实体列表+总条数(无投影)
/// </summary>
public async Task<(List<T> Data, int TotalCount)> QueryAsync<T, TKey>(
Expression<Func<T, bool>>? funcWhere = null,
Expression<Func<T, TKey>>? orderBy = null,
bool isAscending = true,
int pageIndex = 1,
int pageSize = 20,
CancellationToken cancellationToken = default)
where T : class
{
pageIndex = pageIndex < 1 ? 1 : pageIndex;
pageSize = pageSize < 0 ? 0 : pageSize;
using var dbContext = _dbContextFactory.CreateDbContext();
IQueryable<T> query = dbContext.Set<T>();
if (funcWhere is not null) query = query.Where(funcWhere);
if (orderBy is not null) query = isAscending ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
if (pageSize > 0)
{
long totalCountLong = await query.LongCountAsync(cancellationToken);
int totalCount = (int)Math.Min(totalCountLong, int.MaxValue);
var data = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationToken);
return (data, totalCount);
}
else
{
var data = await query.ToListAsync(cancellationToken);
return (data, data.Count);
}
}
/// <summary>
/// 增强版支持投影Select映射直接返回ViewModel列表+总条数
/// </summary>
/// <typeparam name="T">原实体类型</typeparam>
/// <typeparam name="TKey">排序字段类型</typeparam>
/// <typeparam name="TViewModel">目标ViewModel类型</typeparam>
/// <param name="selectExpression">投影表达式EF会解析为SQL的SELECT字段</param>
public async Task<(List<TViewModel> Data, int TotalCount)> QueryAsync<T, TKey, TViewModel>(
Expression<Func<T, TViewModel>> selectExpression, // 新增:投影映射表达式
Expression<Func<T, bool>>? funcWhere = null,
Expression<Func<T, TKey>>? orderBy = null,
bool isAscending = true,
int pageIndex = 1,
int pageSize = 20,
CancellationToken cancellationToken = default)
where T : class
{
pageIndex = pageIndex < 1 ? 1 : pageIndex;
pageSize = pageSize < 0 ? 0 : pageSize;
using var dbContext = _dbContextFactory.CreateDbContext();
IQueryable<T> query = dbContext.Set<T>();
// 1. 过滤
if (funcWhere is not null) query = query.Where(funcWhere);
// 2. 排序
if (orderBy is not null) query = isAscending ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
// 3. 先查总条数(注意:总条数要在投影前查,避免投影影响计数)
long totalCountLong = await query.LongCountAsync(cancellationToken);
int totalCount = (int)Math.Min(totalCountLong, int.MaxValue);
// 4. 分页+投影EF会转换为SQLSELECT Id, Name, LayOutX, LayOutY FROM ... LIMIT ...
IQueryable<TViewModel> viewModelQuery = query
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.Select(selectExpression); // 内置投影替代手动Select
// 5. 转为List
var data = await viewModelQuery.ToListAsync(cancellationToken);
return (data, totalCount);
}
/// <summary>
/// 更新实体
/// </summary>
public int Update<T>(T t) where T : class
{
ArgumentNullException.ThrowIfNull(t);
using var dbContext = _dbContextFactory.CreateDbContext();
var entry = dbContext.Entry(t);
if (entry.State == EntityState.Detached)
{
dbContext.Set<T>().Attach(t);
}
dbContext.Entry(t).State = EntityState.Modified;
return dbContext.SaveChanges();
}
/// <summary>
/// 异步更新实体(支持取消)
/// </summary>
public async Task<int> UpdateAsync<T>(T t, CancellationToken cancellationToken = default) where T : class
{
ArgumentNullException.ThrowIfNull(t);
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
var entry = dbContext.Entry(t);
if (entry.State == EntityState.Detached)
{
dbContext.Set<T>().Attach(t);
}
dbContext.Entry(t).State = EntityState.Modified;
return await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 批量更新实体
/// </summary>
public int Update<T>(IEnumerable<T> tList) where T : class
{
ArgumentNullException.ThrowIfNull(tList);
var list = tList as IList<T> ?? tList.ToList();
if (list.Count == 0) return 0;
using var dbContext = _dbContextFactory.CreateDbContext();
dbContext.Set<T>().UpdateRange(list);
return dbContext.SaveChanges();
}
/// <summary>
/// 异步批量更新实体(支持取消)
/// </summary>
public async Task<int> UpdateAsync<T>(IEnumerable<T> tList, CancellationToken cancellationToken = default) where T : class
{
ArgumentNullException.ThrowIfNull(tList);
var list = tList as IList<T> ?? tList.ToList();
if (list.Count == 0) return 0;
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
dbContext.Set<T>().UpdateRange(list);
return await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// 使用sql语句获取DataTable
/// </summary>
public DataTable GetDataTable(string sql, IEnumerable<MySqlParameter>? parameters = null)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
// 从工厂创建上下文获取连接字符串
using var dbContext = _dbContextFactory.CreateDbContext();
using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
using var cmd = new MySqlCommand(sql, conn)
{
CommandType = CommandType.Text
};
if (parameters != null)
{
foreach (var p in parameters) cmd.Parameters.Add(p);
}
using var adapter = new MySqlDataAdapter(cmd);
var table = new DataTable();
adapter.Fill(table);
return table;
}
/// <summary>
/// 异步使用sql语句获取DataTable支持取消
/// </summary>
public async Task<DataTable> GetDataTableAsync(string sql, IEnumerable<MySqlParameter>? parameters = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
await conn.OpenAsync(cancellationToken).ConfigureAwait(false);
using var cmd = new MySqlCommand(sql, conn) { CommandType = CommandType.Text };
if (parameters != null) cmd.Parameters.AddRange(parameters.ToArray());
using var reader = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);
var table = new DataTable();
table.Load(reader);
return table;
}
// ================= Dapper 辅助方法 =================
/// <summary>
/// 使用 Dapper 查询并映射到 POCO同步
/// </summary>
public IEnumerable<T> QueryByDapper<T>(string sql, object? param = null)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
using var dbContext = _dbContextFactory.CreateDbContext();
using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
conn.Open();
return conn.Query<T>(sql, param);
}
/// <summary>
/// 使用 Dapper 查询并映射到 POCO异步支持 CancellationToken
/// </summary>
public async Task<IEnumerable<T>> QueryByDapperAsync<T>(string sql, object? param = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
await conn.OpenAsync(cancellationToken).ConfigureAwait(false);
var command = new CommandDefinition(sql, param, cancellationToken: cancellationToken);
var result = await conn.QueryAsync<T>(command).ConfigureAwait(false);
return result;
}
/// <summary>
/// 使用 Dapper 查询单条记录(同步)
/// </summary>
public T? QueryFirstOrDefaultByDapper<T>(string sql, object? param = null)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
using var dbContext = _dbContextFactory.CreateDbContext();
using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
conn.Open();
return conn.QueryFirstOrDefault<T>(sql, param);
}
/// <summary>
/// 使用 Dapper 查询单条记录(异步)
/// </summary>
public async Task<T?> QueryFirstOrDefaultByDapperAsync<T>(string sql, object? param = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
await conn.OpenAsync(cancellationToken).ConfigureAwait(false);
var command = new CommandDefinition(sql, param, cancellationToken: cancellationToken);
return await conn.QueryFirstOrDefaultAsync<T>(command).ConfigureAwait(false);
}
/// <summary>
/// 使用 Dapper 执行非查询 SQL同步返回受影响行数
/// </summary>
public int ExecuteByDapper(string sql, object? param = null)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
using var dbContext = _dbContextFactory.CreateDbContext();
using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
conn.Open();
return conn.Execute(sql, param);
}
/// <summary>
/// 使用 Dapper 执行非查询 SQL异步返回受影响行数
/// </summary>
public async Task<int> ExecuteByDapperAsync(string sql, object? param = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
await conn.OpenAsync(cancellationToken).ConfigureAwait(false);
var command = new CommandDefinition(sql, param, cancellationToken: cancellationToken);
return await conn.ExecuteAsync(command).ConfigureAwait(false);
}
/// <summary>
/// 使用 Dapper 执行 SQL 并返回 DataTable异步支持 CancellationToken
/// </summary>
public async Task<DataTable> QueryToDataTableByDapperAsync(string sql, object? param = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
await conn.OpenAsync(cancellationToken).ConfigureAwait(false);
var command = new CommandDefinition(sql, param, cancellationToken: cancellationToken, flags: CommandFlags.Buffered);
await using var reader = await conn.ExecuteReaderAsync(command).ConfigureAwait(false);
var table = new DataTable();
table.Load(reader);
return table;
}
/// <summary>
/// 使用 Dapper 执行 SQL 并返回 DataTable同步
/// </summary>
public DataTable QueryToDataTableByDapper(string sql, object? param = null)
{
if (string.IsNullOrWhiteSpace(sql)) throw new ArgumentException("sql 不能为空", nameof(sql));
using var dbContext = _dbContextFactory.CreateDbContext();
using var conn = new MySqlConnection(dbContext.Database.GetConnectionString());
conn.Open();
using var reader = conn.ExecuteReader(sql, param);
var table = new DataTable();
table.Load(reader);
return table;
}
}

View File

@@ -0,0 +1,57 @@
using Cowain.Base.DBContext;
using Cowain.Base.IServices;
using Cowain.Base.Models;
using Cowain.Base.ViewModels;
using Microsoft.EntityFrameworkCore;
namespace Cowain.Base.Services;
public class LogService : BaseService, ILogService
{
public LogService(IDbContextFactory<SqlDbContext> dbContextFactory) : base(dbContextFactory)
{
}
public async Task<List<SerilogViewModel>> GetAllAsync()
{
var data = await FindAsync<SerilogDto>();
return new List<SerilogViewModel>(data.Select(x => new SerilogViewModel
{
Id = x.id,
Template = x.Template,
Message = x.Message,
Exception = x.Exception,
Properties = x.Properties,
Level = x.Level,
Timestamp = x.Timestamp
}));
}
/// <summary>
/// 分页获取日志复用BaseService的FindAsync+内存分页)
/// </summary>
public async Task<(List<SerilogViewModel>, int totals)> GetAllAsync(int pageIndex, int pageSize)
{
// 复用BaseService的异步查询方法
var allData = await FindAsync<SerilogDto>();
// 分页处理
var paginatedData = allData
.OrderByDescending(x => x.id)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.Select(x => new SerilogViewModel
{
Id = x.id,
Template = x.Template,
Message = x.Message,
Exception = x.Exception,
Properties = x.Properties,
Level = x.Level,
Timestamp = x.Timestamp
})
.ToList();
return (paginatedData, allData.Count);
}
}

View File

@@ -0,0 +1,152 @@
using Avalonia;
using Cowain.Base.DBContext;
using Cowain.Base.Helpers;
using Cowain.Base.IServices;
using Cowain.Base.Models;
using Cowain.Base.Models.Admins;
using Cowain.Base.Models.Menu;
using Cowain.Base.ViewModels;
using Ke.Bee.Localization.Localizer.Abstractions;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.Json;
using MenuItem = Cowain.Base.Models.Menu.MenuItem;
namespace Cowain.Base.Services;
public class UserRoleMenuService : BaseService, IUserRoleMenuService
{
/// <summary>
/// 菜单数据
/// </summary>
private readonly List<MenuItem> _menuItems;
private readonly PageViewMenuHelper _pageMenuHelper;
public UserRoleMenuService(IDbContextFactory<SqlDbContext> dbContextFactory, PageViewMenuHelper pageMenuHelper, MenuConfigurationContext menuContext) : base(dbContextFactory)
{
_menuItems = menuContext.Menus;
_pageMenuHelper = pageMenuHelper;
}
public async Task<List<UserRoleViewModel>> GetAllAsync()
{
using var dbContext = _dbContextFactory.CreateDbContext();
var userRoles = dbContext.GetDbSet<UserRoleDto>();
var userRoleMenus = dbContext.GetDbSet<UserRoleMenuDto>();
var jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var result = await (from ur in userRoles
join urm in userRoleMenus on ur.Id equals urm.RoleId into urms
select new UserRoleViewModel
{
RoleId = ur.Id,
RoleName = ur.RoleName,
IsValid = ur.IsValid,
Menus = new ObservableCollection<UserRoleMenuViewModel>(urms.Select(urm => new UserRoleMenuViewModel
{
Id = urm.Id,
RoleId = urm.RoleId,
MenuKey = urm.MenuKey,
MenuName = _pageMenuHelper.GetMenuName(urm.MenuKey),
MenuActions = new ObservableCollection<string>(JsonSerializer.Deserialize<List<string>>(urm.MenuActions ?? "[]", jsonSerializerOptions) ?? new List<string>())
}).ToList())
}).ToListAsync();
return result ?? new List<UserRoleViewModel>();
}
public async Task<ResultModel> EditUserRoleMenuAsync(UserRoleViewModel? userRole)
{
if (userRole == null)
{
return ResultModel.Error("UserRole cannot be null");
}
if (string.IsNullOrEmpty(userRole.RoleName))
{
return ResultModel.Error("UserRoleName cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var userRoleMenus = dbContext.GetDbSet<UserRoleMenuDto>();
// 删除旧的菜单
var oldMenus = userRoleMenus.Where(urm => urm.RoleId == userRole.RoleId);
dbContext.RemoveRange(oldMenus);
// 添加新的菜单
var newMenus = userRole.Menus?.Select(menu => new UserRoleMenuDto
{
RoleId = userRole.RoleId,
MenuKey = menu.MenuKey,
MenuActions = JsonSerializer.Serialize(menu.MenuActions)
}).ToList();
if (newMenus != null)
{
await userRoleMenus.AddRangeAsync(newMenus);
var ret = await dbContext.SaveChangesAsync();
// 添加完新的数据后id需要告诉userRole的Menus
var addedMenus = await userRoleMenus.Where(urm => urm.RoleId == userRole.RoleId).ToListAsync();
if (userRole.Menus != null)
{
for (int i = 0; i < userRole.Menus.Count; i++)
{
userRole.Menus[i].Id = addedMenus[i].Id;
}
}
return ResultModel.Success($"UserRoleMenu updated successfullycount is {ret}");
}
else
{
var ret = await dbContext.SaveChangesAsync();
return ResultModel.Success($"UserRoleMenu updated successfullycount is {ret}");
}
}
public async Task<ResultModel> EditMenuActionsAsync(UserRoleMenuViewModel? userRoleMenu)
{
if (userRoleMenu == null)
{
return ResultModel.Error("UserRoleMenu cannot be null");
}
if (string.IsNullOrEmpty(userRoleMenu.MenuKey))
{
return ResultModel.Error("MenuKey cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var userRoleMenus = dbContext.GetDbSet<UserRoleMenuDto>();
var menu = await userRoleMenus.FirstOrDefaultAsync(urm => urm.Id == userRoleMenu.Id);
if (menu == null)
{
return ResultModel.Error("UserRoleMenu Actions not found");
}
menu.MenuActions = JsonSerializer.Serialize(userRoleMenu.MenuActions);
dbContext.Update(menu);
var ret = await dbContext.SaveChangesAsync();
return ResultModel.Success($"UserRoleMenu Actions updated successfullycount is {ret}");
}
public async Task<ResultModel> DeleteMenuActionsAsync(UserRoleMenuViewModel? userRoleMenu)
{
if (userRoleMenu == null)
{
return ResultModel.Error("UserRoleMenu cannot be null");
}
if (string.IsNullOrEmpty(userRoleMenu.MenuKey))
{
return ResultModel.Error("MenuKey cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var userRoleMenus = dbContext.GetDbSet<UserRoleMenuDto>();
var menu = await userRoleMenus.FirstOrDefaultAsync(urm => urm.Id == userRoleMenu.Id);
if (menu == null)
{
return ResultModel.Error("UserRoleMenu Actions not found");
}
var ret = await DeleteAsync<UserRoleMenuDto>(menu);
return ResultModel.Success($"UserRoleMenu Actions remove successfullycount is {ret}");
}
}

View File

@@ -0,0 +1,133 @@
using Cowain.Base.DBContext;
using Cowain.Base.IServices;
using Cowain.Base.Models;
using Cowain.Base.Models.Admins;
using Cowain.Base.ViewModels;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Cowain.Base.Services;
public class UserRoleService : BaseService, IUserRoleService
{
public UserRoleService(IDbContextFactory<SqlDbContext> dbContextFactory) : base(dbContextFactory)
{
}
public async Task<ResultModel> AddUserRoleAsync(UserRoleViewModel? userRole)
{
if (userRole == null)
{
return ResultModel.Error("UserRole cannot be null");
}
if (string.IsNullOrEmpty(userRole.RoleName))
{
return ResultModel.Error("UserRoleName cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var DbSet = dbContext.GetDbSet<UserRoleDto>();
var existingRole = await DbSet.FirstOrDefaultAsync(x => x.RoleName == userRole.RoleName);
if (existingRole != null)
{
return ResultModel.Error("UserRoleName already exists");
}
var entity = new UserRoleDto
{
Id = userRole.RoleId,
RoleName = userRole.RoleName,
IsValid = userRole.IsValid
};
await DbSet.AddAsync(entity);
await dbContext.SaveChangesAsync();
return ResultModel.Success("UserRole added successfully");
}
public async Task<ResultModel> EditUserRoleAsync(UserRoleViewModel? userRole)
{
if (userRole == null)
{
return ResultModel.Error("UserRole cannot be null");
}
if (string.IsNullOrEmpty(userRole.RoleName))
{
return ResultModel.Error("UserRoleName cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var DbSet = dbContext.GetDbSet<UserRoleDto>();
var existingRole = await DbSet.FirstOrDefaultAsync(x => x.Id == userRole.RoleId);
if (existingRole == null)
{
return ResultModel.Error("UserRoleName no exists");
}
var duplicateRole = await DbSet.FirstOrDefaultAsync(x => x.RoleName == userRole.RoleName && x.Id != userRole.RoleId);
if (duplicateRole != null)
{
return ResultModel.Error("UserRoleName already exists");
}
existingRole.IsValid = userRole.IsValid;
existingRole.RoleName = userRole.RoleName;
existingRole.UpdateTime = DateTime.Now;
await dbContext.SaveChangesAsync();
return ResultModel.Success("UserRole updated successfully");
}
public async Task<ResultModel> DelUserRoleAsync(UserRoleViewModel? userRole)
{
if (userRole == null)
{
return ResultModel.Error("UserRole cannot be null");
}
if (string.IsNullOrEmpty(userRole.RoleName))
{
return ResultModel.Error("UserRoleName cannot be null");
}
using var dbContext = _dbContextFactory.CreateDbContext();
var DbSet = dbContext.GetDbSet<UserRoleDto>();
var entity = await DbSet.FirstOrDefaultAsync(x => x.Id == userRole.RoleId);
if (entity == null)
{
return ResultModel.Error("UserRole not found");
}
// 删除UserRole还要将UserRoleMenu表中RoleId相同的项也同时删除
var userRoleMenuDbSet = dbContext.GetDbSet<UserRoleMenuDto>();
var userRoleMenus = await userRoleMenuDbSet.Where(x => x.RoleId == userRole.RoleId).ToListAsync();
userRoleMenuDbSet.RemoveRange(userRoleMenus);
DbSet.Remove(entity);
await dbContext.SaveChangesAsync();
return ResultModel.Success("UserRole and related UserRoleMenus deleted successfully");
}
public async Task<List<UserRoleViewModel>> GetAllAsync()
{
using var dbContext = _dbContextFactory.CreateDbContext();
var DbSet = dbContext.GetDbSet<UserRoleDto>();
var data = await DbSet.ToListAsync();
return new List<UserRoleViewModel>(data.Select(x => new UserRoleViewModel
{
RoleId = x.Id,
RoleName = x.RoleName,
IsValid = x.IsValid
}));
}
public async Task<(List<UserRoleViewModel>, int totals)> GetAllAsync(int pageIndex, int pageSize)
{
using var dbContext = _dbContextFactory.CreateDbContext();
var DbSet = dbContext.GetDbSet<UserRoleDto>();
var data = await DbSet.ToListAsync();
var list = data.Skip((pageIndex - 1) * pageSize).Take(pageSize);
return (new List<UserRoleViewModel>(list.Select(x => new UserRoleViewModel
{
RoleId = x.Id,
RoleName = x.RoleName,
IsValid = x.IsValid
})), data.Count());
}
}