feat(smartfactory): 优化员工相关功能

- 添加员工工资创建接口
- 优化员工数据统计功能
- 增加工种名称和业务类型字段
- 调整员工信息展示和导入模板
- 重构员工工资查询逻辑
This commit is contained in:
furongxin 2025-02-22 16:27:36 +08:00
parent ae7f70fcaf
commit ec0ffa1651
13 changed files with 184 additions and 42 deletions

View File

@ -33,9 +33,7 @@ import java.text.DecimalFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -213,11 +211,14 @@ public class FactoryDataController {
List<SizeDO> sizeDOS = sizeService.getListSize();
List<String> size = sizeDOS.stream().map(info -> info.getId() + ":" + info.getName()).collect(Collectors.toList());
Map<Integer, List<String>> mapDropDown = new HashMap<>();
mapDropDown.put(0, factory);
mapDropDown.put(2, size);
// 输出
ExcelUtils.write(response, "出入库数据导入模板.xls", "详情",
FactoryDataImportVO.class, null,
0, factory,
2, size);
mapDropDown);
}
@PostMapping("/import")

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.smartfactory.controller.admin.staff;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
@ -26,10 +27,15 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Tag(name = "管理后台 - 员工")
@ -75,9 +81,9 @@ public class StaffController {
@Operation(summary = "获得员工")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('factory:staff:query')")
public CommonResult<StaffRespVO> getStaff(@RequestParam("id") Long id) {
public CommonResult<StaffDO> getStaff(@RequestParam("id") Long id) {
StaffDO staff = staffService.getStaff(id);
return success(BeanUtils.toBean(staff, StaffRespVO.class));
return success(staff);
}
@GetMapping("/getListByFactory")
@ -96,7 +102,19 @@ public class StaffController {
@PreAuthorize("@ss.hasPermission('factory:staff:query')")
public CommonResult<PageResult<StaffRespVO>> getStaffPage(@Valid StaffPageReqVO pageReqVO) {
PageResult<StaffDO> pageResult = staffService.getStaffPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, StaffRespVO.class));
PageResult<StaffRespVO> result = BeanUtils.toBean(pageResult, StaffRespVO.class);
if (CollUtil.isNotEmpty(result.getList())) {
// 获取工厂详情
Set<Long> factoryIds = convertSet(result.getList(), StaffRespVO::getFactoryId);
Map<Long, FactoryInfoDO> factoryInfoMap = convertMap(factoryInfoService.getFactoryList(factoryIds), FactoryInfoDO::getId);
result.getList().forEach(data -> {
// 设置工厂名称
data.setFactoryName(factoryInfoMap.containsKey(data.getFactoryId()) ? factoryInfoMap.get(data.getFactoryId()).getName() : null);
});
}
return success(result);
}
@GetMapping("/export-excel")
@ -128,11 +146,21 @@ public class StaffController {
.map(item -> item.getValue() + ":" + item.getLabel())
.collect(Collectors.toList());
// 获取业务类型名称
List<DictDataRespDTO> businessTypeVOs = dictDataApi.getDictDataList("system_settlement_type").getCheckedData();
List<String> businessTypeName = businessTypeVOs.stream()
.map(item -> item.getValue() + ":" + item.getLabel())
.collect(Collectors.toList());
Map<Integer, List<String>> mapDropDown = new HashMap<>();
mapDropDown.put(1, factoryName);
mapDropDown.put(2, workTypeName);
mapDropDown.put(3, businessTypeName);
// 输出
ExcelUtils.write(response, "工人导入模板.xlsx", "工人列表",
StaffImportExcelVO.class, null,
1, factoryName,
2, workTypeName);
mapDropDown);
}
@PostMapping("/import")

View File

