From 1c742353b8e308b4efaef12636212d7a655a16a3 Mon Sep 17 00:00:00 2001 From: jillion <439912596@qq.com> Date: Mon, 21 Sep 2026 18:18:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BA=8B=E4=BB=B6=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=91=98=E8=A6=81=E6=8B=BC=E6=8E=A5=E4=B8=8E=E5=8F=AF=E7=9B=AF?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .../inquiry/domain/EventExceptionRule.java | 109 ++++++++++++++++++ .../domain/EventExceptionRuleTest.java | 53 +++++++++ 2 files changed, 162 insertions(+) create mode 100644 inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/domain/EventExceptionRule.java create mode 100644 inquiry-api/jeecg-module-inquiry/src/test/java/org/jeecg/modules/inquiry/domain/EventExceptionRuleTest.java diff --git a/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/domain/EventExceptionRule.java b/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/domain/EventExceptionRule.java new file mode 100644 index 0000000..c47d932 --- /dev/null +++ b/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/domain/EventExceptionRule.java @@ -0,0 +1,109 @@ +package org.jeecg.modules.inquiry.domain; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * 事件异常纯规则:摘要拼接、哪些六态还盯超时、换等待种类才重置计时。 + *

+ * 不写库、不发企微。工单六态不因事件异常改变。 + */ +public final class EventExceptionRule { + + private EventExceptionRule() { + } + + /** + * 多次异常拼在一起;同一类型不重复。 + */ + public static String appendSummary(String existing, String type) { + String add = StringUtils.trimToEmpty(type); + if (add.isEmpty()) { + return StringUtils.trimToEmpty(existing); + } + String cur = StringUtils.trimToEmpty(existing); + if (cur.isEmpty() || "-".equals(cur)) { + return add; + } + Set parts = new LinkedHashSet(Arrays.asList(cur.split(";"))); + if (parts.contains(add)) { + return cur; + } + parts.add(add); + StringBuilder out = new StringBuilder(); + for (String p : parts) { + String one = StringUtils.trimToEmpty(p); + if (one.isEmpty()) { + continue; + } + if (out.length() > 0) { + out.append(';'); + } + out.append(one); + } + return out.toString(); + } + + /** + * 已成交 / 已关闭 / 转人工不再盯;未成交仍可能在等原因。 + */ + public static boolean isWatchable(String status) { + if (StringUtils.isBlank(status)) { + return false; + } + if (TicketStatuses.DEAL.equals(status) + || TicketStatuses.CLOSED.equals(status) + || TicketStatuses.HANDOFF.equals(status)) { + return false; + } + return TicketStatuses.isKnown(status); + } + + /** + * 等待种类变了才重置起点;同一种类重复 start 不改已过时间。 + */ + public static boolean shouldResetClock(String currentKind, String newKind) { + String cur = StringUtils.trimToEmpty(currentKind); + String next = StringUtils.trimToEmpty(newKind); + if (next.isEmpty()) { + return false; + } + return !cur.equals(next); + } + + /** + * 开始等待后的三列新值。 + */ + public static EventWaitState applyStart(String currentKind, Date started, Integer alerted, + String newKind, Date now) { + String next = StringUtils.trimToEmpty(newKind); + if (next.isEmpty()) { + return new EventWaitState(currentKind, started, alerted); + } + if (!shouldResetClock(currentKind, next)) { + Date keep = started != null ? started : now; + int flag = alerted == null ? 0 : alerted.intValue(); + return new EventWaitState(next, keep, flag); + } + return new EventWaitState(next, now, 0); + } + + /** + * 当前等待三列。 + */ + public static final class EventWaitState { + public final String kind; + public final Date startedAt; + public final int alerted; + + public EventWaitState(String kind, Date startedAt, int alerted) { + this.kind = kind; + this.startedAt = startedAt; + this.alerted = alerted; + } + } +} diff --git a/inquiry-api/jeecg-module-inquiry/src/test/java/org/jeecg/modules/inquiry/domain/EventExceptionRuleTest.java b/inquiry-api/jeecg-module-inquiry/src/test/java/org/jeecg/modules/inquiry/domain/EventExceptionRuleTest.java new file mode 100644 index 0000000..bacc542 --- /dev/null +++ b/inquiry-api/jeecg-module-inquiry/src/test/java/org/jeecg/modules/inquiry/domain/EventExceptionRuleTest.java @@ -0,0 +1,53 @@ +package org.jeecg.modules.inquiry.domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * 事件异常纯规则:摘要拼接、可盯状态、换等待种类才重置计时。 + */ +public class EventExceptionRuleTest { + + @Test + public void appendKeepsBothTypes() { + assertEquals("航线响应超时", EventExceptionRule.appendSummary("", "航线响应超时")); + assertEquals("航线响应超时;销售响应超时", + EventExceptionRule.appendSummary("航线响应超时", "销售响应超时")); + assertEquals("航线响应超时", EventExceptionRule.appendSummary("航线响应超时", "航线响应超时")); + } + + @Test + public void lostIsWatchableHandoffIsNot() { + assertTrue(EventExceptionRule.isWatchable("未成交")); + assertTrue(EventExceptionRule.isWatchable(TicketStatuses.INQUIRING)); + assertFalse(EventExceptionRule.isWatchable("已成交")); + assertFalse(EventExceptionRule.isWatchable("已关闭")); + assertFalse(EventExceptionRule.isWatchable("转人工")); + } + + @Test + public void sameKindDoesNotResetClock() { + assertFalse(EventExceptionRule.shouldResetClock("air_quote", "air_quote")); + assertTrue(EventExceptionRule.shouldResetClock("air_quote", "adopt")); + assertTrue(EventExceptionRule.shouldResetClock("", "product_quote")); + } + + @Test + public void applyStartKeepsClockOnSameKind() { + java.util.Date first = new java.util.Date(1_000L); + java.util.Date now = new java.util.Date(2_000L); + EventExceptionRule.EventWaitState keep = EventExceptionRule.applyStart( + "air_quote", first, 1, "air_quote", now); + assertEquals("air_quote", keep.kind); + assertEquals(first, keep.startedAt); + assertEquals(1, keep.alerted); + EventExceptionRule.EventWaitState reset = EventExceptionRule.applyStart( + "air_quote", first, 1, "adopt", now); + assertEquals("adopt", reset.kind); + assertEquals(now, reset.startedAt); + assertEquals(0, reset.alerted); + } +}