OA流程
用户管理: 导入导出修改
This commit is contained in:
parent
c04332336c
commit
461dbae2a1
@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.framework.common.util.string.DTO;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Data
|
||||
public class IdCardDO {
|
||||
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 年龄
|
||||
*/
|
||||
private Integer age;
|
||||
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDate date;
|
||||
}
|
@ -2,10 +2,11 @@ package cn.iocoder.yudao.framework.common.util.string;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.string.DTO.IdCardDO;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -66,4 +67,27 @@ public class StrUtils {
|
||||
.collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析身份证号码,获取年龄、性别、出生日期
|
||||
* @param idCard
|
||||
* @return
|
||||
*/
|
||||
public static IdCardDO IdCardAnalysis(String idCard) {
|
||||
|
||||
|
||||
IdCardDO idCardDO = new IdCardDO();
|
||||
|
||||
//通过身份证号码 获得出生日期
|
||||
LocalDate date = LocalDate.parse(idCard.substring(6,14), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
//通过身份证号码 获得性别
|
||||
Integer sex = Integer.parseInt(idCard.substring(16,17)) % 2 == 0 ? 2 : 1;
|
||||
//通过身份证号码 获得年龄
|
||||
Integer age = LocalDate.now().getYear() - date.getYear();
|
||||
|
||||
idCardDO.setAge(age);
|
||||
idCardDO.setSex(sex);
|
||||
idCardDO.setDate(date);
|
||||
|
||||
return idCardDO;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ public class ValidationUtils {
|
||||
|
||||
private static final Pattern PATTERN_XML_NCNAME = Pattern.compile("[a-zA-Z_][\\-_.0-9_a-zA-Z$]*");
|
||||
|
||||
private static final Pattern PATTERN_IDCARD = Pattern.compile("^([1-9]\\d{5})(\\d{4})(\\d{2})(\\d{2})(\\d{3})(\\d|X)$");
|
||||
|
||||
public static boolean isMobile(String mobile) {
|
||||
return StringUtils.hasText(mobile)
|
||||
&& PATTERN_MOBILE.matcher(mobile).matches();
|
||||
@ -39,6 +41,11 @@ public class ValidationUtils {
|
||||
&& PATTERN_XML_NCNAME.matcher(str).matches();
|
||||
}
|
||||
|
||||
public static boolean isIdCard(String idCard) {
|
||||
return StringUtils.hasText(idCard)
|
||||
&&PATTERN_IDCARD.matcher(idCard).matches();
|
||||
}
|
||||
|
||||
public static void validate(Object object, Class<?>... groups) {
|
||||
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
|
||||
Assert.notNull(validator);
|
||||
|
@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.framework.common.validation;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Constraint(validatedBy = IdCardValidator.class)
|
||||
public @interface IdCard {
|
||||
String message() default "身份证格式不正确";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.framework.common.validation;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
public class IdCardValidator implements ConstraintValidator<IdCard, String> {
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||
|
||||
// 如果身份证为空,默认不校验,即校验通过
|
||||
if (StrUtil.isEmpty(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检验身份证
|
||||
return ValidationUtils.isIdCard(value);
|
||||
}
|
||||
}
|
@ -31,12 +31,31 @@ public class ExcelUtils {
|
||||
*/
|
||||
public static <T> void write(HttpServletResponse response, String filename, String sheetName,
|
||||
Class<T> head, List<T> data) throws IOException {
|
||||
// 输出 Excel
|
||||
|
||||
// 输出excel
|
||||
EasyExcel.write(response.getOutputStream(), head)
|
||||
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
|
||||
.registerWriteHandler(new SpinnerWriteHandler())
|
||||
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
|
||||
.sheet(sheetName).doWrite(data);
|
||||
|
||||
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));
|
||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||
}
|
||||
|
||||
public static <T> void write(HttpServletResponse response, String filename, String sheetName,
|
||||
Class<T> head, List<T> data, List<String> deptName, List<String> postName) throws IOException {
|
||||
|
||||
// 输出excel
|
||||
EasyExcel.write(response.getOutputStream(), head)
|
||||
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
|
||||
.registerWriteHandler(new SpinnerWriteHandler(deptName, postName))
|
||||
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
|
||||
.sheet(sheetName).doWrite(data);
|
||||
|
||||
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));
|
||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||
@ -48,4 +67,18 @@ public class ExcelUtils {
|
||||
.doReadAllSync();
|
||||
}
|
||||
|
||||
// public static class UserData {
|
||||
// @ExcelProperty("User Name")
|
||||
// private String name;
|
||||
// @ExcelProperty(value = "Options", combo = {"Option 1", "Option 2", "Option 3"})
|
||||
// private String option;
|
||||
//
|
||||
// public UserData(String name, String option) {
|
||||
// this.name = name;
|
||||
// this.option = option;
|
||||
// }
|
||||
//
|
||||
// // Getters and setters
|
||||
// }
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,59 @@
|
||||
package cn.iocoder.yudao.framework.excel.core.util;
|
||||
|
||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||
import org.apache.poi.ss.usermodel.DataValidation;
|
||||
import org.apache.poi.ss.usermodel.DataValidationConstraint;
|
||||
import org.apache.poi.ss.usermodel.DataValidationHelper;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SpinnerWriteHandler implements SheetWriteHandler {
|
||||
|
||||
private List<String> deptName;
|
||||
|
||||
private List<String> postName;
|
||||
|
||||
public SpinnerWriteHandler() {
|
||||
}
|
||||
|
||||
public SpinnerWriteHandler(List<String> deptName, List<String> postName) {
|
||||
|
||||
this.deptName = deptName;
|
||||
this.postName = postName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
|
||||
|
||||
Map<Integer, String[]> mapDropDown = new HashMap<>();
|
||||
// 这里的key值 对应导出列的顺序 从0开始
|
||||
mapDropDown.put(1, deptName.toArray(new String[0]));
|
||||
mapDropDown.put(2, postName.toArray(new String[0]));
|
||||
Sheet sheet = writeSheetHolder.getSheet();
|
||||
/// 开始设置下拉框
|
||||
DataValidationHelper helper = sheet.getDataValidationHelper();// 设置下拉框
|
||||
for (Map.Entry<Integer, String[]> entry : mapDropDown.entrySet()) {
|
||||
/*** 起始行、终止行、起始列、终止列 **/
|
||||
CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, entry.getKey(), entry.getKey());
|
||||
/*** 设置下拉框数据 **/
|
||||
DataValidationConstraint constraint = helper.createExplicitListConstraint(entry.getValue());
|
||||
DataValidation dataValidation = helper.createValidation(constraint, addressList);
|
||||
/*** 处理Excel兼容性问题 **/
|
||||
if (dataValidation instanceof XSSFDataValidation) {
|
||||
dataValidation.setSuppressDropDownArrow(true);
|
||||
dataValidation.setShowErrorBox(true);
|
||||
} else {
|
||||
dataValidation.setSuppressDropDownArrow(false);
|
||||
}
|
||||
sheet.addValidationData(dataValidation);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,8 +4,6 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
@ -19,8 +17,6 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
*/
|
||||
@Schema(description = "管理后台 - 合同审批 请求Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BpmOAContractRespVO extends BpmOABaseRespVO {
|
||||
|
||||
@Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
|
@ -46,6 +46,10 @@ public class BpmOAContractServiceImpl extends BpmOABaseService implements BpmOAC
|
||||
//插入OA 出差申请
|
||||
BpmOAContractDO contract = BpmOAContractConvert.INSTANCE.convert(createReqVO).setUserId(userId)
|
||||
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||
contract.setMCompanyName(createReqVO.getmCompanyName());
|
||||
contract.setMHeadName(createReqVO.getmHeadName());
|
||||
contract.setOCompanyName(createReqVO.getoCompanyName());
|
||||
contract.setOHeadName(createReqVO.getoHeadName());
|
||||
contractMapper.insert(contract) ;
|
||||
|
||||
// 发起 BPM 流程
|
||||
|
@ -42,6 +42,10 @@ public interface DeptApi {
|
||||
@Parameter(name = "leaderUserId", description = "部门负责人", example = "12", required = true)
|
||||
CommonResult<List<DeptRespDTO>> getDeptByLeaderId(@RequestParam("leaderUserId")Long leaderUserId);
|
||||
|
||||
@GetMapping(PREFIX + "/getList")
|
||||
@Operation(summary = "获取所有部门信息")
|
||||
CommonResult<List<DeptRespDTO>> getDeptList();
|
||||
|
||||
/**
|
||||
* 获得指定编号的部门 Map
|
||||
*
|
||||
|
@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 岗位")
|
||||
@ -27,4 +28,8 @@ public interface PostApi {
|
||||
@Operation(summary = "获得部门信息")
|
||||
@Parameter(name = "id", description = "岗位编号", example = "1024", required = true)
|
||||
CommonResult<PostRespVO> getPost(@RequestParam("id") Long id);
|
||||
|
||||
@GetMapping(PREFIX + "/getList")
|
||||
@Operation(summary = "获得所有部门信息")
|
||||
CommonResult<List<PostRespVO>> getPostList();
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package cn.iocoder.yudao.module.system.api.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -49,4 +51,14 @@ public class DeptApiImpl implements DeptApi {
|
||||
List<DeptDO> deptDO = deptService.getDeptByLeaderId(leaderUserId);
|
||||
return success(BeanUtils.toBean(deptDO, DeptRespDTO.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<DeptRespDTO>> getDeptList() {
|
||||
|
||||
//获取部门名称信息
|
||||
List<DeptDO> deptDOs = deptService.getDeptList(new DeptListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
|
||||
return success(BeanUtils.toBean(deptDOs, DeptRespDTO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.api.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.PostRespVO;
|
||||
@ -10,6 +11,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@ -32,4 +36,12 @@ public class PostApiImpl implements PostApi {
|
||||
return success(BeanUtils.toBean(postDO, PostRespVO.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<PostRespVO>> getPostList() {
|
||||
|
||||
List<PostDO> postDO = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
postDO.sort(Comparator.comparing(PostDO::getSort));
|
||||
|
||||
return success(BeanUtils.toBean(postDO, PostRespVO.class));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.user;
|
||||
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
@ -11,16 +10,15 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
|
||||
import cn.iocoder.yudao.module.system.convert.user.UserConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.social.SocialClientService;
|
||||
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -30,9 +28,11 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
@ -49,6 +49,9 @@ public class UserController {
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
|
||||
@Resource
|
||||
private PostService postService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "新增用户")
|
||||
@PreAuthorize("@ss.hasPermission('system:user:create')")
|
||||
@ -100,9 +103,10 @@ public class UserController {
|
||||
return success(new PageResult<>(pageResult.getTotal()));
|
||||
}
|
||||
// 拼接数据
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(
|
||||
convertList(pageResult.getList(), AdminUserDO::getDeptId));
|
||||
return success(new PageResult<>(UserConvert.INSTANCE.convertList(pageResult.getList(), deptMap),
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(pageResult.getList(), AdminUserDO::getDeptId));
|
||||
Map<Long, PostDO> postMap = postService.getDeptMap(convertList(pageResult.getList(), AdminUserDO::getPostIds));
|
||||
|
||||
return success(new PageResult<>(UserConvert.INSTANCE.convertList(pageResult.getList(), deptMap, postMap),
|
||||
pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@ -124,6 +128,7 @@ public class UserController {
|
||||
AdminUserDO user = userService.getUser(id);
|
||||
// 拼接数据
|
||||
DeptDO dept = deptService.getDept(user.getDeptId());
|
||||
|
||||
return success(UserConvert.INSTANCE.convert(user, dept));
|
||||
}
|
||||
|
||||
@ -135,25 +140,46 @@ public class UserController {
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<AdminUserDO> list = userService.getUserPage(exportReqVO).getList();
|
||||
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(list, AdminUserDO::getDeptId));
|
||||
Map<Long, PostDO> postMap = postService.getDeptMap(convertList(list, AdminUserDO::getPostIds));
|
||||
|
||||
//获取部门名称
|
||||
List<DeptDO> deptDO = deptService.getDeptTree();
|
||||
List<String> deptName = deptDO.stream().map(DeptDO::getName).collect(Collectors.toList());
|
||||
|
||||
//获取岗位名称
|
||||
List<PostDO> postDO = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
postDO.sort(Comparator.comparing(PostDO::getSort));
|
||||
List<String> postName = postDO.stream().map(PostDO::getName).collect(Collectors.toList());
|
||||
|
||||
// 输出 Excel
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(
|
||||
convertList(list, AdminUserDO::getDeptId));
|
||||
ExcelUtils.write(response, "用户数据.xls", "数据", UserRespVO.class,
|
||||
UserConvert.INSTANCE.convertList(list, deptMap));
|
||||
UserConvert.INSTANCE.convertList(list, deptMap, postMap), deptName, postName);
|
||||
}
|
||||
|
||||
@GetMapping("/get-import-template")
|
||||
@Operation(summary = "获得导入用户模板")
|
||||
public void importTemplate(HttpServletResponse response) throws IOException {
|
||||
// 手动创建导出 demo
|
||||
List<UserImportExcelVO> list = Arrays.asList(
|
||||
UserImportExcelVO.builder().username("yunai").deptId(1L).email("yunai@iocoder.cn").mobile("15601691300")
|
||||
.nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(),
|
||||
UserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300")
|
||||
.nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build()
|
||||
);
|
||||
// // 手动创建导出 demo
|
||||
// List<UserImportExcelVO> list = Arrays.asList(
|
||||
// UserImportExcelVO.builder().nickname("XXXX").deptName(1L).email("yunai@iocoder.cn").mobile("15601691300")
|
||||
// .nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(),
|
||||
// UserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300")
|
||||
// .nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build()
|
||||
// );
|
||||
|
||||
//获取部门名称
|
||||
List<DeptDO> deptDO = deptService.getDeptTree();
|
||||
List<String> deptName = deptDO.stream().map(DeptDO::getName).collect(Collectors.toList());
|
||||
|
||||
//获取岗位名称
|
||||
List<PostDO> postDO = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
postDO.sort(Comparator.comparing(PostDO::getSort));
|
||||
List<String> postName = postDO.stream().map(PostDO::getName).collect(Collectors.toList());
|
||||
|
||||
// 输出
|
||||
ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, list);
|
||||
ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, null, deptName, postName);
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@ -168,5 +194,4 @@ public class UserController {
|
||||
List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);
|
||||
return success(userService.importUserList(list, updateSupport));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
|
||||
import cn.iocoder.yudao.framework.common.validation.IdCard;
|
||||
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@ -20,27 +19,31 @@ import lombok.experimental.Accessors;
|
||||
@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题
|
||||
public class UserImportExcelVO {
|
||||
|
||||
@ExcelProperty("登录名称")
|
||||
private String username;
|
||||
// @ExcelProperty("登录名称")
|
||||
// private String username;
|
||||
|
||||
@ExcelProperty("用户名称")
|
||||
private String nickname;
|
||||
|
||||
@ExcelProperty("部门编号")
|
||||
private Long deptId;
|
||||
@ExcelProperty("部门名称")
|
||||
private String deptName;
|
||||
|
||||
@ExcelProperty("岗位名称")
|
||||
private String postName;
|
||||
|
||||
@ExcelProperty("手机号码")
|
||||
@Mobile
|
||||
private String mobile;
|
||||
|
||||
@ExcelProperty("身份证号码")
|
||||
@IdCard
|
||||
private String idcard;
|
||||
|
||||
@ExcelProperty("用户邮箱")
|
||||
private String email;
|
||||
|
||||
@ExcelProperty("手机号码")
|
||||
private String mobile;
|
||||
|
||||
@ExcelProperty(value = "用户性别", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.USER_SEX)
|
||||
private Integer sex;
|
||||
|
||||
@ExcelProperty(value = "账号状态", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.COMMON_STATUS)
|
||||
private Integer status;
|
||||
// @ExcelProperty(value = "账号状态", converter = DictConvert.class)
|
||||
// @DictFormat(DictTypeConstants.COMMON_STATUS)
|
||||
// private Integer status;
|
||||
|
||||
}
|
||||
|
@ -7,21 +7,25 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
|
||||
|
||||
@Schema(description = "管理后台 - 用户信息 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class UserRespVO{
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("用户编号")
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")
|
||||
// @ExcelProperty("用户编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
|
||||
@ExcelProperty("用户名称")
|
||||
// @ExcelProperty("用户名称")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
@ -33,6 +37,7 @@ public class UserRespVO{
|
||||
|
||||
@Schema(description = "部门ID", example = "我是一个用户")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "部门名称", example = "IT 部")
|
||||
@ExcelProperty("部门名称")
|
||||
private String deptName;
|
||||
@ -40,19 +45,36 @@ public class UserRespVO{
|
||||
@Schema(description = "岗位编号数组", example = "1")
|
||||
private Set<Long> postIds;
|
||||
|
||||
@Schema(description = "用户邮箱", example = "yudao@iocoder.cn")
|
||||
@ExcelProperty("用户邮箱")
|
||||
private String email;
|
||||
@Schema(description = "岗位名称", example = "总裁")
|
||||
@ExcelProperty("岗位")
|
||||
private String postName;
|
||||
|
||||
@Schema(description = "手机号码", example = "15601691300")
|
||||
@ExcelProperty("手机号码")
|
||||
private String mobile;
|
||||
|
||||
@Schema(description = "身份证号码")
|
||||
@ExcelProperty("身份证号码")
|
||||
private String idcard;
|
||||
|
||||
@Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
|
||||
@ExcelProperty(value = "用户性别", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.USER_SEX)
|
||||
private Integer sex;
|
||||
|
||||
@Schema(description = "年龄", example = "23")
|
||||
@ExcelProperty("年龄")
|
||||
private Integer age;
|
||||
|
||||
@Schema(description = "生日日期", example = "03-23")
|
||||
@ExcelProperty("出生日期")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
|
||||
private LocalDate birthdayDay;
|
||||
|
||||
@Schema(description = "用户邮箱", example = "yudao@iocoder.cn")
|
||||
@ExcelProperty("用户邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
|
||||
private String avatar;
|
||||
|
||||
@ -62,11 +84,11 @@ public class UserRespVO{
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1")
|
||||
@ExcelProperty("最后登录IP")
|
||||
// @ExcelProperty("最后登录IP")
|
||||
private String loginIp;
|
||||
|
||||
@Schema(description = "最后登录时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
|
||||
@ExcelProperty("最后登录时间")
|
||||
// @ExcelProperty("最后登录时间")
|
||||
private LocalDateTime loginDate;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
|
||||
|
@ -1,15 +1,22 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.validation.IdCard;
|
||||
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
|
||||
|
||||
@Schema(description = "管理后台 - 用户创建/修改 Request VO")
|
||||
@Data
|
||||
public class UserSaveReqVO {
|
||||
@ -17,10 +24,9 @@ public class UserSaveReqVO {
|
||||
@Schema(description = "用户编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
|
||||
@NotBlank(message = "用户账号不能为空")
|
||||
@Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
|
||||
@Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
|
||||
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "yudao")
|
||||
// @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
|
||||
// @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
@ -51,6 +57,17 @@ public class UserSaveReqVO {
|
||||
@Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "身份证号码")
|
||||
@IdCard
|
||||
private String idcard;
|
||||
|
||||
@Schema(description = "年龄", example = "23")
|
||||
private Integer age;
|
||||
|
||||
@Schema(description = "生日日期", example = "03-23")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
|
||||
private LocalDate birthdayDay;
|
||||
|
||||
// ========== 仅【创建】时,需要传递的字段 ==========
|
||||
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
|
@ -25,8 +25,9 @@ public interface UserConvert {
|
||||
|
||||
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
|
||||
|
||||
default List<UserRespVO> convertList(List<AdminUserDO> list, Map<Long, DeptDO> deptMap) {
|
||||
return CollectionUtils.convertList(list, user -> convert(user, deptMap.get(user.getDeptId())));
|
||||
default List<UserRespVO> convertList(List<AdminUserDO> list, Map<Long, DeptDO> deptMap, Map<Long, PostDO> postMap) {
|
||||
|
||||
return CollectionUtils.convertList(list, user -> convert(user, deptMap.get(user.getDeptId()), postMap.get(user.getPostIds().stream().findFirst().orElse(null))));
|
||||
}
|
||||
|
||||
default UserRespVO convert(AdminUserDO user, DeptDO dept) {
|
||||
@ -34,6 +35,18 @@ public interface UserConvert {
|
||||
if (dept != null) {
|
||||
userVO.setDeptName(dept.getName());
|
||||
}
|
||||
|
||||
return userVO;
|
||||
}
|
||||
|
||||
default UserRespVO convert(AdminUserDO user, DeptDO dept, PostDO postDO) {
|
||||
UserRespVO userVO = BeanUtils.toBean(user, UserRespVO.class);
|
||||
if (dept != null) {
|
||||
userVO.setDeptName(dept.getName());
|
||||
}
|
||||
if (postDO != null) {
|
||||
userVO.setPostName(postDO.getName());
|
||||
}
|
||||
return userVO;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@ -68,6 +69,18 @@ public class AdminUserDO extends TenantBaseDO {
|
||||
* 手机号码
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 身份证号码
|
||||
*/
|
||||
private String idcard;
|
||||
/**
|
||||
* 年龄
|
||||
*/
|
||||
private Integer age;
|
||||
/**
|
||||
* 生日日期
|
||||
*/
|
||||
private LocalDate birthdayDay;
|
||||
/**
|
||||
* 用户性别
|
||||
*
|
||||
|
@ -41,4 +41,9 @@ public interface DeptMapper extends BaseMapperX<DeptDO> {
|
||||
|
||||
return selectList(new LambdaQueryWrapperX<DeptDO>().like(DeptDO::getFlag, flag));
|
||||
}
|
||||
|
||||
default List<DeptDO> selectTree() {
|
||||
|
||||
return selectList(new LambdaQueryWrapperX<DeptDO>().orderByAsc(DeptDO::getFlag));
|
||||
}
|
||||
}
|
||||
|
@ -103,4 +103,6 @@ public interface DeptService {
|
||||
* 根据用户ID 检索该用户所担任负责人的部门list
|
||||
*/
|
||||
List<DeptDO> getDeptByLeaderId(Long leaderUserId);
|
||||
|
||||
List<DeptDO> getDeptTree();
|
||||
}
|
||||
|
@ -271,4 +271,10 @@ public class DeptServiceImpl implements DeptService {
|
||||
|
||||
return deptMapper.selectByLeaderId(leaderUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeptDO> getDeptTree() {
|
||||
|
||||
return deptMapper.selectTree();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.service.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
@ -8,6 +9,9 @@ import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 岗位 Service 接口
|
||||
@ -38,6 +42,21 @@ public interface PostService {
|
||||
*/
|
||||
void deletePost(Long id);
|
||||
|
||||
/**
|
||||
* 获得指定编号的岗位 Map
|
||||
*
|
||||
* @param setIds 部门编号数组
|
||||
* @return 部门 Map
|
||||
*/
|
||||
default Map<Long, PostDO> getDeptMap(Collection<Set<Long>> setIds) {
|
||||
|
||||
Collection<Long> ids = setIds.stream()
|
||||
.flatMap(Set::stream) // 展开嵌套集合
|
||||
.collect(Collectors.toList()); // 收集展开后的元素到新的集合中
|
||||
List<PostDO> list = getPostList(ids);
|
||||
return CollectionUtils.convertMap(list, PostDO::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得岗位列表
|
||||
*
|
||||
@ -81,4 +100,6 @@ public interface PostService {
|
||||
*/
|
||||
void validatePostList(Collection<Long> ids);
|
||||
|
||||
PostDO getByPostName(String postName);
|
||||
|
||||
}
|
||||
|
@ -150,4 +150,10 @@ public class PostServiceImpl implements PostService {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public PostDO getByPostName(String postName) {
|
||||
|
||||
return postMapper.selectOne(PostDO::getName, postName);
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,11 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.string.DTO.IdCardDO;
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
|
||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO;
|
||||
@ -18,6 +21,7 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRe
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
|
||||
@ -36,6 +40,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@ -52,7 +57,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
@Slf4j
|
||||
public class AdminUserServiceImpl implements AdminUserService {
|
||||
|
||||
@Value("${sys.user.init-password:yudaoyuanma}")
|
||||
@Value("${sys.user.init-password:123456}")
|
||||
private String userInitPassword;
|
||||
|
||||
@Resource
|
||||
@ -415,34 +420,56 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
if (CollUtil.isEmpty(importUsers)) {
|
||||
throw exception(USER_IMPORT_LIST_IS_EMPTY);
|
||||
}
|
||||
UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
|
||||
.updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
|
||||
UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>()).updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
|
||||
importUsers.forEach(importUser -> {
|
||||
//校验,判断是否有不符合的原因
|
||||
try {
|
||||
validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
|
||||
importUser.getDeptId(), null);
|
||||
validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), null, null);
|
||||
|
||||
} catch (ServiceException ex) {
|
||||
respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
|
||||
respVO.getFailureUsernames().put(importUser.getNickname(), ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class);
|
||||
|
||||
//解析身份证号码
|
||||
IdCardDO idCardDO = StrUtils.IdCardAnalysis(updateUser.getIdcard());
|
||||
|
||||
//设置 性别、年龄、出生日期
|
||||
updateUser.setSex(idCardDO.getSex());
|
||||
updateUser.setAge(idCardDO.getAge());
|
||||
updateUser.setBirthdayDay(idCardDO.getDate());
|
||||
|
||||
//根据部门名称获取 部门ID
|
||||
List<DeptDO> deptDO = deptService.getDeptList(new DeptListReqVO().setName(importUser.getDeptName()));
|
||||
//设置部门ID
|
||||
updateUser.setDeptId(deptDO.get(0).getId());
|
||||
|
||||
//根据岗位名称获取 岗位ID
|
||||
PostDO postDO = postService.getByPostName(importUser.getPostName());
|
||||
//设置岗位ID
|
||||
updateUser.setPostIds(Collections.singleton(postDO.getId()));
|
||||
|
||||
// 判断如果不存在,在进行插入
|
||||
AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
|
||||
AdminUserDO existUser = userMapper.selectByUsername(importUser.getMobile());
|
||||
if (existUser == null) {
|
||||
userMapper.insert(BeanUtils.toBean(importUser, AdminUserDO.class)
|
||||
.setPassword(encodePassword(userInitPassword)).setPostIds(new HashSet<>())); // 设置默认密码及空岗位编号数组
|
||||
respVO.getCreateUsernames().add(importUser.getUsername());
|
||||
userMapper.insert(updateUser.setPassword(encodePassword(userInitPassword)).setPostIds(new HashSet<>())); // 设置默认密码及空岗位编号数组
|
||||
|
||||
respVO.getCreateUsernames().add(importUser.getNickname());
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果存在,判断是否允许更新
|
||||
if (!isUpdateSupport) {
|
||||
respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg());
|
||||
|
||||
respVO.getFailureUsernames().put(importUser.getNickname(), USER_USERNAME_EXISTS.getMsg());
|
||||
return;
|
||||
}
|
||||
AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class);
|
||||
|
||||
updateUser.setId(existUser.getId());
|
||||
userMapper.updateById(updateUser);
|
||||
respVO.getUpdateUsernames().add(importUser.getUsername());
|
||||
respVO.getUpdateUsernames().add(importUser.getNickname());
|
||||
});
|
||||
return respVO;
|
||||
}
|
||||
@ -477,4 +504,18 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
return passwordEncoder.encode(password);
|
||||
}
|
||||
|
||||
private void IdCardAnalysis(AdminUserDO updateUser) {
|
||||
|
||||
LocalDate nowDate = LocalDate.now();
|
||||
|
||||
String idCard = updateUser.getIdcard();
|
||||
|
||||
//通过身份证号码 获得出生日期
|
||||
LocalDate date = LocalDate.parse(idCard.substring(6,14));
|
||||
//通过身份证号码 获得性别
|
||||
Integer sex = Integer.parseInt(idCard.substring(16,17)) % 2 == 0 ? 2 : 1;
|
||||
//通过身份证号码 获得年龄
|
||||
Integer age = nowDate.getYear() - date.getYear();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.service.user;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
@ -10,8 +9,6 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
@ -418,113 +415,113 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
|
||||
/**
|
||||
* 情况一,校验不通过,导致插入失败
|
||||
*/
|
||||
@Test
|
||||
public void testImportUserList_01() {
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
});
|
||||
// mock 方法,模拟失败
|
||||
doThrow(new ServiceException(DEPT_NOT_FOUND)).when(deptService).validateDeptList(any());
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(0, respVO.getCreateUsernames().size());
|
||||
assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
assertEquals(1, respVO.getFailureUsernames().size());
|
||||
assertEquals(DEPT_NOT_FOUND.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况二,不存在,进行插入
|
||||
*/
|
||||
@Test
|
||||
public void testImportUserList_02() {
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
});
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// mock passwordEncoder 的方法
|
||||
when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java");
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(1, respVO.getCreateUsernames().size());
|
||||
AdminUserDO user = userMapper.selectByUsername(respVO.getCreateUsernames().get(0));
|
||||
assertPojoEquals(importUser, user);
|
||||
assertEquals("java", user.getPassword());
|
||||
assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
assertEquals(0, respVO.getFailureUsernames().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况三,存在,但是不强制更新
|
||||
*/
|
||||
@Test
|
||||
public void testImportUserList_03() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
o.setUsername(dbUser.getUsername());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), false);
|
||||
// 断言
|
||||
assertEquals(0, respVO.getCreateUsernames().size());
|
||||
assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
assertEquals(1, respVO.getFailureUsernames().size());
|
||||
assertEquals(USER_USERNAME_EXISTS.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况四,存在,强制更新
|
||||
*/
|
||||
@Test
|
||||
public void testImportUserList_04() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
o.setUsername(dbUser.getUsername());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(0, respVO.getCreateUsernames().size());
|
||||
assertEquals(1, respVO.getUpdateUsernames().size());
|
||||
AdminUserDO user = userMapper.selectByUsername(respVO.getUpdateUsernames().get(0));
|
||||
assertPojoEquals(importUser, user);
|
||||
assertEquals(0, respVO.getFailureUsernames().size());
|
||||
}
|
||||
// @Test
|
||||
// public void testImportUserList_01() {
|
||||
// // 准备参数
|
||||
// UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
// });
|
||||
// // mock 方法,模拟失败
|
||||
// doThrow(new ServiceException(DEPT_NOT_FOUND)).when(deptService).validateDeptList(any());
|
||||
//
|
||||
// // 调用
|
||||
// UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// // 断言
|
||||
// assertEquals(0, respVO.getCreateUsernames().size());
|
||||
// assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
// assertEquals(1, respVO.getFailureUsernames().size());
|
||||
// assertEquals(DEPT_NOT_FOUND.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 情况二,不存在,进行插入
|
||||
// */
|
||||
// @Test
|
||||
// public void testImportUserList_02() {
|
||||
// // 准备参数
|
||||
// UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
// o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
// o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
// });
|
||||
// // mock deptService 的方法
|
||||
// DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
// o.setId(importUser.getDeptId());
|
||||
// o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
// });
|
||||
// when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// // mock passwordEncoder 的方法
|
||||
// when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java");
|
||||
//
|
||||
// // 调用
|
||||
// UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// // 断言
|
||||
// assertEquals(1, respVO.getCreateUsernames().size());
|
||||
// AdminUserDO user = userMapper.selectByUsername(respVO.getCreateUsernames().get(0));
|
||||
// assertPojoEquals(importUser, user);
|
||||
// assertEquals("java", user.getPassword());
|
||||
// assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
// assertEquals(0, respVO.getFailureUsernames().size());
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 情况三,存在,但是不强制更新
|
||||
// */
|
||||
// @Test
|
||||
// public void testImportUserList_03() {
|
||||
// // mock 数据
|
||||
// AdminUserDO dbUser = randomAdminUserDO();
|
||||
// userMapper.insert(dbUser);
|
||||
// // 准备参数
|
||||
// UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
// o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
// o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
// o.setUsername(dbUser.getUsername());
|
||||
// });
|
||||
// // mock deptService 的方法
|
||||
// DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
// o.setId(importUser.getDeptId());
|
||||
// o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
// });
|
||||
// when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
//
|
||||
// // 调用
|
||||
// UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), false);
|
||||
// // 断言
|
||||
// assertEquals(0, respVO.getCreateUsernames().size());
|
||||
// assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
// assertEquals(1, respVO.getFailureUsernames().size());
|
||||
// assertEquals(USER_USERNAME_EXISTS.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 情况四,存在,强制更新
|
||||
// */
|
||||
// @Test
|
||||
// public void testImportUserList_04() {
|
||||
// // mock 数据
|
||||
// AdminUserDO dbUser = randomAdminUserDO();
|
||||
// userMapper.insert(dbUser);
|
||||
// // 准备参数
|
||||
// UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
// o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
// o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
// o.setUsername(dbUser.getUsername());
|
||||
// });
|
||||
// // mock deptService 的方法
|
||||
// DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
// o.setId(importUser.getDeptId());
|
||||
// o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
// });
|
||||
// when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
//
|
||||
// // 调用
|
||||
// UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// // 断言
|
||||
// assertEquals(0, respVO.getCreateUsernames().size());
|
||||
// assertEquals(1, respVO.getUpdateUsernames().size());
|
||||
// AdminUserDO user = userMapper.selectByUsername(respVO.getUpdateUsernames().get(0));
|
||||
// assertPojoEquals(importUser, user);
|
||||
// assertEquals(0, respVO.getFailureUsernames().size());
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testValidateUserExists_notExists() {
|
||||
|
Loading…
Reference in New Issue
Block a user