feat(system): 添加工资条管理功能
- 实现了工资条创建、更新、查询、导入、导出等功能 - 添加了工资条相关的数据结构和接口定义 - 实现了工资条数据的持久化和查询 - 添加了工资条导入导出的 Excel 处理逻辑
This commit is contained in:
parent
011e7d3510
commit
215fcc82a0
@ -0,0 +1,201 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
|
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip.*;
|
||||||
|
import cn.iocoder.yudao.module.system.service.hr.payslip.PayslipService;
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
|
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.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 工资条")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/hr/payslip")
|
||||||
|
public class PayslipController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PayslipService payslipService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FileApi fileApi;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建工资条")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:payslip:create')")
|
||||||
|
public CommonResult<Boolean> createPayslip(@Valid List<PayslipCreateReqVO> createReqVO) {
|
||||||
|
payslipService.createPayslip(createReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/issued")
|
||||||
|
@Operation(summary = "下发工资条")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:payslip:update')")
|
||||||
|
public CommonResult<Boolean> updatePayslip(@RequestBody PayslipPageReqVO updateReqVO) {
|
||||||
|
payslipService.issuedPayslip(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新工资条")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:payslip:update')")
|
||||||
|
public CommonResult<Boolean> updatePayslip(@RequestBody PayslipCreateReqVO updateReqVO) {
|
||||||
|
payslipService.updatePayslip(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得工资条")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:payslip:query')")
|
||||||
|
public CommonResult<PayslipRespVO> getPayslip(@RequestParam("id") Long id) {
|
||||||
|
|
||||||
|
return success(BeanUtils.toBean(payslipService.getPayslip(id), PayslipRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/Page")
|
||||||
|
@Operation(summary = "获得工资条分页")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:payslip:query')")
|
||||||
|
public CommonResult<PageResult<PayslipRespVO>> getPage(@RequestBody PayslipPageReqVO pageReqVO) {
|
||||||
|
|
||||||
|
PageResult<PayslipRespVO> pageResult = BeanUtils.toBean(payslipService.getPage(pageReqVO), PayslipRespVO.class);
|
||||||
|
pageResult.getList().forEach(data -> {
|
||||||
|
List<PayslipDetail> details = data.getDetails();
|
||||||
|
// 设置实发工资
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("salary")
|
||||||
|
.setName("实发工资")
|
||||||
|
.setValue(data.getSalary()));
|
||||||
|
|
||||||
|
// 设置开户行
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("bankName")
|
||||||
|
.setName("开户行")
|
||||||
|
.setValue(data.getBankName()));
|
||||||
|
|
||||||
|
// 设置银行卡号
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("bankNo")
|
||||||
|
.setName("卡号")
|
||||||
|
.setValue(data.getBankNo()));
|
||||||
|
|
||||||
|
// 设置备注
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("remark")
|
||||||
|
.setName("备注")
|
||||||
|
.setValue(data.getRemark()));
|
||||||
|
|
||||||
|
if (data.getIsConfirm() != null && data.getIsConfirm() == 1) {
|
||||||
|
data.setSignURL(fileApi.getUserSignImgPath(data.getUserId()).getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置签名
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("signURL")
|
||||||
|
.setName("签名")
|
||||||
|
.setValue(data.getSignURL()));
|
||||||
|
data.setDetails(details);
|
||||||
|
});
|
||||||
|
return success(pageResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/myPage")
|
||||||
|
@Operation(summary = "获得当前登录用户的工资条分页")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:payslip:query')")
|
||||||
|
public CommonResult<PageResult<PayslipRespVO>> getMyPage(@RequestBody PayslipPageReqVO pageReqVO) {
|
||||||
|
|
||||||
|
PageResult<PayslipRespVO> pageResult = BeanUtils.toBean(payslipService.getMyPage(pageReqVO), PayslipRespVO.class);
|
||||||
|
pageResult.getList().forEach(data -> {
|
||||||
|
List<PayslipDetail> details = data.getDetails();
|
||||||
|
// 设置实发工资
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("salary")
|
||||||
|
.setName("实发工资")
|
||||||
|
.setValue(data.getSalary()));
|
||||||
|
|
||||||
|
// 设置开户行
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("bankName")
|
||||||
|
.setName("开户行")
|
||||||
|
.setValue(data.getBankName()));
|
||||||
|
|
||||||
|
// 设置银行卡号
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("bankNo")
|
||||||
|
.setName("卡号")
|
||||||
|
.setValue(data.getBankNo()));
|
||||||
|
|
||||||
|
// 设置备注
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("remark")
|
||||||
|
.setName("备注")
|
||||||
|
.setValue(data.getRemark()));
|
||||||
|
|
||||||
|
if (data.getIsConfirm() == 1) {
|
||||||
|
data.setSignURL(fileApi.getUserSignImgPath(data.getUserId()).getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置签名
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("signURL")
|
||||||
|
.setName("签名")
|
||||||
|
.setValue(data.getSignURL()));
|
||||||
|
data.setDetails(details);
|
||||||
|
});
|
||||||
|
return success(pageResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/import")
|
||||||
|
@Operation(summary = "导入工资条")
|
||||||
|
@Parameters({
|
||||||
|
@Parameter(name = "file", description = "Excel 文件", required = true),
|
||||||
|
@Parameter(name = "date", description = "日期", required = true),
|
||||||
|
@Parameter(name = "deptId", description = "公司编号", required = true),
|
||||||
|
@Parameter(name = "isUpdate", description = "是否允许覆盖", required = true)
|
||||||
|
})
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:payslip:import')")
|
||||||
|
public CommonResult<Boolean> importExcel(@RequestParam("file") MultipartFile file,
|
||||||
|
@RequestParam("date") String date,
|
||||||
|
@RequestParam("deptId") Long deptId,
|
||||||
|
@RequestParam("isUpdate") Boolean isUpdate) throws Exception {
|
||||||
|
|
||||||
|
List<PayslipImportExcelVO> list = EasyExcel.read(file.getInputStream(), PayslipImportExcelVO.class, null)
|
||||||
|
.headRowNumber(3)
|
||||||
|
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
|
||||||
|
.doReadAllSync();
|
||||||
|
// 导入数据
|
||||||
|
payslipService.importPayslip(list, date, deptId, isUpdate);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export")
|
||||||
|
@Operation(summary = "导出工资条")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:user:export')")
|
||||||
|
@OperateLog(type = EXPORT)
|
||||||
|
public void exportList(@Validated PayslipPageReqVO exportReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
|
||||||
|
payslipService.exportList(response, exportReqVO);
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.system.controller.admin.hr;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeRespVO;
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeRespVO;
|
||||||
import cn.iocoder.yudao.module.system.service.hr.SalaryTypeService;
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeUpdateSortVO;
|
||||||
|
import cn.iocoder.yudao.module.system.service.hr.type.SalaryTypeService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@ -11,6 +13,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
@ -26,28 +29,35 @@ public class SalaryTypeController {
|
|||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建工资类型")
|
@Operation(summary = "创建工资类型")
|
||||||
@PreAuthorize("@ss.hasPermission('system:hr:salary-type:create')")
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type:create')")
|
||||||
public CommonResult<Long> createSalaryType(@RequestParam("name") String name) {
|
public CommonResult<Long> createSalaryType(@Valid @RequestBody SalaryTypeCreateReqVO createReqVO) {
|
||||||
return success(salaryTypeService.createSalaryType(name));
|
return success(salaryTypeService.createSalaryType(createReqVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/update")
|
@PutMapping("/update")
|
||||||
@Operation(summary = "更新工资类型")
|
@Operation(summary = "更新工资类型")
|
||||||
@PreAuthorize("@ss.hasPermission('system:hr:salary-type:update')")
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type:update')")
|
||||||
public CommonResult<Boolean> updateLogInstance(@RequestParam("id") Long id,
|
public CommonResult<Boolean> updateSalaryType(@Valid @RequestBody SalaryTypeCreateReqVO updateReqVO) {
|
||||||
@RequestParam("name") String name) {
|
salaryTypeService.updateSalaryType(updateReqVO);
|
||||||
salaryTypeService.updateSalaryType(id, name);
|
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/update-status")
|
@PutMapping("/update-status")
|
||||||
@Operation(summary = "更新工资类型状态")
|
@Operation(summary = "更新工资类型状态")
|
||||||
@PreAuthorize("@ss.hasPermission('system:hr:salary-type:update')")
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type:update-status')")
|
||||||
public CommonResult<Boolean> updateLogInstance(@RequestParam("id") Long id,
|
public CommonResult<Boolean> updateSalaryTypeStatus(@RequestParam("id") Long id,
|
||||||
@RequestParam("status") Integer status) {
|
@RequestParam("status") Integer status) {
|
||||||
salaryTypeService.updateSalaryTypeStatus(id, status);
|
salaryTypeService.updateSalaryTypeStatus(id, status);
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update-sort")
|
||||||
|
@Operation(summary = "更新工资类型排序")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type:update-status')")
|
||||||
|
public CommonResult<Boolean> updateSort(@RequestBody List<SalaryTypeUpdateSortVO> updateSortVO) {
|
||||||
|
salaryTypeService.updateSort(updateSortVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
@Operation(summary = "获得工资类型")
|
@Operation(summary = "获得工资类型")
|
||||||
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
package cn.iocoder.yudao.module.system.controller.admin.hr;
|
package cn.iocoder.yudao.module.system.controller.admin.hr;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeItemCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeItemCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.service.hr.SalaryTypeItemService;
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeItemRespVO;
|
||||||
|
import cn.iocoder.yudao.module.system.service.hr.type.SalaryTypeItemService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
@Tag(name = "管理后台 - 工资类型")
|
@Tag(name = "管理后台 - 工资类型配置")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/system/hr/salary-type-item")
|
@RequestMapping("/system/hr/salary-type-item")
|
||||||
public class SalaryTypeItemController {
|
public class SalaryTypeItemController {
|
||||||
@ -30,4 +31,39 @@ public class SalaryTypeItemController {
|
|||||||
public CommonResult<Long> createSalaryTypeItem(@Valid @RequestBody SalaryTypeItemCreateReqVO createReqVO) {
|
public CommonResult<Long> createSalaryTypeItem(@Valid @RequestBody SalaryTypeItemCreateReqVO createReqVO) {
|
||||||
return success(salaryTypeItemService.createSalaryTypeItem(createReqVO));
|
return success(salaryTypeItemService.createSalaryTypeItem(createReqVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新工资类型配置")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type-item:update')")
|
||||||
|
public CommonResult<Boolean> updateLogInstance(@Valid @RequestBody SalaryTypeItemCreateReqVO updateReqVO) {
|
||||||
|
salaryTypeItemService.updateSalaryTypeItem(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update-status")
|
||||||
|
@Operation(summary = "更新工资类型配置状态")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type-item:update-status')")
|
||||||
|
public CommonResult<Boolean> updateLogInstance(@RequestParam("id") Long id,
|
||||||
|
@RequestParam("status") Integer status) {
|
||||||
|
salaryTypeItemService.updateSalaryTypeItemStatus(id, status);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得工资类型配置")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type-item:query')")
|
||||||
|
public CommonResult<SalaryTypeItemRespVO> getSalaryType(@RequestParam("id") Long id) {
|
||||||
|
|
||||||
|
return success(BeanUtils.toBean(salaryTypeItemService.getSalaryTypeItem(id), SalaryTypeItemRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/listByTypeId")
|
||||||
|
@Operation(summary = "获得工资类型配置列表")
|
||||||
|
@Parameter(name = "typeId", description = "类型编号", required = true, example = "1")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:hr:salary-type-item:query')")
|
||||||
|
public CommonResult<List<SalaryTypeItemRespVO>> getSalaryTypeList(@RequestParam("typeId") Long typeId) {
|
||||||
|
|
||||||
|
return success(BeanUtils.toBean(salaryTypeItemService.getListByTypeId(typeId), SalaryTypeItemRespVO.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 工资条创建 Request VO")
|
||||||
|
@Data
|
||||||
|
public class PayslipCreateReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", example = "1")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "部门编号不能为空")
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
|
@Schema(description = "所属公司编号")
|
||||||
|
private Long companyDeptId;
|
||||||
|
|
||||||
|
@Schema(description = "银行开户名")
|
||||||
|
private String bankName;
|
||||||
|
|
||||||
|
@Schema(description = "银行账号")
|
||||||
|
private String bankNo;
|
||||||
|
|
||||||
|
@Schema(description = "工资日期")
|
||||||
|
private String salaryDate;
|
||||||
|
|
||||||
|
@Schema(description = "实发工资")
|
||||||
|
private BigDecimal salary;
|
||||||
|
|
||||||
|
@Schema(description = "工资条详情")
|
||||||
|
private List<PayslipDetail> details;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "是否确认工资单 | 0否 1是", example = "0")
|
||||||
|
private Integer isConfirm;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 工资条详情 Response VO")
|
||||||
|
@Data
|
||||||
|
public class PayslipDetail {
|
||||||
|
|
||||||
|
@Schema(description = "编码")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
@Schema(description = "名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "值")
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子数据
|
||||||
|
*/
|
||||||
|
private List<PayslipDetail> children;
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.validation.IdCard;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工资条 Excel 导入 VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题
|
||||||
|
public class PayslipImportExcelVO {
|
||||||
|
|
||||||
|
@ExcelProperty("姓名")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
@ExcelProperty("身份证号码")
|
||||||
|
@IdCard
|
||||||
|
private String idcard;
|
||||||
|
|
||||||
|
@ExcelProperty("基本工资")
|
||||||
|
private BigDecimal jbgz;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "防暑降温费")
|
||||||
|
private BigDecimal fsjwf;
|
||||||
|
|
||||||
|
@ExcelProperty("误餐补助")
|
||||||
|
private BigDecimal wcbz;
|
||||||
|
|
||||||
|
@ExcelProperty("福利费")
|
||||||
|
private BigDecimal flf;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "合计", index = 7)
|
||||||
|
private BigDecimal sum;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "试用期工资", index = 8)
|
||||||
|
private BigDecimal syqgz;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "应发工资", index = 9)
|
||||||
|
private BigDecimal yfgz;
|
||||||
|
|
||||||
|
@ExcelProperty("养老")
|
||||||
|
private BigDecimal ylbx;
|
||||||
|
|
||||||
|
@ExcelProperty("失业")
|
||||||
|
private BigDecimal sybx;
|
||||||
|
|
||||||
|
@ExcelProperty("医保")
|
||||||
|
private BigDecimal yb;
|
||||||
|
|
||||||
|
@ExcelProperty("大额医疗")
|
||||||
|
private BigDecimal deyl;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "代缴合计", index = 14)
|
||||||
|
private BigDecimal djSum;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "公积金", index = 15)
|
||||||
|
private BigDecimal gjj;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "个税", index = 16)
|
||||||
|
private BigDecimal gs;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "实发工资", index = 17)
|
||||||
|
private BigDecimal salary;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "开户行", index = 18)
|
||||||
|
private String bankName;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "银行卡号", index = 19)
|
||||||
|
private String bankNo;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "备注", index = 20)
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "签名", index = 21)
|
||||||
|
private String isConfirm;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 工资条分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class PayslipPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "用户账号,模糊匹配", example = "yudao")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "公司部门编号,同时筛选子部门", example = "1024")
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
|
@Schema(description = "薪资日期 | yyyy-MM", example = "2024-10")
|
||||||
|
private String date;
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 工资条 Response VO")
|
||||||
|
@Data
|
||||||
|
public class PayslipRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", example = "1")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "用户编号", example = "1")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名称", example = "芋道")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
@Schema(description = "部门编号", example = "1")
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
|
@Schema(description = "部门名称", example = "芋道源码")
|
||||||
|
private String deptName;
|
||||||
|
|
||||||
|
@Schema(description = "所属公司编号")
|
||||||
|
private Long companyDeptId;
|
||||||
|
|
||||||
|
@Schema(description = "银行开户名")
|
||||||
|
private String bankName;
|
||||||
|
|
||||||
|
@Schema(description = "银行账号")
|
||||||
|
private String bankNo;
|
||||||
|
|
||||||
|
@Schema(description = "工资日期")
|
||||||
|
private String salaryDate;
|
||||||
|
|
||||||
|
@Schema(description = "实发工资")
|
||||||
|
private BigDecimal salary;
|
||||||
|
|
||||||
|
@Schema(description = "工资条详情")
|
||||||
|
private List<PayslipDetail> details;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "是否确认工资单 | 0否 1是", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
private Integer isConfirm;
|
||||||
|
|
||||||
|
@Schema(description = "电子签名")
|
||||||
|
private String signURL;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr.vo.type;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 工资类型 Request VO")
|
||||||
|
@Data
|
||||||
|
public class SalaryTypeCreateReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", example = "1")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "类型名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "类型 | 0应发工资项 1代扣代缴项", example = "1")
|
||||||
|
private Integer type;
|
||||||
|
}
|
@ -9,6 +9,9 @@ import javax.validation.constraints.NotNull;
|
|||||||
@Data
|
@Data
|
||||||
public class SalaryTypeItemCreateReqVO {
|
public class SalaryTypeItemCreateReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", example = "1")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
@NotNull(message = "类型编号不能为空")
|
@NotNull(message = "类型编号不能为空")
|
||||||
private Long typeId;
|
private Long typeId;
|
||||||
@ -22,9 +25,8 @@ public class SalaryTypeItemCreateReqVO {
|
|||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(description = "描述", example = "1")
|
@Schema(description = "描述", example = "1")
|
||||||
private String describe;
|
private String itemDescribe;
|
||||||
|
|
||||||
@Schema(description = "加减属性 | 1加 2减", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "加减属性 | 1加 2减", example = "1")
|
||||||
@NotNull(message = "加减属性不能为空")
|
|
||||||
private Integer attributes;
|
private Integer attributes;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public class SalaryTypeItemRespVO {
|
|||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(description = "描述")
|
@Schema(description = "描述")
|
||||||
private String describe;
|
private String itemDescribe;
|
||||||
|
|
||||||
@Schema(description = "加减属性 | 1加 2减")
|
@Schema(description = "加减属性 | 1加 2减")
|
||||||
private Integer attributes;
|
private Integer attributes;
|
||||||
|
@ -13,6 +13,12 @@ public class SalaryTypeRespVO {
|
|||||||
@Schema(description = "类型名称")
|
@Schema(description = "类型名称")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "类型 | 0应发工资项 1代扣代缴项", example = "1")
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
@Schema(description = "显示顺序", example = "1")
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
@Schema(description = "状态 | 0开启 1关闭")
|
@Schema(description = "状态 | 0开启 1关闭")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.hr.vo.type;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 工资类型 Request VO")
|
||||||
|
@Data
|
||||||
|
public class SalaryTypeUpdateSortVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", example = "1")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "顺序", example = "1")
|
||||||
|
private String sort;
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.dal.dataobject.hr;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip.PayslipDetail;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@TableName(value = "hr_payslip", autoResultMap = true)
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class PayslipDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID,自增
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门编号
|
||||||
|
*/
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属公司编号
|
||||||
|
*/
|
||||||
|
private Long companyDeptId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 薪资日期 YYYY-MM
|
||||||
|
*/
|
||||||
|
private String salaryDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实发工资
|
||||||
|
*/
|
||||||
|
private BigDecimal salary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开户行
|
||||||
|
*/
|
||||||
|
private String bankName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 银行卡号
|
||||||
|
*/
|
||||||
|
private String bankNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
|
private List<PayslipDetail> details;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否确认
|
||||||
|
*/
|
||||||
|
private Integer isConfirm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名称
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户部门名称
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String deptName;
|
||||||
|
}
|
@ -24,6 +24,16 @@ public class SalaryTypeDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型 | 0应发工资项 1代扣代缴项
|
||||||
|
*/
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示顺序
|
||||||
|
*/
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态 | 0开启 1关闭
|
* 状态 | 0开启 1关闭
|
||||||
*/
|
*/
|
||||||
|
@ -37,7 +37,7 @@ public class SalaryTypeItemDO extends BaseDO {
|
|||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
private String describe;
|
private String itemDescribe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加减属性 | 1加 2减
|
* 加减属性 | 1加 2减
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.dal.mysql.hr;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip.PayslipPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.hr.PayslipDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PayslipMapper extends BaseMapperX<PayslipDO> {
|
||||||
|
|
||||||
|
default PageResult<PayslipDO> selectPage(PayslipPageReqVO pageReqVO) {
|
||||||
|
|
||||||
|
MPJLambdaWrapperX<PayslipDO> wrapper = new MPJLambdaWrapperX<PayslipDO>()
|
||||||
|
.selectAll(PayslipDO.class)
|
||||||
|
.selectAs(AdminUserDO::getNickname, PayslipDO::getUserName)
|
||||||
|
.selectAs(DeptDO::getName, PayslipDO::getDeptName);
|
||||||
|
wrapper.innerJoin(AdminUserDO.class, on -> on
|
||||||
|
.eq(AdminUserDO::getId, PayslipDO::getUserId)
|
||||||
|
.like(Objects.nonNull(pageReqVO.getName()), AdminUserDO::getNickname, pageReqVO.getName()));
|
||||||
|
wrapper.innerJoin(DeptDO.class, DeptDO::getId, PayslipDO::getDeptId);
|
||||||
|
wrapper.eq(PayslipDO::getSalaryDate, pageReqVO.getDate());
|
||||||
|
wrapper.eqIfPresent(PayslipDO::getCompanyDeptId, pageReqVO.getDeptId());
|
||||||
|
|
||||||
|
return selectJoinPage(pageReqVO, PayslipDO.class, wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
default PageResult<PayslipDO> selectMyPage(PayslipPageReqVO pageReqVO, Long loginUserId) {
|
||||||
|
|
||||||
|
MPJLambdaWrapperX<PayslipDO> wrapper = new MPJLambdaWrapperX<PayslipDO>()
|
||||||
|
.selectAll(PayslipDO.class)
|
||||||
|
.selectAs(AdminUserDO::getNickname, PayslipDO::getUserName)
|
||||||
|
.selectAs(DeptDO::getName, PayslipDO::getDeptName);
|
||||||
|
wrapper.innerJoin(AdminUserDO.class, AdminUserDO::getId, PayslipDO::getUserId);
|
||||||
|
wrapper.innerJoin(DeptDO.class, DeptDO::getId, PayslipDO::getDeptId);
|
||||||
|
wrapper.eqIfPresent(PayslipDO::getSalaryDate, pageReqVO.getDate());
|
||||||
|
wrapper.eq(PayslipDO::getUserId, loginUserId);
|
||||||
|
wrapper.isNotNull(PayslipDO::getIsConfirm);
|
||||||
|
|
||||||
|
return selectJoinPage(pageReqVO, PayslipDO.class, wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deletePayslip(@Param("date") String date, @Param("deptId") Long deptId);
|
||||||
|
}
|
@ -1,18 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.hr;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeItemCreateReqVO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工资类型配置 Service 接口
|
|
||||||
*
|
|
||||||
* @author 符溶馨
|
|
||||||
*/
|
|
||||||
public interface SalaryTypeItemService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建工资类型配置
|
|
||||||
* @param createReqVO 创建信息
|
|
||||||
* @return 工资类型配置编号
|
|
||||||
*/
|
|
||||||
Long createSalaryTypeItem(SalaryTypeItemCreateReqVO createReqVO);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.hr;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeItemCreateReqVO;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class SalaryTypeItemServiceImpl implements SalaryTypeItemService{
|
|
||||||
@Override
|
|
||||||
public Long createSalaryTypeItem(SalaryTypeItemCreateReqVO createReqVO) {
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.hr;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.hr.SalaryTypeDO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.hr.SalaryTypeMapper;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class SalaryTypeServiceImpl implements SalaryTypeService{
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SalaryTypeMapper salaryTypeMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long createSalaryType(String name) {
|
|
||||||
|
|
||||||
// 校验类型名称唯一性
|
|
||||||
if (salaryTypeMapper.selectCount(SalaryTypeDO::getName, name) > 0L) {
|
|
||||||
throw exception(SALARY_TYPE_NAME_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
SalaryTypeDO salaryTypeDO = new SalaryTypeDO()
|
|
||||||
.setName(name)
|
|
||||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
|
||||||
|
|
||||||
salaryTypeMapper.insert(salaryTypeDO);
|
|
||||||
return salaryTypeDO.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateSalaryType(Long id, String name) {
|
|
||||||
|
|
||||||
validateTypeExists(id);
|
|
||||||
|
|
||||||
SalaryTypeDO salaryTypeDO = new SalaryTypeDO()
|
|
||||||
.setId(id)
|
|
||||||
.setName(name);
|
|
||||||
|
|
||||||
salaryTypeMapper.updateById(salaryTypeDO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateSalaryTypeStatus(Long id, Integer status) {
|
|
||||||
|
|
||||||
validateTypeExists(id);
|
|
||||||
|
|
||||||
SalaryTypeDO salaryTypeDO = new SalaryTypeDO()
|
|
||||||
.setId(id)
|
|
||||||
.setStatus(status);
|
|
||||||
|
|
||||||
// 同步设置 类型配置状态
|
|
||||||
|
|
||||||
salaryTypeMapper.updateById(salaryTypeDO);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateTypeExists(Long id) {
|
|
||||||
if (salaryTypeMapper.selectById(id) == null) {
|
|
||||||
throw exception(SALARY_TYPE_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SalaryTypeDO getSalaryType(Long id) {
|
|
||||||
return salaryTypeMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SalaryTypeDO> getSalaryTypeList() {
|
|
||||||
return salaryTypeMapper.selectList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,70 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.service.hr.payslip;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip.PayslipCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip.PayslipImportExcelVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip.PayslipPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.hr.PayslipDO;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工资条 Service 接口
|
||||||
|
*
|
||||||
|
* @author 符溶馨
|
||||||
|
*/
|
||||||
|
public interface PayslipService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量创建工资条
|
||||||
|
* @param createReqVO 创建工资条请求
|
||||||
|
*/
|
||||||
|
void createPayslip(List<PayslipCreateReqVO> createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工资条
|
||||||
|
* @param updateReqVO 更新工资条请求
|
||||||
|
*/
|
||||||
|
void updatePayslip(PayslipCreateReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取工资条详情
|
||||||
|
* @param id 工资条编号
|
||||||
|
* @return 工资条详情
|
||||||
|
*/
|
||||||
|
PayslipDO getPayslip(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得工资条分页
|
||||||
|
* @param pageReqVO 分页信息
|
||||||
|
* @return 工资条分页详情
|
||||||
|
*/
|
||||||
|
PageResult<PayslipDO> getPage(PayslipPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录用户的工资条分页
|
||||||
|
* @param pageReqVO 分页信息
|
||||||
|
* @return 工资条分页详情
|
||||||
|
*/
|
||||||
|
PageResult<PayslipDO> getMyPage(PayslipPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入工资条
|
||||||
|
* @param list 导入工资条数据
|
||||||
|
*/
|
||||||
|
void importPayslip(List<PayslipImportExcelVO> list, String date, Long deptId, Boolean isUpdate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下发工资条
|
||||||
|
* @param updateReqVO 下发条件
|
||||||
|
*/
|
||||||
|
void issuedPayslip(PayslipPageReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工资条导出
|
||||||
|
* @param response 响应
|
||||||
|
* @param exportReqVO 工资条列表
|
||||||
|
*/
|
||||||
|
void exportList(HttpServletResponse response, PayslipPageReqVO exportReqVO);
|
||||||
|
}
|
@ -0,0 +1,361 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.service.hr.payslip;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.payslip.*;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.hr.PayslipDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.mysql.hr.PayslipMapper;
|
||||||
|
import cn.iocoder.yudao.module.system.service.attendance.CustomCellStyleHandler;
|
||||||
|
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||||
|
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
|
import com.alibaba.excel.support.ExcelTypeEnum;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||||
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工资条 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 符溶馨
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PayslipServiceImpl implements PayslipService{
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PayslipMapper payslipMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private DeptService deptService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AdminUserService userService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createPayslip(List<PayslipCreateReqVO> createReqVO) {
|
||||||
|
|
||||||
|
List<PayslipDO> payslipDOList = BeanUtils.toBean(createReqVO, PayslipDO.class);
|
||||||
|
payslipMapper.insertBatch(payslipDOList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePayslip(PayslipCreateReqVO updateReqVO) {
|
||||||
|
|
||||||
|
validateIdExists(updateReqVO.getId());
|
||||||
|
|
||||||
|
PayslipDO updateObj = BeanUtils.toBean(updateReqVO, PayslipDO.class);
|
||||||
|
payslipMapper.updateById(updateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PayslipDO getPayslip(Long id) {
|
||||||
|
|
||||||
|
return payslipMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<PayslipDO> getPage(PayslipPageReqVO pageReqVO) {
|
||||||
|
|
||||||
|
return payslipMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<PayslipDO> getMyPage(PayslipPageReqVO pageReqVO) {
|
||||||
|
|
||||||
|
return payslipMapper.selectMyPage(pageReqVO, getLoginUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
||||||
|
public void importPayslip(List<PayslipImportExcelVO> importList, String date, Long deptId, Boolean isUpdate) {
|
||||||
|
|
||||||
|
if (CollUtil.isEmpty(importList)) {
|
||||||
|
throw exception(PAYSLIP_IMPORT_LIST_IS_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断如果选择覆盖, 则删除原有数据重新插入
|
||||||
|
if (isUpdate) {
|
||||||
|
payslipMapper.deletePayslip(date, deptId);
|
||||||
|
}else {
|
||||||
|
Long count = payslipMapper.selectCount(new LambdaQueryWrapperX<PayslipDO>()
|
||||||
|
.eq(PayslipDO::getSalaryDate, date)
|
||||||
|
.eqIfPresent(PayslipDO::getCompanyDeptId, deptId));
|
||||||
|
|
||||||
|
if (count > 0L) {
|
||||||
|
throw exception(PAYSLIP_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> idCards = convertList(importList, PayslipImportExcelVO::getIdcard);
|
||||||
|
Map<String, AdminUserDO> userMap = convertMap(userService.getUserListByIdCard(idCards), AdminUserDO::getIdcard);
|
||||||
|
|
||||||
|
List<PayslipDO> payslipDOList = new ArrayList<>();
|
||||||
|
importList.forEach(data -> {
|
||||||
|
|
||||||
|
PayslipDO payslipDO = new PayslipDO();
|
||||||
|
try {
|
||||||
|
payslipDO.setUserId(userMap.get(data.getIdcard()).getId());
|
||||||
|
payslipDO.setDeptId(userMap.get(data.getIdcard()).getDeptId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw exception(PAYSLIP_ID_CARD_ERROR, data.getNickname());
|
||||||
|
}
|
||||||
|
payslipDO.setCompanyDeptId(deptId);
|
||||||
|
payslipDO.setSalary(data.getSalary());
|
||||||
|
payslipDO.setSalaryDate(date);
|
||||||
|
payslipDO.setBankName(data.getBankName());
|
||||||
|
payslipDO.setBankNo(data.getBankNo());
|
||||||
|
payslipDO.setRemark(data.getRemark());
|
||||||
|
|
||||||
|
/* begin 设置明细数据 */
|
||||||
|
List<PayslipDetail> details = new ArrayList<>();
|
||||||
|
PayslipDetail detail = new PayslipDetail();
|
||||||
|
// 设置类型名称
|
||||||
|
detail.setName("月总收入");
|
||||||
|
// 设置明细数据
|
||||||
|
List<PayslipDetail> detailList = new ArrayList<>();
|
||||||
|
// 基本工资
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("jbgz")
|
||||||
|
.setName("基本工资")
|
||||||
|
.setValue(data.getJbgz()));
|
||||||
|
// 防暑降温费
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("fsjwf")
|
||||||
|
.setName("防暑降温费")
|
||||||
|
.setValue(data.getFsjwf()));
|
||||||
|
// 误餐补助
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("wcbz")
|
||||||
|
.setName("防暑降温费")
|
||||||
|
.setValue(data.getWcbz()));
|
||||||
|
// 福利费
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("flf")
|
||||||
|
.setName("福利费")
|
||||||
|
.setValue(data.getFlf()));
|
||||||
|
|
||||||
|
// 设置大类数据
|
||||||
|
detail.setChildren(detailList);
|
||||||
|
details.add(detail);
|
||||||
|
|
||||||
|
// 设置合计数据
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("sum")
|
||||||
|
.setName("合计")
|
||||||
|
.setValue(data.getSum()));
|
||||||
|
|
||||||
|
// 设置试用期工资数据
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("syqgz")
|
||||||
|
.setName("试用期工资")
|
||||||
|
.setValue(data.getSyqgz()));
|
||||||
|
|
||||||
|
// 设置试用期工资数据
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("yfgz")
|
||||||
|
.setName("应发工资")
|
||||||
|
.setValue(data.getYfgz()));
|
||||||
|
|
||||||
|
// 设置代扣代缴项数据
|
||||||
|
detailList = new ArrayList<>();
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("ylbx")
|
||||||
|
.setName("养老")
|
||||||
|
.setValue(data.getYlbx()));
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("sybx")
|
||||||
|
.setName("失业")
|
||||||
|
.setValue(data.getSybx()));
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("yb")
|
||||||
|
.setName("医保")
|
||||||
|
.setValue(data.getYb()));
|
||||||
|
detailList.add(new PayslipDetail()
|
||||||
|
.setCode("deyl")
|
||||||
|
.setName("大额医疗")
|
||||||
|
.setValue(data.getDeyl()));
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setName("代扣代缴项")
|
||||||
|
.setChildren(detailList));
|
||||||
|
|
||||||
|
// 设置代缴合计数据
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("djSum")
|
||||||
|
.setName("代缴合计")
|
||||||
|
.setValue(data.getDjSum()));
|
||||||
|
|
||||||
|
// 设置公积金数据
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("gjj")
|
||||||
|
.setName("公积金")
|
||||||
|
.setValue(data.getGjj()));
|
||||||
|
|
||||||
|
// 设置个税数据
|
||||||
|
details.add(new PayslipDetail()
|
||||||
|
.setCode("gs")
|
||||||
|
.setName("个税")
|
||||||
|
.setValue(data.getGs()));
|
||||||
|
/* end */
|
||||||
|
payslipDO.setDetails(details);
|
||||||
|
|
||||||
|
payslipDOList.add(payslipDO);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 批量插入
|
||||||
|
payslipMapper.insertBatch(payslipDOList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void issuedPayslip(PayslipPageReqVO updateReqVO) {
|
||||||
|
|
||||||
|
List<Long> deptIds = convertList(deptService.getChildDept(updateReqVO.getDeptId()), DeptDO::getId);
|
||||||
|
|
||||||
|
// 更新工资条状态 为待确认中
|
||||||
|
payslipMapper.update(new PayslipDO().setIsConfirm(0), new LambdaQueryWrapperX<PayslipDO>()
|
||||||
|
.eq(PayslipDO::getSalaryDate, updateReqVO.getDate())
|
||||||
|
.inIfPresent(PayslipDO::getDeptId, deptIds)
|
||||||
|
.isNull(PayslipDO::getIsConfirm));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exportList(HttpServletResponse response, PayslipPageReqVO exportReqVO) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// 获取工资条列表
|
||||||
|
List<PayslipRespVO> list = new ArrayList<>();
|
||||||
|
if (exportReqVO.getDeptId() != null) {
|
||||||
|
list = BeanUtils.toBean(getPage(exportReqVO).getList(), PayslipRespVO.class);
|
||||||
|
}else {
|
||||||
|
list = BeanUtils.toBean(getMyPage(exportReqVO).getList(), PayslipRespVO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollUtil.isEmpty(list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户详情
|
||||||
|
List<Long> userIds = convertList(list, PayslipRespVO::getUserId);
|
||||||
|
Map<Long, AdminUserDO> userMap = convertMap(userService.getUserList(userIds), AdminUserDO::getId);
|
||||||
|
|
||||||
|
List<List<String>> data = new ArrayList<>();
|
||||||
|
int count = 1;
|
||||||
|
for (PayslipRespVO payslipRespVO : list) {
|
||||||
|
|
||||||
|
List<String> row = new ArrayList<>();
|
||||||
|
row.add(String.valueOf(count++));
|
||||||
|
row.add(payslipRespVO.getUserName());
|
||||||
|
row.add(userMap.get(payslipRespVO.getUserId()).getIdcard());
|
||||||
|
|
||||||
|
Map<String, Object> detailMap = payslipRespVO.getDetails().stream()
|
||||||
|
.map(item -> {
|
||||||
|
List<PayslipDetail> children = new ArrayList<>();
|
||||||
|
if (item.getChildren() != null) {
|
||||||
|
children.addAll(item.getChildren());
|
||||||
|
}else {
|
||||||
|
children.add(item);
|
||||||
|
}
|
||||||
|
return children.stream().collect(Collectors.toMap(PayslipDetail::getCode, PayslipDetail::getValue));
|
||||||
|
})
|
||||||
|
.flatMap(map -> map.entrySet().stream()) // 将每个 Map 转换为 Entry 流
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
Map.Entry::getKey, // 使用 Entry 的 key
|
||||||
|
Map.Entry::getValue, // 使用 Entry 的 value
|
||||||
|
(existing, replacement) -> existing // 处理键冲突,保留现有值
|
||||||
|
));;
|
||||||
|
|
||||||
|
row.add(detailMap.get("jbgz").toString());
|
||||||
|
row.add(detailMap.get("fsjwf").toString());
|
||||||
|
row.add(detailMap.get("wcbz").toString());
|
||||||
|
row.add(detailMap.get("flf").toString());
|
||||||
|
row.add(detailMap.get("sum").toString());
|
||||||
|
row.add(detailMap.get("syqgz").toString());
|
||||||
|
row.add(detailMap.get("yfgz").toString());
|
||||||
|
row.add(detailMap.get("ylbx").toString());
|
||||||
|
row.add(detailMap.get("sybx").toString());
|
||||||
|
row.add(detailMap.get("yb").toString());
|
||||||
|
row.add(detailMap.get("deyl").toString());
|
||||||
|
row.add(detailMap.get("djSum").toString());
|
||||||
|
row.add(detailMap.get("gjj").toString());
|
||||||
|
row.add(detailMap.get("gs").toString());
|
||||||
|
row.add(payslipRespVO.getSalary().toString());
|
||||||
|
row.add(payslipRespVO.getBankName());
|
||||||
|
row.add(payslipRespVO.getBankNo());
|
||||||
|
row.add(payslipRespVO.getRemark());
|
||||||
|
row.add(payslipRespVO.getSignURL());
|
||||||
|
|
||||||
|
data.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取公司信息
|
||||||
|
DeptDO deptDO = deptService.getDept(exportReqVO.getDeptId());
|
||||||
|
|
||||||
|
String headTitle = deptDO.getName() + exportReqVO.getDate() + "工资条";
|
||||||
|
EasyExcel.write(response.getOutputStream())
|
||||||
|
.head(getHead(headTitle, list.get(0)))
|
||||||
|
.autoCloseStream(false)
|
||||||
|
.excelType(ExcelTypeEnum.XLS)
|
||||||
|
.registerWriteHandler(new CustomCellStyleHandler())
|
||||||
|
.sheet("工资条")
|
||||||
|
.doWrite(data);
|
||||||
|
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("工资条", StandardCharsets.UTF_8.name()));
|
||||||
|
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<String>> getHead(String headTitle, PayslipRespVO payslipRespVO) {
|
||||||
|
|
||||||
|
List<List<String>> head = new ArrayList<>();
|
||||||
|
head.add(Arrays.asList(headTitle, "序号", "序号"));
|
||||||
|
head.add(Arrays.asList(headTitle, "姓名", "姓名"));
|
||||||
|
head.add(Arrays.asList(headTitle, "身份证号码", "身份证号码"));
|
||||||
|
for (PayslipDetail detail : payslipRespVO.getDetails()) {
|
||||||
|
|
||||||
|
if (detail.getChildren() == null) {
|
||||||
|
head.add(Arrays.asList(headTitle, detail.getName(), detail.getName()));
|
||||||
|
}else {
|
||||||
|
|
||||||
|
for (PayslipDetail child : detail.getChildren()) {
|
||||||
|
|
||||||
|
head.add(Arrays.asList(headTitle, detail.getName(), child.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
head.add(Arrays.asList(headTitle, "实发工资", "实发工资"));
|
||||||
|
head.add(Arrays.asList(headTitle, "开户行", "开户行"));
|
||||||
|
head.add(Arrays.asList(headTitle, "卡号", "卡号"));
|
||||||
|
head.add(Arrays.asList(headTitle, "备注", "备注"));
|
||||||
|
head.add(Arrays.asList(headTitle, "签名", "签名"));
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateIdExists(Long id) {
|
||||||
|
if (payslipMapper.selectById(id) == null) {
|
||||||
|
throw exception(PAYSLIP_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.service.hr.type;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeItemCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.hr.SalaryTypeItemDO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工资类型配置 Service 接口
|
||||||
|
*
|
||||||
|
* @author 符溶馨
|
||||||
|
*/
|
||||||
|
public interface SalaryTypeItemService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建工资类型配置
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 工资类型配置编号
|
||||||
|
*/
|
||||||
|
Long createSalaryTypeItem(SalaryTypeItemCreateReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工资类型配置
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateSalaryTypeItem(SalaryTypeItemCreateReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工资类型配置状态
|
||||||
|
* @param id 工资类型配置编号
|
||||||
|
* @param status 状态值
|
||||||
|
*/
|
||||||
|
void updateSalaryTypeItemStatus(Long id, Integer status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工资类型配置状态
|
||||||
|
* @param typeId 工资类型编号
|
||||||
|
* @param status 状态值
|
||||||
|
*/
|
||||||
|
void updateStatusByTypeId(Long typeId, Integer status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得工资类型配置
|
||||||
|
* @param id 工资类型配置编号
|
||||||
|
* @return 工资类型配置
|
||||||
|
*/
|
||||||
|
SalaryTypeItemDO getSalaryTypeItem(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得指定的工资类型配置
|
||||||
|
* @return 工资类型配置列表
|
||||||
|
*/
|
||||||
|
List<SalaryTypeItemDO> getListByTypeId(Long typeId);
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.service.hr.type;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeItemCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.hr.SalaryTypeItemDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.mysql.hr.SalaryTypeItemMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SalaryTypeItemServiceImpl implements SalaryTypeItemService{
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SalaryTypeItemMapper salaryTypeItemMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createSalaryTypeItem(SalaryTypeItemCreateReqVO createReqVO) {
|
||||||
|
|
||||||
|
// 校验code的唯一性
|
||||||
|
validateTypeCodeExists(null, createReqVO.getCode());
|
||||||
|
|
||||||
|
SalaryTypeItemDO itemDO = BeanUtils.toBean(createReqVO, SalaryTypeItemDO.class);
|
||||||
|
itemDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
|
||||||
|
// 插入
|
||||||
|
salaryTypeItemMapper.insert(itemDO);
|
||||||
|
return itemDO.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSalaryTypeItem(SalaryTypeItemCreateReqVO updateReqVO) {
|
||||||
|
|
||||||
|
validateTypeItemExists(updateReqVO.getId());
|
||||||
|
// 校验code的唯一性
|
||||||
|
validateTypeCodeExists(updateReqVO.getId(), updateReqVO.getCode());
|
||||||
|
|
||||||
|
SalaryTypeItemDO updateObj = BeanUtils.toBean(updateReqVO, SalaryTypeItemDO.class);
|
||||||
|
salaryTypeItemMapper.updateById(updateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSalaryTypeItemStatus(Long id, Integer status) {
|
||||||
|
|
||||||
|
validateTypeItemExists(id);
|
||||||
|
|
||||||
|
SalaryTypeItemDO itemDO = new SalaryTypeItemDO()
|
||||||
|
.setId(id)
|
||||||
|
.setStatus(status);
|
||||||
|
|
||||||
|
salaryTypeItemMapper.updateById(itemDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStatusByTypeId(Long typeId, Integer status) {
|
||||||
|
|
||||||
|
salaryTypeItemMapper.update(new SalaryTypeItemDO().setStatus(status), new LambdaQueryWrapperX<SalaryTypeItemDO>()
|
||||||
|
.eq(SalaryTypeItemDO::getTypeId, typeId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SalaryTypeItemDO getSalaryTypeItem(Long id) {
|
||||||
|
|
||||||
|
return salaryTypeItemMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SalaryTypeItemDO> getListByTypeId(Long typeId) {
|
||||||
|
|
||||||
|
return salaryTypeItemMapper.selectList(SalaryTypeItemDO::getTypeId, typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTypeItemExists(Long id) {
|
||||||
|
if (salaryTypeItemMapper.selectById(id) == null) {
|
||||||
|
throw exception(SALARY_TYPE_ITEM_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTypeCodeExists(Long id, String code) {
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(code)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验类型名称唯一性
|
||||||
|
SalaryTypeItemDO itemDO = salaryTypeItemMapper.selectOne(SalaryTypeItemDO::getCode, code);
|
||||||
|
if (itemDO == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (id == null) {
|
||||||
|
throw exception(SALARY_TYPE_ITEM_CODE_EXISTS);
|
||||||
|
}
|
||||||
|
if (!itemDO.getId().equals(id)) {
|
||||||
|
throw exception(SALARY_TYPE_ITEM_CODE_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.hr;
|
package cn.iocoder.yudao.module.system.service.hr.type;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeUpdateSortVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.hr.SalaryTypeDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.hr.SalaryTypeDO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -13,17 +15,16 @@ public interface SalaryTypeService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建工资类型
|
* 创建工资类型
|
||||||
* @param name 类型名称
|
* @param createReqVO 创建信息
|
||||||
* @return 类型编号
|
* @return 类型编号
|
||||||
*/
|
*/
|
||||||
Long createSalaryType(String name);
|
Long createSalaryType(SalaryTypeCreateReqVO createReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新工资类型
|
* 更新工资类型
|
||||||
* @param id 类型编号
|
* @param updateReqVO 更新信息
|
||||||
* @param name 类型名称
|
|
||||||
*/
|
*/
|
||||||
void updateSalaryType(Long id, String name);
|
void updateSalaryType(SalaryTypeCreateReqVO updateReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新工资类型状态
|
* 更新工资类型状态
|
||||||
@ -44,4 +45,10 @@ public interface SalaryTypeService {
|
|||||||
* @return 工资类型列表
|
* @return 工资类型列表
|
||||||
*/
|
*/
|
||||||
List<SalaryTypeDO> getSalaryTypeList();
|
List<SalaryTypeDO> getSalaryTypeList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工资类型排序
|
||||||
|
* @param updateSortVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateSort(List<SalaryTypeUpdateSortVO> updateSortVO);
|
||||||
}
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.service.hr.type;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.hr.vo.type.SalaryTypeUpdateSortVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.hr.SalaryTypeDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.mysql.hr.SalaryTypeMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SALARY_TYPE_NAME_EXISTS;
|
||||||
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SALARY_TYPE_NOT_EXISTS;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SalaryTypeServiceImpl implements SalaryTypeService{
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SalaryTypeMapper salaryTypeMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SalaryTypeItemService salaryTypeItemService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createSalaryType(SalaryTypeCreateReqVO createReqVO) {
|
||||||
|
|
||||||
|
// 校验类型名称唯一性
|
||||||
|
validateTypeNameExists(null, createReqVO.getName());
|
||||||
|
|
||||||
|
SalaryTypeDO salaryTypeDO = BeanUtils.toBean(createReqVO, SalaryTypeDO.class)
|
||||||
|
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
|
||||||
|
salaryTypeMapper.insert(salaryTypeDO);
|
||||||
|
return salaryTypeDO.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSalaryType(SalaryTypeCreateReqVO updateReqVO) {
|
||||||
|
|
||||||
|
validateTypeExists(updateReqVO.getId());
|
||||||
|
validateTypeNameExists(updateReqVO.getId(), updateReqVO.getName());
|
||||||
|
|
||||||
|
SalaryTypeDO salaryTypeDO = BeanUtils.toBean(updateReqVO, SalaryTypeDO.class);
|
||||||
|
salaryTypeMapper.updateById(salaryTypeDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSalaryTypeStatus(Long id, Integer status) {
|
||||||
|
|
||||||
|
validateTypeExists(id);
|
||||||
|
|
||||||
|
SalaryTypeDO salaryTypeDO = new SalaryTypeDO()
|
||||||
|
.setId(id)
|
||||||
|
.setStatus(status);
|
||||||
|
|
||||||
|
salaryTypeMapper.updateById(salaryTypeDO);
|
||||||
|
|
||||||
|
// 同步更新 类型配置状态
|
||||||
|
salaryTypeItemService.updateStatusByTypeId(id, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTypeExists(Long id) {
|
||||||
|
if (salaryTypeMapper.selectById(id) == null) {
|
||||||
|
throw exception(SALARY_TYPE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTypeNameExists(Long id, String name) {
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验类型名称唯一性
|
||||||
|
SalaryTypeDO salaryTypeDO = salaryTypeMapper.selectOne(SalaryTypeDO::getName, name);
|
||||||
|
if (salaryTypeDO == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (id == null) {
|
||||||
|
throw exception(SALARY_TYPE_NAME_EXISTS);
|
||||||
|
}
|
||||||
|
if (!salaryTypeDO.getId().equals(id)) {
|
||||||
|
throw exception(SALARY_TYPE_NAME_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SalaryTypeDO getSalaryType(Long id) {
|
||||||
|
|
||||||
|
return salaryTypeMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SalaryTypeDO> getSalaryTypeList() {
|
||||||
|
|
||||||
|
return salaryTypeMapper.selectList(new LambdaQueryWrapperX<SalaryTypeDO>()
|
||||||
|
.orderByAsc(SalaryTypeDO::getSort));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSort(List<SalaryTypeUpdateSortVO> updateSortVO) {
|
||||||
|
|
||||||
|
salaryTypeMapper.updateBatch(BeanUtils.toBean(updateSortVO, SalaryTypeDO.class));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?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="cn.iocoder.yudao.module.system.dal.mysql.hr.PayslipMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||||
|
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||||
|
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||||
|
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<delete id="deletePayslip">
|
||||||
|
delete from hr_payslip
|
||||||
|
where
|
||||||
|
salary_date = #{date}
|
||||||
|
and company_dept_id = #{deptId}
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
Loading…
Reference in New Issue
Block a user