using MyHomePage.Api.Common; using MyHomePage.Api.Models.Dtos; using MyHomePage.Api.Models.Entities; using SqlSugar; namespace MyHomePage.Api.Services; /// public class SearchEngineService : ISearchEngineService { private readonly ISqlSugarClient _db; private readonly SyncLogHelper _sync; public SearchEngineService(ISqlSugarClient db, SyncLogHelper sync) { _db = db; _sync = sync; } /// public async Task> ListAsync() { var list = await _db.Queryable() .OrderBy(e => e.Sort) .OrderBy(e => e.Id) .ToListAsync(); return list.Select(SearchEngineDto.FromEntity).ToList(); } /// public async Task GetByIdAsync(int id) { var e = await _db.Queryable().InSingleAsync(id); return e is null ? null : SearchEngineDto.FromEntity(e); } /// public async Task CreateAsync(SearchEngineUpsertRequest request) { Validate(request); var now = DateTime.UtcNow; var entity = new SearchEngine { Name = request.Name.Trim(), UrlTemplate = request.UrlTemplate.Trim(), IconType = request.IconType, Icon = request.Icon, IconUrl = request.IconUrl, ColorBg = request.ColorBg, Sort = request.Sort, IsDefault = request.IsDefault, CreatedAt = now, UpdatedAt = now }; entity.Id = await _db.Insertable(entity).ExecuteReturnIdentityAsync(); if (entity.IsDefault) await ResetDefaultAsync(entity.Id); await _sync.WriteAsync("search_engine", entity.Id, "create"); return SearchEngineDto.FromEntity(entity); } /// public async Task UpdateAsync(int id, SearchEngineUpsertRequest request) { Validate(request); var entity = await _db.Queryable().InSingleAsync(id) ?? throw new BusinessException("搜索引擎不存在", 404); entity.Name = request.Name.Trim(); entity.UrlTemplate = request.UrlTemplate.Trim(); entity.IconType = request.IconType; entity.Icon = request.Icon; entity.IconUrl = request.IconUrl; entity.ColorBg = request.ColorBg; entity.Sort = request.Sort; entity.IsDefault = request.IsDefault; entity.UpdatedAt = DateTime.UtcNow; await _db.Updateable(entity).ExecuteCommandAsync(); if (entity.IsDefault) await ResetDefaultAsync(entity.Id); await _sync.WriteAsync("search_engine", id, "update"); return SearchEngineDto.FromEntity(entity); } /// public async Task DeleteAsync(int id) { var entity = await _db.Queryable().InSingleAsync(id) ?? throw new BusinessException("搜索引擎不存在", 404); await _db.Deleteable(id).ExecuteCommandAsync(); await _sync.WriteAsync("search_engine", id, "delete"); } /// public async Task SetDefaultAsync(int id) { var entity = await _db.Queryable().InSingleAsync(id) ?? throw new BusinessException("搜索引擎不存在", 404); await ResetDefaultAsync(id); entity.IsDefault = true; entity.UpdatedAt = DateTime.UtcNow; await _db.Updateable(entity).ExecuteCommandAsync(); await _sync.WriteAsync("search_engine", id, "update"); return SearchEngineDto.FromEntity(entity); } /// 把其他引擎的 IsDefault 全部置为 false private async Task ResetDefaultAsync(int keepId) { await _db.Updateable() .SetColumns(e => e.IsDefault == false) .Where(e => e.Id != keepId && e.IsDefault) .ExecuteCommandAsync(); } private static void Validate(SearchEngineUpsertRequest req) { if (string.IsNullOrWhiteSpace(req.Name)) throw new BusinessException("名称不能为空", 400); if (string.IsNullOrWhiteSpace(req.UrlTemplate)) throw new BusinessException("URL 模板不能为空", 400); if (!req.UrlTemplate.Contains("{q}")) throw new BusinessException("URL 模板必须包含 {q} 占位符", 400); } }