|
@@ -11,6 +11,7 @@ import org.dromara.common.core.config.DefaultConfig;
|
|
|
import org.dromara.common.core.constant.DefaultConstants;
|
|
import org.dromara.common.core.constant.DefaultConstants;
|
|
|
import org.dromara.common.core.domain.R;
|
|
import org.dromara.common.core.domain.R;
|
|
|
import org.dromara.common.core.enums.SystemUseTypeEnum;
|
|
import org.dromara.common.core.enums.SystemUseTypeEnum;
|
|
|
|
|
+import org.dromara.common.core.exception.ServiceException;
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
import org.dromara.common.redis.utils.RedisUtils;
|
|
import org.dromara.common.redis.utils.RedisUtils;
|
|
|
import org.dromara.server.consume.cache.TokenManager;
|
|
import org.dromara.server.consume.cache.TokenManager;
|
|
@@ -22,9 +23,11 @@ import org.dromara.server.consume.domain.vo.yc.TermToken;
|
|
|
import org.dromara.server.consume.service.IXfTermService;
|
|
import org.dromara.server.consume.service.IXfTermService;
|
|
|
import org.dromara.system.api.RemoteUserService;
|
|
import org.dromara.system.api.RemoteUserService;
|
|
|
import org.dromara.system.api.domain.vo.RemoteUserVo;
|
|
import org.dromara.system.api.domain.vo.RemoteUserVo;
|
|
|
|
|
+import org.redisson.api.RLock;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.text.MessageFormat;
|
|
import java.text.MessageFormat;
|
|
|
|
|
+import java.time.Duration;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneOffset;
|
|
import java.time.ZoneOffset;
|
|
|
import java.util.Date;
|
|
import java.util.Date;
|
|
@@ -32,6 +35,7 @@ import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
import java.util.UUID;
|
|
import java.util.UUID;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @ClassName TermBusiness
|
|
* @ClassName TermBusiness
|
|
@@ -110,24 +114,30 @@ public class TermBusiness {
|
|
|
|
|
|
|
|
public R<TermToken> getTermTokenNew(Long termNo, String admin, String pwd){
|
|
public R<TermToken> getTermTokenNew(Long termNo, String admin, String pwd){
|
|
|
String strTermNo = String.valueOf(termNo);
|
|
String strTermNo = String.valueOf(termNo);
|
|
|
- String cacheName = StringUtils.format("{}:term_token", defaultConfig.getTenantId());
|
|
|
|
|
- TermToken termToken = RedisUtils.getCacheMapValue(cacheName, strTermNo);
|
|
|
|
|
- if(ObjectUtil.isEmpty(termToken)|| termToken.getExpireTime() < new Date().getTime()){
|
|
|
|
|
- LocalDateTime ldt = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
|
|
|
|
|
- Date minDate = Date.from(ldt.toInstant(ZoneOffset.of("+8")));
|
|
|
|
|
-
|
|
|
|
|
- LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
- LocalDateTime expireTime = now.plusHours(4);
|
|
|
|
|
-
|
|
|
|
|
- RemoteXfTermVo remoteVo = remoteTermService.queryByNo(termNo, defaultConfig.getTenantId());
|
|
|
|
|
- if (ObjectUtil.isEmpty(remoteVo)) {
|
|
|
|
|
- return R.fail(MessageFormat.format("机号为[{0}]的设备不存在", termNo), null);
|
|
|
|
|
|
|
+ String tenantId = defaultConfig.getTenantId();
|
|
|
|
|
+ String cacheName = StringUtils.format("{}:term_token:{}", tenantId, termNo);
|
|
|
|
|
+ TermToken termToken = RedisUtils.getCacheObject(cacheName);
|
|
|
|
|
+ if(ObjectUtil.isEmpty(termToken)|| termToken.getExpireTime() < System.currentTimeMillis()) {
|
|
|
|
|
+ String lockKey = "LOCK:" + cacheName + ":" + strTermNo;
|
|
|
|
|
+ RLock lock = RedisUtils.getClient().getLock(lockKey);
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 尝试加锁,等待2秒,锁自动释放时间10秒
|
|
|
|
|
+ if (lock.tryLock(2, 10, TimeUnit.SECONDS)) {
|
|
|
|
|
+ // 双重检查(Double-Check)
|
|
|
|
|
+ termToken = RedisUtils.getCacheObject(cacheName);
|
|
|
|
|
+ if (ObjectUtil.isEmpty(termToken) || termToken.getExpireTime() < System.currentTimeMillis()) {
|
|
|
|
|
+ // 创建新token
|
|
|
|
|
+ termToken = createAndSaveToken(termNo, admin, strTermNo, cacheName);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
|
|
+ log.error("获取锁中断", e);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ if (lock.isLocked() && lock.isHeldByCurrentThread()) {
|
|
|
|
|
+ lock.unlock();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- termToken = new TermToken(strTermNo, UUID.randomUUID().toString(), admin, new Date().getTime(), minDate.getTime(),
|
|
|
|
|
- Date.from(expireTime.toInstant(ZoneOffset.of("+8"))).getTime(), remoteVo.getRoomName());
|
|
|
|
|
-
|
|
|
|
|
- RedisUtils.setCacheMapValue(cacheName, strTermNo, termToken);
|
|
|
|
|
}
|
|
}
|
|
|
return R.ok(MessageFormat.format("获取token成功,设备编号[{0}],账号[{1}]", termNo, admin), termToken);
|
|
return R.ok(MessageFormat.format("获取token成功,设备编号[{0}],账号[{1}]", termNo, admin), termToken);
|
|
|
}
|
|
}
|
|
@@ -267,4 +277,30 @@ public class TermBusiness {
|
|
|
return termInfo;
|
|
return termInfo;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private TermToken createAndSaveToken(Long termNo, String admin, String strTermNo, String cacheName) {
|
|
|
|
|
+ // 设备查询
|
|
|
|
|
+ RemoteXfTermVo remoteVo = remoteTermService.queryByNo(termNo, defaultConfig.getTenantId());
|
|
|
|
|
+ if (ObjectUtil.isEmpty(remoteVo)) {
|
|
|
|
|
+ throw new ServiceException(MessageFormat.format("机号为[{0}]的设备不存在", termNo));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 创建token(简化时间处理)
|
|
|
|
|
+ long now = System.currentTimeMillis();
|
|
|
|
|
+ long expireTime = now + TimeUnit.HOURS.toMillis(4); // 4小时后过期
|
|
|
|
|
+
|
|
|
|
|
+ TermToken newToken = new TermToken(
|
|
|
|
|
+ strTermNo,
|
|
|
|
|
+ UUID.randomUUID().toString(),
|
|
|
|
|
+ admin,
|
|
|
|
|
+ now,
|
|
|
|
|
+ Date.from(LocalDateTime.of(2000, 1, 1, 0, 0).toInstant(ZoneOffset.of("+8"))).getTime(),
|
|
|
|
|
+ expireTime,
|
|
|
|
|
+ remoteVo.getRoomName()
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // 写入Redis
|
|
|
|
|
+ RedisUtils.setCacheObject(cacheName, newToken, Duration.ofHours(4));
|
|
|
|
|
+ return newToken;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|