Browse Source

Merge remote-tracking branch 'origin/master'

master
zhaohe 4 months ago
parent
commit
db785357ef
  1. 20
      src/main/java/a8k/app/config/WebConfig.java
  2. 36
      src/main/java/a8k/app/controler/api/v1/app/ctrl/DeviceInitControler.java
  3. 1
      src/main/java/a8k/app/controler/api/v1/app/setting/DeviceSettingControler.java
  4. 1
      src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java
  5. 1
      src/main/java/a8k/app/factory/ZAppPromoptFactory.java
  6. 1
      src/main/java/a8k/app/hardware/type/A8kEcode.java
  7. 3
      src/main/java/a8k/app/i18n/Internationalization.java
  8. 27
      src/main/java/a8k/app/interceptor/RefreshAccessInterceptor.java
  9. 282
      src/main/java/a8k/app/service/data/AppUserMgrService.java
  10. 4
      src/main/java/a8k/app/service/lowerctrl/DeviceMoveToZeroCtrlService.java
  11. 5
      src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/AC30ScanTubeHolderTask.java
  12. 5
      src/main/java/a8k/app/service/setting/AppSettingsMgrService.java
  13. 7
      src/main/java/a8k/app/service/statemgr/TubeStateMgrService.java
  14. 1
      src/main/java/a8k/app/type/error/AEConsumeNotEnoughError.java

20
src/main/java/a8k/app/config/WebConfig.java

@ -0,0 +1,20 @@
package a8k.app.config;
import a8k.app.interceptor.RefreshAccessInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final RefreshAccessInterceptor refreshInterceptor;
public WebConfig(RefreshAccessInterceptor refreshInterceptor) {
this.refreshInterceptor = refreshInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(refreshInterceptor).addPathPatterns("/api/**");
}
}

36
src/main/java/a8k/app/controler/api/v1/app/ctrl/DeviceInitControler.java

@ -2,11 +2,11 @@ package a8k.app.controler.api.v1.app.ctrl;
import a8k.app.service.lowerctrl.DeviceMoveToZeroCtrlService;
import a8k.app.service.mainctrl.DeviceInitService;
import a8k.app.type.ui.ApiRet;
import a8k.app.service.statemgr.GStateMgrService;
import a8k.app.type.exception.AppException;
import a8k.app.type.ui.ApiRet;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
@ -21,19 +21,27 @@ import org.springframework.web.bind.annotation.ResponseBody;
@ResponseBody
@RequiredArgsConstructor
public class DeviceInitControler {
private final DeviceInitService deviceInitService;
private final DeviceInitService deviceInitService;
private final GStateMgrService gStateMgrService;
@Operation(description = "初始化设备")
@PostMapping("/initDevice")
public ApiRet<?> initDevice() throws AppException {
deviceInitService.initDeviceAsync();
return ApiRet.success();
}
@Operation(description = "初始化设备")
@PostMapping("/initDevice")
public ApiRet<?> initDevice() throws AppException {
deviceInitService.initDeviceAsync();
return ApiRet.success();
}
@Operation(description = "获取设备初始化状态")
@PostMapping("/getDeviceInitedTaskState")
public ApiRet<DeviceMoveToZeroCtrlService.State> getDeviceInitedTaskState() {
return ApiRet.success(deviceInitService.getDeviceInitedTaskState());
}
@Operation(description = "获取设备是否完成启动")
@PostMapping("/isBoardParamInited")
public ApiRet<Boolean> isBoardParamInited() {
return ApiRet.success(gStateMgrService.getBoardParamInited());
}
@Operation(description = "获取设备初始化状态")
@PostMapping("/getDeviceInitedTaskState")
public ApiRet<DeviceMoveToZeroCtrlService.State> getDeviceInitedTaskState() {
return ApiRet.success(deviceInitService.getDeviceInitedTaskState());
}
}

1
src/main/java/a8k/app/controler/api/v1/app/setting/DeviceSettingControler.java

