feat(REQ-3300) - 添加 IM 群聊Tips 按钮的操作接口

This commit is contained in:
wangli 2025-02-06 15:59:30 +08:00
parent 34b7cfd5f0
commit 952f0e3d55
11 changed files with 199 additions and 24 deletions

View File

@ -4,7 +4,9 @@ import cn.axzo.framework.domain.web.result.ApiPageResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.nanopart.visa.api.request.ChangeRecordForbidReq;
import cn.axzo.nanopart.visa.api.request.ChangeStatusRequest;
import cn.axzo.nanopart.visa.api.request.FetchVisaAllConfirmReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeApproveCreateReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeApproveOnlyReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeDiscussCreateReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeExportReq;
import cn.axzo.nanopart.visa.api.request.VisaChangePageSearchReq;
@ -97,7 +99,23 @@ public interface ChangeRecordApi {
ApiResult<List<VisaChangeInitiatorResp>> listInitiator(@RequestBody @Validated VisaInitiatorListReq req);
/**
* 变洽签废止
* IM 变洽签群中点击提交审批前拉取对应的确认人列表
*
* @return
*/
@PostMapping("/api/visa/change/confirm/list")
ApiResult<List<VisaChangeApproveCreateReq.ApprovePersonInfo>> getVisaAllConfirm(@Validated @RequestBody FetchVisaAllConfirmReq req);
/**
* IM 变洽签群提交审批按钮
*
* @return
*/
@PostMapping("/api/visa/change/approve/only/create")
ApiResult<Long> approveExistsVisaChangeRecord(@Validated @RequestBody VisaChangeApproveOnlyReq req);
/**
* IM 变洽签群废止按钮
*
* @return
*/

View File

@ -0,0 +1,27 @@
package cn.axzo.nanopart.visa.api.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
/**
* 拉取指定已存在变洽签的确认人全部列表
*
* @author wangli
* @since 2025-02-06 13:56
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class FetchVisaAllConfirmReq {
/**
* 变洽签 ID
*/
@NotNull(message = "变洽签 ID 不能为空")
private Long visaId;
}

View File

@ -0,0 +1,41 @@
package cn.axzo.nanopart.visa.api.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 通过 IM 群聊中发起的审批入参模型
*
* @author wangli
* @since 2025-02-06 13:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VisaChangeApproveOnlyReq {
/**
* 变洽签 ID
*/
@NotNull(message = "变洽签 ID 不能为空")
private Long visaId;
/**
* 需要设置审批人的节点标识
*/
@NotBlank(message = "待设置审批人的节点为空")
private String activityId;
/**
* 审批人信息
*/
private List<VisaChangeApproveCreateReq.ApprovePersonInfo> approvePersonInfoList;
}

View File

