From 0807ba5ce869701892b6d57f2ea3ea4647fed5f2 Mon Sep 17 00:00:00 2001 From: yanglin Date: Mon, 23 Dec 2024 10:22:08 +0800 Subject: [PATCH 1/5] =?UTF-8?q?REQ-3282:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../message/migrate/OuIdMigrateService.java | 250 ------------------ .../migrate/OuIdMigrateServiceTest.java | 24 -- 2 files changed, 274 deletions(-) delete mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/migrate/OuIdMigrateService.java delete mode 100644 start/src/test/java/cn/axzo/msg/center/message/migrate/OuIdMigrateServiceTest.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/migrate/OuIdMigrateService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/migrate/OuIdMigrateService.java deleted file mode 100644 index 1eab458f..00000000 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/migrate/OuIdMigrateService.java +++ /dev/null @@ -1,250 +0,0 @@ -package cn.axzo.msg.center.message.migrate; - -import cn.axzo.apollo.api.ApolloWorkerTaskOrderApi; -import cn.axzo.framework.domain.web.result.ApiResult; -import cn.axzo.maokai.api.client.CooperateShipQueryApi; -import cn.axzo.maokai.api.client.OrganizationalNodeUserApi; -import cn.axzo.maokai.api.client.OrganizationalTeamOuRelationApi; -import cn.axzo.maokai.api.vo.response.OrganizationalTeamOuRelationResp; -import cn.axzo.msg.center.common.utils.BizAssertions; -import cn.axzo.msg.center.dal.PendingMessageRecordDao; -import cn.axzo.msg.center.domain.entity.PendingMessageRecord; -import cn.axzo.msg.center.domain.entity.PendingRecordExt; -import cn.axzo.msg.center.domain.enums.YesNoEnum; -import cn.axzo.msg.center.domain.persistence.BaseEntityExt; -import cn.axzo.msg.center.service.enums.YesOrNo; -import cn.axzo.pluto.api.TeamServiceApi; -import cn.axzo.pluto.teams.common.enums.UserTerminalPerspective; -import cn.azxo.framework.common.model.CommonResponse; -import com.alibaba.fastjson.JSONObject; -import com.google.common.collect.Lists; -import jodd.util.concurrent.ThreadFactoryBuilder; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; - -/** - * @author yanglin - */ -@Slf4j -@Component -@RequiredArgsConstructor -public class OuIdMigrateService { - - private static final String MIGRATE_OU_CURSOR = "msg_center_migrate_ou_cursor"; - - private final RedisTemplate redisTemplate; - private final PendingMessageRecordDao pendingMessageRecordDao; - private final OrganizationalTeamOuRelationApi organizationalTeamOuRelationApi; - private final TeamServiceApi teamServiceApi; - private final CooperateShipQueryApi cooperateShipQueryApi; - private final ApolloWorkerTaskOrderApi apolloWorkerTaskOrderApi; - private final OrganizationalNodeUserApi organizationalNodeUserApi; - - @Value("${message.pending.ouMigrateBatchSize:100}") - private final Long migrateBatchSize; - - @Getter - private volatile boolean isRunning; - - - - private final ThreadFactory moduleStatisticTaskThreadFactory = ThreadFactoryBuilder.create() - .setDaemon(true) - .setNameFormat("MODULE_STATISTIC_TASK_%d") - .get(); - private final ExecutorService taskThreadPool = new ThreadPoolExecutor(20, 100, 10, TimeUnit.SECONDS, - new ArrayBlockingQueue<>(2000), moduleStatisticTaskThreadFactory); - - public void migrate(List records) { - try { - String ids = records.stream() - .map(BaseEntityExt::getId) - .map(String::valueOf) - .collect(joining(",")); - log.info("start - migrate ou id: {}", ids); - // 迁移ou_id=0的 - // 逻辑: 通过身份查询人默认的班组,获取到班组后,再获取班组对应的团队,取团队的id - migrateZeroOuId(records); - log.info("end - migrate ou id: {}", ids); - } catch (Exception e) { - log.warn("ouId fail", e); - } - } - - private void migrateZeroOuId(List records) throws ExecutionException, InterruptedException { - // 业务发送待办时未传ouId - List zeroOuIdRecords = records.stream() - .filter(i -> i.getOuId().equals(0L)) - .collect(toList()); - if (zeroOuIdRecords.isEmpty()) { - log.info("updateOuIdJob migrate is empty"); - return; - } - - List> partitions = Lists - .partition(zeroOuIdRecords, 20); - List futures = new ArrayList<>(); - for (int i = 0; i < partitions.size(); i++) { - List dataList = partitions.get(i); - futures.add(CompletableFuture.runAsync(() -> - updateZero(dataList), taskThreadPool)); - } - CompletableFuture.allOf(futures.stream().toArray(CompletableFuture[]::new)).get(); - } - - private void updateZero(List records) { - List update = records.stream() - .map(record -> { - try { - log.info("zeroOuId, record:{}", record.getId()); - Long identityId = record.getExecutorId(); - - DefaultTeamInfo defaultTeam = getDefaultTeamId(identityId); - log.info("zeroOuId, record:{}, defaultTeam:{}", record.getId(), JSONObject.toJSONString(defaultTeam)); - if (defaultTeam == null) { - PendingMessageRecord pendingMessageRecord = new PendingMessageRecord(); - pendingMessageRecord.setId(record.getId()); - pendingMessageRecord.setIsDelete(YesNoEnum.YES.getCode().longValue()); - return pendingMessageRecord; - } - - Map teamId2OuInfo = - getOuInfoByTeamId(Lists.newArrayList(defaultTeam.teamId)); - OrganizationalTeamOuRelationResp teamInfo = teamId2OuInfo.get(defaultTeam.teamId); - log.info("zeroOuId, record:{}, teamInfo:{}", record.getId(), JSONObject.toJSONString(teamInfo)); - if (teamInfo == null) { - PendingMessageRecord pendingMessageRecord = new PendingMessageRecord(); - pendingMessageRecord.setId(record.getId()); - pendingMessageRecord.setIsDelete(YesNoEnum.YES.getCode().longValue()); - return pendingMessageRecord; - } else { - return tryUpdate(record, teamInfo.getOuId(), String.format( - "找到了默认团队, 并通过身份id找到默认团队, 再找到对应的单位. teamId=%d, ouId=%d, 视角=%s, 视角type=%s", - defaultTeam.teamId, teamInfo.getOuId(), defaultTeam.perspectiveDesc, defaultTeam.perspective)); - } - } catch (Exception e) { - log.warn("ouId fail, recordId:{}; e:{}", record.getId(), e); - } - return null; - }) - .filter(Objects::nonNull) - .collect(toList()); - List removeIds = update.stream() - .filter(record -> Objects.equals(record.getIsDelete(), YesNoEnum.YES.getCode().longValue())) - .map(PendingMessageRecord::getId) - .collect(toList()); - if (!CollectionUtils.isEmpty(removeIds)) { - pendingMessageRecordDao.removeByIds(removeIds); - } - - List updates = update.stream() - .filter(record -> !Objects.equals(record.getIsDelete(), YesNoEnum.YES.getCode().longValue())) - .collect(toList()); - if (!CollectionUtils.isEmpty(updates)) { - pendingMessageRecordDao.updateBatchById(updates); - } - } - - @Nullable - private DefaultTeamInfo getDefaultTeamId(Long identityId) { - Integer successCode = 200; - CommonResponse resp1 = teamServiceApi.getDefaultTeam( - identityId, UserTerminalPerspective.LEADER_PERSPECTIVE.code); - if (successCode.equals(resp1.getCode())) { - return new DefaultTeamInfo(resp1.getData(), UserTerminalPerspective.LEADER_PERSPECTIVE, "工人端-班组长视角"); - } - CommonResponse resp2 = teamServiceApi.getDefaultTeam( - identityId, UserTerminalPerspective.CMP_LEADER_PERSPECTIVE.code); - if (successCode.equals(resp2.getCode())) { - return new DefaultTeamInfo(resp2.getData(), UserTerminalPerspective.CMP_LEADER_PERSPECTIVE, "管理端-班b组长视角"); - } - CommonResponse resp3 = teamServiceApi.getDefaultTeam( - identityId, UserTerminalPerspective.WORKER_PERSPECTIVE.code); - if (successCode.equals(resp3.getCode())) { - return new DefaultTeamInfo(resp3.getData(), UserTerminalPerspective.WORKER_PERSPECTIVE, "工人端-工人视角"); - } - return null; - } - - @NotNull - private Map getOuInfoByTeamId(List maybeTeamIds) { - ApiResult> maybeTeamIdsResp = - organizationalTeamOuRelationApi.getByTeamOuIds(Lists.newArrayList(maybeTeamIds)); - return BizAssertions - .assertResponse(maybeTeamIdsResp, "can't get plat team info").stream() - .collect(Collectors.toMap(OrganizationalTeamOuRelationResp::getTeamOuId, Function.identity())); - } - - private PendingMessageRecord tryUpdate(PendingMessageRecord record, Long newOuId, String ouIdMigrateDesc) { - PendingRecordExt ext = record.getRecordExt(); - if (ext == null) - ext = new PendingRecordExt(); - if (record.getIsOuIdMigrated() == YesOrNo.YES) - return null; - // 找不到的newOuId不进行更新 - if (newOuId == null || newOuId == 0 ) { - return null; - } - - // 最原始的ouId不要被覆盖了 - if (ext.getMigrateOu().getOriginalOuId() != null) - ext.getMigrateOu().setOriginalOuId(record.getOuId()); - ext.getMigrateOu().setOuIdMigrateTime(new Date()); - ext.getMigrateOu().setOuIdMigrateDesc(ouIdMigrateDesc); - - PendingMessageRecord update = new PendingMessageRecord(); - update.setId(record.getId()); - update.setOuId(newOuId); - update.setRecordExt(ext); - update.setUpdateAt(new Date()); - update.setIsOuIdMigrated(YesOrNo.YES); - log.warn("migrating pending record's ouId field. pending message id={}, originalOuId={}, newOuId={}", - record.getId(), record.getOuId(), newOuId); - return update; - } - - @Data - @ToString - @NoArgsConstructor - @AllArgsConstructor - public static class Param { - private List migrateRecordIds; - private boolean scanMigrate; - } - - @RequiredArgsConstructor - private static class DefaultTeamInfo { - private final Long teamId; - private final UserTerminalPerspective perspective; - private final String perspectiveDesc; - } -} \ No newline at end of file diff --git a/start/src/test/java/cn/axzo/msg/center/message/migrate/OuIdMigrateServiceTest.java b/start/src/test/java/cn/axzo/msg/center/message/migrate/OuIdMigrateServiceTest.java deleted file mode 100644 index 88085e45..00000000 --- a/start/src/test/java/cn/axzo/msg/center/message/migrate/OuIdMigrateServiceTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.axzo.msg.center.message.migrate; - -import cn.axzo.msg.center.MsgCenterApplication; -import lombok.RequiredArgsConstructor; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @author yanglin - */ -@SpringBootTest(classes = MsgCenterApplication.class) -@RequiredArgsConstructor(onConstructor_ = @Autowired) -class OuIdMigrateServiceTest { - - private final OuIdMigrateService ouIdMigrateService; - - @Test - void foo() { - } - -} \ No newline at end of file From 6eee6b7c9ce324635741c26b565b47c59c3de7e9 Mon Sep 17 00:00:00 2001 From: yanglin Date: Mon, 23 Dec 2024 10:35:39 +0800 Subject: [PATCH 2/5] =?UTF-8?q?REQ-3282:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inside-notices/pom.xml | 5 +++++ .../message/service/impl/PendingMessageNewServiceImpl.java | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/inside-notices/pom.xml b/inside-notices/pom.xml index f57f7629..a6c1d5f8 100644 --- a/inside-notices/pom.xml +++ b/inside-notices/pom.xml @@ -21,6 +21,11 @@ + + cn.axzo.org + org-api + 1.0.0-SNAPSHOT + cn.axzo.epic epic-api diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index b10961a1..f23367a1 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -9,7 +9,6 @@ import cn.axzo.msg.center.dal.MessageGroupNodeDao; import cn.axzo.msg.center.domain.entity.MessageGroupNode; import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig; -import cn.axzo.msg.center.message.service.impl.v3.ModelV3Parser; import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -43,7 +42,6 @@ public class PendingMessageNewServiceImpl { private final OrganizationalTeamOuRelationApi organizationalTeamOuRelationApi; private final PendingMessageBizConfig pendingMessageBizConfig; private final MessageGroupNodeDao messageGroupNodeDao; - private final ModelV3Parser modelV3Parser; public Map getTerminalConfigInfo() { Map> appType2NodeIds = pendingMessageBizConfig.getMsgGroupConfig(); From 1a77c14233117b11ec3bcbe0acae78887b3e89e5 Mon Sep 17 00:00:00 2001 From: yanglin Date: Mon, 23 Dec 2024 17:41:41 +0800 Subject: [PATCH 3/5] =?UTF-8?q?REQ-3282:=20=E6=9B=BF=E6=8D=A2=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/PendingMessageNewServiceImpl.java | 16 ++++++++-------- .../msg/center/common/utils/BizAssertions.java | 16 ++++++++++++++++ .../cn/axzo/msg/center/MsgCenterApplication.java | 3 ++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index f23367a1..10ccb5a2 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -1,8 +1,6 @@ package cn.axzo.msg.center.message.service.impl; -import cn.axzo.framework.domain.web.result.ApiResult; -import cn.axzo.maokai.api.client.OrganizationalTeamOuRelationApi; -import cn.axzo.maokai.api.vo.response.OrganizationalTeamOuRelationResp; +import cn.axzo.foundation.result.ApiResult; import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; import cn.axzo.msg.center.common.utils.BizAssertions; import cn.axzo.msg.center.dal.MessageGroupNodeDao; @@ -10,6 +8,8 @@ import cn.axzo.msg.center.domain.entity.MessageGroupNode; import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig; import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum; +import cn.axzo.orggateway.api.orgteamourelation.OrgTeamOuRelationFeignApi; +import cn.axzo.orggateway.api.orgteamourelation.resp.OrgTeamOuRelationResp; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -39,7 +39,7 @@ import static java.util.stream.Collectors.toSet; @RequiredArgsConstructor public class PendingMessageNewServiceImpl { - private final OrganizationalTeamOuRelationApi organizationalTeamOuRelationApi; + private final OrgTeamOuRelationFeignApi orgTeamOuRelationFeignApi; private final PendingMessageBizConfig pendingMessageBizConfig; private final MessageGroupNodeDao messageGroupNodeDao; @@ -82,12 +82,12 @@ public class PendingMessageNewServiceImpl { ouIds.add(ouId); // 2. 查询ouId下面所有的平台班组id当成ouId if (ouId != 0) { - ApiResult> resp = - organizationalTeamOuRelationApi.teamOuRelationList(ouId); - List relations = + ApiResult> resp = + orgTeamOuRelationFeignApi.teamOuRelationList(ouId); + List relations = BizAssertions.assertResponse(resp, "获取平台班组id失败"); relations.stream() - .map(OrganizationalTeamOuRelationResp::getTeamOuId) + .map(OrgTeamOuRelationResp::getTeamOuId) .distinct() .forEach(ouIds::add); } diff --git a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/BizAssertions.java b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/BizAssertions.java index e4da16dc..2b016bfc 100644 --- a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/BizAssertions.java +++ b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/BizAssertions.java @@ -132,4 +132,20 @@ public class BizAssertions { return response.getData(); } + public static T assertResponse(cn.axzo.foundation.result.ApiResult response) { + return assertResponse(response, "error resp={}", JSON.toJSONString(response)); + } + + public static T assertResponse(cn.axzo.foundation.result.ApiResult response, String message, Object... args) { + if (!response.isSuccess()) { + String finalMsg = MessageFormatter.arrayFormat(message, args).getMessage(); + if (StringUtils.isNotBlank(response.getMsg())) { + finalMsg += ": " + response.getMsg(); + } + ServiceException e = new ServiceException(finalMsg); + log.warn("remote call response with error. response={}", JSON.toJSONString(response), e); + throw e; + } + return response.getData(); + } } \ No newline at end of file diff --git a/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java b/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java index c22f03f6..a4a5b827 100644 --- a/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java +++ b/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java @@ -28,7 +28,8 @@ import org.springframework.core.env.Environment; "cn.axzo.msg.center.inside.notices.service.impl", "cn.axzo.meepo.api", "cn.axzo.riven.client.feign", - "cn.axzo.epic.client.feign" + "cn.axzo.epic.client.feign", + "cn.axzo.orggateway.api.orgteamourelation" }) /*@EnableAsync*/ public class MsgCenterApplication { From 9218cd3dbcdc6a61847c0ef932ca6a84a8f1d846 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 25 Dec 2024 14:05:00 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat(REQ-3282):=20messageApiV2=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inside-notices/pom.xml | 4 + .../impl/v2/MessageApiV2Controller.java | 36 ++++ .../impl/PendingMessageNewServiceImpl.java | 6 +- msg-center-api-v2/pom.xml | 47 +++++ .../api/v2/config/MsgCenterApiV2Config.java | 14 ++ .../api/v2/message/feign/MessageApiV2.java | 20 +++ .../api/v2/message/req/MessageSendV2Req.java | 167 ++++++++++++++++++ .../api/v2/message/req/PersonV2DTO.java | 59 +++++++ .../v2/message/resp/MessageSendResultV2.java | 33 ++++ .../v2/message/resp/MessageSendV2Resp.java | 48 +++++ .../v2/message/resp/TemplateSendV2Result.java | 74 ++++++++ .../main/resources/META-INF/spring.factories | 2 + pom.xml | 7 + 13 files changed, 514 insertions(+), 3 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v2/MessageApiV2Controller.java create mode 100644 msg-center-api-v2/pom.xml create mode 100644 msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/config/MsgCenterApiV2Config.java create mode 100644 msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/feign/MessageApiV2.java create mode 100644 msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/MessageSendV2Req.java create mode 100644 msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/PersonV2DTO.java create mode 100644 msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendResultV2.java create mode 100644 msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendV2Resp.java create mode 100644 msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/TemplateSendV2Result.java create mode 100644 msg-center-api-v2/src/main/resources/META-INF/spring.factories diff --git a/inside-notices/pom.xml b/inside-notices/pom.xml index a6c1d5f8..14e26e33 100644 --- a/inside-notices/pom.xml +++ b/inside-notices/pom.xml @@ -189,6 +189,10 @@ 3.5.0 compile + + cn.axzo.msgcenter + msg-center-api-v2 + \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v2/MessageApiV2Controller.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v2/MessageApiV2Controller.java new file mode 100644 index 00000000..f7716f9b --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v2/MessageApiV2Controller.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.center.inside.notices.service.impl.v2; + +import cn.axzo.foundation.result.ApiResult; +import cn.axzo.msg.center.api.request.v3.MessageSendReqV3; +import cn.axzo.msg.center.api.response.v3.MessageSendRespV3; +import cn.axzo.msg.center.api.v2.message.feign.MessageApiV2; +import cn.axzo.msg.center.api.v2.message.req.MessageSendV2Req; +import cn.axzo.msg.center.api.v2.message.resp.MessageSendV2Resp; +import cn.axzo.msg.center.inside.notices.service.MessageServiceV3; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2024/12/13 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +public class MessageApiV2Controller implements MessageApiV2 { + + private final MessageServiceV3 messageServiceV3; + + @Override + public ApiResult send(MessageSendV2Req req) { + log.info("MessageAPIV3Controller.send req={}", req); + MessageSendReqV3 sendReqV3 = new MessageSendReqV3(); + BeanUtils.copyProperties(req, sendReqV3); + MessageSendRespV3 sendRespV3 = messageServiceV3.send(sendReqV3); + MessageSendV2Resp sendV2Resp = new MessageSendV2Resp(); + BeanUtils.copyProperties(sendRespV3, sendV2Resp); + return ApiResult.success(sendV2Resp); + } +} \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index 10ccb5a2..8d051131 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -8,7 +8,7 @@ import cn.axzo.msg.center.domain.entity.MessageGroupNode; import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig; import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum; -import cn.axzo.orggateway.api.orgteamourelation.OrgTeamOuRelationFeignApi; +import cn.axzo.orggateway.api.orgteamourelation.OrgTeamOuRelationApi; import cn.axzo.orggateway.api.orgteamourelation.resp.OrgTeamOuRelationResp; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -39,7 +39,7 @@ import static java.util.stream.Collectors.toSet; @RequiredArgsConstructor public class PendingMessageNewServiceImpl { - private final OrgTeamOuRelationFeignApi orgTeamOuRelationFeignApi; + private final OrgTeamOuRelationApi orgTeamOuRelationApi; private final PendingMessageBizConfig pendingMessageBizConfig; private final MessageGroupNodeDao messageGroupNodeDao; @@ -83,7 +83,7 @@ public class PendingMessageNewServiceImpl { // 2. 查询ouId下面所有的平台班组id当成ouId if (ouId != 0) { ApiResult> resp = - orgTeamOuRelationFeignApi.teamOuRelationList(ouId); + orgTeamOuRelationApi.teamOuRelationList(ouId); List relations = BizAssertions.assertResponse(resp, "获取平台班组id失败"); relations.stream() diff --git a/msg-center-api-v2/pom.xml b/msg-center-api-v2/pom.xml new file mode 100644 index 00000000..1dade2cb --- /dev/null +++ b/msg-center-api-v2/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + + msg-center + cn.axzo.msgcenter + ${revision} + ../pom.xml + + + msg-center-api-v2 + ${msg-center-api-v2-version} + + + 8 + 8 + UTF-8 + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + cn.axzo.foundation + common-lib + 2.0.0-SNAPSHOT + + + org.projectlombok + lombok + + + com.alibaba + fastjson + + + javax.validation + validation-api + + + + \ No newline at end of file diff --git a/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/config/MsgCenterApiV2Config.java b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/config/MsgCenterApiV2Config.java new file mode 100644 index 00000000..1fd3da23 --- /dev/null +++ b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/config/MsgCenterApiV2Config.java @@ -0,0 +1,14 @@ +package cn.axzo.msg.center.api.v2.config; + +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Configuration; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2024/12/10 + */ +@Configuration +@EnableFeignClients(basePackages = "cn.axzo.msg.center.api.v2.**.feign") +public class MsgCenterApiV2Config { + +} \ No newline at end of file diff --git a/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/feign/MessageApiV2.java b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/feign/MessageApiV2.java new file mode 100644 index 00000000..fcf40466 --- /dev/null +++ b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/feign/MessageApiV2.java @@ -0,0 +1,20 @@ +package cn.axzo.msg.center.api.v2.message.feign; + +import cn.axzo.foundation.result.ApiResult; +import cn.axzo.msg.center.api.v2.message.req.MessageSendV2Req; +import cn.axzo.msg.center.api.v2.message.resp.MessageSendV2Resp; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.validation.Valid; + +@FeignClient( + value = "msg-center", + url = "${axzo.service.msg-center:http://msg-center:8080}") +public interface MessageApiV2 { + + @PostMapping(value = "api/message/v2/send") + ApiResult send(@RequestBody @Valid MessageSendV2Req req); + +} \ No newline at end of file diff --git a/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/MessageSendV2Req.java b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/MessageSendV2Req.java new file mode 100644 index 00000000..672ac2e3 --- /dev/null +++ b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/MessageSendV2Req.java @@ -0,0 +1,167 @@ +package cn.axzo.msg.center.api.v2.message.req; + +import cn.axzo.basics.common.util.AssertUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +/** + * @author yanglin + */ +@Setter +@Getter +@Slf4j +public class MessageSendV2Req implements Serializable { + + /** + * 发送待办时, channelParams 的 key, 传值 {@link PendingSendInfo} + */ + public static final String CHANNEL_PENDING = "channel_pending"; + + /** + * 发起者 + *

如果是平台,则发起人为空 + */ + private PersonV2DTO sender; + + /** + * 接收者列表 + */ + @NotNull(message = "接收者列表不能为空") + private List receivers; + + /** + * 业务事件code + * oms->消息模板 配置 + */ + @NotBlank(message = "业务事件code不能为空") + private String bizEventMappingCode; + + /** + * 关联业务唯一标识 + * 例如: 请假申请的编号 + */ + private String bizCode; + + /** + * 业务扩展参数-JSON字符串格式 + */ + private JSONObject bizExtParams; + + /** + * 路由参数-JSON字符串格式 + */ + private JSONObject routerParams; + + /** + * 发送者项目部ID + */ + private Long senderWorkspaceId; + + /** + * 发送者企业ID + */ + private Long senderOuId; + + /** + * 接收者项目部ID + */ + private Long receiversWorkspaceId; + + /** + * 接收者企业ID + *

如果是工人,则所在企业可以为空;其它均必传 + */ + private Long receiversOuId; + + /** + * 接收者(消息)所属组织类型 + */ + private Integer receiversOrgType; + + /** + * 副标题 + */ + private String subtitle; + + /** + * 渠道参数 + */ + private JSONObject channelParams; + + public void addChannelParam(String key, Object object) { + if (channelParams == null) { + channelParams = new JSONObject(); + } + channelParams.put(key, object); + } + + public T getChannelParam(String key, Class asType) { + if (channelParams == null) { + return null; + } + if (!channelParams.containsKey(key)) { + return null; + } + return channelParams.getObject(key, asType); + } + + public Collection distinctReceivers() { + if (receivers == null) { + return Collections.emptySet(); + } + HashMap personId2Person = new HashMap<>(); + for (PersonV2DTO receiver : receivers) { + if (!personId2Person.containsKey(receiver.getId())) { + personId2Person.put(receiver.getId(), receiver); + } + } + return personId2Person.values(); + } + + public List receivers() { + if (receivers == null) { + return Collections.emptyList(); + } + return receivers; + } + + public Long determineReceiversOuId() { + return receiversOuId == null ? 0L : receiversOuId; + } + + public Long determineReceiversWorkspaceId() { + return receiversWorkspaceId == null ? 0L : receiversWorkspaceId; + } + + public String determineBizCode() { + return bizCode == null ? "" : bizCode; + } + + public void validate() { + AssertUtil.notNull(bizEventMappingCode, "bizEventCode不能为空"); + AssertUtil.notEmpty(receivers, "receivers不能为空"); + + for (PersonV2DTO receiver : receivers) { + AssertUtil.notNull(receiver.getId(), "接收者ID不能为空"); + if (receiver.getId() <= 0) + log.warn("接收者ID <= 0, request={}", this); + // 去掉这个校验 + //AssertUtil.isFalse(receiver.getId() <= 0, "接收者ID必须>=0"); + } + } + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} \ No newline at end of file diff --git a/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/PersonV2DTO.java b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/PersonV2DTO.java new file mode 100644 index 00000000..7c1c9571 --- /dev/null +++ b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/req/PersonV2DTO.java @@ -0,0 +1,59 @@ +package cn.axzo.msg.center.api.v2.message.req; + +import lombok.*; + +import java.io.Serializable; + +/** + * @author yanglin + */ +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PersonV2DTO implements Serializable { + + private static final long serialVersionUID = 1231840051925115741L; + + public PersonV2DTO(Long id) { + this.id = id; + } + + public PersonV2DTO(Long id, String name) { + this.id = id; + this.name = name; + } + + /** + * 自然人id + */ + private Long id; + /** + * 姓名 + */ + private String name; + + /** + * IM消息接收模型, 可以为空 + *

优先使用这里的ouId, 如果这里没有传, 就使用 {@link cn.axzo.msg.center.api.request.v3.MessageSendReqV3} 中的相应的信息 + */ + private ReceiveModel imReceiveModel; + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class ReceiveModel { + + /** + * 接收者单位id + */ + private Long ouId; + + /** + * 接收者项目部id + */ + private Long workspaceId; + } + +} \ No newline at end of file diff --git a/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendResultV2.java b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendResultV2.java new file mode 100644 index 00000000..9cb266f2 --- /dev/null +++ b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendResultV2.java @@ -0,0 +1,33 @@ +package cn.axzo.msg.center.api.v2.message.resp; + +import com.alibaba.fastjson.JSON; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serializable; + +/** + * @author yanglin + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class MessageSendResultV2 implements Serializable { + /** + * 接收者id + */ + private Long receiverPersonId; + + /** + * 渠道结果id + */ + private Long resultId; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} \ No newline at end of file diff --git a/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendV2Resp.java b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendV2Resp.java new file mode 100644 index 00000000..7f3cfd80 --- /dev/null +++ b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/MessageSendV2Resp.java @@ -0,0 +1,48 @@ +package cn.axzo.msg.center.api.v2.message.resp; + +import com.alibaba.fastjson.JSON; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.*; + +/** + * @author yanglin + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MessageSendV2Resp implements Serializable { + /** + * 这次批量发送的批次号, 如果配置了多个模版,多个渠道, 可以用批次号串联起来 + */ + private String batchNo; + + /** + * 模版code -> 模版发送结果 + */ + private Map templateCode2SendResult; + + public void addResult(TemplateSendV2Result result) { + templateCode2SendResult.put(result.getTemplateCode(), result); + } + + public Optional findTemplateSendResult(String templateCode) { + return Optional.ofNullable(templateCode2SendResult.get(templateCode)); + } + + public Set templateCodes() { + return new HashSet<>(templateCode2SendResult.keySet()); + } + + public Map templateSendResults() { + return Collections.unmodifiableMap(templateCode2SendResult); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} \ No newline at end of file diff --git a/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/TemplateSendV2Result.java b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/TemplateSendV2Result.java new file mode 100644 index 00000000..b2327c26 --- /dev/null +++ b/msg-center-api-v2/src/main/java/cn/axzo/msg/center/api/v2/message/resp/TemplateSendV2Result.java @@ -0,0 +1,74 @@ +package cn.axzo.msg.center.api.v2.message.resp; + +import com.alibaba.fastjson.JSON; +import lombok.Data; + +import java.io.Serializable; +import java.util.*; + +/** + * @author yanglin + */ +@Data +public class TemplateSendV2Result implements Serializable { + /** + * 模版编码 + */ + private String templateCode; + + /** + * 渠道 + *

NOTIFICATION: 通知, PENDING: 待办 + */ + private String channel; + + /** + * 接收者personId -> 接收人发送结果 + * key: string, 兼容json的key必须为string类型 + */ + private Map receiverPersonId2SendResult; + + @SuppressWarnings("unused") + public TemplateSendV2Result() { + } + + public TemplateSendV2Result(String templateCode, String channel) { + this.templateCode = templateCode; + this.channel = channel; + this.receiverPersonId2SendResult = new HashMap<>(); + } + + public void addResult(MessageSendResultV2 result) { + if (receiverPersonId2SendResult == null) + // 序列化问题 + throw new RuntimeException("需要通过构造函数初始化receiverPersonId2SendResult"); + String receiverPersonId = String.valueOf(result.getReceiverPersonId()); + receiverPersonId2SendResult.put(receiverPersonId, result); + } + + public Optional findResultByReceiver(Long receiverPersonId) { + if (receiverPersonId2SendResult == null) + return Optional.empty(); + if (receiverPersonId == null) + return Optional.empty(); + String strReceiverPersonId = String.valueOf(receiverPersonId); + return Optional.ofNullable(receiverPersonId2SendResult.get(strReceiverPersonId)); + } + + /** + * 返回的数量不一定和发送请求中的receivers数量一致, 发送的时候根据receiver的personId去了重 + *

推荐使用 {@link #findResultByReceiver}, 根据接收者获取发送结果 + * + * @return 所有的发送结果 + */ + public Collection messageSendResults() { + if (receiverPersonId2SendResult == null) + return Collections.emptyList(); + return new ArrayList<>(receiverPersonId2SendResult.values()); + } + + @Override + public String toString() { + return JSON.toJSONString(receiverPersonId2SendResult); + } +} \ No newline at end of file diff --git a/msg-center-api-v2/src/main/resources/META-INF/spring.factories b/msg-center-api-v2/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..b238b5c7 --- /dev/null +++ b/msg-center-api-v2/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +cn.axzo.msg.center.api.v2.config.MsgCenterApiV2Config \ No newline at end of file diff --git a/pom.xml b/pom.xml index fab19410..9a308783 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,7 @@ start msg-center-dal msg-center-domain + msg-center-api-v2 @@ -32,6 +33,7 @@ UTF-8 1.0.0-SNAPSHOT 1.0.1-SNAPSHOT + 1.0.1-SNAPSHOT 2.0.0-SNAPSHOT 2.0.0-SNAPSHOT 1.18.22 @@ -99,6 +101,11 @@ annotations ${jetbrains.version} + + cn.axzo.msgcenter + msg-center-api-v2 + ${msg-center-api-v2-version} + From 1143451680b2a36ca423123257507f2aaa9766c3 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 25 Dec 2024 17:47:21 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat(REQ-3282):=20=E8=B0=83=E6=95=B4api?= =?UTF-8?q?=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a308783..32786ce7 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ pom ${revision} + msg-center-api-v2 wx-notices inside-notices msg-center-api @@ -24,7 +25,6 @@ start msg-center-dal msg-center-domain - msg-center-api-v2