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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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