jh-module-ecg/jh-module-ecg-biz/pom.xml
@@ -130,6 +130,16 @@ <artifactId>spring-cloud-starter-openfeign</artifactId> <version>${openfeign.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/Constants.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,5 @@ package cn.lihu.jh.module.ecg; public interface Constants { static final String ECG_OPENING_TIME_KEY = "ecg.openingtime"; } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/Utils.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,30 @@ package cn.lihu.jh.module.ecg; import jodd.typeconverter.impl.LocalTimeConverter; import java.time.LocalTime; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Utils { public static LocalTime parseOpeningTime(String strOpeningTime) { String regex = "(\\d+)[:ï¼](\\d+)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(strOpeningTime); if (!matcher.find()) return null; // è·åæ´ä¸ªå¹é çå符串 String fullMatch = matcher.group(); // è·å第ä¸ä¸ªæè·ç»ï¼å°æ¶ï¼ String strHour = matcher.group(1); // è·å第äºä¸ªæè·ç»ï¼åéï¼ String strMinute = matcher.group(2); LocalTime localTime = LocalTime.of(Integer.valueOf(strHour), Integer.valueOf(strMinute)); return localTime; } } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/config/DynamicSchedulingConfig.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,43 @@ package cn.lihu.jh.module.ecg.config; import cn.lihu.jh.module.ecg.Utils; import cn.lihu.jh.module.ecg.service.queue.QueueService; import cn.lihu.jh.module.infra.api.config.ConfigApi; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import javax.annotation.Resource; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.concurrent.Executors; import static cn.lihu.jh.module.ecg.Constants.ECG_OPENING_TIME_KEY; @Configuration @EnableScheduling public class DynamicSchedulingConfig implements SchedulingConfigurer { @Resource private ConfigApi configApi; @Resource private QueueService queueService; @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(Executors.newScheduledThreadPool(1)); String strOpeningTime = configApi.getConfigValueByKey(ECG_OPENING_TIME_KEY); LocalTime openingTime = Utils.parseOpeningTime(strOpeningTime); String cronExpression = String.format("0 %d %d * * ?", openingTime.getMinute(), openingTime.getHour()); System.out.println(cronExpression); taskRegistrar.addCronTask(() -> { System.out.println("Dynamic Task executed at: " + System.currentTimeMillis()); queueService.startBiz(); }, cronExpression); } } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/controller/admin/appointment/AppointmentController.java
@@ -1,6 +1,8 @@ package cn.lihu.jh.module.ecg.controller.admin.appointment; import cn.hutool.core.bean.BeanUtil; import cn.lihu.jh.framework.common.exception.ErrorCode; import cn.lihu.jh.framework.common.util.date.DateUtils; import cn.lihu.jh.module.ecg.controller.admin.queue.vo.QueueSaveReqVO; import cn.lihu.jh.module.ecg.feign.RemoteDataService; import cn.lihu.jh.module.ecg.feign.RestApiReqBodyVo; @@ -27,6 +29,8 @@ import cn.lihu.jh.framework.common.pojo.PageResult; import cn.lihu.jh.framework.common.pojo.CommonResult; import cn.lihu.jh.framework.common.util.object.BeanUtils; import static cn.lihu.jh.framework.common.pojo.CommonResult.error; import static cn.lihu.jh.framework.common.pojo.CommonResult.success; import cn.lihu.jh.framework.excel.core.util.ExcelUtils; @@ -180,6 +184,9 @@ //TODO å ä»é¢çº¦è¡¨åæ°æ®ï¼åç»å¯¹æ¥æ°æ®å¹³å°æ¥é¢çº¦æ°æ® AppointmentDO appointment = appointmentService.getAppointment(confirmReqVO.getId()); if ( !DateUtils.isToday(appointment.getBookDate()) ) return error( new ErrorCode(101, "䏿¯ä»å¤©çé¢çº¦ç¨æ·")); QueueSaveReqVO queueSaveReqVO = new QueueSaveReqVO(); queueSaveReqVO.setPatId( appointment.getPatId()); queueSaveReqVO.setPatName( appointment.getPatName() ); jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/controller/admin/queue/queueController.java
@@ -96,16 +96,17 @@ @Operation(summary = "å¼è¯è®¾ç½®") @PreAuthorize("@ss.hasPermission('ecg:queue:setting')") public CommonResult<Integer> openingSetting() { // ä»DB忥工ä½çæ£è éåæ°æ®å° å·¥ä½ä¼å éå, å¯è½ææ°å¼å·¥ä½ queueService.initQueue(); return success(0); } @GetMapping("/reorder") @Operation(summary = "å¼è¯åä¸å»ï¼å¯¹å°±è¯åå¤ç人åéæ°æåº") @GetMapping("/startbiz") @Operation(summary = "æå¨å¼è¯") @PreAuthorize("@ss.hasPermission('ecg:queue:setting')") public CommonResult<Integer> queueReorder() { queueService.reorderQueue(); public CommonResult<Integer> startBiz() { queueService.startBiz(); return success(0); } } } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/controller/admin/queue/vo/queueSaveReqVO.java
@@ -5,6 +5,7 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; @Schema(description = "管çåå° - æéæ°å¢/ä¿®æ¹ Request VO") @@ -25,6 +26,10 @@ @Schema(description = "æ£è æ§å«") private Byte patGender; @Schema(description = "é¢çº¦æ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "é¢çº¦æ¥æä¸è½ä¸ºç©º") private LocalDateTime bookDate; @Schema(description = "é¢çº¦æ¶é´æ®µ", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "é¢çº¦æ¶é´æ®µä¸è½ä¸ºç©º") private Integer bookTimeslot; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/listener/MySpringEventListener.java
@@ -1,22 +1,46 @@ package cn.lihu.jh.module.ecg.listener; import cn.lihu.jh.module.ecg.Utils; import cn.lihu.jh.module.ecg.service.queue.QueueService; import cn.lihu.jh.module.infra.api.config.ConfigApi; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import static cn.lihu.jh.module.ecg.Constants.ECG_OPENING_TIME_KEY; @Component public class MySpringEventListener { @Resource private ConfigApi configApi; @Resource private QueueService queueService; @EventListener public void onApplicationEvent(ApplicationStartedEvent event) { System.out.println("åºç¨å¯å¨å®æï¼éç¥çå¬å¨æ§è¡ç¼åé¢å è½½æä½"); System.out.println("åºç¨å¯å¨å®æï¼ç³»ç»åå§ããã"); queueService.initQueue(); queueService.hurryup(); String strOpeningTime = configApi.getConfigValueByKey(ECG_OPENING_TIME_KEY); LocalTime openingTime = Utils.parseOpeningTime(strOpeningTime); // è·åå½åæ¶é´ LocalTime currentTime = LocalTime.now(); // æ¯è¾æ¶é´ if (currentTime.isBefore(openingTime)) { // NO OP } else if (currentTime.isAfter(openingTime)) { queueService.startBiz(); } else { queueService.startBiz(); } } } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/queueService.java
@@ -14,6 +14,8 @@ */ public interface QueueService { void startBiz(); /** * å建æé * @@ -59,7 +61,7 @@ void queue(QueueSaveReqVO queueSaveReqVO); /** * * ç³»ç»é坿¶ï¼ä»DB忥工ä½çæ£è éåæ°æ®å° å·¥ä½ä¼å éå */ void initQueue(); jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/queueServiceImpl.java
@@ -35,6 +35,14 @@ final static Integer MAX_QUEUE_NUM = 3; @Resource private queueMapper queueMapper; @Resource private RoomMapper roomMapper; AtomicInteger openingFlag = new AtomicInteger(0); AtomicInteger curSeqNum = new AtomicInteger(0); PriorityBlockingQueue<BedQueueBO> priorityQueue = new PriorityBlockingQueue<>(); @@ -42,11 +50,6 @@ ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); @Resource private queueMapper queueMapper; @Resource private RoomMapper roomMapper; @Override public Integer createqueue(QueueSaveReqVO createReqVO) { @@ -91,7 +94,7 @@ } /** * ç³»ç»é坿¶ï¼ä»DB忥éåæ°æ®å° å·¥ä½ä¼å éå * ç³»ç»é坿¶ï¼ä»DB忥工ä½çæ£è éåæ°æ®å° å·¥ä½ä¼å éå */ public void initQueue() { priorityQueue.clear(); @@ -145,7 +148,7 @@ * çå°åä¸ä¸ä¸ª æéä¸äººå çé»è¾å®æåï¼å忥ä¸é */ public void hurryup() { while (true) { while (1 == openingFlag.get()) { BedQueueBO bedQueueBO = priorityQueue.peek(); if (null == bedQueueBO) return; @@ -190,6 +193,9 @@ queueSaveReqVO.setStatus(QueueStatusEnum.WAITING.getStatus()); //æéä¸ QueueDO queue = BeanUtils.toBean(queueSaveReqVO, QueueDO.class); queueMapper.insert(queue); if (0 == openingFlag.get()) return; singleThreadExecutor.execute( () -> { hurryup(); @@ -259,4 +265,9 @@ return patientStatisticVO; } public void startBiz() { openingFlag.set(1); hurryup(); } } jh-module-ecg/jh-module-ecg-biz/src/test/java/cn/lihu/jh/module/ecg/service/appointment/AppointmentServiceImplTest.java
@@ -1,202 +1,56 @@ //package cn.lihu.jh.module.ecg.service.appointment; // //import org.junit.jupiter.api.Disabled; //import org.junit.jupiter.api.Test; //import org.springframework.boot.test.mock.mockito.MockBean; // //import jakarta.annotation.Resource; // //import cn.lihu.jh.framework.test.core.ut.BaseDbUnitTest; // //import cn.lihu.jh.module.ecg.controller.admin.appointment.vo.*; //import cn.lihu.jh.module.ecg.dal.dataobject.appointment.AppointmentDO; //import cn.lihu.jh.module.ecg.dal.mysql.appointment.AppointmentMapper; //import cn.lihu.jh.framework.common.pojo.PageResult; // //import jakarta.annotation.Resource; //import org.springframework.context.annotation.Import; //import java.util.*; //import java.time.LocalDateTime; // //import static cn.hutool.core.util.RandomUtil.*; //import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.*; //import static cn.lihu.jh.framework.test.core.util.AssertUtils.*; //import static cn.lihu.jh.framework.test.core.util.RandomUtils.*; //import static cn.lihu.jh.framework.common.util.date.LocalDateTimeUtils.*; //import static cn.lihu.jh.framework.common.util.object.ObjectUtils.*; //import static cn.lihu.jh.framework.common.util.date.DateUtils.*; //import static org.junit.jupiter.api.Assertions.*; //import static org.mockito.Mockito.*; // ///** // * {@link AppointmentServiceImpl} çåå æµè¯ç±» // * // * @author 马忳¢ // */ //@Import(AppointmentServiceImpl.class) //public class AppointmentServiceImplTest extends BaseDbUnitTest { // // @Resource // private AppointmentServiceImpl appointmentService; // // @Resource // private AppointmentMapper appointmentMapper; // // @Test // public void testCreateAppointment_success() { // // åå¤åæ° // AppointmentSaveReqVO createReqVO = randomPojo(AppointmentSaveReqVO.class).setId(null); // // // è°ç¨ // Integer appointmentId = appointmentService.createAppointment(createReqVO); // // æè¨ // assertNotNull(appointmentId); // // æ ¡éªè®°å½ç屿§æ¯å¦æ£ç¡® // AppointmentDO appointment = appointmentMapper.selectById(appointmentId); // assertPojoEquals(createReqVO, appointment, "id"); // } // // @Test // public void testUpdateAppointment_success() { // // mock æ°æ® // AppointmentDO dbAppointment = randomPojo(AppointmentDO.class); // appointmentMapper.insert(dbAppointment);// @Sql: å æå ¥åºä¸æ¡åå¨çæ°æ® // // åå¤åæ° // AppointmentSaveReqVO updateReqVO = randomPojo(AppointmentSaveReqVO.class, o -> { // o.setId(dbAppointment.getId()); // è®¾ç½®æ´æ°ç ID // }); // // // è°ç¨ // appointmentService.updateAppointment(updateReqVO); // // æ ¡éªæ¯å¦æ´æ°æ£ç¡® // AppointmentDO appointment = appointmentMapper.selectById(updateReqVO.getId()); // è·åææ°ç // assertPojoEquals(updateReqVO, appointment); // } // // @Test // public void testUpdateAppointment_notExists() { // // åå¤åæ° // AppointmentSaveReqVO updateReqVO = randomPojo(AppointmentSaveReqVO.class); // // // è°ç¨, å¹¶æè¨å¼å¸¸ // assertServiceException(() -> appointmentService.updateAppointment(updateReqVO), APPOINTMENT_NOT_EXISTS); // } // // @Test // public void testDeleteAppointment_success() { // // mock æ°æ® // AppointmentDO dbAppointment = randomPojo(AppointmentDO.class); // appointmentMapper.insert(dbAppointment);// @Sql: å æå ¥åºä¸æ¡åå¨çæ°æ® // // åå¤åæ° // Integer id = dbAppointment.getId(); // // // è°ç¨ // appointmentService.deleteAppointment(id); // // æ ¡éªæ°æ®ä¸åå¨äº // assertNull(appointmentMapper.selectById(id)); // } // // @Test // public void testDeleteAppointment_notExists() { // // åå¤åæ° // Integer id = randomIntegerId(); // // // è°ç¨, å¹¶æè¨å¼å¸¸ // assertServiceException(() -> appointmentService.deleteAppointment(id), APPOINTMENT_NOT_EXISTS); // } // // @Test // @Disabled // TODO è¯·ä¿®æ¹ null 为éè¦çå¼ï¼ç¶åå é¤ @Disabled 注解 // public void testGetAppointmentPage() { // // mock æ°æ® // AppointmentDO dbAppointment = randomPojo(AppointmentDO.class, o -> { // ç伿¥è¯¢å° // o.setPatId(null); // o.setPatName(null); // o.setPatGender(null); // o.setPatBirthday(null); // o.setPatMobile(null); // o.setPatPhone(null); // o.setPatIdentityId(null); // o.setPatAddr(null); // o.setPatDeptCode(null); // o.setPatDeptDesc(null); // o.setPatWardCode(null); // o.setPatWardDesc(null); // o.setPatBedNo(null); // o.setBookId(null); // o.setBookPeriodStart(null); // o.setBookPeriodEnd(null); // o.setBookTime(null); // o.setBookCheckType(null); // o.setBookSrc(null); // }); // appointmentMapper.insert(dbAppointment); // // æµè¯ patId ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatId(null))); // // æµè¯ patName ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatName(null))); // // æµè¯ patGender ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatGender(null))); // // æµè¯ patBirthday ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatBirthday(null))); // // æµè¯ patMobile ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatMobile(null))); // // æµè¯ patPhone ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatPhone(null))); // // æµè¯ patIdentityId ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatIdentityId(null))); // // æµè¯ patAddr ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatAddr(null))); // // æµè¯ patDeptCode ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatDeptCode(null))); // // æµè¯ patDeptDesc ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatDeptDesc(null))); // // æµè¯ patWardCode ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatWardCode(null))); // // æµè¯ patWardDesc ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatWardDesc(null))); // // æµè¯ patBedNo ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setPatBedNo(null))); // // æµè¯ bookId ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setBookId(null))); // // æµè¯ bookPeriodStart ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setBookPeriodStart(null))); // // æµè¯ bookPeriodEnd ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setBookPeriodEnd(null))); // // æµè¯ bookTime ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setBookTime(null))); // // æµè¯ bookCheckType ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setBookCheckType(null))); // // æµè¯ bookSrc ä¸å¹é // appointmentMapper.insert(cloneIgnoreId(dbAppointment, o -> o.setBookSrc(null))); // // åå¤åæ° // AppointmentPageReqVO reqVO = new AppointmentPageReqVO(); // reqVO.setPatId(null); // reqVO.setPatName(null); // reqVO.setPatGender(null); // reqVO.setPatBirthday(null); // reqVO.setPatMobile(null); // reqVO.setPatPhone(null); // reqVO.setPatIdentityId(null); // reqVO.setPatAddr(null); // reqVO.setPatDeptCode(null); // reqVO.setPatDeptDesc(null); // reqVO.setPatWardCode(null); // reqVO.setPatWardDesc(null); // reqVO.setPatBedNo(null); // reqVO.setBookId(null); // reqVO.setBookPeriodStart(null); // reqVO.setBookPeriodEnd(null); // reqVO.setBookTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); // reqVO.setBookCheckType(null); // reqVO.setBookSrc(null); // // // è°ç¨ // PageResult<AppointmentDO> pageResult = appointmentService.getAppointmentPage(reqVO); // // æè¨ // assertEquals(1, pageResult.getTotal()); // assertEquals(1, pageResult.getList().size()); // assertPojoEquals(dbAppointment, pageResult.getList().get(0)); // } // //} package cn.lihu.jh.module.ecg.service.appointment; import cn.lihu.jh.module.ecg.controller.admin.appointment.vo.*; import cn.lihu.jh.module.ecg.dal.dataobject.appointment.AppointmentDO; import cn.lihu.jh.module.ecg.dal.mysql.appointment.AppointmentMapper; import cn.lihu.jh.framework.common.pojo.PageResult; import org.junit.Test; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; import javax.annotation.Resource; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * {@link AppointmentServiceImpl} çåå æµè¯ç±» * * @author 马忳¢ */ @SpringBootTest public class AppointmentServiceImplTest { @Resource private AppointmentServiceImpl appointmentService; @Resource private AppointmentMapper appointmentMapper; @Test public void test() { String regex = "(\\d+)[:ï¼](\\d+)"; String input = "08ï¼00"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); if (matcher.find()) { // è·åæ´ä¸ªå¹é çå符串 String fullMatch = matcher.group(); System.out.println("Full match: " + fullMatch); // è·å第ä¸ä¸ªæè·ç»ï¼ç¨æ·åï¼ String username = matcher.group(1); System.out.println("Username: " + username); System.out.println("Username: " + Integer.valueOf(username)); // è·å第äºä¸ªæè·ç»ï¼ååï¼ String domain = matcher.group(2); System.out.println("Domain: " + domain); System.out.println("Domain: " + Integer.valueOf(domain)); } } }