You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
9.9 KiB
C#

// ============================================================================
// 【文件说明】HwAboutUsInfoService.cs - 关于我们信息服务类
// ============================================================================
// 这个服务类负责处理"关于我们"模块的主信息业务逻辑,包括:
// - 关于我们信息的 CRUD 操作
// - 中英文标题、描述等多字段管理
//
// 【业务背景】
// "关于我们"是企业官网的常见模块,用于展示公司介绍、发展历程、团队信息等内容。
// 这个服务管理主信息表,明细信息由 HwAboutUsInfoDetailService 管理。
//
// 【与 Java Spring Boot 的对比】
// Java Spring Boot:
// @Service
// public class HwAboutUsInfoServiceImpl implements HwAboutUsInfoService { ... }
//
// ASP.NET Core + Furion:
// public class HwAboutUsInfoService : ITransient { ... }
// ============================================================================
namespace Admin.NET.Plugin.HwPortal;
/// <summary>
/// 关于我们信息服务类。
/// <para>
/// 【服务职责】
/// 1. 管理"关于我们"主信息的增删改查
/// 2. 处理多语言字段(中英文标题和描述)
/// 3. 处理空字符串规范化(与 XML 方案保持一致)
/// </para>
/// <para>
/// 【空字符串处理策略】
/// 原 XML 方案中MyBatis 的 &lt;if test="... != null and ... != ''"&gt;
/// 会跳过空字符串字段不入库。
/// 为了保持数据一致性,这里使用 NormalizeEmptyToNull 方法
/// 将空字符串统一转为 null。
/// </para>
/// </summary>
public class HwAboutUsInfoService : ITransient
{
/// <summary>
/// MyBatis 映射器名称(保留用于回滚)。
/// </summary>
private const string Mapper = "HwAboutUsInfoMapper";
/// <summary>
/// MyBatis 执行器(保留用于回滚)。
/// </summary>
private readonly HwPortalMyBatisExecutor _executor;
/// <summary>
/// SqlSugar 数据访问对象。
/// </summary>
private readonly ISqlSugarClient _db;
/// <summary>
/// 构造函数(依赖注入)。
/// </summary>
/// <param name="executor">MyBatis 执行器</param>
/// <param name="db">SqlSugar 数据访问对象</param>
public HwAboutUsInfoService(HwPortalMyBatisExecutor executor, ISqlSugarClient db)
{
_executor = executor;
_db = db;
}
/// <summary>
/// 根据主键查询关于我们信息。
/// </summary>
/// <param name="aboutUsInfoId">关于我们信息ID</param>
/// <returns>关于我们实体</returns>
public async Task<HwAboutUsInfo> SelectHwAboutUsInfoByAboutUsInfoId(long aboutUsInfoId)
{
// 回滚到 XML 方案时可直接恢复:
// return await _executor.QuerySingleAsync<HwAboutUsInfo>(Mapper, "selectHwAboutUsInfoByAboutUsInfoId", new { aboutUsInfoId });
return await _db.Queryable<HwAboutUsInfo>()
.Where(item => item.AboutUsInfoId == aboutUsInfoId)
.FirstAsync();
}
/// <summary>
/// 查询关于我们信息列表。
/// <para>
/// 【动态查询条件】
/// 支持按类型、标题、描述、排序号、图片等条件筛选。
/// 所有条件都是可选的,有值时才添加到 WHERE 子句。
/// </para>
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>关于我们信息列表</returns>
public async Task<List<HwAboutUsInfo>> SelectHwAboutUsInfoList(HwAboutUsInfo input)
{
HwAboutUsInfo query = input ?? new HwAboutUsInfo();
// 回滚到 XML 方案时可直接恢复:
// return await _executor.QueryListAsync<HwAboutUsInfo>(Mapper, "selectHwAboutUsInfoList", query);
return await _db.Queryable<HwAboutUsInfo>()
.WhereIF(!string.IsNullOrWhiteSpace(query.AboutUsInfoType), item => item.AboutUsInfoType == query.AboutUsInfoType)
.WhereIF(!string.IsNullOrWhiteSpace(query.AboutUsInfoTitle), item => item.AboutUsInfoTitle.Contains(query.AboutUsInfoTitle))
.WhereIF(!string.IsNullOrWhiteSpace(query.AboutUsInfoDesc), item => item.AboutUsInfoDesc.Contains(query.AboutUsInfoDesc))
.WhereIF(query.AboutUsInfoOrder.HasValue, item => item.AboutUsInfoOrder == query.AboutUsInfoOrder)
.WhereIF(!string.IsNullOrWhiteSpace(query.AboutUsInfoPic), item => item.AboutUsInfoPic == query.AboutUsInfoPic)
.ToListAsync();
}
/// <summary>
/// 新增关于我们信息。
/// <para>
/// 【空字符串规范化】
/// Why这里先把"原 XML 会跳过的空串字段"归一成 null
/// 避免改造后写出不同的数据口径。
///
/// 原 XML 中 MyBatis 的条件:
/// &lt;if test="aboutUsInfoEtitle != null and aboutUsInfoEtitle != ''"&gt;
/// about_us_info_etitle = #{aboutUsInfoEtitle},
/// &lt;/if&gt;
///
/// 当传入空字符串时XML 不会更新该字段。
/// 为了保持行为一致,这里将空字符串转为 null。
/// </para>
/// </summary>
/// <param name="input">关于我们信息</param>
/// <returns>影响行数</returns>
public async Task<int> InsertHwAboutUsInfo(HwAboutUsInfo input)
{
// 【数据规范化】
// 将空字符串转为 null与 XML 方案保持一致
input.AboutUsInfoEtitle = NormalizeEmptyToNull(input.AboutUsInfoEtitle);
input.AboutUsInfoTitle = NormalizeEmptyToNull(input.AboutUsInfoTitle);
input.AboutUsInfoDesc = NormalizeEmptyToNull(input.AboutUsInfoDesc);
input.DisplayModal = NormalizeEmptyToNull(input.DisplayModal);
// 【审计字段】
input.CreateTime = HwPortalContextHelper.Now();
// 回滚到 XML 方案时可直接恢复:
// long identity = await _executor.InsertReturnIdentityAsync(Mapper, "insertHwAboutUsInfo", input);
HwAboutUsInfo entity = await _db.Insertable(input).ExecuteReturnEntityAsync();
input.AboutUsInfoId = entity.AboutUsInfoId;
return input.AboutUsInfoId > 0 ? 1 : 0;
}
/// <summary>
/// 更新关于我们信息。
/// <para>
/// 【字段级更新策略】
/// 1. 先查询现有记录
/// 2. 对非空字段进行更新
/// 3. 空字符串也视为有效值(使用 string.IsNullOrWhiteSpace 判断)
///
/// 【注意】
/// 这里对字符串字段使用 string.IsNullOrWhiteSpace 判断,
/// 而不是简单的 != null这是为了兼容前端可能传入空字符串的情况。
/// </para>
/// </summary>
/// <param name="input">更新的数据</param>
/// <returns>影响行数</returns>
public async Task<int> UpdateHwAboutUsInfo(HwAboutUsInfo input)
{
input.UpdateTime = HwPortalContextHelper.Now();
// 回滚到 XML 方案时可直接恢复:
// return await _executor.ExecuteAsync(Mapper, "updateHwAboutUsInfo", input);
HwAboutUsInfo current = await SelectHwAboutUsInfoByAboutUsInfoId(input.AboutUsInfoId ?? 0);
if (current == null)
{
return 0;
}
// 【类型字段】
// 使用 != null 判断,允许更新为空字符串
if (input.AboutUsInfoType != null)
{
current.AboutUsInfoType = input.AboutUsInfoType;
}
// 【英文字段】
// 使用 string.IsNullOrWhiteSpace 判断,空字符串不更新
if (!string.IsNullOrWhiteSpace(input.AboutUsInfoEtitle))
{
current.AboutUsInfoEtitle = input.AboutUsInfoEtitle;
}
// 【中文字段】
if (!string.IsNullOrWhiteSpace(input.AboutUsInfoTitle))
{
current.AboutUsInfoTitle = input.AboutUsInfoTitle;
}
// 【描述字段】
if (!string.IsNullOrWhiteSpace(input.AboutUsInfoDesc))
{
current.AboutUsInfoDesc = input.AboutUsInfoDesc;
}
// 【排序号】
if (input.AboutUsInfoOrder.HasValue)
{
current.AboutUsInfoOrder = input.AboutUsInfoOrder;
}
// 【显示模式】
if (!string.IsNullOrWhiteSpace(input.DisplayModal))
{
current.DisplayModal = input.DisplayModal;
}
// 【图片字段】
// 图片字段使用 != null 判断,允许更新为空
if (input.AboutUsInfoPic != null)
{
current.AboutUsInfoPic = input.AboutUsInfoPic;
}
// 【审计字段】
if (input.CreateTime.HasValue)
{
current.CreateTime = input.CreateTime;
}
if (input.CreateBy != null)
{
current.CreateBy = input.CreateBy;
}
current.UpdateTime = input.UpdateTime;
if (input.UpdateBy != null)
{
current.UpdateBy = input.UpdateBy;
}
return await _db.Updateable(current).ExecuteCommandAsync();
}
/// <summary>
/// 批量删除关于我们信息。
/// </summary>
/// <param name="aboutUsInfoIds">关于我们信息ID数组</param>
/// <returns>影响行数</returns>
public async Task<int> DeleteHwAboutUsInfoByAboutUsInfoIds(long[] aboutUsInfoIds)
{
// 回滚到 XML 方案时可直接恢复:
// return await _executor.ExecuteAsync(Mapper, "deleteHwAboutUsInfoByAboutUsInfoIds", new { array = aboutUsInfoIds });
return await _db.Deleteable<HwAboutUsInfo>()
.In(aboutUsInfoIds)
.ExecuteCommandAsync();
}
/// <summary>
/// 将空字符串规范化转为 null。
/// <para>
/// 【辅助方法】
/// 用于保持与 XML 方案的数据一致性。
/// 原 XML 中 &lt;if&gt; 标签会跳过空字符串,
/// 这里主动将空字符串转为 null达到同样效果。
/// </para>
/// </summary>
/// <param name="value">输入字符串</param>
/// <returns>null 或原值</returns>
private static string NormalizeEmptyToNull(string value)
{
return string.IsNullOrWhiteSpace(value) ? null : value;
}
}