Files
EmailBill/Repository/BaseRepository.cs
孙诚 ef4ed9fd57
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 6s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 2s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
feat: Implement scheduled tasks management and budget archiving functionality
- Added BudgetArchiveJob for monthly budget archiving.
- Created BudgetArchive entity and BudgetArchiveRepository for managing archived budgets.
- Introduced JobController for handling job execution, pausing, and resuming.
- Developed ScheduledTasksView for displaying and managing scheduled tasks in the frontend.
- Updated PeriodicBillJob to improve scope handling.
- Enhanced OpenAiService with increased HTTP timeout.
- Added archiveBudgets API endpoint for archiving budgets by year and month.
- Refactored BudgetController to utilize new repository patterns and improved error handling.
- Introduced rich-content styles for better rendering of HTML content in Vue components.
- Updated various Vue components to support rich HTML content display.
2026-01-09 14:03:01 +08:00

186 lines
4.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace Repository;
/// <summary>
/// 仓储基础接口
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
public interface IBaseRepository<T> where T : BaseEntity
{
/// <summary>
/// 获取所有数据
/// </summary>
Task<IEnumerable<T>> GetAllAsync();
/// <summary>
/// 根据ID获取单条数据
/// </summary>
Task<T?> GetByIdAsync(long id);
/// <summary>
/// 根据ID获取单条数据
/// </summary>
Task<T[]> GetByIdsAsync(long[] ids);
/// <summary>
/// 添加数据
/// </summary>
Task<bool> AddAsync(T entity);
/// <summary>
/// 添加数据
/// </summary>
Task<bool> AddRangeAsync(IEnumerable<T> entities);
/// <summary>
/// 更新数据
/// </summary>
Task<bool> UpdateAsync(T entity);
/// <summary>
/// 批量更新数据
/// </summary>
Task<bool> UpdateRangeAsync(IEnumerable<T> entities);
/// <summary>
/// 删除数据
/// </summary>
Task<bool> DeleteAsync(long id);
/// <summary>
/// 执行动态SQL查询返回动态对象
/// </summary>
/// <param name="completeSql">完整的SELECT SQL语句</param>
/// <returns>动态查询结果列表</returns>
Task<List<dynamic>> ExecuteDynamicSqlAsync(string completeSql);
}
/// <summary>
/// 仓储基类实现 - 基于 FreeSql
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
public abstract class BaseRepository<T>(IFreeSql freeSql) : IBaseRepository<T> where T : BaseEntity
{
protected readonly IFreeSql FreeSql = freeSql ?? throw new ArgumentNullException(nameof(freeSql));
public virtual async Task<IEnumerable<T>> GetAllAsync()
{
try
{
return await FreeSql.Select<T>().ToListAsync();
}
catch
{
return [];
}
}
public virtual async Task<T?> GetByIdAsync(long id)
{
try
{
// FreeSql 会根据配置自动识别主键
return await FreeSql.Select<T>().Where(x => x.Id == id).FirstAsync();
}
catch
{
return null;
}
}
public virtual async Task<T[]> GetByIdsAsync(long[] ids)
{
try
{
var result = await FreeSql.Select<T>().Where(x => ids.Contains(x.Id)).ToListAsync();
return result.ToArray();
}
catch
{
return [];
}
}
public virtual async Task<bool> AddAsync(T entity)
{
try
{
var result = await FreeSql.Insert(entity).ExecuteAffrowsAsync();
return result == 1;
}
catch
{
return false;
}
}
public async Task<bool> AddRangeAsync(IEnumerable<T> entities)
{
var result = await FreeSql.Insert(entities).ExecuteAffrowsAsync();
return result == entities.Count();
}
public virtual async Task<bool> UpdateAsync(T entity)
{
try
{
var affrows = await FreeSql.Update<T>()
.SetSource(entity)
.ExecuteAffrowsAsync();
return affrows > 0;
}
catch (Exception ex)
{
Console.WriteLine($"Update failed: {ex.Message}");
return false;
}
}
public virtual async Task<bool> UpdateRangeAsync(IEnumerable<T> entities)
{
try
{
var affrows = await FreeSql.Update<T>()
.SetSource(entities)
.ExecuteAffrowsAsync();
return affrows == entities.Count();
}
catch (Exception ex)
{
Console.WriteLine($"UpdateRange failed: {ex.Message}");
return false;
}
}
public virtual async Task<bool> DeleteAsync(long id)
{
try
{
var affrows = await FreeSql.Delete<T>().Where(x => x.Id == id).ExecuteAffrowsAsync();
return affrows > 0;
}
catch
{
return false;
}
}
public async Task<List<dynamic>> ExecuteDynamicSqlAsync(string completeSql)
{
var dt = await FreeSql.Ado.ExecuteDataTableAsync(completeSql);
var result = new List<dynamic>();
foreach (System.Data.DataRow row in dt.Rows)
{
var expando = new System.Dynamic.ExpandoObject() as IDictionary<string, object>;
foreach (System.Data.DataColumn column in dt.Columns)
{
expando[column.ColumnName] = row[column];
}
result.Add(expando);
}
return result;
}
}