feat:导入用户防抖
fix:删除用户bug修改
This commit is contained in:
1 parent
f86a3b9f28
commit
99341f509b
4 files changed
+99
-14
No files matched your search
+27
@@ -0,0 +1,27 @@
|
||||
package com.bsd.pjcloud.admin.api.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 删除用户请求项。
|
||||
* <p>流程信息来自用户列表快照,后端删除时仍以数据库中的实时审批状态和流程ID为准。</p>
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "删除用户请求项")
|
||||
public class SysUserDeleteDto {
|
||||
|
||||
/**
|
||||
* 待删除的系统用户ID。
|
||||
*/
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 前端列表中的审批流程实例ID快照;允许为空,不作为后端取消流程的可信数据源。
|
||||
*/
|
||||
@Schema(description = "审批流程实例ID快照")
|
||||
private String processId;
|
||||
}
|
||||
+30
-7
@@ -27,6 +27,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.admin.api.dto.ForgotPasswordDTO;
|
||||
import com.bsd.pjcloud.admin.api.dto.SysUserDeleteDto;
|
||||
import com.bsd.pjcloud.admin.api.dto.UserDTO;
|
||||
import com.bsd.pjcloud.admin.api.dto.UserDeptSimpleInfo;
|
||||
import com.bsd.pjcloud.admin.api.dto.UserInfo;
|
||||
@@ -45,6 +46,7 @@ import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScope;
|
||||
import com.bsd.pjcloud.common.excel.annotation.RequestExcel;
|
||||
import com.bsd.pjcloud.common.excel.annotation.ResponseExcel;
|
||||
import com.bsd.pjcloud.common.idempotent.annotation.Idempotent;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.common.security.annotation.HasPermission;
|
||||
import com.bsd.pjcloud.common.security.annotation.Inner;
|
||||
@@ -247,17 +249,24 @@ public class SysUserController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户信息
|
||||
* 删除用户信息;审核中的用户会先取消当前审批流程。
|
||||
*
|
||||
* @param ids ID
|
||||
* @return R
|
||||
* @param users 待删除用户及其前端流程快照
|
||||
* @return 删除结果;请求为空或删除前置校验失败时返回失败信息
|
||||
*/
|
||||
@SysLog("删除用户信息")
|
||||
@DeleteMapping
|
||||
@HasPermission("sys_user_del")
|
||||
@Operation(summary = "删除用户", description = "根据ID删除用户")
|
||||
public R userDel(@RequestBody Long[] ids) {
|
||||
return R.ok(userService.deleteUserByIds(ids));
|
||||
@Operation(summary = "删除用户", description = "根据ID删除用户,审核中的用户会先取消审批流程")
|
||||
public R<Boolean> userDel(@Valid @RequestBody List<SysUserDeleteDto> users) {
|
||||
if (CollUtil.isEmpty(users)) {
|
||||
return R.failed("请选择要删除的用户");
|
||||
}
|
||||
if (users.stream().anyMatch(user -> user == null || user.getUserId() == null)) {
|
||||
return R.failed("用户ID不能为空");
|
||||
}
|
||||
Long[] userIds = users.stream().map(SysUserDeleteDto::getUserId).distinct().toArray(Long[]::new);
|
||||
return R.ok(userService.deleteUserByIds(userIds));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -411,16 +420,30 @@ public class SysUserController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入学生用户
|
||||
* 导入学生用户。
|
||||
*
|
||||
* @param studentUserExcelList Excel 中解析出的学生用户数据
|
||||
* @param bindingResult Excel 通用校验产生的错误信息
|
||||
* @return 导入结果;失败时包含对应行号和错误原因
|
||||
*/
|
||||
@PostMapping("/import-student")
|
||||
@HasPermission("sys_student_user_export")
|
||||
@Idempotent(expireTime = 5, key = "'/user/import-student:' + #studentUserExcelList.hashCode() + ':' + T(com.bsd.pjcloud.common.security.util.SecurityUtils).getUser().getId()", info = "正在导入中,请勿重复操作")
|
||||
public R importStudentUser(@RequestExcel List<StudentUserExcelVO> studentUserExcelList, BindingResult bindingResult) {
|
||||
return userService.importStudentUser(studentUserExcelList, bindingResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入用户及 Excel 中内嵌的人脸图片。
|
||||
*
|
||||
* @param file 原始 Excel 文件,用于读取内嵌的人脸图片
|
||||
* @param excelList Excel 中解析出的用户数据
|
||||
* @param bindingResult Excel 通用校验产生的错误信息
|
||||
* @return 导入结果;失败时包含校验错误或人脸图片处理错误
|
||||
*/
|
||||
@PostMapping("/import-face")
|
||||
@HasPermission("sys_user_export")
|
||||
@Idempotent(expireTime = 5, key = "'/user/import-face:' + #file.getSize() + ':' + #excelList.hashCode() + ':' + T(com.bsd.pjcloud.common.security.util.SecurityUtils).getUser().getId()", info = "正在导入中,请勿重复操作")
|
||||
public R importUserFace(@RequestParam("file") MultipartFile file, @RequestExcel List<UserExcelFaceVo> excelList, BindingResult bindingResult) {
|
||||
return userService.importUserFace(file, excelList, bindingResult);
|
||||
}
|
||||
|
||||
+3
-3
@@ -64,10 +64,10 @@ public interface SysUserService extends IService<SysUser> {
|
||||
IPage<UserVO> innerPage(Page page, UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* 删除指定用户,并在删除前取消其中仍处于审核中的审批流程。
|
||||
*
|
||||
* @param ids 用户
|
||||
* @return boolean
|
||||
* @param ids 待删除的用户ID数组,不能为空
|
||||
* @return 用户及其关联数据进入删除流程后返回 {@code true}
|
||||
*/
|
||||
Boolean deleteUserByIds(Long[] ids);
|
||||
|
||||
|
||||
+39
-4
@@ -79,9 +79,11 @@ import com.bsd.pjcloud.common.data.tenant.TenantContextHolder;
|
||||
import com.bsd.pjcloud.common.excel.vo.ErrorMessage;
|
||||
import com.bsd.pjcloud.common.security.service.PjcloudUser;
|
||||
import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
import com.bsd.pjcloud.flow.task.api.feign.RemoteFlowEngineService;
|
||||
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
|
||||
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
|
||||
import com.bsd.pjcloud.flow.task.dto.TaskDto;
|
||||
import com.bsd.pjcloud.flow.task.dto.TaskParamDto;
|
||||
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletService;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
@@ -172,6 +174,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
private final RemoteWalletService remoteWalletService;
|
||||
|
||||
/**
|
||||
* 审批流程远程服务,用于在删除审核中用户前终止对应流程实例。
|
||||
*/
|
||||
private final RemoteFlowEngineService remoteFlowEngineService;
|
||||
|
||||
private final SysFileService sysFileService;
|
||||
|
||||
private final FlowUtil flowUtil;
|
||||
@@ -403,16 +410,23 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* 删除用户,并在删除前终止仍处于审核中的用户审批流程。
|
||||
* <p>审批状态和流程ID以数据库实时数据为准;流程取消失败时抛出异常并停止本次删除。</p>
|
||||
*
|
||||
* @param ids 用户ID 列表
|
||||
* @return Boolean
|
||||
* @return 所有用户及其关联数据进入删除流程后返回 {@code true}
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteUserByIds(Long[] ids) {
|
||||
if (ArrayUtil.isEmpty(ids)) {
|
||||
throw new RuntimeException("请选择要删除的用户");
|
||||
}
|
||||
List<Long> userIds = CollUtil.toList(ids);
|
||||
List<SysUser> userList = baseMapper.selectBatchIds(userIds);
|
||||
if (userList.size() != userIds.stream().distinct().count()) {
|
||||
throw new RuntimeException("部分用户不存在或已删除,请刷新后重试");
|
||||
}
|
||||
// 判断是否可以删除
|
||||
userList.forEach(v -> {
|
||||
String errorMsg = remoteWalletService.isDel(v.getUserId()).getData();
|
||||
@@ -421,6 +435,27 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
});
|
||||
|
||||
// 只终止数据库中仍为审核中的流程;前端携带的流程ID可能已经过期,不能作为删除依据。
|
||||
List<String> pendingProcessIds = new ArrayList<>();
|
||||
for (SysUser user : userList) {
|
||||
if (!ObjectUtil.equals(user.getProcessStatus(), TaskCheckStatusEnum.PADDING.getCode())) {
|
||||
continue;
|
||||
}
|
||||
if (StrUtil.isBlank(user.getProcessId())) {
|
||||
throw new RuntimeException("审核中的用户缺少流程ID,无法删除");
|
||||
}
|
||||
pendingProcessIds.add(user.getProcessId());
|
||||
}
|
||||
if (CollUtil.isNotEmpty(pendingProcessIds)) {
|
||||
TaskParamDto taskParam = new TaskParamDto();
|
||||
taskParam.setProcessInstanceIdList(pendingProcessIds.stream().distinct().toList());
|
||||
R<String> stopResult = remoteFlowEngineService.stopProcessInstance(taskParam);
|
||||
if (stopResult == null || !stopResult.isOk()) {
|
||||
String errorMessage = stopResult == null ? null : stopResult.getMsg();
|
||||
throw new RuntimeException(StrUtil.blankToDefault(errorMessage, "取消用户审批流程失败"));
|
||||
}
|
||||
}
|
||||
|
||||
// 删除 spring cache
|
||||
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
|
||||
for (SysUser sysUser : userList) {
|
||||
@@ -435,9 +470,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
this.removeBatchByIds(userIds);
|
||||
// 删除钱包
|
||||
CompletableFuture.runAsync(() -> {
|
||||
remoteWalletService.delWallet(List.of(ids));
|
||||
remoteWalletService.delWallet(userIds);
|
||||
});
|
||||
for (Long userId : ids) {
|
||||
for (Long userId : userIds) {
|
||||
remoteWalletService.userChange(userId, Boolean.TRUE);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user