66import me .chanjar .weixin .common .bean .WxAccessToken ;
77import me .chanjar .weixin .common .redis .WxRedisOps ;
88import me .chanjar .weixin .common .util .http .apache .ApacheHttpClientBuilder ;
9+ import me .chanjar .weixin .cp .bean .WxCpProviderToken ;
910import me .chanjar .weixin .cp .config .WxCpTpConfigStorage ;
1011import me .chanjar .weixin .cp .util .json .WxCpGsonBuilder ;
12+ import org .apache .commons .lang3 .StringUtils ;
1113
1214import java .io .File ;
1315import java .io .Serializable ;
1416import java .util .concurrent .TimeUnit ;
17+ import java .util .concurrent .locks .Lock ;
1518
1619/**
1720 * 企业微信各种固定、授权配置的Redisson存储实现
@@ -66,6 +69,14 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
6669 */
6770 private volatile String providerSecret ;
6871
72+ // lock key
73+ protected static final String LOCK_KEY = "wechat_tp_lock:" ;
74+ protected static final String LOCKER_PROVIDER_ACCESS_TOKEN = "providerAccessTokenLock" ;
75+ protected static final String LOCKER_SUITE_ACCESS_TOKEN = "suiteAccessTokenLock" ;
76+ protected static final String LOCKER_ACCESS_TOKEN = "accessTokenLock" ;
77+ protected static final String LOCKER_CORP_JSAPI_TICKET = "corpJsapiTicketLock" ;
78+ protected static final String LOCKER_SUITE_JSAPI_TICKET = "suiteJsapiTicketLock" ;
79+
6980 @ Override
7081 public void setBaseApiUrl (String baseUrl ) {
7182 this .baseApiUrl = baseUrl ;
@@ -88,6 +99,20 @@ public String getSuiteAccessToken() {
8899 return wxRedisOps .getValue (keyWithPrefix (suiteAccessTokenKey ));
89100 }
90101
102+ @ Override
103+ public WxAccessToken getSuiteAccessTokenEntity () {
104+ String suiteAccessToken = wxRedisOps .getValue (keyWithPrefix (suiteAccessTokenKey ));
105+ Long expireIn = wxRedisOps .getExpire (keyWithPrefix (suiteAccessTokenKey ));
106+ if (StringUtils .isBlank (suiteAccessToken ) || expireIn == null || expireIn == 0 || expireIn == -2 ) {
107+ return new WxAccessToken ();
108+ }
109+
110+ WxAccessToken suiteAccessTokenEntity = new WxAccessToken ();
111+ suiteAccessTokenEntity .setAccessToken (suiteAccessToken );
112+ suiteAccessTokenEntity .setExpiresIn (Math .max (Math .toIntExact (expireIn ), 0 ));
113+ return suiteAccessTokenEntity ;
114+ }
115+
91116 @ Override
92117 public boolean isSuiteAccessTokenExpired () {
93118 //remain time to live in seconds, or key not exist
@@ -185,13 +210,32 @@ public String getAccessToken(String authCorpId) {
185210 return wxRedisOps .getValue (keyWithPrefix (authCorpId ) + accessTokenKey );
186211 }
187212
213+ @ Override
214+ public WxAccessToken getAccessTokenEntity (String authCorpId ) {
215+ String accessToken = wxRedisOps .getValue (keyWithPrefix (authCorpId ) + accessTokenKey );
216+ Long expire = wxRedisOps .getExpire (keyWithPrefix (authCorpId ) + accessTokenKey );
217+ if (StringUtils .isBlank (accessToken ) || expire == null || expire == 0 || expire == -2 ) {
218+ return new WxAccessToken ();
219+ }
220+
221+ WxAccessToken accessTokenEntity = new WxAccessToken ();
222+ accessTokenEntity .setAccessToken (accessToken );
223+ accessTokenEntity .setExpiresIn (Math .max (Math .toIntExact (expire ), 0 ));
224+ return accessTokenEntity ;
225+ }
226+
188227 @ Override
189228 public boolean isAccessTokenExpired (String authCorpId ) {
190229 //没有设置或者TTL为0,都是过期
191230 return wxRedisOps .getExpire (keyWithPrefix (authCorpId ) + accessTokenKey ) == 0L
192231 || wxRedisOps .getExpire (keyWithPrefix (authCorpId ) + accessTokenKey ) == -2 ;
193232 }
194233
234+ @ Override
235+ public void expireAccessToken (String authCorpId ) {
236+ wxRedisOps .expire (keyWithPrefix (authCorpId ) + accessTokenKey , 0 , TimeUnit .SECONDS );
237+ }
238+
195239 @ Override
196240 public void updateAccessToken (String authCorpId , String accessToken , int expiredInSeconds ) {
197241 wxRedisOps .setValue (keyWithPrefix (authCorpId ) + accessTokenKey , accessToken , expiredInSeconds , TimeUnit .SECONDS );
@@ -213,6 +257,11 @@ public boolean isAuthCorpJsApiTicketExpired(String authCorpId) {
213257 || wxRedisOps .getExpire (keyWithPrefix (authCorpId ) + authCorpJsApiTicketKey ) == -2 ;
214258 }
215259
260+ @ Override
261+ public void expireAuthCorpJsApiTicket (String authCorpId ) {
262+ wxRedisOps .expire (keyWithPrefix (authCorpId ) + authCorpJsApiTicketKey , 0 , TimeUnit .SECONDS );
263+ }
264+
216265 @ Override
217266 public void updateAuthCorpJsApiTicket (String authCorpId , String jsApiTicket , int expiredInSeconds ) {
218267 wxRedisOps .setValue (keyWithPrefix (authCorpId ) + authCorpJsApiTicketKey , jsApiTicket , expiredInSeconds ,
@@ -235,6 +284,11 @@ public boolean isAuthSuiteJsApiTicketExpired(String authCorpId) {
235284 || wxRedisOps .getExpire (keyWithPrefix (authCorpId ) + authSuiteJsApiTicketKey ) == -2 ;
236285 }
237286
287+ @ Override
288+ public void expireAuthSuiteJsApiTicket (String authCorpId ) {
289+ wxRedisOps .expire (keyWithPrefix (authCorpId ) + authSuiteJsApiTicketKey , 0 , TimeUnit .SECONDS );
290+ }
291+
238292 @ Override
239293 public void updateAuthSuiteJsApiTicket (String authCorpId , String jsApiTicket , int expiredInSeconds ) {
240294 wxRedisOps .setValue (keyWithPrefix (authCorpId ) + authSuiteJsApiTicketKey , jsApiTicket , expiredInSeconds ,
@@ -257,6 +311,25 @@ public String getProviderToken() {
257311 return wxRedisOps .getValue (keyWithPrefix (providerTokenKey ));
258312 }
259313
314+ @ Override
315+ public WxCpProviderToken getProviderTokenEntity () {
316+ String providerToken = wxRedisOps .getValue (keyWithPrefix (providerTokenKey ));
317+ Long expire = wxRedisOps .getExpire (keyWithPrefix (providerTokenKey ));
318+
319+ if (StringUtils .isBlank (providerToken ) || expire == null || expire == 0 || expire == -2 ) {
320+ return new WxCpProviderToken ();
321+ }
322+
323+ WxCpProviderToken wxCpProviderToken = new WxCpProviderToken ();
324+ wxCpProviderToken .setProviderAccessToken (providerToken );
325+ wxCpProviderToken .setExpiresIn (Math .max (Math .toIntExact (expire ), 0 ));
326+ return wxCpProviderToken ;
327+ }
328+
329+ @ Override
330+ public void expireProviderToken () {
331+ wxRedisOps .expire (keyWithPrefix (providerTokenKey ), 0 , TimeUnit .SECONDS );
332+ }
260333
261334 /**
262335 * 网络代理相关
@@ -286,6 +359,37 @@ public File getTmpDirFile() {
286359 return tmpDirFile ;
287360 }
288361
362+ @ Override
363+ public Lock getProviderAccessTokenLock () {
364+ return getLockByKey (String .join (":" , this .corpId , LOCKER_PROVIDER_ACCESS_TOKEN ));
365+ }
366+
367+ @ Override
368+ public Lock getSuiteAccessTokenLock () {
369+ return getLockByKey (LOCKER_SUITE_ACCESS_TOKEN );
370+ }
371+
372+ @ Override
373+ public Lock getAccessTokenLock (String authCorpId ) {
374+ return getLockByKey (String .join (":" , authCorpId , LOCKER_ACCESS_TOKEN ));
375+ }
376+
377+ @ Override
378+ public Lock getAuthCorpJsapiTicketLock (String authCorpId ) {
379+ return getLockByKey (String .join (":" , authCorpId , LOCKER_CORP_JSAPI_TICKET ));
380+ }
381+
382+ @ Override
383+ public Lock getSuiteJsapiTicketLock (String authCorpId ) {
384+ return getLockByKey (String .join (":" , authCorpId , LOCKER_SUITE_JSAPI_TICKET ));
385+ }
386+
387+ private Lock getLockByKey (String key ) {
388+ // 最终key的模式:(keyPrefix:)wechat_tp_lock:suiteId:(authCorpId):lockKey
389+ // 其中keyPrefix目前不支持外部配置,authCorpId只有涉及到corpAccessToken, suiteJsapiTicket, authCorpJsapiTicket时才会拼上
390+ return this .wxRedisOps .getLock (String .join (":" , keyWithPrefix (LOCK_KEY + this .suiteId ), key ));
391+ }
392+
289393 @ Override
290394 public ApacheHttpClientBuilder getApacheHttpClientBuilder () {
291395 return this .apacheHttpClientBuilder ;
0 commit comments