using System.Linq.Expressions;
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extras.Thirdparty.DingDing;
using JNPF.Extras.Thirdparty.WeChat;
using JNPF.FriendlyException;
using JNPF.LinqBuilder;
using JNPF.Systems.Entitys.Dto.Organize;
using JNPF.Systems.Entitys.Dto.SynThirdInfo;
using JNPF.Systems.Entitys.Dto.SysConfig;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using JNPF.Systems.Interfaces.System;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Systems.System;
///
/// 第三方同步
/// 版 本:V3.2
/// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com)
/// 日 期:2021-06-01.
///
[ApiDescriptionSettings(Tag = "System", Name = "SynThirdInfo", Order = 210)]
[Route("api/system/[controller]")]
public class SynThirdInfoService : ISynThirdInfoService, IDynamicApiController, ITransient
{
///
/// 服务基础仓储.
///
private readonly ISqlSugarRepository _repository;
///
/// 系统配置服务.
///
private readonly ISysConfigService _sysConfigService;
///
/// 用户管理.
///
private readonly IUserManager _userManager;
///
/// 初始化一个类型的新实例.
///
public SynThirdInfoService(
ISqlSugarRepository repository,
ISysConfigService sysConfigService,
IUserManager userManager)
{
_repository = repository;
_sysConfigService = sysConfigService;
_userManager = userManager;
}
#region Get
///
/// 列表.
///
/// 请求参数.
///
[HttpGet("getSynThirdTotal/{thirdType}")]
public async Task GetList(int thirdType)
{
var whereLambda = LinqExpression.And();
whereLambda = whereLambda.And(x => x.ThirdType == thirdType);
return await GetListByThirdType(whereLambda, "用户", "组织");
}
///
/// 钉钉同步组织.
///
///
[HttpGet("synAllOrganizeSysToDing")]
public async Task synAllOrganizeSysToDing(string type)
{
var flag = "0".Equals(type) ? await SynData(2, 1) : await SynSysData(2, 1);
var whereLambda = LinqExpression.And();
whereLambda = whereLambda.And(x => x.ThirdType == 2 && x.DataType < 3);
return await GetListByThirdType(whereLambda, "组织", "组织");
}
///
/// 企业微信同步组织.
///
///
[HttpGet("synAllOrganizeSysToQy")]
public async Task synAllOrganizeSysToQy(string type)
{
var flag = "0".Equals(type) ? await SynData(1, 1) : await SynSysData(1, 1);
var whereLambda = LinqExpression.And();
whereLambda = whereLambda.And(x => x.ThirdType == 1 && x.DataType < 3);
return await GetListByThirdType(whereLambda, "组织", "组织");
}
///
/// 钉钉同步用户.
///
///
[HttpGet("synAllUserSysToDing")]
public async Task synAllUserSysToDing(string type)
{
var flag = "0".Equals(type) ? await SynData(2, 3) : await SynSysData(2, 3);
var whereLambda = LinqExpression.And();
whereLambda = whereLambda.And(x => x.ThirdType == 2 && x.DataType == 3);
return await GetListByThirdType(whereLambda, "用户", "用户");
}
///
/// 企业微信同步用户.
///
///
[HttpGet("synAllUserSysToQy")]
public async Task synAllUserSysToQy(string type)
{
var flag = "0".Equals(type) ? await SynData(1, 3) : await SynSysData(1, 3);
var whereLambda = LinqExpression.And();
whereLambda = whereLambda.And(x => x.ThirdType == 1 && x.DataType == 3);
return await GetListByThirdType(whereLambda, "用户", "用户");
}
#endregion
#region Method
///
/// 获取同步数据.
///
/// 条件Lambda表达式.
///
///
///
private async Task GetListByThirdType(Expression> whereLambda, string synType1, string synType2)
{
var synThirdInfoList = await _repository.AsQueryable().Where(whereLambda).ToListAsync();
var userList = await _repository.AsSugarClient().Queryable().Where(x => x.DeleteMark == null).ToListAsync();
var orgList = await _repository.AsSugarClient().Queryable().Where(x => x.DeleteMark == null).ToListAsync();
if (synType1.Equals(synType2))
{
return new SynThirdInfoOutput()
{
synType = synType1,
recordTotal = synType1.Equals("组织") ? orgList.Count : userList.Count,
synDate = synThirdInfoList.Select(x => x.LastModifyTime).ToList().Max().IsEmpty() ? synThirdInfoList.Select(x => x.CreatorTime).ToList().Max() : synThirdInfoList.Select(x => x.LastModifyTime).ToList().Max(),
synFailCount = synThirdInfoList.FindAll(x => x.SynState.Equals("2")).Count,
synSuccessCount = synThirdInfoList.FindAll(x => x.SynState.Equals("1")).Count,
unSynCount = synThirdInfoList.FindAll(x => x.SynState.Equals("0")).Count,
};
}
else
{
var output = new List();
var synUserList = synThirdInfoList.FindAll(x => x.DataType == 3);
var synOrgList = synThirdInfoList.FindAll(x => x.DataType < 3);
output.Add(new SynThirdInfoOutput()
{
synType = synType2,
recordTotal = synType2.Equals("组织") ? orgList.Count : userList.Count,
synDate = synOrgList.Select(x => x.LastModifyTime).ToList().Max().IsEmpty() ? synOrgList.Select(x => x.CreatorTime).ToList().Max() : synOrgList.Select(x => x.LastModifyTime).ToList().Max(),
synFailCount = synOrgList.FindAll(x => x.SynState.Equals("2")).Count,
synSuccessCount = synOrgList.FindAll(x => x.SynState.Equals("1")).Count,
unSynCount = synOrgList.FindAll(x => x.SynState.Equals("0")).Count,
});
output.Add(new SynThirdInfoOutput()
{
synType = synType1,
recordTotal = synType1.Equals("组织") ? orgList.Count : userList.Count,
synDate = synUserList.Select(x => x.LastModifyTime).ToList().Max().IsEmpty() ? synUserList.Select(x => x.CreatorTime).ToList().Max() : synUserList.Select(x => x.LastModifyTime).ToList().Max(),
synFailCount = synUserList.FindAll(x => x.SynState.Equals("2")).Count,
synSuccessCount = synUserList.FindAll(x => x.SynState.Equals("1")).Count,
unSynCount = synUserList.FindAll(x => x.SynState.Equals("0")).Count,
});
return output;
}
}
///
/// 同步数据(同步到第三方).
///
///
///
///
private async Task SynData(int thirdType, int dataType)
{
try
{
var sysConfig = await _sysConfigService.GetInfo();
var synThirdInfo = await _repository.AsQueryable().Where(x => x.ThirdType == thirdType).ToListAsync();
var orgList = (await _repository.AsSugarClient().Queryable().Where(x => x.DeleteMark == null).ToListAsync()).Adapt>().ToTree("-1");
var userList = await _repository.AsSugarClient().Queryable().Where(x => x.DeleteMark == null).ToListAsync();
if (dataType == 3)
await SynUser(thirdType, dataType, sysConfig, userList);
else
await SynDep(thirdType, dataType, sysConfig, orgList);
return 1;
}
catch (Exception ex)
{
return 0;
}
}
///
/// 同步数据(同步到系统).
///
///
///
///
private async Task SynSysData(int thirdType, int dataType)
{
try
{
var sysConfig = await _sysConfigService.GetInfo();
if (dataType == 3)
await SynSysUser(thirdType, dataType, sysConfig);
else
await SynSysDep(thirdType, dataType, sysConfig);
return 1;
}
catch (Exception ex)
{
return 0;
}
}
///
/// 删除第三方数据.
///
///
///
///
///
///
[NonAction]
public async Task DelSynData(int thirdType, int dataType, SysConfigOutput sysConfig, string id)
{
string msg = string.Empty;
try
{
var synInfo = await _repository.GetFirstAsync(x => x.ThirdType == thirdType && x.DataType == dataType && x.SysObjId == id);
if (synInfo.IsNullOrEmpty() || synInfo.ThirdObjId.IsNullOrEmpty())
throw Oops.Oh(ErrorCode.D9004);
if (thirdType == 1)
{
var weChat = new WeChatUtil(sysConfig.qyhCorpId, sysConfig.qyhCorpSecret);
if (dataType == 3)
weChat.DeleteMember(synInfo.ThirdObjId);
else
weChat.DeleteDepartment(synInfo.ThirdObjId.ParseToInt(), ref msg);
}
else
{
var ding = new DingUtil(sysConfig.dingSynAppKey, sysConfig.dingSynAppSecret);
if (dataType == 3)
ding.DeleteUser(new DingUserParameter() { Userid = synInfo.ThirdObjId }, ref msg);
else
ding.DeleteDep(new DingDepartmentParameter() { DeptId = synInfo.ThirdObjId.ParseToInt() }, ref msg);
}
await _repository.DeleteAsync(synInfo);
}
catch (Exception ex)
{
throw Oops.Oh(msg);
}
}
///
/// 判断是否存在同步成功数据.
///
///
///
///
///
private async Task IsExistThirdObjId(string id, int thirdType, int dataType)
{
return !await _repository.IsAnyAsync(x => x.ThirdType == thirdType && x.DataType == dataType && x.SysObjId.Equals(id) && !SqlFunc.IsNullOrEmpty(x.ThirdObjId));
}
///
/// 保存同步数据.
///
///
///
///
///
///
///
private async Task Save(int thirdType, int dataType, string sysObjId, string thirdObjId, string msg)
{
var entity = await _repository.GetFirstAsync(x => x.SysObjId == sysObjId && x.ThirdType == thirdType);
if (entity == null)
{
entity = new SynThirdInfoEntity();
entity.Id = SnowflakeIdHelper.NextId();
entity.CreatorTime = DateTime.Now;
entity.CreatorUserId = _userManager.UserId;
entity.ThirdType = thirdType;
entity.DataType = dataType;
entity.SysObjId = sysObjId;
entity.ThirdObjId = thirdObjId;
entity.SynState = thirdObjId.IsNullOrEmpty() ? "2" : "1";
entity.Description = msg;
var newDic = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteReturnEntityAsync();
_ = newDic ?? throw Oops.Oh(ErrorCode.D9005);
}
else
{
entity.LastModifyTime = DateTime.Now;
entity.LastModifyUserId = _userManager.UserId;
entity.ThirdObjId = thirdObjId;
entity.SynState = thirdObjId.IsEmpty() ? "2" : "1";
entity.Description = msg;
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
if (isOk < 0)
throw Oops.Oh(ErrorCode.D9006);
}
}
///
/// 获取第三方部门.
///
///
///
///
private async Task GetThirdDep(string organizeId, int thirdType, List thirdDepList)
{
var info = await _repository.GetFirstAsync(x => x.SysObjId == organizeId && x.ThirdType == thirdType);
if (info.IsNotEmptyOrNull() && info.ThirdObjId.IsNotEmptyOrNull())
{
thirdDepList.Add(Convert.ToInt32(info.ThirdObjId));
}
}
///
/// 根据系统主键获取第三方主键.
///
/// 系统主键.
/// 第三方类型.
/// 数据类型.
///
[NonAction]
public async Task> GetThirdIdList(List ids, int thirdType, int dataType)
{
return await _repository.AsQueryable().Where(x => x.ThirdType == thirdType
&& x.DataType == dataType && !SqlFunc.IsNullOrEmpty(x.ThirdObjId)).
In(x => x.SysObjId, ids.ToArray()).Select(x => x.ThirdObjId).ToListAsync();
}
#region 部门同步
///
/// 同步部门.
///
/// 第三方类型.
/// 组织类型.
/// 系统配置.
/// 组织.
///
[NonAction]
public async Task SynDep(int thirdType, int dataType, SysConfigOutput sysConfig, List orgList)
{
switch (thirdType)
{
case 1:
var weChat = new WeChatUtil(sysConfig.qyhCorpId, sysConfig.qyhCorpSecret);
foreach (var item in orgList)
{
await WeChatDep(item, weChat, thirdType, dataType);
}
break;
default:
var ding = new DingUtil(sysConfig.dingSynAppKey, sysConfig.dingSynAppSecret);
foreach (var item in orgList)
{
await DingDep(item, ding, thirdType, dataType);
}
break;
}
}
///
/// 同步部门.
///
///
///
///
///
[NonAction]
public async Task SynSysDep(int thirdType, int dataType, SysConfigOutput sysConfig)
{
try
{
var depList = new List();
switch (thirdType)
{
case 1:
var weChat = new WeChatUtil(sysConfig.qyhCorpId, sysConfig.qyhCorpSecret);
depList = weChat.GetDepartmentList().Adapt>();
break;
default:
var ding = new DingUtil(sysConfig.dingSynAppKey, sysConfig.dingSynAppSecret);
depList = ding.GetDepList().Adapt>();
break;
}
foreach (var item in depList)
{
// 根组织不同步
if (item.Id != "-1")
{
var syncEntity = await _repository.GetFirstAsync(x => x.ThirdObjId == item.Id && x.DataType == dataType);
// 存在同步数据
if (syncEntity.IsNotEmptyOrNull())
{
await _repository.AsSugarClient().Updateable().SetColumns(it => new OrganizeEntity()
{
FullName = item.FullName,
LastModifyUserId = _userManager.UserId,
LastModifyTime = SqlFunc.GetDate()
}).Where(it => it.Id.Equals(syncEntity.SysObjId)).ExecuteCommandHasChangeAsync();
}
else
{
var parentEntity = new OrganizeEntity();
if (item.ParentId == "1")
{
parentEntity = await _repository.AsSugarClient().Queryable().FirstAsync(x => x.ParentId == "-1");
item.ParentId = parentEntity.Id;
}
else
{
item.ParentId = (await _repository.GetFirstAsync(x => x.ThirdObjId == item.ParentId && x.DataType == dataType))?.SysObjId;
parentEntity = await _repository.AsSugarClient().Queryable().FirstAsync(x => x.Id == item.ParentId);
}
var thirdObjId = item.Id;
item.Id = SnowflakeIdHelper.NextId();
item.OrganizeIdTree = parentEntity.OrganizeIdTree + "," + item.Id;
await Save(thirdType, dataType, item.Id, thirdObjId, string.Empty);
await _repository.AsSugarClient().Insertable(item).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
}
}
else
{
var parentEntity = await _repository.AsSugarClient().Queryable().FirstAsync(x => x.ParentId == "-1");
if (!_repository.IsAny(x => x.DataType == dataType && x.SysObjId == parentEntity.Id))
{
await Save(thirdType, dataType, parentEntity.Id, item.Id, string.Empty);
}
}
}
}
catch (Exception e)
{
throw;
}
}
private async Task WeChatDep(OrganizeListOutput org, WeChatUtil weChatQYHelper, int thirdType, int dataType)
{
long parentid = 1;
var entity = await _repository.GetFirstAsync(x => x.SysObjId == org.parentId && x.ThirdType == thirdType && x.SynState == "1");
if (entity.IsNotEmptyOrNull())
{
parentid = Convert.ToInt32(entity.ThirdObjId);
}
var thirdObjId = string.Empty;
var msg = string.Empty;
if (await IsExistThirdObjId(org.id, thirdType, dataType))
{
// 顶级组织
if (org.parentId.Equals("-1"))
{
thirdObjId = "1";
}
else
{
thirdObjId = weChatQYHelper.CreateDepartment(org.fullName, parentid, 1, ref msg).ToString();
}
}
else
{
var synEntity = await _repository.GetFirstAsync(x => org.id == x.SysObjId && thirdType == x.ThirdType);
if (synEntity.IsNotEmptyOrNull())
{
thirdObjId = synEntity.ThirdObjId;
var id = Convert.ToInt32(thirdObjId);
weChatQYHelper.UpdateDepartment(id, org.fullName, (int)parentid, 1, ref msg);
}
}
await Save(thirdType, dataType, org.id, thirdObjId, msg);
if (org.hasChildren)
{
foreach (var item in org.children)
{
var orgChild = item.Adapt();
await WeChatDep(orgChild, weChatQYHelper, thirdType, dataType);
}
}
}
private async Task DingDep(OrganizeListOutput org, DingUtil dingHelper, int thirdType, int dataType)
{
var dingDep = new DingDepartmentParameter();
dingDep.Name = org.fullName;
var entity = await _repository.GetFirstAsync(x => x.SysObjId == org.parentId && x.ThirdType == thirdType && x.SynState == "1");
if (entity != null)
{
dingDep.ParentId = Convert.ToInt32(entity.ThirdObjId);
}
var thirdObjId = string.Empty;
var msg = string.Empty;
if (await IsExistThirdObjId(org.id, thirdType, dataType))
{
if (org.parentId.Equals("-1"))
{
thirdObjId = "1";
}
else
{
thirdObjId = dingHelper.CreateDep(dingDep, ref msg);
}
}
else
{
var synEntity = await _repository.GetFirstAsync(x => org.id == x.SysObjId && thirdType == x.ThirdType);
if (synEntity.IsNotEmptyOrNull())
{
thirdObjId = synEntity.ThirdObjId;
dingDep.DeptId = Convert.ToInt32(thirdObjId);
var flag = dingHelper.UpdateDep(dingDep, ref msg);
thirdObjId = flag ? thirdObjId : string.Empty;
}
}
await Save(thirdType, dataType, org.id, thirdObjId, msg);
if (org.hasChildren)
{
foreach (var item in org.children)
{
var orgChild = item.Adapt();
await DingDep(orgChild, dingHelper, thirdType, dataType);
}
}
}
#endregion
#region 用户同步
///
/// 同步用户.
///
///
///
///
///
///
[NonAction]
public async Task SynUser(int thirdType, int dataType, SysConfigOutput sysConfig, List userList)
{
switch (thirdType)
{
case 1:
var weChat = new WeChatUtil(sysConfig.qyhCorpId, sysConfig.qyhCorpSecret);
foreach (var item in userList)
{
await WeChatUser(item, weChat, thirdType, dataType);
}
break;
default:
var ding = new DingUtil(sysConfig.dingSynAppKey, sysConfig.dingSynAppSecret);
foreach (var item in userList)
{
await DingUser(item, ding, thirdType, dataType);
}
break;
}
}
///
/// 同步用户.
///
///
///
///
///
[NonAction]
public async Task SynSysUser(int thirdType, int dataType, SysConfigOutput sysConfig)
{
try
{
var userList = new List();
switch (thirdType)
{
case 1:
var weChat = new WeChatUtil(sysConfig.qyhCorpId, sysConfig.qyhCorpSecret);
userList = weChat.GetDepartmentMember().Adapt>();
break;
default:
var ding = new DingUtil(sysConfig.dingSynAppKey, sysConfig.dingSynAppSecret);
userList = ding.GetUserList().Adapt>();
break;
}
foreach (var item in userList)
{
var syncEntity = await _repository.GetFirstAsync(x => x.ThirdObjId == item.Account && x.DataType == dataType);
// 存在同步数据
if (syncEntity.IsNotEmptyOrNull())
{
await _repository.AsSugarClient().Updateable().SetColumns(it => new UserEntity()
{
RealName = item.RealName,
LastModifyUserId = _userManager.UserId,
LastModifyTime = SqlFunc.GetDate()
}).Where(it => it.Id.Equals(syncEntity.SysObjId)).ExecuteCommandHasChangeAsync();
}
else
{
await Save(thirdType, dataType, item.Id, item.Account, "");
var syncOrgEntity = await _repository.GetFirstAsync(x => x.ThirdObjId == item.OrganizeId && x.DataType == 1);
if (syncOrgEntity.IsNotEmptyOrNull())
{
item.OrganizeId = syncOrgEntity.SysObjId;
}
await _repository.AsSugarClient().Insertable(item).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
}
}
}
catch (Exception ex)
{
throw;
}
}
private async Task WeChatUser(UserEntity user, WeChatUtil weChatQYHelper, int thirdType, int dataType)
{
var qyUser = new QYMember();
List depList = new List();
await GetThirdDep(user.OrganizeId, thirdType, depList);
qyUser.userid = user.Id;
qyUser.name = user.RealName;
qyUser.mobile = user.MobilePhone;
qyUser.email = user.Email;
qyUser.department = depList.Select(x => (long)x).ToArray();
var thirdObjId = string.Empty;
var msg = string.Empty;
if (await IsExistThirdObjId(user.Id, thirdType, dataType))
{
var flag = weChatQYHelper.CreateMember(qyUser, ref msg);
thirdObjId = flag ? user.Id : weChatQYHelper.GetUserid(qyUser.mobile);
}
else
{
var flag = weChatQYHelper.UpdateMember(qyUser, ref msg);
thirdObjId = flag ? user.Id : weChatQYHelper.GetUserid(qyUser.mobile);
}
await Save(thirdType, dataType, user.Id, thirdObjId, msg);
}
private async Task DingUser(UserEntity user, DingUtil dingHelper, int thirdType, int dataType)
{
var dingUser = new DingUserParameter();
List depList = new List();
await GetThirdDep(user.OrganizeId, thirdType, depList);
dingUser.Name = user.RealName;
dingUser.Mobile = user.MobilePhone;
dingUser.Email = user.Email;
dingUser.DeptIdList = string.Join(",", depList);
var thirdObjId = string.Empty;
var msg = string.Empty;
if (await IsExistThirdObjId(user.Id, thirdType, dataType))
{
thirdObjId = dingHelper.CreateUser(dingUser, ref msg);
}
else
{
thirdObjId = (await _repository.GetFirstAsync(x => x.SysObjId == user.Id && x.ThirdType == thirdType)).ThirdObjId;
dingUser.Userid = thirdObjId;
var flag = dingHelper.UpdateUser(dingUser, ref msg);
thirdObjId = flag ? thirdObjId : string.Empty;
}
await Save(thirdType, dataType, user.Id, thirdObjId, msg);
}
#endregion
#endregion
}