// ============================================================================ // 【文件说明】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; /// /// 关于我们信息服务类。 /// /// 【服务职责】 /// 1. 管理"关于我们"主信息的增删改查 /// 2. 处理多语言字段(中英文标题和描述) /// 3. 处理空字符串规范化(与 XML 方案保持一致) /// /// /// 【空字符串处理策略】 /// 原 XML 方案中,MyBatis 的 <if test="... != null and ... != ''"> /// 会跳过空字符串字段不入库。 /// 为了保持数据一致性,这里使用 NormalizeEmptyToNull 方法 /// 将空字符串统一转为 null。 /// /// public class HwAboutUsInfoService : ITransient { /// /// MyBatis 映射器名称(保留用于回滚)。 /// private const string Mapper = "HwAboutUsInfoMapper"; /// /// MyBatis 执行器(保留用于回滚)。 /// private readonly HwPortalMyBatisExecutor _executor; /// /// SqlSugar 数据访问对象。 /// private readonly ISqlSugarClient _db; /// /// 构造函数(依赖注入)。 /// /// MyBatis 执行器 /// SqlSugar 数据访问对象 public HwAboutUsInfoService(HwPortalMyBatisExecutor executor, ISqlSugarClient db) { _executor = executor; _db = db; } /// /// 根据主键查询关于我们信息。 /// /// 关于我们信息ID /// 关于我们实体 public async Task SelectHwAboutUsInfoByAboutUsInfoId(long aboutUsInfoId) { // 回滚到 XML 方案时可直接恢复: // return await _executor.QuerySingleAsync(Mapper, "selectHwAboutUsInfoByAboutUsInfoId", new { aboutUsInfoId }); return await _db.Queryable() .Where(item => item.AboutUsInfoId == aboutUsInfoId) .FirstAsync(); } /// /// 查询关于我们信息列表。 /// /// 【动态查询条件】 /// 支持按类型、标题、描述、排序号、图片等条件筛选。 /// 所有条件都是可选的,有值时才添加到 WHERE 子句。 /// /// /// 查询条件 /// 关于我们信息列表 public async Task> SelectHwAboutUsInfoList(HwAboutUsInfo input) { HwAboutUsInfo query = input ?? new HwAboutUsInfo(); // 回滚到 XML 方案时可直接恢复: // return await _executor.QueryListAsync(Mapper, "selectHwAboutUsInfoList", query); return await _db.Queryable() .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(); } /// /// 新增关于我们信息。 /// /// 【空字符串规范化】 /// Why:这里先把"原 XML 会跳过的空串字段"归一成 null, /// 避免改造后写出不同的数据口径。 /// /// 原 XML 中 MyBatis 的条件: /// <if test="aboutUsInfoEtitle != null and aboutUsInfoEtitle != ''"> /// about_us_info_etitle = #{aboutUsInfoEtitle}, /// </if> /// /// 当传入空字符串时,XML 不会更新该字段。 /// 为了保持行为一致,这里将空字符串转为 null。 /// /// /// 关于我们信息 /// 影响行数 public async Task 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; } /// /// 更新关于我们信息。 /// /// 【字段级更新策略】 /// 1. 先查询现有记录 /// 2. 对非空字段进行更新 /// 3. 空字符串也视为有效值(使用 string.IsNullOrWhiteSpace 判断) /// /// 【注意】 /// 这里对字符串字段使用 string.IsNullOrWhiteSpace 判断, /// 而不是简单的 != null,这是为了兼容前端可能传入空字符串的情况。 /// /// /// 更新的数据 /// 影响行数 public async Task 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(); } /// /// 批量删除关于我们信息。 /// /// 关于我们信息ID数组 /// 影响行数 public async Task DeleteHwAboutUsInfoByAboutUsInfoIds(long[] aboutUsInfoIds) { // 回滚到 XML 方案时可直接恢复: // return await _executor.ExecuteAsync(Mapper, "deleteHwAboutUsInfoByAboutUsInfoIds", new { array = aboutUsInfoIds }); return await _db.Deleteable() .In(aboutUsInfoIds) .ExecuteCommandAsync(); } /// /// 将空字符串规范化转为 null。 /// /// 【辅助方法】 /// 用于保持与 XML 方案的数据一致性。 /// 原 XML 中 <if> 标签会跳过空字符串, /// 这里主动将空字符串转为 null,达到同样效果。 /// /// /// 输入字符串 /// null 或原值 private static string NormalizeEmptyToNull(string value) { return string.IsNullOrWhiteSpace(value) ? null : value; } }