@ -6,7 +6,9 @@ import cn.axzo.framework.domain.web.result.PageData;
import cn.axzo.nanopart.visa.api.changerecord.ChangeRecordApi;
import cn.axzo.nanopart.visa.api.request.ChangeRecordForbidReq;
import cn.axzo.nanopart.visa.api.request.ChangeStatusRequest;
import cn.axzo.nanopart.visa.api.request.FetchVisaAllConfirmReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeApproveCreateReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeApproveOnlyReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeDiscussCreateReq;
import cn.axzo.nanopart.visa.api.request.VisaChangeExportReq;
import cn.axzo.nanopart.visa.api.request.VisaChangePageSearchReq;
@ -93,6 +95,16 @@ public class ChangeRecordController implements ChangeRecordApi {
return ApiResult.ok(changeRecordService.listInitiator(req));
}
@Override
public ApiResult<List<VisaChangeApproveCreateReq.ApprovePersonInfo>> getVisaAllConfirm(FetchVisaAllConfirmReq req) {
return ApiResult.ok(changeRecordConfirmService.listAllConfirmByVisaId(req.getVisaId()));
}
@Override
public ApiResult<Long> approveExistsVisaChangeRecord(VisaChangeApproveOnlyReq req) {
return null;
}
@Override
public ApiResult<Void> forbidChangeRecord(ChangeRecordForbidReq req) {
changeRecordService.forbid(req);

View File

@ -16,7 +16,7 @@ import java.util.Objects;
* @since 2025-01-20 10:18
*/
public abstract class BasicLogSupport {
private final EventProducer eventProducer;
protected final EventProducer eventProducer;
protected final VisaOrganizationalNodeUserGateway visaOrganizationalNodeUserGateway;
protected BasicLogSupport(EventProducer eventProducer, VisaOrganizationalNodeUserGateway visaOrganizationalNodeUserGateway) {

View File

@ -1,20 +1,28 @@
package cn.axzo.nanopart.visa.server.mq.listener.workflow.process;
import cn.axzo.framework.rocketmq.EventProducer;
import cn.axzo.nanopart.visa.server.domain.ChangeRecord;
import cn.axzo.nanopart.visa.server.domain.ChangeRecordLog;
import cn.axzo.nanopart.visa.server.domain.ChangeRecordRelation;
import cn.axzo.nanopart.visa.server.mq.listener.workflow.BasicLogSupport;
import cn.axzo.nanopart.visa.server.mq.producer.VisaChangeLogPayload;
import cn.axzo.nanopart.visa.server.rpc.VisaOrganizationalNodeUserGateway;
import cn.axzo.nanopart.visa.server.service.ChangeRecordRelationService;
import cn.axzo.nanopart.visa.server.service.ChangeRecordService;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.response.mq.ProcessInstanceDTO;
import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler;
import org.springframework.stereotype.Component;
import java.util.Date;
import static cn.axzo.nanopart.visa.api.constant.VisaConstant.WORKFLOW_VAR_VISA_TYPE_KEY;
import static cn.axzo.nanopart.visa.api.enums.VisaLogTypeEnum.APPROVE_COMPLETED;
import static cn.axzo.nanopart.visa.api.enums.VisaLogTypeEnum.REJECT_APPROVE;
import static cn.axzo.nanopart.visa.api.enums.VisaLogTypeEnum.REVERT_APPROVE;
import static cn.axzo.nanopart.visa.api.enums.VisaLogTypeEnum.TO_APPRROVE;
import static cn.axzo.nanopart.visa.api.enums.VisaRelationFieldEnum.PROCESS_INSTANCE;
/**
* 工作流广播的实例维度的所有事件类型
@ -24,13 +32,16 @@ import static cn.axzo.nanopart.visa.api.enums.VisaLogTypeEnum.TO_APPRROVE;
*/
@Component
public class ProcessInstanceAllEventHandler extends BasicLogSupport implements ProcessInstanceEventHandler {
private final EventProducer eventProducer;
protected final VisaOrganizationalNodeUserGateway visaOrganizationalNodeUserGateway;
protected final ChangeRecordService changeRecordService;
protected final ChangeRecordRelationService changeRecordRelationService;
public ProcessInstanceAllEventHandler(EventProducer eventProducer, VisaOrganizationalNodeUserGateway visaOrganizationalNodeUserGateway) {
public ProcessInstanceAllEventHandler(EventProducer eventProducer,
VisaOrganizationalNodeUserGateway visaOrganizationalNodeUserGateway,
ChangeRecordService changeRecordService,
ChangeRecordRelationService changeRecordRelationService) {
super(eventProducer, visaOrganizationalNodeUserGateway);
this.eventProducer = eventProducer;
this.visaOrganizationalNodeUserGateway = visaOrganizationalNodeUserGateway;
this.changeRecordService = changeRecordService;
this.changeRecordRelationService = changeRecordRelationService;
}
@Override
@ -69,6 +80,8 @@ public class ProcessInstanceAllEventHandler extends BasicLogSupport implements P
.content(String.format(APPROVE_COMPLETED.getContent(), visaType))
.build();
eventProducer.send(VisaChangeLogPayload.form(log));
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.APPROVED);
}
/**
@ -88,6 +101,8 @@ public class ProcessInstanceAllEventHandler extends BasicLogSupport implements P
.content(String.format(REVERT_APPROVE.getContent(), buildLogUserInfo(initiator)))
.build();
eventProducer.send(VisaChangeLogPayload.form(log));
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.CANCELLED);
}
/**
@ -105,10 +120,40 @@ public class ProcessInstanceAllEventHandler extends BasicLogSupport implements P
.content(String.format(REJECT_APPROVE.getContent(), buildLogUserInfo(lastOperationAssigner), dto.getReason()))
.build();
eventProducer.send(VisaChangeLogPayload.form(log));
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.REJECTED);
}
@Override
public void onAborted(ProcessInstanceDTO dto) {
ProcessInstanceEventHandler.super.onAborted(dto);
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.ABORTED);
}
private void updateChangeRecordApprovalStatus(ProcessInstanceDTO dto, BpmnProcessInstanceResultEnum resultEnum) {
// 更新主表审批信息
changeRecordService.lambdaQuery()
.eq(ChangeRecord::getId, Long.valueOf(dto.getBusinessKey()))
.eq(ChangeRecord::getApprovalId, dto.getProcessInstanceId())
.eq(ChangeRecord::getIsDelete, 0)
.oneOpt()
.ifPresent(changeRecord -> {
changeRecord.setApprovalStatus(resultEnum.getStatus());
changeRecord.setApprovalCompleteTime(new Date());
changeRecordService.updateById(changeRecord);
});
// 更新关联表审批信息
changeRecordRelationService.lambdaQuery()
.eq(ChangeRecordRelation::getVisaId, Long.valueOf(dto.getBusinessKey()))
.eq(ChangeRecordRelation::getVarName, PROCESS_INSTANCE.getCode())
.eq(ChangeRecordRelation::getContent, dto.getProcessInstanceId())
.oneOpt()
.ifPresent(changeRecordRelation -> {
changeRecordRelation.setContentExt(resultEnum.getStatus());
changeRecordRelationService.updateById(changeRecordRelation);
});
}
}

View File

@ -21,13 +21,9 @@ import static cn.axzo.nanopart.visa.api.enums.VisaLogTypeEnum.TRANSMIT_APPROVE;
*/
@Component
public class ProcessTaskAllEventHandler extends BasicLogSupport implements ProcessTaskEventHandler {
private final EventProducer eventProducer;
protected final VisaOrganizationalNodeUserGateway visaOrganizationalNodeUserGateway;
public ProcessTaskAllEventHandler(EventProducer eventProducer, VisaOrganizationalNodeUserGateway visaOrganizationalNodeUserGateway) {
super(eventProducer, visaOrganizationalNodeUserGateway);
this.eventProducer = eventProducer;
this.visaOrganizationalNodeUserGateway = visaOrganizationalNodeUserGateway;
}
@Override

View File

@ -3,9 +3,10 @@ package cn.axzo.nanopart.visa.server.service;
import cn.axzo.nanopart.visa.api.enums.VisaButtonTypeEnum;
import cn.axzo.nanopart.visa.api.enums.VisaConfirmBizTypeEnum;
import cn.axzo.nanopart.visa.api.enums.VisaStatusEnum;
import cn.axzo.nanopart.visa.api.request.VisaChangeApproveCreateReq;
import cn.axzo.nanopart.visa.api.response.VisaDetailByIdResponse;
import cn.axzo.nanopart.visa.server.dto.VisaConfirmDto;
import cn.axzo.nanopart.visa.server.domain.ChangeRecordConfirm;
import cn.axzo.nanopart.visa.server.dto.VisaConfirmDto;
import java.util.List;
import java.util.Set;
@ -66,4 +67,11 @@ public interface ChangeRecordConfirmService {
* @return 变更签证visaId集合
*/
Set<Long> permissionVisaData(String dataObjectCode, Long currentPersonId, Long currentWorkspaceId, Long currentOuId);
/**
* 获取指定的变洽签所有的确认人
* @param visaId
* @return
*/
List<VisaChangeApproveCreateReq.ApprovePersonInfo> listAllConfirmByVisaId(Long visaId);
}

View File

@ -14,6 +14,7 @@ import cn.axzo.nanopart.visa.api.response.VisaChangeInitiatorResp;
import cn.axzo.nanopart.visa.api.response.VisaChangePageSearchResp;
import cn.axzo.nanopart.visa.api.response.VisaDetailByIdResponse;
import cn.axzo.nanopart.visa.server.domain.ChangeRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
@ -22,7 +23,7 @@ import java.util.List;
* @date 2025/01/15
* @desc 变更签证记录
*/
public interface ChangeRecordService {
public interface ChangeRecordService extends IService<ChangeRecord> {
/**
* 状态变更

View File

@ -10,6 +10,7 @@ import cn.axzo.nanopart.visa.api.enums.VisaButtonTypeEnum;
import cn.axzo.nanopart.visa.api.enums.VisaConfirmBizTypeEnum;
import cn.axzo.nanopart.visa.api.enums.VisaLogTypeEnum;
import cn.axzo.nanopart.visa.api.enums.VisaStatusEnum;
import cn.axzo.nanopart.visa.api.request.VisaChangeApproveCreateReq;
import cn.axzo.nanopart.visa.api.response.VisaDetailByIdResponse;
import cn.axzo.nanopart.visa.server.domain.ChangeRecord;
import cn.axzo.nanopart.visa.server.domain.ChangeRecordConfirm;
@ -36,10 +37,12 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -276,6 +279,17 @@ public class ChangeRecordConfirmServiceImpl extends ServiceImpl<ChangeRecordConf
return profiles.stream().collect(Collectors.toMap(PersonProfileDto::getId, PersonProfileDto::getRealName, (x, y) -> x));
}
private Map<Long, PersonProfileDto> buildPersonDtoMap(Set<Long> personSet) {
if (CollectionUtils.isEmpty(personSet)) {
return Maps.newHashMap();
}
List<PersonProfileDto> profiles = visaProfileGateway.getProfiles(Lists.newArrayList(personSet));
if (CollectionUtils.isEmpty(profiles)) {
return Maps.newHashMap();
}
return profiles.stream().collect(Collectors.toMap(PersonProfileDto::getId, Function.identity(), (x, y) -> x));
}
/**
* 条件查询列表
*/
@ -334,4 +348,20 @@ public class ChangeRecordConfirmServiceImpl extends ServiceImpl<ChangeRecordConf
return visaIdList;
}
@Override
public List<VisaChangeApproveCreateReq.ApprovePersonInfo> listAllConfirmByVisaId(Long visaId) {
VisaConfirmDto dto = VisaConfirmDto.builder()
.visaId(visaId)
.bizType(VisaConfirmBizTypeEnum.CONFIRM).build();
List<ChangeRecordConfirm> list = this.findByCondition(dto);
if (CollectionUtils.isEmpty(list)) {
return Lists.newArrayList();
}
Map<Long, PersonProfileDto> personMap = buildPersonDtoMap(list.stream()
.map(ChangeRecordConfirm::getPersonId)
.collect(Collectors.toSet()));
list.stream().map(i-> VisaChangeApproveCreateReq.ApprovePersonInfo.builder().build())
.collect(Collectors.toList());
return null;
}
}

View File

@ -506,7 +506,7 @@ public class ChangeRecordServiceImpl extends ServiceImpl<ChangeRecordDao, Change
.collect(Collectors.toSet()));
}
// 群头像
request.setAvatar("");
request.setAvatar("https://axzo-obs-public.obs.cn-north-4.myhuaweicloud.com:443/obs-public/obs-public/visa-group.png");
request.setMemberLimit(100L);
request.setBizGroupInfo(Maps.of(IM_GROUP_BIZ_INFO_RECORD_ID, visaId));
GroupCreateResponse imGroup = msgCenterGateway.createImGroup(request);
@ -643,14 +643,12 @@ public class ChangeRecordServiceImpl extends ServiceImpl<ChangeRecordDao, Change
}
approvers.addAll(approvePersonInfoList.stream()
.flatMap(info -> info.getPersonIdList().stream()
.map(personId -> BpmnTaskDelegateAssigner.builder()
.personId(String.valueOf(personId))
.tenantId(String.valueOf(info.getWorkspaceId()))
.ouId(String.valueOf(info.getUnitId()))
.build()))
.collect(Collectors.toList())
);
.map(i -> BpmnTaskDelegateAssigner.builder()
.personId(String.valueOf(i.getPersonId()))
.tenantId(String.valueOf(i.getWorkspaceId()))
.ouId(String.valueOf(i.getOuId()))
.build())
.collect(Collectors.toList()));
return approvers;
}
@ -925,7 +923,7 @@ public class ChangeRecordServiceImpl extends ServiceImpl<ChangeRecordDao, Change
// cooperateShipGateway.genericQuery()
// 班组存在性及状态
}
// }
AssertUtil.isTrue(req.getAmountChange().compareTo(maxAmount) <= 0 && req.getAmountChange().compareTo(minAmount) >= 0, "金额变化超出范围");
// 关联单据合法性
if (CollUtil.isNotEmpty(req.getRelationOrderMap())) {
@ -1030,7 +1028,6 @@ public class ChangeRecordServiceImpl extends ServiceImpl<ChangeRecordDao, Change
if (StringUtils.hasText(record.getApprovalId())) {
BpmnProcessInstanceAbortDTO abort = new BpmnProcessInstanceAbortDTO();
abort.setProcessInstanceId(record.getApprovalId());
// TODO 中止审批的原因
abort.setReason("变更签证单据被废止,中止审批流");
abort.setAssigner(BpmnTaskDelegateAssigner.builder()
.personId(String.valueOf(req.getOperatorPersonId()))