Skip to content

Commit 49354cd

Browse files
committed
移除:同步钉钉用户服务;
新增:同步钉钉用户job
1 parent 9d207c9 commit 49354cd

File tree

3 files changed

+208
-130
lines changed

3 files changed

+208
-130
lines changed

Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/Admin.NET.Plugin.DingTalk.csproj

+4
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@
2525
</None>
2626
</ItemGroup>
2727

28+
<ItemGroup>
29+
<Folder Include="Job\" />
30+
</ItemGroup>
31+
2832
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
// 大名科技(天津)有限公司 版权所有
2+
//
3+
// 此源代码遵循位于源代码树根目录中的 LICENSE 文件的许可证
4+
//
5+
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动
6+
//
7+
// 任何基于本项目二次开发而产生的一切法律纠纷和责任,均与作者无关
8+
9+
using Admin.NET.Plugin.DingTalk;
10+
using Furion.Schedule;
11+
using Microsoft.Extensions.DependencyInjection;
12+
using Microsoft.Extensions.Logging;
13+
14+
namespace Admin.NET.Plugin.Job;
15+
16+
17+
/// <summary>
18+
/// 同步钉钉用户job
19+
/// </summary>
20+
[JobDetail("SyncDingTalkUserJob", Description = "同步钉钉用户", GroupName = "default", Concurrent = false)]
21+
[Daily(TriggerId = "SyncDingTalkUserTrigger", Description = "同步钉钉用户")]
22+
public class SyncDingTalkUserJob : IJob
23+
{
24+
private readonly IServiceScopeFactory _scopeFactory;
25+
private readonly IDingTalkApi _dingTalkApi;
26+
private readonly ILogger _logger;
27+
public SyncDingTalkUserJob(IServiceScopeFactory scopeFactory, IDingTalkApi dingTalkApi, ILoggerFactory loggerFactory)
28+
{
29+
_scopeFactory = scopeFactory;
30+
_dingTalkApi = dingTalkApi;
31+
_logger = loggerFactory.CreateLogger("System.Logging.LoggingMonitor");
32+
}
33+
34+
public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
35+
{
36+
using var serviceScope = _scopeFactory.CreateScope();
37+
var _sysUserRep = serviceScope.ServiceProvider.GetRequiredService<SqlSugarRepository<SysUser>>();
38+
var _dingTalkUserRepo = serviceScope.ServiceProvider.GetRequiredService<SqlSugarRepository<DingTalkUser>>();
39+
var _dingTalkOptions = serviceScope.ServiceProvider.GetRequiredService<IOptions<DingTalkOptions>>();
40+
// 获取token
41+
var param = new GetDingTalkTokenInput()
42+
{
43+
AppKey = _dingTalkOptions.Value.ClientId,
44+
AppSecret = _dingTalkOptions.Value.ClientSecret
45+
};
46+
var tokenRes = await _dingTalkApi.GetDingTalkToken(param);
47+
if (tokenRes.ErrCode != 0)
48+
{
49+
throw Oops.Oh(tokenRes.ErrMsg);
50+
}
51+
var dingTalkUserList = new List<DingTalkEmpRosterFieldVo>();
52+
var offset = 0;
53+
while (offset >= 0)
54+
{
55+
// 获取用户id列表
56+
var userIdsRes = await _dingTalkApi.GetDingTalkCurrentEmployeesList(tokenRes.AccessToken, new GetDingTalkCurrentEmployeesListInput
57+
{
58+
StatusList = "2,3,5,-1",
59+
Size = 50,
60+
Offset = offset
61+
});
62+
if (!userIdsRes.Success)
63+
{
64+
_logger.LogError(userIdsRes.ErrMsg);
65+
break;
66+
}
67+
// 根据用户id获取花名册
68+
var rosterRes = await _dingTalkApi.GetDingTalkCurrentEmployeesRosterList(tokenRes.AccessToken, new GetDingTalkCurrentEmployeesRosterListInput()
69+
{
70+
UserIdList = string.Join(",", userIdsRes.Result.DataList),
71+
FieldFilterList = $"{DingTalkConst.NameField},{DingTalkConst.JobNumberField},{DingTalkConst.MobileField}",
72+
AgentId = _dingTalkOptions.Value.AgentId
73+
});
74+
if (!rosterRes.Success)
75+
{
76+
_logger.LogError(rosterRes.ErrMsg);
77+
break;
78+
}
79+
dingTalkUserList.AddRange(rosterRes.Result);
80+
if (userIdsRes.Result.NextCursor == null)
81+
{
82+
break;
83+
}
84+
// 保存分页游标
85+
offset = (int)userIdsRes.Result.NextCursor;
86+
}
87+
88+
// 判断新增还是更新
89+
var sysDingTalkUserIdList = await _dingTalkUserRepo.AsQueryable()
90+
.Select(x => new
91+
{
92+
x.Id,
93+
x.DingTalkUserId
94+
})
95+
.ToListAsync();
96+
// 需要更新的用户id
97+
var uDingTalkUser = dingTalkUserList.Where(x => sysDingTalkUserIdList.Any(d => d.DingTalkUserId == x.UserId));
98+
// 需要新增的用户id
99+
var iDingTalkUser = dingTalkUserList.Where(u => !sysDingTalkUserIdList.Any(d => d.DingTalkUserId == u.UserId));
100+
#region 新增钉钉用户
101+
var iUser = iDingTalkUser
102+
.Select(res => new SysDingTalkUser
103+
{
104+
DingTalkUserId = res.UserId,
105+
Name = res.FieldDataList
106+
.Where(f => f.FieldCode == DingTalkFieldConst.NameField)
107+
.Select(f => f.FieldValueList.Select(v => v.Value).FirstOrDefault())
108+
.FirstOrDefault(),
109+
Mobile = res.FieldDataList
110+
.Where(f => f.FieldCode == DingTalkFieldConst.MobileField)
111+
.Select(f => f.FieldValueList.Select(v => v.Value).FirstOrDefault())
112+
.FirstOrDefault(),
113+
JobNumber = res.FieldDataList
114+
.Where(f => f.FieldCode == DingTalkFieldConst.JobNumberField)
115+
.Select(f => f.FieldValueList.Select(v => v.Value).FirstOrDefault())
116+
.FirstOrDefault(),
117+
}).ToList();
118+
if (iUser.Count > 0)
119+
{
120+
var iUserRes = await _dingTalkUserRepo.CopyNew().AsInsertable(iUser).ExecuteCommandAsync();
121+
if (iUserRes <= 0)
122+
{
123+
throw Oops.Oh("保存钉钉用户错误");
124+
}
125+
}
126+
#endregion
127+
128+
#region 更新钉钉用户
129+
var uUser = uDingTalkUser
130+
.Select(res => new SysDingTalkUser
131+
{
132+
Id = sysDingTalkUserIdList.Where(d => d.DingTalkUserId == res.UserId).Select(d => d.Id).FirstOrDefault(),
133+
DingTalkUserId = res.UserId,
134+
Name = res.FieldDataList
135+
.Where(f => f.FieldCode == DingTalkFieldConst.NameField)
136+
.Select(f => f.FieldValueList.Select(v => v.Value).FirstOrDefault())
137+
.FirstOrDefault(),
138+
Mobile = res.FieldDataList
139+
.Where(f => f.FieldCode == DingTalkFieldConst.MobileField)
140+
.Select(f => f.FieldValueList.Select(v => v.Value).FirstOrDefault())
141+
.FirstOrDefault(),
142+
JobNumber = res.FieldDataList
143+
.Where(f => f.FieldCode == DingTalkFieldConst.JobNumberField)
144+
.Select(f => f.FieldValueList.Select(v => v.Value).FirstOrDefault())
145+
.FirstOrDefault(),
146+
}).ToList();
147+
if (uUser.Count > 0)
148+
{
149+
var uUserRes = await _dingTalkUserRepo.CopyNew().AsUpdateable(uUser)
150+
.UpdateColumns(d => new
151+
{
152+
d.DingTalkUserId,
153+
d.Name,
154+
d.Mobile,
155+
d.JobNumber,
156+
d.UpdateTime,
157+
d.UpdateUserName,
158+
d.UpdateUserId,
159+
}).ExecuteCommandAsync();
160+
if (uUserRes <= 0)
161+
{
162+
throw Oops.Oh("更新钉钉用户错误");
163+
}
164+
}
165+
#endregion
166+
// 通过系统用户账号(工号),更新钉钉用户表里面的系统用户id
167+
var sysUser = await _sysUserRep.AsQueryable().Select(x => new
168+
{
169+
x.Id,
170+
x.Account
171+
}).ToListAsync();
172+
var sysDingTalkUser = await _dingTalkUserRepo.AsQueryable()
173+
.Where(d => sysUser.Any(u => u.Account == d.JobNumber))
174+
.Select(x => new
175+
{
176+
x.Id,
177+
x.JobNumber,
178+
x.Mobile
179+
}).ToListAsync();
180+
var uSysDingTalkUser = sysDingTalkUser.Select(d => new DingTalkUser
181+
{
182+
Id = d.Id,
183+
SysUserId = sysUser.Where(u => u.Account == d.JobNumber).Select(u => u.Id).FirstOrDefault(),
184+
}).ToList();
185+
var uSysDingTalkUserRes = await _dingTalkUserRepo.CopyNew().AsUpdateable(uSysDingTalkUser)
186+
.UpdateColumns(d => new
187+
{
188+
d.SysUserId,
189+
d.UpdateTime,
190+
d.UpdateUserName,
191+
d.UpdateUserId,
192+
}).ExecuteCommandAsync();
193+
if (uSysDingTalkUserRes <= 0)
194+
{
195+
_logger.LogError("同步钉钉用户错误");
196+
return;
197+
}
198+
var originColor = Console.ForegroundColor;
199+
Console.ForegroundColor = ConsoleColor.Yellow;
200+
Console.WriteLine("【" + DateTime.Now + "】同步钉钉用户");
201+
Console.ForegroundColor = originColor;
202+
}
203+
204+
}

Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/Service/DingTalkService.cs

