// ============================================================================ // 【文件说明】HwWeb1Service.cs - 网页内容服务类 // ============================================================================ // 这个服务类负责处理网页内容的业务逻辑,包括: // - 网页内容的 CRUD 操作 // - 多维度查询(网站代码、设备ID、类型ID) // - 搜索索引重建 // // 【业务背景】 // 网页内容模块用于管理网站的页面内容,支持按网站代码、设备类型、页面类型等多维度管理。 // // 【与 Java Spring Boot 的对比】 // Java Spring Boot: // @Service // public class HwWeb1ServiceImpl implements HwWeb1Service { ... } // // ASP.NET Core + Furion: // public class HwWeb1Service : ITransient { ... } // ============================================================================ namespace Admin.NET.Plugin.HwPortal; /// /// 网页内容服务类。 /// /// 【服务职责】 /// 1. 管理网页内容的增删改查 /// 2. 支持多维度查询(网站代码、设备ID、类型ID) /// 3. 网页内容变更时自动重建搜索索引 /// /// /// 【更新策略】 /// 更新操作采用"先删除后插入"的策略: /// 先删除符合条件的旧记录,然后插入新记录。 /// 这种策略简化了更新逻辑,但会改变记录的ID。 /// /// public class HwWeb1Service : ITransient { /// /// MyBatis 映射器名称(保留用于回滚)。 /// private const string Mapper = "HwWebMapper1"; /// /// MyBatis 执行器(保留用于回滚)。 /// private readonly HwPortalMyBatisExecutor _executor; /// /// SqlSugar 数据访问对象。 /// private readonly ISqlSugarClient _db; /// /// 搜索索引重建服务。 /// private readonly IHwSearchRebuildService _searchRebuildService; /// /// 日志记录器。 /// private readonly ILogger _logger; /// /// 构造函数(依赖注入)。 /// /// MyBatis 执行器 /// SqlSugar 数据访问对象 /// 搜索索引重建服务 /// 日志记录器 public HwWeb1Service(HwPortalMyBatisExecutor executor, ISqlSugarClient db, IHwSearchRebuildService searchRebuildService, ILogger logger) { _executor = executor; _db = db; _searchRebuildService = searchRebuildService; _logger = logger; } /// /// 根据网站代码查询网页内容。 /// /// 【软删除过滤】 /// 查询时自动过滤已删除的记录(IsDelete == "0")。 /// /// /// 网站代码 /// 网页内容实体 public async Task SelectHwWebByWebcode(long webCode) { // 回滚到 XML 方案时可直接恢复: // return await _executor.QuerySingleAsync(Mapper, "selectHwWebByWebcode", new { webCode }); return await _db.Queryable() .Where(item => item.IsDelete == "0" && item.WebCode == webCode) .FirstAsync(); } /// /// 查询单个网页内容(多维度匹配)。 /// /// 【多维度匹配】 /// 按网站代码、设备ID、类型ID三个维度精确匹配。 /// /// /// 查询条件 /// 网页内容实体 public async Task SelectHwWebOne(HwWeb1 input) { HwWeb1 query = input ?? new HwWeb1(); // 回滚到 XML 方案时可直接恢复: // return await _executor.QuerySingleAsync(Mapper, "selectHwWebOne", query); return await _db.Queryable() .Where(item => item.IsDelete == "0" && item.WebCode == query.WebCode && item.DeviceId == query.DeviceId && item.TypeId == query.TypeId) .FirstAsync(); } /// /// 查询网页内容列表。 /// /// 【动态查询条件】 /// 支持按网页ID、JSON内容、网站代码、设备ID、类型ID、英文JSON等条件筛选。 /// /// /// 查询条件 /// 网页内容列表 public async Task> SelectHwWebList(HwWeb1 input) { HwWeb1 query = input ?? new HwWeb1(); // 回滚到 XML 方案时可直接恢复: // return await _executor.QueryListAsync(Mapper, "selectHwWebList", query); return await _db.Queryable() .Where(item => item.IsDelete == "0") .WhereIF(query.WebId.HasValue, item => item.WebId == query.WebId) .WhereIF(query.WebJson != null && query.WebJson != string.Empty, item => item.WebJson == query.WebJson) .WhereIF(query.WebJsonString != null && query.WebJsonString != string.Empty, item => item.WebJsonString == query.WebJsonString) .WhereIF(query.WebCode.HasValue, item => item.WebCode == query.WebCode) .WhereIF(query.DeviceId.HasValue, item => item.DeviceId == query.DeviceId) .WhereIF(query.TypeId.HasValue, item => item.TypeId == query.TypeId) .WhereIF(query.WebJsonEnglish != null, item => item.WebJsonEnglish == query.WebJsonEnglish) .ToListAsync(); } /// /// 新增网页内容。 /// /// 【搜索索引重建】 /// 网页内容新增后,自动触发搜索索引重建。 /// /// /// 网页内容数据 /// 影响行数 public async Task InsertHwWeb(HwWeb1 input) { // 【软删除标记初始化】 input.IsDelete = string.IsNullOrWhiteSpace(input.IsDelete) ? "0" : input.IsDelete; // 回滚到 XML 方案时可直接恢复: // long identity = await _executor.InsertReturnIdentityAsync(Mapper, "insertHwWeb", input); HwWeb1 entity = await _db.Insertable(input).ExecuteReturnEntityAsync(); input.WebId = entity.WebId; // 【搜索索引重建】 if (input.WebId > 0) { await RebuildSearchIndexQuietly("hw_web1"); } return input.WebId > 0 ? 1 : 0; } /// /// 更新网页内容。 /// /// 【更新策略】 /// 采用"先删除后插入"的策略: /// 1. 先查询并删除符合条件的旧记录(软删除) /// 2. 设置新记录的 IsDelete = "0" /// 3. 插入新记录 /// /// 这种策略简化了更新逻辑,但会改变记录的ID。 /// /// /// 【搜索索引重建】 /// 网页内容更新后,自动触发搜索索引重建。 /// /// /// 更新的数据 /// 影响行数 public async Task UpdateHwWeb(HwWeb1 input) { // 【查询旧记录】 HwWeb1 query = new() { WebCode = input.WebCode, TypeId = input.TypeId, DeviceId = input.DeviceId }; List exists = await SelectHwWebList(query); // 【删除旧记录】 if (exists.Count > 0) { await DeleteHwWebByWebIds(exists.Where(u => u.WebId.HasValue).Select(u => u.WebId!.Value).ToArray(), false); } // 【设置新记录】 input.IsDelete = "0"; // 回滚到 XML 方案时可直接恢复: // long identity = await _executor.InsertReturnIdentityAsync(Mapper, "insertHwWeb", input); HwWeb1 entity = await _db.Insertable(input).ExecuteReturnEntityAsync(); input.WebId = entity.WebId; // 【搜索索引重建】 if (input.WebId > 0) { await RebuildSearchIndexQuietly("hw_web1"); } return input.WebId > 0 ? 1 : 0; } /// /// 批量删除网页内容(软删除)。 /// /// 网页ID数组 /// 影响行数 public Task DeleteHwWebByWebIds(long[] webIds) { return DeleteHwWebByWebIds(webIds, true); } /// /// 批量删除网页内容(软删除)。 /// /// 【软删除实现】 /// 将 IsDelete 字段更新为"1",而不是物理删除。 /// /// /// 【搜索索引重建】 /// 网页内容删除后,自动触发搜索索引重建。 /// /// /// 网页ID数组 /// 是否重建搜索索引 /// 影响行数 private async Task DeleteHwWebByWebIds(long[] webIds, bool rebuild) { // 回滚到 XML 方案时可直接恢复: // int rows = await _executor.ExecuteAsync(Mapper, "deleteHwWebByWebIds", new { array = webIds }); // 【查询待删除的网页】 List pages = await _db.Queryable() .Where(item => item.WebId.HasValue && webIds.Contains(item.WebId.Value)) .ToListAsync(); // 【软删除标记】 foreach (HwWeb1 page in pages) { page.IsDelete = "1"; } // 【批量更新】 int rows = pages.Count == 0 ? 0 : await _db.Updateable(pages) .UpdateColumns(item => new { item.IsDelete }) .ExecuteCommandAsync(); // 【搜索索引重建】 if (rows > 0 && rebuild) { await RebuildSearchIndexQuietly("hw_web1"); } return rows; } /// /// 静默重建搜索索引。 /// /// 数据来源 private async Task RebuildSearchIndexQuietly(string source) { try { await _searchRebuildService.RebuildAllAsync(); } catch (Exception ex) { _logger.LogError(ex, "rebuild portal search index failed after {Source} changed", source); } } }