From f76eb0e587150f9dc767d8c175192306431470ec Mon Sep 17 00:00:00 2001 From: WendyYang Date: Fri, 30 Aug 2024 11:34:16 +0800 Subject: [PATCH] =?UTF-8?q?modify:=201.=20=E7=8A=B6=E6=80=81=E6=9C=BA?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8F=98=E6=9B=B4=E5=A4=B1=E8=B4=A5=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hz-pm-api/pom.xml | 12 +++++ .../impl/ProjectStateMachineBuilderImpl.java | 12 +++-- .../impl/TenderStateMachineBuilderImpl.java | 12 +++-- .../builder/impl/XcfhxStateMachineBuilderImpl.java | 1 - .../statemachine/factory/ProjectGuardFactory.java | 59 +++++++++++++++----- .../statemachine/factory/TenderGuardFactory.java | 22 +++++++- .../util/AbstractStateMachineUtil.java | 28 +++++++--- .../statemachine/util/AdaptStateMachineUtil.java | 19 +++---- .../statemachine/util/ProjectStateMachineUtil.java | 39 +++++++------- .../util/SelfTestStateMachineUtil.java | 15 +++--- .../statemachine/util/TenderStateMachineUtil.java | 20 ++++--- .../util/TestValidStateMachineUtil.java | 4 +- .../statemachine/util/XcfhxStateMachineUtil.java | 17 +++--- .../com/hz/pm/api/common/util/ThreadPoolUtil.java | 1 - .../meeting/task/ExpertInviteExecutorConfig.java | 15 +++--- .../api/meeting/task/MsgCallReplyRewriteTask.java | 4 +- .../api/meeting/task/RandomInviteProperties.java | 6 +++ hz-pm-api/src/main/resources/application-dev.yml | 6 ++- hz-pm-api/src/main/resources/application-prod.yml | 4 ++ .../com/hz/pm/api/common/StateMachineTest.java | 46 ++++++++++++++++ hz-pm-api/src/test/resources/application-dev.yml | 62 +++++++++++++++------- pom.xml | 2 +- 22 files changed, 294 insertions(+), 112 deletions(-) create mode 100644 hz-pm-api/src/test/java/com/hz/pm/api/common/StateMachineTest.java diff --git a/hz-pm-api/pom.xml b/hz-pm-api/pom.xml index ee0c566..6825829 100644 --- a/hz-pm-api/pom.xml +++ b/hz-pm-api/pom.xml @@ -12,6 +12,18 @@ + org.openjdk.jmh + jmh-core + 1.37 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.37 + test + + com.google.guava guava 33.0.0-jre diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/ProjectStateMachineBuilderImpl.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/ProjectStateMachineBuilderImpl.java index 9b002ab..72386fe 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/ProjectStateMachineBuilderImpl.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/ProjectStateMachineBuilderImpl.java @@ -3,7 +3,7 @@ package com.hz.pm.api.common.statemachine.builder.impl; import com.hz.pm.api.common.statemachine.builder.BaseStateMachineBuilder; import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent; import com.hz.pm.api.common.statemachine.factory.ProjectGuardFactory; -import com.hz.pm.api.common.statemachine.factory.ProjectGuardFactory.ProjectPurchaseToFirstAcceptGuard; +import com.hz.pm.api.common.statemachine.factory.ProjectGuardFactory.ProjectPurchaseToAcceptGuard; import com.hz.pm.api.projectlib.model.entity.Project; import com.hz.pm.api.projectlib.model.enumeration.status.ProjectStatus; import lombok.RequiredArgsConstructor; @@ -32,13 +32,15 @@ import java.util.EnumSet; */ @Slf4j @Component -@EnableStateMachine(name = ProjectStateMachineBuilderImpl.MACHINE_ID) @RequiredArgsConstructor +@EnableStateMachine(name = ProjectStateMachineBuilderImpl.MACHINE_ID) public class ProjectStateMachineBuilderImpl implements BaseStateMachineBuilder { public static final String MACHINE_ID = "projectDeclareStateMachine"; private final BeanFactory beanFactory; + private final ProjectPurchaseToAcceptGuard projectPurchaseToAcceptGuard; + private final ProjectGuardFactory.ProjectPurchaseToAdaptGuard projectPurchaseToAdaptGuard; @Override public StateMachine build() throws StateMachineException { @@ -149,13 +151,15 @@ public class ProjectStateMachineBuilderImpl implements BaseStateMachineBuilder

待初验 .withExternal() .source(ProjectStatus.ON_PURCHASING) .target(ProjectStatus.TO_BE_FIRST_INSPECTED) .event(ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD) - .guard(new ProjectPurchaseToFirstAcceptGuard()) + .guard(projectPurchaseToAcceptGuard) .and() // 填写试试计划 -> 待初验 .withExternal() diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/TenderStateMachineBuilderImpl.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/TenderStateMachineBuilderImpl.java index e16659a..c1593a1 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/TenderStateMachineBuilderImpl.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/builder/impl/TenderStateMachineBuilderImpl.java @@ -3,7 +3,7 @@ package com.hz.pm.api.common.statemachine.builder.impl; import cn.hutool.core.collection.ListUtil; import com.hz.pm.api.common.statemachine.builder.BaseStateMachineBuilder; import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent; -import com.hz.pm.api.common.statemachine.factory.TenderGuardFactory; +import com.hz.pm.api.common.statemachine.factory.TenderGuardFactory.PurchaseContractRecordToAcceptGuard; import com.hz.pm.api.projectdeclared.model.entity.Purchase; import com.hz.pm.api.projectlib.model.enumeration.status.ITenderStatus; import com.hz.pm.api.projectlib.model.enumeration.status.TenderAdaptStatus; @@ -26,6 +26,8 @@ import org.springframework.stereotype.Component; import java.util.HashSet; import java.util.List; +import static com.hz.pm.api.common.statemachine.factory.TenderGuardFactory.PurchaseContractRecordToOperationGuard; + /** *

* 标段状态机 @@ -36,13 +38,16 @@ import java.util.List; */ @Slf4j @Component -@EnableStateMachine(name = TenderStateMachineBuilderImpl.MACHINE_ID) @RequiredArgsConstructor +@EnableStateMachine(name = TenderStateMachineBuilderImpl.MACHINE_ID) public class TenderStateMachineBuilderImpl implements BaseStateMachineBuilder { public static final String MACHINE_ID = "tenderStateMachine"; private final BeanFactory beanFactory; + private final PurchaseContractRecordToAcceptGuard purchaseContractRecordToAcceptGuard; + private final PurchaseContractRecordToOperationGuard purchaseContractRecordToOperationGuard; + @Override public StateMachine build() throws StateMachineException { @@ -81,12 +86,13 @@ public class TenderStateMachineBuilderImpl implements BaseStateMachineBuilder { + + private IPurchaseService purchaseService; + + @Override + public boolean evaluate(StateContext ctx) { + return !canTurnToAdapt(ctx, purchaseService); + } + } - public static class ProjectPurchaseToFirstAcceptGuard implements Guard { + @AllArgsConstructor + public static class ProjectPurchaseToAdaptGuard implements Guard { - private final IPurchaseService purchaseService = SpringUtils.getBean(IPurchaseService.class); + private IPurchaseService purchaseService; @Override - public boolean evaluate(StateContext stateContext) { - Project project = ProjectStateChangeAction.getProject(stateContext.getMessage()); - Wrapper query = Wrappers.lambdaQuery(Purchase.class) - .select(Purchase::getId, Purchase::getBidType) - .eq(Purchase::getProjectId, project.getId()); - List purchases = purchaseService.list(query); - return CollUtil.allMatch(purchases, w -> !BidTypeEnum.BUILD_APP.eq(w.getBidType())); + public boolean evaluate(StateContext ctx) { + return canTurnToAdapt(ctx, purchaseService); } } + private static boolean canTurnToAdapt(StateContext ctx, + IPurchaseService purchaseService) { + Project project = ProjectStateChangeAction.getProject(ctx.getMessage()); + Wrapper query = Wrappers.lambdaQuery(Purchase.class) + .select(Purchase::getId, Purchase::getBidType) + .eq(Purchase::getProjectId, project.getId()); + List purchases = purchaseService.list(query); + return CollUtil.anyMatch(purchases, w -> BidTypeEnum.BUILD_APP.eq(w.getBidType())); + } + + + @Bean + public ProjectPurchaseToAcceptGuard projectPurchaseToAcceptGuard() { + return new ProjectPurchaseToAcceptGuard(purchaseService); + } + + @Bean + public ProjectPurchaseToAdaptGuard projectPurchaseToAdaptGuard() { + return new ProjectPurchaseToAdaptGuard(purchaseService); + } + } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/factory/TenderGuardFactory.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/factory/TenderGuardFactory.java index 95e7a7c..83297d3 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/factory/TenderGuardFactory.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/factory/TenderGuardFactory.java @@ -5,6 +5,8 @@ import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent; import com.hz.pm.api.projectdeclared.model.entity.Purchase; import com.hz.pm.api.projectdeclared.model.enumerization.BidTypeEnum; import com.hz.pm.api.projectlib.model.enumeration.status.ITenderStatus; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.statemachine.StateContext; import org.springframework.statemachine.guard.Guard; @@ -16,12 +18,28 @@ import org.springframework.statemachine.guard.Guard; * @author WendyYang * @since 17:51 2024/8/20 */ +@Configuration public class TenderGuardFactory { - private TenderGuardFactory() { + @Bean + public PurchaseContractRecordToOperationGuard purchaseContractRecordToOperationGuard() { + return new PurchaseContractRecordToOperationGuard(); } - public static class PurchaseContractRecordGuard implements Guard { + @Bean + public PurchaseContractRecordToAcceptGuard purchaseContractRecordToAcceptGuard() { + return new PurchaseContractRecordToAcceptGuard(); + } + + public static class PurchaseContractRecordToOperationGuard implements Guard { + @Override + public boolean evaluate(StateContext context) { + Purchase purchase = TenderStateChangeActionUtil.getPurchaseInfo(context.getMessage()); + return BidTypeEnum.BUILD_APP.eq(purchase.getBidType()); + } + } + + public static class PurchaseContractRecordToAcceptGuard implements Guard { @Override public boolean evaluate(StateContext context) { Purchase purchase = TenderStateChangeActionUtil.getPurchaseInfo(context.getMessage()); diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AbstractStateMachineUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AbstractStateMachineUtil.java index f64afc1..1a8ddad 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AbstractStateMachineUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AbstractStateMachineUtil.java @@ -1,9 +1,10 @@ package com.hz.pm.api.common.statemachine.util; +import cn.hutool.log.Log; +import cn.hutool.log.LogFactory; import com.hz.pm.api.common.statemachine.event.AbstractStateChangeEvent; import com.ningdatech.basic.exception.BizException; import com.wflow.exception.BusinessException; -import org.slf4j.LoggerFactory; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -19,6 +20,8 @@ import java.util.function.Function; */ public interface AbstractStateMachineUtil & AbstractStateChangeEvent> { + Log LOG = LogFactory.get(AbstractStateMachineUtil.class); + /** * 获取状态变更事件类型 * @@ -29,12 +32,19 @@ public interface AbstractStateMachineUtil & AbstractStateCh return (Class) ((ParameterizedType) type).getActualTypeArguments()[1]; } + default AbstractStateMachineUtil getLockClass() { + LOG.info("acquire state machine lock:{}", this.getClass().getSimpleName()); + return this; + } + //通过审核 default void pass(O obj) { try { - execute(obj, AbstractStateChangeEvent.getPassEvent(eventClass(), statusFunction().apply(obj))); + synchronized (getLockClass()) { + execute(obj, AbstractStateChangeEvent.getPassEvent(eventClass(), statusFunction().apply(obj))); + } } catch (Exception e) { - LoggerFactory.getLogger(this.getClass()).info("状态机 通过失败", e); + LOG.error("状态机通过失败", e); throw BizException.wrap("状态机通过失败"); } } @@ -43,9 +53,11 @@ public interface AbstractStateMachineUtil & AbstractStateCh //拒绝 default void reject(O obj) { try { - execute(obj, AbstractStateChangeEvent.getRejectEvent(eventClass(), statusFunction().apply(obj))); + synchronized (getLockClass()) { + execute(obj, AbstractStateChangeEvent.getRejectEvent(eventClass(), statusFunction().apply(obj))); + } } catch (Exception e) { - LoggerFactory.getLogger(this.getClass()).info("状态机 拒绝失败 :{}", e.getMessage()); + LOG.error("状态机拒绝失败", e); throw new BusinessException("状态机拒绝失败"); } } @@ -53,9 +65,11 @@ public interface AbstractStateMachineUtil & AbstractStateCh //撤回 default void withDraw(O obj) { try { - execute(obj, AbstractStateChangeEvent.getWithdrawEvent(eventClass(), statusFunction().apply(obj))); + synchronized (getLockClass()) { + execute(obj, AbstractStateChangeEvent.getWithdrawEvent(eventClass(), statusFunction().apply(obj))); + } } catch (Exception e) { - LoggerFactory.getLogger(this.getClass()).info("状态机 撤回失败 :{}", e.getMessage()); + LOG.error("状态机撤回失败", e); throw new BusinessException("状态机撤回失败"); } } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AdaptStateMachineUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AdaptStateMachineUtil.java index a74f381..83c881c 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AdaptStateMachineUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/AdaptStateMachineUtil.java @@ -5,10 +5,8 @@ import com.hz.pm.api.common.statemachine.event.AdaptStateChangeEvent; import com.hz.pm.api.projectdeclared.model.entity.Purchase; import com.hz.pm.api.projectdeclared.utils.ProjectIdCodeCacheUtil; import com.hz.pm.api.projectlib.entity.PurchaseStatusChange; -import com.hz.pm.api.projectlib.model.enumeration.status.ITenderStatus; import com.hz.pm.api.projectlib.model.enumeration.status.TenderAdaptStatus; import com.hz.pm.api.projectlib.service.IPurchaseStatusChangeService; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; @@ -29,16 +27,23 @@ import java.util.function.Function; */ @Slf4j @Component -@RequiredArgsConstructor public class AdaptStateMachineUtil implements AbstractStateMachineUtil { public static final String PURCHASE = "purchaseInfo"; //================================================================================================================== - private final AdaptStateMachineBuilderImpl adaptStateMachineBuilder; + private final StateMachinePersister stateMachinePersister; + private final StateMachine stateMachine; private final IPurchaseStatusChangeService purchaseStatusChangeService; + public AdaptStateMachineUtil(AdaptStateMachineBuilderImpl adaptStateMachineBuilder, + IPurchaseStatusChangeService purchaseStatusChangeService) { + this.purchaseStatusChangeService = purchaseStatusChangeService; + this.stateMachine = adaptStateMachineBuilder.build(); + this.stateMachinePersister = adaptStateMachineBuilder.stateMachinePersister(); + } + @Override public Function statusFunction() { return Purchase::getAdaptStatus; @@ -46,8 +51,6 @@ public class AdaptStateMachineUtil implements AbstractStateMachineUtil stateMachine = adaptStateMachineBuilder.build(); Message message = MessageBuilder.withPayload(event) .setHeader(PURCHASE, purchase) .build(); //初始化状态机 - StateMachinePersister stateMachinePersister = adaptStateMachineBuilder.stateMachinePersister(); stateMachinePersister.restore(stateMachine, purchase); stateMachine.sendEvent(message); change.setAfterStatus(purchase.getAdaptStatus()); purchaseStatusChangeService.save(change); - log.info("调用状态机后的标段状态为:{}", purchase.getAdaptStatus()); + log.info("调用状态机后的标段状态为:{} ==> {}", change.getBeforeStatus(), change.getAfterStatus()); } } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/ProjectStateMachineUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/ProjectStateMachineUtil.java index b7050d4..1f0d44b 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/ProjectStateMachineUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/ProjectStateMachineUtil.java @@ -27,7 +27,6 @@ import java.util.function.Function; */ @Slf4j @Component -@RequiredArgsConstructor public class ProjectStateMachineUtil implements AbstractStateMachineUtil { private static final String PROJECT_DECLARE = StateMachineConst.PROJECT_DECLARE; @@ -36,12 +35,20 @@ public class ProjectStateMachineUtil implements AbstractStateMachineUtil stateMachinePersister; + private final StateMachine stateMachine; private final IProjectStatusChangeService projectStatusChangeService; - private final IProjectApplicationService projectApplicationService; + public ProjectStateMachineUtil(ProjectStateMachineBuilderImpl projectStateMachineBuilder, + IProjectStatusChangeService projectStatusChangeService, + IProjectApplicationService projectApplicationService) { + this.projectStatusChangeService = projectStatusChangeService; + this.projectApplicationService = projectApplicationService; + this.stateMachinePersister = projectStateMachineBuilder.stateMachinePersister(); + this.stateMachine = projectStateMachineBuilder.build(); + } + @Override public Function statusFunction() { return Project::getStatus; @@ -49,29 +56,25 @@ public class ProjectStateMachineUtil implements AbstractStateMachineUtil stateMachine = projectStateMachineBuilder.build(); Message message = MessageBuilder.withPayload(event) .setHeader(PROJECT_DECLARE, project) .setHeader(APPLICATION_DECLARE, projectApplicationService.getApplicationsByProject(project)) .build(); //初始化状态机 - StateMachinePersister projectDeclareStateMachinePersister = projectStateMachineBuilder.stateMachinePersister(); - projectDeclareStateMachinePersister.restore(stateMachine, project); + stateMachinePersister.restore(stateMachine, project); stateMachine.sendEvent(message); - projectStatusChange.setProjectId(project.getId()); - projectStatusChange.setAfterStatus(project.getStatus()); - projectStatusChange.setEvent(event.name()); - projectStatusChange.setCreateOn(LocalDateTime.now()); - projectStatusChange.setProjectCode(project.getProjectCode()); + change.setProjectId(project.getId()); + change.setAfterStatus(project.getStatus()); + change.setEvent(event.name()); + change.setCreateOn(LocalDateTime.now()); + change.setProjectCode(project.getProjectCode()); // 插入项目状态变更表中 - projectStatusChangeService.save(projectStatusChange); - log.info("调用状态机后的项目状态为:{}", project.getStatus()); + projectStatusChangeService.save(change); + log.info("调用状态机后的标段状态为:{} ==> {}", change.getBeforeStatus(), change.getAfterStatus()); } } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/SelfTestStateMachineUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/SelfTestStateMachineUtil.java index 25f096d..513a8ba 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/SelfTestStateMachineUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/SelfTestStateMachineUtil.java @@ -28,15 +28,21 @@ import java.util.function.Function; */ @Slf4j @Component -@RequiredArgsConstructor public class SelfTestStateMachineUtil implements AbstractStateMachineUtil { public static final String PURCHASE = "purchaseInfo"; //================================================================================================================== - private final SelfTestStateMachineBuilderImpl selfTestStateMachineBuilder; private final IPurchaseStatusChangeService purchaseStatusChangeService; + private final StateMachinePersister stateMachinePersister; + private final StateMachine stateMachine; + + public SelfTestStateMachineUtil(SelfTestStateMachineBuilderImpl selfTestStateMachineBuilder, IPurchaseStatusChangeService purchaseStatusChangeService) { + this.purchaseStatusChangeService = purchaseStatusChangeService; + this.stateMachinePersister = selfTestStateMachineBuilder.stateMachinePersister(); + this.stateMachine = selfTestStateMachineBuilder.build(); + } @Override public Function statusFunction() { @@ -45,7 +51,6 @@ public class SelfTestStateMachineUtil implements AbstractStateMachineUtil stateMachine = selfTestStateMachineBuilder.build(); Message message = MessageBuilder.withPayload(event) .setHeader(PURCHASE, purchase) .build(); //初始化状态机 - StateMachinePersister stateMachinePersister = selfTestStateMachineBuilder.stateMachinePersister(); stateMachinePersister.restore(stateMachine, purchase); stateMachine.sendEvent(message); change.setAfterStatus(purchase.getSelfTestStatus()); purchaseStatusChangeService.save(change); - log.info("调用状态机后的标段状态为:{}", purchase.getSelfTestStatus()); + log.info("调用状态机后的标段状态为:{} ==> {}", change.getBeforeStatus(), change.getAfterStatus()); } } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TenderStateMachineUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TenderStateMachineUtil.java index c792a0e..983e34d 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TenderStateMachineUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TenderStateMachineUtil.java @@ -1,6 +1,5 @@ package com.hz.pm.api.common.statemachine.util; -import cn.hutool.core.util.ObjUtil; import com.hz.pm.api.common.statemachine.builder.impl.TenderStateMachineBuilderImpl; import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent; import com.hz.pm.api.projectdeclared.model.entity.Purchase; @@ -30,15 +29,21 @@ import java.util.function.Function; */ @Slf4j @Component -@RequiredArgsConstructor public class TenderStateMachineUtil implements AbstractStateMachineUtil { public static final String PURCHASE = "purchaseInfo"; //================================================================================================================== - private final TenderStateMachineBuilderImpl tenderStateMachineBuilder; private final IPurchaseStatusChangeService purchaseStatusChangeService; + private final StateMachinePersister stateMachinePersister; + private final StateMachine stateMachine; + + public TenderStateMachineUtil(IPurchaseStatusChangeService purchaseStatusChangeService, TenderStateMachineBuilderImpl tenderStateMachineBuilder) { + this.purchaseStatusChangeService = purchaseStatusChangeService; + this.stateMachinePersister = tenderStateMachineBuilder.stateMachinePersister(); + this.stateMachine = tenderStateMachineBuilder.build(); + } @Override public Function statusFunction() { @@ -47,7 +52,6 @@ public class TenderStateMachineUtil implements AbstractStateMachineUtil stateMachine = tenderStateMachineBuilder.build(); Message message = MessageBuilder.withPayload(event) .setHeader(PURCHASE, purchase) .build(); //初始化状态机 - StateMachinePersister stateMachinePersister = tenderStateMachineBuilder.stateMachinePersister(); stateMachinePersister.restore(stateMachine, purchase); stateMachine.sendEvent(message); change.setAfterStatus(purchase.getStatus()); purchaseStatusChangeService.save(change); - if (ObjUtil.equal(change.getBeforeStatus(), change.getBeforeStatus())) { - log.error("状态变更失败:{} {}", purchase, event); - throw BizException.wrap("状态变更失败"); - } - log.info("调用状态机后的标段状态为:{}", purchase.getStatus()); + log.info("调用状态机后的标段状态为:{} ==> {}", change.getBeforeStatus(), change.getAfterStatus()); } } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TestValidStateMachineUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TestValidStateMachineUtil.java index 58ff54c..5e069d8 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TestValidStateMachineUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/TestValidStateMachineUtil.java @@ -45,8 +45,6 @@ public class TestValidStateMachineUtil implements AbstractStateMachineUtil {}", change.getBeforeStatus(), change.getAfterStatus()); } } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/XcfhxStateMachineUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/XcfhxStateMachineUtil.java index f41cf4b..f4f1127 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/XcfhxStateMachineUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/statemachine/util/XcfhxStateMachineUtil.java @@ -28,15 +28,22 @@ import java.util.function.Function; */ @Slf4j @Component -@RequiredArgsConstructor public class XcfhxStateMachineUtil implements AbstractStateMachineUtil { public static final String PURCHASE = "purchaseInfo"; //================================================================================================================== - private final XcfhxStateMachineBuilderImpl xcfhxStateMachineBuilder; private final IPurchaseStatusChangeService purchaseStatusChangeService; + private final StateMachinePersister stateMachinePersister; + private final StateMachine stateMachine; + + public XcfhxStateMachineUtil(XcfhxStateMachineBuilderImpl xcfhxStateMachineBuilder, + IPurchaseStatusChangeService purchaseStatusChangeService) { + this.purchaseStatusChangeService = purchaseStatusChangeService; + this.stateMachine = xcfhxStateMachineBuilder.build(); + this.stateMachinePersister = xcfhxStateMachineBuilder.stateMachinePersister(); + } @Override public Function statusFunction() { @@ -45,8 +52,6 @@ public class XcfhxStateMachineUtil implements AbstractStateMachineUtil stateMachine = xcfhxStateMachineBuilder.build(); Message message = MessageBuilder.withPayload(event) .setHeader(PURCHASE, purchase) .build(); //初始化状态机 - StateMachinePersister stateMachinePersister = xcfhxStateMachineBuilder.stateMachinePersister(); stateMachinePersister.restore(stateMachine, purchase); stateMachine.sendEvent(message); change.setAfterStatus(purchase.getXcfhxApplyStatus()); purchaseStatusChangeService.save(change); - log.info("调用状态机后的标段状态为:{}", purchase.getXcfhxApplyStatus()); + log.info("调用状态机后的标段状态为:{} ==> {}", change.getBeforeStatus(), change.getAfterStatus()); } } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/util/ThreadPoolUtil.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/util/ThreadPoolUtil.java index cd8584a..a09fb84 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/util/ThreadPoolUtil.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/util/ThreadPoolUtil.java @@ -28,7 +28,6 @@ public class ThreadPoolUtil { static { ThreadPoolUtilProperties properties = SpringUtil.getBean(ThreadPoolUtilProperties.class); - log.info("ThreadPoolUtilProperties:{}", properties); ThreadPoolProperties requestProps = properties.getRequest(); REQUEST = new MDCThreadPoolTaskExecutor(); REQUEST.setCorePoolSize(requestProps.getCorePoolSize()); diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertInviteExecutorConfig.java b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertInviteExecutorConfig.java index f73bf5d..898f866 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertInviteExecutorConfig.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/ExpertInviteExecutorConfig.java @@ -1,5 +1,7 @@ package com.hz.pm.api.meeting.task; +import com.hz.pm.api.common.config.ThreadPoolUtilProperties.ThreadPoolProperties; +import com.hz.pm.api.common.util.MDCThreadPoolTaskScheduler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; @@ -16,13 +18,14 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; public class ExpertInviteExecutorConfig { @Bean(name = "expertInviteScheduler") - public ThreadPoolTaskScheduler threadPoolTaskScheduler() { - ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); - scheduler.setPoolSize(3); + public ThreadPoolTaskScheduler threadPoolTaskScheduler(RandomInviteProperties properties) { + ThreadPoolProperties threadPoolProperties = properties.getThreadPoolProperties(); + MDCThreadPoolTaskScheduler scheduler = new MDCThreadPoolTaskScheduler(); + scheduler.setPoolSize(threadPoolProperties.getCorePoolSize()); scheduler.setThreadGroupName("expert-invite"); - scheduler.setThreadNamePrefix("invite-executor-"); - scheduler.setAwaitTerminationSeconds(60); - scheduler.setWaitForTasksToCompleteOnShutdown(true); + scheduler.setThreadNamePrefix(threadPoolProperties.getThreadNamePrefix()); + scheduler.setAwaitTerminationSeconds(120); + scheduler.setWaitForTasksToCompleteOnShutdown(threadPoolProperties.getWaitForTasksToCompleteOnShutdown()); return scheduler; } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/MsgCallReplyRewriteTask.java b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/MsgCallReplyRewriteTask.java index b0b6970..0e82572 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/MsgCallReplyRewriteTask.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/MsgCallReplyRewriteTask.java @@ -48,13 +48,15 @@ public class MsgCallReplyRewriteTask { static { // 初始化线程池 EXECUTOR = new MDCThreadPoolTaskExecutor(); + EXECUTOR.setBeanName("msgCallReplyRewriteExecutor"); EXECUTOR.setCorePoolSize(2); EXECUTOR.setMaxPoolSize(4); EXECUTOR.setQueueCapacity(100); EXECUTOR.setKeepAliveSeconds(120); - EXECUTOR.setThreadPriority(Thread.NORM_PRIORITY); + EXECUTOR.setThreadPriority(Thread.NORM_PRIORITY - 1); EXECUTOR.setWaitForTasksToCompleteOnShutdown(true); EXECUTOR.setThreadNamePrefix("callRewriteExecutor-"); + EXECUTOR.setAllowCoreThreadTimeOut(true); EXECUTOR.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/RandomInviteProperties.java b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/RandomInviteProperties.java index 2b674b3..7f4a3f3 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/RandomInviteProperties.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/task/RandomInviteProperties.java @@ -1,7 +1,10 @@ package com.hz.pm.api.meeting.task; +import com.hz.pm.api.common.config.ThreadPoolUtilProperties; +import com.hz.pm.api.common.config.ThreadPoolUtilProperties.ThreadPoolProperties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.stereotype.Component; /** @@ -56,4 +59,7 @@ public class RandomInviteProperties { private Integer inviteEndHour = 20; + @NestedConfigurationProperty + private ThreadPoolProperties threadPoolProperties; + } diff --git a/hz-pm-api/src/main/resources/application-dev.yml b/hz-pm-api/src/main/resources/application-dev.yml index c2ea566..8b16536 100644 --- a/hz-pm-api/src/main/resources/application-dev.yml +++ b/hz-pm-api/src/main/resources/application-dev.yml @@ -224,4 +224,8 @@ thread-pool-util: thread-name-prefix: request-executor- scheduler: core-pool-size: 2 - thread-name-prefix: scheduler-executor- \ No newline at end of file + thread-name-prefix: scheduler-executor- +random-invite: + thread-pool-properties: + core-pool-size: 2 + thread-name-prefix: expert-invite-executor- \ No newline at end of file diff --git a/hz-pm-api/src/main/resources/application-prod.yml b/hz-pm-api/src/main/resources/application-prod.yml index 8d92e3d..9efb5b9 100644 --- a/hz-pm-api/src/main/resources/application-prod.yml +++ b/hz-pm-api/src/main/resources/application-prod.yml @@ -248,3 +248,7 @@ wflow-thread-pool-util: queue-capacity: 300 keep-alive-seconds: 120 max-pool-size: 8 +random-invite: + thread-pool-properties: + core-pool-size: 3 + thread-name-prefix: expert-invite-executor- \ No newline at end of file diff --git a/hz-pm-api/src/test/java/com/hz/pm/api/common/StateMachineTest.java b/hz-pm-api/src/test/java/com/hz/pm/api/common/StateMachineTest.java new file mode 100644 index 0000000..8e32776 --- /dev/null +++ b/hz-pm-api/src/test/java/com/hz/pm/api/common/StateMachineTest.java @@ -0,0 +1,46 @@ +package com.hz.pm.api.common; + +import com.hz.pm.api.AppTests; +import com.hz.pm.api.common.statemachine.util.TenderStateMachineUtil; +import com.hz.pm.api.common.statemachine.util.XcfhxStateMachineUtil; +import com.hz.pm.api.common.util.ThreadPoolUtil; +import com.hz.pm.api.projectdeclared.model.entity.Purchase; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.concurrent.CountDownLatch; + +/** + *

+ * StateMachineTest + *

+ * + * @author WendyYang + * @since 19:43 2024/8/29 + */ +public class StateMachineTest extends AppTests { + + @Autowired + private TenderStateMachineUtil tenderStateMachineUtil; + @Autowired + private XcfhxStateMachineUtil xcfhxStateMachineUtil; + + @Test + public void test() { + CountDownLatch count = new CountDownLatch(1000); + for (int j = 0; j < 100; j++) { + ThreadPoolUtil.REQUEST.execute(() -> { + Purchase purchase = new Purchase(); + purchase.setProjectId(3496L); + for (int i = 0; i < 5; i++) { + purchase.setBidType(i % 2 == 0 ? 2 : 1); + purchase.setStatus(101); + purchase.setXcfhxApplyStatus(301); + xcfhxStateMachineUtil.pass(purchase); + } + count.countDown(); + }); + } + } + +} diff --git a/hz-pm-api/src/test/resources/application-dev.yml b/hz-pm-api/src/test/resources/application-dev.yml index ff43fda..b9d5c9e 100644 --- a/hz-pm-api/src/test/resources/application-dev.yml +++ b/hz-pm-api/src/test/resources/application-dev.yml @@ -16,7 +16,7 @@ spring: timeout: 5000 host: 47.98.125.47 port: 26379 - database: 5 + database: 7 password: Ndkj1234 jedis: pool: @@ -153,17 +153,6 @@ sa-token: # 是否输出操作日志 is-log: false -yxt: - # wsdl-url: http://115.239.137.23:9501/ws/v1?wsdl - wsdl-url: classpath:/wsdl.xml - #账号 - user-code: hzndkj - #密码 - password: hzndkj@2021 - #音信通开关 - sms-enable: true - tel-enable: true - login: phone-verify-code: skip: true @@ -176,26 +165,63 @@ sync-mh-user: sync-mh-company: open: false mh: - zwdd-work-notice: + sso: client-id: ningda-74a5e5da-3bc3-414a-b9e6-004b7d87e310 client-secret: ningda-df746ce4-0c79-4242-b3c7-90ff8630c9742c6727cd-3ae7-48ae-87ad-2b39188ebabd - sso: + zwdd-work-notice: client-id: ningda-74a5e5da-3bc3-414a-b9e6-004b7d87e310 client-secret: ningda-df746ce4-0c79-4242-b3c7-90ff8630c9742c6727cd-3ae7-48ae-87ad-2b39188ebabd - api-host: https://hzszxc.hzswb.cn:8443/mh-gateway/auth-single + api-host: https://hzszxc.hzswb.cn:8443/test/mh-gateway/auth-single expert-qr-code-url: https://jiema.wwei.cn/uploads/2023/12/28/658d7a3f15f06.jpg file: down-url: https://weixin.hzszxc.hzswb.cn:8443/test/mh-gateway/oss/oss/previewFileLogin detail-url: https://weixin.hzszxc.hzswb.cn:8443/test/mh-gateway/oss/ossfile/getFileInfoList upload-url: https://weixin.hzszxc.hzswb.cn:8443/test/mh-gateway/oss/oss/uploadFileSkipLogin + file-preview: + public-host: http://ztzz2.hzswb.cn/yl + auth-code: secret-key: nqkmzqojg5j4eiypr3rb8s7nb4noa8b2 agent-login: proxy: secret-key: nqkwiqojg7g4eiypr3rb8s7nb4noa8b2 -# 短信服务地址 sms-send: host: http://10.54.38.13:8081/mh-gateway/auth-single -# 电话服务地址 +sms-client: + host: http://10.54.38.13:8081/mh-gateway/auth-single + open: false + mobile-call: - host: http://183.158.240.86:18181/blue_esl_api \ No newline at end of file + host: http://183.158.240.86:18181/blue_esl_api + +# 提醒任务 +reminder-task: + declared-record: + open: false + cron: 0 30 8 * * ? +hz-pm: + interfaceKey: hz_meeting_expert_info + +web: + login: + url: http://hzpm.ningdatech.com + api: + url: http://hzpm.ningdatech.com/hzpm + +expert-invite: + skip-send-call: true + skip-send-sms: true + +mh-system-replace-sync: + open: false + +thread-pool-util: + request: + core-pool-size: 5 + max-pool-size: 10 + queue-capacity: 100 + keep-alive-seconds: 120 + thread-name-prefix: request-executor- + scheduler: + core-pool-size: 2 + thread-name-prefix: scheduler-executor- \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2d0c6b0..2545291 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ org.springframework.statemachine spring-statemachine-core - 2.0.1.RELEASE + 2.2.0.RELEASE com.github.oshi