package cn.flightfeather.supervision.common.wx
|
|
import cn.flightfeather.supervision.common.net.WXHttpService
|
import org.springframework.stereotype.Component
|
import java.util.concurrent.Executors
|
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.TimeUnit
|
|
/**
|
* 小程序全局后台接口调用凭据管理
|
*/
|
@Component
|
class WxTokenManager {
|
|
companion object {
|
private const val TAG = "WxTokenManager"
|
}
|
private var schedule = Executors.newScheduledThreadPool(2)
|
|
private var token = ""
|
|
fun run(){
|
if (token.isBlank()) {
|
refreshToken(0)
|
}
|
}
|
|
/**
|
* 刷新接口调用凭证
|
* @param delay 延迟执行时间,单位:秒
|
* @param force 是否强制中断当前线程,重新执行
|
*/
|
fun refreshToken(delay:Long, force:Boolean = false) {
|
if (force) {
|
schedule = closeThread(schedule)
|
}
|
schedule.schedule({
|
getTokenTask()
|
}, delay, TimeUnit.SECONDS)
|
}
|
|
fun getAccessToken(): String {
|
if (token.isBlank()) {
|
throw IllegalStateException("[${TAG}]获取小程序接口调用凭据,当前token还未获取到")
|
}
|
return token
|
}
|
|
private fun getTokenTask() {
|
val res = WXHttpService.getAccessToken()
|
if (res == null) {
|
//请求失败,10s后重试
|
refreshToken(10)
|
} else {
|
var nextDelay = 6900L//下一次获取凭证时间间隔(秒)
|
when (res["errcode"]?.asInt) {
|
//请求成功
|
null, 0 -> {
|
val t = res["access_token"]?.asString
|
if (t == null) {
|
refreshToken(60)
|
} else {
|
token = t
|
res["expires_in"]?.asLong?.let { nextDelay = it - 300 }
|
refreshToken(nextDelay)
|
}
|
}
|
//微信服务器系统繁忙,稍后重试
|
-1 -> {
|
refreshToken(60)
|
}
|
//AppSecret错误
|
40001 -> {
|
throw IllegalStateException("[${TAG}]获取小程序接口调用凭据,AppSecret[${WxConfig.SECRET}]错误")
|
}
|
40002 -> {
|
throw IllegalStateException("[${TAG}]获取小程序接口调用凭据,请确保grant_type字段值为client_credential")
|
}
|
40003 -> {
|
throw IllegalStateException("[${TAG}]获取小程序接口调用凭据,AppID[${WxConfig.APP_ID}]错误")
|
}
|
}
|
}
|
}
|
|
private fun closeThread(s: ScheduledExecutorService): ScheduledExecutorService {
|
try {
|
s.shutdown()
|
if (s.awaitTermination(10, TimeUnit.SECONDS)) {
|
s.shutdownNow()
|
}
|
} catch (e: InterruptedException) {
|
e.printStackTrace()
|
s.shutdownNow()
|
}
|
return Executors.newScheduledThreadPool(2)
|
}
|
}
|