-130
Original file line numberDiff line numberDiff line change
@@ -30,136 +30,6 @@ public DingTalkService(IDingTalkApi dingTalkApi,
3030
_sysUserRep = sysUserRep;
3131
}
3232

33-
/// <summary>
34-
/// 同步钉钉用户
35-
/// </summary>
36-
/// <returns></returns>
37-
[DisplayName("同步钉钉用户")]
38-
public async Task SyncDingTalkUser()
39-
{
40-
var param = new GetDingTalkTokenInput()
41-
{
42-
AppKey = _dingTalkOptions.ClientId,
43-
AppSecret = _dingTalkOptions.ClientSecret
44-
};
45-
var tokenRes = await _dingTalkApi.GetDingTalkToken(param);
46-
if (tokenRes.ErrCode != 0)
47-
throw Oops.Oh(tokenRes.ErrMsg);
48-
49-
var offset = 0;
50-
while (offset >= 0)
51-
{
52-
// 获取用户Id列表
53-
var userIdsRes = await _dingTalkApi.GetDingTalkCurrentEmployeesList(tokenRes.AccessToken, new GetDingTalkCurrentEmployeesListInput
54-
{
55-
StatusList = "2,3,5,-1",
56-
Size = 50,
57-
Offset = offset
58-
});
59-
if (!userIdsRes.Success)
60-
throw Oops.Oh(userIdsRes.ErrMsg);
61-
62-
// 根据用户Id获取花名册
63-
var rosterRes = await _dingTalkApi.GetDingTalkCurrentEmployeesRosterList(tokenRes.AccessToken, new GetDingTalkCurrentEmployeesRosterListInput()
64-
{
65-
UserIdList = string.Join(",", userIdsRes.Result.DataList),
66-
FieldFilterList = $"{DingTalkConst.NameField},{DingTalkConst.JobNumberField},{DingTalkConst.MobileField}",
67-
AgentId = _dingTalkOptions.AgentId
68-
});
69-
if (!rosterRes.Success)
70-
throw Oops.Oh(rosterRes.ErrMsg);
71-
72-
// 判断新增还是更新
73-
var userIds = rosterRes.Result.Select(u => u.UserId).ToList();
74-
var uDingTalkUser = await _dingTalkUserRepo.AsQueryable()
75-
.Where(u => userIds.Contains(u.DingTalkUserId))
76-
.ToListAsync();
77-
78-
var uUserIds = uDingTalkUser.Select(u => u.DingTalkUserId); // 需要更新的用户Id
79-
var iUserIds = userIds.Where(u => !uUserIds.Contains(u)); // 需要新增的用户Id
80-
81-
// 保存钉钉用户
82-
var iUsers = rosterRes.Result
83-
.Where(u => iUserIds.Contains(u.UserId))
84-
.Select(u => new DingTalkUser
85-
{
86-
DingTalkUserId = u.UserId,
87-
Name = u.FieldDataList.Where(m => m.FieldCode == DingTalkConst.NameField).Select(m => m.FieldValueList.Select(n => n.Value).FirstOrDefault()).FirstOrDefault(),
88-
Mobile = u.FieldDataList.Where(m => m.FieldCode == DingTalkConst.MobileField).Select(m => m.FieldValueList.Select(n => n.Value).FirstOrDefault()).FirstOrDefault(),
89-
JobNumber = u.FieldDataList.Where(m => m.FieldCode == DingTalkConst.JobNumberField).Select(m => m.FieldValueList.Select(n => n.Value).FirstOrDefault()).FirstOrDefault(),
90-
}).ToList();
91-
if (iUsers.Count > 0)
92-
{
93-
await _dingTalkUserRepo.AsInsertable(iUsers).ExecuteCommandAsync();
94-
}
95-
96-
// 更新钉钉用户
97-
var uUsers = rosterRes.Result
98-
.Where(u => uUserIds.Contains(u.UserId))
99-
.Select(u => new DingTalkUser
100-
{
101-
Id = uDingTalkUser.Where(m => m.DingTalkUserId == u.UserId).Select(m => m.Id).FirstOrDefault(),
102-
DingTalkUserId = u.UserId,
103-
Name = u.FieldDataList.Where(m => m.FieldCode == DingTalkConst.NameField).Select(m => m.FieldValueList.Select(n => n.Value).FirstOrDefault()).FirstOrDefault(),
104-
Mobile = u.FieldDataList.Where(m => m.FieldCode == DingTalkConst.MobileField).Select(m => m.FieldValueList.Select(n => n.Value).FirstOrDefault()).FirstOrDefault(),
105-
JobNumber = u.FieldDataList.Where(m => m.FieldCode == DingTalkConst.JobNumberField).Select(m => m.FieldValueList.Select(n => n.Value).FirstOrDefault()).FirstOrDefault(),
106-
}).ToList();
107-
if (uUsers.Count > 0)
108-
{
109-
await _dingTalkUserRepo.AsUpdateable(uUsers).UpdateColumns(u => new
110-
{
111-
u.DingTalkUserId,
112-
u.Name,
113-
u.Mobile,
114-
u.JobNumber,
115-
u.UpdateTime,
116-
u.UpdateUserName,
117-
u.UpdateUserId,
118-
}).ExecuteCommandAsync();
119-
}
120-
121-
// 保存分页游标
122-
if (userIdsRes.Result.NextCursor == null)
123-
break;
124-
offset = (int)userIdsRes.Result.NextCursor;
125-
}
126-
127-
var sysUser = await _sysUserRep.AsQueryable()
128-
.Select(u => new
129-
{
130-
u.Id,
131-
u.Account,
132-
u.Phone
133-
}).ToListAsync();
134-
var dingTalkUser = await _dingTalkUserRepo.AsQueryable()
135-
.Where(u => sysUser.Any(m => m.Account == u.JobNumber))
136-
.Select(u => new
137-
{
138-
u.Id,
139-
u.JobNumber,
140-
u.Mobile
141-
}).ToListAsync();
142-
143-
// 更新钉钉用户中系统用户Id
144-
var uDingTalkUsers = dingTalkUser.Select(u => new DingTalkUser
145-
{
146-
Id = u.Id,
147-
SysUserId = sysUser.Where(m => m.Account == u.JobNumber).Select(m => m.Id).FirstOrDefault(),
148-
}).ToList();
149-
if (uDingTalkUsers.Count > 0)
150-
{
151-
await _dingTalkUserRepo.AsUpdateable(uDingTalkUsers).UpdateColumns(u => new
152-
{
153-
u.SysUserId,
154-
u.UpdateTime,
155-
u.UpdateUserName,
156-
u.UpdateUserId,
157-
}).ExecuteCommandAsync();
158-
}
159-
160-
return;
161-
}
162-
16333
/// <summary>
16434
/// 获取企业内部应用的access_token
16535
/// </summary>

0 commit comments

Comments
 (0)