@ -30,6 +30,9 @@ public class StaffImportExcelVO {
@ExcelProperty("工种名称")
private String workTypeName;
@ExcelProperty("业务类型名称")
private String businessTypeName;
@ExcelProperty("手机号码")
@Mobile
private String mobile;

View File

@ -15,15 +15,12 @@ public class StaffPageReqVO extends PageParam {
@Schema(description = "员工昵称")
private String nickName;
@Schema(description = "年龄")
private Integer age;
@Schema(description = "用户性别0男 1女 2未知")
private Integer sex;
@Schema(description = "工种id", example = "6971")
private Integer workTypeId;
@Schema(description = "所属业务类型")
private Integer businessType;
@Schema(description = "工厂id", example = "6971")
private Long factoryId;

View File

@ -31,6 +31,9 @@ public class StaffRespVO {
@Schema(description = "工种id", example = "6971")
private Integer workTypeId;
@Schema(description = "所属业务类型")
private Integer businessType;
@Schema(description = "工厂id", example = "6971")
private Long factoryId;

View File

@ -27,6 +27,9 @@ public class StaffSaveReqVO {
@Schema(description = "工种id", example = "6971")
private Integer workTypeId;
@Schema(description = "所属业务类型")
private Integer businessType;
@Schema(description = "工厂id", example = "6971")
private Long factoryId;

View File

@ -6,6 +6,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staff.vo.StaffPageReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staff.vo.StaffRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staff.vo.StaffSaveReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryPageReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalarySaveReqVO;
@ -49,8 +52,12 @@ public class StaffSalaryController {
@Resource
private FactoryInfoService factoryInfoService;
@Resource
private LoanApi loanApi;
@PostMapping("/create")
@Operation(summary = "创建员工工资")
@PreAuthorize("@ss.hasPermission('smartfactory:staff-salary:create')")
public CommonResult<Long> createStaff(@Valid @RequestBody StaffSalarySaveReqVO createReqVO) {
return success(staffSalaryService.createStaffSalary(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新厂区员工工资")
@ -83,15 +90,8 @@ public class StaffSalaryController {
@PreAuthorize("@ss.hasPermission('smartfactory:staff-salary:query')")
public CommonResult<StaffSalaryRespVO> getStaffSalary(@RequestParam("id") Long id) {
StaffSalaryDO staffSalary = staffSalaryService.getStaffSalary(id);
StaffSalaryRespVO respVO = BeanUtils.toBean(staffSalary, StaffSalaryRespVO.class);
if (respVO != null) {
// 获取员工借支信息
LoanDTO loanDTO = loanApi.getByUserId(staffSalary.getStaffId()).getCheckedData();
// 设置员工借支余额
respVO.setLoanAmount(loanDTO.getRemainingAmount());
}
return success(respVO);
return success(BeanUtils.toBean(staffSalary, StaffSalaryRespVO.class));
}
@GetMapping("/get-list")

View File

@ -48,6 +48,11 @@ public class StaffDO extends BaseDO {
*/
private Integer workTypeId;
/**
* 所属业务类型
*/
private Integer businessType;
/**
* 工厂id
*/

View File

@ -3,12 +3,18 @@ package cn.iocoder.yudao.module.smartfactory.dal.mysql.staff;
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.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staff.vo.StaffPageReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryPageReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryRespVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factoryinfo.FactoryInfoDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staff.StaffDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staffsalary.StaffSalaryDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Objects;
/**
* 员工 Mapper
@ -20,8 +26,9 @@ public interface StaffMapper extends BaseMapperX<StaffDO> {
default PageResult<StaffDO> selectPage(StaffPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<StaffDO>()
.eqIfPresent(StaffDO::getAge, reqVO.getAge())
.eqIfPresent(StaffDO::getWorkTypeId, reqVO.getWorkTypeId())
.eqIfPresent(StaffDO::getFactoryId, reqVO.getFactoryId())
.likeIfPresent(StaffDO::getNickName, reqVO.getNickName())
.eqIfPresent(StaffDO::getStatus, reqVO.getStatus())
.orderByDesc(StaffDO::getId));
}
@ -40,4 +47,35 @@ public interface StaffMapper extends BaseMapperX<StaffDO> {
* @return 员工信息列表
*/
List<StaffDO> getStaffDataV2(@Param("factoryId") Long factoryId);
default PageResult<StaffSalaryRespVO> selectSalaryPage(StaffSalaryPageReqVO pageReqVO) {
MPJLambdaWrapperX<StaffDO> query = new MPJLambdaWrapperX<StaffDO>()
.selectAs(StaffDO::getId, StaffSalaryRespVO::getStaffId)
.selectAs(StaffDO::getNickName, StaffSalaryRespVO::getStaffName)
.selectAs(StaffDO::getFactoryId, StaffSalaryRespVO::getFactoryId)
.selectAs(FactoryInfoDO::getName, StaffSalaryRespVO::getFactoryName)
.selectAs(StaffDO::getWorkTypeId, StaffSalaryRespVO::getWorkTypeId)
.selectAs(StaffSalaryDO::getMonth, StaffSalaryRespVO::getMonth)
.selectAs(StaffDO::getSalary, StaffSalaryRespVO::getSalary)
.selectAs(StaffSalaryDO::getId, StaffSalaryRespVO::getId)
.selectAs(StaffSalaryDO::getAttendanceDays, StaffSalaryRespVO::getAttendanceDays)
.selectAs(StaffSalaryDO::getPayableAmount, StaffSalaryRespVO::getPayableAmount)
.selectAs(StaffSalaryDO::getReturnAmount, StaffSalaryRespVO::getReturnAmount)
.selectAs(StaffSalaryDO::getDeductionAmount, StaffSalaryRespVO::getDeductionAmount)
.selectAs(StaffSalaryDO::getRealAmount, StaffSalaryRespVO::getRealAmount)
.selectAs(StaffSalaryDO::getDeductionItems, StaffSalaryRespVO::getDeductionItems)
.selectAs(StaffSalaryDO::getStatus, StaffSalaryRespVO::getStatus)
.selectAs(StaffSalaryDO::getCreateTime, StaffSalaryRespVO::getCreateTime);
query.leftJoin(StaffSalaryDO.class, on -> on
.eq(StaffDO::getId, StaffSalaryDO::getStaffId)
.eq(Objects.nonNull(pageReqVO.getMonth()), StaffSalaryDO::getMonth, pageReqVO.getMonth())
.eq(Objects.nonNull(pageReqVO.getStatus()), StaffSalaryDO::getStatus, pageReqVO.getStatus()));
query.leftJoin(FactoryInfoDO.class, FactoryInfoDO::getId, StaffDO::getFactoryId);
query.eqIfPresent(StaffDO::getFactoryId, pageReqVO.getFactoryId());
query.eqIfPresent(StaffDO::getWorkTypeId, pageReqVO.getWorkTypeId());
query.eqIfPresent(StaffDO::getId, pageReqVO.getStaffId());
return selectJoinPage(pageReqVO, StaffSalaryRespVO.class, query);
}
}

View File

@ -16,17 +16,19 @@ import cn.iocoder.yudao.module.smartfactory.controller.admin.staff.vo.StaffPageR
import cn.iocoder.yudao.module.smartfactory.controller.admin.staff.vo.StaffSaveReqVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staff.StaffDO;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.staff.StaffMapper;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.*;
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.convertMap;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.STAFF_NOT_EXISTS;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IMPORT_LIST_IS_EMPTY;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_USERNAME_EXISTS;
@ -43,6 +45,9 @@ public class StaffServiceImpl implements StaffService {
@Resource
private StaffMapper staffMapper;
@Resource
private DictDataApi dictDataApi;
@Override
public Long createStaff(StaffSaveReqVO createReqVO) {
// 插入
@ -54,7 +59,9 @@ public class StaffServiceImpl implements StaffService {
@Override
public void updateStaff(StaffSaveReqVO updateReqVO) {
validateUserForCreateOrUpdate(updateReqVO.getId(), null, null, null);
if (staffMapper.selectById(updateReqVO.getId()) == null) {
throw exception(STAFF_NOT_EXISTS);
}
// 更新
StaffDO updateObj = BeanUtils.toBean(updateReqVO, StaffDO.class);
staffMapper.updateById(updateObj);
@ -66,7 +73,7 @@ public class StaffServiceImpl implements StaffService {
staffMapper.deleteById(id);
}
private void validateUserForCreateOrUpdate(Long id, String username, String mobile, String idCard) {
private void validateUserForCreate(Long id, String username, String mobile, String idCard) {
// 关闭数据权限避免因为没有数据权限查询不到数据进而导致唯一校验不正确
DataPermissionUtils.executeIgnore(() -> {
@ -95,7 +102,18 @@ public class StaffServiceImpl implements StaffService {
@Override
public StaffDataRespVO getStaffData(Long factoryId) {
StaffDataRespVO vo = new StaffDataRespVO();
List<StaffDO> dos = staffMapper.getStaffData(factoryId);
List<StaffDO> dos = staffMapper.selectList(new LambdaQueryWrapperX<StaffDO>()
.ne(StaffDO::getStatus, 0));
// 获取工种信息
List<DictDataRespDTO> workTypeVOs = dictDataApi.getDictDataList("user_work_type").getCheckedData();
Map<String, String> workTypeMap = workTypeVOs.stream().collect(Collectors.toMap(DictDataRespDTO::getValue, DictDataRespDTO::getLabel));
// 设置工种名称
dos.forEach(item -> {
item.setPostName(workTypeMap.getOrDefault(item.getWorkTypeId().toString(), ""));
});
vo.setTotal(dos.size());
vo.setMaleTotal((int) dos.stream().filter(a -> a.getSex() == 0).count());
vo.setFemaleTotal((int) dos.stream().filter(a -> a.getSex() == 1).count());
@ -112,6 +130,14 @@ public class StaffServiceImpl implements StaffService {
public StaffDataRespVO getStaffDataV2(Long factoryId) {
StaffDataRespVO vo = new StaffDataRespVO();
List<StaffDO> dos = staffMapper.getStaffDataV2(factoryId);
// 获取工种信息
List<DictDataRespDTO> workTypeVOs = dictDataApi.getDictDataList("user_work_type").getCheckedData();
Map<String, String> workTypeMap = workTypeVOs.stream().collect(Collectors.toMap(DictDataRespDTO::getValue, DictDataRespDTO::getLabel));
// 设置工种名称
dos.forEach(item -> {
item.setPostName(workTypeMap.getOrDefault(item.getWorkTypeId().toString(), ""));
});
vo.setTotal(dos.size());
vo.setMaleTotal((int) dos.stream().filter(a -> a.getSex() == 0).count());
vo.setFemaleTotal((int) dos.stream().filter(a -> a.getSex() == 1).count());
@ -137,7 +163,7 @@ public class StaffServiceImpl implements StaffService {
//校验判断是否有不符合的原因
try {
if (!updateSupport) {
validateUserForCreateOrUpdate(null, importUser.getNickName(), null, importUser.getIdCard());
validateUserForCreate(null, importUser.getNickName(), null, importUser.getIdCard());
}
} catch (ServiceException ex) {
respVO.getFailureUsernames().put(importUser.getNickName(), ex.getMessage());
@ -167,11 +193,17 @@ public class StaffServiceImpl implements StaffService {
updateUser.setWorkTypeId(Integer.valueOf(importUser.getWorkTypeName().split(":")[0]));
}
// 设置业务类型
if (StrUtil.isNotEmpty(importUser.getBusinessTypeName())) {
updateUser.setBusinessType(Integer.valueOf(importUser.getBusinessTypeName().split(":")[0]));
}
// 判断如果不存在在进行插入
if (updateSupport) {
StaffDO staffDO = staffMapper.selectOne(new LambdaQueryWrapperX<StaffDO>()
.eq(StaffDO::getIdCard, importUser.getIdCard())
.eq(StaffDO::getNickName, importUser.getNickName()));
.eqIfPresent(StaffDO::getIdCard, importUser.getIdCard())
.eqIfPresent(StaffDO::getNickName, importUser.getNickName()));
updateUser.setId(staffDO.getId());
staffMapper.updateById(updateUser);

View File

@ -16,6 +16,13 @@ import java.util.List;
*/
public interface StaffSalaryService {
/**
* 创建厂区员工工资
* @param createReqVO 创建信息
* @return 工资编号
*/
Long createStaffSalary(StaffSalarySaveReqVO createReqVO);
/**
* 更新厂区员工工资
*

View File

@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.Staf
import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalarySaveReqVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staffsalary.StaffSalaryDO;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.staff.StaffMapper;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.staffsalary.StaffSalaryMapper;
import cn.iocoder.yudao.module.system.api.loan.LoanApi;
import cn.iocoder.yudao.module.system.api.loan.dto.LoanDTO;
@ -19,6 +20,7 @@ import java.math.BigDecimal;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.STAFF_SALARY_EXISTS;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.STAFF_SALARY_NOT_EXISTS;
/**
@ -33,9 +35,30 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
@Resource
private StaffSalaryMapper staffSalaryMapper;
@Resource
private StaffMapper staffMapper;
@Resource
private LoanApi loanApi;
@Override
public Long createStaffSalary(StaffSalarySaveReqVO createReqVO) {
// 校验当前月份工资是否存在
Long count = staffSalaryMapper.selectCount(new LambdaQueryWrapperX<StaffSalaryDO>()
.eq(StaffSalaryDO::getStaffId, createReqVO.getStaffId())
.eq(StaffSalaryDO::getMonth, createReqVO.getMonth()));
if (count > 0L) {
throw exception(STAFF_SALARY_EXISTS);
}
// 插入
StaffSalaryDO staffSalaryDO = BeanUtils.toBean(createReqVO, StaffSalaryDO.class);
staffSalaryMapper.insert(staffSalaryDO);
return staffSalaryDO.getId();
}
@Override
public void updateStaffSalary(StaffSalarySaveReqVO updateReqVO) {
// 校验存在
@ -68,8 +91,13 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
@Override
public PageResult<StaffSalaryRespVO> getStaffSalaryPage(StaffSalaryPageReqVO pageReqVO) {
if (pageReqVO.getMonth() != null) {
return staffMapper.selectSalaryPage(pageReqVO);
}else {
return staffSalaryMapper.selectSalaryPage(pageReqVO);
}
}
@Override
public void updateStatus(StaffSalarySaveReqVO updateReqVO) {

View File

@ -37,18 +37,15 @@
ext.work_type as workType,
b.factory_id as factoryId,
a.idcard as idCard,
a.status as status,
d.label as postName
a.status as status
FROM
system_users AS a
LEFT JOIN system_users_ext AS ext ON a.id = ext.user_id
LEFT JOIN system_dept AS b ON a.dept_id = b.id
LEFT JOIN sf_factory_info AS c ON b.factory_id = c.id
left join system_dict_data as d on ext.work_type = d.value
<where>
a.user_type = 2
and a.deleted = 0
and d.dict_type = 'user_work_type'
<if test="factoryId != null">
and b.factory_id = #{factoryId}
</if>