// ============================================================================
// 【文件说明】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);
}
}
}