Merge remote-tracking branch 'origin/test' into master-huawei

This commit is contained in:
thesai 2021-11-18 18:59:52 +08:00
commit cfc33cc649
24 changed files with 193 additions and 77 deletions

View File

@ -12,6 +12,8 @@ public enum TencentSMSTemplate {
VerificationCode_International("JiuLian", 453984, 2),
OrderNotice("玖琏科技", 260120, 4),
SystemNotice("玖琏科技", 0000, 3),
ZzjAlertNotice("玖琏科技", 1206126, 2),
;
private String sign;

View File

@ -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()));
}
}

View File

@ -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);
}
}

View File

@ -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);
/**
* 发送订单通知
*/

View File

@ -107,6 +107,7 @@ public class LoginSessionManager {
LoginUserInfoVO loginUserInfoVO = this.queryLoginInfoByToken(token);
BusinessExceptionAssertEnum.LOGIN_EXPIRED.assertNotNull(loginUserInfoVO);
loginUserInfoVO.cancelPreLogout();
loginUserInfoVO.updateLastQueryTime();
return loginUserInfoVO;
}

View File

@ -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);

View File

@ -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);
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) {

View File

@ -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,
/** 列车车门开关 */

View File

@ -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) {

View File

@ -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 -> {

View File

@ -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());
}
}

View File

@ -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 {

View 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);
}
}

View File

@ -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));
}
}