Merge branch 'main' of http://47.97.8.94:19527/yj/zn-cloud
This commit is contained in:
commit
df2bc13a38
@ -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("yyyyMMdd"));
|
||||
//通过身份证号码 获得性别
|
||||
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,30 @@ 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 宽度
|
||||
.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 +66,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);
|
||||
}
|
||||
}
|
||||
}
|
@ -36,7 +36,6 @@ public class BpmOAContractController {
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建请求申请")
|
||||
public CommonResult<Long> createContract(@Valid @RequestBody BpmOAContractCreateReqVO createReqVO) {
|
||||
|
||||
return success(contractService.createContract(getLoginUserId(), createReqVO));
|
||||
}
|
||||
|
||||
|
@ -60,4 +60,15 @@ public class BpmOAImprestController {
|
||||
|
||||
return success(BpmOAImprestConvert.INSTANCE.convert(imprest));
|
||||
}
|
||||
|
||||
@GetMapping("/getProcessInstanceId")
|
||||
@Operation(summary = "获得备用金表单")
|
||||
@Parameter(name = "reimbursementId", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<BpmOAImprestRespVO> getImprestByReimbursementId(@RequestParam("reimbursementId") Long reimbursementId) {
|
||||
|
||||
//根据user 查询审批通过并且未报销得表单。
|
||||
BpmOAImprestDO imprest = imprestService.getImprestByReimbursementId(reimbursementId);
|
||||
|
||||
return success(BpmOAImprestConvert.INSTANCE.convert(imprest));
|
||||
}
|
||||
}
|
||||
|
@ -37,14 +37,14 @@ public class BpmOALeaveController {
|
||||
private BpmOALeaveService leaveService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:oa-leave:create')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:oa-leave:create')")
|
||||
@Operation(summary = "创建请求申请")
|
||||
public CommonResult<Long> createLeave(@Valid @RequestBody BpmOALeaveCreateReqVO createReqVO) {
|
||||
return success(leaveService.createLeave(getLoginUserId(), createReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')")
|
||||
@Operation(summary = "获得请假申请")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<BpmOALeaveRespVO> getLeave(@RequestParam("id") Long id) {
|
||||
@ -53,7 +53,7 @@ public class BpmOALeaveController {
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')")
|
||||
@Operation(summary = "获得请假申请分页")
|
||||
public CommonResult<PageResult<BpmOALeaveRespVO>> getLeavePage(@Valid BpmOALeavePageReqVO pageVO) {
|
||||
PageResult<BpmOALeaveDO> pageResult = leaveService.getLeavePage(getLoginUserId(), pageVO);
|
||||
|
@ -30,14 +30,14 @@ public class BpmOAProcureController {
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建OA 采购申请")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:oa-procure:create')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:oa-procure:create')")
|
||||
public CommonResult<Long> createOaProcure(@Valid @RequestBody BpmOAProcureSaveReqVO createReqVO) {
|
||||
return success(bpmOaProcureService.createOaProcure(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新OA 采购申请")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:oa-procure:update')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:oa-procure:update')")
|
||||
public CommonResult<Boolean> updateOaProcure(@Valid @RequestBody BpmOAProcureSaveReqVO updateReqVO) {
|
||||
bpmOaProcureService.updateOaProcure(updateReqVO);
|
||||
return success(true);
|
||||
@ -46,7 +46,7 @@ public class BpmOAProcureController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除OA 采购申请")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:oa-procure:delete')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:oa-procure:delete')")
|
||||
public CommonResult<Boolean> deleteOaProcure(@RequestParam("id") Long id) {
|
||||
bpmOaProcureService.deleteOaProcure(id);
|
||||
return success(true);
|
||||
@ -55,7 +55,7 @@ public class BpmOAProcureController {
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得OA 采购申请")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:oa-procure:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:oa-procure:query')")
|
||||
public CommonResult<BpmOAProcureRespVO> getOaProcure(@RequestParam("id") Long id) {
|
||||
BpmOAProcureDO oaProcure = bpmOaProcureService.getOaProcure(id);
|
||||
return success(BpmOAProcureConvert.INSTANCE.convert(oaProcure));
|
||||
|
@ -39,14 +39,14 @@ public class BpmOAProcurePayController {
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建采购支付")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:create')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:create')")
|
||||
public CommonResult<Long> createOAProcurePay(@Valid @RequestBody BpmOAProcurePaySaveReqVO createReqVO) {
|
||||
return success(oAProcurePayService.createOAProcurePay(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新采购支付")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:update')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:update')")
|
||||
public CommonResult<Boolean> updateOAProcurePay(@Valid @RequestBody BpmOAProcurePaySaveReqVO updateReqVO) {
|
||||
oAProcurePayService.updateOAProcurePay(updateReqVO);
|
||||
return success(true);
|
||||
@ -55,7 +55,7 @@ public class BpmOAProcurePayController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除采购支付")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:delete')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:delete')")
|
||||
public CommonResult<Boolean> deleteOAProcurePay(@RequestParam("id") Long id) {
|
||||
oAProcurePayService.deleteOAProcurePay(id);
|
||||
return success(true);
|
||||
@ -64,7 +64,7 @@ public class BpmOAProcurePayController {
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得采购支付")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:query')")
|
||||
public CommonResult<BpmOAProcurePayRespVO> getOAProcurePay(@RequestParam("id") Long id) {
|
||||
BpmOAProcurePayDO oAProcurePay = oAProcurePayService.getOAProcurePay(id);
|
||||
return success(BeanUtils.toBean(oAProcurePay, BpmOAProcurePayRespVO.class));
|
||||
@ -72,7 +72,7 @@ public class BpmOAProcurePayController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得采购支付分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay:query')")
|
||||
public CommonResult<PageResult<BpmOAProcurePayRespVO>> getOAProcurePayPage(@Valid BpmOAProcurePayPageReqVO pageReqVO) {
|
||||
PageResult<BpmOAProcurePayDO> pageResult = oAProcurePayService.getOAProcurePayPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, BpmOAProcurePayRespVO.class));
|
||||
|
@ -31,14 +31,14 @@ public class BpmOAProcurePayItemController {
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建采购收款明细")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:create')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:create')")
|
||||
public CommonResult<Long> createOAProcurePayItem(@Valid @RequestBody BpmOAProcurePayItemSaveReqVO createReqVO) {
|
||||
return success(oAProcurePayItemService.createOAProcurePayItem(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新采购收款明细")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:update')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:update')")
|
||||
public CommonResult<Boolean> updateOAProcurePayItem(@Valid @RequestBody BpmOAProcurePayItemSaveReqVO updateReqVO) {
|
||||
oAProcurePayItemService.updateOAProcurePayItem(updateReqVO);
|
||||
return success(true);
|
||||
@ -47,7 +47,7 @@ public class BpmOAProcurePayItemController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除采购收款明细")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:delete')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:delete')")
|
||||
public CommonResult<Boolean> deleteOAProcurePayItem(@RequestParam("id") Long id) {
|
||||
oAProcurePayItemService.deleteOAProcurePayItem(id);
|
||||
return success(true);
|
||||
@ -56,7 +56,7 @@ public class BpmOAProcurePayItemController {
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得采购收款明细")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:query')")
|
||||
public CommonResult<BpmOAProcurePayItemRespVO> getOAProcurePayItem(@RequestParam("id") Long id) {
|
||||
BpmOAProcurePayItemDO oAProcurePayItem = oAProcurePayItemService.getOAProcurePayItem(id);
|
||||
return success(BeanUtils.toBean(oAProcurePayItem, BpmOAProcurePayItemRespVO.class));
|
||||
@ -64,7 +64,7 @@ public class BpmOAProcurePayItemController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得采购收款明细分页")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('bpm:OA-procure-pay-item:query')")
|
||||
public CommonResult<PageResult<BpmOAProcurePayItemRespVO>> getOAProcurePayItemPage(@Valid BpmOAProcurePayItemPageReqVO pageReqVO) {
|
||||
PageResult<BpmOAProcurePayItemDO> pageResult = oAProcurePayItemService.getOAProcurePayItemPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, BpmOAProcurePayItemRespVO.class));
|
||||
|
@ -6,6 +6,9 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.shiftjobs.BpmOAShiftjo
|
||||
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAShiftjobsConvert;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAShiftjobsDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAShiftjobsService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -33,6 +36,15 @@ public class BpmOAShiftjobsController {
|
||||
@Resource
|
||||
private BpmOAShiftjobsService shiftjobsService;
|
||||
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi userApi;
|
||||
|
||||
@Resource
|
||||
private PostApi postApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建请求申请")
|
||||
public CommonResult<Long> createShiftjobs(@Valid @RequestBody BpmOAShiftjobsCreateReqVO createReqVO) {
|
||||
@ -47,6 +59,22 @@ public class BpmOAShiftjobsController {
|
||||
|
||||
BpmOAShiftjobsDO shiftjobs = shiftjobsService.getShiftjobs(id);
|
||||
|
||||
return success(BpmOAShiftjobsConvert.INSTANCE.convert(shiftjobs));
|
||||
BpmOAShiftjobsRespVO bpmOAShiftjobsRespVO = BpmOAShiftjobsConvert.INSTANCE.convert(shiftjobs);
|
||||
//设置原部门名称
|
||||
bpmOAShiftjobsRespVO.setOldDeptName(deptApi.getDept(shiftjobs.getOldDeptId()).getCheckedData().getName());
|
||||
//设置原岗位名称
|
||||
bpmOAShiftjobsRespVO.setOldPostName(postApi.getPost(shiftjobs.getOldPostId()).getCheckedData().getName());
|
||||
//设置原负责人昵称
|
||||
bpmOAShiftjobsRespVO.setOldParentName(userApi.getUser(shiftjobs.getOldParentId()).getCheckedData().getNickname());
|
||||
|
||||
//设置新部门名称
|
||||
bpmOAShiftjobsRespVO.setNewDeptName(deptApi.getDept(shiftjobs.getNewDeptId()).getCheckedData().getName());
|
||||
//设置新岗位名称
|
||||
bpmOAShiftjobsRespVO.setNewPostName(postApi.getPost(shiftjobs.getNewPostId()).getCheckedData().getName());
|
||||
//设置新负责人昵称
|
||||
bpmOAShiftjobsRespVO.setNewParentName(userApi.getUser(shiftjobs.getNewParentId()).getCheckedData().getNickname());
|
||||
|
||||
|
||||
return success(bpmOAShiftjobsRespVO);
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract;
|
||||
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;
|
||||
@ -20,9 +18,6 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
* @author 符溶馨
|
||||
*/
|
||||
@Schema(description = "管理后台 - 合同审批创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode()
|
||||
@ToString(callSuper = true)
|
||||
public class BpmOAContractCreateReqVO {
|
||||
|
||||
@Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ -52,4 +47,82 @@ public class BpmOAContractCreateReqVO {
|
||||
|
||||
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<UploadUserFile> fileItems;
|
||||
|
||||
public BpmOAContractCreateReqVO() {
|
||||
}
|
||||
|
||||
public BpmOAContractCreateReqVO(String contractName, String contractNumber, LocalDate signingDate, String mCompanyName, String mHeadName, String oCompanyName, String oHeadName, List<UploadUserFile> fileItems) {
|
||||
this.contractName = contractName;
|
||||
this.contractNumber = contractNumber;
|
||||
this.signingDate = signingDate;
|
||||
this.mCompanyName = mCompanyName;
|
||||
this.mHeadName = mHeadName;
|
||||
this.oCompanyName = oCompanyName;
|
||||
this.oHeadName = oHeadName;
|
||||
this.fileItems = fileItems;
|
||||
}
|
||||
|
||||
public String getContractName() {
|
||||
return contractName;
|
||||
}
|
||||
|
||||
public void setContractName(String contractName) {
|
||||
this.contractName = contractName;
|
||||
}
|
||||
|
||||
public String getContractNumber() {
|
||||
return contractNumber;
|
||||
}
|
||||
|
||||
public void setContractNumber(String contractNumber) {
|
||||
this.contractNumber = contractNumber;
|
||||
}
|
||||
|
||||
public LocalDate getSigningDate() {
|
||||
return signingDate;
|
||||
}
|
||||
|
||||
public void setSigningDate(LocalDate signingDate) {
|
||||
this.signingDate = signingDate;
|
||||
}
|
||||
|
||||
public String getmCompanyName() {
|
||||
return mCompanyName;
|
||||
}
|
||||
|
||||
public void setmCompanyName(String mCompanyName) {
|
||||
this.mCompanyName = mCompanyName;
|
||||
}
|
||||
|
||||
public String getmHeadName() {
|
||||
return mHeadName;
|
||||
}
|
||||
|
||||
public void setmHeadName(String mHeadName) {
|
||||
this.mHeadName = mHeadName;
|
||||
}
|
||||
|
||||
public String getoCompanyName() {
|
||||
return oCompanyName;
|
||||
}
|
||||
|
||||
public void setoCompanyName(String oCompanyName) {
|
||||
this.oCompanyName = oCompanyName;
|
||||
}
|
||||
|
||||
public String getoHeadName() {
|
||||
return oHeadName;
|
||||
}
|
||||
|
||||
public void setoHeadName(String oHeadName) {
|
||||
this.oHeadName = oHeadName;
|
||||
}
|
||||
|
||||
public List<UploadUserFile> getFileItems() {
|
||||
return fileItems;
|
||||
}
|
||||
|
||||
public void setFileItems(List<UploadUserFile> fileItems) {
|
||||
this.fileItems = fileItems;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -41,6 +41,9 @@ public class BpmOAImprestRespVO extends BpmOABaseRespVO {
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
|
||||
private LocalDate date;
|
||||
|
||||
@Schema(description = "报销流程编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private Integer reimbursementId;
|
||||
|
||||
@Schema(description = "报销状态", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "报销状态不能为空")
|
||||
private Integer status;
|
||||
|
@ -27,8 +27,11 @@ public class BpmOAReimbursementCreateReqVO {
|
||||
@NotNull(message = "报销总金额中文大写不能为空")
|
||||
private String totalMoneyChinese ;
|
||||
|
||||
@Schema(description = "报销类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "报销类型不能为空")
|
||||
private BigDecimal reimbursementType ;
|
||||
|
||||
@Schema(description = "备用金差额", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
@NotNull(message = "备用金差额不能为空")
|
||||
private BigDecimal difference ;
|
||||
|
||||
@Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
|
@ -28,8 +28,11 @@ public class BpmOAReimbursementRespVO extends BpmOABaseRespVO {
|
||||
@NotNull(message = "报销总金额中文大写不能为空")
|
||||
private String totalMoneyChinese ;
|
||||
|
||||
@Schema(description = "报销类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "报销类型不能为空")
|
||||
private BigDecimal reimbursementType ;
|
||||
|
||||
@Schema(description = "备用金差额", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
@NotNull(message = "备用金差额不能为空")
|
||||
private BigDecimal difference ;
|
||||
|
||||
@Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
|
@ -43,6 +43,26 @@ public class BpmOAShiftjobsRespVO extends BpmOABaseRespVO {
|
||||
@Schema(description = "新岗位编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private Long newPostId;
|
||||
|
||||
@Schema(description = "原部门名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "原部门不能为空")
|
||||
private String oldDeptName;
|
||||
|
||||
@Schema(description = "原上级领导昵称", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private String oldParentName;
|
||||
|
||||
@Schema(description = "原岗位名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private String oldPostName;
|
||||
|
||||
@Schema(description = "新部门名臣", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "新部门不能为空")
|
||||
private String newDeptName;
|
||||
|
||||
@Schema(description = "新上级领导昵称", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private String newParentName;
|
||||
|
||||
@Schema(description = "新岗位名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private String newPostName;
|
||||
|
||||
@Schema(description = "备注", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private String notes;
|
||||
|
||||
|
@ -21,7 +21,7 @@ import java.util.List;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
//@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BpmOAContractDO extends BaseDO {
|
||||
|
@ -69,6 +69,11 @@ public class BpmOAImprestDO extends BaseDO {
|
||||
*/
|
||||
private LocalDate date;
|
||||
|
||||
/**
|
||||
* 报销流程业务编号
|
||||
*/
|
||||
private Long reimbursementId;
|
||||
|
||||
/**
|
||||
* 申请的结果
|
||||
*
|
||||
|
@ -28,6 +28,15 @@ import java.util.List;
|
||||
@AllArgsConstructor
|
||||
public class BpmOAReimbursementDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 1: 自费
|
||||
*/
|
||||
public static final Integer EXPENSE_TYPE = 1;
|
||||
/**
|
||||
* 2: 备用金
|
||||
*/
|
||||
public static final Integer IMPREST_TYPE = 2;
|
||||
|
||||
/**
|
||||
* 请假表单主键
|
||||
*/
|
||||
@ -55,6 +64,11 @@ public class BpmOAReimbursementDO extends BaseDO {
|
||||
*/
|
||||
private String totalMoneyChinese;
|
||||
|
||||
/**
|
||||
* 报销类型
|
||||
*/
|
||||
private Integer reimbursementType;
|
||||
|
||||
/**
|
||||
* 备用差额
|
||||
*/
|
||||
|
@ -18,7 +18,7 @@ public interface BpmOAImprestMapper extends BaseMapperX<BpmOAImprestDO> {
|
||||
default BpmOAImprestDO selectByUserId(Long userId, Integer status){
|
||||
|
||||
return selectOne(new LambdaQueryWrapperX<BpmOAImprestDO>().eq(BpmOAImprestDO::getUserId, userId)
|
||||
.eq(BpmOAImprestDO::getResult, BpmProcessInstanceResultEnum.PROCESS.getResult())
|
||||
.eq(BpmOAImprestDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult())
|
||||
.eq(BpmOAImprestDO::getStatus, status));
|
||||
}
|
||||
}
|
||||
|
@ -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 流程
|
||||
|
@ -45,4 +45,12 @@ public interface BpmOAImprestService {
|
||||
* @return 备用金申请
|
||||
*/
|
||||
BpmOAImprestDO getImprestByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 获得备用金表单
|
||||
*
|
||||
* @param reimbursementId 编号
|
||||
* @return 备用金申请
|
||||
*/
|
||||
BpmOAImprestDO getImprestByReimbursementId(Long reimbursementId);
|
||||
}
|
||||
|
@ -91,4 +91,11 @@ public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAIm
|
||||
//根据user 查询审批通过并且未报销得表单。
|
||||
return imprestMapper.selectByUserId(userId, BpmOAImprestDO.FLAG_FALSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmOAImprestDO getImprestByReimbursementId(Long reimbursementId) {
|
||||
|
||||
//根据报销业务编号获取备用金详情
|
||||
return imprestMapper.selectOne(BpmOAImprestDO::getReimbursementId, reimbursementId);
|
||||
}
|
||||
}
|
||||
|
@ -72,10 +72,10 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
|
||||
// 将工作流的编号,更新到 OA 报销表单中
|
||||
reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(reimbursement.getId()).setProcessInstanceId(processInstanceId));
|
||||
|
||||
//如果是备用金报销,则更新备用金流程status
|
||||
//如果是备用金报销,则更新备用金流程status,并存入当前报销流程ID
|
||||
if (createReqVO.getDifference() != null) {
|
||||
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestService.getImprestByUserId(userId);
|
||||
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.IN_PROGRESS));
|
||||
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setReimbursementId(reimbursement.getId()).setStatus(BpmOAImprestDO.IN_PROGRESS));
|
||||
}
|
||||
|
||||
List<UploadUserFile> fileItems = createReqVO.getFileItems() ;
|
||||
@ -95,7 +95,7 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
|
||||
if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) {
|
||||
|
||||
ProcessInstance instance = bpmProcessInstanceService.getProcessInstance(processInstanceId);
|
||||
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectByUserId(Long.valueOf(instance.getStartUserId()), BpmOAImprestDO.IN_PROGRESS);
|
||||
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectOne(BpmOAImprestDO::getReimbursementId, id);
|
||||
|
||||
if (instance.isEnded() && bpmOAImprestDO != null) {
|
||||
|
||||
@ -111,8 +111,7 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
|
||||
|| BpmProcessInstanceResultEnum.CANCEL.getResult().equals(result)
|
||||
|| BpmProcessInstanceResultEnum.BACK.getResult().equals(result)) {
|
||||
|
||||
ProcessInstance instance = bpmProcessInstanceService.getProcessInstance(processInstanceId);
|
||||
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectByUserId(Long.valueOf(instance.getStartUserId()), BpmOAImprestDO.IN_PROGRESS);
|
||||
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectOne(BpmOAImprestDO::getReimbursementId, id);
|
||||
|
||||
if (bpmOAImprestDO != null) {
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.api.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.PostRespVO;
|
||||
import cn.iocoder.yudao.module.system.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -10,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 服务 - 岗位")
|
||||
@ -22,4 +24,12 @@ public interface PostApi {
|
||||
@Parameter(name = "ids", description = "岗位编号数组", example = "1,2", required = true)
|
||||
CommonResult<Boolean> validPostList(@RequestParam("ids") Collection<Long> ids);
|
||||
|
||||
@GetMapping(PREFIX + "/get")
|
||||
@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();
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package cn.iocoder.yudao.module.system.api.dept.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "RPC 服务 - 岗位 Response DTO")
|
||||
@Data
|
||||
public class PostRespVO {
|
||||
|
||||
@Schema(description = "岗位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "岗位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "总监")
|
||||
private String name;
|
||||
}
|
@ -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,12 +1,19 @@
|
||||
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;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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;
|
||||
|
||||
@ -23,4 +30,18 @@ public class PostApiImpl implements PostApi {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<PostRespVO> getPost(Long id) {
|
||||
PostDO postDO = postService.getPost(id);
|
||||
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,8 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
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 +46,9 @@ public class UserController {
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
|
||||
@Resource
|
||||
private PostService postService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "新增用户")
|
||||
@PreAuthorize("@ss.hasPermission('system:user:create')")
|
||||
@ -100,9 +100,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 +125,7 @@ public class UserController {
|
||||
AdminUserDO user = userService.getUser(id);
|
||||
// 拼接数据
|
||||
DeptDO dept = deptService.getDept(user.getDeptId());
|
||||
|
||||
return success(UserConvert.INSTANCE.convert(user, dept));
|
||||
}
|
||||
|
||||
@ -135,25 +137,42 @@ 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<PostDO> postDO = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
postDO.sort(Comparator.comparing(PostDO::getSort));
|
||||
|
||||
// 输出 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), getDeptNameFun(deptDO), getPostNameFun(postDO));
|
||||
}
|
||||
|
||||
@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<PostDO> postDO = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
postDO.sort(Comparator.comparing(PostDO::getSort));
|
||||
|
||||
// 输出
|
||||
ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, list);
|
||||
ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, null, getDeptNameFun(deptDO), getPostNameFun(postDO));
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@ -169,4 +188,27 @@ public class UserController {
|
||||
return success(userService.importUserList(list, updateSupport));
|
||||
}
|
||||
|
||||
private List<String> getDeptNameFun(List<DeptDO> deptDO) {
|
||||
|
||||
List<String> deptName = new ArrayList<>();
|
||||
|
||||
for (DeptDO var : deptDO) {
|
||||
|
||||
deptName.add(var.getId() + ":" + var.getName());
|
||||
}
|
||||
|
||||
return deptName;
|
||||
}
|
||||
|
||||
private List<String> getPostNameFun(List<PostDO> postDO) {
|
||||
|
||||
List<String> postName = new ArrayList<>();
|
||||
|
||||
for (PostDO var : postDO) {
|
||||
|
||||
postName.add(var.getId() + ":" + var.getName());
|
||||
}
|
||||
|
||||
return postName;
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public interface PostMapper extends BaseMapperX<PostDO> {
|
||||
.likeIfPresent(PostDO::getCode, reqVO.getCode())
|
||||
.likeIfPresent(PostDO::getName, reqVO.getName())
|
||||
.eqIfPresent(PostDO::getStatus, reqVO.getStatus())
|
||||
.orderByDesc(PostDO::getId));
|
||||
.orderByAsc(PostDO::getSort));
|
||||
}
|
||||
|
||||
default PostDO selectByName(String name) {
|
||||
|
@ -101,4 +101,6 @@ public interface DeptService {
|
||||
* 根据用户ID 检索该用户所担任负责人的部门list
|
||||
*/
|
||||
List<DeptDO> getDeptByLeaderId(Long leaderUserId);
|
||||
|
||||
List<DeptDO> getDeptTree();
|
||||
}
|
||||
|
@ -269,4 +269,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);
|
||||
}
|
||||
}
|
||||
|
@ -155,9 +155,9 @@ public class RoleServiceImpl implements RoleService {
|
||||
throw exception(ROLE_NOT_EXISTS);
|
||||
}
|
||||
// 内置角色,不允许删除
|
||||
if (RoleTypeEnum.SYSTEM.getType().equals(roleDO.getType())) {
|
||||
throw exception(ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE);
|
||||
}
|
||||
// if (RoleTypeEnum.SYSTEM.getType().equals(roleDO.getType())) {
|
||||
// throw exception(ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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,62 @@ 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
|
||||
if (importUser.getDeptName() != null && !importUser.getDeptName().isEmpty()) {
|
||||
|
||||
//excel接受到部门名称格式为 id:name
|
||||
updateUser.setDeptId(Long.valueOf(importUser.getDeptName().split(":")[0]));
|
||||
}
|
||||
|
||||
//设置岗位ID
|
||||
if (importUser.getPostName() != null && !importUser.getPostName().isEmpty()) {
|
||||
|
||||
//excel接受到部门名称格式为 id:name
|
||||
String postID = importUser.getPostName().split(":")[0];
|
||||
|
||||
updateUser.setPostIds(Collections.singleton(Long.valueOf(postID)));
|
||||
}
|
||||
|
||||
// 判断如果不存在,在进行插入
|
||||
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))); // 设置默认密码
|
||||
|
||||
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 +510,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