|
|
// ============================================================================
|
|
|
// 【文件说明】HwContactUsInfoService.cs - 联系我们信息服务类
|
|
|
// ============================================================================
|
|
|
// 这个服务类负责处理"联系我们"模块的业务逻辑,包括:
|
|
|
// - 用户留言/咨询信息的 CRUD 操作
|
|
|
// - 用户信息(姓名、邮箱、电话、IP)管理
|
|
|
//
|
|
|
// 【业务背景】
|
|
|
// "联系我们"是企业官网的常见模块,用于收集用户的咨询、反馈、合作意向等。
|
|
|
// 这个服务管理用户提交的联系信息。
|
|
|
//
|
|
|
// 【与 Java Spring Boot 的对比】
|
|
|
// Java Spring Boot:
|
|
|
// @Service
|
|
|
// public class HwContactUsInfoServiceImpl implements HwContactUsInfoService { ... }
|
|
|
//
|
|
|
// ASP.NET Core + Furion:
|
|
|
// public class HwContactUsInfoService : ITransient { ... }
|
|
|
// ============================================================================
|
|
|
|
|
|
namespace Admin.NET.Plugin.HwPortal;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 联系我们信息服务类。
|
|
|
/// <para>
|
|
|
/// 【服务职责】
|
|
|
/// 1. 管理用户联系信息的增删改查
|
|
|
/// 2. 处理用户信息字段(姓名、邮箱、电话、IP)
|
|
|
/// 3. 数据规范化(空字符串处理)
|
|
|
/// </para>
|
|
|
/// <para>
|
|
|
/// 【用户姓名字段特殊处理】
|
|
|
/// Why:用户姓名在原 XML 中空串不会入库,这里同步保持,
|
|
|
/// 避免后台筛选出现空值脏数据。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
public class HwContactUsInfoService : ITransient
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// MyBatis 映射器名称(保留用于回滚)。
|
|
|
/// </summary>
|
|
|
private const string Mapper = "HwContactUsInfoMapper";
|
|
|
|
|
|
/// <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 HwContactUsInfoService(HwPortalMyBatisExecutor executor, ISqlSugarClient db)
|
|
|
{
|
|
|
_executor = executor;
|
|
|
_db = db;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据ID查询联系信息。
|
|
|
/// </summary>
|
|
|
/// <param name="contactUsInfoId">联系信息ID</param>
|
|
|
/// <returns>联系信息实体</returns>
|
|
|
public async Task<HwContactUsInfo> SelectHwContactUsInfoByContactUsInfoId(long contactUsInfoId)
|
|
|
{
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// return await _executor.QuerySingleAsync<HwContactUsInfo>(Mapper, "selectHwContactUsInfoByContactUsInfoId", new { contactUsInfoId });
|
|
|
return await _db.Queryable<HwContactUsInfo>()
|
|
|
.Where(item => item.ContactUsInfoId == contactUsInfoId)
|
|
|
.FirstAsync();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查询联系信息列表。
|
|
|
/// <para>
|
|
|
/// 【动态查询条件】
|
|
|
/// 支持按用户名、邮箱、电话、IP等条件模糊查询。
|
|
|
/// 所有条件都是可选的,有值时才添加到 WHERE 子句。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="input">查询条件</param>
|
|
|
/// <returns>联系信息列表</returns>
|
|
|
public async Task<List<HwContactUsInfo>> SelectHwContactUsInfoList(HwContactUsInfo input)
|
|
|
{
|
|
|
HwContactUsInfo query = input ?? new HwContactUsInfo();
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// return await _executor.QueryListAsync<HwContactUsInfo>(Mapper, "selectHwContactUsInfoList", query);
|
|
|
return await _db.Queryable<HwContactUsInfo>()
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(query.UserName), item => item.UserName.Contains(query.UserName))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(query.UserEmail), item => item.UserEmail.Contains(query.UserEmail))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(query.UserPhone), item => item.UserPhone.Contains(query.UserPhone))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(query.UserIp), item => item.UserIp.Contains(query.UserIp))
|
|
|
.ToListAsync();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 新增联系信息。
|
|
|
/// <para>
|
|
|
/// 【用户姓名字段特殊处理】
|
|
|
/// Why:用户姓名在原 XML 中空串不会入库,这里同步保持,
|
|
|
/// 避免后台筛选出现空值脏数据。
|
|
|
///
|
|
|
/// 原 XML 中 MyBatis 的条件:
|
|
|
/// <if test="userName != null and userName != ''">
|
|
|
/// user_name = #{userName},
|
|
|
/// </if>
|
|
|
///
|
|
|
/// 当传入空字符串时,XML 不会插入该字段。
|
|
|
/// 为了保持行为一致,这里将空字符串转为 null。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="input">联系信息</param>
|
|
|
/// <returns>影响行数</returns>
|
|
|
public async Task<int> InsertHwContactUsInfo(HwContactUsInfo input)
|
|
|
{
|
|
|
// 【数据规范化】
|
|
|
// 将用户姓名空字符串转为 null,与 XML 方案保持一致
|
|
|
// Why:用户姓名在原 XML 中空串不会入库,这里同步保持,避免后台筛选出现空值脏数据。
|
|
|
input.UserName = NormalizeEmptyToNull(input.UserName);
|
|
|
|
|
|
// 【审计字段】
|
|
|
input.CreateTime = HwPortalContextHelper.Now();
|
|
|
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// long identity = await _executor.InsertReturnIdentityAsync(Mapper, "insertHwContactUsInfo", input);
|
|
|
HwContactUsInfo entity = await _db.Insertable(input).ExecuteReturnEntityAsync();
|
|
|
input.ContactUsInfoId = entity.ContactUsInfoId;
|
|
|
return input.ContactUsInfoId > 0 ? 1 : 0;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 更新联系信息。
|
|
|
/// <para>
|
|
|
/// 【字段级更新策略】
|
|
|
/// 1. 先查询现有记录
|
|
|
/// 2. 对非空字段进行更新
|
|
|
/// 3. 空字符串也视为有效值
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="input">更新的数据</param>
|
|
|
/// <returns>影响行数</returns>
|
|
|
public async Task<int> UpdateHwContactUsInfo(HwContactUsInfo input)
|
|
|
{
|
|
|
input.UpdateTime = HwPortalContextHelper.Now();
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// return await _executor.ExecuteAsync(Mapper, "updateHwContactUsInfo", input);
|
|
|
HwContactUsInfo current = await SelectHwContactUsInfoByContactUsInfoId(input.ContactUsInfoId ?? 0);
|
|
|
if (current == null)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// 【用户姓名字段】
|
|
|
// 使用 string.IsNullOrWhiteSpace 判断,空字符串不更新
|
|
|
if (!string.IsNullOrWhiteSpace(input.UserName))
|
|
|
{
|
|
|
current.UserName = input.UserName;
|
|
|
}
|
|
|
|
|
|
// 【邮箱字段】
|
|
|
// 使用 != null 判断,允许更新为空字符串
|
|
|
if (input.UserEmail != null)
|
|
|
{
|
|
|
current.UserEmail = input.UserEmail;
|
|
|
}
|
|
|
|
|
|
// 【电话字段】
|
|
|
if (input.UserPhone != null)
|
|
|
{
|
|
|
current.UserPhone = input.UserPhone;
|
|
|
}
|
|
|
|
|
|
// 【IP字段】
|
|
|
if (input.UserIp != null)
|
|
|
{
|
|
|
current.UserIp = input.UserIp;
|
|
|
}
|
|
|
|
|
|
// 【备注字段】
|
|
|
if (input.Remark != null)
|
|
|
{
|
|
|
current.Remark = input.Remark;
|
|
|
}
|
|
|
|
|
|
// 【审计字段】
|
|
|
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="contactUsInfoIds">联系信息ID数组</param>
|
|
|
/// <returns>影响行数</returns>
|
|
|
public async Task<int> DeleteHwContactUsInfoByContactUsInfoIds(long[] contactUsInfoIds)
|
|
|
{
|
|
|
// 回滚到 XML 方案时可直接恢复:
|
|
|
// return await _executor.ExecuteAsync(Mapper, "deleteHwContactUsInfoByContactUsInfoIds", new { array = contactUsInfoIds });
|
|
|
return await _db.Deleteable<HwContactUsInfo>()
|
|
|
.In(contactUsInfoIds)
|
|
|
.ExecuteCommandAsync();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将空字符串规范化转为 null。
|
|
|
/// <para>
|
|
|
/// 【辅助方法】
|
|
|
/// 用于保持与 XML 方案的数据一致性。
|
|
|
/// 原 XML 中 <if> 标签会跳过空字符串,
|
|
|
/// 这里主动将空字符串转为 null,达到同样效果。
|
|
|
/// </para>
|
|
|
/// </summary>
|
|
|
/// <param name="value">输入字符串</param>
|
|
|
/// <returns>null 或原值</returns>
|
|
|
private static string NormalizeEmptyToNull(string value)
|
|
|
{
|
|
|
return string.IsNullOrWhiteSpace(value) ? null : value;
|
|
|
}
|
|
|
}
|