Merge branch 'feature/REQ-1507' of axzsource.com:universal/infrastructure/backend/msg-center-plat into pre

This commit is contained in:
luofu 2023-11-23 18:22:29 +08:00
commit b2048b7064
11 changed files with 120 additions and 28 deletions

View File

@ -334,6 +334,7 @@ public class MessageCoreServiceImpl implements MessageCoreService {
param.setOperator(PersonDTO.builder().id(request.getPersonId()).build());
param.setTerminalType(AppTerminalTypeEnum.CMS_WEB_PC);
param.setWithIdentify(false);
param.setOuId(request.getOuId());
int pendingCnt = pendingMessageNewService.countUncompleted(param);
return new MessageStatisticRes(generalCnt, pendingCnt);
}

View File

@ -5,6 +5,7 @@ import cn.axzo.msg.center.service.dto.IdentityDTO;
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
import cn.axzo.msg.center.service.dto.PersonDTO;
import cn.axzo.msg.center.service.enums.BizCategoryEnum;
import cn.axzo.msg.center.service.enums.BizFinalStateEnum;
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
@ -124,9 +125,9 @@ public class PendingMessageDTO implements Serializable {
*/
private MessageTemplateRouterDTO msgTemplateRouter;
/**
* 业务终态的印章图片地址
* 业务终态
*/
private String bizFinalStateIcon;
private BizFinalStateEnum bizFinalState;
/**
* 路由参数
*/
@ -172,6 +173,7 @@ public class PendingMessageDTO implements Serializable {
.createTime(DateFormatUtil.toLocalDateTime(pendingMessageRecord.getCreateAt()))
.updateTime(DateFormatUtil.toLocalDateTime(pendingMessageRecord.getUpdateAt()))
.routerParam(pendingMessageRecord.getRouterParams())
.bizFinalState(pendingMessageRecord.getBizFinalState())
.build();
}
@ -201,7 +203,7 @@ public class PendingMessageDTO implements Serializable {
.deadlineTimestamp(DateFormatUtil.toTimestamp(this.deadline))
.detailRouter(MessageRouterUtil.fetchBizDetailRouter(this.msgTemplateRouter, terminalType).orElse(null))
.buttonRouters(MessageRouterUtil.fetchMessageRouterButtons(this.msgTemplateRouter, terminalType))
.bizFinalStateIcon(this.bizFinalStateIcon)
.bizFinalStateIcon(Optional.ofNullable(bizFinalState).map(BizFinalStateEnum::getIcon).orElse(null))
.build();
}

View File

@ -30,6 +30,10 @@ public class MessageGroupNodeStatisticParam implements Serializable {
* 当前登录账户的自然id(前端不care)
*/
private PersonDTO operator;
/**
* 单位id
*/
private Long ouId;
/**
* 应用终端类型
*/

View File

@ -111,6 +111,7 @@ public class PendingMessageDataInitServiceImpl implements PendingMessageDataInit
log.info("[cold_blade] transform rows:[{}]", pendingMessageRecords.size());
Map<String, Long> executorIdWorkspceIdMap = pendingMessageRecords.stream()
.filter(e -> Objects.equals(e.getExecutorType(), IdentityTypeEnum.PRACTITIONER))
.filter(e -> filterWorkspaceId(e.getOrgId()))
.filter(e -> !ouIdMap.containsKey(getKey(e)))
.collect(Collectors.toMap(this::getKey, PendingMessageRecord::getExecutorId, (cur, next) -> next));
Map<String, Long> map = fetchOuId(executorIdWorkspceIdMap);
@ -192,6 +193,12 @@ public class PendingMessageDataInitServiceImpl implements PendingMessageDataInit
return msgTemplateMap.get(Integer.parseInt(String.valueOf(relationId)));
}
private boolean filterWorkspaceId(Long workspaceId) {
return Objects.nonNull(workspaceId)
&& workspaceId > 0
&& EXCLUDE_WORKSPACE_IDS.stream().map(Long::valueOf).noneMatch(e -> e.equals(workspaceId));
}
/**
* 原模板ID与test环境新模板ID映射表
*/

View File

@ -67,8 +67,10 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -142,6 +144,9 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
BizFinalStateEnum bizFinalState = fetchBizFinalState(request.getRoleCategory(), request.getBizFinalState());
// 开始构建分页查询条件
LambdaQueryChainWrapper<PendingMessageRecord> query = pendingMessageRecordDao.lambdaQuery()
// REQ-1507期发起人不通过ouId过滤
.eq(!PendingMessageRoleCategoryEnum.PROMOTER.equals(request.getRoleCategory())
&& Objects.nonNull(request.getOuId()), PendingMessageRecord::getOuId, request.getOuId())
.eq(Objects.nonNull(pendingMessageState), PendingMessageRecord::getState, pendingMessageState)
.eq(Objects.nonNull(bizFinalState), PendingMessageRecord::getBizFinalState, bizFinalState)
.eq(Objects.nonNull(request.getWorkspaceId()), PendingMessageRecord::getOrgId, request.getWorkspaceId());
@ -173,7 +178,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
}
query.in(PendingMessageRecord::getTemplateCode, templateCodes);
// 构建排序条件
buildSortCondition(query, request.getOrderFields());
buildSortCondition(query, request.getOrderFields(), pendingMessageState);
IPage<PendingMessageRecord> page = request.toPage();
IPage<PendingMessageRecord> result = query.page(page);
@ -195,6 +200,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
PersonDTO operator = PersonDTO.from(request.getPersonId(), request.getIdentityId(), request.getIdentityType());
// 开始构建分页查询条件
LambdaQueryChainWrapper<PendingMessageRecord> query = pendingMessageRecordDao.lambdaQuery()
.eq(Objects.nonNull(request.getOuId()), PendingMessageRecord::getOuId, request.getOuId())
.eq(Objects.nonNull(pendingMessageState), PendingMessageRecord::getState, pendingMessageState);
// 构建人维度的查询条件
buildPersonCondition(query, request.getWithIdentify(), request.getRoleCategory(), operator);
@ -221,7 +227,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
}
query.in(PendingMessageRecord::getTemplateCode, templateCodesPathMap.keySet());
// 构建排序条件
buildSortCondition(query, request.getOrderFields());
buildSortCondition(query, request.getOrderFields(), pendingMessageState);
IPage<PendingMessageRecord> result = query.page(request.toPage());
if (CollectionUtils.isEmpty(result.getRecords())) {
return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), Collections.emptyList());
@ -378,8 +384,17 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
.map(MessageTemplateDTO::getMsgTemplateRouter)
.orElse(null);
// 解析并替换掉路由地址中的动态参数变量
msgTemplateRouter = MessageRouterUtil
.parseAndConcatRouteUrl(msgTemplateRouter, JSONObjectUtil.parseObject(pendingMessageRecord.getRouterParams()));
JSONObject routerParam = JSONObjectUtil.parseObject(pendingMessageRecord.getRouterParams());
JSONObject authParam = new JSONObject();
if (!routerParam.containsKey("ouId")) {
authParam.put("ouId", pendingMessageRecord.getOuId());
}
if (!routerParam.containsKey("workspaceId")) {
authParam.put("workspaceId", pendingMessageRecord.getOrgId());
}
authParam.putAll(routerParam);
msgTemplateRouter = MessageRouterUtil.parseRouteUrl(msgTemplateRouter, authParam);
msgTemplateRouter = MessageRouterUtil.parseAndConcatRouteUrl(msgTemplateRouter, routerParam);
pendingMessage.setMsgTemplateRouter(msgTemplateRouter);
// 获取模板卡片信息
List<MessageCardContentItemDTO> msgCardContentItems = messageTemplates.stream()
@ -390,7 +405,6 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
// 解析并替换卡片信息里面的动态参数变量
msgCardContentItems = MessageCardUtil.parseMessageCard(msgCardContentItems, pendingMessageRecord.getBizExtParam());
pendingMessage.setCardItems(msgCardContentItems);
// TODO: [cold_blade] [P0] 业务终态图标url
return pendingMessage;
}
@ -462,6 +476,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
}
LambdaQueryChainWrapper<PendingMessageRecord> query = pendingMessageRecordDao.lambdaQuery()
.in(PendingMessageRecord::getTemplateCode, templateCodes)
.eq(Objects.nonNull(param.getOuId()), PendingMessageRecord::getOuId, param.getOuId())
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT);
buildPersonCondition(query, param.getWithIdentify(), PendingMessageRoleCategoryEnum.EXECUTOR, param.getOperator());
return query.count();
@ -496,6 +511,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
personIdFunc = PendingMessageRecord::getPromoterPersonId;
identityIdFunc = PendingMessageRecord::getPromoterId;
identityTypeFunc = PendingMessageRecord::getPromoterType;
buildPromoterCondition(query, operator);
} else {
// 代办执行者查询条件
personIdFunc = PendingMessageRecord::getExecutorPersonId;
@ -509,11 +525,30 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
}
}
private void buildPromoterCondition(LambdaQueryChainWrapper<PendingMessageRecord> query, PersonDTO operator) {
Date queryFrom = DateFormatUtil.toDate(LocalDateTime.now().minusDays(90));
List<PendingMessageRecord> records = pendingMessageRecordDao.lambdaQuery()
.eq(PendingMessageRecord::getPromoterPersonId, operator.getId())
.gt(PendingMessageRecord::getCreateAt, queryFrom)
.select(PendingMessageRecord::getId, PendingMessageRecord::getRequestNo)
.list();
Map<String, List<PendingMessageRecord>> map = records.stream()
.collect(Collectors.groupingBy(PendingMessageRecord::getRequestNo));
List<Long> ids = map.values().stream()
.map(e -> e.stream().mapToLong(PendingMessageRecord::getId).max().orElse(0))
.collect(Collectors.toList());
query.in(CollectionUtils.isNotEmpty(ids), PendingMessageRecord::getId, ids);
}
private void buildSortCondition(LambdaQueryChainWrapper<PendingMessageRecord> query,
Collection<QueryOrderByDTO> orderFields) {
Collection<QueryOrderByDTO> orderFields, PendingMessageStateEnum state) {
if (CollectionUtils.isEmpty(orderFields)) {
// 默认时间降序
query.orderByDesc(PendingMessageRecord::getCreateAt);
if (PendingMessageStateEnum.COMPLETED.equals(state)) {
query.orderByDesc(PendingMessageRecord::getUpdateAt);
} else {
query.orderByDesc(PendingMessageRecord::getCreateAt);
}
return;
}
orderFields.stream()
@ -537,7 +572,8 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
record.setRequestNo(requestNo);
record.setState(PendingMessageStateEnum.HAS_BEEN_SENT);
// 构建代办记录的人维度的相关信息
buildPersonInfo(record, param.getPromoter(), executor, workspace.getId());
buildPersonInfo(record, param.getPromoter(), executor,
Optional.ofNullable(workspace).map(SimpleWorkspaceRes::getId).orElse(0L));
// 构建模板信息
buildTemplateInfo(record, msgTemplate, param.getBizExtParams());
// 构建代办所属企业/项目等相关信息
@ -562,8 +598,9 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
record.setExecutorPersonId(executor.getId());
record.setExecutorName(executor.getName());
// 执行人身份是从业人员查询ouId
record.setOuId(getPractitionOuId(executor, workspaceId));
if(null == record.getOuId()){
record.setOuId(getPractitionOuId(executor, workspaceId));
}
}
private Long getPractitionOuId(PersonDTO executor, Long workspaceId) {

View File

@ -19,7 +19,6 @@ import java.util.Objects;
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class JSONObjectUtil {
private static final JSONObject EMPTY_JSON_OBJ = new JSONObject();
private static final String EMPTY_JSON_OBJ_STR = "{}";
private static final String EMPTY_JSON_ARR_STR = "[]";
@ -31,7 +30,7 @@ public final class JSONObjectUtil {
*/
public static JSONObject parseObject(String str) {
if (StringUtils.isBlank(str)) {
return EMPTY_JSON_OBJ;
return new JSONObject();
}
return JSON.parseObject(str);
}

View File

@ -123,6 +123,30 @@ public final class MessageRouterUtil {
return JSON.parseArray(styleObj.toJSONString(), ButtonStyleEnum.class);
}
/**
* 解析模板上配置的路由地址,将发送消息时的参数替换上去并将路由参数追加到模板的路由地址后面兼容APP端新老版本
*
* @param msgTemplateRouter 路由信息
* @param routerParam 路由参数
* @return MessageTemplateRouterDTO
*/
public static MessageTemplateRouterDTO parseRouteUrl(MessageTemplateRouterDTO msgTemplateRouter,
JSONObject routerParam) {
if (Objects.isNull(msgTemplateRouter)) {
return msgTemplateRouter;
}
// 拷贝一份避免修改入参
msgTemplateRouter = msgTemplateRouter.deepClone();
// 路由参数有效
if (Objects.nonNull(routerParam)) {
// 编排业务详情路由
parseAndConcatDetailRouterUrl(msgTemplateRouter.getRouteDetail(), routerParam, false);
// 编排路由按钮
parseAndConcatButtonRouterUrl(msgTemplateRouter.getRouteButtons(), routerParam, false);
}
return msgTemplateRouter;
}
/**
* 解析模板上配置的路由地址,将发送消息时的参数替换上去并将路由参数追加到模板的路由地址后面兼容APP端新老版本
*
@ -140,44 +164,48 @@ public final class MessageRouterUtil {
// 路由参数有效
if (Objects.nonNull(routerParam)) {
// 编排业务详情路由
parseAndConcatDetailRouterUrl(msgTemplateRouter.getRouteDetail(), routerParam);
parseAndConcatDetailRouterUrl(msgTemplateRouter.getRouteDetail(), routerParam, true);
// 编排路由按钮
parseAndConcatButtonRouterUrl(msgTemplateRouter.getRouteButtons(), routerParam);
parseAndConcatButtonRouterUrl(msgTemplateRouter.getRouteButtons(), routerParam, true);
}
return msgTemplateRouter;
}
private static void parseAndConcatDetailRouterUrl(MessageRouteDetailDTO routeDetail, JSONObject routerParam) {
private static void parseAndConcatDetailRouterUrl(MessageRouteDetailDTO routeDetail, JSONObject routerParam,
boolean isConcat) {
if (Objects.isNull(routeDetail)) {
return;
}
routeDetail.getRouterConfigs()
.forEach(e -> concatRouterParam(e::getUrl, e::setUrl, routerParam));
.forEach(e -> concatRouterParam(e::getUrl, e::setUrl, routerParam, isConcat));
}
private static void parseAndConcatButtonRouterUrl(List<MessageRouteButtonDTO> routeButtons, JSONObject routerParam) {
private static void parseAndConcatButtonRouterUrl(List<MessageRouteButtonDTO> routeButtons, JSONObject routerParam,
boolean isConcat) {
if (CollectionUtils.isEmpty(routeButtons)) {
return;
}
routeButtons.forEach(e -> {
if (StringUtils.isNotBlank(e.getApiUrl())) {
// API调用类型的按钮
concatRouterParam(e::getApiUrl, e::setApiUrl, routerParam);
concatRouterParam(e::getApiUrl, e::setApiUrl, routerParam, isConcat);
}
if (CollectionUtils.isNotEmpty(e.getRouterConfigs())) {
// 页面跳转类型的按钮
e.getRouterConfigs()
.forEach(config -> concatRouterParam(config::getUrl, config::setUrl, routerParam));
.forEach(config -> concatRouterParam(config::getUrl, config::setUrl, routerParam, isConcat));
}
});
}
private static void concatRouterParam(Supplier<String> getUrlSupplier, Consumer<String> setUrlConsumer,
JSONObject routerParam) {
JSONObject routerParam, boolean isConcat) {
// 替换原始URL中的参数变量
String routerUrl = PlaceholderResolver.getDefaultResolver().resolveByMap(getUrlSupplier.get(), routerParam);
// 将routerParam追加到原始的URL后面
routerUrl = concatRouterParam(routerUrl, routerParam);
if (isConcat) {
routerUrl = concatRouterParam(routerUrl, routerParam);
}
setUrlConsumer.accept(routerUrl);
}

View File

@ -26,6 +26,10 @@ public class MessageStatisticReq implements Serializable {
*/
@NotNull(message = "personId is required")
private Long personId;
/**
* 单位id
*/
private Long ouId;
@Override
public String toString() {

View File

@ -19,17 +19,19 @@ public enum BizFinalStateEnum {
/**
* 已处理
*/
COMPLETED,
COMPLETED("https://static.axzo.cn/fe-static/uni-icon/public/seal-1%23_%241699341908382.png"),
/**
* 已撤销
*/
RETRACT,
RETRACT("https://static.axzo.cn/fe-static/uni-icon/public/seal-3%23_%241699341908381.png"),
/**
* 已通过
*/
PASSED,
PASSED("https://static.axzo.cn/fe-static/uni-icon/public/seal-4%23_%241699341908374.png"),
/**
* 已拒绝
*/
REJECTED;
REJECTED("https://static.axzo.cn/fe-static/uni-icon/public/seal-2%23_%241699341908381.png");
private final String icon;
}

View File

@ -27,6 +27,10 @@ public class PendingMessageCountUncompletedRequest implements Serializable {
*/
@NotNull(message = "personId is required")
private Long personId;
/**
* 单位id
*/
private Long ouId;
/**
* 当前登录账户的身份id(前端不care)
*/

View File

@ -28,6 +28,10 @@ public class PendingMessageStatisticRequest implements Serializable {
*/
@NotNull(message = "personId is required")
private Long personId;
/**
* 单位id
*/
private Long ouId;
/**
* 当前登录账户的身份id(前端不care)
*/