Fisheye: Tag 41533 refers to a dead (removed) revision in file `ssts-sterile/src/test/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilizationRecordManagerImplIsHavedoneNeedNoticeSterilisationTest.java'. Fisheye: No comparison available. Pass `N' to diff? Index: ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/model/SterilisationNotice.java =================================================================== diff -u -r41338 -r41533 --- ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/model/SterilisationNotice.java (.../SterilisationNotice.java) (revision 41338) +++ ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/model/SterilisationNotice.java (.../SterilisationNotice.java) (revision 41533) @@ -72,6 +72,17 @@ this.confirmMessage = confirmMessage; } + /** + * 设置触发提醒 + * @param remind 提醒规则 + */ + public void triggerNotice(SterilizationFrequecyRemind remind) { + setSuccess(false); + setRemindMode(remind.getRemindMode()); + setSterilisation(remind.getSterilisation().getSterilisation()); + setFrequency(remind.getFrequency()); + } + @Override public boolean equals(Object object) { if (this == object) return true; Index: ssts-sterile/src/test/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilizationRecordManagerImplIsHavedoneNeedNoticeSterilisationTest.java =================================================================== diff -u -r41361 -r41533 --- ssts-sterile/src/test/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilizationRecordManagerImplIsHavedoneNeedNoticeSterilisationTest.java (.../SterilizationRecordManagerImplIsHavedoneNeedNoticeSterilisationTest.java) (revision 41361) +++ ssts-sterile/src/test/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilizationRecordManagerImplIsHavedoneNeedNoticeSterilisationTest.java (.../SterilisationNoticeCheckerImplIsHavedoneNeedNoticeSterilisationTest.java) (revision 41533) @@ -31,7 +31,7 @@ /** * 单元测试:isHavedoneNeedNoticeSterilisation 方法 */ -public class SterilizationRecordManagerImplIsHavedoneNeedNoticeSterilisationTest { +public class SterilisationNoticeCheckerImplIsHavedoneNeedNoticeSterilisationTest { @InjectMocks private SterilisationNoticeCheckerImpl sterilisationNoticeChecker; @@ -227,15 +227,6 @@ } } - private static void validateFalse(JSONObject result, String remindMode, String sterilisation, int frequency, String msgKey) { - assertFalse(result.getBoolean("success")); - assertEquals(remindMode, result.getString("remindMode")); - assertEquals(sterilisation, result.getString("sterilisation")); - assertEquals(frequency, result.getInt("frequency")); - assertTrue(result.containsKey("confirmMessage")); - assertTrue(result.getString("confirmMessage").contains(msgKey)); - } - /** * 测试:提醒规则中炉次为空。跳过这种错误的配置 */ @@ -306,6 +297,48 @@ assertFalse(result.containsKey("confirmMessage")); } + /** + * 测试:多条强制提醒的规则都能匹配。应该只能检查优先级最高的那一个。无论优先级最高的那个有没有触发提醒,其他规则都忽略。 + * 因为这种情况可能产生死循环. + * 每天 第1炉 DB 强制提醒
+ * 周三 第1炉 P1 强制提醒
+ * 长假前第一天 第1炉 P2 强制提醒
+ * + * 针对上面情况,如果长假后第一天也是周三,那只提醒第1炉应该是P2.调三的规则忽略。 + */ + @Test + public void testMultiMandatoryRemindMatch_TriggerOnlyOne() { + Sterilizer sterilizer = new Sterilizer(); + List reminds = new ArrayList<>(); + reminds.add(buildReminder(SterilizationFrequecyRemind.REMINDMODE_MANDATORY, DATE_TYPE_EVERYDAY, 1, "DB")); + reminds.add(buildReminder(SterilizationFrequecyRemind.REMINDMODE_MANDATORY, DATE_TYPE_WEEK_START+3, 1, "P1")); + reminds.add(buildReminder(SterilizationFrequecyRemind.REMINDMODE_MANDATORY, DATE_TYPE_LONG_HOLIDAY_BEFORE, 1, "P2")); + + sterilizer.setSterilizationFrequecyReminds(reminds); + when(objectDao.getByProperty(eq("Sterilizer"), eq("name"), anyString())).thenReturn(sterilizer); + when(holidayConfigManager.holidayTypeOfToday()).thenReturn(HolidayType.LongBefore); + try(MockedStatic forgonDateUtils = mockStatic(ForgonDateUtils.class)){ + forgonDateUtils.when(ForgonDateUtils::getDayWeekOfToday).thenReturn(Calendar.WEDNESDAY); + SterilisationNotice notice = sterilisationNoticeChecker.isHavedoneNeedNoticeSterilisation("Sterilizer", "wrongType", "1"); + assertFalse(notice.getSuccess()); + validateFalse(trans2JSONObject(notice), REMINDMODE_MANDATORY, "P2", 1, "必须"); + + // 调整为长假前的程序P2,则不再检查周3的P1和每天的DB + notice = sterilisationNoticeChecker.isHavedoneNeedNoticeSterilisation("Sterilizer", "P2", "1"); + assertTrue(notice.getSuccess()); + + // 如果改为非强制提醒,并且调整为P2,那么还会提醒P1 + reminds.get(0).setRemindMode(SterilizationFrequecyRemind.REMINDMODE_NONMANDATORY); + reminds.get(1).setRemindMode(SterilizationFrequecyRemind.REMINDMODE_NONMANDATORY); + reminds.get(2).setRemindMode(SterilizationFrequecyRemind.REMINDMODE_NONMANDATORY); + notice = sterilisationNoticeChecker.isHavedoneNeedNoticeSterilisation("Sterilizer", "P2", "1"); + validateFalse(trans2JSONObject(notice), REMINDMODE_NONMANDATORY, "P1", 1, "应该"); + // 满足了P2,会提示P1,满足P1,又会提示P2,所以循环了,但是因为是非强制提醒,依然还是可以提交灭菌记录的。 + notice = sterilisationNoticeChecker.isHavedoneNeedNoticeSterilisation("Sterilizer", "P1", "1"); + validateFalse(trans2JSONObject(notice), REMINDMODE_NONMANDATORY, "P2", 1, "应该"); + } + } + private SterilizationFrequecyRemind buildReminder(String remindMode, int dateType, int frequency, String sterilisation) { Sterilisation ss = new Sterilisation(); ss.setSterilisation(sterilisation); @@ -316,4 +349,13 @@ remind.setDateType(dateType); return remind; } + + private static void validateFalse(JSONObject result, String remindMode, String sterilisation, int frequency, String msgKey) { + assertFalse(result.getBoolean("success")); + assertEquals(remindMode, result.getString("remindMode")); + assertEquals(sterilisation, result.getString("sterilisation")); + assertEquals(frequency, result.getInt("frequency")); + assertTrue(result.containsKey("confirmMessage")); + assertTrue(result.getString("confirmMessage").contains(msgKey)); + } } Index: ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilisationNoticeCheckerImpl.java =================================================================== diff -u -r41361 -r41533 --- ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilisationNoticeCheckerImpl.java (.../SterilisationNoticeCheckerImpl.java) (revision 41361) +++ ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilisationNoticeCheckerImpl.java (.../SterilisationNoticeCheckerImpl.java) (revision 41533) @@ -40,48 +40,88 @@ // 优先处理强制提醒 List mandatoryList = list.stream().filter(SterilizationFrequecyRemind::mandatoryMode).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(mandatoryList)) { - notice = checkInSameMode(holidayType, sterilizerName, sterilizationType, frequency, mandatoryList, notice); + boolean ret = checkInSameMode(holidayType, sterilizerName, sterilizationType, frequency, mandatoryList, notice, true); if(!notice.success()){ return notice; } + if(ret){ + // 强制提醒已经有满足条件的规则了,只是没有触发提醒。这种情况下要结束检查,避免进入死循环一直触发强制提醒 + return notice; + } } List nonMandatoryList = list.stream().filter(remind->!remind.mandatoryMode()).collect(Collectors.toList()); - notice = checkInSameMode(holidayType, sterilizerName, sterilizationType, frequency, nonMandatoryList, notice); + checkInSameMode(holidayType, sterilizerName, sterilizationType, frequency, nonMandatoryList, notice, false); if(!notice.success()){ return notice; } } return notice; } - private SterilisationNotice checkInSameMode(HolidayType todayHolidayType, String sterilizerName, String sterilizationType, - String frequency, List reminds, SterilisationNotice notice){ + /** + * 在相同提醒模式(提醒方式)下检查提醒规则。比如都是强制提醒的规则或者都是非强制提醒的规则 + * @param todayHolidayType 当天假期类型 + * @param sterilizerName 灭菌炉名称 + * @param sterilizationType 灭菌程序 + * @param frequency 当前炉次 + * @param reminds 提醒规则列表,列表中所有规则都是强制提醒或者都是非强制提醒 + * @param notice 提醒结果 + * @return 如果规则列表中有一个规则匹配成功,则返回true,所有规则都没有匹配成功,则返回false。不管有没有触发提醒。 + */ + private boolean checkInSameMode(HolidayType todayHolidayType, String sterilizerName, String sterilizationType, + String frequency, List reminds, SterilisationNotice notice, boolean maddatory){ List holidayList = reminds.stream().filter(remind->remind.dateTypeLongHoliday() || remind.dateTypeShortHoliday()).collect(Collectors.toList()); + boolean ret = false; if(CollectionUtils.isNotEmpty(holidayList)){ - notice = checkInSamePriorityAndMode(todayHolidayType, sterilizerName, sterilizationType, frequency, holidayList, notice); + ret |= checkInSamePriorityAndMode(todayHolidayType, sterilizerName, sterilizationType, frequency, holidayList, notice, maddatory); if(!notice.success()){ - return notice; + return ret; } + if(maddatory && ret) { + return ret; + } } List weekList = reminds.stream().filter(SterilizationFrequecyRemind::dateTypeWeek).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(weekList)){ - notice = checkInSamePriorityAndMode(todayHolidayType, sterilizerName, sterilizationType, frequency, weekList, notice); + ret |= checkInSamePriorityAndMode(todayHolidayType, sterilizerName, sterilizationType, frequency, weekList, notice, maddatory); if(!notice.success()){ - return notice; + return ret; } + if(maddatory && ret) { + return ret; + } } List mandatoryEverydayList = reminds.stream().filter(remind -> !holidayList.contains(remind) && !weekList.contains(remind)).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(mandatoryEverydayList)){ - notice = checkInSamePriorityAndMode(todayHolidayType, sterilizerName, sterilizationType, frequency, mandatoryEverydayList, notice); + ret |= checkInSamePriorityAndMode(todayHolidayType, sterilizerName, sterilizationType, frequency, mandatoryEverydayList, notice, maddatory); if(!notice.success()){ - return notice; + return ret; } + if(maddatory && ret) { + return ret; + } } - return notice; + return ret; } - private SterilisationNotice checkInSamePriorityAndMode(HolidayType todayHolidayType, String sterilizerName, String sterilizationType, String frequency, List sterilizationFrequecyReminds, SterilisationNotice notice) { + /**、 + * 在相同优先级和模式下检查。比如都是强制提醒或者都是非强制提醒,然后日期的优先级一样 + * @param todayHolidayType 当天的假期类型 + * @param sterilizerName 灭菌炉名称 + * @param sterilizationType 灭菌程序 + * @param frequency 当前炉次 + * @param sterilizationFrequecyReminds 相同优先级和提醒模式的规则列表 + * @param notice 提醒结果 + * @param maddatory 是否强制提醒。如果是强制提醒,那有一个规则匹配,后续就不能再检查了,不然可能进入死循环,两个灭菌程序互相触发。 + * 比如一个规则要P1灭菌程序,另一个要P2灭菌程序,满足P1满足不了P2,满足P2满足不了P1。 + * @return 如果规则列表中有一个规则匹配成功,则返回true,所有规则都没有匹配成功,则返回false。不管有没有触发提醒。 + * 匹配成功的条件是日期类型匹配并且炉次匹配。触发条件是在匹配的基础上,灭菌程序不同则触发,相同就不触发 + */ + private boolean checkInSamePriorityAndMode( + HolidayType todayHolidayType, String sterilizerName, String sterilizationType, String frequency, + List sterilizationFrequecyReminds, SterilisationNotice notice, boolean maddatory) { int weekDay = ForgonDateUtils.getDayWeekOfToday(); + boolean ret = false; for (SterilizationFrequecyRemind remind : sterilizationFrequecyReminds) { // 配置中的炉次或者灭菌程序为空时,不验证 if(remind.getFrequency() == null || remind.getFrequency() < 1 @@ -102,18 +142,21 @@ } } // 都是假期匹配或者星期匹配或者是每天的,只要炉次匹配就行了 - if(StringUtils.equals(frequency, remind.getFrequency().toString()) - && !StringUtils.equals(sterilizationType, remind.getSterilisation().getSterilisation())){ - notice = new SterilisationNotice(false, remind.getRemindMode(), - remind.getSterilisation().getSterilisation(), remind.getFrequency()); - if(StringUtils.equals(remind.getRemindMode(), SterilizationFrequecyRemind.REMINDMODE_MANDATORY)){ - notice.setConfirmMessage(sterilizerName + "第" + frequency + "炉的灭菌程序必须是" + remind.getSterilisation().getSterilisation() + "!"); - }else{ - notice.setConfirmMessage(sterilizerName + "第" + frequency + "炉的灭菌程序应该是" + remind.getSterilisation().getSterilisation() + ",不修改灭菌程序继续操作吗?"); + if(StringUtils.equals(frequency, remind.getFrequency().toString())){ + if(!StringUtils.equals(sterilizationType, remind.getSterilisation().getSterilisation())){ + notice.triggerNotice(remind); + if(StringUtils.equals(remind.getRemindMode(), SterilizationFrequecyRemind.REMINDMODE_MANDATORY)){ + notice.setConfirmMessage(sterilizerName + "第" + frequency + "炉的灭菌程序必须是" + remind.getSterilisation().getSterilisation() + "!"); + }else{ + notice.setConfirmMessage(sterilizerName + "第" + frequency + "炉的灭菌程序应该是" + remind.getSterilisation().getSterilisation() + ",不修改灭菌程序继续操作吗?"); + } } - break; + ret = true; + if(maddatory){ // 强制提醒,已经有匹配的规则了,就不再检查了 + return ret; + } } } - return notice; + return ret; } } Index: ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilisationNoticeChecker.java =================================================================== diff -u -r41361 -r41533 --- ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilisationNoticeChecker.java (.../SterilisationNoticeChecker.java) (revision 41361) +++ ssts-sterile/src/main/java/com/forgon/disinfectsystem/sterilizationmanager/sterilizationrecord/service/SterilisationNoticeChecker.java (.../SterilisationNoticeChecker.java) (revision 41533) @@ -5,10 +5,13 @@ public interface SterilisationNoticeChecker { /** * 验证灭菌炉某一炉次对应的灭菌程序是否正确(灭菌炉的“按炉次提醒的灭菌程序设置”中设置炉次对应的灭菌程序) + * 优先级:强制提醒 > 非强制提醒。都是强制提醒或者都是非强制提醒时,假期 > 星期 > 每天. + * 优先级的规则是,对于强制提醒,如果高优先级的规则匹配,则验证并且得到结果就返回,不再验证低优先级的规则,哪怕高优先级的规则 没有触发。 + * 对于非强制提醒,如果高优先级的规则匹配,则验证,在没有触发的情况下,再验证低优先级的规则,直到有一个触发或者都不触发。 * @param sterilizerName 灭菌炉名称 * @param sterilizationType 灭菌程序 * @param frequency 炉次 - * @return {success:true} or {success:false,message:**} + * @return 提醒信息,success为true时,表示不提醒,为false时,表示有提醒信息,并且包含提醒的模式,在强制提醒的情况下,前端不能提交灭菌记录,非强制提醒可以提交灭菌记录。 */ SterilisationNotice isHavedoneNeedNoticeSterilisation(String sterilizerName, String sterilizationType, String frequency); }