Pre Merge pull request !719 from AprilWind/importData

This commit is contained in:
AprilWind 2025-07-04 06:50:42 +00:00 committed by Gitee
commit fa1dd1b852
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 211 additions and 0 deletions

View File

@ -5,6 +5,7 @@ import cn.hutool.core.lang.tree.Tree;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
@ -16,13 +17,18 @@ import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.bo.SysRoleBo;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysRoleVo;
import org.dromara.system.domain.vo.SysUserRoleImportVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.listener.SysUserRoleImportListener;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysRoleService;
import org.dromara.system.service.ISysUserService;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
/**
@ -60,6 +66,28 @@ public class SysRoleController extends BaseController {
ExcelUtil.exportExcel(list, "角色数据", SysRoleVo.class, response);
}
/**
* 导入用户角色数据分配或取消授权
*
* @param file 导入文件
* @param assign true = 分配用户false = 取消授权
*/
@Log(title = "角色管理", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:role:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file, @RequestParam(value = "assign", required = true) boolean assign) throws Exception {
ExcelResult<SysUserRoleImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserRoleImportVo.class, new SysUserRoleImportListener(assign));
return R.ok(result.getAnalysis());
}
/**
* 获取角色导入模板
*/
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
ExcelUtil.exportExcel(new ArrayList<>(), "角色数据", SysUserRoleImportVo.class, response);
}
/**
* 根据角色编号获取详细信息
*

View File

@ -0,0 +1,40 @@
package org.dromara.system.domain.vo;
import cn.idev.excel.annotation.ExcelProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
/**
* 用户角色导入对象
*
* @author AprilWind
*/
@Data
@NoArgsConstructor
// @Accessors(chain = true) // 导入不允许使用 会找不到set方法
public class SysUserRoleImportVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户账号
*/
@ExcelProperty(value = "用户账号")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符")
private String userName;
/**
* 角色权限标识
*/
@ExcelProperty(value = "角色权限")
@NotBlank(message = "角色权限不能为空")
private String roleKey;
}

View File

@ -0,0 +1,143 @@
package org.dromara.system.listener;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HtmlUtil;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.excel.core.ExcelListener;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.system.domain.SysUserRole;
import org.dromara.system.domain.vo.SysRoleVo;
import org.dromara.system.domain.vo.SysUserRoleImportVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserRoleMapper;
import org.dromara.system.service.ISysRoleService;
import org.dromara.system.service.ISysUserService;
import java.util.List;
import java.util.Map;
/**
* 系统用户自定义导入
*
* @author Lion Li
*/
@Slf4j
public class SysUserRoleImportListener extends AnalysisEventListener<SysUserRoleImportVo> implements ExcelListener<SysUserRoleImportVo> {
private final ISysUserService userService;
private final ISysRoleService roleService;
private final SysUserRoleMapper userRoleMapper;
private final Boolean assign;
private final Map<String, Long> roleKeyIdMap;
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public SysUserRoleImportListener(Boolean assign) {
this.userService = SpringUtils.getBean(ISysUserService.class);
this.roleService = SpringUtils.getBean(ISysRoleService.class);
this.userRoleMapper = SpringUtils.getBean(SysUserRoleMapper.class);
this.assign = assign;
this.roleKeyIdMap = StreamUtils.toMap(roleService.selectRoleAll(), SysRoleVo::getRoleKey, SysRoleVo::getRoleId);
}
@Override
public void invoke(SysUserRoleImportVo record, AnalysisContext context) {
try {
ValidatorUtils.validate(record);
Long roleId = roleKeyIdMap.get(record.getRoleKey());
if (ObjectUtil.isNull(roleId)) {
failureNum++;
failureMsg.append("<br/>").append(failureNum).append("、角色标识 [").append(record.getRoleKey()).append("] 不存在");
return;
} else {
roleService.checkRoleDataScope(roleId);
}
SysUserVo sysUser = this.userService.selectUserByUserName(record.getUserName());
if (ObjectUtil.isNull(sysUser)) {
failureNum++;
failureMsg.append("<br/>").append(failureNum).append("、账号 [").append(record.getUserName()).append("] 不存在");
return;
}
Long userId = sysUser.getUserId();
SysUserRole userRole = new SysUserRole();
userRole.setRoleId(roleId);
userRole.setUserId(userId);
if (assign) {
Long count = userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, roleId)
.eq(SysUserRole::getUserId, userId)
);
if (count == 0) {
userRoleMapper.insert(userRole);
successMsg.append("<br/>").append(++successNum).append("、账号 [").append(record.getUserName()).append("] 分配角色成功");
} else {
successMsg.append("<br/>").append(++successNum).append("、账号 [").append(record.getUserName()).append("] 已存在角色,无需重复分配");
}
} else {
userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, roleId)
.eq(SysUserRole::getUserId, userId)
);
successNum++;
successMsg.append("<br/>").append(successNum).append("、账号 [").append(record.getUserName()).append("] 取消角色成功");
}
} catch (Exception e) {
failureNum++;
String msg = "<br/>" + failureNum + "、账号 " + HtmlUtil.cleanHtmlTag(ObjectUtil.defaultIfNull(record.getUserName(), "未知账号")) + " 操作失败:";
String message = e.getMessage();
if (e instanceof ConstraintViolationException cvException) {
message = StreamUtils.join(cvException.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
}
failureMsg.append(msg).append(message);
log.error(msg, e);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<SysUserRoleImportVo> getExcelResult() {
return new ExcelResult<>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
@Override
public List<SysUserRoleImportVo> getList() {
return null;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}