Merge remote-tracking branch 'origin/test' into master-huawei
This commit is contained in:
commit
cfc33cc649
@ -12,6 +12,8 @@ public enum TencentSMSTemplate {
|
||||
VerificationCode_International("JiuLian", 453984, 2),
|
||||
OrderNotice("玖琏科技", 260120, 4),
|
||||
SystemNotice("玖琏科技", 0000, 3),
|
||||
|
||||
ZzjAlertNotice("玖琏科技", 1206126, 2),
|
||||
;
|
||||
|
||||
private String sign;
|
||||
|
@ -0,0 +1,42 @@
|
||||
package club.joylink.rtss.controller;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.services.ISmsService;
|
||||
import club.joylink.rtss.vo.SmsResponse;
|
||||
import club.joylink.rtss.vo.sms.ZzjAlertSmsParamVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信接口
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/sms")
|
||||
public class SmsController {
|
||||
@Autowired
|
||||
private ISmsService iSmsService;
|
||||
|
||||
@PostMapping("/zzjAlert")
|
||||
public void sendZzjAlert(@RequestBody ZzjAlertSmsParamVo paramVo) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL
|
||||
.assertTrue(paramVo.isValidRequest());
|
||||
long ts = System.currentTimeMillis();
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add(paramVo.getDeviceName());
|
||||
params.add(paramVo.getDescription());
|
||||
SmsResponse resp = this.iSmsService.sendZzjAlertNotice(paramVo.getMobile(),
|
||||
paramVo.getNationCode(), params, ts);
|
||||
BusinessExceptionAssertEnum.THIRD_SERVICE_CALL_EXCEPTION.assertTrue(resp.getResult() == 0,
|
||||
String.format("短信发送服务调用异常:[result: %s, errmsg: %s]", resp.getResult(), resp.getErrmsg()));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -54,11 +54,15 @@ public class LoginUserController {
|
||||
}
|
||||
return filter;
|
||||
}).collect(Collectors.toList());
|
||||
int total = filterList.size();
|
||||
if (queryVO.getOffset() > total) {
|
||||
queryVO.setPageNum(1);
|
||||
}
|
||||
List<LoginUserInfoVO> resultList = filterList.stream()
|
||||
.skip(queryVO.getOffset())
|
||||
.limit(queryVO.getPageSize())
|
||||
.collect(Collectors.toList());
|
||||
return new PageVO<>(queryVO.getPageNum(), queryVO.getPageSize(), filterList.size(), resultList);
|
||||
return new PageVO<>(queryVO.getPageNum(), queryVO.getPageSize(), total, resultList);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ public interface ISmsService {
|
||||
*/
|
||||
SmsResponse sendValidateCode(String mobile, String nationCode, List<String> params, long ts);
|
||||
|
||||
SmsResponse sendZzjAlertNotice(String mobile, String nationCode, List<String> parmas, long ts);
|
||||
|
||||
/**
|
||||
* 发送订单通知
|
||||
*/
|
||||
|
@ -107,6 +107,7 @@ public class LoginSessionManager {
|
||||
LoginUserInfoVO loginUserInfoVO = this.queryLoginInfoByToken(token);
|
||||
BusinessExceptionAssertEnum.LOGIN_EXPIRED.assertNotNull(loginUserInfoVO);
|
||||
loginUserInfoVO.cancelPreLogout();
|
||||
loginUserInfoVO.updateLastQueryTime();
|
||||
return loginUserInfoVO;
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,11 @@ public class TcSmsService implements ISmsService {
|
||||
return sendToOneOnTpl(template, mobile, nationCode, params, ts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendZzjAlertNotice(String mobile, String nationCode, List<String> parmas, long ts) {
|
||||
return sendToOneOnTpl(TencentSMSTemplate.ZzjAlertNotice, mobile, nationCode, parmas, ts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendOrderNotice(List<InternationalMobile> internationalMobileList, List<String> params) {
|
||||
return sendToMultiOnTpl(TencentSMSTemplate.OrderNotice, internationalMobileList, params);
|
||||
|
@ -80,6 +80,43 @@ public class AuthenticateService implements IAuthenticateService {
|
||||
@Autowired
|
||||
private StompMessageService stompMessageService;
|
||||
|
||||
@Scheduled(fixedRate = 1000)
|
||||
public void clearExpireCache() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 清理扫码登录状态
|
||||
List<LoginStatusVO> loginStatus = this.loginSessionManager.queryAllLoginStatus();
|
||||
for (LoginStatusVO status : loginStatus) {
|
||||
if ((status.getFinishTime() != null && now.isAfter(status.getFinishTime().plusSeconds(30))) ||
|
||||
now.isAfter(status.getLastQueryTime().plusMinutes(1))) {
|
||||
this.loginSessionManager.removeLoginStatus(status);
|
||||
}
|
||||
}
|
||||
// 清理用户会话信息
|
||||
List<LoginUserInfoVO> loginUserInfos = this.loginSessionManager.getAllLoginUserInfos();
|
||||
for (LoginUserInfoVO loginUserInfo : loginUserInfos) {
|
||||
if (loginUserInfo.isWechatLogin()) {
|
||||
if (now.isAfter(loginUserInfo.getLastQueryTime().plusMinutes(10))) {
|
||||
log.info("登出小程序用户:{}", loginUserInfo.getAccountVO().getId());
|
||||
this.logout(loginUserInfo);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (loginUserInfo.getPreLogoutTime() != null) { // 预登出
|
||||
LocalDateTime preLogoutTime = loginUserInfo.getPreLogoutTime();
|
||||
if (Objects.nonNull(preLogoutTime) &&
|
||||
now.isAfter(preLogoutTime.plusSeconds(30))) {
|
||||
// 预退出30秒如果还没有取消,视为退出系统
|
||||
log.info(String.format("登出预登出用户[%s-%s-%s-%s]",
|
||||
loginUserInfo.getAccountVO().getId(),
|
||||
loginUserInfo.getClient(),
|
||||
loginUserInfo.getProject(),
|
||||
loginUserInfo.getDeviceVO()));
|
||||
this.logout(loginUserInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginStatusVO getWmLoginUrl(String clientId, String secret, Project project, String deviceCode) {
|
||||
String envId = SystemEnv.getSystemEnvIdByName(this.otherConfig.getEnv());
|
||||
@ -95,13 +132,15 @@ public class AuthenticateService implements IAuthenticateService {
|
||||
LoginScanParam param = new LoginScanParam(envId, sessionId, clientId);
|
||||
String state = param.toParam();
|
||||
String url = weChatConfig.getWmLoginUrl(state);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LoginStatusVO loginStatusVO = LoginStatusVO.builder()
|
||||
.url(url)
|
||||
.sessionId(sessionId)
|
||||
.client(client)
|
||||
.project(project)
|
||||
.deviceVO(deviceVO)
|
||||
.time(LocalDateTime.now())
|
||||
.time(now)
|
||||
.lastQueryTime(now)
|
||||
.status(LoginStatusVO.ScanLoginStatus.WAIT)
|
||||
.build();
|
||||
this.loginSessionManager.saveLoginStatus(loginStatusVO);
|
||||
@ -195,30 +234,6 @@ public class AuthenticateService implements IAuthenticateService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查预登出用户,超时登出
|
||||
*/
|
||||
@Scheduled(fixedRate = 1000)
|
||||
public void logoutProgress() {
|
||||
List<LoginUserInfoVO> infoVOList = this.loginSessionManager.queryPreLogoutInfos();
|
||||
if (!CollectionUtils.isEmpty(infoVOList)) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
for (LoginUserInfoVO userInfoVO : infoVOList) {
|
||||
LocalDateTime preLogoutTime = userInfoVO.getPreLogoutTime();
|
||||
if (Objects.nonNull(preLogoutTime) &&
|
||||
now.isAfter(preLogoutTime.plusSeconds(10))) {
|
||||
// 预退出10秒如果还没有取消,视为退出系统
|
||||
log.info(String.format("登出预登出用户[%s-%s-%s-%s]",
|
||||
userInfoVO.getAccountVO().getId(),
|
||||
userInfoVO.getClient(),
|
||||
userInfoVO.getProject(),
|
||||
userInfoVO.getDeviceVO()));
|
||||
this.logout(userInfoVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wmConfirmClientLogin(String code, String state) {
|
||||
LoginScanParam param = LoginScanParam.parse(state);
|
||||
@ -390,7 +405,7 @@ public class AuthenticateService implements IAuthenticateService {
|
||||
if (Objects.nonNull(loginUserInfoVO)) {
|
||||
log.debug(String.format("用户[%s(%s)]登出[%s]",
|
||||
loginUserInfoVO.getAccountVO().getNickname(), loginUserInfoVO.getAccountVO().getId(),
|
||||
loginUserInfoVO.getClientInfoStr()));
|
||||
loginUserInfoVO.buildClientInfoStr()));
|
||||
// 清除用户登录信息
|
||||
this.loginSessionManager.clearOf(loginUserInfoVO);
|
||||
UserLogoutEvent userLogoutEvent = new UserLogoutEvent(this, loginUserInfoVO);
|
||||
@ -439,34 +454,11 @@ public class AuthenticateService implements IAuthenticateService {
|
||||
if (loginStatusVO.isProjectDeviceLogin()) {
|
||||
this.checkAndHandleSpecialDeviceLogin(loginStatusVO);
|
||||
}
|
||||
loginStatusVO.checkExpireAndUpdate();
|
||||
if (loginStatusVO.isComplete()) {
|
||||
// 完成,删除
|
||||
this.loginSessionManager.removeLoginStatus(loginStatusVO);
|
||||
return LoginStatusVO.builder()
|
||||
loginStatusVO.updateQueryTime();
|
||||
return LoginStatusVO.builder()
|
||||
.status(loginStatusVO.getStatus())
|
||||
.token(loginStatusVO.getToken())
|
||||
.build();
|
||||
} else {
|
||||
return LoginStatusVO.builder()
|
||||
.status(loginStatusVO.getStatus())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedRate = 5000)
|
||||
public void loginStatusClean() {
|
||||
List<LoginStatusVO> loginStatusList = this.loginSessionManager.queryAllLoginStatus();
|
||||
List<LoginStatusVO> removeList = new ArrayList<>();
|
||||
for (LoginStatusVO loginStatusVO : loginStatusList) {
|
||||
int deleteRemain = loginStatusVO.updateDeleteRemain(5000);
|
||||
if (deleteRemain > 10000) {
|
||||
removeList.add(loginStatusVO);
|
||||
}
|
||||
}
|
||||
for (LoginStatusVO loginStatusVO : removeList) {
|
||||
this.loginSessionManager.removeLoginStatus(loginStatusVO);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndHandleSpecialDeviceLogin(LoginStatusVO loginStatusVO) {
|
||||
|
@ -404,8 +404,9 @@ public class Operation {
|
||||
Driver_ATO_Open,
|
||||
/** 改变ATP状态 */
|
||||
Driver_ATP_Change,
|
||||
// /** 改变列车运行模式 */
|
||||
// Driver_Drive_Mode_Change,
|
||||
/** 改变列车运行模式 */
|
||||
@Deprecated // 场景旧数据反序列化需要
|
||||
Driver_Drive_Mode_Change,
|
||||
/** 换端 */
|
||||
Driver_Change_Head,
|
||||
/** 列车车门开关 */
|
||||
|
@ -4,6 +4,7 @@ import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.DriveMode;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
@ -80,8 +81,10 @@ public class DriverOperateHandler {
|
||||
ATPService.changeGear(train, gear);
|
||||
}
|
||||
|
||||
// @OperateHandlerMapping(type = Operation.Type.Driver_Drive_Mode_Change)
|
||||
// public void changeTrainDriveMode(Simulation simulation, String groupNumber, DriveMode driveMode) {
|
||||
// 场景旧数据反序列化需要
|
||||
@Deprecated
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Drive_Mode_Change)
|
||||
public void changeTrainDriveMode(Simulation simulation, String groupNumber, DriveMode driveMode) {
|
||||
// VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
// switch (driveMode) {
|
||||
// case AM:
|
||||
@ -92,7 +95,7 @@ public class DriverOperateHandler {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_ATO_Open)
|
||||
public void openAto(Simulation simulation, String groupNumber) {
|
||||
|
@ -425,11 +425,10 @@ public class Section extends DelayUnlockDevice {
|
||||
*/
|
||||
public void clearOccupy() {
|
||||
setCtOccupied(false);
|
||||
this.setNctOccupied(false);
|
||||
setNctOccupied(false);
|
||||
if (!CollectionUtils.isEmpty(this.logicList)) {
|
||||
for (Section section : this.logicList) {
|
||||
section.setCtOccupied(false);
|
||||
section.setNctOccupied(false);
|
||||
section.clearOccupy();
|
||||
}
|
||||
}
|
||||
// if (this.isAxleCounter()) {
|
||||
@ -850,14 +849,14 @@ public class Section extends DelayUnlockDevice {
|
||||
}
|
||||
Section cross = queryCross();
|
||||
if (cross != null) {
|
||||
cross.crossJudgeInvalid();
|
||||
cross.crossJudgeOccupied();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 岔心判断失效
|
||||
* 岔心判断占用
|
||||
*/
|
||||
private void crossJudgeInvalid() {
|
||||
private void crossJudgeOccupied() {
|
||||
if (!this.cross)
|
||||
return;
|
||||
this.logicList.forEach(logic -> {
|
||||
|
@ -43,16 +43,23 @@ public class LoginUserInfoVO {
|
||||
private String group;
|
||||
|
||||
private LocalDateTime preLogoutTime;
|
||||
private LocalDateTime lastQueryTime; // 最后使用时间
|
||||
|
||||
public LoginUserInfoVO(AccountVO accountVO, Client client, Project project, ProjectDeviceVO deviceVO) {
|
||||
this.accountVO = accountVO;
|
||||
this.client = client;
|
||||
this.project = project;
|
||||
this.deviceVO = deviceVO;
|
||||
this.loginTime = LocalDateTime.now();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
this.loginTime = now;
|
||||
this.lastQueryTime = now;
|
||||
this.token = buildToken();
|
||||
}
|
||||
|
||||
public void updateLastQueryTime() {
|
||||
this.lastQueryTime = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public static LoginUserInfoVO buildStressTestInfo() {
|
||||
AccountVO accountVO = new AccountVO();
|
||||
accountVO.setId(1l);
|
||||
@ -83,7 +90,7 @@ public class LoginUserInfoVO {
|
||||
return accountLogin;
|
||||
}
|
||||
|
||||
public String getClientInfoStr() {
|
||||
public String buildClientInfoStr() {
|
||||
String device = null;
|
||||
if (Objects.nonNull(this.deviceVO)) {
|
||||
device = this.deviceVO.toString();
|
||||
@ -92,7 +99,7 @@ public class LoginUserInfoVO {
|
||||
}
|
||||
|
||||
public String buildDebugStr() {
|
||||
return String.format("%s, user{id: %s, nickname: %s, name: %s}", this.getClientInfoStr(), accountVO.getId(), accountVO.getNickname(), accountVO.getName());
|
||||
return String.format("%s, user{id: %s, nickname: %s, name: %s}", this.buildClientInfoStr(), accountVO.getId(), accountVO.getNickname(), accountVO.getName());
|
||||
}
|
||||
|
||||
public boolean isProjectDeviceLogin() {
|
||||
@ -112,4 +119,8 @@ public class LoginUserInfoVO {
|
||||
public boolean isDispatcherRaceTrainingLogin() {
|
||||
return Project.DRTS.equals(this.project);
|
||||
}
|
||||
|
||||
public boolean isWechatLogin() {
|
||||
return Client.Assistant.equals(this.getClient());
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,10 @@ public class LoginStatusVO {
|
||||
|
||||
private LocalDateTime time;
|
||||
|
||||
private int deleteRemain;
|
||||
@JsonIgnore
|
||||
private LocalDateTime finishTime;
|
||||
@JsonIgnore
|
||||
private LocalDateTime lastQueryTime;
|
||||
|
||||
private ScanLoginStatus status;
|
||||
|
||||
@ -54,25 +57,16 @@ public class LoginStatusVO {
|
||||
}
|
||||
|
||||
public void checkExpireAndUpdate() {
|
||||
this.resetDeleteRemain();
|
||||
if (Objects.nonNull(this.deviceVO)) {
|
||||
// 项目设备,永不过期
|
||||
return;
|
||||
}
|
||||
if (LocalDateTime.now().isAfter(time.plusMinutes(5))) {
|
||||
this.status = ScanLoginStatus.EXPIRE;
|
||||
this.finishTime = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetDeleteRemain() {
|
||||
this.deleteRemain = 0;
|
||||
}
|
||||
|
||||
public int updateDeleteRemain(int add) {
|
||||
this.deleteRemain += add;
|
||||
return this.deleteRemain;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isProjectDeviceLogin() {
|
||||
return Objects.nonNull(this.deviceVO);
|
||||
@ -81,6 +75,11 @@ public class LoginStatusVO {
|
||||
public void success(String token) {
|
||||
this.token = token;
|
||||
this.status = LoginStatusVO.ScanLoginStatus.SUCCESS;
|
||||
this.finishTime = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public void updateQueryTime() {
|
||||
this.lastQueryTime = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public enum ScanLoginStatus {
|
||||
|
27
src/main/java/club/joylink/rtss/vo/sms/SmsParamVo.java
Normal file
27
src/main/java/club/joylink/rtss/vo/sms/SmsParamVo.java
Normal file
@ -0,0 +1,27 @@
|
||||
package club.joylink.rtss.vo.sms;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class SmsParamVo {
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 国际码
|
||||
*/
|
||||
private String nationCode = "86";
|
||||
/**
|
||||
* 请求校验
|
||||
*/
|
||||
String checksum;
|
||||
|
||||
public abstract String calCheckSum();
|
||||
|
||||
public boolean isValidRequest() {
|
||||
return this.calCheckSum().equals(checksum);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package club.joylink.rtss.vo.sms;
|
||||
|
||||
import club.joylink.rtss.util.EncryptUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 转辙机告警短信消息参数
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class ZzjAlertSmsParamVo extends SmsParamVo {
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String deviceName;
|
||||
/**
|
||||
* 故障描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
@Override
|
||||
public String calCheckSum() {
|
||||
return EncryptUtil.md5(String.format("[%s]-%s::%s::%s", "joylink", this.getMobile(), this.deviceName, this.description));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user