feat: 员工信息管理功能完善

- 将员工表org_no字段迁移至dept_id,关联系统部门表
- 更新员工信息相关DTO、VO和Controller,使用deptId替代orgNo
- 添加员工信息管理OpenSpec规范文档(proposal/design/spec/tasks)
- 更新API文档,反映部门关联变更
- 添加数据库迁移脚本employee_org_no_to_dept_id.sql
- 新增员工信息分页接口测试脚本(PowerShell/Python)
- 更新CLAUDE.md,添加MCP数据库工具使用说明

Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
This commit is contained in:
wkc
2026-01-28 16:57:38 +08:00
parent eac1112f9b
commit 47f9491941
23 changed files with 2090 additions and 40 deletions

View File

@@ -143,7 +143,7 @@ public class DpcEmployeeController extends BaseController {
DpcEmployeeAddDTO dto = new DpcEmployeeAddDTO();
dto.setName(entity.getName());
dto.setTellerNo(entity.getTellerNo());
dto.setOrgNo(entity.getOrgNo());
dto.setDeptId(entity.getDeptId());
dto.setIdCard(entity.getIdCard());
dto.setPhone(entity.getPhone());
dto.setHireDate(entity.getHireDate());

View File

@@ -35,9 +35,9 @@ public class DpcEmployee implements Serializable {
@Excel(name = "柜员号")
private String tellerNo;
/** 所属机构号 */
@Excel(name = "所属机构号")
private String orgNo;
/** 所属部门ID */
@Excel(name = "所属部门ID")
private Long deptId;
/** 身份证号 */
@Excel(name = "身份证号")

View File

@@ -35,10 +35,9 @@ public class DpcEmployeeAddDTO implements Serializable {
@Size(max = 50, message = "柜员号长度不能超过50个字符")
private String tellerNo;
/** 所属机构号 */
@Excel(name = "所属机构号")
@Size(max = 50, message = "所属机构号长度不能超过50个字符")
private String orgNo;
/** 所属部门ID */
@Excel(name = "所属部门ID")
private Long deptId;
/** 身份证号 */
@Excel(name = "身份证号")

View File

@@ -37,10 +37,9 @@ public class DpcEmployeeEditDTO implements Serializable {
@Size(max = 50, message = "柜员号长度不能超过50个字符")
private String tellerNo;
/** 所属机构号 */
@Excel(name = "所属机构号")
@Size(max = 50, message = "所属机构号长度不能超过50个字符")
private String orgNo;
/** 所属部门ID */
@Excel(name = "所属部门ID")
private Long deptId;
/** 身份证号 */
@Excel(name = "身份证号")

View File

@@ -23,8 +23,8 @@ public class DpcEmployeeQueryDTO implements Serializable {
/** 柜员号(精确查询) */
private String tellerNo;
/** 所属机构号 */
private String orgNo;
/** 所属部门ID */
private Long deptId;
/** 身份证号(精确查询) */
private String idCard;

View File

@@ -28,8 +28,11 @@ public class DpcEmployeeVO implements Serializable {
/** 柜员号 */
private String tellerNo;
/** 所属机构号 */
private String orgNo;
/** 所属部门ID */
private Long deptId;
/** 所属部门名称 */
private String deptName;
/** 身份证号 */
private String idCard;

View File

@@ -1,7 +1,9 @@
package com.ruoyi.dpc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.dpc.domain.DpcEmployee;
import com.ruoyi.dpc.domain.dto.DpcEmployeeQueryDTO;
import com.ruoyi.dpc.domain.vo.DpcEmployeeVO;
import org.apache.ibatis.annotations.Param;
@@ -13,6 +15,16 @@ import org.apache.ibatis.annotations.Param;
*/
public interface DpcEmployeeMapper extends BaseMapper<DpcEmployee> {
/**
* 分页查询员工列表(包含部门名称)
*
* @param page 分页对象
* @param queryDTO 查询条件
* @return 员工VO分页结果
*/
Page<DpcEmployeeVO> selectEmployeePageWithDept(@Param("page") Page<DpcEmployeeVO> page,
@Param("query") DpcEmployeeQueryDTO queryDTO);
/**
* 查询员工详情(包含亲属列表)
*

View File

@@ -63,18 +63,20 @@ public class DpcEmployeeServiceImpl implements IDpcEmployeeService {
*/
@Override
public Page<DpcEmployeeVO> selectEmployeePage(Page<DpcEmployee> page, DpcEmployeeQueryDTO queryDTO) {
LambdaQueryWrapper<DpcEmployee> wrapper = buildQueryWrapper(queryDTO);
Page<DpcEmployee> resultPage = employeeMapper.selectPage(page, wrapper);
// 使用关联查询获取部门名称
Page<DpcEmployeeVO> voPage = new Page<>(page.getCurrent(), page.getSize());
Page<DpcEmployeeVO> resultPage = employeeMapper.selectEmployeePageWithDept(voPage, queryDTO);
// 直接复用resultPage只转换records
Page<DpcEmployeeVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
voPage.setRecords(resultPage.getRecords().stream()
.map(this::convertToVO)
.collect(Collectors.toList()));
// 复制其他分页信息
voPage.setPages(resultPage.getPages());
// 设置状态描述
resultPage.getRecords().forEach(vo -> {
if ("0".equals(vo.getStatus())) {
vo.setStatusDesc("在职");
} else if ("1".equals(vo.getStatus())) {
vo.setStatusDesc("离职");
}
});
return voPage;
return resultPage;
}
/**
@@ -262,7 +264,7 @@ public class DpcEmployeeServiceImpl implements IDpcEmployeeService {
LambdaQueryWrapper<DpcEmployee> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotEmpty(queryDTO.getName()), DpcEmployee::getName, queryDTO.getName())
.eq(StringUtils.isNotEmpty(queryDTO.getTellerNo()), DpcEmployee::getTellerNo, queryDTO.getTellerNo())
.eq(StringUtils.isNotEmpty(queryDTO.getOrgNo()), DpcEmployee::getOrgNo, queryDTO.getOrgNo())
.eq(queryDTO.getDeptId() != null, DpcEmployee::getDeptId, queryDTO.getDeptId())
.eq(StringUtils.isNotEmpty(queryDTO.getIdCard()), DpcEmployee::getIdCard, queryDTO.getIdCard())
.eq(StringUtils.isNotEmpty(queryDTO.getStatus()), DpcEmployee::getStatus, queryDTO.getStatus())
.orderByDesc(DpcEmployee::getCreateTime);

View File

@@ -8,7 +8,8 @@
<id property="employeeId" column="employee_id"/>
<result property="name" column="name"/>
<result property="tellerNo" column="teller_no"/>
<result property="orgNo" column="org_no"/>
<result property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
<result property="idCard" column="id_card"/>
<result property="phone" column="phone"/>
<result property="hireDate" column="hire_date"/>
@@ -24,9 +25,35 @@
</collection>
</resultMap>
<select id="selectEmployeePageWithDept" resultMap="DpcEmployeeVOResult">
SELECT
e.employee_id, e.name, e.teller_no, e.dept_id, e.id_card, e.phone, e.hire_date, e.status, e.create_time,
d.dept_name
FROM dpc_employee e
LEFT JOIN sys_dept d ON e.dept_id = d.dept_id
<where>
<if test="query.name != null and query.name != ''">
AND e.name LIKE CONCAT('%', #{query.name}, '%')
</if>
<if test="query.tellerNo != null and query.tellerNo != ''">
AND e.teller_no = #{query.tellerNo}
</if>
<if test="query.deptId != null">
AND e.dept_id = #{query.deptId}
</if>
<if test="query.idCard != null and query.idCard != ''">
AND e.id_card = #{query.idCard}
</if>
<if test="query.status != null and query.status != ''">
AND e.status = #{query.status}
</if>
</where>
ORDER BY e.create_time DESC
</select>
<select id="selectEmployeeWithRelatives" parameterType="Long" resultMap="DpcEmployeeVOResult">
SELECT
e.employee_id, e.name, e.teller_no, e.org_no, e.id_card, e.phone, e.hire_date, e.status, e.create_time,
e.employee_id, e.name, e.teller_no, e.dept_id, e.id_card, e.phone, e.hire_date, e.status, e.create_time,
r.relative_id, r.employee_id, r.relative_name, r.relative_id_card, r.relative_phone, r.relationship
FROM dpc_employee e
LEFT JOIN dpc_employee_relative r ON e.employee_id = r.employee_id