Merge branch 'feature/REQ-2097' into pre

This commit is contained in:
yanglin 2024-01-30 15:16:32 +08:00
commit a1fce83f12
10 changed files with 293 additions and 1 deletions

5
CHANGELOG.md Normal file
View File

@ -0,0 +1,5 @@
## REQ-2097
```mysql
ALTER TABLE pending_message_record
ADD hide_until DATETIME NULL COMMENT '在这个时间之前都不显示';
```

View File

@ -135,4 +135,9 @@ public class PendingMessageNewController implements PendingMessageClient {
public CommonResponse<List<PendingMessageSimpleDTO>> getLatestByBizCode(PendingMessageByBizCodeRequest bizCode) {
return CommonResponse.success(pendingMessageNewService.getLatestByBizCode(bizCode));
}
@Override
public CommonResponse<Boolean> setHide(SetHideRequest req) {
return CommonResponse.success(pendingMessageNewService.setHide(req));
}
}

View File

@ -6,12 +6,22 @@ import cn.axzo.msg.center.message.domain.dto.PendingMessageStatisticDTO;
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.request.*;
import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageByBizCodeRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageFixedTemplatePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageQueryRequest;
import cn.axzo.msg.center.service.pending.request.RevokePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.SetHideRequest;
import cn.axzo.msg.center.service.pending.request.UpdatePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
import cn.axzo.msg.center.service.pending.response.PushPendingMessageDTO;
import cn.azxo.framework.common.model.Page;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@ -177,4 +187,9 @@ public interface PendingMessageNewService {
* @return
*/
List<PendingMessageSimpleDTO> getLatestByBizCode(PendingMessageByBizCodeRequest bizCode);
/**
* 将待办设置为隐藏
*/
Boolean setHide(SetHideRequest req);
}

View File

