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 tokenRes = await _dingTalkApi . GetDingTalkToken ( _dingTalkOptions . Value . ClientId , _dingTalkOptions . Value . ClientSecret ) ;
42
+ if ( tokenRes . ErrCode != 0 )
43
+ {
44
+ throw Oops . Oh ( tokenRes . ErrMsg ) ;
45
+ }
46
+ var dingTalkUserList = new List < DingTalkEmpRosterFieldVo > ( ) ;
47
+ var offset = 0 ;
48
+ while ( offset >= 0 )
49
+ {
50
+ // 获取用户id列表
51
+ var userIdsRes = await _dingTalkApi . GetDingTalkCurrentEmployeesList ( tokenRes . AccessToken , new GetDingTalkCurrentEmployeesListInput
52
+ {
53
+ StatusList = "2,3,5,-1" ,
54
+ Size = 50 ,
55
+ Offset = offset
56
+ } ) ;
57
+ if ( ! userIdsRes . Success )
58
+ {
59
+ _logger . LogError ( userIdsRes . ErrMsg ) ;
60
+ break ;
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 . Value . AgentId
68
+ } ) ;
69
+ if ( ! rosterRes . Success )
70
+ {
71
+ _logger . LogError ( rosterRes . ErrMsg ) ;
72
+ break ;
73
+ }
74
+ dingTalkUserList . AddRange ( rosterRes . Result ) ;
75
+ if ( userIdsRes . Result . NextCursor == null )
76
+ {
77
+ break ;
78
+ }
79
+ // 保存分页游标
80
+ offset = ( int ) userIdsRes . Result . NextCursor ;
81
+ }
82
+
83
+ // 判断新增还是更新
84
+ var sysDingTalkUserIdList = await _dingTalkUserRepo . AsQueryable ( )
85
+ . Select ( x => new
86
+ {
87
+ x . Id ,
88
+ x . DingTalkUserId
89
+ } )
90
+ . ToListAsync ( ) ;
91
+ // 需要更新的用户id
92
+ var uDingTalkUser = dingTalkUserList . Where ( x => sysDingTalkUserIdList . Any ( d => d . DingTalkUserId == x . UserId ) ) ;
93
+ // 需要新增的用户id
94
+ var iDingTalkUser = dingTalkUserList . Where ( u => ! sysDingTalkUserIdList . Any ( d => d . DingTalkUserId == u . UserId ) ) ;
95
+ #region 新增钉钉用户
96
+ var iUser = iDingTalkUser
97
+ . Select ( res => new DingTalkUser
98
+ {
99
+ DingTalkUserId = res . UserId ,
100
+ Name = res . FieldDataList
101
+ . Where ( f => f . FieldCode == DingTalkConst . NameField )
102
+ . Select ( f => f . FieldValueList . Select ( v => v . Value ) . FirstOrDefault ( ) )
103
+ . FirstOrDefault ( ) ,
104
+ Mobile = res . FieldDataList
105
+ . Where ( f => f . FieldCode == DingTalkConst . MobileField )
106
+ . Select ( f => f . FieldValueList . Select ( v => v . Value ) . FirstOrDefault ( ) )
107
+ . FirstOrDefault ( ) ,
108
+ JobNumber = res . FieldDataList
109
+ . Where ( f => f . FieldCode == DingTalkConst . JobNumberField )
110
+ . Select ( f => f . FieldValueList . Select ( v => v . Value ) . FirstOrDefault ( ) )
111
+ . FirstOrDefault ( ) ,
112
+ } ) . ToList ( ) ;
113
+ if ( iUser . Count > 0 )
114
+ {
115
+ var iUserRes = await _dingTalkUserRepo . CopyNew ( ) . AsInsertable ( iUser ) . ExecuteCommandAsync ( ) ;
116
+ if ( iUserRes <= 0 )
117
+ {
118
+ throw Oops . Oh ( "保存钉钉用户错误" ) ;
119
+ }
120
+ }
121
+ #endregion
122
+
123
+ #region 更新钉钉用户
124
+ var uUser = uDingTalkUser
125
+ . Select ( res => new DingTalkUser
126
+ {
127
+ Id = sysDingTalkUserIdList . Where ( d => d . DingTalkUserId == res . UserId ) . Select ( d => d . Id ) . FirstOrDefault ( ) ,
128
+ DingTalkUserId = res . UserId ,
129
+ Name = res . FieldDataList
130
+ . Where ( f => f . FieldCode == DingTalkConst . NameField )
131
+ . Select ( f => f . FieldValueList . Select ( v => v . Value ) . FirstOrDefault ( ) )
132
+ . FirstOrDefault ( ) ,
133
+ Mobile = res . FieldDataList
134
+ . Where ( f => f . FieldCode == DingTalkConst . MobileField )
135
+ . Select ( f => f . FieldValueList . Select ( v => v . Value ) . FirstOrDefault ( ) )
136
+ . FirstOrDefault ( ) ,
137
+ JobNumber = res . FieldDataList
138
+ . Where ( f => f . FieldCode == DingTalkConst . JobNumberField )
139
+ . Select ( f => f . FieldValueList . Select ( v => v . Value ) . FirstOrDefault ( ) )
140
+ . FirstOrDefault ( ) ,
141
+ } ) . ToList ( ) ;
142
+ if ( uUser . Count > 0 )
143
+ {
144
+ var uUserRes = await _dingTalkUserRepo . CopyNew ( ) . AsUpdateable ( uUser )
145
+ . UpdateColumns ( d => new
146
+ {
147
+ d . DingTalkUserId ,
148
+ d . Name ,
149
+ d . Mobile ,
150
+ d . JobNumber ,
151
+ d . UpdateTime ,
152
+ d . UpdateUserName ,
153
+ d . UpdateUserId ,
154
+ } ) . ExecuteCommandAsync ( ) ;
155
+ if ( uUserRes <= 0 )
156
+ {
157
+ throw Oops . Oh ( "更新钉钉用户错误" ) ;
158
+ }
159
+ }
160
+ #endregion
161
+ // 通过系统用户账号(工号),更新钉钉用户表里面的系统用户id
162
+ var sysUser = await _sysUserRep . AsQueryable ( ) . Select ( x => new
163
+ {
164
+ x . Id ,
165
+ x . Account
166
+ } ) . ToListAsync ( ) ;
167
+ var sysDingTalkUser = await _dingTalkUserRepo . AsQueryable ( )
168
+ . Where ( d => sysUser . Any ( u => u . Account == d . JobNumber ) )
169
+ . Select ( x => new
170
+ {
171
+ x . Id ,
172
+ x . JobNumber ,
173
+ x . Mobile
174
+ } ) . ToListAsync ( ) ;
175
+ var uSysDingTalkUser = sysDingTalkUser . Select ( d => new DingTalkUser
176
+ {
177
+ Id = d . Id ,
178
+ SysUserId = sysUser . Where ( u => u . Account == d . JobNumber ) . Select ( u => u . Id ) . FirstOrDefault ( ) ,
179
+ } ) . ToList ( ) ;
180
+ var uSysDingTalkUserRes = await _dingTalkUserRepo . CopyNew ( ) . AsUpdateable ( uSysDingTalkUser )
181
+ . UpdateColumns ( d => new
182
+ {
183
+ d . SysUserId ,
184
+ d . UpdateTime ,
185
+ d . UpdateUserName ,
186
+ d . UpdateUserId ,
187
+ } ) . ExecuteCommandAsync ( ) ;
188
+ if ( uSysDingTalkUserRes <= 0 )
189
+ {
190
+ _logger . LogError ( "同步钉钉用户错误" ) ;
191
+ return ;
192
+ }
193
+ var originColor = Console . ForegroundColor ;
194
+ Console . ForegroundColor = ConsoleColor . Yellow ;
195
+ Console . WriteLine ( "【" + DateTime . Now + "】同步钉钉用户" ) ;
196
+ Console . ForegroundColor = originColor ;
197
+ }
198
+
199
+ }
0 commit comments