@ -1,5 +1,6 @@
package a8k.app.controler.api.v1.app.setting;
import a8k.app.service.data.AppUserMgrService;
import a8k.app.type.exception.AppException;
import a8k.app.type.ui.ApiRet;
import a8k.app.dao.type.db.DeviceSetting;

1
src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java

@ -156,7 +156,6 @@ public class AppWebSocketEndpointMgr {
reportState("TubeHolderSetting", tubeHolderSettingMgrService.getTubeHolderSettings());
}
@Scheduled(fixedDelay = 200)
public void reportDeviceState() {
reportState("DeviceWorkState", deviceWorkStateMgrService.getDeviceWorkState());

1
src/main/java/a8k/app/factory/ZAppPromoptFactory.java

@ -66,6 +66,7 @@ public class ZAppPromoptFactory {
} else {
vals[2] = new ZAppPromoptTable.Val(MessageLevel.Info, consumableStatInfo.requireCnt.toString());
}
table.addVar(vals);
}
return new ZAppPromopt(MessageLevel.Error, "耗材不足", null, table);
} else if (error instanceof AETubeError appError) {

1
src/main/java/a8k/app/hardware/type/A8kEcode.java

@ -61,6 +61,7 @@ public enum A8kEcode {
APPE_DO_ACTION_FAIL_DEVICE_IS_WORKING(152),//设备正在工作中不允许执行操作
APPE_CONSUMABLES_IS_IN_USE_NOT_ALLOW_UNSTALL(153),//耗材正在使用中不允许卸载
DEVICE_STARTUP_IN_PROGRESS(154), // 设备启动中请稍后
//
// 业务流程中的错误
// 1. 点击开始运行后设备在运行过程中出现的错误

3
src/main/java/a8k/app/i18n/Internationalization.java

@ -18,7 +18,7 @@ public class Internationalization {
case APPE_TUBE_HOLDER_SETTING_IS_LOCKED -> "试管架设置被锁定,已锁定的.";
case APPE_EMERGENCY_SAMPLE_IS_PROCESSING -> "添加急诊样本失败,急诊样本还没有处理完成";
case APPE_ADD_EMERGENCY_ACTION_IS_NOT_ALLOWED_WHEN_WORKING -> "添加急诊样本失败,设备正在运行中";
case APPE_DEVICE_IS_IN_FATAL_ERROR -> "设备处于严重错误,请重新初始化后再启动";
case APPE_DEVICE_IS_IN_FATAL_ERROR -> "设备处于严重错误,请关闭电源重启设备";
case APPE_SCAN_TUBEHOLDER_TYPE_TIMEOUT -> "扫描试管架类型超时";
case APPE_TUBE_HOLDER_TYPE_IS_NOT_SUPPORT -> "试管架类型不支持";
case APPE_INFEED_OVERTIME_FAIL -> "入料超时失败";
@ -66,6 +66,7 @@ public class Internationalization {
case IP_FORMAT_ERROR -> "IP格式错误";
case SHUTDOWN_ERROR_DEVICE_IS_WORKING -> "设备正在工作中,不允许关机";
case LOGIN_OUT_ERROR_DEVICE_IS_WORKING -> "设备正在工作中,不允许注销";
case DEVICE_STARTUP_IN_PROGRESS -> "设备启动中,请稍后";
default -> ecode.toString();
};
}

27
src/main/java/a8k/app/interceptor/RefreshAccessInterceptor.java

@ -0,0 +1,27 @@
package a8k.app.interceptor;
import a8k.app.service.data.AppUserMgrService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
/**
* Interceptor that refreshes the last-access timestamp on each HTTP request.
*/
@Component
public class RefreshAccessInterceptor implements HandlerInterceptor {
private final AppUserMgrService userMgr;
public RefreshAccessInterceptor(AppUserMgrService userMgr) {
this.userMgr = userMgr;
}
@Override
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
userMgr.recordAccess();
return true;
}
}

282
src/main/java/a8k/app/service/data/AppUserMgrService.java

@ -1,123 +1,193 @@
package a8k.app.service.data;
import a8k.app.dao.AppUsrDao;
import a8k.app.dao.DeviceSettingDao;
import a8k.app.dao.type.db.AppUser;
import a8k.app.dao.type.db.DeviceSetting;
import a8k.app.hardware.type.A8kEcode;
import a8k.app.type.exception.AppException;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
@Component
@EnableScheduling //Enable scheduled tasks
public class AppUserMgrService {
static Logger logger = org.slf4j.LoggerFactory.getLogger(AppUserMgrService.class);
@Resource
AppUsrDao appUsrDao;
AppUser loginUsr = null;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// EXT FUNC
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public AppUser login(int id, String password) throws AppException {
var usr = appUsrDao.getUsrById(id);
if (usr == null)
throw new AppException(A8kEcode.USR_NOT_EXIT);
if (!usr.password.equals(password)) {
throw new AppException(A8kEcode.USR_PASSWORD_ERROR);
}
loginUsr = usr;
return (usr);
}
public Void unlogin() {
loginUsr = null;
return null;
}
synchronized public AppUser getLoginUsr() {
return (loginUsr);
}
public List<AppUser> getUsrlist() {
return (appUsrDao.getAllUsr());
}
public AppUser addUser(String account, String password, AppUser.UsrRole type) throws AppException {
var user = appUsrDao.getUsrByAccount(account);
if (user != null) {
throw new AppException(A8kEcode.USR_ALREADY_EXIST);
}
user = new AppUser(account, password, type);
appUsrDao.addUser(user);
return appUsrDao.getUsrByAccount(account);
}
public Void delUser(Integer id) {
appUsrDao.deleteUserById(id);
return null;
}
public AppUser updateUsr(AppUser usr) {
appUsrDao.updateUser(usr);
return usr;
}
public AppUser modifyUsrPwd(Integer id, String oldpasswd,String password) throws AppException {
var user = appUsrDao.getUsrById(id);
if (user == null) {
throw new AppException(A8kEcode.USR_NOT_EXIT);
}
if(!user.password.equals(oldpasswd)){
throw new AppException(A8kEcode.USR_OLD_PASSWORD_ERROR);
}
if (password.isEmpty()) {
throw new AppException(A8kEcode.USR_PASSWORD_IS_EMPTY);
}
user.password = password;
appUsrDao.updateUser(user);
return user;
}
public AppUser modifyUsrRole(Integer id, AppUser.UsrRole usrRole) throws AppException {
var user = appUsrDao.getUsrById(id);
if (user == null) {
throw new AppException(A8kEcode.USR_NOT_EXIT);
}
user.usrRole = usrRole;
appUsrDao.updateUser(user);
return user;
}
public AppUser modifyUsrAccount(Integer id, String newaccount) throws AppException {
var user = appUsrDao.getUsrById(id);
if (user == null) {
throw new AppException(A8kEcode.USR_NOT_EXIT);
}
user.account = newaccount;
appUsrDao.updateUser(user);
return user;
}
static Logger logger = org.slf4j.LoggerFactory.getLogger(AppUserMgrService.class);
/**
* current user
*/
@Resource
AppUsrDao appUsrDao;
@Resource
DeviceSettingDao deviceSettingDao;
AppUser loginUsr = null;
/**
* timestamp of last access
*/
private volatile Instant lastAccess;
/**
* auto logout time out duration
*/
private volatile Duration autoLogoutTimeout;
/**
* flag to enable auto logout
*/
private volatile boolean autoLogout;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// EXT FUNC
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/**
* load timeout and switch
*/
@PostConstruct
public void init() {
DeviceSetting deviceSetting = deviceSettingDao.get();
int minutes = deviceSetting.getAutoLogoutTimeout();
this.autoLogoutTimeout = Duration.ofMinutes(minutes);
boolean autoLogout = deviceSetting.getAutoLogout();
this.autoLogout = autoLogout;
logger.debug("initialized autoLogout={}, timeout={} minutes", autoLogout, minutes);
}
public AppUser login(int id, String password) throws AppException {
var usr = appUsrDao.getUsrById(id);
if (usr == null)
throw new AppException(A8kEcode.USR_NOT_EXIT);
if (!usr.password.equals(password)) {
throw new AppException(A8kEcode.USR_PASSWORD_ERROR);
}
loginUsr = usr;
return (usr);
}
public Void unlogin() {
loginUsr = null;
return null;
}
/**
* refresh lastAccess on each intercepted request
*/
public synchronized void recordAccess() {
if (loginUsr != null) {
this.lastAccess = Instant.now();
}
}
public synchronized void updateAutoLogout(boolean autoLogout) {
this.autoLogout = autoLogout;
logger.debug("updated cache autoLogout:{}", autoLogout);
}
public synchronized void updateAutoLogoutTimeout(int autoLogoutTimeout) {
this.autoLogoutTimeout = Duration.ofMinutes(autoLogoutTimeout);
logger.debug("updated cache autoLogoutTimeout {} minutes", autoLogoutTimeout);
}
synchronized public AppUser getLoginUsr() {
return (loginUsr);
}
public List<AppUser> getUsrlist() {
return (appUsrDao.getAllUsr());
}
public AppUser addUser(String account, String password, AppUser.UsrRole type) throws AppException {
var user = appUsrDao.getUsrByAccount(account);
if (user != null) {
throw new AppException(A8kEcode.USR_ALREADY_EXIST);
}
user = new AppUser(account, password, type);
appUsrDao.addUser(user);
return appUsrDao.getUsrByAccount(account);
}
public Void delUser(Integer id) {
appUsrDao.deleteUserById(id);
return null;
}
public AppUser updateUsr(AppUser usr) {
appUsrDao.updateUser(usr);
return usr;
}
public AppUser modifyUsrPwd(Integer id, String oldpasswd, String password) throws AppException {
var user = appUsrDao.getUsrById(id);
if (user == null) {
throw new AppException(A8kEcode.USR_NOT_EXIT);
}
if (!user.password.equals(oldpasswd)) {
throw new AppException(A8kEcode.USR_OLD_PASSWORD_ERROR);
}
if (password.isEmpty()) {
throw new AppException(A8kEcode.USR_PASSWORD_IS_EMPTY);
}
user.password = password;
appUsrDao.updateUser(user);
return user;
}
public AppUser modifyUsrRole(Integer id, AppUser.UsrRole usrRole) throws AppException {
var user = appUsrDao.getUsrById(id);
if (user == null) {
throw new AppException(A8kEcode.USR_NOT_EXIT);
}
user.usrRole = usrRole;
appUsrDao.updateUser(user);
return user;
}
public AppUser modifyUsrAccount(Integer id, String newaccount) throws AppException {
var user = appUsrDao.getUsrById(id);
if (user == null) {
throw new AppException(A8kEcode.USR_NOT_EXIT);
}
user.account = newaccount;
appUsrDao.updateUser(user);
return user;
}
@Scheduled(fixedDelay = 60_000)
public void autoLogoutTask() {
if (!autoLogout || loginUsr == null) {
return;
}
if (Duration.between(lastAccess, Instant.now()).compareTo(autoLogoutTimeout) >= 0) {
logger.info("auto logout user {} after {} minutes inactivity", loginUsr.account, autoLogoutTimeout.toMinutes());
unlogin();
}
}
}

4
src/main/java/a8k/app/service/lowerctrl/DeviceMoveToZeroCtrlService.java

@ -273,7 +273,9 @@ public class DeviceMoveToZeroCtrlService {
if (workThread != null && workThread.isAlive()) {
throw AppException.ofAECodeError("设备正在初始化中");
}
if(!gstate.getBoardParamInited()){
throw AppException.of(A8kEcode.DEVICE_STARTUP_IN_PROGRESS);
}
if (workThread != null) {
try {
workThread.join();

5
src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/AC30ScanTubeHolderTask.java

@ -91,9 +91,7 @@ public class AC30ScanTubeHolderTask extends A8kActionTask {
}
public Boolean isReady() {
return tubeStateMgrService.isTubeHolderProcessCompleted() &&
getTubeholderEnterPosPPS() &&
!deviceWorkStateMgrService.getConsumeNotEnoughErrorFlag();
return tubeStateMgrService.isTubeHolderProcessCompleted() && getTubeholderEnterPosPPS();
}
public String toDisplayString() {
@ -153,7 +151,6 @@ public class AC30ScanTubeHolderTask extends A8kActionTask {
log.info("试管架配置 {}", setting);
TubeHolder tubeholder = new TubeHolder();
Assert.isTrue(setting == null || setting.tubeSettings.length == tubeholder.getTubes().length, "试管架配置信息与试管数量不匹配");
//获取试管架类型
A8kTubeHolderType tubeHolderType = A8kTubeHolderType.of(scanResult.tubeHolderType);

5
src/main/java/a8k/app/service/setting/AppSettingsMgrService.java

@ -1,5 +1,6 @@
package a8k.app.service.setting;
import a8k.app.service.data.AppUserMgrService;
import a8k.app.type.exception.AppException;
import a8k.app.dao.DeviceSettingDao;
import a8k.app.dao.LISSettingDao;
@ -16,6 +17,8 @@ import org.springframework.stereotype.Component;
@Component
public class AppSettingsMgrService {
Logger logger = org.slf4j.LoggerFactory.getLogger(AppSettingsMgrService.class);
@Resource
AppUserMgrService appUserMgrService;
@Resource
DeviceSettingDao deviceSettingDao;
@ -61,12 +64,14 @@ public class AppSettingsMgrService {
DeviceSetting setting = deviceSettingDao.get();
setting.autoLogoutTimeout = val;
deviceSettingDao.update(setting);
appUserMgrService.updateAutoLogoutTimeout(val);
}
public void setAutoLogout(Boolean val) {
DeviceSetting setting = deviceSettingDao.get();
setting.autoLogout = val;
deviceSettingDao.update(setting);
appUserMgrService.updateAutoLogout(val);
}

7
src/main/java/a8k/app/service/statemgr/TubeStateMgrService.java

@ -124,8 +124,8 @@ public class TubeStateMgrService {
//试管状态管理
//
public synchronized AppError newTubeHolder(TubeHolder tubeHolder) throws AppException {
this.tubeHolder = tubeHolder;
var tubes = tubeHolder.getTubes();
// this.tubeHolder = tubeHolder;
// var tubes = tubeHolder.getTubes();
List<ConsumableStateAnalyzerService.ConsumableStatInfo> statInfos = consumableStateAnalyzerService.analyze(tubeHolder);
@ -140,7 +140,8 @@ public class TubeStateMgrService {
return new AppError(A8kEcode.APPE_TIP_NOT_ENOUGH);
}
this.tubeHolder = tubeHolder;
var tubes = tubeHolder.getTubes();
for (Tube tube : tubes) {
if (tube.getState().equals(TubeState.EMPTY)) {
continue;

1
src/main/java/a8k/app/type/error/AEConsumeNotEnoughError.java

@ -13,6 +13,7 @@ public class AEConsumeNotEnoughError extends AppError {
public AEConsumeNotEnoughError(List<ConsumableStateAnalyzerService.ConsumableStatInfo> consumableStatInfos) {
super(A8kEcode.APPE_CONSUME_NOT_ENOUGH);
this.consumableStatInfos = consumableStatInfos;
}
}
Loading…
Cancel
Save