@ -16,6 +16,7 @@ import cn.axzo.msg.center.api.enums.MsgStateEnum;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
import cn.axzo.msg.center.common.exception.ServiceException;
import cn.axzo.msg.center.common.utils.BizAssertions;
import cn.axzo.msg.center.common.utils.PageHelperUtil;
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
import cn.axzo.msg.center.dal.PendingMessageRecordDao;
@ -59,6 +60,7 @@ import cn.axzo.msg.center.service.pending.request.PendingMessageFixedTemplatePag
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageQueryRequest;
import cn.axzo.msg.center.service.pending.request.RevokePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.SetHideRequest;
import cn.axzo.msg.center.service.pending.request.UpdatePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
@ -82,6 +84,8 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -123,6 +127,9 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
private final PendingCalendarCodeConfig calendarCodeConfig;
private final MessageApi messageApi;
@Value("${msg.center.pending.hide-seconds:60}")
private int pendingDefaultHideSeconds;
@Override
public List<PendingMessageStatisticDTO> groupStatistic(MessageGroupNodeStatisticParam param) {
List<String> groupTreeRootNodeCodes = messageGroupNodeService
@ -180,6 +187,8 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
query.and(v -> v.like(PendingMessageRecord::getTitle, request.getTitle())
.or().like(PendingMessageRecord::getPromoterName, request.getTitle()));
}
// 设置隐藏时间
buildHideUntil(query);
// 构建人维度的查询条件
buildPersonCondition(query, request.getWithIdentify(), request.getRoleCategory(), operator);
// 模板的分类对代办进行分组过滤
@ -251,6 +260,8 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
LambdaQueryChainWrapper<PendingMessageRecord> query = pendingMessageRecordDao.lambdaQuery()
.eq(Objects.nonNull(request.getOuId()), PendingMessageRecord::getOuId, request.getOuId())
.eq(Objects.nonNull(pendingMessageState), PendingMessageRecord::getState, pendingMessageState);
// 设置隐藏时间
buildHideUntil(query);
// 构建人维度的查询条件
buildPersonCondition(query, request.getWithIdentify(), request.getRoleCategory(), operator);
// 模板的分类对代办进行分组过滤
@ -376,6 +387,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
log.info("the [{}] record is updated complete.", requestNo);
return pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.COMPLETED)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getRequestNo, requestNo)
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
.eq(PendingMessageRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
@ -392,6 +404,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
Boolean update = pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.COMPLETED)
.set(StringUtils.isNotBlank(bizExtParam), PendingMessageRecord::getBizExtParam, bizExtParam)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getId, param.getId())
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
.eq(PendingMessageRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
@ -417,6 +430,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
log.info("the [{}] record is updated retract.", requestNo);
return pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.RETRACT)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getRequestNo, requestNo)
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
.eq(PendingMessageRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
@ -432,6 +446,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
log.info("the [{}] record is updated retract by id.", msgId);
Boolean update = pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.RETRACT)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getId, msgId)
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
.eq(PendingMessageRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
@ -458,6 +473,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
}
result = pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.COMPLETED)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getTemplateCode, param.getTemplateCode())
.eq(PendingMessageRecord::getBizCode, param.getBizCode())
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
@ -501,6 +517,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
log.info("the [{}] record is completeByTemplateCodeSubBizCode retract.", param);
return pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.COMPLETED)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getTemplateCode, param.getTemplateCode())
.eq(PendingMessageRecord::getBizCode, param.getBizCode())
.eq(PendingMessageRecord::getSubBizCode, param.getSubBizCode())
@ -514,6 +531,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
log.info("the [{}] record is revokeByTemplateCodeBizCode retract.", param);
return pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.RETRACT)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getTemplateCode, param.getTemplateCode())
.eq(PendingMessageRecord::getBizCode, param.getBizCode())
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
@ -526,6 +544,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
log.info("the [{}] record is RevokePendingMessageByIdRequest.", param);
return pendingMessageRecordDao.lambdaUpdate()
.set(PendingMessageRecord::getState, PendingMessageStateEnum.RETRACT)
.set(PendingMessageRecord::getHideUntil, null)
.eq(PendingMessageRecord::getId, param.getId())
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
.eq(PendingMessageRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
@ -571,6 +590,25 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
return pendingMessageSimpleDTOS;
}
@Override
public Boolean setHide(SetHideRequest req) {
BizAssertions.assertFalse(req.getMsgId() != null && StringUtils.isNotBlank(req.getSubBizCode()),
"msgId, subBizCode 参数二选一, 不能都传");
if (req.getMsgId() == null) {
BizAssertions.assertTrue(StringUtils.isNotBlank(req.getSubBizCode()), "msgId, subBizCode 参数二选一");
} else if (StringUtils.isBlank(req.getSubBizCode())) {
BizAssertions.assertNotNull(req.getMsgId(), "msgId, subBizCode 参数二选一");
}
int seconds = req.getHideSeconds() == null ? pendingDefaultHideSeconds : req.getHideSeconds();
Date expireTime = DateTime.now().plusSeconds(seconds).toDate();
return pendingMessageRecordDao.lambdaUpdate()
.eq(req.getMsgId() != null, PendingMessageRecord::getId, req.getMsgId())
.eq(StringUtils.isNotBlank(req.getSubBizCode()), PendingMessageRecord::getSubBizCode, req.getSubBizCode())
.eq(PendingMessageRecord::getState, PendingMessageStateEnum.HAS_BEEN_SENT)
.set(PendingMessageRecord::getHideUntil, expireTime)
.update();
}
private PendingMessageDTO convert(PendingMessageRecord pendingMessageRecord, List<MessageTemplateDTO> messageTemplates) {
PendingMessageDTO pendingMessage = PendingMessageDTO.from(pendingMessageRecord);
// 对应模板的路由策略
@ -699,6 +737,12 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
.orElse(null);
}
private void buildHideUntil(LambdaQueryChainWrapper<PendingMessageRecord> query) {
query.and(q -> q.isNull(PendingMessageRecord::getHideUntil)
.or()
.lt(PendingMessageRecord::getHideUntil, new Date()));
}
private void buildPersonCondition(LambdaQueryChainWrapper<PendingMessageRecord> query, Boolean withIdentify,
PendingMessageRoleCategoryEnum roleCategory, PersonDTO operator) {
IdentityDTO identity = null;

View File

@ -188,6 +188,12 @@ public interface PendingMessageClient {
@PostMapping(value = "/pending-message/update/byId", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Boolean> updateById(@RequestBody @Valid UpdatePendingMessageByIdRequest param);
/**
* 将待办设置为隐藏, 列表页不展示
*/
@PostMapping(value = "/pending-message/update/setHide", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Boolean> setHide(@RequestBody @Valid SetHideRequest req);
/**
* 通过BizCode获取最新代办
*

View File

@ -134,4 +134,10 @@ public class PendingMessageClientFallback implements PendingMessageClient {
log.error("fall back while getLatestByBizCode pending message update by ID. param:[{}]", param);
return CommonResponse.error("fall back while revoking pending message update by ID");
}
@Override
public CommonResponse<Boolean> setHide(SetHideRequest req) {
log.error("fall back setHide. req={}", req);
return CommonResponse.error("fall back while invoking setHide");
}
}

View File

@ -0,0 +1,39 @@
package cn.axzo.msg.center.service.pending.request;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.annotation.Nullable;
/**
* @author haiyangjin
* @date 2023/11/16
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SetHideRequest {
/**
* 需要隐藏的待办id, msgId, subBizCode 参数二选一
*/
private Long msgId;
/**
* 流程类代办的流程结点编码, msgId, subBizCode 参数二选一
*/
private String subBizCode;
/**
* 需要隐藏多少秒, 如果没有传将会使用默认值
*/
@Nullable
private Integer hideSeconds;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,122 @@
package cn.axzo.msg.center.common.utils;
import cn.axzo.basics.common.exception.ServiceException;
import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.framework.domain.web.result.ApiListResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.helpers.MessageFormatter;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
/**
* @author yanglin
*/
@Slf4j
public class BizAssertions {
/**
* 断言为NULL
*/
public static void assertNull(Object actual, String message, Object... args) {
AssertUtil.isNull(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言不为NULL
*/
public static void assertNotNull(Object actual, String message, Object... args) {
AssertUtil.notNull(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言集合不为空
*/
public static void assertNotEmpty(Collection<?> actual, String message, Object... args) {
AssertUtil.notEmpty(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言数组不为空
*/
public static <T> void assertNotEmpty(T[] actual, String message, Object... args) {
AssertUtil.notEmpty(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言值为真
*/
public static void assertTrue(boolean actual, String message, Object... args) {
AssertUtil.isTrue(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言值不为真
*/
public static void assertFalse(boolean actual, String message, Object... args) {
AssertUtil.isFalse(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言值2个值是否equals
*/
public static void assertEquals(Object expected, Object actual, String message, Object... args) {
if (!Objects.equals(expected, actual)) {
throw new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
}
}
/**
* 断言值2个值是否不equals
*/
public static void assertNotEquals(Object expected, Object actual, String message, Object... args) {
if (Objects.equals(expected, actual)) {
throw new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
}
}
public static <T> T assertResponse(CommonResponse<T> response) {
return assertResponse(response, "error resp={}", JSON.toJSONString(response));
}
public static <T> T assertResponse(CommonResponse<T> response, String message, Object... args) {
if (response.getCode() != HttpStatus.HTTP_OK) {
ServiceException e = new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
log.warn("remote call response with error", e);
throw e;
}
return response.getData();
}
public static <T> T assertResponse(ApiResult<T> response) {
return assertResponse(response, "error resp={}", JSON.toJSONString(response));
}
public static <T> T assertResponse(ApiResult<T> response, String message, Object... args) {
if (!response.isSuccess()) {
ServiceException e = new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
log.warn("remote call response with error", e);
throw e;
}
return response.getData();
}
public static <T> List<T> assertResponse(ApiListResult<T> response) {
return assertResponse(response, "error resp={}", JSON.toJSONString(response));
}
public static <T> List<T> assertResponse(ApiListResult<T> response, String message, Object... args) {
if (!response.isSuccess()) {
ServiceException e = new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
log.warn("remote call response with error", e);
throw e;
}
return response.getData();
}
}

View File

@ -145,6 +145,10 @@ public class PendingMessageRecord extends BaseEntityExt<PendingMessageRecord> im
* 最终失败原因
*/
private String failCause;
/**
* 在这个时间之前不显示
*/
private Date hideUntil;
@Override
public String toString() {

View File

@ -0,0 +1,46 @@
package cn.axzo.msg.center.message.service;
import cn.axzo.msg.center.MsgCenterApplication;
import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
import cn.axzo.msg.center.service.pending.request.SetHideRequest;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.azxo.framework.common.model.Page;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Commit;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author yanglin
*/
@SpringBootTest(classes = MsgCenterApplication.class)
@RequiredArgsConstructor(onConstructor_ = @Autowired)
class PendingMessageNewServiceTest {
private final PendingMessageNewService pendingMessageNewService;
@Test
@Commit
void foo() {
//SetHideRequest req = new SetHideRequest();
//req.setSubBizCode("08345cb9-669a-11ee-8d91-02550a00001f");
//pendingMessageNewService.setHide(req);
//String jsonStr = "{\"appTerminalType\":\"CMS_WEB_PC\",\"groupNodeCode\":\"\",\"identityId\":1593,\"identityType\":\"PRACTITIONER\",\"msgState\":\"HAS_BEEN_SENT\",\"ouId\":5812,\"page\":1,\"pageSize\":10,\"personId\":2849,\"roleCategory\":\"EXECUTOR\",\"terminalType\":\"WEB\"}";
//PendingMessagePageRequest request = JSON.parseObject(jsonStr, PendingMessagePageRequest.class);
//Page<PendingMessageResponse> pendingMessageResponsePage = pendingMessageNewService.pageQuery(request);
//System.out.println();
//pendingMessageNewService.complete("650d3eaa3d3a4064b34a64b7b1c8dffb");
//pendingMessageNewService.completeById(CompletePendingMessageByIdRequest.builder().id(20578L).build());
//pendingMessageNewService.completeByTemplateCodeBizCode(CompletePendingMessageRequest.builder().templateCode("75047e6339484e81bcce244d56fb2363").bizCode("DFX202311231600002").build());
//pendingMessageNewService.completeByTemplateCodeSubBizCode(CompletePendingBySubCodeRequest.builder().bizCode("0818e560-669a-11ee-8d91-02550a00001f").subBizCode("08345cb9-669a-11ee-8d91-02550a00001f").templateCode("a97760e573674658b6b351e2f3a6e379").build());
}
}