Commit b1848be2 authored by 刘斌's avatar 刘斌

fix: 初始化基础信息,增加离职管理

parent ef3bb2d0
This diff is collapsed.
package com.anplus.hr.constant;
/**
* @author 刘斌
* @date 2025/11/17 17:14
*/
public interface EmployeeChangeLogTypeConstant {
String Entry = "1";
String Resign = "2";
String Transfer = "3";
String Regularization = "4";
String RenewalContract = "5";
}
package com.anplus.hr.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author 刘斌
* @date 2025/11/17 10:59
*/
@Getter
@AllArgsConstructor
public enum HrAgeGroupEnum {
UNDER_24("1", "24岁以下", 24),
AGE_25_TO_34("2", "25-34岁", 34),
AGE_35_TO_44("3", "35-44岁", 44),
OVER_45("4", "45岁以上", 200);
private final String code;
private final String name;
private final int ageLimit;
public static HrAgeGroupEnum getByAge(Integer age) {
if (age == null || age <= 0) {
return null;
}
for (HrAgeGroupEnum value : values()) {
if (age <= value.getAgeLimit()) {
return value;
}
}
return OVER_45;
}
}
......@@ -45,4 +45,39 @@ public interface HrConstant {
* 员工用工形式
*/
String HR_EMPLOYMENT_FORM = "hr_employment_form";
/**
* 员工职级
*/
String HR_JOB_LEVEL = "hr_job_level";
/**
* 员工岗位类型
*/
String HR_POSITION_TYPE = "hr_position_type";
/**
* 员工序列
*/
String HR_SEQUENCE = "hr_sequence";
/**
* 员工学历分类
*/
String HR_EDUCATION_CATEGORY = "hr_education_category";
/**
* 员工合同形式
*/
String HR_CONTRACT_FORM = "hr_contract_form";
/**
* 通用是否
*/
String SYS_YES_NO = "sys_yes_no";
/**
* 员工离职类型
*/
String HR_RESIGNATION_TYPE = "hr_resignation_type";
}
package com.anplus.hr.constant;
/**
* @author 刘斌
* @date 2025/11/18 14:38
*/
public interface HrEmployeeConstants {
/**
* 员工类型-转正员工
*/
String EMPLOYEE_TYPE_REGULAR = "1";
/**
* 用工形式-正式工
*/
String EMPLOYMENT_FORM_REGULAR = "1";
/**
* 合同形式-新签
*/
String CONTRACT_FORM_NEW = "1";
}
......@@ -6,15 +6,63 @@ package com.anplus.hr.constant;
*/
public interface HrFlowTypeConstant {
String Entry = "1";
/**
* 入职
*/
String ENTRY = "1";
/**
* 离职
*/
String RESIGN = "2";
/**
* 调配/异动
*/
String TRANSFER = "3";
/**
* 转正
*/
String REGULARIZATION = "4";
/**
* 续签
*/
String RENEWAL_CONTRACT = "5";
/**
* 部门调整
*/
String DEPT = "6";
/**
* 入职流程编码
*/
String ENTRY_CODE = "hrEntryFlow";
/**
* 离职流程编码
*/
String RESIGN_CODE = "hrResignFlow";
/**
* 调配流程编码
*/
String TRANSFER_CODE = "hrTransferFlow";
/**
* 转正流程编码
*/
String REGULARIZATION_CODE = "hrRegularizationFlow";
/**
* 续签流程编码
*/
String RENEWAL_CONTRACT_CODE = "renewalContractFlow";
/**
* 部门调整流程编码
*/
String DEPT_CODE = "hrDeptFlow";
}
package com.anplus.hr.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author 刘斌
* @date 2025/11/17 20:26
*/
@Getter
@AllArgsConstructor
public enum HrResignYearsOfServiceTypeEnum {
PROBATION_PERIOD("1", "试用期内", 6),
UNDER_THREE_YEARS("2", "入职3年内", 36),
OVER_THREE_YEARS("3", "入职3年以上", 1200);
private final String code;
private final String name;
private final int monthsLimit;
public static HrResignYearsOfServiceTypeEnum getByTotalMonths(Integer totalMonths) {
if (totalMonths == null || totalMonths <= 0) {
return null;
}
for (HrResignYearsOfServiceTypeEnum value : values()) {
if (totalMonths < value.monthsLimit) {
return value;
}
}
return null;
}
}
package com.anplus.hr.constant;
/**
* @author 刘斌
* @date 2025/11/17 20:43
*/
public interface HrResignationTypeConstant {
// 主动离职
String HAND_IN_WORK = "1";
// 被动离职
String FIRED = "2";
// 试用期未转正
String PROBATION_NOT_PASSED = "3";
}
package com.anplus.hr.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author 刘斌
* @date 2025/11/19 11:17
* 员工生命周期状态
* 用于报表统计
*/
@Getter
@AllArgsConstructor
public enum HrStatusEnum {
/**
* 草稿
*/
DRAFT(0, "草稿"),
/**
* 已入职
*/
ENTRY(1, "已入职"),
/**
* 已转正
*/
REGULARIZATION(2, "已转正"),
// TRANSFER(2, "已完成"),
// RENEWAL_CONTRACT(2, "已完成"),
/**
* 已离职
*/
RESIGN(8, "已离职");
/**
* 状态
*/
private final Integer status;
/**
* 描述
*/
private final String desc;
private static final Map<Integer, HrStatusEnum> STATUS_MAP = Arrays.stream(HrStatusEnum.values())
.collect(Collectors.toConcurrentMap(HrStatusEnum::getStatus, Function.identity()));
}
package com.anplus.hr.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author 刘斌
* @date 2025/11/17 11:12
*/
@Getter
@AllArgsConstructor
public enum HrYearsOfServiceSegmentEnum {
UNDER_TWO("1", "<2年", 24),
TWO_TO_FIVE("2", "≥2年<5年", 60),
FIVE_TO_TEN("3", "≥5年<10年", 120),
OVER_TEN("4", "≥10年以上", 1200);
private final String code;
private final String name;
private final int monthsLimit;
public static HrYearsOfServiceSegmentEnum getByTotalMonths(Integer totalMonths) {
if (totalMonths == null || totalMonths <= 0) {
return null;
}
for (HrYearsOfServiceSegmentEnum value : values()) {
if (totalMonths < value.monthsLimit) {
return value;
}
}
return null;
}
}
package com.anplus.hr.controller;
import java.util.List;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.binfast.common.core.constant.BusinessType;
import top.binfast.common.core.validate.AddGroup;
import top.binfast.common.core.validate.EditGroup;
import top.binfast.common.core.util.ResponseUtils;
import top.binfast.common.excel.annotion.ExcelExport;
import top.binfast.common.log.annotation.PinSysLog;
import com.anplus.hr.domain.params.EmployeeChangeLogListParam;
import com.anplus.hr.domain.params.EmployeeChangeLogParam;
import com.anplus.hr.domain.vo.EmployeeChangeLogVo;
import com.anplus.hr.service.EmployeeChangeLogServ;
/**
* 员工异动记录
*
* @author LiuBin
* @date 2025-11-17
*/
@Validated
@RestController
@RequestMapping("/employee/changeLog")
public class EmployeeChangeLogCtrl {
@Resource
private EmployeeChangeLogServ employeeChangeLogServ;
/**
* 查询员工异动记录列表
*/
@SaCheckPermission("employee:changeLog:list")
@GetMapping("/page")
public PageResponse<EmployeeChangeLogVo> pageList(EmployeeChangeLogListParam param) {
return employeeChangeLogServ.queryPageList(param);
}
/**
* 导出员工异动记录列表
*/
@ExcelExport
@SaCheckPermission("employee:changeLog:export")
@PinSysLog(value = "员工异动记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public List<EmployeeChangeLogVo> export(EmployeeChangeLogListParam param) {
return employeeChangeLogServ.queryList(param);
}
/**
* 获取员工异动记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("employee:changeLog:query")
@GetMapping("/{id}")
public SingleResponse<EmployeeChangeLogVo> getDetail(@PathVariable @Min(1)
Long id) {
return SingleResponse.of(employeeChangeLogServ.queryById(id));
}
/**
* 新增员工异动记录
*/
@SaCheckPermission("employee:changeLog:add")
@PinSysLog(value = "员工异动记录", businessType = BusinessType.INSERT)
@PostMapping()
public Response add(@Validated(AddGroup.class) @RequestBody EmployeeChangeLogParam param) {
return ResponseUtils.ofResult(employeeChangeLogServ.insertByParam(param));
}
/**
* 修改员工异动记录
*/
@SaCheckPermission("employee:changeLog:edit")
@PinSysLog(value = "员工异动记录", businessType = BusinessType.UPDATE)
@PutMapping()
public Response edit(@Validated(EditGroup.class) @RequestBody EmployeeChangeLogParam param) {
return ResponseUtils.ofResult(employeeChangeLogServ.updateByParam(param));
}
/**
* 删除员工异动记录
*
* @param ids 主键串
*/
@SaCheckPermission("employee:changeLog:remove")
@PinSysLog(value = "员工异动记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public Response remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return ResponseUtils.ofResult(employeeChangeLogServ.delByIds(List.of(ids)));
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.anplus.hr.domain.params.*;
import com.anplus.hr.domain.vo.EmployeeInfoImportVo;
import com.anplus.hr.domain.vo.EmployeeInfoResignImportVo;
import com.anplus.hr.domain.vo.EmployeeInfoVo;
import com.anplus.hr.service.EmployeeInfoServ;
import jakarta.annotation.Resource;
......@@ -21,6 +22,7 @@ import top.binfast.common.core.validate.AddGroup;
import top.binfast.common.core.validate.EditGroup;
import top.binfast.common.excel.annotion.ExcelExport;
import top.binfast.common.excel.annotion.ExcelStream;
import top.binfast.common.idempotent.annotation.NoRepeatSubmit;
import top.binfast.common.log.annotation.PinSysLog;
import java.util.ArrayList;
......@@ -54,30 +56,42 @@ public class EmployeeInfoCtrl {
/**
* 导出员工信息列表
*/
@ExcelExport(template = "导出简历模板.xlsx", fill = true)
@ExcelExport
@NoRepeatSubmit(interval = 60_000)
@SaCheckPermission("employee:info:export")
@PinSysLog(value = "员工信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public List<EmployeeInfoVo> export(EmployeeInfoListParam param) {
return employeeInfoServ.queryList(param);
}
/**
* 导出员工信息列表
*/
@ExcelExport(template = "简历模板.xlsx", fill = true)
@SaCheckPermission("employee:info:export")
@PinSysLog(value = "员工信息", businessType = BusinessType.EXPORT)
@PostMapping("/export/{id}")
public List<EmployeeInfoVo> export(@PathVariable Long id) {
EmployeeInfoVo vo = employeeInfoServ.infoDetail(id);
vo.setOnDuty("1".equals(vo.getEmployeeType()) ? "在职" : "离职");
return List.of(vo);
}
/**
* 导入员工信息列表
*/
// @NoRepeatSubmit(interval = 60_000)
@PinSysLog(value = "系统用户", businessType = BusinessType.IMPORT)
@SaCheckPermission("employee:info:import")
@PostMapping(value = "/excel/import")
public Response importWithOptions(@ExcelStream(headRowNumber = 2) Stream<EmployeeInfoImportVo> stream, @RequestPart("file") MultipartFile file) {
public Response importEmployees(@ExcelStream(headRowNumber = 2) Stream<EmployeeInfoImportVo> stream, @RequestPart("file") MultipartFile file) {
return employeeInfoServ.importEmployeeList(stream, file);
}
/**
* 获取导入模板
*/
@ExcelExport(template = "模板.xlsx", fill = true)
@ExcelExport(template = "在职模板.xlsx", fill = true)
@PostMapping("/importTemplate")
public List<EmployeeInfoImportVo> importTemplate() {
return new ArrayList<>();
......@@ -112,6 +126,7 @@ public class EmployeeInfoCtrl {
/**
* 新增员工信息
*/
@NoRepeatSubmit
@SaCheckPermission("employee:info:add")
@PinSysLog(value = "员工信息", businessType = BusinessType.INSERT)
@PostMapping()
......@@ -122,6 +137,7 @@ public class EmployeeInfoCtrl {
/**
* 修改员工信息
*/
@NoRepeatSubmit
@SaCheckPermission("employee:info:edit")
@PinSysLog(value = "员工信息", businessType = BusinessType.UPDATE)
@PutMapping()
......@@ -132,6 +148,7 @@ public class EmployeeInfoCtrl {
/**
* 申请入职
*/
@NoRepeatSubmit(interval = 60_000)
@SaCheckPermission("employee:info:add")
@PinSysLog(value = "员工信息-入职申请", businessType = BusinessType.UPDATE)
@PostMapping("/applyEntry")
......@@ -142,6 +159,7 @@ public class EmployeeInfoCtrl {
/**
* 申请调职
*/
@NoRepeatSubmit(interval = 60_000)
@SaCheckPermission("employee:info:edit")
@PinSysLog(value = "员工信息-调职申请", businessType = BusinessType.UPDATE)
@PostMapping("/applyTransfer")
......@@ -152,6 +170,7 @@ public class EmployeeInfoCtrl {
/**
* 申请离职
*/
@NoRepeatSubmit(interval = 60_000)
@SaCheckPermission("employee:info:resign")
@PinSysLog(value = "员工信息-离职申请", businessType = BusinessType.UPDATE)
@PostMapping("/applyResign")
......@@ -164,6 +183,7 @@ public class EmployeeInfoCtrl {
*
* @param ids 主键串
*/
@NoRepeatSubmit
@SaCheckPermission("employee:info:remove")
@PinSysLog(value = "员工信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
......
package com.anplus.hr.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.anplus.hr.domain.params.EmployeeInfoListParam;
import com.anplus.hr.domain.vo.EmployeeInfoResignImportVo;
import com.anplus.hr.domain.vo.EmployeeInfoResignVo;
import com.anplus.hr.service.EmployeeInfoResignServ;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import org.dromara.core.trans.anno.TransMethodResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.binfast.common.core.constant.BusinessType;
import top.binfast.common.excel.annotion.ExcelExport;
import top.binfast.common.excel.annotion.ExcelStream;
import top.binfast.common.idempotent.annotation.NoRepeatSubmit;
import top.binfast.common.log.annotation.PinSysLog;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* @author 刘斌
* @date 2025/11/13 20:40
*/
@Validated
@RestController
@RequestMapping("/employee/info/resign")
public class EmployeeInfoResignCtrl {
@Resource
private EmployeeInfoResignServ employeeInfoResignServ;
/**
* 查询员工信息列表
*/
@TransMethodResult
@SaCheckPermission("employee:infoResign:list")
@GetMapping("/page")
public PageResponse<EmployeeInfoResignVo> pageList(EmployeeInfoListParam param) {
return employeeInfoResignServ.queryPageList(param);
}
/**
* 导出员工信息列表
*/
@ExcelExport
@NoRepeatSubmit(interval = 60_000)
@SaCheckPermission("employee:infoResign:export")
@PinSysLog(value = "离职员工信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public List<EmployeeInfoResignVo> export(EmployeeInfoListParam param) {
return employeeInfoResignServ.queryList(param);
}
/**
* 导入员工信息列表
*/
// @NoRepeatSubmit(interval = 60_000)
@PinSysLog(value = "离职员工导入", businessType = BusinessType.IMPORT)
@SaCheckPermission("employee:infoResign:import")
@PostMapping(value = "/excel/import")
public Response importWithOptions(@ExcelStream(headRowNumber = 2) Stream<EmployeeInfoResignImportVo> stream, @RequestPart("file") MultipartFile file) {
return employeeInfoResignServ.importEmployeeResignList(stream, file);
}
/**
* 获取导入模板
*/
@ExcelExport(template = "离职模板.xlsx", fill = true)
@PostMapping("/importTemplate")
public List<EmployeeInfoResignImportVo> importTemplate() {
return new ArrayList<>();
}
/**
* 展示员工信息详细信息
*
* @param id 主键
*/
@TransMethodResult
@SaCheckPermission("employee:infoResign:query")
@GetMapping("/detail/{id}")
public SingleResponse<EmployeeInfoResignVo> infoDetail(@PathVariable @Min(1)
Long id) {
return SingleResponse.of(employeeInfoResignServ.infoDetail(id));
}
}
package com.anplus.hr.domain;
import top.binfast.common.mybatis.bean.model.TenantModel;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.io.Serial;
/**
* 员工异动记录对象 employee_change_log
*
* @author LiuBin
* @date 2025-11-17
*/
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@TableName("employee_change_log")
public class EmployeeChangeLog extends TenantModel {
@Serial
private static final long serialVersionUID = 1L;
/**
* 异动类型
*/
private String type;
/**
* 板块
*/
private String plate;
/**
* 部门ID
*/
private Long deptId;
/**
* 员工ID
*/
private Long employeeId;
/**
* 异动时间
*/
private LocalDate changeDate;
/**
* 离职类型 1.主动离职 2.被动离职
*/
private String resignType;
/**
* 离职工龄类型
*/
private String resignYearsOfServiceType;
}
package com.anplus.hr.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import top.binfast.common.mybatis.bean.model.BaseModel;
import top.binfast.common.mybatis.bean.model.TenantModel;
import java.io.Serial;
import java.time.LocalDate;
......@@ -13,13 +14,13 @@ import java.time.LocalDate;
* 员工信息对象 employee_info
*
* @author LiuBin
* @date 2025-10-28
* @date 2025-11-13
*/
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@TableName("employee_info")
public class EmployeeInfo extends BaseModel {
public class EmployeeInfo extends TenantModel {
@Serial
private static final long serialVersionUID = 1L;
......@@ -29,11 +30,6 @@ public class EmployeeInfo extends BaseModel {
*/
private String plate;
/**
* 项目
*/
private String project;
/**
* 一级部门
*/
......@@ -45,29 +41,39 @@ public class EmployeeInfo extends BaseModel {
private String secondLevelDepartment;
/**
* 部门id
* 三级部门
*/
private String thirdLevelDepartment;
/**
* 部门ID
*/
private Long deptId;
/**
* 工号
*/
private String employeeId;
private String employeeNo;
/**
* 职级
*/
private String jobLevel;
private Integer jobLevel;
/**
* 岗位
* 岗位类型
*/
private String position;
private String positionType;
/**
* 职务
* 序列
*/
private String post;
private String sequence;
/**
* 主岗位
*/
private String position;
/**
* 姓名
......@@ -80,9 +86,9 @@ public class EmployeeInfo extends BaseModel {
private String gender;
/**
* 简历图片
* 头像OSS_ID
*/
private String resumeImage;
private Long ossId;
/**
* 身份证号码
......@@ -104,6 +110,36 @@ public class EmployeeInfo extends BaseModel {
*/
private String ageGroup;
/**
* 兼职板块
*/
private String partTimePlate;
/**
* 兼职一级部门
*/
private String partTimeFirstDept;
/**
* 兼职二级部门
*/
private String partTimeSecondDept;
/**
* 兼职三级部门
*/
private String partTimeThirdDept;
/**
* 兼职部门ID
*/
private Long partDeptId;
/**
* 兼职岗位
*/
private String partTimePosition;
/**
* 籍贯
*/
......@@ -164,35 +200,70 @@ public class EmployeeInfo extends BaseModel {
*/
private String yearsOfService;
/**
* 工龄总月数
*/
private Integer yearsOfServiceMonths;
/**
* 工龄段
*/
private String yearsOfServiceSegment;
/**
* 学历
* 全日制学历
*/
private String fulltimeEducation;
/**
* 全日制毕业院校
*/
private String fulltimeSchool;
/**
* 全日制专业
*/
private String education;
private String fulltimeMajor;
/**
* 学位
* 全日制毕业日期
*/
private String degree;
private LocalDate fulltimeGraduationDate;
/**
* 毕业时间
* 全日制学位
*/
private LocalDate graduationDate;
private String fulltimeDegree;
/**
* 专业
* 非全日制学历
*/
private String major;
private String nonFulltimeEducation;
/**
* 毕业院校
* 非全日制毕业院校
*/
private String graduateSchool;
private String nonFulltimeSchool;
/**
* 非全日制专业
*/
private String nonFulltimeMajor;
/**
* 非全日制毕业日期
*/
private LocalDate nonFulltimeGraduationDate;
/**
* 非全日制学位
*/
private String nonFulltimeDegree;
/**
* 学历分类
*/
private String educationCategory;
/**
* 员工类型
......@@ -205,15 +276,30 @@ public class EmployeeInfo extends BaseModel {
private String professionalTitle;
/**
* 简历
* 证书情况
*/
private String certificateStatus;
/**
* 外部个人履历
*/
private String externalResume;
/**
* 内部个人履历
*/
private String resume;
private String internalResume;
/**
* 用工形式
*/
private String employmentForm;
/**
* 合同形式
*/
private String contractForm;
/**
* 劳动合同期限
*/
......@@ -244,26 +330,101 @@ public class EmployeeInfo extends BaseModel {
*/
private String contractEntity;
/**
* 社保主体
*/
private String socialSecurityEntity;
/**
* 是否缴纳社保
*/
private String hasSocialSecurityPaid;
/**
* 公积金主体
*/
private String providentFundEntity;
/**
* 是否缴纳公积金
*/
private String hasProvidentFundPaid;
/**
* 试用期(月数)
*/
private Integer probationPeriod;
/**
* 转正时间
*/
private LocalDate regularizationDate;
/**
* 异动情况
* 奖励情况
*/
private String transferStatus;
private String rewardStatus;
/**
* 奖惩情况
* 处罚情况
*/
private String rewardPunishmentStatus;
private String punishmentStatus;
/**
* 备注
*/
private String remarks;
/**
* 办公电话
*/
private String officePhone;
/**
* 短线
*/
private String shortLine;
/**
* 银行卡号
*/
private String bankCardNumber;
/**
* 开户行
*/
private String bankName;
/**
* 公司内是否有亲属关系
*/
private String hasRelativeInCompany;
/**
* 亲属姓名
*/
private String relativeName;
/**
* 介绍人
*/
private String introducer;
/**
* 工资发放地
*/
private String salaryLocation;
/**
* 绩效比例
*/
private String performanceRatio;
/**
* 离职类型
*/
private String resignationType;
/**
* 离职时间
*/
......@@ -275,7 +436,17 @@ public class EmployeeInfo extends BaseModel {
private String resignationReason;
/**
* 离职审批状态
* 最后结薪日
*/
private LocalDate finalPayDate;
/**
* 员工状态
*/
private Integer status;
/**
* 离职申请状态
*/
private Integer resignationApplyStatus;
......@@ -285,9 +456,24 @@ public class EmployeeInfo extends BaseModel {
private Integer entryApplyStatus;
/**
* 调配申请审批状态
* 调配申请状态
*/
private Integer transferApplyStatus;
/**
* 转正申请状态
*/
private Integer regularApplyStatus;
/**
* 续签合同申请状态
*/
private Integer renewalApplyStatus;
/**
* 照片
*/
@TableField(exist = false)
private String photo;
}
package com.anplus.hr.domain.params;
import lombok.Getter;
import lombok.Setter;
import top.binfast.common.core.bean.params.PageQueryParam;
import java.util.HashMap;
import java.util.Map;
import java.time.LocalDateTime;
/**
* 员工异动记录分页对象 employee_change_log
*
* @author LiuBin
* @date 2025-11-17
*/
@Getter
@Setter
public class EmployeeChangeLogListParam extends PageQueryParam {
/**
* 异动类型
*/
private String type;
/**
* 板块
*/
private String plate;
/**
* 部门ID
*/
private Long deptId;
/**
* 员工ID
*/
private Long employeeId;
/**
* 异动时间
*/
private LocalDateTime changeDate;
/**
* 离职类型
*/
private String resignType;
/**
* 离职工龄类型
*/
private String resignYearsOfServiceType;
private Map<String, Object> params = new HashMap<>();
}
package com.anplus.hr.domain.params;
import cn.idev.excel.annotation.ExcelProperty;
import com.anplus.hr.domain.EmployeeChangeLog;
import top.binfast.common.core.validate.AddGroup;
import top.binfast.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import jakarta.validation.constraints.*;
import java.time.LocalDateTime;;
/**
* 员工异动记录业务对象 employee_change_log
*
* @author LiuBin
* @date 2025-11-17
*/
@Data
@AutoMapper(target = EmployeeChangeLog.class, reverseConvertGenerate = false)
public class EmployeeChangeLogParam {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = { EditGroup.class })
private Long id;
/**
* 异动类型
*/
@NotBlank(message = "异动类型不能为空", groups = { AddGroup.class, EditGroup.class })
private String type;
/**
* 板块
*/
private String plate;
/**
* 部门ID
*/
@NotNull(message = "部门ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long deptId;
/**
* 员工ID
*/
@NotNull(message = "员工ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long employeeId;
/**
* 异动时间
*/
@NotNull(message = "异动时间不能为空", groups = { AddGroup.class, EditGroup.class })
private LocalDateTime changeDate;
/**
* 离职类型
*/
@NotBlank(message = "离职类型不能为空", groups = { AddGroup.class, EditGroup.class })
private String resignType;
/**
* 离职工龄类型
*/
@NotBlank(message = "离职工龄类型不能为空", groups = { AddGroup.class, EditGroup.class })
private String resignYearsOfServiceType;
}
package com.anplus.hr.domain.params;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
/**
* @author 刘斌
* @date 2025/10/31 15:47
......@@ -11,5 +14,11 @@ public class EmployeeEntryApplyParam {
private Long id;
/**
* 入职时间
*/
@NotNull(message = "入职时间不能为空")
private LocalDate entryDate;
private String remark;
}
......@@ -8,13 +8,11 @@ import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
;
/**
* 员工信息分页对象 employee_info
*
* @author LiuBin
* @date 2025-10-28
* @date 2025-11-13
*/
@Getter
@Setter
......@@ -25,11 +23,6 @@ public class EmployeeInfoListParam extends PageQueryParam {
*/
private String plate;
/**
* 项目
*/
private String project;
/**
* 一级部门
*/
......@@ -40,6 +33,16 @@ public class EmployeeInfoListParam extends PageQueryParam {
*/
private String secondLevelDepartment;
/**
* 三级部门
*/
private String thirdLevelDepartment;
/**
* 部门ID
*/
private Long deptId;
/**
* 工号
*/
......@@ -48,17 +51,22 @@ public class EmployeeInfoListParam extends PageQueryParam {
/**
* 职级
*/
private String jobLevel;
private Integer jobLevel;
/**
* 岗位
* 岗位类型
*/
private String position;
private String positionType;
/**
* 序列
*/
private String sequence;
/**
* 职务
* 主岗位
*/
private String post;
private String position;
/**
* 姓名
......@@ -75,6 +83,11 @@ public class EmployeeInfoListParam extends PageQueryParam {
*/
private String idCardNumber;
/**
* 照片
*/
private String photo;
/**
* 出生日期
*/
......@@ -90,6 +103,31 @@ public class EmployeeInfoListParam extends PageQueryParam {
*/
private String ageGroup;
/**
* 兼职板块
*/
private String partTimePlate;
/**
* 兼职一级部门
*/
private String partTimeFirstDept;
/**
* 兼职二级部门
*/
private String partTimeSecondDept;
/**
* 兼职三级部门
*/
private String partTimeThirdDept;
/**
* 兼职岗位
*/
private String partTimePosition;
/**
* 籍贯
*/
......@@ -156,29 +194,59 @@ public class EmployeeInfoListParam extends PageQueryParam {
private String yearsOfServiceSegment;
/**
* 学历
* 全日制学历
*/
private String fulltimeEducation;
/**
* 全日制毕业院校
*/
private String fulltimeSchool;
/**
* 全日制专业
*/
private String fulltimeMajor;
/**
* 全日制毕业日期
*/
private String education;
private LocalDate fulltimeGraduationDate;
/**
* 学位
* 全日制学位
*/
private String degree;
private String fulltimeDegree;
/**
* 毕业时间
* 非全日制学历
*/
private LocalDate graduationDate;
private String nonFulltimeEducation;
/**
* 专业
* 非全日制毕业院校
*/
private String major;
private String nonFulltimeSchool;
/**
* 毕业院校
* 非全日制专业
*/
private String graduateSchool;
private String nonFulltimeMajor;
/**
* 非全日制毕业日期
*/
private LocalDate nonFulltimeGraduationDate;
/**
* 非全日制学位
*/
private String nonFulltimeDegree;
/**
* 学历分类
*/
private String educationCategory;
/**
* 员工类型
......@@ -191,15 +259,30 @@ public class EmployeeInfoListParam extends PageQueryParam {
private String professionalTitle;
/**
* 简历
* 证书情况
*/
private String certificateStatus;
/**
* 外部个人履历
*/
private String externalResume;
/**
* 内部个人履历
*/
private String resume;
private String internalResume;
/**
* 用工形式
*/
private String employmentForm;
/**
* 合同形式
*/
private String contractForm;
/**
* 劳动合同期限
*/
......@@ -230,26 +313,101 @@ public class EmployeeInfoListParam extends PageQueryParam {
*/
private String contractEntity;
/**
* 社保主体
*/
private String socialSecurityEntity;
/**
* 是否缴纳社保
*/
private String hasSocialSecurityPaid;
/**
* 公积金主体
*/
private String providentFundEntity;
/**
* 是否缴纳公积金
*/
private String hasProvidentFundPaid;
/**
* 试用期(月数)
*/
private Integer probationPeriod;
/**
* 转正时间
*/
private LocalDate regularizationDate;
/**
* 异动情况
* 奖励情况
*/
private String transferStatus;
private String rewardStatus;
/**
* 奖惩情况
* 处罚情况
*/
private String rewardPunishmentStatus;
private String punishmentStatus;
/**
* 备注
*/
private String remarks;
/**
* 办公电话
*/
private String officePhone;
/**
* 短线
*/
private String shortLine;
/**
* 银行卡号
*/
private String bankCardNumber;
/**
* 开户行
*/
private String bankName;
/**
* 公司内是否有亲属关系
*/
private String hasRelativeInCompany;
/**
* 亲属姓名
*/
private String relativeName;
/**
* 介绍人
*/
private String introducer;
/**
* 工资发放地
*/
private String salaryLocation;
/**
* 绩效比例
*/
private String performanceRatio;
/**
* 离职类型
*/
private String resignationType;
/**
* 离职时间
*/
......@@ -260,6 +418,31 @@ public class EmployeeInfoListParam extends PageQueryParam {
*/
private String resignationReason;
/**
* 最后结薪日
*/
private LocalDate finalPayDate;
/**
* 员工生命周期状态
*/
private Integer status;
// /**
// * 离职申请状态
// */
// private Integer resignationApplyStatus;
//
// /**
// * 入职审批状态
// */
// private Integer entryApplyStatus;
//
// /**
// * 调配申请状态
// */
// private Integer transferApplyStatus;
private Map<String, Object> params = new HashMap<>();
......
package com.anplus.hr.domain.params;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
/**
* 转正申请参数
* @author 刘斌
* @date 2025/11/18 11:27
*
* !!!需要自动填写的字段!!!
* 员工类型:转正员工
* 用工形式:正式工
* 合同形式:新签
* 劳动合同期限:开始时间-结束时间
* 合同到期提醒:结束时间减一个月
*/
@Data
public class EmployeeRegularApplyParam {
private Long id;
/**
* 劳动合同开始时间
*/
@NotNull(message = "劳动合同开始时间")
private LocalDate contractStartDate;
/**
* 劳动合同截止时间
*/
@NotNull(message = "劳动合同截止时间")
private LocalDate contractEndDate;
/**
* 劳动合同签订情况
*/
private String contractSigningStatus;
/**
* 合同主体
*/
private String contractEntity;
/**
* 社保主体
*/
private String socialSecurityEntity;
/**
* 是否缴纳社保
*/
private String hasSocialSecurityPaid;
/**
* 公积金主体
*/
private String providentFundEntity;
/**
* 是否缴纳公积金
*/
private String hasProvidentFundPaid;
/**
* 转正时间
*/
private LocalDate regularizationDate;
private String remark;
}
package com.anplus.hr.domain.params;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
/**
* 续签合同申请参数
* @author 刘斌
* @date 2025/11/18 11:36
*
* !!!需要自动填写的字段!!!
* 劳动合同期限:开始时间-结束时间
* 合同到期提醒:结束时间减一个月
*/
@Data
public class EmployeeRenewalContractApplyParam {
private Long id;
/**
* 合同形式
*/
@NotBlank(message = "合同形式不能为空")
private String contractForm;
/**
* 劳动合同开始时间
*/
@NotNull(message = "劳动合同开始时间不能为空")
private LocalDate contractStartDate;
/**
* 劳动合同截止时间
*/
@NotNull(message = "劳动合同截止时间不能为空")
private LocalDate contractEndDate;
/**
* 劳动合同签订情况
*/
private String contractSigningStatus;
private String remark;
}
package com.anplus.hr.domain.params;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import top.binfast.common.core.validate.AddGroup;
import top.binfast.common.core.validate.EditGroup;
import java.time.LocalDate;
/**
* 离职申请参数
* @author 刘斌
* @date 2025/10/31 15:48
*/
......@@ -14,12 +18,24 @@ public class EmployeeResignApplyParam {
private Long id;
/**
* 离职类型
*/
@NotBlank(message = "离职类型不能为空")
private String resignationType;
/**
* 离职时间
*/
@NotNull(message = "离职时间不能为空")
private LocalDate resignDate;
/**
* 最后结薪日
*/
// @NotNull(message = "最后结薪日不能为空")
private LocalDate finalPayDate;
/**
* 离职原因
*/
......
......@@ -13,12 +13,33 @@ public class EmployeeTransferApplyParam {
private Long id;
/**
* 板块
*/
@NotBlank(message = "板块不能为空")
private String plate;
/**
* 一级部门
*/
@NotBlank(message = "一级部门不能为空")
private String firstLevelDepartment;
/**
* 二级部门
*/
@NotBlank(message = "二级部门不能为空")
private String secondLevelDepartment;
/**
* 三级部门
*/
@NotBlank(message = "三级部门不能为空")
private String thirdLevelDepartment;
/**
* 部门id
*/
@NotNull(message = "部门id不能为空")
private Long deptId;
......
package com.anplus.hr.domain.vo;
import java.time.LocalDateTime;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.ExcelIgnore;
import com.anplus.hr.domain.EmployeeChangeLog;
import top.binfast.common.excel.annotion.ExcelDictFormat;
import top.binfast.common.excel.converters.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 员工异动记录视图对象 employee_change_log
*
* @author LiuBin
* @date 2025-11-17
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = EmployeeChangeLog.class)
public class EmployeeChangeLogVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Long id;
/**
* 异动类型
*/
@ExcelProperty(value = "异动类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "HR_CHANGE_LOG_TYPE")
private String type;
/**
* 板块
*/
@ExcelProperty(value = "板块")
private String plate;
/**
* 部门ID
*/
@ExcelProperty(value = "部门ID")
private Long deptId;
/**
* 员工ID
*/
@ExcelProperty(value = "员工ID")
private Long employeeId;
/**
* 异动时间
*/
@ExcelProperty(value = "异动时间")
private LocalDateTime changeDate;
/**
* 离职类型
*/
@ExcelProperty(value = "离职类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "HR_RESIGNATION_TYPE")
private String resignType;
/**
* 离职工龄类型
*/
@ExcelProperty(value = "离职工龄类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "HR_RESIGN_YEARS_OF_SERVICE_TYPE")
private String resignYearsOfServiceType;
}
package com.anplus.hr.domain.vo;
import cn.idev.excel.annotation.ExcelProperty;
import com.anplus.hr.constant.HrConstant;
import com.anplus.hr.domain.EmployeeInfo;
import com.anplus.hr.domain.params.EmployeeInfoParam;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import lombok.Getter;
import lombok.Setter;
import top.binfast.common.excel.annotion.ExcelDictFormat;
import top.binfast.common.excel.converters.ExcelDictConvert;
import java.io.Serial;
import java.time.LocalDate;
/**
* @author 刘斌
* @date 2025/11/13 20:47
*/
@Getter
@AutoMappers({
@AutoMapper(target = EmployeeInfo.class, reverseConvertGenerate = false),
@AutoMapper(target = EmployeeInfoParam.class, reverseConvertGenerate = false)
})
public class EmployeeInfoResignImportVo extends EmployeeInfoImportVo {
@Serial
private static final long serialVersionUID = 1L;
/**
* 离职类型
*/
@ExcelProperty(value = "离职类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = HrConstant.HR_RESIGNATION_TYPE)
private String resignationType;
/**
* 离职时间
*/
@Setter
@ExcelProperty(value = "离职时间")
private LocalDate resignationDate;
/**
* 离职原因
*/
@ExcelProperty(value = "离职原因")
private String resignationReason;
/**
* 最后结薪日
*/
@Setter
@ExcelProperty(value = "最后结薪日")
private LocalDate finalPayDate;
public void setResignationType(String resignationType) {
this.resignationType = resignationType == null ? null : resignationType.trim();
}
public void setResignationReason(String resignationReason) {
this.resignationReason = resignationReason == null ? null : resignationReason.trim();
}
}
package com.anplus.hr.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.anplus.hr.constant.HrConstant;
import com.anplus.hr.domain.EmployeeInfo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.core.trans.anno.Trans;
import org.dromara.core.trans.constant.TransType;
import top.binfast.common.excel.annotion.ExcelDictFormat;
import top.binfast.common.excel.converters.ExcelDictConvert;
import java.time.LocalDate;
/**
* @author 刘斌
* @date 2025/11/13 20:44
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = EmployeeInfo.class)
public class EmployeeInfoResignVo extends EmployeeInfoVo {
/**
* 离职类型
*/
@ExcelProperty(value = "离职类型", converter = ExcelDictConvert.class, index = 77)
@ExcelDictFormat(dictType = HrConstant.HR_RESIGNATION_TYPE)
@Trans(type = TransType.DICTIONARY, key = HrConstant.HR_RESIGNATION_TYPE)
private String resignationType;
/**
* 离职时间
*/
@ExcelProperty(value = "离职时间", index = 78)
private LocalDate resignationDate;
/**
* 离职原因
*/
@ExcelProperty(value = "离职原因", index = 79)
private String resignationReason;
/**
* 最后结薪日
*/
@ExcelProperty(value = "最后结薪日", index = 80)
private LocalDate finalPayDate;
/**
* 离职申请状态
*/
// @ExcelProperty(value = "离职申请状态")
private Integer resignationApplyStatus;
}
package com.anplus.hr.mapper;
import com.anplus.hr.domain.EmployeeChangeLog;
import top.binfast.common.mybatis.mapper.BinBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 员工异动记录Mapper接口
*
* @author LiuBin
* @date 2025-11-17
*/
@Mapper
public interface EmployeeChangeLogMapper extends BinBaseMapper<EmployeeChangeLog> {
}
......@@ -13,4 +13,13 @@ public interface EmployeeAuditLogServ {
List<SysAuditLog> queryAuditLogs(String flowLogIds);
Boolean saveAuditLogs(List<SysAuditLog> auditLog);
default void saveAuditLog(String auditName, String auditField, String auditFieldName, String afterVal, List<SysAuditLog> list) {
SysAuditLog auditLog = new SysAuditLog();
auditLog.setAuditName(auditName);
auditLog.setAuditField(auditField);
auditLog.setAuditFieldName(auditFieldName);
auditLog.setAfterVal(afterVal);
list.add(auditLog);
}
}
package com.anplus.hr.service;
import com.alibaba.cola.dto.PageResponse;
import com.anplus.hr.domain.EmployeeChangeLog;
import com.anplus.hr.domain.EmployeeInfo;
import com.anplus.hr.domain.params.EmployeeChangeLogListParam;
import com.anplus.hr.domain.params.EmployeeChangeLogParam;
import com.anplus.hr.domain.vo.EmployeeChangeLogVo;
import com.baomidou.mybatisplus.extension.service.IService;
import java.time.LocalDate;
import java.util.List;
/**
* 员工异动记录Service接口
*
* @author LiuBin
* @date 2025-11-17
*/
public interface EmployeeChangeLogServ extends IService<EmployeeChangeLog> {
/**
* 分页查询员工异动记录列表
*
* @param param 查询条件
* @return 员工异动记录分页列表
*/
PageResponse<EmployeeChangeLogVo> queryPageList(EmployeeChangeLogListParam param);
/**
* 查询符合条件的员工异动记录列表
*
* @param param 查询条件
* @return 员工异动记录列表
*/
List<EmployeeChangeLogVo> queryList(EmployeeChangeLogListParam param);
/**
* 查询员工异动记录
*
* @param id 主键
* @return 员工异动记录
*/
EmployeeChangeLogVo queryById(Long id);
/**
* 新增员工异动记录
*
* @param employeeInfo 员工信息
* @param changeType 变更类型
* @return 是否新增成功
*/
Boolean insertByEmployee(EmployeeInfo employeeInfo, String changeType, LocalDate changeDate);
/**
* 新增员工异动记录
*
* @param param 员工异动记录
* @return 是否新增成功
*/
Boolean insertByParam(EmployeeChangeLogParam param);
/**
* 修改员工异动记录
*
* @param param 员工异动记录
* @return 是否修改成功
*/
Boolean updateByParam(EmployeeChangeLogParam param);
/**
* 校验并批量删除员工异动记录信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
Boolean delByIds(List<Long> ids);
}
package com.anplus.hr.service;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.anplus.hr.domain.EmployeeInfo;
import com.anplus.hr.domain.params.EmployeeInfoListParam;
import com.anplus.hr.domain.vo.EmployeeInfoResignImportVo;
import com.anplus.hr.domain.vo.EmployeeInfoResignVo;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.stream.Stream;
/**
* @author 刘斌
* @date 2025/11/13 20:40
*/
public interface EmployeeInfoResignServ extends IService<EmployeeInfo> {
/**
* 分页查询离职员工信息列表
*
* @param param 查询条件
* @return 员工信息分页列表
*/
PageResponse<EmployeeInfoResignVo> queryPageList(EmployeeInfoListParam param);
/**
* 查询符合条件的离职员工信息列表
*
* @param param 查询条件
* @return 员工信息列表
*/
List<EmployeeInfoResignVo> queryList(EmployeeInfoListParam param);
/**
* 导入离职员工信息列表
*
* @param stream 员工信息列表
* @return 是否导入成功
*/
Response importEmployeeResignList(Stream<EmployeeInfoResignImportVo> stream, MultipartFile file);
/**
* 获取离职员工信息详情
*
* @param id 主键
* @return 员工信息
*/
EmployeeInfoResignVo infoDetail(Long id);
}
package com.anplus.hr.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.anplus.hr.domain.EmployeeInfo;
import com.anplus.hr.domain.params.*;
import com.anplus.hr.domain.vo.EmployeeInfoImportVo;
import com.anplus.hr.domain.vo.EmployeeInfoVo;
import org.springframework.web.multipart.MultipartFile;
import top.binfast.app.biz.sysapi.bean.model.oss.SysOss;
import top.binfast.common.excel.image.CellImageData;
import top.binfast.common.excel.image.ExcelProcessingResult;
import top.binfast.common.oss.entity.UploadResult;
import java.util.List;
import java.util.stream.Stream;
......@@ -37,6 +44,14 @@ public interface EmployeeInfoServ extends IService<EmployeeInfo> {
*/
List<EmployeeInfoVo> queryList(EmployeeInfoListParam param);
/**
* 构建查询条件
*
* @param param 查询条件
* @return 查询条件
*/
LambdaQueryWrapper<EmployeeInfo> buildQueryWrapper(EmployeeInfoListParam param);
/**
* 导入员工信息列表
*
......@@ -105,6 +120,20 @@ public interface EmployeeInfoServ extends IService<EmployeeInfo> {
*/
Boolean applyResign(EmployeeResignApplyParam param);
/**
* 员工转正申请
*
* @param param 参数
*/
Boolean applyRegular(EmployeeRegularApplyParam param);
/**
* 员工续签合同申请
*
* @param param 参数
*/
Boolean applyRenewalContract(EmployeeRenewalContractApplyParam param);
/**
* 校验并批量删除员工信息信息
*
......@@ -113,4 +142,32 @@ public interface EmployeeInfoServ extends IService<EmployeeInfo> {
*/
Boolean delByIds(List<Long> ids);
/**
* 处理图片上传结果
*
* @param excelProcessingResult excel处理结果
* @param importVo 导入数据
*/
SysOss handleImageToUrl(ExcelProcessingResult excelProcessingResult, EmployeeInfoImportVo importVo);
/**
* 构建部门名称字符串
*
* @param importVo 导入数据
* @return 部门名称字符串
*/
default String buildDeptNameStr(EmployeeInfoImportVo importVo) {
StringBuilder builder = new StringBuilder(importVo.getPlate());
if (StrUtil.isNotBlank(importVo.getFirstLevelDepartment())) {
builder.append(StrUtil.SLASH).append(importVo.getFirstLevelDepartment());
}
if (StrUtil.isNotBlank(importVo.getSecondLevelDepartment())) {
builder.append(StrUtil.SLASH).append(importVo.getSecondLevelDepartment());
}
if (StrUtil.isNotBlank(importVo.getThirdLevelDepartment())) {
builder.append(StrUtil.SLASH).append(importVo.getThirdLevelDepartment());
}
return builder.toString();
}
}
package com.anplus.hr.service.impl;
import com.anplus.hr.domain.EmployeeInfo;
import com.anplus.hr.domain.vo.EmployeeInfoVo;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import top.binfast.app.biz.sysapi.bean.model.oss.SysOss;
import top.binfast.app.biz.sysapi.dao.system.SysOssMapper;
import top.binfast.common.oss.core.OssService;
import top.binfast.common.oss.enums.AccessPolicyType;
import java.util.Date;
import java.util.List;
/**
* @author 刘斌
* @date 2025/11/17 10:35
*/
@Component
@RequiredArgsConstructor
public class EmployeeAsyncService {
private final SysOssMapper sysOssMapper;
private final OssService ossService;
@Async
public void saveOssBatch(List<SysOss> ossList) {
sysOssMapper.insert(ossList);
}
/**
* 生成临时URL
*
* @param employeeInfoVo
* @return
*/
public EmployeeInfoVo matchingUrl(EmployeeInfoVo employeeInfoVo) {
// OssClient storage = OssFactory.instance(oss.getService());
// 仅修改桶类型为 private 的URL,临时URL时长为300s
if (employeeInfoVo.getPhoto() == null) {
return employeeInfoVo;
}
Date expiration = new Date(new Date().getTime() + 300 * 1000L);
if (AccessPolicyType.PRIVATE == ossService.getAccessPolicy()) {
employeeInfoVo.setPhoto(ossService.getPrivateUrl(employeeInfoVo.getPhoto(), expiration));
}
return employeeInfoVo;
}
}
package com.anplus.hr.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageResponse;
import com.anplus.hr.constant.EmployeeChangeLogTypeConstant;
import com.anplus.hr.constant.HrResignYearsOfServiceTypeEnum;
import com.anplus.hr.constant.HrResignationTypeConstant;
import com.anplus.hr.domain.EmployeeChangeLog;
import com.anplus.hr.domain.EmployeeInfo;
import com.anplus.hr.domain.params.EmployeeChangeLogListParam;
import com.anplus.hr.domain.params.EmployeeChangeLogParam;
import com.anplus.hr.domain.vo.EmployeeChangeLogVo;
import com.anplus.hr.mapper.EmployeeChangeLogMapper;
import com.anplus.hr.service.EmployeeChangeLogServ;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import top.binfast.app.biz.sysapi.bean.model.auth.SysDept;
import top.binfast.app.biz.sysapi.dao.auth.SysDeptMapper;
import top.binfast.common.core.util.MapstructUtils;
import top.binfast.common.mybatis.util.QueryUtil;
import java.time.LocalDate;
import java.util.List;
/**
* 员工异动记录Service业务层处理
*
* @author LiuBin
* @date 2025-11-17
*/
@RequiredArgsConstructor
@Service
public class EmployeeChangeLogServImpl extends ServiceImpl<EmployeeChangeLogMapper, EmployeeChangeLog> implements EmployeeChangeLogServ {
private final EmployeeChangeLogMapper employeeChangeLogMapper;
private final SysDeptMapper sysDeptMapper;
/**
* 分页查询员工异动记录列表
*
* @param param 查询条件
* @return 员工异动记录分页列表
*/
@Override
public PageResponse<EmployeeChangeLogVo> queryPageList(EmployeeChangeLogListParam param) {
Page<EmployeeChangeLog> page = QueryUtil.getPage(param);
LambdaQueryWrapper<EmployeeChangeLog> lambdaQuery = this.buildQueryWrapper(param);
employeeChangeLogMapper.selectPage(page, lambdaQuery);
return QueryUtil.getPageResponse(page, MapstructUtils.convert(page.getRecords(), EmployeeChangeLogVo.class));
}
/**
* 查询符合条件的员工异动记录列表
*
* @param param 查询条件
* @return 员工异动记录列表
*/
@Override
public List<EmployeeChangeLogVo> queryList(EmployeeChangeLogListParam param) {
LambdaQueryWrapper<EmployeeChangeLog> lambdaQuery = this.buildQueryWrapper(param);
return MapstructUtils.convert(employeeChangeLogMapper.selectList(lambdaQuery), EmployeeChangeLogVo.class);
}
private LambdaQueryWrapper<EmployeeChangeLog> buildQueryWrapper(EmployeeChangeLogListParam param) {
LambdaQueryWrapper<EmployeeChangeLog> lambdaQuery = Wrappers.<EmployeeChangeLog>lambdaQuery();
lambdaQuery.orderByDesc(EmployeeChangeLog::getId);
lambdaQuery.eq(StrUtil.isNotBlank(param.getType()), EmployeeChangeLog::getType, param.getType());
lambdaQuery.eq(param.getDeptId() != null, EmployeeChangeLog::getDeptId, param.getDeptId());
lambdaQuery.eq(param.getEmployeeId() != null, EmployeeChangeLog::getEmployeeId, param.getEmployeeId());
lambdaQuery.eq(param.getChangeDate() != null, EmployeeChangeLog::getChangeDate, param.getChangeDate());
lambdaQuery.eq(StrUtil.isNotBlank(param.getResignType()), EmployeeChangeLog::getResignType, param.getResignType());
lambdaQuery.eq(StrUtil.isNotBlank(param.getResignYearsOfServiceType()), EmployeeChangeLog::getResignYearsOfServiceType, param.getResignYearsOfServiceType());
return lambdaQuery;
}
/**
* 查询员工异动记录
*
* @param id 主键
* @return 员工异动记录
*/
@Override
public EmployeeChangeLogVo queryById(Long id) {
EmployeeChangeLog employeeChangeLog = employeeChangeLogMapper.selectById(id);
return MapstructUtils.convert(employeeChangeLog, EmployeeChangeLogVo.class);
}
@Override
public Boolean insertByEmployee(EmployeeInfo employeeInfo, String changeType, LocalDate changeDate) {
SysDept childDept = sysDeptMapper.selectById(employeeInfo.getDeptId());
List<String> split = StrUtil.splitTrim(childDept.getNodePath(), '/');
if (split.size() < 2) {
return true;
}
Long parentDeptId = split.stream().map(Convert::toLong).filter(t -> t > 0).findFirst().get();
SysDept parentDept = sysDeptMapper.selectById(parentDeptId);
EmployeeChangeLog changeLog = new EmployeeChangeLog();
changeLog.setEmployeeId(employeeInfo.getId());
changeLog.setDeptId(employeeInfo.getDeptId());
changeLog.setPlate(parentDept.getName());
changeLog.setType(changeType);
changeLog.setChangeDate(changeDate != null ? changeDate : LocalDate.now());
if (EmployeeChangeLogTypeConstant.Resign.equals(changeType)) {
changeLog.setResignType(HrResignationTypeConstant.FIRED.equals(employeeInfo.getResignationType()) ?
HrResignationTypeConstant.FIRED : HrResignationTypeConstant.HAND_IN_WORK);
HrResignYearsOfServiceTypeEnum hrResignYearsOfServiceTypeEnum;
if (HrResignationTypeConstant.PROBATION_NOT_PASSED.equals(employeeInfo.getResignationType())) {
hrResignYearsOfServiceTypeEnum = HrResignYearsOfServiceTypeEnum.PROBATION_PERIOD;
} else {
hrResignYearsOfServiceTypeEnum = HrResignYearsOfServiceTypeEnum.getByTotalMonths(employeeInfo.getYearsOfServiceMonths());
}
if (hrResignYearsOfServiceTypeEnum != null) {
changeLog.setResignYearsOfServiceType(hrResignYearsOfServiceTypeEnum.getCode());
}
}
return this.save(changeLog);
}
/**
* 新增员工异动记录
*
* @param param 员工异动记录
* @return 是否新增成功
*/
@Override
public Boolean insertByParam(EmployeeChangeLogParam param) {
EmployeeChangeLog employeeChangeLog = MapstructUtils.convert(param, EmployeeChangeLog.class);
return this.save(employeeChangeLog);
}
/**
* 修改员工异动记录
*
* @param param 员工异动记录
* @return 是否修改成功
*/
@Override
public Boolean updateByParam(EmployeeChangeLogParam param) {
EmployeeChangeLog employeeChangeLog = MapstructUtils.convert(param, EmployeeChangeLog.class);
return this.updateById(employeeChangeLog);
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(EmployeeChangeLog entity) {
// 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除员工异动记录信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
@Override
// @Transactional(rollbackFor = {Exception.class})
public Boolean delByIds(List<Long> ids) {
//做一些业务上的校验,判断是否需要校验
return this.removeByIds(ids);
}
}
package com.anplus.hr.service.impl;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.anplus.hr.config.SeniorityUtils;
import com.anplus.hr.constant.HrAgeGroupEnum;
import com.anplus.hr.constant.HrFlowEnum;
import com.anplus.hr.constant.HrYearsOfServiceSegmentEnum;
import com.anplus.hr.domain.EmployeeInfo;
import com.anplus.hr.mapper.EmployeeInfoMapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.ArrayList;
import java.util.List;
/**
......@@ -42,23 +45,42 @@ public class EmployeeScheduleService {
List<EmployeeInfo> employeeInfos = employeeInfoMapper.selectList(new LambdaUpdateWrapper<EmployeeInfo>()
.eq(EmployeeInfo::getEntryApplyStatus, HrFlowEnum.FINISH.getStatus())
.ne(EmployeeInfo::getResignationApplyStatus, HrFlowEnum.FINISH.getStatus()));
List<EmployeeInfo> updateList = new ArrayList<>();
for (EmployeeInfo employeeInfo : employeeInfos) {
Period period = LocalDateTimeUtil.betweenPeriod(employeeInfo.getEntryDate(), LocalDate.from(LocalDateTime.now()));
int years = period.getYears();
int months = period.getMonths();
employeeInfo.setYearsOfService(years > 0 ? years + "年" + months + "个月" : months + "个月");
// TODO 更新员工工龄组
precessRefreshAge(employeeInfo);
boolean isUpdate = false;
int newTotalMonths = SeniorityUtils.calculateTotalMonths(employeeInfo.getEntryDate());
if (employeeInfo.getYearsOfServiceMonths() != newTotalMonths) {
isUpdate = true;
employeeInfo.setYearsOfServiceMonths(newTotalMonths);
employeeInfo.setYearsOfService(SeniorityUtils.formatMonthsToSeniority(newTotalMonths));
// 更新员工工龄组
HrYearsOfServiceSegmentEnum yearsOfServiceSegmentEnum = HrYearsOfServiceSegmentEnum.getByTotalMonths(newTotalMonths);
if (yearsOfServiceSegmentEnum != null) {
employeeInfo.setYearsOfServiceSegment(yearsOfServiceSegmentEnum.getCode());
}
}
isUpdate = isUpdate || precessRefreshAge(employeeInfo);
if (isUpdate) {
updateList.add(employeeInfo);
}
}
employeeInfoMapper.updateById(updateList);
}
private void precessRefreshAge(EmployeeInfo employeeInfo) {
private boolean precessRefreshAge(EmployeeInfo employeeInfo) {
boolean isUpdate = false;
Period period = LocalDateTimeUtil.betweenPeriod(employeeInfo.getBirthDate(), LocalDate.from(LocalDateTime.now()));
if (employeeInfo.getAge() != period.getYears()) {
employeeInfo.setAge(period.getYears());
// TODO 更新员工年龄组
int years = period.getYears();
if (employeeInfo.getAge() != years) {
isUpdate = true;
employeeInfo.setAge(years);
// 更新员工年龄组
HrAgeGroupEnum ageGroupEnum = HrAgeGroupEnum.getByAge(years);
if (ageGroupEnum != null) {
employeeInfo.setAgeGroup(ageGroupEnum.getCode());
}
}
return isUpdate;
}
/**
......
......@@ -61,13 +61,16 @@ springdoc:
oss:
enable: true
endpoint: https://oss-cn-hangzhou.aliyuncs.com
endpoint: https://oss-cn-beijing.aliyuncs.com
domain: http://cdn.hr.antaikeji.top
# 也可以采用自定义域名
# endpoint: https://rjyefa9l9.hn-bkt.clouddn.com
access-key: AASFFFKKK
access-secret: PPSFSFAFJH8783JJK
bucket: binfast
region: cn-hangzhou
access-key: LTAI4Fq5tjMLps5529Vnp7Kz
access-secret: W1UAzbKf5Ufo6lrFVTe6hicKPoSBSG
bucket: an-plus-hr
region: cn-beijing
# 存储空间访问权限控制 0: 私有 1:公开 2:公共读
accessPolicy: 0
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
# https://sms4j.com/doc3/ 差异配置文档地址 支持单厂商多配置,可以配置多个同时使用
......
......@@ -61,13 +61,16 @@ springdoc:
oss:
enable: true
endpoint: https://oss-cn-hangzhou.aliyuncs.com
endpoint: https://oss-cn-beijing.aliyuncs.com
domain: http://cdn.hr.antaikeji.top
# 也可以采用自定义域名
# endpoint: https://rjyefa9l9.hn-bkt.clouddn.com
access-key: AASFFFKKK
access-secret: PPSFSFAFJH8783JJK
bucket: binfast
region: cn-hangzhou
access-key: LTAI4Fq5tjMLps5529Vnp7Kz
access-secret: W1UAzbKf5Ufo6lrFVTe6hicKPoSBSG
bucket: an-plus-hr
region: cn-beijing
# 存储空间访问权限控制 0: 私有 1:公开 2:公共读
accessPolicy: 0
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
# https://sms4j.com/doc3/ 差异配置文档地址 支持单厂商多配置,可以配置多个同时使用
......
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.anplus.hr.mapper.EmployeeChangeLogMapper">
</mapper>
......@@ -18,7 +18,7 @@
<mapstruct-plus.version>1.4.8</mapstruct-plus.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
<binfast.version>1.2.5</binfast.version>
<binfast.version>1.2.6</binfast.version>
<lombok.version>1.18.38</lombok.version>
</properties>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment