Files
ccdi/doc/design/2026-02-05-员工柜员号优化设计.md
wkc 9c84af78f2 docs: 添加员工柜员号优化设计文档
- 移除tellerNo字段,将employeeId设置为柜员号
- 柜员号为7位数字,手动输入,唯一性校验
- 包含数据库、后端、前端、测试等完整设计方案
- 生成测试脚本和API文档更新计划
2026-02-05 14:06:35 +08:00

12 KiB

员工柜员号优化设计文档

文档版本: v1.0 创建日期: 2026-02-05 设计目标: 统一标识符,移除tellerNo字段,将employeeId设置为柜员号


一、需求概述

1.1 需求背景

当前员工信息表中存在两个字段用于标识员工:

  • employee_id: 数据库主键,自增ID
  • teller_no: 柜员号,业务标识符

这种双标识符设计造成了字段冗余和业务混淆。

1.2 需求目标

  • 移除 teller_no 字段,简化数据结构
  • employee_id 改为手动输入的柜员号(7位数字)
  • 统一标识符,避免业务混淆
  • 保持数据完整性和业务连续性

1.3 约束条件

  • 系统处于开发阶段,无正式生产数据
  • 柜员号必须为7位数字
  • 柜员号必须唯一,不允许重复
  • 柜员号为必填字段

二、数据库层设计

2.1 表结构修改

删除字段

ALTER TABLE ccdi_employee DROP COLUMN teller_no;

修改主键字段

-- 移除自增属性
ALTER TABLE ccdi_employee MODIFY employee_id BIGINT(20) NOT NULL;

-- 更新字段注释
ALTER TABLE ccdi_employee MODIFY COLUMN employee_id BIGINT(20) NOT NULL COMMENT '员工ID(柜员号,7位数字)';

重建表方案(推荐,清空数据场景)

DROP TABLE IF EXISTS ccdi_employee;

CREATE TABLE ccdi_employee (
  employee_id BIGINT(20) NOT NULL COMMENT '员工ID(柜员号,7位数字)',
  name VARCHAR(100) NOT NULL COMMENT '姓名',
  dept_id BIGINT(20) DEFAULT NULL COMMENT '所属部门ID',
  id_card VARCHAR(18) NOT NULL COMMENT '身份证号',
  phone VARCHAR(11) DEFAULT NULL COMMENT '电话',
  hire_date DATE DEFAULT NULL COMMENT '入职时间',
  status CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态(0在职 1离职)',
  create_by VARCHAR(64) DEFAULT '' COMMENT '创建者',
  create_time DATETIME DEFAULT NULL COMMENT '创建时间',
  update_by VARCHAR(64) DEFAULT '' COMMENT '更新者',
  update_time DATETIME DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (employee_id),
  KEY idx_dept_id (dept_id),
  KEY idx_status (status),
  UNIQUE KEY uk_id_card (id_card)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工信息表';

2.2 索引调整

  • 移除: UNIQUE KEY teller_no
  • 保留: PRIMARY KEY (employee_id) 天然保证唯一性

三、后端代码层设计

3.1 Entity 实体类 (CcdiEmployee.java)

修改前:

@TableId(type = IdType.AUTO)
private Long employeeId;

private String tellerNo;

修改后:

@TableId(type = IdType.INPUT)  // 改为手动输入
private Long employeeId;

// 删除 tellerNo 字段

3.2 DTO 类修改

CcdiEmployeeAddDTO.java

/** 员工ID(柜员号) */
@NotNull(message = "柜员号不能为空")
@Min(value = 1000000L, message = "柜员号必须为7位数字")
@Max(value = 9999999L, message = "柜员号必须为7位数字")
private Long employeeId;

// 删除 tellerNo 字段

CcdiEmployeeEditDTO.java

// employeeId 作为主键标识,通过路径参数传递,不在请求体中

// 删除 tellerNo 字段

CcdiEmployeeQueryDTO.java

/** 柜员号(精确查询) */
@Min(value = 1000000L, message = "柜员号必须为7位数字")
@Max(value = 9999999L, message = "柜员号必须为7位数字")
private Long employeeId;

// 删除 tellerNo 字段

3.3 VO 类修改 (CcdiEmployeeVO.java)

/** 员工ID(柜员号) */
private Long employeeId;

// 删除 tellerNo 字段

3.4 Service 层修改

新增柜员号唯一性校验

@Override
public void checkEmployeeIdUnique(Long employeeId) {
    CcdiEmployee existing = baseMapper.selectById(employeeId);
    if (existing != null) {
        throw new ServiceException("柜员号已存在,请使用其他柜员号");
    }
}

新增员工方法调整

@Override
public void addEmployee(CcdiEmployeeAddDTO dto) {
    // 1. 校验柜员号唯一性
    checkEmployeeIdUnique(dto.getEmployeeId());

    // 2. 校验身份证号唯一性
    checkIdCardUnique(dto.getIdCard());

    // 3. 转换并保存
    CcdiEmployee employee = BeanUtil.copyProperties(dto, CcdiEmployee.class);
    baseMapper.insert(employee);
}

3.5 Mapper XML 修改

ResultMap 调整

<resultMap type="com.ruoyi.ccdi.domain.vo.CcdiEmployeeVO" id="CcdiEmployeeVOResult">
    <id property="employeeId" column="employee_id"/>
    <result property="name" column="name"/>
    <!-- 删除 tellerNo 映射 -->
    <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"/>
    <result property="status" column="status"/>
    <result property="createTime" column="create_time"/>
</resultMap>

查询 SQL 调整

<select id="selectEmployeePageWithDept" resultMap="CcdiEmployeeVOResult">
    SELECT
        e.employee_id, e.name, e.dept_id, e.id_card, e.phone,
        e.hire_date, e.status, e.create_time,
        d.dept_name
    FROM ccdi_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.employeeId != null">
            AND e.employee_id = #{query.employeeId}
        </if>
        <!-- 删除 teller_no 查询条件 -->
        <if test="query.deptId != null">
            AND e.dept_id = #{query.deptId}
        </if>
        <if test="query.idCard != null and query.idCard != ''">
            AND e.id_card LIKE CONCAT('%', #{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>

3.6 Controller 层修改

接口参数调整

  • POST /ccdi/employee: 新增接口,接收 employeeId 作为必填字段
  • PUT /ccdi/employee/{employeeId}: 编辑接口,employeeId 作为路径参数不可修改
  • GET /ccdi/employee/list: 列表查询,移除 tellerNo 查询参数,保留 employeeId 精确查询

Swagger 注释更新

@Operation(summary = "新增员工信息", description = "employeeId为柜员号,7位数字")

四、前端代码层设计

4.1 查询表单调整

<!-- 删除原来的 tellerNo 查询条件 -->

<!-- 新增:员工ID(柜员号)查询 -->
<el-form-item label="柜员号" prop="employeeId">
  <el-input
    v-model="queryParams.employeeId"
    placeholder="请输入7位柜员号"
    clearable
    maxlength="7"
    oninput="value=value.replace(/[^\d]/g,'')"
    style="width: 240px"
    @keyup.enter.native="handleQuery"
  />
</el-form-item>

4.2 表格列调整

<!-- 删除 -->
<!-- <el-table-column label="柜员号" prop="tellerNo" /> -->

<!-- 新增 -->
<el-table-column label="柜员号" align="center" prop="employeeId" :show-overflow-tooltip="true"/>

4.3 新增/编辑对话框调整

<!-- 新增模式:可输入 -->
<el-form-item label="柜员号" prop="employeeId" v-if="!isEdit">
  <el-input
    v-model="form.employeeId"
    placeholder="请输入7位柜员号"
    clearable
    maxlength="7"
    oninput="value=value.replace(/[^\d]/g,'')"
    style="width: 240px"
  />
</el-form-item>

<!-- 编辑模式:只读 -->
<el-form-item label="柜员号" prop="employeeId" v-if="isEdit">
  <el-input v-model="form.employeeId" disabled style="width: 240px"/>
</el-form-item>

4.4 JavaScript 数据结构

data() {
  return {
    queryParams: {
      name: null,
      employeeId: null,  // 替代 tellerNo
      deptId: null,
      idCard: null,
      status: null
    },
    form: {
      employeeId: null,  // 替代 tellerNo
      name: null,
      deptId: null,
      // ...
    }
  }
}

4.5 表单校验规则

rules: {
  employeeId: [
    { required: true, message: "柜员号不能为空", trigger: "blur" },
    { pattern: /^\d{7}$/, message: "柜员号必须为7位数字", trigger: "blur" }
  ],
  // 其他规则...
}

五、测试方案

5.1 新增员工测试

测试场景 输入数据 预期结果
正常场景 柜员号: 1000000 新增成功
格式错误-少于7位 柜员号: 123456 提示"柜员号必须为7位数字"
格式错误-多于7位 柜员号: 12345678 提示"柜员号必须为7位数字"
格式错误-非数字 柜员号: 123456a 提示"柜员号必须为7位数字"
唯一性冲突 重复的柜员号 提示"柜员号已存在"
必填校验 柜员号为空 提示"柜员号不能为空"

5.2 编辑员工测试

测试场景 操作 预期结果
正常编辑 修改其他字段,柜员号不可变 编辑成功,柜员号不变
只读验证 尝试修改柜员号 柜员号输入框禁用

5.3 查询测试

测试场景 输入 预期结果
精确查询 输入7位柜员号 返回匹配的员工记录
列表显示 查看列表 显示employeeId作为柜员号

六、文档更新清单

6.1 API 文档更新

  • 文件路径: doc/api/员工信息管理API文档.md
  • 更新内容:
    1. 新增接口:移除 tellerNo,新增 employeeId 参数说明
    2. 编辑接口:更新路径参数为 employeeId
    3. 查询接口:移除 tellerNo 查询参数,新增 employeeId
    4. 返回数据:移除 tellerNo 字段
    5. 字段说明表:更新 employeeId 为"员工ID(柜员号,7位数字)"

6.2 测试脚本

  • 文件路径: doc/test/2026-02-05-employee-modify-test.sh
  • 测试账号: username: admin, password: admin123
  • 测试接口: /login/test 获取 token

6.3 数据库脚本

  • 文件路径: sql/modify_employee_id_to_teller_no.sql
  • 执行顺序:
    1. 删除 teller_no 字段
    2. 修改 employee_id 为非自增
    3. 更新字段注释

七、实施步骤

7.1 数据库修改

  1. 备份现有数据库(如有数据)
  2. 执行 SQL 脚本修改表结构
  3. 验证表结构修改成功

7.2 后端代码修改

  1. 修改 Entity 实体类
  2. 修改 DTO 类(Add/Edit/Query)
  3. 修改 VO 类
  4. 修改 Service 层,添加唯一性校验
  5. 修改 Mapper XML
  6. 修改 Controller 层
  7. 编译后端项目,确保无错误

7.3 前端代码修改

  1. 修改查询表单
  2. 修改表格列
  3. 修改新增/编辑对话框
  4. 修改 JavaScript 数据结构和方法
  5. 添加表单校验规则
  6. 编译前端项目,确保无错误

7.4 测试验证

  1. 执行测试脚本
  2. 验证新增功能
  3. 验证编辑功能
  4. 验证查询功能
  5. 验证唯一性校验
  6. 验证格式校验
  7. 生成测试报告

7.5 文档更新

  1. 更新 API 文档
  2. 更新测试报告
  3. 提交代码到版本控制

八、风险评估与应对

8.1 风险点

  1. 数据迁移风险: 如果有正式数据,需要迁移方案

    • 应对: 当前为开发阶段,无正式数据,直接修改
  2. 接口兼容性: 前端调用可能受影响

    • 应对: 同步修改前端代码和接口调用
  3. 业务逻辑依赖: 其他模块可能引用 tellerNo

    • 应对: 全局搜索 tellerNo 引用,同步修改

8.2 回滚方案

如果修改后出现问题,可以:

  1. 恢复数据库表结构(添加回 teller_no 字段)
  2. 恢复代码到修改前的版本
  3. 恢复前端代码到修改前的版本

九、验收标准

9.1 功能验收

  • 数据库 teller_no 字段已删除
  • employee_id 改为非自增,手动输入
  • 后端代码所有 tellerNo 引用已移除
  • 前端页面显示 employeeId 作为柜员号
  • 新增员工时必须输入7位数字柜员号
  • 柜员号唯一性校验生效
  • 柜员号格式校验生效
  • 编辑时柜员号不可修改

9.2 性能验收

  • 接口响应时间无明显变化
  • 数据库查询效率正常

9.3 文档验收

  • API 文档已更新
  • 测试脚本已生成
  • 测试报告已生成

文档结束