Laservall_manager_system/VOL.HR/Services/DeptSync/Partial/HR_DeptSyncService.cs

246 lines
9.1 KiB
C#
Raw Normal View History

2025-09-25 14:37:10 +08:00
/*
2025-09-26 13:35:45 +08:00
*HR_DeptSync类的业务代码应在此处编写
2025-09-25 14:37:10 +08:00
*使repository.EF/Dapper等信息
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current操作
2025-09-26 13:35:45 +08:00
*HR_DeptSyncService对增ServiceFunFilter
2025-09-25 14:37:10 +08:00
*/
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using VOL.Core.DBManager;
using VOL.Core.Extensions;
using VOL.DingTalk.Models.Biz;
using VOL.DingTalk.Services.Biz;
using VOL.Entity.DomainModels.DeptShip.SystemDept;
2025-09-26 13:35:45 +08:00
using VOL.HR.IRepositories;
using VOL.YSErp.Models.Biz;
using VOL.YSErp.Services.Biz;
2025-09-25 14:37:10 +08:00
2025-09-26 13:35:45 +08:00
namespace VOL.HR.Services
2025-09-25 14:37:10 +08:00
{
2025-09-26 13:35:45 +08:00
public partial class HR_DeptSyncService
2025-09-25 14:37:10 +08:00
{
private readonly IHttpContextAccessor _httpContextAccessor;
2025-09-26 13:35:45 +08:00
private readonly IHR_DeptSyncRepository _repository;//访问数据库
private readonly IHR_DeptShipRepository _shipRepository;//访问数据库
private readonly DingTalkService _dingTalkService;
private readonly YSERPService _ysService;
[ActivatorUtilitiesConstructor]
private Core.CacheManager.ICacheService _cacheService;
2025-09-25 14:37:10 +08:00
[ActivatorUtilitiesConstructor]
2025-09-26 13:35:45 +08:00
public HR_DeptSyncService(
IHR_DeptSyncRepository dbRepository,
IHR_DeptShipRepository shipDbRepository,
IHttpContextAccessor httpContextAccessor,
Core.CacheManager.ICacheService cacheService
2025-09-25 14:37:10 +08:00
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
_shipRepository = shipDbRepository;
2025-09-25 14:37:10 +08:00
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
_cacheService = cacheService;
_dingTalkService = new DingTalkService(new DingTalk.Models.SystemToken(), new DingTalk.Models.DingTalkConfig());
_ysService = new YSERPService(new YSErp.Models.SystemToken(), new YSErp.Models.YSConfig());
2025-09-25 14:37:10 +08:00
}
public async Task CacheYSDepartments()
{
var ysDepts = await _ysService.GetAllDepartmentsAsync();
if(ysDepts != null)
{
_cacheService.Remove("YS_DEPT_CACHE");
_cacheService.Add("YS_DEPT_CACHE", JsonConvert.SerializeObject(ysDepts), 60 * 60);
var db = DBServerProvider.SqlSugarClient;
// 自动建表
db.CodeFirst.InitTables<HR_YSDept>();
try
{
db.BeginTran();
// 通过缓存直接反序列化转换对象
var deptsData = _cacheService.Get<List<HR_YSDept>>("YS_DEPT_CACHE");
// 清空再插入
db.DbMaintenance.TruncateTable<HR_YSDept>();
db.Fastest<HR_YSDept>().BulkCopy(deptsData);
db.CommitTran();
}
catch (Exception ex)
{
db.RollbackTran();
throw;
}
}
}
public async Task CacheDingTalkDepartments()
{
var depts = await _dingTalkService.GetSubDepartmentsAsync();
if (depts != null)
{
_cacheService.Remove("DINGTALK_DEPT_CACHE");
_cacheService.Add("DINGTALK_DEPT_CACHE", JsonConvert.SerializeObject(depts), 60 * 60);
var db = DBServerProvider.SqlSugarClient;
try
{
// 自动建表
db.CodeFirst.InitTables<HR_DingTalkDept>();
db.BeginTran();
// 通过缓存直接反序列化转换对象
var deptsData = _cacheService.Get<List<HR_DingTalkDept>>("DINGTALK_DEPT_CACHE");
// 清空再插入
db.DbMaintenance.TruncateTable<HR_DingTalkDept>();
db.Fastest<HR_DingTalkDept>().BulkCopy(deptsData);
db.CommitTran();
}
catch (Exception ex)
{
db.RollbackTran();
throw;
}
}
}
public async Task CreateDingTalkDept(DingTalkDepartment dept)
{
}
public async Task SyncYSERPDeptToDingTalk()
{
var ysDepts = await _ysService.GetAllDepartmentsAsync();
//var depts = await _dingTalkService.GetSubDepartmentsAsync();
//var deptShip = _shipRepository.Find(i => i.IsRoot ?? false);
if(ysDepts.Count != 0)
{
var rootDept = _shipRepository.Find(i => i.IsRoot ?? false).FirstOrDefault();
BuildYSDeptTree(ysDepts).Where(i => i.id == rootDept.YSDeptId).ToList().ForEach(CreateOrUpdateDingTalkDept);
}
}
public void CreateOrUpdateDingTalkDept(YSERPDepartment ysDept)
{
var deptShip = _shipRepository.Find(i => i.YSDeptId == ysDept.id).FirstOrDefault();
if (deptShip != null && (!deptShip.IsRoot ?? true))
{
}
else
{
if (string.IsNullOrEmpty(ysDept.parentid))
{
var rootDept = _shipRepository.Find(i => i.IsRoot ?? false).FirstOrDefault();
var pId = int.Parse(rootDept?.DingTalkDeptId ?? "1");
try
{
_dingTalkService.CreateDingTalkDept(new DingTalkDepartment
{
parent_id = pId,
name = ysDept.name
});
}
catch (Exception)
{
throw;
}
}
}
}
/// <summary>
/// 将扁平的 YSERP 部门列表转换为树形结构
/// 规则:
/// - parentid 为 null/empty/"0" 或者父节点在列表中不存在时,视为根节点
/// - 避免将节点添加为自己的子节点
/// - 会初始化每个节点的 subDepts 列表并按 displayorder 排序(然后按 name 作为次级排序)
/// </summary>
/// <param name="flatList">扁平部门列表</param>
/// <returns>树形结构的根节点列表</returns>
private List<YSERPDepartment> BuildYSDeptTree(List<YSERPDepartment> flatList)
{
if (flatList == null || flatList.Count == 0)
return new List<YSERPDepartment>();
// 初始化 subDepts防止 null 引发 NRE
foreach (var d in flatList)
{
if (d.subDepts == null)
d.subDepts = new List<YSERPDepartment>();
else
d.subDepts.Clear();
}
// 建立 id -> node 的字典(只包含有 id 的节点)
var dict = flatList
.Where(d => !string.IsNullOrEmpty(d.id))
.GroupBy(d => d.id) // 防止重复 id 导致异常,取第一个
.ToDictionary(g => g.Key, g => g.First());
var roots = new List<YSERPDepartment>();
foreach (var node in flatList)
{
// 视为根的条件parentid 为空、等于 "0"、或父节点不存在、或者 parentid 与自身 id 相同(防止自引用)
if (string.IsNullOrEmpty(node.parentid) || node.parentid == "0" ||
!dict.ContainsKey(node.parentid) || node.parentid == node.id)
{
roots.Add(node);
}
else
{
// 将当前节点添加到父节点的子集合
if (dict.TryGetValue(node.parentid, out var parent))
{
if (parent.subDepts == null)
parent.subDepts = new List<YSERPDepartment>();
parent.subDepts.Add(node);
}
else
{
// 找不到父节点视为根
roots.Add(node);
}
}
}
// 递归排序子节点(按 displayorder再按 name
void SortRecursively(List<YSERPDepartment> list)
{
if (list == null || list.Count == 0) return;
list.Sort((a, b) =>
{
var c = a.displayorder.CompareTo(b.displayorder);
if (c == 0) return string.Compare(a.name, b.name, StringComparison.Ordinal);
return c;
});
foreach (var item in list)
{
SortRecursively(item.subDepts);
}
}
SortRecursively(roots);
return roots;
}
}
2025-09-25 14:37:10 +08:00
}