From 84268d8a934812c8d82b59f52090b96693c79817 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 18 Mar 2024 15:36:32 +0800 Subject: [PATCH 01/25] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0op-api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nanopart-server/pom.xml | 12 ++ op/op-api/pom.xml | 32 +++++ .../main/java/cn/axzo/nanopart/api/OpApi.java | 110 ++++++++++++++++++ .../config/NanopartApiAutoConfiguration.java | 9 ++ .../api/constant/NanopartConstant.java | 13 +++ .../main/resources/META-INF/spring.factories | 2 + op/op-server/pom.xml | 45 +++++++ .../controller/OpMessageConfigController.java | 33 ++++++ .../cn/axzo/op/domain/OpMessageConfig.java | 100 ++++++++++++++++ .../axzo/op/mapper/OpMessageConfigMapper.java | 9 ++ .../op/service/OpMessageConfigService.java | 57 +++++++++ .../impl/OpMessageConfigServiceImpl.java | 26 +++++ .../src/test/resources/mysql/schema.sql | 25 ++++ op/pom.xml | 25 ++++ pom.xml | 1 + 15 files changed, 499 insertions(+) create mode 100644 op/op-api/pom.xml create mode 100644 op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java create mode 100644 op/op-api/src/main/java/cn/axzo/nanopart/api/config/NanopartApiAutoConfiguration.java create mode 100644 op/op-api/src/main/java/cn/axzo/nanopart/api/constant/NanopartConstant.java create mode 100644 op/op-api/src/main/resources/META-INF/spring.factories create mode 100644 op/op-server/pom.xml create mode 100644 op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java create mode 100644 op/op-server/src/main/java/cn/axzo/op/domain/OpMessageConfig.java create mode 100644 op/op-server/src/main/java/cn/axzo/op/mapper/OpMessageConfigMapper.java create mode 100644 op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java create mode 100644 op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java create mode 100644 op/op-server/src/test/resources/mysql/schema.sql create mode 100644 op/pom.xml diff --git a/nanopart-server/pom.xml b/nanopart-server/pom.xml index 2b2f9b27..f2210aca 100644 --- a/nanopart-server/pom.xml +++ b/nanopart-server/pom.xml @@ -96,6 +96,18 @@ black-list-service 2.0.0-SNAPSHOT + + + cn.axzo.nanopart + op-api + 2.0.0-SNAPSHOT + + + + cn.axzo.nanopart + op-server + 2.0.0-SNAPSHOT + diff --git a/op/op-api/pom.xml b/op/op-api/pom.xml new file mode 100644 index 00000000..ce89d3c9 --- /dev/null +++ b/op/op-api/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + cn.axzo.nanopart + op + ${revision} + ../pom.xml + + + op-api + jar + op-api + + + + org.springframework.cloud + spring-cloud-openfeign-core + + + cn.axzo.framework + axzo-common-domain + + + + cn.axzo.basics + basics-common + + + diff --git a/op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java b/op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java new file mode 100644 index 00000000..53494837 --- /dev/null +++ b/op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java @@ -0,0 +1,110 @@ +package cn.axzo.nanopart.api; + +import cn.axzo.framework.domain.web.result.ApiPageResult; +import cn.axzo.pokonyan.dao.page.IPageParam; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.Date; +import java.util.List; + +@FeignClient(name = "nanopart", url = "http://nanopart:8080") +public interface OpApi { + + @PostMapping("/api/op-message-config/page") + ApiPageResult page(@RequestBody PageOpMessageConfigReq req); + + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class ListOpMessageConfigReq { + + private List ids; + + private Date planStartTimeLE; + + private String status; + } + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class PageOpMessageConfigReq extends ListOpMessageConfigReq implements IPageParam { + Integer pageNumber; + + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + List sort; + } + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + class OpMessageConfigResp { + private Long id; + + /** + * im-center服务im_message_task的id + */ + private Long imMessageTaskId; + + /** + * 消息名字 + */ + private String name; + + /** + * 发送者的三方平台账号id + */ + private String sendImAccount; + + /** + * 消息接收配置 + */ + private JSONObject receiveData; + + private String status; + + private String title; + + private String content; + + private String contentType; + + @TableField(value = "cover_img") + private String coverImg; + + private JSONObject jumpData; + + private JSONObject pushData; + + private JSONObject ext; + + private Date planStartTime; + + private Date startedTime; + + private Date finishedTime; + + private Integer isDelete; + + private Date createAt; + + private Date updateAt; + } +} diff --git a/op/op-api/src/main/java/cn/axzo/nanopart/api/config/NanopartApiAutoConfiguration.java b/op/op-api/src/main/java/cn/axzo/nanopart/api/config/NanopartApiAutoConfiguration.java new file mode 100644 index 00000000..816d5e34 --- /dev/null +++ b/op/op-api/src/main/java/cn/axzo/nanopart/api/config/NanopartApiAutoConfiguration.java @@ -0,0 +1,9 @@ +package cn.axzo.nanopart.api.config; + +import cn.axzo.nanopart.api.constant.NanopartConstant; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@EnableFeignClients(NanopartConstant.BASIC_FEIGN_PACKAGE) +public class NanopartApiAutoConfiguration { + +} diff --git a/op/op-api/src/main/java/cn/axzo/nanopart/api/constant/NanopartConstant.java b/op/op-api/src/main/java/cn/axzo/nanopart/api/constant/NanopartConstant.java new file mode 100644 index 00000000..24a48010 --- /dev/null +++ b/op/op-api/src/main/java/cn/axzo/nanopart/api/constant/NanopartConstant.java @@ -0,0 +1,13 @@ +package cn.axzo.nanopart.api.constant; + +/** + * @author: chenwenjian + * @date: 2023/8/14 9:38 + * @description: + * @modifiedBy: + * @version: 1.0 + */ +public class NanopartConstant { + + public static final String BASIC_FEIGN_PACKAGE = "cn.axzo.nanopart.api"; +} \ No newline at end of file diff --git a/op/op-api/src/main/resources/META-INF/spring.factories b/op/op-api/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..bf796ec6 --- /dev/null +++ b/op/op-api/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +cn.axzo.nanopart.api.config.NanopartApiAutoConfiguration \ No newline at end of file diff --git a/op/op-server/pom.xml b/op/op-server/pom.xml new file mode 100644 index 00000000..22770c3f --- /dev/null +++ b/op/op-server/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + + cn.axzo.nanopart + op + ${revision} + ../pom.xml + + + op-server + jar + + op-server + + + + + cn.axzo.framework + axzo-mybatisplus-spring-boot-starter + + + + com.alibaba + druid-spring-boot-starter + + + cn.axzo.basics + basics-common + + + cn.axzo.nanopart + op-api + 2.0.0-SNAPSHOT + + + org.springframework.cloud + spring-cloud-context + + + cn.axzo.pokonyan + pokonyan + + + \ No newline at end of file diff --git a/op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java new file mode 100644 index 00000000..7a26f031 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java @@ -0,0 +1,33 @@ +package cn.axzo.op.controller; + +import cn.axzo.framework.domain.web.result.ApiPageResult; +import cn.axzo.nanopart.api.OpApi; +import cn.axzo.op.domain.OpMessageConfig; +import cn.axzo.op.service.OpMessageConfigService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class OpMessageConfigController implements OpApi { + + @Autowired + private OpMessageConfigService opMessageConfigService; + + @Override + public ApiPageResult page(PageOpMessageConfigReq param) { + OpMessageConfigService.PageOpMessageConfigParam pageOpMessageConfigParam = OpMessageConfigService.PageOpMessageConfigParam.builder().build(); + BeanUtils.copyProperties(param, pageOpMessageConfigParam); + + Page page = opMessageConfigService.page(pageOpMessageConfigParam); + + return ApiPageResult.ok(page.convert(record -> { + OpMessageConfigResp opMessageConfigResp = OpMessageConfigResp.builder().build(); + BeanUtils.copyProperties(record, opMessageConfigResp); + return opMessageConfigResp; + })); + } + + +} diff --git a/op/op-server/src/main/java/cn/axzo/op/domain/OpMessageConfig.java b/op/op-server/src/main/java/cn/axzo/op/domain/OpMessageConfig.java new file mode 100644 index 00000000..939b6f60 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/op/domain/OpMessageConfig.java @@ -0,0 +1,100 @@ +package cn.axzo.op.domain; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; + +import java.util.Date; + +@Data +@SuperBuilder +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "`op_message_config`", autoResultMap = true) +public class OpMessageConfig { + + @TableId(type = IdType.AUTO) + private Long id; + + /** + * im-center服务im_message_task的id + */ + @TableField(value = "im_message_task_id") + private Long imMessageTaskId; + + /** + * 消息名字 + */ + @TableField(value = "name") + private String name; + + /** + * 发送者的三方平台账号id + */ + @TableField(value = "send_im_account") + private String sendImAccount; + + /** + * 消息接收配置 + */ + @TableField(typeHandler = FastjsonTypeHandler.class) + private JSONObject receiveData; + + private Status status; + + @TableField(value = "title") + private String title; + + @TableField(value = "content") + private String content; + + @TableField(value = "content_type") + private String contentType; + + @TableField(value = "cover_img") + private String coverImg; + + @TableField(typeHandler = FastjsonTypeHandler.class) + private JSONObject jumpData; + + @TableField(typeHandler = FastjsonTypeHandler.class) + private JSONObject pushData; + + @TableField(typeHandler = FastjsonTypeHandler.class) + private JSONObject ext; + + @TableField + private Date planStartTime; + + @TableField + private Date startedTime; + + @TableField + private Date finishedTime; + + @TableField + private Integer isDelete; + + @TableField + private Date createAt; + + @TableField + private Date updateAt; + + public enum Status { + DRAFT, + PENDING, + RUNNING, + COMPLETED, + ; + } +} diff --git a/op/op-server/src/main/java/cn/axzo/op/mapper/OpMessageConfigMapper.java b/op/op-server/src/main/java/cn/axzo/op/mapper/OpMessageConfigMapper.java new file mode 100644 index 00000000..abd0d8ba --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/op/mapper/OpMessageConfigMapper.java @@ -0,0 +1,9 @@ +package cn.axzo.op.mapper; + +import cn.axzo.op.domain.OpMessageConfig; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springframework.stereotype.Repository; + +@Repository +public interface OpMessageConfigMapper extends BaseMapper { +} diff --git a/op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java new file mode 100644 index 00000000..f0237771 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java @@ -0,0 +1,57 @@ +package cn.axzo.op.service; + +import cn.axzo.nanopart.api.OpApi; +import cn.axzo.op.domain.OpMessageConfig; +import cn.axzo.pokonyan.dao.page.IPageParam; +import cn.axzo.pokonyan.dao.wrapper.CriteriaField; +import cn.axzo.pokonyan.dao.wrapper.Operator; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.lang.annotation.Native; +import java.util.Date; +import java.util.List; + +public interface OpMessageConfigService extends IService { + + Page page(PageOpMessageConfigParam param); + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class ListOpMessageConfigParam { + + @CriteriaField(field = "id", operator = Operator.IN) + private List ids; + + @CriteriaField(field = "planStartTime", operator = Operator.LE) + private Date planStartTimeLE; + + @CriteriaField(field = "status", operator = Operator.EQ) + private OpMessageConfig.Status status; + } + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class PageOpMessageConfigParam extends ListOpMessageConfigParam implements IPageParam { + @CriteriaField(ignore = true) + Integer pageNumber; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; + } + +} diff --git a/op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java b/op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java new file mode 100644 index 00000000..ebcba4e6 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java @@ -0,0 +1,26 @@ +package cn.axzo.op.service.impl; + +import cn.axzo.op.domain.OpMessageConfig; +import cn.axzo.op.mapper.OpMessageConfigMapper; +import cn.axzo.op.service.OpMessageConfigService; +import cn.axzo.pokonyan.dao.converter.PageConverter; +import cn.axzo.pokonyan.dao.mysql.QueryWrapperHelper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class OpMessageConfigServiceImpl extends ServiceImpl + implements OpMessageConfigService { + + @Override + public Page page(PageOpMessageConfigParam param) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, OpMessageConfig.class); + wrapper.eq("is_delete", 0); + + return this.page(PageConverter.convertToMybatis(param, OpMessageConfig.class), wrapper); + } +} diff --git a/op/op-server/src/test/resources/mysql/schema.sql b/op/op-server/src/test/resources/mysql/schema.sql new file mode 100644 index 00000000..e768549c --- /dev/null +++ b/op/op-server/src/test/resources/mysql/schema.sql @@ -0,0 +1,25 @@ + +CREATE TABLE IF NOT EXISTS op_message_config +( + id bigint auto_increment comment '主键', + im_message_task_id bigint null comment 'im-center服务im_message_task的id', + `name` varchar(50) not null comment '消息名字', + send_im_account varchar(100) not null comment '发送者的三方平台账号id', + receive_data json not null comment '消息接收配置', + status varchar(32) not null default 'DRAFT' comment '消息状态:DRAFT、PENDING、RUNNING、COMPLETED', + title varchar(128) not null default '' comment '消息标题', + content varchar(512) not null default '' comment '消息内容', + content_type varchar(32) not null comment '消息形式:IMAGE_TEXT_SAMPLE', + cover_img varchar(512) not null default '' comment '消息封面大图', + jump_data json comment '跳转配置', + push_data json comment 'push配置', + ext varchar(1024) not null default '{}' COMMENT '其它额外信息', + plan_start_time DATETIME(3) not null comment '任务计划开始时间,时间大于改时间会对未完成的任务进行执行操作', + started_time DATETIME(3) null comment '实际开始时间', + finished_time DATETIME(3) null comment '实际完成时间', + is_delete tinyint default 0 not null comment '未删除0,删除1', + create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间', + update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间', + PRIMARY KEY (`id`) + ) ENGINE = InnoDB + DEFAULT CHARSET = utf8 comment '运营消息配置'; \ No newline at end of file diff --git a/op/pom.xml b/op/pom.xml new file mode 100644 index 00000000..8ec4c801 --- /dev/null +++ b/op/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + + cn.axzo.nanopart + nanopart + ${revision} + ../pom.xml + + + op + pom + + op + + + op-api + op-server + + + + + + + diff --git a/pom.xml b/pom.xml index 964c6818..783f4ea1 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ nanopart-server config job + op From 1e1b5a25db9cfa05de1f4fccc4799e83dcc1edf9 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 19 Mar 2024 16:40:43 +0800 Subject: [PATCH 02/25] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=BF=90?= =?UTF-8?q?=E8=90=A5=E6=B6=88=E6=81=AF=E7=9A=84=E5=A2=9E=E5=88=A0=E6=94=B9?= =?UTF-8?q?=E6=9F=A5=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nanopart-server/pom.xml | 10 + .../cn/axzo/nanopart/NanopartApplication.java | 2 +- .../cn/axzo/nanopart/config/FeignConfig.java | 138 +++++++++ op/README.md | 1 + op/RELEASE.md | 2 + op/op-api/pom.xml | 12 +- .../main/java/cn/axzo/nanopart/api/OpApi.java | 110 -------- .../cn/axzo/op/api/OpMessageConfigApi.java | 265 ++++++++++++++++++ .../config/NanopartApiAutoConfiguration.java | 4 +- .../api/constant/NanopartConstant.java | 4 +- op/op-server/pom.xml | 61 +++- .../nanopart/server/config/BizResultCode.java | 18 ++ .../controller/OpMessageConfigController.java | 75 +++++ .../server}/domain/OpMessageConfig.java | 40 ++- .../server}/mapper/OpMessageConfigMapper.java | 4 +- .../service/OpMessageConfigService.java | 232 +++++++++++++++ .../impl/OpMessageConfigServiceImpl.java | 142 ++++++++++ .../controller/OpMessageConfigController.java | 33 --- .../op/service/OpMessageConfigService.java | 57 ---- .../impl/OpMessageConfigServiceImpl.java | 26 -- .../src/test/resources/mysql/schema.sql | 7 +- op/pom.xml | 89 +++++- 22 files changed, 1076 insertions(+), 256 deletions(-) create mode 100644 nanopart-server/src/main/java/cn/axzo/nanopart/config/FeignConfig.java create mode 100644 op/README.md create mode 100644 op/RELEASE.md delete mode 100644 op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java create mode 100644 op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java rename op/op-api/src/main/java/cn/axzo/{nanopart => op}/api/config/NanopartApiAutoConfiguration.java (64%) rename op/op-api/src/main/java/cn/axzo/{nanopart => op}/api/constant/NanopartConstant.java (56%) create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java rename op/op-server/src/main/java/cn/axzo/{op => nanopart/server}/domain/OpMessageConfig.java (72%) rename op/op-server/src/main/java/cn/axzo/{op => nanopart/server}/mapper/OpMessageConfigMapper.java (67%) create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java delete mode 100644 op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java delete mode 100644 op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java delete mode 100644 op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java diff --git a/nanopart-server/pom.xml b/nanopart-server/pom.xml index f2210aca..a49b945d 100644 --- a/nanopart-server/pom.xml +++ b/nanopart-server/pom.xml @@ -108,6 +108,16 @@ op-server 2.0.0-SNAPSHOT + + + cn.axzo.im.center + im-center-api + + + + cn.axzo.basics + basics-profiles-api + diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java b/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java index 8cf18f79..21e1ae73 100644 --- a/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java +++ b/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy; @MapperScan(value = {"cn.axzo.**.mapper"}) @SpringBootApplication @EnableFeignClients(basePackages = { - "cn.axzo.nanopart.api" + "cn.axzo" }) @EnableAspectJAutoProxy() public class NanopartApplication { diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/config/FeignConfig.java b/nanopart-server/src/main/java/cn/axzo/nanopart/config/FeignConfig.java new file mode 100644 index 00000000..dbb23e00 --- /dev/null +++ b/nanopart-server/src/main/java/cn/axzo/nanopart/config/FeignConfig.java @@ -0,0 +1,138 @@ +package cn.axzo.nanopart.config; + +import cn.azxo.framework.common.constatns.Constants; +import cn.hutool.core.util.ReflectUtil; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import feign.Target.HardCodedTarget; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Objects; + +/** + * @author liuyang + * @date 2020/10/24 + **/ +@Component +@Slf4j +@Profile({"dev", "test", "local", "pre"}) +public class FeignConfig implements RequestInterceptor, EnvironmentAware { + private Environment environment; + @Value("${maokaiEnvUrl:http://dev-app.axzo.cn/maokai}") + private String maokaiEnvUrl; + @Value("${apolloEnvUrl:http://dev-app.axzo.cn/apollo}") + private String apolloEnvUrl; + @Value("${mnsEnvUrl:http://dev-app.axzo.cn/mns}") + private String mnsEnvUrl; + @Value("${pudgeEnvUrl:http://dev-app.axzo.cn/pudge}") + private String pudgeEnvUrl; + @Value("${outmanEnvUrl:http://dev-app.axzo.cn/outman}") + private String outmanEnvUrl; + @Value("${thronesEnvUrl:http://dev-app.axzo.cn/thrones}") + private String thronesEnvUrl; + @Value("${workspaceEnvUrl:http://dev-app.axzo.cn/workspace}") + private String workspaceEnvUrl; + @Value("${thirdPartUrl:http://dev-app.axzo.cn/thirdParty}") + private String thirdPartUrl; + @Value("${nanopartUrl:http://dev-app.axzo.cn/nanopart}") + private String nanopartUrl; + @Value("${tyrEnvUrl:http://dev-app.axzo.cn/tyr}") + private String tyrEnvUrl; + @Value("${plutoEnvUrl:http://dev-app.axzo.cn/pluto}") + private String plutoUrl; + @Value("${sennaEnvUrl:http://dev-app.axzo.cn/senna}") + private String sennaEnvUrl; + @Value("${workflowEngineEnvUrl:http://dev-app.axzo.cn/workflow-engine}") + private String workflowEngineEnvUrl; + @Value("${msgCenterEngineEnvUrl:http://dev-app.axzo.cn/msg-center}") + private String msgCenterEngineEnvUrl; + @Value("${imCenterEnvUrl:http://dev-app.axzo.cn/im-center}") + private String imCenterEnvUrl; + @Value("${msgCenterEngineEnvUrl:http://dev-app.axzo.cn/braum}") + private String braumEnvUrl; + @Value("${labourEnvUrl:http://dev-app.axzo.cn/labour}") + private String labourEvnUrl; + @Value("${epicEnvUrl:http://dev-app.axzo.cn/epic}") + private String epicEnvUrl; + @Value("${karmaEnvUrl:http://dev-app.axzo.cn/karma}") + private String karmaEnvUrl; + @Value("${dataCollectionUrl:http://dev-app.axzo.cn/dataCollection}") + private String dataCollectionUrl; + @Value("${attendanceUrl:http://dev-app.axzo.cn/attendance}") + private String attendanceApi; + private static String POD_NAMESPACE; + + static { + Map env = System.getenv(); + if (env != null) { + POD_NAMESPACE = env.get("MY_POD_NAMESPACE"); + } + log.info("init FeignConfig, POD_NAMESPACE value is {}", POD_NAMESPACE); + } + + @SneakyThrows + @Override + public void apply(RequestTemplate requestTemplate) { + if (POD_NAMESPACE == null) { + HardCodedTarget target = (HardCodedTarget) requestTemplate.feignTarget(); + String url = requestTemplate.feignTarget().url(); + // 如需修改微服务地址,建议通过外部化参数来调整 + url = url.replace("http://maokai:8080", maokaiEnvUrl); + url = url.replace("http://apollo:11000", apolloEnvUrl); + url = url.replace("http://mns:8989", mnsEnvUrl); + url = url.replace("http://pudge:10099", pudgeEnvUrl); + url = url.replace("http://outman:8989", outmanEnvUrl); + url = url.replace("http://thrones", thronesEnvUrl); + url = url.replace("http://workspace:8080", workspaceEnvUrl); + url = url.replace("http://third-party:11000", thirdPartUrl); + url = url.replace("http://nanopart:8080", nanopartUrl); + url = url.replace("http://tyr:8080", tyrEnvUrl); + url = url.replace("http://pluto:8080", plutoUrl); + url = url.replace("http://senna:8080", sennaEnvUrl); + url = url.replace("http://workflow-engine:8080", workflowEngineEnvUrl); + url = url.replace("http://msg-center:8080", msgCenterEngineEnvUrl); + url = url.replace("http://im-center:8080", imCenterEnvUrl); + url = url.replace("http://braum:8080", braumEnvUrl); + url = url.replace("http://labour:8080", labourEvnUrl); + url = url.replace("http://epic:8080", epicEnvUrl); + url = url.replace("http://karma:8080", karmaEnvUrl); + url = url.replace("http://data-collection:21200", dataCollectionUrl); + url = url.replace("http://attendance:8080", attendanceApi); + String profile = environment.getProperty("spring.profiles.active"); + if(Objects.equals(profile, "test") && url.contains("dev-app.axzo.cn")) { + url = url.replace("dev-app", "test-api"); + } + if(Objects.equals(profile, "pre") && url.contains("dev-app.axzo.cn")) { + url = url.replace("dev-app", "pre-api"); + } + if(Objects.equals(profile, "live") && url.contains("dev-app.axzo.cn")) { + url = url.replace("dev-app", "live-api"); + } + requestTemplate.target(url); + Field field = ReflectUtil.getField(target.getClass(), "url"); + field.setAccessible(true); + field.set(target, url); + } + requestTemplate.header(Constants.CTX_LOG_ID_MDC, MDC.get(Constants.CTX_LOG_ID_MDC)); + requestTemplate.header("X-SERVER-NAME", environment.getProperty("spring.application.name")); + } + + /** + * Set the {@code Environment} that this component runs in. + * + * @param environment + */ + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } +} diff --git a/op/README.md b/op/README.md new file mode 100644 index 00000000..5fe9c670 --- /dev/null +++ b/op/README.md @@ -0,0 +1 @@ +# 项目介绍 \ No newline at end of file diff --git a/op/RELEASE.md b/op/RELEASE.md new file mode 100644 index 00000000..a033ae0c --- /dev/null +++ b/op/RELEASE.md @@ -0,0 +1,2 @@ +# 发布记录 + diff --git a/op/op-api/pom.xml b/op/op-api/pom.xml index ce89d3c9..de4b0e10 100644 --- a/op/op-api/pom.xml +++ b/op/op-api/pom.xml @@ -1,11 +1,11 @@ - 4.0.0 + - cn.axzo.nanopart op + cn.axzo.nanopart ${revision} ../pom.xml @@ -28,5 +28,11 @@ cn.axzo.basics basics-common + + + cn.axzo.basics + basics-profiles-api + + diff --git a/op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java b/op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java deleted file mode 100644 index 53494837..00000000 --- a/op/op-api/src/main/java/cn/axzo/nanopart/api/OpApi.java +++ /dev/null @@ -1,110 +0,0 @@ -package cn.axzo.nanopart.api; - -import cn.axzo.framework.domain.web.result.ApiPageResult; -import cn.axzo.pokonyan.dao.page.IPageParam; -import com.alibaba.fastjson.JSONObject; -import com.baomidou.mybatisplus.annotation.TableField; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; - -import java.util.Date; -import java.util.List; - -@FeignClient(name = "nanopart", url = "http://nanopart:8080") -public interface OpApi { - - @PostMapping("/api/op-message-config/page") - ApiPageResult page(@RequestBody PageOpMessageConfigReq req); - - - @SuperBuilder - @Data - @NoArgsConstructor - @AllArgsConstructor - class ListOpMessageConfigReq { - - private List ids; - - private Date planStartTimeLE; - - private String status; - } - - @SuperBuilder - @Data - @NoArgsConstructor - @AllArgsConstructor - class PageOpMessageConfigReq extends ListOpMessageConfigReq implements IPageParam { - Integer pageNumber; - - Integer pageSize; - - /** - * 排序:使用示例,createTime__DESC - */ - List sort; - } - - @Data - @Builder - @AllArgsConstructor - @NoArgsConstructor - class OpMessageConfigResp { - private Long id; - - /** - * im-center服务im_message_task的id - */ - private Long imMessageTaskId; - - /** - * 消息名字 - */ - private String name; - - /** - * 发送者的三方平台账号id - */ - private String sendImAccount; - - /** - * 消息接收配置 - */ - private JSONObject receiveData; - - private String status; - - private String title; - - private String content; - - private String contentType; - - @TableField(value = "cover_img") - private String coverImg; - - private JSONObject jumpData; - - private JSONObject pushData; - - private JSONObject ext; - - private Date planStartTime; - - private Date startedTime; - - private Date finishedTime; - - private Integer isDelete; - - private Date createAt; - - private Date updateAt; - } -} diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java new file mode 100644 index 00000000..75bc7024 --- /dev/null +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -0,0 +1,265 @@ +package cn.axzo.op.api; + +import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; +import cn.axzo.framework.domain.web.result.ApiPageResult; +import cn.axzo.framework.domain.web.result.ApiResult; +import com.alibaba.fastjson.JSONObject; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Date; +import java.util.List; + +@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}") +public interface OpMessageConfigApi { + + @PostMapping("/api/op-message-config/page") + ApiPageResult page(@RequestBody PageOpMessageConfigReq req); + + @PostMapping("/api/op-message-config/create") + ApiResult create(@Valid @RequestBody CreateOpMessageConfigParam req); + + @PostMapping("/api/op-message-config/delete") + ApiResult delete(@Valid @RequestBody DeleteOpMessageConfigParam param); + + @PostMapping("/api/op-message-config/update") + ApiResult update(@Valid @RequestBody UpdateOpMessageConfigParam param); + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class UpdateOpMessageConfigParam { + + @NotNull(message = "id不能为空") + private Long id; + + private String name; + + private String sendImAccount; + + private JSONObject receiveData; + + private String status; + + private String title; + + private String content; + + private String contentType; + + private String coverImg; + + private JSONObject jumpData; + + private JSONObject pushData; + + private JSONObject ext; + + private Date planStartTime; + + @NotNull(message = "updatePersonId不能为空") + private Long updatePersonId; + } + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class DeleteOpMessageConfigParam { + + @NotNull(message = "id不能为空") + private Long id; + + @NotNull(message = "deletePersonId不能为空") + private Long deletePersonId; + } + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class CreateOpMessageConfigParam { + private String name; + + private String sendImAccount; + + private JSONObject receiveData; + + private String status; + + private String title; + + private String content; + + private String contentType; + + private String coverImg; + + private JSONObject jumpData; + + private JSONObject pushData; + + private JSONObject ext; + + private Date planStartTime; + + @NotNull(message = "createPersonId不能为空") + private Long createPersonId; + } + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class ListOpMessageConfigReq { + + private List ids; + + private Date planStartTimeLE; + + private List statuses; + + private String nameLike; + + private String sendImAccount; + + private String contentType; + + /** + * 返回发送的信息: + * IM机器人账号:返回头像、名字等信息 + * 账号有机器人和系统人员信息,查询的接口不同 + */ + private boolean needSendUserInfo; + + /** + * 返回创建人的信息 + */ + private boolean needCreatePersonInfo; + } + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class PageOpMessageConfigReq extends ListOpMessageConfigReq { + Integer pageNumber; + + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + List sort; + } + + @Data + @SuperBuilder + @AllArgsConstructor + @NoArgsConstructor + class OpMessageConfigResp extends OpMessageConfigBaseResp { + private SendUserInfo sendUserInfo; + + private PersonProfileDto createPersonProfile; + } + @Data + @SuperBuilder + @AllArgsConstructor + @NoArgsConstructor + class OpMessageConfigBaseResp { + private Long id; + + /** + * im-center服务im_message_task的id + */ + private Long imMessageTaskId; + + /** + * 消息名字 + */ + private String name; + + /** + * 发送者的三方平台账号id + */ + private String sendImAccount; + + /** + * 消息接收配置 + */ + private JSONObject receiveData; + + private String status; + + private String title; + + private String content; + + private String contentType; + + private String coverImg; + + private JSONObject jumpData; + + private JSONObject pushData; + + private JSONObject ext; + + private Date planStartTime; + + private Date startedTime; + + private Date finishedTime; + + private Integer isDelete; + + private Date createAt; + + private Date updateAt; + + private Long createPersonId; + + /** + * 删除人id + */ + private Long deletePersonId; + + /** + * 更新人id + */ + private Long updatePersonId; + } + + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class SendUserInfo { + + /** + * im账号 + */ + private String imAccount; + + /** + * 昵称 + */ + private String nickName; + + + /** + * 头像 + */ + private String headImageUrl; + } +} diff --git a/op/op-api/src/main/java/cn/axzo/nanopart/api/config/NanopartApiAutoConfiguration.java b/op/op-api/src/main/java/cn/axzo/op/api/config/NanopartApiAutoConfiguration.java similarity index 64% rename from op/op-api/src/main/java/cn/axzo/nanopart/api/config/NanopartApiAutoConfiguration.java rename to op/op-api/src/main/java/cn/axzo/op/api/config/NanopartApiAutoConfiguration.java index 816d5e34..180299f5 100644 --- a/op/op-api/src/main/java/cn/axzo/nanopart/api/config/NanopartApiAutoConfiguration.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/config/NanopartApiAutoConfiguration.java @@ -1,6 +1,6 @@ -package cn.axzo.nanopart.api.config; +package cn.axzo.op.api.config; -import cn.axzo.nanopart.api.constant.NanopartConstant; +import cn.axzo.op.api.constant.NanopartConstant; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableFeignClients(NanopartConstant.BASIC_FEIGN_PACKAGE) diff --git a/op/op-api/src/main/java/cn/axzo/nanopart/api/constant/NanopartConstant.java b/op/op-api/src/main/java/cn/axzo/op/api/constant/NanopartConstant.java similarity index 56% rename from op/op-api/src/main/java/cn/axzo/nanopart/api/constant/NanopartConstant.java rename to op/op-api/src/main/java/cn/axzo/op/api/constant/NanopartConstant.java index 24a48010..9abc2e18 100644 --- a/op/op-api/src/main/java/cn/axzo/nanopart/api/constant/NanopartConstant.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/constant/NanopartConstant.java @@ -1,4 +1,4 @@ -package cn.axzo.nanopart.api.constant; +package cn.axzo.op.api.constant; /** * @author: chenwenjian @@ -9,5 +9,5 @@ package cn.axzo.nanopart.api.constant; */ public class NanopartConstant { - public static final String BASIC_FEIGN_PACKAGE = "cn.axzo.nanopart.api"; + public static final String BASIC_FEIGN_PACKAGE = "cn.axzo"; } \ No newline at end of file diff --git a/op/op-server/pom.xml b/op/op-server/pom.xml index 22770c3f..3d290869 100644 --- a/op/op-server/pom.xml +++ b/op/op-server/pom.xml @@ -1,12 +1,12 @@ - - 4.0.0 + + cn.axzo.nanopart op ${revision} ../pom.xml + 4.0.0 op-server jar @@ -14,32 +14,71 @@ op-server + + cn.axzo.framework + axzo-web-spring-boot-starter + + + cn.axzo.framework + axzo-spring-cloud-starter + + + cn.axzo.framework + axzo-consumer-spring-cloud-starter + + + cn.axzo.framework + axzo-processor-spring-boot-starter + cn.axzo.framework axzo-mybatisplus-spring-boot-starter - + - com.alibaba - druid-spring-boot-starter + cn.axzo.framework + axzo-swagger-yapi-spring-boot-starter + + mysql + mysql-connector-java + + + cn.hutool + hutool-all + + cn.axzo.basics basics-common + + + cn.axzo.framework + axzo-logger-spring-boot-starter + + cn.axzo.nanopart op-api 2.0.0-SNAPSHOT - - org.springframework.cloud - spring-cloud-context - + cn.axzo.pokonyan pokonyan + + + cn.axzo.im.center + im-center-api + + + + cn.axzo.basics + basics-profiles-api + + - \ No newline at end of file + diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java new file mode 100644 index 00000000..bcfd7325 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java @@ -0,0 +1,18 @@ +package cn.axzo.nanopart.server.config; + +import cn.axzo.pokonyan.exception.ResultCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum BizResultCode implements ResultCode { + + OP_MESSAGE_CONFIG_NOT_FOUND("100", "运营消息配置不存在"), + DELETE_OP_MESSAGE_CONFIG_STATUS_ERROR("101", "删除运营消息配置失败,状态异常"), + UPDATE_OP_MESSAGE_CONFIG_STATUS_ERROR("102", "更新运营消息配置失败,状态异常"),; + + + private String errorCode; + private String errorMessage; +} diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java new file mode 100644 index 00000000..969c61b0 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java @@ -0,0 +1,75 @@ +package cn.axzo.nanopart.server.controller; + +import cn.axzo.framework.domain.web.result.ApiPageResult; +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.nanopart.server.domain.OpMessageConfig; +import cn.axzo.nanopart.server.service.OpMessageConfigService; +import cn.axzo.op.api.OpMessageConfigApi; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class OpMessageConfigController implements OpMessageConfigApi { + + + @Autowired + private OpMessageConfigService opMessageConfigService; + + @Override + public ApiPageResult page(PageOpMessageConfigReq param) { + OpMessageConfigService.PageOpMessageConfigParam pageOpMessageConfigParam = OpMessageConfigService.PageOpMessageConfigParam.builder().build(); + BeanUtils.copyProperties(param, pageOpMessageConfigParam); + + Page page = opMessageConfigService.page(pageOpMessageConfigParam); + + return ApiPageResult.ok(page.convert(record -> { + OpMessageConfigResp opMessageConfigResp = OpMessageConfigResp.builder().build(); + BeanUtils.copyProperties(record, opMessageConfigResp); + opMessageConfigResp.setStatus(record.getStatus().name()); + + if (record.getSendUserInfo() != null) { + SendUserInfo sendUserInfo = SendUserInfo.builder().build(); + BeanUtils.copyProperties(record.getSendUserInfo(), sendUserInfo); + opMessageConfigResp.setSendUserInfo(sendUserInfo); + } + + return opMessageConfigResp; + })); + } + + @Override + public ApiResult create(CreateOpMessageConfigParam param) { + OpMessageConfigService.CreateOpMessageConfigParam createOpMessageConfigParam = OpMessageConfigService.CreateOpMessageConfigParam.builder().build(); + BeanUtils.copyProperties(param, createOpMessageConfigParam); + + OpMessageConfig opMessageConfig = opMessageConfigService.create(createOpMessageConfigParam); + + OpMessageConfigBaseResp opMessageConfigResp = OpMessageConfigBaseResp.builder().build();; + BeanUtils.copyProperties(opMessageConfig, opMessageConfigResp); + return ApiResult.ok(opMessageConfigResp); + } + + @Override + public ApiResult delete(DeleteOpMessageConfigParam param) { + OpMessageConfigService.DeleteOpMessageConfigParam deleteOpMessageConfigParam = OpMessageConfigService.DeleteOpMessageConfigParam.builder() + .id(param.getId()) + .deletePersonId(param.getDeletePersonId()) + .build(); + opMessageConfigService.delete(deleteOpMessageConfigParam); + return ApiResult.ok(); + } + + @Override + public ApiResult update(UpdateOpMessageConfigParam param) { + OpMessageConfigService.UpdateOpMessageConfigParam updateOpMessageConfigParam = OpMessageConfigService.UpdateOpMessageConfigParam.builder().build(); + BeanUtils.copyProperties(param, updateOpMessageConfigParam); + + OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); + + OpMessageConfigBaseResp opMessageConfigResp = OpMessageConfigBaseResp.builder().build();; + BeanUtils.copyProperties(opMessageConfig, opMessageConfigResp); + return ApiResult.ok(opMessageConfigResp); + } +} diff --git a/op/op-server/src/main/java/cn/axzo/op/domain/OpMessageConfig.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java similarity index 72% rename from op/op-server/src/main/java/cn/axzo/op/domain/OpMessageConfig.java rename to op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java index 939b6f60..e3ad55b7 100644 --- a/op/op-server/src/main/java/cn/axzo/op/domain/OpMessageConfig.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java @@ -1,4 +1,4 @@ -package cn.axzo.op.domain; +package cn.axzo.nanopart.server.domain; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.IdType; @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import com.google.common.collect.Sets; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -13,6 +14,7 @@ import lombok.experimental.Accessors; import lombok.experimental.SuperBuilder; import java.util.Date; +import java.util.Set; @Data @SuperBuilder @@ -22,6 +24,16 @@ import java.util.Date; @TableName(value = "`op_message_config`", autoResultMap = true) public class OpMessageConfig { + private static final Set CAN_DELETE_STATUSES = Sets.newHashSet( + Status.DRAFT, + Status.PENDING + ); + + private static final Set CAN_UPDATE_STATUSES = Sets.newHashSet( + Status.DRAFT, + Status.PENDING + ); + @TableId(type = IdType.AUTO) private Long id; @@ -90,6 +102,24 @@ public class OpMessageConfig { @TableField private Date updateAt; + /** + * 创建人id + */ + @TableField + private Long createPersonId; + + /** + * 删除人id + */ + @TableField + private Long deletePersonId; + + /** + * 更新人id + */ + @TableField + private Long updatePersonId; + public enum Status { DRAFT, PENDING, @@ -97,4 +127,12 @@ public class OpMessageConfig { COMPLETED, ; } + + public boolean canDelete() { + return CAN_DELETE_STATUSES.contains(this.getStatus()); + } + + public boolean canUpdate() { + return CAN_UPDATE_STATUSES.contains(this.getStatus()); + } } diff --git a/op/op-server/src/main/java/cn/axzo/op/mapper/OpMessageConfigMapper.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/mapper/OpMessageConfigMapper.java similarity index 67% rename from op/op-server/src/main/java/cn/axzo/op/mapper/OpMessageConfigMapper.java rename to op/op-server/src/main/java/cn/axzo/nanopart/server/mapper/OpMessageConfigMapper.java index abd0d8ba..5f65d564 100644 --- a/op/op-server/src/main/java/cn/axzo/op/mapper/OpMessageConfigMapper.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/mapper/OpMessageConfigMapper.java @@ -1,6 +1,6 @@ -package cn.axzo.op.mapper; +package cn.axzo.nanopart.server.mapper; -import cn.axzo.op.domain.OpMessageConfig; +import cn.axzo.nanopart.server.domain.OpMessageConfig; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.springframework.stereotype.Repository; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java new file mode 100644 index 00000000..efebb4ab --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -0,0 +1,232 @@ +package cn.axzo.nanopart.server.service; + +import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; +import cn.axzo.im.center.api.feign.RobotInfoApi; +import cn.axzo.nanopart.server.domain.OpMessageConfig; +import cn.axzo.pokonyan.dao.page.IPageParam; +import cn.axzo.pokonyan.dao.wrapper.CriteriaField; +import cn.axzo.pokonyan.dao.wrapper.Operator; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.beans.BeanUtils; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +public interface OpMessageConfigService extends IService { + + Page page(PageOpMessageConfigParam param); + + OpMessageConfig create(CreateOpMessageConfigParam param); + + OpMessageConfig update(UpdateOpMessageConfigParam param); + + void delete(DeleteOpMessageConfigParam param); + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class DeleteOpMessageConfigParam { + private Long id; + + private Long deletePersonId; + } + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class UpdateOpMessageConfigParam { + + private Long id; + + private String name; + + private String sendImAccount; + + private JSONObject receiveData; + + private String status; + + private String title; + + private String content; + + private String contentType; + + private String coverImg; + + private JSONObject jumpData; + + private JSONObject pushData; + + private JSONObject ext; + + private Date planStartTime; + + private Long updatePersonId; + + public OpMessageConfig to() { + OpMessageConfig opMessageConfig = OpMessageConfig.builder().build(); + BeanUtils.copyProperties(this, opMessageConfig); + return opMessageConfig; + } + } + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class CreateOpMessageConfigParam { + private String name; + + private String sendImAccount; + + private JSONObject receiveData; + + private String status; + + private String title; + + private String content; + + private String contentType; + + private String coverImg; + + private JSONObject jumpData; + + private JSONObject pushData; + + private JSONObject ext; + + private Date planStartTime; + + private Long createPersonId; + + public OpMessageConfig to() { + OpMessageConfig opMessageConfig = OpMessageConfig.builder().build(); + BeanUtils.copyProperties(this, opMessageConfig); + return opMessageConfig; + } + } + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class ListOpMessageConfigParam { + + @CriteriaField(field = "id", operator = Operator.IN) + private List ids; + + @CriteriaField(field = "name", operator = Operator.LIKE) + private String nameLike; + + @CriteriaField(field = "sendImAccount", operator = Operator.EQ) + private String sendImAccount; + + @CriteriaField(field = "planStartTime", operator = Operator.LE) + private Date planStartTimeLE; + + @CriteriaField(field = "status", operator = Operator.IN) + private List statuses; + + @CriteriaField(field = "contentType", operator = Operator.EQ) + private String contentType; + + /** + * 返回发送的信息: + * IM机器人账号:返回头像、名字等信息 + * 账号有机器人和系统人员信息,查询的接口不同 + */ + @CriteriaField(ignore = true) + private boolean needSendUserInfo; + + /** + * 返回创建人的信息 + */ + @CriteriaField(ignore = true) + private boolean needCreatePersonInfo; + } + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class SendUserInfo { + + /** + * im账号 + */ + private String imAccount; + + /** + * 昵称 + */ + private String nickName; + + + /** + * 头像 + */ + private String headImageUrl; + + public static SendUserInfo from(RobotInfoApi.RobotInfoDTO robotInfoDTO) { + return SendUserInfo.builder() + .imAccount(robotInfoDTO.getImAccount()) + .nickName(robotInfoDTO.getNickName()) + .headImageUrl(robotInfoDTO.getHeadImageUrl()) + .build(); + } + } + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class PageOpMessageConfigParam extends ListOpMessageConfigParam implements IPageParam { + @CriteriaField(ignore = true) + Integer pageNumber; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; + } + + @SuperBuilder + @Data + @NoArgsConstructor + @AllArgsConstructor + class OpMessageConfigDTO extends OpMessageConfig { + + private SendUserInfo sendUserInfo; + + private PersonProfileDto createPersonProfile; + + public static OpMessageConfigDTO from(OpMessageConfig opMessageConfig, + Map sendUserInfos, + Map personProfiles) { + OpMessageConfigDTO opMessageConfigDTO = OpMessageConfigDTO.builder().build(); + BeanUtils.copyProperties(opMessageConfig, opMessageConfigDTO); + + opMessageConfigDTO.setSendUserInfo(sendUserInfos.get(opMessageConfigDTO.getSendImAccount())); + + opMessageConfigDTO.setCreatePersonProfile(personProfiles.get(opMessageConfigDTO.getCreatePersonId())); + return opMessageConfigDTO; + } + } +} diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java new file mode 100644 index 00000000..aec620df --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java @@ -0,0 +1,142 @@ +package cn.axzo.nanopart.server.service.impl; + +import cn.axzo.basics.profiles.api.UserProfileServiceApi; +import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; +import cn.axzo.im.center.api.feign.RobotInfoApi; +import cn.axzo.nanopart.server.domain.OpMessageConfig; +import cn.axzo.nanopart.server.mapper.OpMessageConfigMapper; +import cn.axzo.nanopart.server.service.OpMessageConfigService; +import cn.axzo.pokonyan.dao.converter.PageConverter; +import cn.axzo.pokonyan.dao.mysql.QueryWrapperHelper; +import cn.axzo.pokonyan.exception.Aassert; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static cn.axzo.nanopart.server.config.BizResultCode.DELETE_OP_MESSAGE_CONFIG_STATUS_ERROR; +import static cn.axzo.nanopart.server.config.BizResultCode.OP_MESSAGE_CONFIG_NOT_FOUND; +import static cn.axzo.nanopart.server.config.BizResultCode.UPDATE_OP_MESSAGE_CONFIG_STATUS_ERROR; + +@Slf4j +@Service +public class OpMessageConfigServiceImpl extends ServiceImpl + implements OpMessageConfigService { + + @Autowired + private RobotInfoApi robotInfoApi; + @Autowired + private UserProfileServiceApi userProfileServiceApi; + + @Override + public Page page(PageOpMessageConfigParam param) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, OpMessageConfig.class); + wrapper.eq("is_delete", 0); + + Page page = this.page(PageConverter.convertToMybatis(param, OpMessageConfig.class), wrapper); + + Map sendUserInfos = listSendUserInfo(param, page.getRecords()); + + Map personProfiles = listCreatePersonProfile(param, page.getRecords()); + + return PageConverter.convert(page, (record) -> OpMessageConfigDTO.from(record, sendUserInfos, personProfiles)); + } + + @Override + public OpMessageConfig create(CreateOpMessageConfigParam param) { + OpMessageConfig opMessageConfig = param.to(); + this.save(opMessageConfig); + return this.getById(opMessageConfig.getId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public OpMessageConfig update(UpdateOpMessageConfigParam param) { + OpMessageConfig oldOpMessageConfig = getAndLock(param.getId()); + + Aassert.check(oldOpMessageConfig.canUpdate(), UPDATE_OP_MESSAGE_CONFIG_STATUS_ERROR); + + this.updateById(param.to()); + return this.getById(param.getId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(DeleteOpMessageConfigParam param) { + OpMessageConfig oldOpMessageConfig = getAndLock(param.getId()); + Aassert.check(oldOpMessageConfig.canDelete(), DELETE_OP_MESSAGE_CONFIG_STATUS_ERROR); + + // 因为updateById处理的时候,有拦截器过滤掉了isDelete的更新 + this.lambdaUpdate() + .set(OpMessageConfig::getIsDelete, 1) + .set(OpMessageConfig::getDeletePersonId, param.getDeletePersonId()) + .eq(OpMessageConfig::getId, param.getId()) + .update(); + } + + private OpMessageConfig getAndLock(Long id) { + OpMessageConfig oldOpMessageConfig = this.lambdaQuery() + .eq(OpMessageConfig::getId, id) + .last("for update") + .one(); + Aassert.notNull(oldOpMessageConfig, OP_MESSAGE_CONFIG_NOT_FOUND); + return oldOpMessageConfig; + } + + private Map listSendUserInfo(PageOpMessageConfigParam param, + List opMessageConfigs) { + if (CollectionUtils.isEmpty(opMessageConfigs) || BooleanUtils.isNotTrue(param.isNeedSendUserInfo())) { + return Collections.emptyMap(); + } + + List sendImAccounts = opMessageConfigs.stream() + .map(OpMessageConfig::getSendImAccount) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(sendImAccounts)) { + return Collections.emptyMap(); + } + + // 现在发送者只有机器人,所以发送者的头像信息从robotInfoApi中获取 + return robotInfoApi.page(RobotInfoApi.PageRobotInfoParam.builder() + .imAccounts(sendImAccounts) + .build()) + .getData() + .getList() + .stream() + .map(SendUserInfo::from) + .collect(Collectors.toMap(SendUserInfo::getImAccount, Function.identity())); + } + + private Map listCreatePersonProfile(PageOpMessageConfigParam param, + List opMessageConfigs) { + if (CollectionUtils.isEmpty(opMessageConfigs) || BooleanUtils.isNotTrue(param.isNeedCreatePersonInfo())) { + return Collections.emptyMap(); + } + + List createPersonIds = opMessageConfigs.stream() + .map(OpMessageConfig::getCreatePersonId) + .distinct() + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(createPersonIds)) { + return Collections.emptyMap(); + } + + return userProfileServiceApi.postPersonProfiles(createPersonIds).getData() + .stream() + .collect(Collectors.toMap(PersonProfileDto::getId, Function.identity())); + } +} diff --git a/op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java deleted file mode 100644 index 7a26f031..00000000 --- a/op/op-server/src/main/java/cn/axzo/op/controller/OpMessageConfigController.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.axzo.op.controller; - -import cn.axzo.framework.domain.web.result.ApiPageResult; -import cn.axzo.nanopart.api.OpApi; -import cn.axzo.op.domain.OpMessageConfig; -import cn.axzo.op.service.OpMessageConfigService; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class OpMessageConfigController implements OpApi { - - @Autowired - private OpMessageConfigService opMessageConfigService; - - @Override - public ApiPageResult page(PageOpMessageConfigReq param) { - OpMessageConfigService.PageOpMessageConfigParam pageOpMessageConfigParam = OpMessageConfigService.PageOpMessageConfigParam.builder().build(); - BeanUtils.copyProperties(param, pageOpMessageConfigParam); - - Page page = opMessageConfigService.page(pageOpMessageConfigParam); - - return ApiPageResult.ok(page.convert(record -> { - OpMessageConfigResp opMessageConfigResp = OpMessageConfigResp.builder().build(); - BeanUtils.copyProperties(record, opMessageConfigResp); - return opMessageConfigResp; - })); - } - - -} diff --git a/op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java deleted file mode 100644 index f0237771..00000000 --- a/op/op-server/src/main/java/cn/axzo/op/service/OpMessageConfigService.java +++ /dev/null @@ -1,57 +0,0 @@ -package cn.axzo.op.service; - -import cn.axzo.nanopart.api.OpApi; -import cn.axzo.op.domain.OpMessageConfig; -import cn.axzo.pokonyan.dao.page.IPageParam; -import cn.axzo.pokonyan.dao.wrapper.CriteriaField; -import cn.axzo.pokonyan.dao.wrapper.Operator; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.extension.service.IService; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; - -import java.lang.annotation.Native; -import java.util.Date; -import java.util.List; - -public interface OpMessageConfigService extends IService { - - Page page(PageOpMessageConfigParam param); - - @SuperBuilder - @Data - @NoArgsConstructor - @AllArgsConstructor - class ListOpMessageConfigParam { - - @CriteriaField(field = "id", operator = Operator.IN) - private List ids; - - @CriteriaField(field = "planStartTime", operator = Operator.LE) - private Date planStartTimeLE; - - @CriteriaField(field = "status", operator = Operator.EQ) - private OpMessageConfig.Status status; - } - - @SuperBuilder - @Data - @NoArgsConstructor - @AllArgsConstructor - class PageOpMessageConfigParam extends ListOpMessageConfigParam implements IPageParam { - @CriteriaField(ignore = true) - Integer pageNumber; - - @CriteriaField(ignore = true) - Integer pageSize; - - /** - * 排序:使用示例,createTime__DESC - */ - @CriteriaField(ignore = true) - List sort; - } - -} diff --git a/op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java b/op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java deleted file mode 100644 index ebcba4e6..00000000 --- a/op/op-server/src/main/java/cn/axzo/op/service/impl/OpMessageConfigServiceImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.axzo.op.service.impl; - -import cn.axzo.op.domain.OpMessageConfig; -import cn.axzo.op.mapper.OpMessageConfigMapper; -import cn.axzo.op.service.OpMessageConfigService; -import cn.axzo.pokonyan.dao.converter.PageConverter; -import cn.axzo.pokonyan.dao.mysql.QueryWrapperHelper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -@Slf4j -@Service -public class OpMessageConfigServiceImpl extends ServiceImpl - implements OpMessageConfigService { - - @Override - public Page page(PageOpMessageConfigParam param) { - QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, OpMessageConfig.class); - wrapper.eq("is_delete", 0); - - return this.page(PageConverter.convertToMybatis(param, OpMessageConfig.class), wrapper); - } -} diff --git a/op/op-server/src/test/resources/mysql/schema.sql b/op/op-server/src/test/resources/mysql/schema.sql index e768549c..a2383ac5 100644 --- a/op/op-server/src/test/resources/mysql/schema.sql +++ b/op/op-server/src/test/resources/mysql/schema.sql @@ -2,10 +2,10 @@ CREATE TABLE IF NOT EXISTS op_message_config ( id bigint auto_increment comment '主键', - im_message_task_id bigint null comment 'im-center服务im_message_task的id', + im_message_task_id bigint not null default 0 comment 'im-center服务im_message_task的id', `name` varchar(50) not null comment '消息名字', send_im_account varchar(100) not null comment '发送者的三方平台账号id', - receive_data json not null comment '消息接收配置', + receive_data json null comment '消息接收配置', status varchar(32) not null default 'DRAFT' comment '消息状态:DRAFT、PENDING、RUNNING、COMPLETED', title varchar(128) not null default '' comment '消息标题', content varchar(512) not null default '' comment '消息内容', @@ -19,6 +19,9 @@ CREATE TABLE IF NOT EXISTS op_message_config finished_time DATETIME(3) null comment '实际完成时间', is_delete tinyint default 0 not null comment '未删除0,删除1', create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间', + create_person_id bigint not null comment '创建人id', + delete_person_id bigint not null default 0 comment '删除人id', + update_person_id bigint not null default 0 comment '更新人id', update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间', PRIMARY KEY (`id`) ) ENGINE = InnoDB diff --git a/op/pom.xml b/op/pom.xml index 8ec4c801..32479682 100644 --- a/op/pom.xml +++ b/op/pom.xml @@ -1,6 +1,8 @@ + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 + cn.axzo.nanopart nanopart @@ -8,18 +10,93 @@ ../pom.xml + cn.axzo.nanopart op pom - op - - op-api - op-server - + + 2.0.0-SNAPSHOT + 2.0.0-SNAPSHOT + 1.18.22 + 1.4.2.Final + + + + + + + cn.axzo.infra + axzo-bom + ${axzo-bom.version} + pom + import + + + cn.axzo.infra + axzo-dependencies + ${axzo-dependencies.version} + pom + import + + + + + + + org.projectlombok + lombok + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + junit + junit + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + + + + + axzo + axzo repository + https://nexus.axzo.cn/repository/axzo/ + + + + op-server + op-api + From 4f693816d56d9d6f07413c09ff842e6864653161 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 20 Mar 2024 11:10:18 +0800 Subject: [PATCH 03/25] =?UTF-8?q?feat:=20api=E5=A2=9E=E5=8A=A0status?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/axzo/op/api/OpMessageConfigApi.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java index 75bc7024..562cf731 100644 --- a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -48,7 +48,7 @@ public interface OpMessageConfigApi { private JSONObject receiveData; - private String status; + private Status status; private String title; @@ -94,7 +94,7 @@ public interface OpMessageConfigApi { private JSONObject receiveData; - private String status; + private Status status; private String title; @@ -262,4 +262,12 @@ public interface OpMessageConfigApi { */ private String headImageUrl; } + + enum Status { + DRAFT, + PENDING, + RUNNING, + COMPLETED, + ; + } } From f03427455748f3a81a8224b75c611f70acd5a645 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 20 Mar 2024 14:28:46 +0800 Subject: [PATCH 04/25] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0receivePlatform?= =?UTF-8?q?s=E7=9A=84=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/op/api/OpMessageConfigApi.java | 14 ++++++++++++- .../controller/OpMessageConfigController.java | 6 ++++++ .../service/OpMessageConfigService.java | 20 +++++++++++++++++++ .../impl/OpMessageConfigServiceImpl.java | 4 +--- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java index 562cf731..cc9b4e19 100644 --- a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -1,6 +1,5 @@ package cn.axzo.op.api; -import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import com.alibaba.fastjson.JSONObject; @@ -134,6 +133,8 @@ public interface OpMessageConfigApi { private String contentType; + private List receivePlatforms; + /** * 返回发送的信息: * IM机器人账号:返回头像、名字等信息 @@ -171,6 +172,17 @@ public interface OpMessageConfigApi { private PersonProfileDto createPersonProfile; } + + @Data + @SuperBuilder + @AllArgsConstructor + @NoArgsConstructor + class PersonProfileDto { + + private String phone; + private String realName; + } + @Data @SuperBuilder @AllArgsConstructor diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java index 969c61b0..21b31d47 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java @@ -35,6 +35,12 @@ public class OpMessageConfigController implements OpMessageConfigApi { opMessageConfigResp.setSendUserInfo(sendUserInfo); } + if (record.getCreatePersonProfile() != null) { + PersonProfileDto createPersonProfile = PersonProfileDto.builder().build(); + BeanUtils.copyProperties(record.getCreatePersonProfile(), createPersonProfile); + opMessageConfigResp.setCreatePersonProfile(createPersonProfile); + } + return opMessageConfigResp; })); } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index efebb4ab..1ab390c5 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -3,10 +3,12 @@ package cn.axzo.nanopart.server.service; import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; import cn.axzo.im.center.api.feign.RobotInfoApi; import cn.axzo.nanopart.server.domain.OpMessageConfig; +import cn.axzo.pokonyan.dao.mysql.QueryWrapperHelper; import cn.axzo.pokonyan.dao.page.IPageParam; import cn.axzo.pokonyan.dao.wrapper.CriteriaField; import cn.axzo.pokonyan.dao.wrapper.Operator; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import lombok.AllArgsConstructor; @@ -15,10 +17,12 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.springframework.beans.BeanUtils; +import org.springframework.util.CollectionUtils; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public interface OpMessageConfigService extends IService { @@ -143,6 +147,9 @@ public interface OpMessageConfigService extends IService { @CriteriaField(field = "contentType", operator = Operator.EQ) private String contentType; + @CriteriaField(ignore = true) + private List receivePlatforms;; + /** * 返回发送的信息: * IM机器人账号:返回头像、名字等信息 @@ -205,6 +212,19 @@ public interface OpMessageConfigService extends IService { */ @CriteriaField(ignore = true) List sort; + + public QueryWrapper toQueryWrapper() { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(this, OpMessageConfig.class); + wrapper.eq("is_delete", 0); + + if (!CollectionUtils.isEmpty(this.getReceivePlatforms())) { + String sql = this.getReceivePlatforms().stream() + .map(e -> "json_contains(receive_data->'$.platforms', '\"" + e + "\"')") + .collect(Collectors.joining(" or ")); + wrapper.and(e -> e.apply(sql)); + } + return wrapper; + } } @SuperBuilder diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java index aec620df..4dfc398a 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java @@ -7,7 +7,6 @@ import cn.axzo.nanopart.server.domain.OpMessageConfig; import cn.axzo.nanopart.server.mapper.OpMessageConfigMapper; import cn.axzo.nanopart.server.service.OpMessageConfigService; import cn.axzo.pokonyan.dao.converter.PageConverter; -import cn.axzo.pokonyan.dao.mysql.QueryWrapperHelper; import cn.axzo.pokonyan.exception.Aassert; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -42,8 +41,7 @@ public class OpMessageConfigServiceImpl extends ServiceImpl page(PageOpMessageConfigParam param) { - QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, OpMessageConfig.class); - wrapper.eq("is_delete", 0); + QueryWrapper wrapper = param.toQueryWrapper(); Page page = this.page(PageConverter.convertToMybatis(param, OpMessageConfig.class), wrapper); From baabd470c7129e3168a42b117b6f620dcadd4423 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 20 Mar 2024 16:33:47 +0800 Subject: [PATCH 05/25] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=8D=89?= =?UTF-8?q?=E7=A8=BF=E4=BF=9D=E5=AD=98=E6=8F=90=E4=BA=A4=E5=92=8C=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=9C=BA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/op/api/OpMessageConfigApi.java | 67 +++++++++++++++++-- .../nanopart/server/config/BizResultCode.java | 4 +- .../controller/OpMessageConfigController.java | 60 +++++++++++++++-- .../server/domain/OpMessageConfig.java | 28 ++++++++ .../service/OpMessageConfigService.java | 22 ++++-- .../impl/OpMessageConfigServiceImpl.java | 37 +++++++++- .../src/test/resources/mysql/schema.sql | 1 + 7 files changed, 198 insertions(+), 21 deletions(-) diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java index cc9b4e19..2d6608ba 100644 --- a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSONObject; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.springframework.cloud.openfeign.FeignClient; @@ -32,6 +33,12 @@ public interface OpMessageConfigApi { @PostMapping("/api/op-message-config/update") ApiResult update(@Valid @RequestBody UpdateOpMessageConfigParam param); + @PostMapping("/api/op-message-config/draft/save") + ApiResult saveDraft(@Valid @RequestBody SaveDraftOpMessageConfigParam req); + + @PostMapping("/api/op-message-config/draft/submit") + ApiResult submitDraft(@Valid @RequestBody SaveDraftOpMessageConfigParam req); + @Builder @Data @NoArgsConstructor @@ -47,7 +54,7 @@ public interface OpMessageConfigApi { private JSONObject receiveData; - private Status status; + private ActionEnum action; private String title; @@ -65,10 +72,15 @@ public interface OpMessageConfigApi { private Date planStartTime; - @NotNull(message = "updatePersonId不能为空") - private Long updatePersonId; + @NotNull(message = "operatePersonId不能为空") + private Long operatePersonId; } + @Getter + @AllArgsConstructor + enum ActionEnum { + SUBMIT_DRAFT + } @Builder @Data @NoArgsConstructor @@ -78,8 +90,8 @@ public interface OpMessageConfigApi { @NotNull(message = "id不能为空") private Long id; - @NotNull(message = "deletePersonId不能为空") - private Long deletePersonId; + @NotNull(message = "operatePersonId不能为空") + private Long operatePersonId; } @Builder @@ -111,8 +123,8 @@ public interface OpMessageConfigApi { private Date planStartTime; - @NotNull(message = "createPersonId不能为空") - private Long createPersonId; + @NotNull(message = "operatePersonId不能为空") + private Long operatePersonId; } @SuperBuilder @@ -146,6 +158,11 @@ public interface OpMessageConfigApi { * 返回创建人的信息 */ private boolean needCreatePersonInfo; + + /** + * 返回提交审核人的信息 + */ + private boolean needSubmitPersonInfo; } @SuperBuilder @@ -171,6 +188,8 @@ public interface OpMessageConfigApi { private SendUserInfo sendUserInfo; private PersonProfileDto createPersonProfile; + + private PersonProfileDto submitPersonProfile; } @Data @@ -282,4 +301,38 @@ public interface OpMessageConfigApi { COMPLETED, ; } + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class SaveDraftOpMessageConfigParam { + + private Long id; + + private String name; + + private String sendImAccount; + + private JSONObject receiveData; + + private String title; + + private String content; + + private String contentType; + + private String coverImg; + + private JSONObject jumpData; + + private JSONObject pushData; + + private JSONObject ext; + + private Date planStartTime; + + @NotNull(message = "operatePersonId不能为空") + private Long operatePersonId; + } } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java index bcfd7325..542ccbbc 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/config/BizResultCode.java @@ -10,7 +10,9 @@ public enum BizResultCode implements ResultCode { OP_MESSAGE_CONFIG_NOT_FOUND("100", "运营消息配置不存在"), DELETE_OP_MESSAGE_CONFIG_STATUS_ERROR("101", "删除运营消息配置失败,状态异常"), - UPDATE_OP_MESSAGE_CONFIG_STATUS_ERROR("102", "更新运营消息配置失败,状态异常"),; + UPDATE_OP_MESSAGE_CONFIG_STATUS_ERROR("102", "更新运营消息配置失败,状态异常"), + OP_MESSAGE_CONFIG_ID_NOT_NULL("103", "id不能为空"), + OP_MESSAGE_CONFIG_STATUS_ERROR("104", "操作运营消息配置失败,状态异常"),; private String errorCode; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java index 21b31d47..5b942a33 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java @@ -5,11 +5,14 @@ import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.nanopart.server.domain.OpMessageConfig; import cn.axzo.nanopart.server.service.OpMessageConfigService; import cn.axzo.op.api.OpMessageConfigApi; +import cn.axzo.pokonyan.exception.Aassert; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; +import static cn.axzo.nanopart.server.config.BizResultCode.OP_MESSAGE_CONFIG_ID_NOT_NULL; + @RestController public class OpMessageConfigController implements OpMessageConfigApi { @@ -41,6 +44,12 @@ public class OpMessageConfigController implements OpMessageConfigApi { opMessageConfigResp.setCreatePersonProfile(createPersonProfile); } + if (record.getSubmitPersonProfile() != null) { + PersonProfileDto submitPersonProfile = PersonProfileDto.builder().build(); + BeanUtils.copyProperties(record.getSubmitPersonProfile(), submitPersonProfile); + opMessageConfigResp.setCreatePersonProfile(submitPersonProfile); + } + return opMessageConfigResp; })); } @@ -49,19 +58,19 @@ public class OpMessageConfigController implements OpMessageConfigApi { public ApiResult create(CreateOpMessageConfigParam param) { OpMessageConfigService.CreateOpMessageConfigParam createOpMessageConfigParam = OpMessageConfigService.CreateOpMessageConfigParam.builder().build(); BeanUtils.copyProperties(param, createOpMessageConfigParam); + // 默认状态为待执行,创建人就是提交审核人 + createOpMessageConfigParam.setSubmitPersonId(param.getOperatePersonId()); + createOpMessageConfigParam.setCreatePersonId(param.getOperatePersonId()); OpMessageConfig opMessageConfig = opMessageConfigService.create(createOpMessageConfigParam); - - OpMessageConfigBaseResp opMessageConfigResp = OpMessageConfigBaseResp.builder().build();; - BeanUtils.copyProperties(opMessageConfig, opMessageConfigResp); - return ApiResult.ok(opMessageConfigResp); + return ApiResult.ok(to(opMessageConfig)); } @Override public ApiResult delete(DeleteOpMessageConfigParam param) { OpMessageConfigService.DeleteOpMessageConfigParam deleteOpMessageConfigParam = OpMessageConfigService.DeleteOpMessageConfigParam.builder() .id(param.getId()) - .deletePersonId(param.getDeletePersonId()) + .deletePersonId(param.getOperatePersonId()) .build(); opMessageConfigService.delete(deleteOpMessageConfigParam); return ApiResult.ok(); @@ -71,11 +80,50 @@ public class OpMessageConfigController implements OpMessageConfigApi { public ApiResult update(UpdateOpMessageConfigParam param) { OpMessageConfigService.UpdateOpMessageConfigParam updateOpMessageConfigParam = OpMessageConfigService.UpdateOpMessageConfigParam.builder().build(); BeanUtils.copyProperties(param, updateOpMessageConfigParam); + updateOpMessageConfigParam.setUpdatePersonId(param.getOperatePersonId()); OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); + return ApiResult.ok(to(opMessageConfig)); + } + @Override + public ApiResult saveDraft(SaveDraftOpMessageConfigParam req) { + + if (req.getId() == null) { + OpMessageConfigService.CreateOpMessageConfigParam createOpMessageConfigParam = OpMessageConfigService.CreateOpMessageConfigParam.builder().build(); + BeanUtils.copyProperties(req, createOpMessageConfigParam); + createOpMessageConfigParam.setStatus(OpMessageConfig.Status.DRAFT.name()); + createOpMessageConfigParam.setCreatePersonId(req.getOperatePersonId()); + + OpMessageConfig opMessageConfig = opMessageConfigService.create(createOpMessageConfigParam); + return ApiResult.ok(to(opMessageConfig)); + } + + OpMessageConfigService.UpdateOpMessageConfigParam updateOpMessageConfigParam = OpMessageConfigService.UpdateOpMessageConfigParam.builder().build(); + BeanUtils.copyProperties(req, updateOpMessageConfigParam); + updateOpMessageConfigParam.setUpdatePersonId(req.getOperatePersonId()); + + OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); + return ApiResult.ok(to(opMessageConfig)); + } + + @Override + public ApiResult submitDraft(SaveDraftOpMessageConfigParam req) { + Aassert.notNull(req.getId(), OP_MESSAGE_CONFIG_ID_NOT_NULL); + + OpMessageConfigService.UpdateOpMessageConfigParam updateOpMessageConfigParam = OpMessageConfigService.UpdateOpMessageConfigParam.builder().build(); + BeanUtils.copyProperties(req, updateOpMessageConfigParam); + updateOpMessageConfigParam.setAction(OpMessageConfig.ActionEnum.SUBMIT_DRAFT); + updateOpMessageConfigParam.setUpdatePersonId(req.getOperatePersonId()); + + OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); + return ApiResult.ok(to(opMessageConfig)); + } + + public OpMessageConfigBaseResp to(OpMessageConfig opMessageConfig) { OpMessageConfigBaseResp opMessageConfigResp = OpMessageConfigBaseResp.builder().build();; BeanUtils.copyProperties(opMessageConfig, opMessageConfigResp); - return ApiResult.ok(opMessageConfigResp); + opMessageConfigResp.setStatus(opMessageConfig.getStatus().name()); + return opMessageConfigResp; } } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java index e3ad55b7..dbcaf779 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java @@ -1,19 +1,24 @@ package cn.axzo.nanopart.server.domain; +import cn.axzo.nanopart.server.config.BizResultCode; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.Sets; +import com.google.common.collect.Table; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import lombok.experimental.SuperBuilder; import java.util.Date; +import java.util.Optional; import java.util.Set; @Data @@ -120,6 +125,12 @@ public class OpMessageConfig { @TableField private Long updatePersonId; + /** + * 提交审核人 + */ + @TableField + private Long submitPersonId; + public enum Status { DRAFT, PENDING, @@ -135,4 +146,21 @@ public class OpMessageConfig { public boolean canUpdate() { return CAN_UPDATE_STATUSES.contains(this.getStatus()); } + + @Getter + @AllArgsConstructor + public enum ActionEnum { + SUBMIT_DRAFT, + ; + + private static final Table STATUS_FLOWS = HashBasedTable.create(); + + static { + STATUS_FLOWS.put(Status.DRAFT, SUBMIT_DRAFT, Status.PENDING); + } + + public Status getNextStatus(Status oldStatus) { + return Optional.ofNullable(STATUS_FLOWS.get(oldStatus, this)).orElseThrow(BizResultCode.OP_MESSAGE_CONFIG_STATUS_ERROR::toException); + } + } } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index 1ab390c5..893e46f2 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -58,8 +58,6 @@ public interface OpMessageConfigService extends IService { private JSONObject receiveData; - private String status; - private String title; private String content; @@ -78,6 +76,10 @@ public interface OpMessageConfigService extends IService { private Long updatePersonId; + private Long submitPersonId; + + private OpMessageConfig.ActionEnum action; + public OpMessageConfig to() { OpMessageConfig opMessageConfig = OpMessageConfig.builder().build(); BeanUtils.copyProperties(this, opMessageConfig); @@ -116,6 +118,8 @@ public interface OpMessageConfigService extends IService { private Long createPersonId; + private Long submitPersonId; + public OpMessageConfig to() { OpMessageConfig opMessageConfig = OpMessageConfig.builder().build(); BeanUtils.copyProperties(this, opMessageConfig); @@ -163,6 +167,12 @@ public interface OpMessageConfigService extends IService { */ @CriteriaField(ignore = true) private boolean needCreatePersonInfo; + + /** + * 返回提交审核人的信息 + */ + @CriteriaField(ignore = true) + private boolean needSubmitPersonInfo; } @Builder @@ -237,15 +247,19 @@ public interface OpMessageConfigService extends IService { private PersonProfileDto createPersonProfile; + private PersonProfileDto submitPersonProfile; + public static OpMessageConfigDTO from(OpMessageConfig opMessageConfig, Map sendUserInfos, - Map personProfiles) { + Map createPersonProfiles, + Map submitPersonProfiles) { OpMessageConfigDTO opMessageConfigDTO = OpMessageConfigDTO.builder().build(); BeanUtils.copyProperties(opMessageConfig, opMessageConfigDTO); opMessageConfigDTO.setSendUserInfo(sendUserInfos.get(opMessageConfigDTO.getSendImAccount())); - opMessageConfigDTO.setCreatePersonProfile(personProfiles.get(opMessageConfigDTO.getCreatePersonId())); + opMessageConfigDTO.setCreatePersonProfile(createPersonProfiles.get(opMessageConfigDTO.getCreatePersonId())); + opMessageConfigDTO.setSubmitPersonProfile(submitPersonProfiles.get(opMessageConfigDTO.getSubmitPersonId())); return opMessageConfigDTO; } } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java index 4dfc398a..8151f6b3 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java @@ -34,6 +34,8 @@ import static cn.axzo.nanopart.server.config.BizResultCode.UPDATE_OP_MESSAGE_CON public class OpMessageConfigServiceImpl extends ServiceImpl implements OpMessageConfigService { + private static final Long DEFAULT_ZERO_PERSON_ID = 0L; + @Autowired private RobotInfoApi robotInfoApi; @Autowired @@ -47,9 +49,13 @@ public class OpMessageConfigServiceImpl extends ServiceImpl sendUserInfos = listSendUserInfo(param, page.getRecords()); - Map personProfiles = listCreatePersonProfile(param, page.getRecords()); + Map createPersonProfiles = listCreatePersonProfile(param, page.getRecords()); + Map submitPersonProfiles = listSubmitPersonProfile(param, page.getRecords()); - return PageConverter.convert(page, (record) -> OpMessageConfigDTO.from(record, sendUserInfos, personProfiles)); + return PageConverter.convert(page, (record) -> OpMessageConfigDTO.from(record, + sendUserInfos, + submitPersonProfiles, + submitPersonProfiles)); } @Override @@ -66,7 +72,12 @@ public class OpMessageConfigServiceImpl extends ServiceImpl listSubmitPersonProfile(PageOpMessageConfigParam param, + List opMessageConfigs) { + if (CollectionUtils.isEmpty(opMessageConfigs) || BooleanUtils.isNotTrue(param.isNeedSubmitPersonInfo())) { + return Collections.emptyMap(); + } + + List submitPersonIds = opMessageConfigs.stream() + .map(OpMessageConfig::getSubmitPersonId) + .filter(id -> !Objects.equals(DEFAULT_ZERO_PERSON_ID, id)) + .distinct() + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(submitPersonIds)) { + return Collections.emptyMap(); + } + + return userProfileServiceApi.postPersonProfiles(submitPersonIds).getData() + .stream() + .collect(Collectors.toMap(PersonProfileDto::getId, Function.identity())); + } } diff --git a/op/op-server/src/test/resources/mysql/schema.sql b/op/op-server/src/test/resources/mysql/schema.sql index a2383ac5..04d08ae3 100644 --- a/op/op-server/src/test/resources/mysql/schema.sql +++ b/op/op-server/src/test/resources/mysql/schema.sql @@ -20,6 +20,7 @@ CREATE TABLE IF NOT EXISTS op_message_config is_delete tinyint default 0 not null comment '未删除0,删除1', create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间', create_person_id bigint not null comment '创建人id', + submit_person_id bigint not null default 0 comment '提交审核人id,可能跟crate_person_id不一样,比如先保存草稿', delete_person_id bigint not null default 0 comment '删除人id', update_person_id bigint not null default 0 comment '更新人id', update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间', From 9625ab04d175ae500b4dc10c09198d52d4698864 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 20 Mar 2024 16:41:47 +0800 Subject: [PATCH 06/25] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E7=9A=84=E4=B8=9A=E5=8A=A1=E5=BC=82=E5=B8=B8=E6=8B=A6?= =?UTF-8?q?=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanopart/config/exception/ExceptionAdviceHandler.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java b/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java index 5392e0a5..13db216b 100644 --- a/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java +++ b/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java @@ -1,6 +1,7 @@ package cn.axzo.nanopart.config.exception; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.pokonyan.exception.BusinessException; import lombok.extern.slf4j.Slf4j; import org.springframework.core.annotation.Order; import org.springframework.util.CollectionUtils; @@ -41,6 +42,12 @@ public class ExceptionAdviceHandler { return ApiResult.err(e.getMessage()); } + @ExceptionHandler(BusinessException.class) + public ApiResult businessExceptionHandler(BusinessException e){ + log.warn("业务异常", e); + return ApiResult.err(e.getErrorMsg()); + } + @ExceptionHandler(BindException.class) public ApiResult bindExceptionHandler(BindException e) { log.warn("业务异常", e); From ef94711462c40a0bd0a07a6eab2d54aa342fc964 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 25 Mar 2024 13:44:21 +0800 Subject: [PATCH 07/25] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0xxlJob=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E8=BF=90=E8=90=A5=E6=B6=88=E6=81=AF=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E6=B6=88=E6=81=AF=E5=8F=91=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/op/api/OpMessageConfigApi.java | 2 + op/op-server/pom.xml | 5 + .../controller/OpMessageConfigController.java | 6 +- .../server/controller/PrivateController.java | 22 +++ .../server/domain/OpMessageConfig.java | 158 ++++++++++++++++- .../service/OpMessageConfigService.java | 9 + .../impl/OpMessageConfigServiceImpl.java | 3 - .../server/xxljob/SendMessageJob.java | 167 ++++++++++++++++++ .../nanopart/server/xxljob/XxlJobConfig.java | 60 +++++++ .../src/test/resources/mysql/schema.sql | 1 + 10 files changed, 420 insertions(+), 13 deletions(-) create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java index 2d6608ba..6b609b4c 100644 --- a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -268,6 +268,8 @@ public interface OpMessageConfigApi { * 更新人id */ private Long updatePersonId; + + private Date submitTime; } diff --git a/op/op-server/pom.xml b/op/op-server/pom.xml index 3d290869..cd5e2826 100644 --- a/op/op-server/pom.xml +++ b/op/op-server/pom.xml @@ -80,5 +80,10 @@ basics-profiles-api + + com.xuxueli + xxl-job-core + + diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java index 5b942a33..4fed418e 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java @@ -11,6 +11,8 @@ import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; +import java.util.Date; + import static cn.axzo.nanopart.server.config.BizResultCode.OP_MESSAGE_CONFIG_ID_NOT_NULL; @RestController @@ -61,7 +63,7 @@ public class OpMessageConfigController implements OpMessageConfigApi { // 默认状态为待执行,创建人就是提交审核人 createOpMessageConfigParam.setSubmitPersonId(param.getOperatePersonId()); createOpMessageConfigParam.setCreatePersonId(param.getOperatePersonId()); - + createOpMessageConfigParam.setStatus(OpMessageConfig.Status.PENDING.name()); OpMessageConfig opMessageConfig = opMessageConfigService.create(createOpMessageConfigParam); return ApiResult.ok(to(opMessageConfig)); } @@ -115,6 +117,8 @@ public class OpMessageConfigController implements OpMessageConfigApi { BeanUtils.copyProperties(req, updateOpMessageConfigParam); updateOpMessageConfigParam.setAction(OpMessageConfig.ActionEnum.SUBMIT_DRAFT); updateOpMessageConfigParam.setUpdatePersonId(req.getOperatePersonId()); + updateOpMessageConfigParam.setSubmitPersonId(req.getOperatePersonId()); + updateOpMessageConfigParam.setSubmitTime(new Date()); OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); return ApiResult.ok(to(opMessageConfig)); diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java new file mode 100644 index 00000000..e656e06f --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java @@ -0,0 +1,22 @@ +package cn.axzo.nanopart.server.controller; + +import cn.axzo.nanopart.server.xxljob.SendMessageJob; +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/private") +public class PrivateController { + + @Autowired + private SendMessageJob sendMessageJob; + + @PostMapping("/send-message/job/run") + public Object runSendMessage(@RequestBody SendMessageJob.SendMessageParam param) throws Exception { + return sendMessageJob.execute(JSONObject.toJSONString(param)); + } +} diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java index dbcaf779..d33a690a 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java @@ -11,13 +11,18 @@ import com.google.common.collect.HashBasedTable; import com.google.common.collect.Sets; import com.google.common.collect.Table; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import lombok.experimental.SuperBuilder; +import org.apache.commons.lang3.StringUtils; +import java.util.Arrays; import java.util.Date; +import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -34,11 +39,6 @@ public class OpMessageConfig { Status.PENDING ); - private static final Set CAN_UPDATE_STATUSES = Sets.newHashSet( - Status.DRAFT, - Status.PENDING - ); - @TableId(type = IdType.AUTO) private Long id; @@ -104,6 +104,9 @@ public class OpMessageConfig { @TableField private Date createAt; + @TableField + private Date submitTime; + @TableField private Date updateAt; @@ -143,24 +146,161 @@ public class OpMessageConfig { return CAN_DELETE_STATUSES.contains(this.getStatus()); } - public boolean canUpdate() { - return CAN_UPDATE_STATUSES.contains(this.getStatus()); - } - @Getter @AllArgsConstructor public enum ActionEnum { SUBMIT_DRAFT, + RUN, + COMPLETE ; private static final Table STATUS_FLOWS = HashBasedTable.create(); static { STATUS_FLOWS.put(Status.DRAFT, SUBMIT_DRAFT, Status.PENDING); + STATUS_FLOWS.put(Status.PENDING, RUN, Status.RUNNING); + STATUS_FLOWS.put(Status.RUNNING, COMPLETE, Status.COMPLETED); } public Status getNextStatus(Status oldStatus) { return Optional.ofNullable(STATUS_FLOWS.get(oldStatus, this)).orElseThrow(BizResultCode.OP_MESSAGE_CONFIG_STATUS_ERROR::toException); } } + + public ReceiveData resolveReceiveData() { + JSONObject receiveData = Optional.ofNullable(this.getReceiveData()).orElseGet(JSONObject::new); + return JSONObject.toJavaObject(receiveData, ReceiveData.class); + } + + public JumpData resolveJumpData() { + JSONObject jumpData = Optional.ofNullable(this.getJumpData()).orElseGet(JSONObject::new); + return JSONObject.toJavaObject(jumpData, JumpData.class); + } + + public PushData resolvePushData() { + JSONObject pushData = Optional.ofNullable(this.getPushData()).orElseGet(JSONObject::new); + return JSONObject.toJavaObject(pushData, PushData.class); + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ReceiveData { + + private List persons; + + /** + * 推送时间策略:now(立即发送)、specifyTime(指定时间) + */ + private String strategy; + + private String fileName; + + private String fileKey; + + /** + * 接收的类型:all(全部员工)、import(导入名单) + */ + private String type; + + /** + * 接收渠道平台:CMP(B端: APP(管理端)+ CMS)、CM(C端:APP(工人端)) + */ + private List platforms; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Person { + + private Long ouId; + + private Long personId; + } + + @Getter + @AllArgsConstructor + public enum ReceiveType { + ALL("all", "全部员工"), + IMPORT("import", "导入名单"); + + private String code; + + private String desc; + + public static ReceiveType of(String typeCode) { + if (StringUtils.isBlank(typeCode)) { + return null; + } + + return Arrays.stream(values()) + .filter(e -> Objects.equals(e.getCode(), typeCode)) + .findFirst() + .orElse(null); + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class JumpData { + private boolean switchOn; + + private List platforms; + } + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class Platform { + + private JumpPlatform platform; + + private String url; + } + + @Getter + @AllArgsConstructor + public enum JumpPlatform { + PC, + CM_IOS, + CM_ANDROID, + CMP_IOS, + CMP_ANDROID + ; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class PushData { + + private boolean switchOn; + + /** + * 声音文件 + */ + private String voiceFile; + + /** + * 提醒方式:voice(声音)、vibrate(震动) + */ + private String ability; + + /** + * push类型:system(系统消息)、op(运营消息) + */ + private String type; + + /** + * 声音类型:custom(自定义)、system(系统 + */ + private String voiceType; + } } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index 893e46f2..42e0d8df 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -80,6 +80,14 @@ public interface OpMessageConfigService extends IService { private OpMessageConfig.ActionEnum action; + private Date submitTime; + + private Long imMessageTaskId; + + private Date startedTime; + + private Date finishedTime; + public OpMessageConfig to() { OpMessageConfig opMessageConfig = OpMessageConfig.builder().build(); BeanUtils.copyProperties(this, opMessageConfig); @@ -123,6 +131,7 @@ public interface OpMessageConfigService extends IService { public OpMessageConfig to() { OpMessageConfig opMessageConfig = OpMessageConfig.builder().build(); BeanUtils.copyProperties(this, opMessageConfig); + opMessageConfig.setSubmitTime(new Date()); return opMessageConfig; } } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java index 8151f6b3..177e7fad 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java @@ -27,7 +27,6 @@ import java.util.stream.Collectors; import static cn.axzo.nanopart.server.config.BizResultCode.DELETE_OP_MESSAGE_CONFIG_STATUS_ERROR; import static cn.axzo.nanopart.server.config.BizResultCode.OP_MESSAGE_CONFIG_NOT_FOUND; -import static cn.axzo.nanopart.server.config.BizResultCode.UPDATE_OP_MESSAGE_CONFIG_STATUS_ERROR; @Slf4j @Service @@ -70,8 +69,6 @@ public class OpMessageConfigServiceImpl extends ServiceImpl execute(String s) throws Exception { + log.info("start sendMessageJob,s:{}", s); + SendMessageParam sendMessageParam = Optional.ofNullable(s) + .map(e -> JSONObject.parseObject(e, SendMessageParam.class)) + .orElseGet(() -> SendMessageParam.builder().build()); + Integer pageNumber = 1; + Date now = new Date(); + + SendMessageJob proxySendMessageJob = applicationContext.getBean(this.getClass()); + + while (true) { + OpMessageConfigService.PageOpMessageConfigParam req = OpMessageConfigService.PageOpMessageConfigParam.builder() + .ids(sendMessageParam.getIds()) + .planStartTimeLE(now) + .statuses(Lists.newArrayList(OpMessageConfig.Status.PENDING.name())) + .pageNumber(pageNumber++) + .pageSize(DEFAULT_PAGE_SIZE) + .build(); + + Page page = opMessageConfigService.page(req); + if (CollectionUtils.isNotEmpty(page.getRecords())) { + // 一个一个更新,数据量不大,一个失败不影响其他的运营消息 + page.getRecords().forEach(proxySendMessageJob::sendMessage); + } + + if (!page.hasNext()) { + break; + } + } + log.info("end sendMessageJob"); + return ReturnT.SUCCESS; + } + + @Transactional(rollbackFor = Exception.class) + public void sendMessage(OpMessageConfigService.OpMessageConfigDTO opMessageConfig) { + opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() + .id(opMessageConfig.getId()) + .action(OpMessageConfig.ActionEnum.RUN) + .startedTime(new Date()) + .build()); + + OpMessageConfig.ReceiveData receiveData = opMessageConfig.resolveReceiveData(); + OpMessageConfig.ReceiveType receiveType = OpMessageConfig.ReceiveType.of(receiveData.getType()); + boolean isAllPerson = Objects.equals(OpMessageConfig.ReceiveType.ALL, receiveType); + + List appTypes = BooleanUtils.isTrue(isAllPerson) ? receiveData.getPlatforms().stream().map(AppTypeEnum::valueOf).collect(Collectors.toList()) : null; + + MessageTaskResp messageTask = messageApi.sendMessageAsync(AsyncSendMessageParam.builder() + .sendImAccount(opMessageConfig.getSendImAccount()) + .receivePersons(resolveReceivePerson(receiveData)) + .allPerson(isAllPerson) + .appTypes(appTypes) + .msgHeader(opMessageConfig.getTitle()) + .msgContent(opMessageConfig.getContent()) + .jumpData(resolveJumpData(opMessageConfig)) + .pushData(resolve(opMessageConfig)) + .cardBannerUrl(opMessageConfig.getCoverImg()) + .build()).getData(); + + opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() + .id(opMessageConfig.getId()) + .imMessageTaskId(messageTask.getId()) + // 消息是异步执行的,准确的完成时间,需要监听messageTask的完成时间才准确,现在mq配置较低,消息服务没有发送mq + .finishedTime(new Date()) + .action(OpMessageConfig.ActionEnum.COMPLETE) + .build()); + } + + + private List resolveReceivePerson(OpMessageConfig.ReceiveData receiveData) { + OpMessageConfig.ReceiveType receiveType = OpMessageConfig.ReceiveType.of(receiveData.getType()); + boolean isAllPerson = Objects.equals(OpMessageConfig.ReceiveType.ALL, receiveType); + + if (BooleanUtils.isTrue(isAllPerson)) { + return Collections.emptyList(); + } + + return receiveData.getPlatforms().stream() + .flatMap(platform -> receiveData.getPersons() + .stream() + .map(person -> cn.axzo.im.center.api.vo.req.SendMessageParam.ReceivePerson.builder() + .personId(person.getPersonId().toString()) + .ouId(person.getOuId()) + .appType(AppTypeEnum.valueOf(platform)) + .build()) + ) + .collect(Collectors.toList()); + } + + private List resolveJumpData(OpMessageConfigService.OpMessageConfigDTO opMessageConfig) { + return opMessageConfig.resolveJumpData().getPlatforms().stream() + .map(platform -> cn.axzo.im.center.api.vo.req.SendMessageParam.JumpData.builder() + .platform(cn.axzo.im.center.api.vo.req.SendMessageParam.JumpPlatform.valueOf(platform.getPlatform().name())) + .url(platform.getUrl()) + .build()) + .collect(Collectors.toList()); + } + + private cn.axzo.im.center.api.vo.req.SendMessageParam.PushData resolve(OpMessageConfigService.OpMessageConfigDTO opMessageConfig) { + + OpMessageConfig.PushData pushData = opMessageConfig.resolvePushData(); + return cn.axzo.im.center.api.vo.req.SendMessageParam.PushData.builder() + .voiceFile(pushData.getVoiceFile()) + .ability(pushData.getAbility()) + .type(pushData.getType()) + .voiceType(pushData.getVoiceType()) + .build(); + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SendMessageParam { + private List ids; + } +} diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java new file mode 100644 index 00000000..161e3a7b --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java @@ -0,0 +1,60 @@ +package cn.axzo.nanopart.server.xxljob; + +import cn.azxo.framework.common.service.JobParamResolver; +import cn.azxo.framework.common.spring.condition.NonLocalEnvironment; +import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Xxl Job Config + * + * @author zhaoyong_sh + * @see XxlJobConfig + * @since 2021-05-19 10:26 + */ +@Slf4j +@Configuration +public class XxlJobConfig { + + @Value("${xxl.job.admin.addresses}") + private String adminAddresses; + + @Value("${xxl.job.executor.appName}") + private String appName; + + @Value("${xxl.job.executor.ip:}") + private String ip; + + @Value("${xxl.job.executor.port}") + private int port; + + @Value("${xxl.job.accessToken:}") + private String accessToken; + + @Value("${xxl.job.executor.logPath:}") + private String logPath; + + @Bean + @NonLocalEnvironment + public XxlJobSpringExecutor xxlJobExecutor() { + log.info(">>>>>>>>>>> axzo nanopart op-server service xxl-job config init."); + XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); + xxlJobSpringExecutor.setAdminAddresses(adminAddresses); + xxlJobSpringExecutor.setAppname(appName); + xxlJobSpringExecutor.setIp(ip); + xxlJobSpringExecutor.setPort(port); + xxlJobSpringExecutor.setAccessToken(accessToken); + xxlJobSpringExecutor.setLogPath(logPath); + xxlJobSpringExecutor.setLogRetentionDays(7); + return xxlJobSpringExecutor; + } + + @Bean + public JobParamResolver jobParamResolver(){ + return new JobParamResolver(); + } + +} diff --git a/op/op-server/src/test/resources/mysql/schema.sql b/op/op-server/src/test/resources/mysql/schema.sql index 04d08ae3..ce6c2040 100644 --- a/op/op-server/src/test/resources/mysql/schema.sql +++ b/op/op-server/src/test/resources/mysql/schema.sql @@ -17,6 +17,7 @@ CREATE TABLE IF NOT EXISTS op_message_config plan_start_time DATETIME(3) not null comment '任务计划开始时间,时间大于改时间会对未完成的任务进行执行操作', started_time DATETIME(3) null comment '实际开始时间', finished_time DATETIME(3) null comment '实际完成时间', + submit_time DATETIME(3) null comment '提交审核时间', is_delete tinyint default 0 not null comment '未删除0,删除1', create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间', create_person_id bigint not null comment '创建人id', From ece89671cbf65de362aa707e8dce175c06cfe5b8 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 26 Mar 2024 16:28:33 +0800 Subject: [PATCH 08/25] =?UTF-8?q?feat:=20=E5=8E=BB=E6=8E=89pushData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/nanopart/server/xxljob/SendMessageJob.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 58325493..e8986964 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -103,7 +103,6 @@ public class SendMessageJob extends IJobHandler { .msgHeader(opMessageConfig.getTitle()) .msgContent(opMessageConfig.getContent()) .jumpData(resolveJumpData(opMessageConfig)) - .pushData(resolve(opMessageConfig)) .cardBannerUrl(opMessageConfig.getCoverImg()) .build()).getData(); @@ -146,17 +145,6 @@ public class SendMessageJob extends IJobHandler { .collect(Collectors.toList()); } - private cn.axzo.im.center.api.vo.req.SendMessageParam.PushData resolve(OpMessageConfigService.OpMessageConfigDTO opMessageConfig) { - - OpMessageConfig.PushData pushData = opMessageConfig.resolvePushData(); - return cn.axzo.im.center.api.vo.req.SendMessageParam.PushData.builder() - .voiceFile(pushData.getVoiceFile()) - .ability(pushData.getAbility()) - .type(pushData.getType()) - .voiceType(pushData.getVoiceType()) - .build(); - } - @Data @Builder @NoArgsConstructor From 6c0673b52ed978b046cf6d1c3dd05a8757e243d1 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 26 Mar 2024 16:54:00 +0800 Subject: [PATCH 09/25] =?UTF-8?q?feat:=20=E8=BF=81=E7=A7=BBxxlJob=E7=9A=84?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/nanopart/config/XxlJobConfig.java | 0 .../nanopart/server/xxljob/XxlJobConfig.java | 60 ------------------- 2 files changed, 60 deletions(-) create mode 100644 nanopart-server/src/main/java/cn/axzo/nanopart/config/XxlJobConfig.java delete mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/config/XxlJobConfig.java b/nanopart-server/src/main/java/cn/axzo/nanopart/config/XxlJobConfig.java new file mode 100644 index 00000000..e69de29b diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java deleted file mode 100644 index 161e3a7b..00000000 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/XxlJobConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -package cn.axzo.nanopart.server.xxljob; - -import cn.azxo.framework.common.service.JobParamResolver; -import cn.azxo.framework.common.spring.condition.NonLocalEnvironment; -import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Xxl Job Config - * - * @author zhaoyong_sh - * @see XxlJobConfig - * @since 2021-05-19 10:26 - */ -@Slf4j -@Configuration -public class XxlJobConfig { - - @Value("${xxl.job.admin.addresses}") - private String adminAddresses; - - @Value("${xxl.job.executor.appName}") - private String appName; - - @Value("${xxl.job.executor.ip:}") - private String ip; - - @Value("${xxl.job.executor.port}") - private int port; - - @Value("${xxl.job.accessToken:}") - private String accessToken; - - @Value("${xxl.job.executor.logPath:}") - private String logPath; - - @Bean - @NonLocalEnvironment - public XxlJobSpringExecutor xxlJobExecutor() { - log.info(">>>>>>>>>>> axzo nanopart op-server service xxl-job config init."); - XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); - xxlJobSpringExecutor.setAdminAddresses(adminAddresses); - xxlJobSpringExecutor.setAppname(appName); - xxlJobSpringExecutor.setIp(ip); - xxlJobSpringExecutor.setPort(port); - xxlJobSpringExecutor.setAccessToken(accessToken); - xxlJobSpringExecutor.setLogPath(logPath); - xxlJobSpringExecutor.setLogRetentionDays(7); - return xxlJobSpringExecutor; - } - - @Bean - public JobParamResolver jobParamResolver(){ - return new JobParamResolver(); - } - -} From a9583014698990b4c9f2d50e69d29e90536c5d75 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 27 Mar 2024 20:43:28 +0800 Subject: [PATCH 10/25] =?UTF-8?q?feat:=20(REQ-2129)=E5=A2=9E=E5=8A=A0push?= =?UTF-8?q?=E6=B6=88=E6=81=AFhandler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nanopart-server/pom.xml | 5 + .../cn/axzo/nanopart/NanopartApplication.java | 3 + .../config/RocketMQEventConfiguration.java | 90 +++++++++ .../cn/axzo/nanopart/config/XxlJobConfig.java | 69 +++++++ op/op-server/pom.xml | 10 + .../controller/OpMessageConfigController.java | 19 ++ .../server/controller/PrivateController.java | 10 + .../server/domain/OpMessageConfig.java | 6 + .../server/event/outer/EventTypeEnum.java | 31 +++ .../outer/PushYouMengMessageHandler.java | 184 ++++++++++++++++++ .../payload/MessageHistoryUpdatedPayload.java | 176 +++++++++++++++++ .../service/OpMessageConfigService.java | 3 + .../server/xxljob/SendMessageJob.java | 18 +- 13 files changed, 616 insertions(+), 8 deletions(-) create mode 100644 nanopart-server/src/main/java/cn/axzo/nanopart/config/RocketMQEventConfiguration.java create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/EventTypeEnum.java create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java create mode 100644 op/op-server/src/main/java/cn/axzo/nanopart/server/event/payload/MessageHistoryUpdatedPayload.java diff --git a/nanopart-server/pom.xml b/nanopart-server/pom.xml index a49b945d..dc5ecf22 100644 --- a/nanopart-server/pom.xml +++ b/nanopart-server/pom.xml @@ -118,6 +118,11 @@ cn.axzo.basics basics-profiles-api + + + cn.axzo.framework.rocketmq + axzo-common-rocketmq + diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java b/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java index 21e1ae73..521bb1b8 100644 --- a/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java +++ b/nanopart-server/src/main/java/cn/axzo/nanopart/NanopartApplication.java @@ -1,10 +1,12 @@ package cn.axzo.nanopart; +import cn.axzo.nanopart.config.RocketMQEventConfiguration; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.Import; @MapperScan(value = {"cn.axzo.**.mapper"}) @SpringBootApplication @@ -12,6 +14,7 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy; "cn.axzo" }) @EnableAspectJAutoProxy() +@Import(RocketMQEventConfiguration.class) public class NanopartApplication { public static void main(String[] args) { SpringApplication.run(NanopartApplication.class, args); diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/config/RocketMQEventConfiguration.java b/nanopart-server/src/main/java/cn/axzo/nanopart/config/RocketMQEventConfiguration.java new file mode 100644 index 00000000..31ff6a9e --- /dev/null +++ b/nanopart-server/src/main/java/cn/axzo/nanopart/config/RocketMQEventConfiguration.java @@ -0,0 +1,90 @@ +package cn.axzo.nanopart.config; + +import cn.axzo.framework.rocketmq.BaseListener; +import cn.axzo.framework.rocketmq.DefaultEventConsumer; +import cn.axzo.framework.rocketmq.EventConsumer; +import cn.axzo.framework.rocketmq.EventHandlerRepository; +import cn.axzo.framework.rocketmq.EventProducer; +import cn.axzo.framework.rocketmq.RocketMQEventProducer; +import lombok.extern.slf4j.Slf4j; +import org.apache.rocketmq.common.message.MessageExt; +import org.apache.rocketmq.spring.annotation.ConsumeMode; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.apache.rocketmq.spring.core.RocketMQTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import java.util.function.Consumer; + +/** + * @Author: liyong.tian + * @Date: 2023/7/25 14:43 + * @Description: + */ +@Slf4j +public class RocketMQEventConfiguration { + + @Value("${spring.application.name}") + private String appName; + + @Value("${topic}") + private String topic; + + @Bean + public RocketMQTemplate ser(){ + return new RocketMQTemplate(); + } + @Bean + EventProducer eventProducer(RocketMQTemplate rocketMQTemplate) { + return new RocketMQEventProducer(rocketMQTemplate, + "nanopart", + appName, + EventProducer.Context.builder() + .meta(RocketMQEventProducer.RocketMQMessageMeta.builder() + .topic(topic) + .build()) + .build(), + null + ); + } + + @Bean + EventConsumer eventConsumer(EventHandlerRepository eventHandlerRepository) { + Consumer callback = (eventWrapper) -> { + if (eventWrapper.isHandled()) { + // 只收集被App真正消费的消息. + //String topic = (String) eventWrapper.getExt().get(EVENT_TOPIC_KEY); + + } + }; + return new DefaultEventConsumer(appName, eventHandlerRepository, callback); + } + + @Slf4j + @Component + @RocketMQMessageListener(topic = "topic_im_center_${spring.profiles.active}", + consumerGroup = "GID_topic_im_center_${spring.application.name}_${spring.profiles.active}", + consumeMode = ConsumeMode.ORDERLY, + nameServer = "${rocketmq.name-server}" + ) + public static class DefaultListener extends BaseListener implements RocketMQListener { + + @Autowired + private EventConsumer eventConsumer; + + @Override + public void onMessage(MessageExt message) { + super.onEvent(message, eventConsumer); + } + } + + @Bean + EventHandlerRepository eventHandlerRepository() { + return new EventHandlerRepository((ex, logText) -> { + log.warn("MQ, handle warning {}", logText, ex); + }); + } +} diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/config/XxlJobConfig.java b/nanopart-server/src/main/java/cn/axzo/nanopart/config/XxlJobConfig.java index e69de29b..21788baa 100644 --- a/nanopart-server/src/main/java/cn/axzo/nanopart/config/XxlJobConfig.java +++ b/nanopart-server/src/main/java/cn/axzo/nanopart/config/XxlJobConfig.java @@ -0,0 +1,69 @@ +package cn.axzo.nanopart.config; + +import cn.azxo.framework.common.logger.JobLoggerTemplate; +import cn.azxo.framework.common.service.JobParamResolver; +import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * xxl-job config + * + * @author xuxueli 2017-04-28 + */ +@Configuration +public class XxlJobConfig { + + private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class); + + // @Value("http://dev-xxl-job.axzo.cn/xxl-job-admin") + @Value("${xxl.job.admin.addresses}") + private String adminAddresses; + + @Value("${xxl.job.executor.appname}") + private String appName; + + @Value("") + private String ip; + + @Value("${xxl.job.executor.port}") + private int port; + + // @Value("${xxl.job.accessToken}") + @Value("") + private String accessToken; + + @Value("") + private String logPath; + + @Value("-1") + private int logRetentionDays; + + @Bean + public XxlJobSpringExecutor xxlJobExecutor() { + logger.info(">>>>>>>>>>> xxl-job config init."); + XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); + xxlJobSpringExecutor.setAdminAddresses(adminAddresses); + xxlJobSpringExecutor.setAppname(appName); + xxlJobSpringExecutor.setIp(ip); + xxlJobSpringExecutor.setPort(port); + xxlJobSpringExecutor.setAccessToken(accessToken); + xxlJobSpringExecutor.setLogPath(logPath); + xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); + + return xxlJobSpringExecutor; + } + + @Bean("jobParamResolver") + public JobParamResolver jobParamResolver() { + return new JobParamResolver(); + } + + @Bean("jobLoggerTemplate") + public JobLoggerTemplate jobLoggerTemplate() { + return new JobLoggerTemplate(); + } +} diff --git a/op/op-server/pom.xml b/op/op-server/pom.xml index cd5e2826..040cbe95 100644 --- a/op/op-server/pom.xml +++ b/op/op-server/pom.xml @@ -85,5 +85,15 @@ xxl-job-core + + cn.axzo.framework.rocketmq + axzo-common-rocketmq + + + + cn.axzo.msgcenter + msg-center-api + 1.0.1-SNAPSHOT + diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java index 4fed418e..35276af6 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java @@ -6,6 +6,7 @@ import cn.axzo.nanopart.server.domain.OpMessageConfig; import cn.axzo.nanopart.server.service.OpMessageConfigService; import cn.axzo.op.api.OpMessageConfigApi; import cn.axzo.pokonyan.exception.Aassert; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -64,10 +65,25 @@ public class OpMessageConfigController implements OpMessageConfigApi { createOpMessageConfigParam.setSubmitPersonId(param.getOperatePersonId()); createOpMessageConfigParam.setCreatePersonId(param.getOperatePersonId()); createOpMessageConfigParam.setStatus(OpMessageConfig.Status.PENDING.name()); + createOpMessageConfigParam.setPlanStartTime(resolvePlanStartTime(param.getReceiveData(), param.getPlanStartTime())); + OpMessageConfig opMessageConfig = opMessageConfigService.create(createOpMessageConfigParam); return ApiResult.ok(to(opMessageConfig)); } + private Date resolvePlanStartTime(JSONObject receiveData, Date planStartTime) { + if (planStartTime != null) { + return planStartTime; + } + if (receiveData == null) { + return null; + } + if (receiveData.toJavaObject(OpMessageConfig.ReceiveData.class).isNowStrategy()) { + return new Date(); + } + return null; + } + @Override public ApiResult delete(DeleteOpMessageConfigParam param) { OpMessageConfigService.DeleteOpMessageConfigParam deleteOpMessageConfigParam = OpMessageConfigService.DeleteOpMessageConfigParam.builder() @@ -83,6 +99,7 @@ public class OpMessageConfigController implements OpMessageConfigApi { OpMessageConfigService.UpdateOpMessageConfigParam updateOpMessageConfigParam = OpMessageConfigService.UpdateOpMessageConfigParam.builder().build(); BeanUtils.copyProperties(param, updateOpMessageConfigParam); updateOpMessageConfigParam.setUpdatePersonId(param.getOperatePersonId()); + updateOpMessageConfigParam.setPlanStartTime(resolvePlanStartTime(param.getReceiveData(), param.getPlanStartTime())); OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); return ApiResult.ok(to(opMessageConfig)); @@ -104,6 +121,7 @@ public class OpMessageConfigController implements OpMessageConfigApi { OpMessageConfigService.UpdateOpMessageConfigParam updateOpMessageConfigParam = OpMessageConfigService.UpdateOpMessageConfigParam.builder().build(); BeanUtils.copyProperties(req, updateOpMessageConfigParam); updateOpMessageConfigParam.setUpdatePersonId(req.getOperatePersonId()); + updateOpMessageConfigParam.setPlanStartTime(resolvePlanStartTime(req.getReceiveData(), req.getPlanStartTime())); OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); return ApiResult.ok(to(opMessageConfig)); @@ -119,6 +137,7 @@ public class OpMessageConfigController implements OpMessageConfigApi { updateOpMessageConfigParam.setUpdatePersonId(req.getOperatePersonId()); updateOpMessageConfigParam.setSubmitPersonId(req.getOperatePersonId()); updateOpMessageConfigParam.setSubmitTime(new Date()); + updateOpMessageConfigParam.setPlanStartTime(resolvePlanStartTime(req.getReceiveData(), req.getPlanStartTime())); OpMessageConfig opMessageConfig = opMessageConfigService.update(updateOpMessageConfigParam); return ApiResult.ok(to(opMessageConfig)); diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java index e656e06f..a2eaeb99 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/PrivateController.java @@ -1,5 +1,7 @@ package cn.axzo.nanopart.server.controller; +import cn.axzo.framework.rocketmq.Event; +import cn.axzo.nanopart.server.event.outer.PushYouMengMessageHandler; import cn.axzo.nanopart.server.xxljob.SendMessageJob; import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Autowired; @@ -14,9 +16,17 @@ public class PrivateController { @Autowired private SendMessageJob sendMessageJob; + @Autowired + private PushYouMengMessageHandler pushYouMengMessageHandler; @PostMapping("/send-message/job/run") public Object runSendMessage(@RequestBody SendMessageJob.SendMessageParam param) throws Exception { return sendMessageJob.execute(JSONObject.toJSONString(param)); } + + @PostMapping("/you-meng/push") + public Object pushYouMeng(@RequestBody Event param) throws Exception { + pushYouMengMessageHandler.onEvent(param, null); + return null; + } } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java index d33a690a..eb452cda 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/domain/OpMessageConfig.java @@ -208,6 +208,10 @@ public class OpMessageConfig { * 接收渠道平台:CMP(B端: APP(管理端)+ CMS)、CM(C端:APP(工人端)) */ private List platforms; + + public boolean isNowStrategy() { + return Objects.equals("now", this.getStrategy()); + } } @Data @@ -288,6 +292,8 @@ public class OpMessageConfig { */ private String voiceFile; + private String voiceFileName; + /** * 提醒方式:voice(声音)、vibrate(震动) */ diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/EventTypeEnum.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/EventTypeEnum.java new file mode 100644 index 00000000..a8eae015 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/EventTypeEnum.java @@ -0,0 +1,31 @@ +package cn.axzo.nanopart.server.event.outer; + +import cn.axzo.framework.rocketmq.Event; +import lombok.Getter; + +/** + * @Classname EventTypeEnum + * @Date 2021/2/7 6:05 下午 + * @Created by lilong + */ +@Getter +public enum EventTypeEnum { + + MESSAGE_HISTORY_UPDATED("message-history", "message-history-updated", "发送记录修改") + ; + + EventTypeEnum(String model, String name, String desc) { + this.eventCode = Event.EventCode.builder() + .module(model) + .name(name) + .build(); + this.model = model; + this.name = name; + this.desc = desc; + } + + private String model; + private String name; + private String desc; + private Event.EventCode eventCode; +} diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java new file mode 100644 index 00000000..df2bd05a --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java @@ -0,0 +1,184 @@ +package cn.axzo.nanopart.server.event.outer; + +import cn.axzo.framework.rocketmq.Event; +import cn.axzo.framework.rocketmq.EventConsumer; +import cn.axzo.framework.rocketmq.EventHandler; +import cn.axzo.msg.center.api.MessagePushApi; +import cn.axzo.msg.center.api.request.MsgBody4Guest; +import cn.axzo.nanopart.server.domain.OpMessageConfig; +import cn.axzo.nanopart.server.event.payload.MessageHistoryUpdatedPayload; +import cn.axzo.nanopart.server.service.OpMessageConfigService; +import cn.axzo.nanopart.server.xxljob.SendMessageJob; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static cn.axzo.nanopart.server.event.payload.MessageHistoryUpdatedPayload.PLATFORM_ROUTER_TYPE; + +@Slf4j +@Component +public class PushYouMengMessageHandler implements EventHandler, InitializingBean { + + @Autowired + private EventConsumer eventConsumer; + @Autowired + private OpMessageConfigService opMessageConfigService; + @Autowired + private MessagePushApi messagePushApi; + + /** + * 按照这个顺序解析routerType + */ + private static final List ROUTER_TYPE_SORTED = Lists.newArrayList( + MessageHistoryUpdatedPayload.IOS_PLATFORM, + MessageHistoryUpdatedPayload.ANDROID_PLATFORM, + MessageHistoryUpdatedPayload.WEBVIEW_PLATFORM, + MessageHistoryUpdatedPayload.MINI_PROGRAM_PLATFORM, + MessageHistoryUpdatedPayload.WECHAT_MINI_PROGRAM_PLATFORM); + + /** + * 按照这个顺序解析IOS的url + */ + private static final List IOS_URL_SORTED = Lists.newArrayList( + MessageHistoryUpdatedPayload.IOS_PLATFORM, + MessageHistoryUpdatedPayload.WEBVIEW_PLATFORM, + MessageHistoryUpdatedPayload.MINI_PROGRAM_PLATFORM, + MessageHistoryUpdatedPayload.WECHAT_MINI_PROGRAM_PLATFORM); + + /** + * 按照这个顺序解析ANDROID的url + */ + private static final List ANDROID_URL_SORTED = Lists.newArrayList( + MessageHistoryUpdatedPayload.ANDROID_PLATFORM, + MessageHistoryUpdatedPayload.WEBVIEW_PLATFORM, + MessageHistoryUpdatedPayload.MINI_PROGRAM_PLATFORM, + MessageHistoryUpdatedPayload.WECHAT_MINI_PROGRAM_PLATFORM); + + + @Override + public void onEvent(Event event, EventConsumer.Context context) { + log.info("begin push-handler rocketmq event: {}", event); + MessageHistoryUpdatedPayload payload = event.normalizedData(MessageHistoryUpdatedPayload.class); + if (Objects.isNull(payload) || StringUtils.isBlank(payload.getNewMessageHistory().getBizId())) { + return; + } + + if (!payload.getNewMessageHistory().getBizId().startsWith(SendMessageJob.BIZ_ID_PREFIX)) { + log.info("push-handler 非op-message的消息"); + return; + } + + if (!payload.isSuccess()) { + log.info("push-handler is not success"); + return; + } + + if (payload.getNewMessageHistory().getImMessageTaskId() == null) { + log.info("push-handler imMessageTaskId is null"); + return; + } + + Optional opMessageConfigDTO = opMessageConfigService.page(OpMessageConfigService.PageOpMessageConfigParam.builder() + .imMessageTaskId(payload.getNewMessageHistory().getImMessageTaskId()) + .build()) + .getRecords() + .stream() + .findFirst(); + if (!opMessageConfigDTO.isPresent()) { + log.info("push-handler imMessageTaskId is not found,{}", payload.getNewMessageHistory().getImMessageTaskId()); + return; + } + + if (opMessageConfigDTO.get().getPushData() == null) { + log.info("push-handler, opMessageConfig:{},未配置push信息", opMessageConfigDTO.get().getId()); + return; + } + OpMessageConfig.PushData pushData = opMessageConfigDTO.get().getPushData().toJavaObject(OpMessageConfig.PushData.class); + + if (BooleanUtils.isNotTrue(pushData.isSwitchOn())) { + log.info("push-handler, opMessageConfig:{},push开关未打开", opMessageConfigDTO.get().getId()); + return; + } + + MessageHistoryUpdatedPayload.MessageHistory newMessageHistory = payload.getNewMessageHistory(); + MessageHistoryUpdatedPayload.MessageBody messageBody = newMessageHistory.resolveMessageBody(); + messagePushApi.sendPushMessage(MsgBody4Guest.builder() + .ty(0) + .f("0") + .appClient(newMessageHistory.getAppType()) + .m(messageBody.getMsgContent()) + .m3(newMessageHistory.getReceivePersonId()) + .m2(resolveM2(messageBody, pushData)) + // 为了兼容老版本,保证老版本的工人端能收到push,所以新的push都alias都是person + .t("not_identity" + newMessageHistory.getReceivePersonId()) + .ouId(newMessageHistory.getReceiveOuId()) + .build()); + + log.info("end push-handler rocketmq event: {}", event); + } + + private String resolveM2(MessageHistoryUpdatedPayload.MessageBody messageBody, + OpMessageConfig.PushData pushData) { + JSONObject jsonObject = new JSONObject() + .fluentPut("t", messageBody.getMsgHeader()) + .fluentPut("type", 0); + if (StringUtils.isNotBlank(pushData.getVoiceFile())) { + jsonObject.fluentPut("audio", pushData.getVoiceFile()); + } + + List actionPaths = messageBody.resolveMsgBody().getCardDetailButton().getActionPaths(); + if (CollectionUtils.isNotEmpty(actionPaths)) { + resolveRouter(jsonObject, actionPaths); + } + return jsonObject.toJSONString(); + } + + /** + * + * @param jsonObject + * @param actionPaths + */ + private void resolveRouter(JSONObject jsonObject, List actionPaths) { + + Map actionPathMap = actionPaths.stream() + .collect(Collectors.toMap(MessageHistoryUpdatedPayload.ActionPath::getPlatform, Function.identity())); + Optional routerType = ROUTER_TYPE_SORTED.stream() + .map(actionPathMap::get) + .filter(Objects::nonNull) + .findFirst(); + routerType.ifPresent(actionPath -> jsonObject.fluentPut("rt", PLATFORM_ROUTER_TYPE.get(actionPath.getPlatform()))); + + Optional ios = IOS_URL_SORTED.stream() + .map(actionPathMap::get) + .filter(Objects::nonNull) + .findFirst(); + // IOS的跳转URL + ios.ifPresent(actionPath -> jsonObject.fluentPut("ir", actionPath.getUrl())); + + Optional android = ANDROID_URL_SORTED.stream() + .map(actionPathMap::get) + .filter(Objects::nonNull) + .findFirst(); + // ANDROID的跳转URL + android.ifPresent(actionPath -> jsonObject.fluentPut("ar", actionPath.getUrl())); + + } + + @Override + public void afterPropertiesSet() throws Exception { + eventConsumer.registerHandler(EventTypeEnum.MESSAGE_HISTORY_UPDATED.getEventCode(), this); + } +} diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/event/payload/MessageHistoryUpdatedPayload.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/payload/MessageHistoryUpdatedPayload.java new file mode 100644 index 00000000..3b4c24b7 --- /dev/null +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/payload/MessageHistoryUpdatedPayload.java @@ -0,0 +1,176 @@ +package cn.axzo.nanopart.server.event.payload; + +import cn.axzo.im.center.common.enums.AppTypeEnum; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Maps; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MessageHistoryUpdatedPayload implements Serializable { + + public static final String IOS_PLATFORM = "IOS"; + public static final String ANDROID_PLATFORM = "ANDROID"; + public static final String WEBVIEW_PLATFORM = "WEBVIEW"; + public static final String MINI_PROGRAM_PLATFORM = "MINI_PROGRAM"; + public static final String WECHAT_MINI_PROGRAM_PLATFORM = "WECHAT_MINI_PROGRAM"; + + public static final Map PLATFORM_ROUTER_TYPE = Maps.newHashMap(); + static { + PLATFORM_ROUTER_TYPE.put(IOS_PLATFORM, 2); + PLATFORM_ROUTER_TYPE.put(ANDROID_PLATFORM, 2); + PLATFORM_ROUTER_TYPE.put(WEBVIEW_PLATFORM, 3); + PLATFORM_ROUTER_TYPE.put(MINI_PROGRAM_PLATFORM, 1); + PLATFORM_ROUTER_TYPE.put(WECHAT_MINI_PROGRAM_PLATFORM, 5); + } + + private MessageHistory newMessageHistory; + private MessageHistory oldMessageHistory; + + public boolean isSuccess() { + return !Objects.equals(newMessageHistory.getStatus(), oldMessageHistory.getStatus()) + && Objects.equals(newMessageHistory.getStatus(), MessageHistory.Status.SUCCEED.name()); + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class MessageHistory implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + /** + * 上游业务请求ID + */ + private String bizId; + + /** + * 普通用户,通过appType包装 + * 包装以后进行账户注册 + */ + private String messageId; + + /** + * 发送者IM账户 + */ + private String fromAccount; + + /** + * 发送者IM账户 + */ + private String toAccount; + + /** + * 终端类型 + * + * @see AppTypeEnum + */ + private String appType; + + /** + * channel 网易云信 + */ + private String channel; + + private String messageBody; + + private String result; + + private Long imMessageTaskId; + + private String receivePersonId; + + private Long receiveOuId; + + private String status; + + private Integer isDelete; + + private Date createAt; + + private Date updateAt; + + public enum Status { + PENDING, + SUCCEED, + FAILED, + ; + } + + public MessageBody resolveMessageBody() { + return JSONObject.parseObject(messageBody, MessageBody.class); + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class MessageBody { + + /** + * 模板消息:Template、聊天消息:Chat、通知消息:Notify + */ + private String msgType; + + /** + * 消息标题 + */ + private String msgHeader; + + /** + * 消息内容 + */ + private String msgContent; + + /** + * 消息通知结构体 + */ + private String msgBody; + + public MsgBody resolveMsgBody() { + return JSONObject.parseObject(msgBody, MsgBody.class); + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class MsgBody { + private CardDetailButton cardDetailButton; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class CardDetailButton { + private List actionPaths; + + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ActionPath { + private String platform; + + private String url; + } +} diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index 42e0d8df..25b0d0b4 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -160,6 +160,9 @@ public interface OpMessageConfigService extends IService { @CriteriaField(field = "contentType", operator = Operator.EQ) private String contentType; + @CriteriaField(field = "imMessageTaskId", operator = Operator.EQ) + private Long imMessageTaskId; + @CriteriaField(ignore = true) private List receivePlatforms;; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index e8986964..162fceae 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -37,6 +37,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class SendMessageJob extends IJobHandler { + public static final String BIZ_ID_PREFIX = "op-message"; @Autowired private OpMessageConfigService opMessageConfigService; @Autowired @@ -96,14 +97,15 @@ public class SendMessageJob extends IJobHandler { List appTypes = BooleanUtils.isTrue(isAllPerson) ? receiveData.getPlatforms().stream().map(AppTypeEnum::valueOf).collect(Collectors.toList()) : null; MessageTaskResp messageTask = messageApi.sendMessageAsync(AsyncSendMessageParam.builder() - .sendImAccount(opMessageConfig.getSendImAccount()) - .receivePersons(resolveReceivePerson(receiveData)) - .allPerson(isAllPerson) - .appTypes(appTypes) - .msgHeader(opMessageConfig.getTitle()) - .msgContent(opMessageConfig.getContent()) - .jumpData(resolveJumpData(opMessageConfig)) - .cardBannerUrl(opMessageConfig.getCoverImg()) + .bizId(String.format("%s:%s", BIZ_ID_PREFIX, opMessageConfig.getId())) + .sendImAccount(opMessageConfig.getSendImAccount()) + .receivePersons(resolveReceivePerson(receiveData)) + .allPerson(isAllPerson) + .appTypes(appTypes) + .msgHeader(opMessageConfig.getTitle()) + .msgContent(opMessageConfig.getContent()) + .jumpData(resolveJumpData(opMessageConfig)) + .cardBannerUrl(opMessageConfig.getCoverImg()) .build()).getData(); opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() From 8d4c0a3bc1c0195c95a1af114b285c7dffe91e5b Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 29 Mar 2024 13:32:25 +0800 Subject: [PATCH 11/25] =?UTF-8?q?feat:=20=E5=8F=91=E9=80=81=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/event/outer/PushYouMengMessageHandler.java | 1 + .../cn/axzo/nanopart/server/xxljob/SendMessageJob.java | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java index df2bd05a..b667a47f 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java @@ -125,6 +125,7 @@ public class PushYouMengMessageHandler implements EventHandler, InitializingBean // 为了兼容老版本,保证老版本的工人端能收到push,所以新的push都alias都是person .t("not_identity" + newMessageHistory.getReceivePersonId()) .ouId(newMessageHistory.getReceiveOuId()) + .pushType(pushData.getType()) .build()); log.info("end push-handler rocketmq event: {}", event); diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 162fceae..e1f43a98 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -118,7 +118,7 @@ public class SendMessageJob extends IJobHandler { } - private List resolveReceivePerson(OpMessageConfig.ReceiveData receiveData) { + private List resolveReceivePerson(OpMessageConfig.ReceiveData receiveData) { OpMessageConfig.ReceiveType receiveType = OpMessageConfig.ReceiveType.of(receiveData.getType()); boolean isAllPerson = Objects.equals(OpMessageConfig.ReceiveType.ALL, receiveType); @@ -129,9 +129,10 @@ public class SendMessageJob extends IJobHandler { return receiveData.getPlatforms().stream() .flatMap(platform -> receiveData.getPersons() .stream() - .map(person -> cn.axzo.im.center.api.vo.req.SendMessageParam.ReceivePerson.builder() + .map(person -> AsyncSendMessageParam.ReceivePerson.builder() .personId(person.getPersonId().toString()) - .ouId(person.getOuId()) + // 现在工人端是不会有ouId + .ouId(AppTypeEnum.valueOf(platform) == AppTypeEnum.CM ? null : person.getOuId()) .appType(AppTypeEnum.valueOf(platform)) .build()) ) From 1230e00fbf52ce5c0f5fc4849644d2d9acd18764 Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 29 Mar 2024 15:38:17 +0800 Subject: [PATCH 12/25] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E8=8D=89=E7=A8=BF?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E3=80=81=E6=8F=90=E4=BA=A4=E7=9A=84=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanopart/server/controller/OpMessageConfigController.java | 4 ++-- .../axzo/nanopart/server/service/OpMessageConfigService.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java index 35276af6..7cd15ad7 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java @@ -64,7 +64,7 @@ public class OpMessageConfigController implements OpMessageConfigApi { // 默认状态为待执行,创建人就是提交审核人 createOpMessageConfigParam.setSubmitPersonId(param.getOperatePersonId()); createOpMessageConfigParam.setCreatePersonId(param.getOperatePersonId()); - createOpMessageConfigParam.setStatus(OpMessageConfig.Status.PENDING.name()); + createOpMessageConfigParam.setStatus(OpMessageConfig.Status.PENDING); createOpMessageConfigParam.setPlanStartTime(resolvePlanStartTime(param.getReceiveData(), param.getPlanStartTime())); OpMessageConfig opMessageConfig = opMessageConfigService.create(createOpMessageConfigParam); @@ -111,7 +111,7 @@ public class OpMessageConfigController implements OpMessageConfigApi { if (req.getId() == null) { OpMessageConfigService.CreateOpMessageConfigParam createOpMessageConfigParam = OpMessageConfigService.CreateOpMessageConfigParam.builder().build(); BeanUtils.copyProperties(req, createOpMessageConfigParam); - createOpMessageConfigParam.setStatus(OpMessageConfig.Status.DRAFT.name()); + createOpMessageConfigParam.setStatus(OpMessageConfig.Status.DRAFT); createOpMessageConfigParam.setCreatePersonId(req.getOperatePersonId()); OpMessageConfig opMessageConfig = opMessageConfigService.create(createOpMessageConfigParam); diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index 25b0d0b4..276761bd 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -106,7 +106,7 @@ public interface OpMessageConfigService extends IService { private JSONObject receiveData; - private String status; + private OpMessageConfig.Status status; private String title; From c56549b1dce878493998e78a6ac7c2ddc051122e Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 29 Mar 2024 19:51:05 +0800 Subject: [PATCH 13/25] =?UTF-8?q?feat:=20=E8=A7=A3=E5=86=B3push=E6=97=B6?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E9=85=8D=E7=BD=AE=E8=B7=B3=E8=BD=AC=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../outer/PushYouMengMessageHandler.java | 7 ++- .../server/xxljob/SendMessageJob.java | 49 +++++++++++++++---- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java index b667a47f..ddcfca67 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/event/outer/PushYouMengMessageHandler.java @@ -139,10 +139,9 @@ public class PushYouMengMessageHandler implements EventHandler, InitializingBean if (StringUtils.isNotBlank(pushData.getVoiceFile())) { jsonObject.fluentPut("audio", pushData.getVoiceFile()); } - - List actionPaths = messageBody.resolveMsgBody().getCardDetailButton().getActionPaths(); - if (CollectionUtils.isNotEmpty(actionPaths)) { - resolveRouter(jsonObject, actionPaths); + MessageHistoryUpdatedPayload.CardDetailButton cardDetailButton = messageBody.resolveMsgBody().getCardDetailButton(); + if (cardDetailButton != null && CollectionUtils.isNotEmpty(cardDetailButton.getActionPaths())) { + resolveRouter(jsonObject, cardDetailButton.getActionPaths()); } return jsonObject.toJSONString(); } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index e1f43a98..07e90cf1 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -126,16 +126,45 @@ public class SendMessageJob extends IJobHandler { return Collections.emptyList(); } - return receiveData.getPlatforms().stream() - .flatMap(platform -> receiveData.getPersons() - .stream() - .map(person -> AsyncSendMessageParam.ReceivePerson.builder() - .personId(person.getPersonId().toString()) - // 现在工人端是不会有ouId - .ouId(AppTypeEnum.valueOf(platform) == AppTypeEnum.CM ? null : person.getOuId()) - .appType(AppTypeEnum.valueOf(platform)) - .build()) - ) + List cmReceivePersons = listCmReceivePersons(receiveData); + List cmpReceivePersons = listCmPReceivePersons(receiveData); + cmReceivePersons.addAll(cmpReceivePersons); + return cmReceivePersons; + } + + private List listCmReceivePersons(OpMessageConfig.ReceiveData receiveData) { + boolean isCm = receiveData.getPlatforms().stream() + .anyMatch(platform -> AppTypeEnum.valueOf(platform) == AppTypeEnum.CM); + + if (BooleanUtils.isNotTrue(isCm)) { + return Collections.emptyList(); + } + + return receiveData.getPersons().stream() + .map(OpMessageConfig.Person::getPersonId) + .distinct() + .map(personId -> AsyncSendMessageParam.ReceivePerson.builder() + .personId(personId.toString()) + .appType(AppTypeEnum.CM) + .build()) + .collect(Collectors.toList()); + } + + + private List listCmPReceivePersons(OpMessageConfig.ReceiveData receiveData) { + boolean isCmp = receiveData.getPlatforms().stream() + .anyMatch(platform -> AppTypeEnum.valueOf(platform) == AppTypeEnum.CMP); + + if (BooleanUtils.isNotTrue(isCmp)) { + return Collections.emptyList(); + } + + return receiveData.getPersons().stream() + .map(person -> AsyncSendMessageParam.ReceivePerson.builder() + .personId(person.getPersonId().toString()) + .ouId(person.getOuId()) + .appType(AppTypeEnum.CM) + .build()) .collect(Collectors.toList()); } From eaaef501e0716c102cf0c169d54e0d7684c38b49 Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 29 Mar 2024 20:10:31 +0800 Subject: [PATCH 14/25] =?UTF-8?q?feat:=20=E8=A7=A3=E5=86=B3=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E8=B7=9FCM,CMP=E7=AB=AF=E7=9A=84=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 07e90cf1..0a1dd736 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -150,7 +150,6 @@ public class SendMessageJob extends IJobHandler { .collect(Collectors.toList()); } - private List listCmPReceivePersons(OpMessageConfig.ReceiveData receiveData) { boolean isCmp = receiveData.getPlatforms().stream() .anyMatch(platform -> AppTypeEnum.valueOf(platform) == AppTypeEnum.CMP); @@ -160,10 +159,11 @@ public class SendMessageJob extends IJobHandler { } return receiveData.getPersons().stream() + .filter(person -> person.getOuId() != null) .map(person -> AsyncSendMessageParam.ReceivePerson.builder() .personId(person.getPersonId().toString()) .ouId(person.getOuId()) - .appType(AppTypeEnum.CM) + .appType(AppTypeEnum.CMP) .build()) .collect(Collectors.toList()); } From ab72ae6e6b3af68e328ff6b0c862f274134f184c Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 1 Apr 2024 09:34:05 +0800 Subject: [PATCH 15/25] =?UTF-8?q?feat:=20=E5=88=86=E9=A1=B5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=A2=9E=E5=8A=A0=E6=8F=90=E4=BA=A4=E4=BA=BA=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanopart/server/controller/OpMessageConfigController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java index 7cd15ad7..8a55ea30 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/controller/OpMessageConfigController.java @@ -50,7 +50,7 @@ public class OpMessageConfigController implements OpMessageConfigApi { if (record.getSubmitPersonProfile() != null) { PersonProfileDto submitPersonProfile = PersonProfileDto.builder().build(); BeanUtils.copyProperties(record.getSubmitPersonProfile(), submitPersonProfile); - opMessageConfigResp.setCreatePersonProfile(submitPersonProfile); + opMessageConfigResp.setSubmitPersonProfile(submitPersonProfile); } return opMessageConfigResp; From 7293dff5ed13f935df0f2b7e8a84c9c5d556a685 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 1 Apr 2024 13:36:46 +0800 Subject: [PATCH 16/25] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=8E=A5=E6=94=B6=E4=BA=BA=E8=B4=A6=E5=8F=B7=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 0a1dd736..51fd69df 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -137,7 +137,7 @@ public class SendMessageJob extends IJobHandler { .anyMatch(platform -> AppTypeEnum.valueOf(platform) == AppTypeEnum.CM); if (BooleanUtils.isNotTrue(isCm)) { - return Collections.emptyList(); + return Lists.newArrayList(); } return receiveData.getPersons().stream() @@ -155,7 +155,7 @@ public class SendMessageJob extends IJobHandler { .anyMatch(platform -> AppTypeEnum.valueOf(platform) == AppTypeEnum.CMP); if (BooleanUtils.isNotTrue(isCmp)) { - return Collections.emptyList(); + return Lists.newArrayList(); } return receiveData.getPersons().stream() From 400e1f03ea9cc4437405602afb924c8b7ff43976 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 1 Apr 2024 16:23:00 +0800 Subject: [PATCH 17/25] =?UTF-8?q?feat:=20=E5=AD=98=E5=9C=A8=E5=8F=AA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BA=86=E7=AE=A1=E7=90=86=E7=AB=AF=EF=BC=8C?= =?UTF-8?q?=E4=BD=86=E6=98=AFimport=E7=9A=84=E4=BA=BA=E5=91=98=E6=B2=A1?= =?UTF-8?q?=E5=AF=BC=E5=85=A5ouId=EF=BC=8C=E5=AF=BC=E8=87=B4=E6=8E=A5?= =?UTF-8?q?=E6=94=B6=E4=BA=BA=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/xxljob/SendMessageJob.java | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 51fd69df..b73bc6c2 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -96,25 +96,35 @@ public class SendMessageJob extends IJobHandler { List appTypes = BooleanUtils.isTrue(isAllPerson) ? receiveData.getPlatforms().stream().map(AppTypeEnum::valueOf).collect(Collectors.toList()) : null; - MessageTaskResp messageTask = messageApi.sendMessageAsync(AsyncSendMessageParam.builder() - .bizId(String.format("%s:%s", BIZ_ID_PREFIX, opMessageConfig.getId())) - .sendImAccount(opMessageConfig.getSendImAccount()) - .receivePersons(resolveReceivePerson(receiveData)) - .allPerson(isAllPerson) - .appTypes(appTypes) - .msgHeader(opMessageConfig.getTitle()) - .msgContent(opMessageConfig.getContent()) - .jumpData(resolveJumpData(opMessageConfig)) - .cardBannerUrl(opMessageConfig.getCoverImg()) - .build()).getData(); - - opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() - .id(opMessageConfig.getId()) - .imMessageTaskId(messageTask.getId()) - // 消息是异步执行的,准确的完成时间,需要监听messageTask的完成时间才准确,现在mq配置较低,消息服务没有发送mq - .finishedTime(new Date()) - .action(OpMessageConfig.ActionEnum.COMPLETE) - .build()); + List receivePersons = resolveReceivePerson(receiveData); + if (CollectionUtils.isNotEmpty(receivePersons)) { + MessageTaskResp messageTask = messageApi.sendMessageAsync(AsyncSendMessageParam.builder() + .bizId(String.format("%s:%s", BIZ_ID_PREFIX, opMessageConfig.getId())) + .sendImAccount(opMessageConfig.getSendImAccount()) + .receivePersons(receivePersons) + .allPerson(isAllPerson) + .appTypes(appTypes) + .msgHeader(opMessageConfig.getTitle()) + .msgContent(opMessageConfig.getContent()) + .jumpData(resolveJumpData(opMessageConfig)) + .cardBannerUrl(opMessageConfig.getCoverImg()) + .build()).getData(); + opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() + .id(opMessageConfig.getId()) + .imMessageTaskId(messageTask.getId()) + // 消息是异步执行的,准确的完成时间,需要监听messageTask的完成时间才准确,现在mq配置较低,消息服务没有发送mq + .finishedTime(new Date()) + .action(OpMessageConfig.ActionEnum.COMPLETE) + .build()); + } else { + // 存在只配置了管理端,但是import的人员没导入ouId,导致接收人为空 + opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() + .id(opMessageConfig.getId()) + // 消息是异步执行的,准确的完成时间,需要监听messageTask的完成时间才准确,现在mq配置较低,消息服务没有发送mq + .finishedTime(new Date()) + .action(OpMessageConfig.ActionEnum.COMPLETE) + .build()); + } } From bef172b954ea36f9f0066fe66bbcf38525e49e49 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 1 Apr 2024 16:31:31 +0800 Subject: [PATCH 18/25] =?UTF-8?q?feat:=20=E6=89=A7=E8=A1=8C=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=97=B6=EF=BC=8C=E6=9F=90=E4=B8=AA=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5catch=EF=BC=8C=E4=B8=8D=E8=83=BD=E9=98=BB?= =?UTF-8?q?=E5=A1=9E=E5=85=B6=E4=BB=96=E4=BB=BB=E5=8A=A1=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/nanopart/server/xxljob/SendMessageJob.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index b73bc6c2..d2a0f6aa 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -71,7 +71,13 @@ public class SendMessageJob extends IJobHandler { Page page = opMessageConfigService.page(req); if (CollectionUtils.isNotEmpty(page.getRecords())) { // 一个一个更新,数据量不大,一个失败不影响其他的运营消息 - page.getRecords().forEach(proxySendMessageJob::sendMessage); + page.getRecords().forEach(e -> { + try { + proxySendMessageJob.sendMessage(e); + } catch (Exception ex) { + log.error("job 执行失败, job{}, ex", e.getId(), ex); + } + }); } if (!page.hasNext()) { From f23f60640e62a625d65845d12bf533eea6ed6e1d Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 2 Apr 2024 15:46:34 +0800 Subject: [PATCH 19/25] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9pageNumber?= =?UTF-8?q?=E4=B8=BApage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/axzo/op/api/OpMessageConfigApi.java | 2 +- .../nanopart/server/service/OpMessageConfigService.java | 2 +- .../server/service/impl/OpMessageConfigServiceImpl.java | 5 +++-- .../cn/axzo/nanopart/server/xxljob/SendMessageJob.java | 2 +- op/op-server/src/test/resources/mysql/schema.sql | 8 ++++---- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java index 6b609b4c..fb51441c 100644 --- a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -170,7 +170,7 @@ public interface OpMessageConfigApi { @NoArgsConstructor @AllArgsConstructor class PageOpMessageConfigReq extends ListOpMessageConfigReq { - Integer pageNumber; + Integer page; Integer pageSize; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index 276761bd..4994f7c3 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -224,7 +224,7 @@ public interface OpMessageConfigService extends IService { @AllArgsConstructor class PageOpMessageConfigParam extends ListOpMessageConfigParam implements IPageParam { @CriteriaField(ignore = true) - Integer pageNumber; + Integer page; @CriteriaField(ignore = true) Integer pageSize; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java index 177e7fad..16fa111d 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/OpMessageConfigServiceImpl.java @@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -53,7 +54,7 @@ public class OpMessageConfigServiceImpl extends ServiceImpl OpMessageConfigDTO.from(record, sendUserInfos, - submitPersonProfiles, + createPersonProfiles, submitPersonProfiles)); } @@ -109,7 +110,7 @@ public class OpMessageConfigServiceImpl extends ServiceImpl sendImAccounts = opMessageConfigs.stream() .map(OpMessageConfig::getSendImAccount) - .filter(Objects::nonNull) + .filter(StringUtils::isNotBlank) .distinct() .collect(Collectors.toList()); if (CollectionUtils.isEmpty(sendImAccounts)) { diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index d2a0f6aa..64b4b0d9 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -64,7 +64,7 @@ public class SendMessageJob extends IJobHandler { .ids(sendMessageParam.getIds()) .planStartTimeLE(now) .statuses(Lists.newArrayList(OpMessageConfig.Status.PENDING.name())) - .pageNumber(pageNumber++) + .page(pageNumber++) .pageSize(DEFAULT_PAGE_SIZE) .build(); diff --git a/op/op-server/src/test/resources/mysql/schema.sql b/op/op-server/src/test/resources/mysql/schema.sql index ce6c2040..71b13e91 100644 --- a/op/op-server/src/test/resources/mysql/schema.sql +++ b/op/op-server/src/test/resources/mysql/schema.sql @@ -3,18 +3,18 @@ CREATE TABLE IF NOT EXISTS op_message_config ( id bigint auto_increment comment '主键', im_message_task_id bigint not null default 0 comment 'im-center服务im_message_task的id', - `name` varchar(50) not null comment '消息名字', - send_im_account varchar(100) not null comment '发送者的三方平台账号id', + `name` varchar(50) not null default '' comment '消息名字', + send_im_account varchar(100) not null default '' comment '发送者的三方平台账号id', receive_data json null comment '消息接收配置', status varchar(32) not null default 'DRAFT' comment '消息状态:DRAFT、PENDING、RUNNING、COMPLETED', title varchar(128) not null default '' comment '消息标题', content varchar(512) not null default '' comment '消息内容', - content_type varchar(32) not null comment '消息形式:IMAGE_TEXT_SAMPLE', + content_type varchar(32) not null default '' comment '消息形式:IMAGE_TEXT_SAMPLE', cover_img varchar(512) not null default '' comment '消息封面大图', jump_data json comment '跳转配置', push_data json comment 'push配置', ext varchar(1024) not null default '{}' COMMENT '其它额外信息', - plan_start_time DATETIME(3) not null comment '任务计划开始时间,时间大于改时间会对未完成的任务进行执行操作', + plan_start_time DATETIME(3) null comment '任务计划开始时间,时间大于改时间会对未完成的任务进行执行操作', started_time DATETIME(3) null comment '实际开始时间', finished_time DATETIME(3) null comment '实际完成时间', submit_time DATETIME(3) null comment '提交审核时间', From b4769328b7c01e16291e284a5b3c0d30d1972010 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 3 Apr 2024 10:56:22 +0800 Subject: [PATCH 20/25] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0im=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E6=A8=A1=E7=B3=8A=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java | 2 ++ .../axzo/nanopart/server/service/OpMessageConfigService.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java index fb51441c..c7adea0a 100644 --- a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -143,6 +143,8 @@ public interface OpMessageConfigApi { private String sendImAccount; + private String sendImAccountList; + private String contentType; private List receivePlatforms; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index 4994f7c3..593f9dee 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -151,6 +151,9 @@ public interface OpMessageConfigService extends IService { @CriteriaField(field = "sendImAccount", operator = Operator.EQ) private String sendImAccount; + @CriteriaField(field = "sendImAccount", operator = Operator.LIKE) + private String sendImAccountList; + @CriteriaField(field = "planStartTime", operator = Operator.LE) private Date planStartTimeLE; From 7bd417da029894f93e534bd6bcd8b084aeafd582 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 3 Apr 2024 13:42:23 +0800 Subject: [PATCH 21/25] =?UTF-8?q?feat:=20=E5=8F=91=E9=80=81=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=97=B6=E5=A2=9E=E5=8A=A0workspaceId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/xxljob/SendMessageJob.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 64b4b0d9..6e7d8e5e 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -4,6 +4,9 @@ import cn.axzo.im.center.api.feign.MessageApi; import cn.axzo.im.center.api.vo.req.AsyncSendMessageParam; import cn.axzo.im.center.api.vo.resp.MessageTaskResp; import cn.axzo.im.center.common.enums.AppTypeEnum; +import cn.axzo.maokai.api.client.CooperateShipQueryApi; +import cn.axzo.maokai.api.vo.request.CooperateShipQueryReq; +import cn.axzo.maokai.api.vo.response.CooperateShipResp; import cn.axzo.nanopart.server.domain.OpMessageConfig; import cn.axzo.nanopart.server.service.OpMessageConfigService; import com.alibaba.fastjson.JSONObject; @@ -28,6 +31,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -44,6 +48,8 @@ public class SendMessageJob extends IJobHandler { private MessageApi messageApi; @Autowired private ApplicationContext applicationContext; + @Autowired + private CooperateShipQueryApi cooperateShipQueryApi; private static final Integer DEFAULT_PAGE_SIZE = 10; @@ -174,16 +180,37 @@ public class SendMessageJob extends IJobHandler { return Lists.newArrayList(); } + Map workspaceIds = listWorkspaceIds(receiveData); + return receiveData.getPersons().stream() .filter(person -> person.getOuId() != null) .map(person -> AsyncSendMessageParam.ReceivePerson.builder() .personId(person.getPersonId().toString()) .ouId(person.getOuId()) .appType(AppTypeEnum.CMP) + .workspaceId(workspaceIds.get(person.getOuId())) .build()) .collect(Collectors.toList()); } + private Map listWorkspaceIds(OpMessageConfig.ReceiveData receiveData) { + List ouIds = receiveData.getPersons().stream() + .map(OpMessageConfig.Person::getOuId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ouIds)) { + return Collections.emptyMap(); + } + + return cooperateShipQueryApi.genericQuery(CooperateShipQueryReq.builder() + .ouIdList(ouIds) + .build()) + .getData() + .stream() + .collect(Collectors.toMap(CooperateShipResp::getOrganizationalUnitId, CooperateShipResp::getWorkspaceId)); + } + private List resolveJumpData(OpMessageConfigService.OpMessageConfigDTO opMessageConfig) { return opMessageConfig.resolveJumpData().getPlatforms().stream() .map(platform -> cn.axzo.im.center.api.vo.req.SendMessageParam.JumpData.builder() From 52563936af99d2ebb1ef6a5a431c8763f2e5ee3c Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 3 Apr 2024 14:19:11 +0800 Subject: [PATCH 22/25] =?UTF-8?q?feat:=20=E8=A7=A3=E5=86=B3=E4=B8=80?= =?UTF-8?q?=E4=B8=AAouIds=E6=89=BE=E5=88=B0=E5=A4=9A=E4=B8=AAworkspaceId?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/nanopart/server/xxljob/SendMessageJob.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 6e7d8e5e..7ea0ef98 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -1,5 +1,6 @@ package cn.axzo.nanopart.server.xxljob; +import cn.axzo.framework.domain.web.result.ApiListResult; import cn.axzo.im.center.api.feign.MessageApi; import cn.axzo.im.center.api.vo.req.AsyncSendMessageParam; import cn.axzo.im.center.api.vo.resp.MessageTaskResp; @@ -202,13 +203,14 @@ public class SendMessageJob extends IJobHandler { if (CollectionUtils.isEmpty(ouIds)) { return Collections.emptyMap(); } - - return cooperateShipQueryApi.genericQuery(CooperateShipQueryReq.builder() + log.info("list workspaceId,{}", ouIds); + ApiListResult cooperateShipRespApiListResult = cooperateShipQueryApi.genericQuery(CooperateShipQueryReq.builder() .ouIdList(ouIds) - .build()) - .getData() + .build()); + log.info("list workspaceId result,{}", cooperateShipRespApiListResult); + return cooperateShipRespApiListResult.getData() .stream() - .collect(Collectors.toMap(CooperateShipResp::getOrganizationalUnitId, CooperateShipResp::getWorkspaceId)); + .collect(Collectors.toMap(CooperateShipResp::getOrganizationalUnitId, CooperateShipResp::getWorkspaceId, (f, s) -> f)); } private List resolveJumpData(OpMessageConfigService.OpMessageConfigDTO opMessageConfig) { From e60eadd139369d303f6e56ec8a80194ac07f81b6 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 3 Apr 2024 14:34:31 +0800 Subject: [PATCH 23/25] =?UTF-8?q?feat:=20=E6=9F=A5=E8=AF=A2=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E9=83=A8=E6=97=B6=E5=8F=AA=E6=9F=A5=E8=AF=A2=E4=BC=81?= =?UTF-8?q?=E4=B8=9A=E9=A1=B9=E7=9B=AE=E9=83=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java | 1 + 1 file changed, 1 insertion(+) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index 7ea0ef98..a0eaac5e 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -206,6 +206,7 @@ public class SendMessageJob extends IJobHandler { log.info("list workspaceId,{}", ouIds); ApiListResult cooperateShipRespApiListResult = cooperateShipQueryApi.genericQuery(CooperateShipQueryReq.builder() .ouIdList(ouIds) + .workspaceType(1) .build()); log.info("list workspaceId result,{}", cooperateShipRespApiListResult); return cooperateShipRespApiListResult.getData() From 86ec567ed4b1c6203365c46eb1f4ea346b42094e Mon Sep 17 00:00:00 2001 From: lilong Date: Sun, 7 Apr 2024 10:12:12 +0800 Subject: [PATCH 24/25] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9page=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E7=9A=84=E6=95=B0=E6=8D=AE=E7=8A=B6=E6=80=81=E8=A2=AB?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8Cpage?= =?UTF-8?q?=E5=86=99=E6=88=90=E7=AC=AC=E4=B8=80=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index a0eaac5e..fc5c60c4 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -71,7 +71,7 @@ public class SendMessageJob extends IJobHandler { .ids(sendMessageParam.getIds()) .planStartTimeLE(now) .statuses(Lists.newArrayList(OpMessageConfig.Status.PENDING.name())) - .page(pageNumber++) + .page(pageNumber) .pageSize(DEFAULT_PAGE_SIZE) .build(); From 8abf00079a59c864fbb5621c0fbc28cb60a7f190 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 9 Apr 2024 17:20:51 +0800 Subject: [PATCH 25/25] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E5=85=A8?= =?UTF-8?q?=E5=91=98=E5=8F=91=E9=80=81=E6=97=B6=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/op/api/OpMessageConfigApi.java | 2 +- .../service/OpMessageConfigService.java | 2 +- .../server/xxljob/SendMessageJob.java | 19 ++++++++++--------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java index c7adea0a..8f1cfb8c 100644 --- a/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java +++ b/op/op-api/src/main/java/cn/axzo/op/api/OpMessageConfigApi.java @@ -143,7 +143,7 @@ public interface OpMessageConfigApi { private String sendImAccount; - private String sendImAccountList; + private String sendImAccountLike; private String contentType; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java index 593f9dee..3a83c88a 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/OpMessageConfigService.java @@ -152,7 +152,7 @@ public interface OpMessageConfigService extends IService { private String sendImAccount; @CriteriaField(field = "sendImAccount", operator = Operator.LIKE) - private String sendImAccountList; + private String sendImAccountLike; @CriteriaField(field = "planStartTime", operator = Operator.LE) private Date planStartTimeLE; diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java index fc5c60c4..751df7b9 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/xxljob/SendMessageJob.java @@ -110,7 +110,16 @@ public class SendMessageJob extends IJobHandler { List appTypes = BooleanUtils.isTrue(isAllPerson) ? receiveData.getPlatforms().stream().map(AppTypeEnum::valueOf).collect(Collectors.toList()) : null; List receivePersons = resolveReceivePerson(receiveData); - if (CollectionUtils.isNotEmpty(receivePersons)) { + // 接收方式是import,且解析后没有接收人,则直接完成任务 + // 存在只配置了管理端,但是import的人员没导入ouId,导致接收人为空 + if (CollectionUtils.isEmpty(receivePersons) && Objects.equals(OpMessageConfig.ReceiveType.IMPORT, receiveType)) { + opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() + .id(opMessageConfig.getId()) + // 消息是异步执行的,准确的完成时间,需要监听messageTask的完成时间才准确,现在mq配置较低,消息服务没有发送mq + .finishedTime(new Date()) + .action(OpMessageConfig.ActionEnum.COMPLETE) + .build()); + } else { MessageTaskResp messageTask = messageApi.sendMessageAsync(AsyncSendMessageParam.builder() .bizId(String.format("%s:%s", BIZ_ID_PREFIX, opMessageConfig.getId())) .sendImAccount(opMessageConfig.getSendImAccount()) @@ -129,14 +138,6 @@ public class SendMessageJob extends IJobHandler { .finishedTime(new Date()) .action(OpMessageConfig.ActionEnum.COMPLETE) .build()); - } else { - // 存在只配置了管理端,但是import的人员没导入ouId,导致接收人为空 - opMessageConfigService.update(OpMessageConfigService.UpdateOpMessageConfigParam.builder() - .id(opMessageConfig.getId()) - // 消息是异步执行的,准确的完成时间,需要监听messageTask的完成时间才准确,现在mq配置较低,消息服务没有发送mq - .finishedTime(new Date()) - .action(OpMessageConfig.ActionEnum.COMPLETE) - .build()); } }