|
|
// ============================================================================
|
|
|
// 【文件说明】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;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 网页内容服务类。
|
|
|
/// <para>
|
|
|
/// 【服务职责】
|
|
|
/// 1. 管理网页内容的增删改查
|
|
|
/// 2. 支持多维度查询(网站代码、设备ID、类型ID)
|
|
|
/// 3. 网页内容变更时自动重建搜索索引
|
|
|
/// </para>
|
|
|
/// <para>
|
|
|
/// 【更新策略】
|
|
|
/// 更新操作采用"先删除后插入"的策略:
|
|
|
/// 先删除符合条件的旧记录,然后插入新记录。
|
|
|
/// 这种策略简化了更新逻辑,但会改变记录的ID。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
public class HwWeb1Service : ITransient
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// MyBatis 映射器名称(保留用于回滚)。
|
|
|
/// </summary>
|
|
|
private const string Mapper = "HwWebMapper1";
|
|
|
|
|
|
/// <summary>
|
|
|
/// MyBatis 执行器(保留用于回滚)。
|
|
|
/// </summary>
|
|
|
private readonly HwPortalMyBatisExecutor _executor;
|
|
|
|
|
|
/// <summary>
|
|
|
/// SqlSugar 数据访问对象。
|
|
|
/// </summary>
|
|
|
private readonly ISqlSugarClient _db;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 搜索索引重建服务。
|
|
|
/// </summary>
|
|
|
private readonly IHwSearchRebuildService _searchRebuildService;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 日志记录器。
|
|
|
/// </summary>
|
|
|
private readonly ILogger<HwWeb1Service> _logger;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 构造函数(依赖注入)。
|
|
|
/// </summary>
|
|
|
/// <param name="executor">MyBatis 执行器</param>
|
|
|
/// <param name="db">SqlSugar 数据访问对象</param>
|
|
|
/// <param name="searchRebuildService">搜索索引重建服务</param>
|
|
|
/// <param name="logger">日志记录器</param>
|
|
|
public HwWeb1Service(HwPortalMyBatisExecutor executor, ISqlSugarClient db, IHwSearchRebuildService searchRebuildService, ILogger<HwWeb1Service> logger)
|
|
|
{
|
|
|
_executor = executor;
|
|
|
_db = db;
|
|
|
_searchRebuildService = searchRebuildService;
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据网站代码查询网页内容。
|
|
|
/// <para>
|
|
|
/// 【软删除过滤】
|
|
|
/// 查询时自动过滤已删除的记录(IsDelete == "0")。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="webCode">网站代码</param>
|
|
|
/// <returns>网页内容实体</returns>
|
|
|
public async Task<HwWeb1> SelectHwWebByWebcode(long webCode)
|
|
|
{
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// return await _executor.QuerySingleAsync<HwWeb1>(Mapper, "selectHwWebByWebcode", new { webCode });
|
|
|
return await _db.Queryable<HwWeb1>()
|
|
|
.Where(item => item.IsDelete == "0" && item.WebCode == webCode)
|
|
|
.FirstAsync();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查询单个网页内容(多维度匹配)。
|
|
|
/// <para>
|
|
|
/// 【多维度匹配】
|
|
|
/// 按网站代码、设备ID、类型ID三个维度精确匹配。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="input">查询条件</param>
|
|
|
/// <returns>网页内容实体</returns>
|
|
|
public async Task<HwWeb1> SelectHwWebOne(HwWeb1 input)
|
|
|
{
|
|
|
HwWeb1 query = input ?? new HwWeb1();
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// return await _executor.QuerySingleAsync<HwWeb1>(Mapper, "selectHwWebOne", query);
|
|
|
return await _db.Queryable<HwWeb1>()
|
|
|
.Where(item => item.IsDelete == "0" && item.WebCode == query.WebCode && item.DeviceId == query.DeviceId && item.TypeId == query.TypeId)
|
|
|
.FirstAsync();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查询网页内容列表。
|
|
|
/// <para>
|
|
|
/// 【动态查询条件】
|
|
|
/// 支持按网页ID、JSON内容、网站代码、设备ID、类型ID、英文JSON等条件筛选。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="input">查询条件</param>
|
|
|
/// <returns>网页内容列表</returns>
|
|
|
public async Task<List<HwWeb1>> SelectHwWebList(HwWeb1 input)
|
|
|
{
|
|
|
HwWeb1 query = input ?? new HwWeb1();
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// return await _executor.QueryListAsync<HwWeb1>(Mapper, "selectHwWebList", query);
|
|
|
return await _db.Queryable<HwWeb1>()
|
|
|
.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();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 新增网页内容。
|
|
|
/// <para>
|
|
|
/// 【搜索索引重建】
|
|
|
/// 网页内容新增后,自动触发搜索索引重建。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="input">网页内容数据</param>
|
|
|
/// <returns>影响行数</returns>
|
|
|
public async Task<int> 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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 更新网页内容。
|
|
|
/// <para>
|
|
|
/// 【更新策略】
|
|
|
/// 采用"先删除后插入"的策略:
|
|
|
/// 1. 先查询并删除符合条件的旧记录(软删除)
|
|
|
/// 2. 设置新记录的 IsDelete = "0"
|
|
|
/// 3. 插入新记录
|
|
|
///
|
|
|
/// 这种策略简化了更新逻辑,但会改变记录的ID。
|
|
|
/// </para>
|
|
|
/// <para>
|
|
|
/// 【搜索索引重建】
|
|
|
/// 网页内容更新后,自动触发搜索索引重建。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="input">更新的数据</param>
|
|
|
/// <returns>影响行数</returns>
|
|
|
public async Task<int> UpdateHwWeb(HwWeb1 input)
|
|
|
{
|
|
|
// 【查询旧记录】
|
|
|
HwWeb1 query = new()
|
|
|
{
|
|
|
WebCode = input.WebCode,
|
|
|
TypeId = input.TypeId,
|
|
|
DeviceId = input.DeviceId
|
|
|
};
|
|
|
List<HwWeb1> 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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 批量删除网页内容(软删除)。
|
|
|
/// </summary>
|
|
|
/// <param name="webIds">网页ID数组</param>
|
|
|
/// <returns>影响行数</returns>
|
|
|
public Task<int> DeleteHwWebByWebIds(long[] webIds)
|
|
|
{
|
|
|
return DeleteHwWebByWebIds(webIds, true);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 批量删除网页内容(软删除)。
|
|
|
/// <para>
|
|
|
/// 【软删除实现】
|
|
|
/// 将 IsDelete 字段更新为"1",而不是物理删除。
|
|
|
/// </para>
|
|
|
/// <para>
|
|
|
/// 【搜索索引重建】
|
|
|
/// 网页内容删除后,自动触发搜索索引重建。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="webIds">网页ID数组</param>
|
|
|
/// <param name="rebuild">是否重建搜索索引</param>
|
|
|
/// <returns>影响行数</returns>
|
|
|
private async Task<int> DeleteHwWebByWebIds(long[] webIds, bool rebuild)
|
|
|
{
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// int rows = await _executor.ExecuteAsync(Mapper, "deleteHwWebByWebIds", new { array = webIds });
|
|
|
|
|
|
// 【查询待删除的网页】
|
|
|
List<HwWeb1> pages = await _db.Queryable<HwWeb1>()
|
|
|
.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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 静默重建搜索索引。
|
|
|
/// </summary>
|
|
|
/// <param name="source">数据来源</param>
|
|
|
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);
|
|
|
}
|
|
|
}
|
|
|
}
|