功能需求规格文档 — ECS 考勤管理
本文档描述 ECS 电子班牌模块「考勤管理」功能的完整需求规格。
技能将根据此文档生成后端 + 前端代码。
1. 基础信息
| 属性 |
值 |
| 功能中文名 |
考勤管理 |
| 功能简写 |
attend |
| 所属模块 |
ruoyi-modules/ruoyi-ecs |
| 主表名 |
t_ecs_attend |
| 从表名 |
无 |
| 是否多租户 |
是 |
| 数据库类型 |
kingbase(人大金仓) |
| 描述 |
管理学员考勤记录,数据由考勤设备上传,支持查看、查询、导出;同时支持手工考勤补签(选择教室→班级→班级下学员) |
2. 接口清单
2.1 主表接口
| 接口 |
HTTP |
路径(后端) |
前端路径 |
权限字符 |
| 列表 |
GET |
/attend/list |
/ecs/attend/list |
ecs:attend:list |
| 详情 |
GET |
/attend/{id} |
/ecs/attend/{id} |
ecs:attend:query |
| 新增(手工考勤) |
POST |
/attend/ |
/ecs/attend/ |
ecs:attend:add |
| 导出数据 |
POST |
/attend/export |
/ecs/attend/export |
ecs:attend:export |
说明:考勤记录主要来自设备上传,本模块提供查看、查询和导出功能。手工考勤为补签场景,需关联选择教室、班级、班级下学员。不支持编辑、删除、导入操作。
2.2 补充接口
无
3. 字段属性速查表
| 属性 |
含义 |
可选值 |
说明 |
fieldName |
字段名(驼峰) |
— |
代码变量名 |
columnName |
列名(下划线) |
— |
数据库列名 |
fieldType |
Java类型 |
String/Long/Integer/BigDecimal/Date |
|
inDb |
是否在表中存在 |
true/false |
false=纯前端计算字段 |
inTable |
列表是否显示 |
true/false |
生成表格列 |
inQuery |
是否查询字段 |
true/false |
生成搜索条件 |
queryType |
查询方式 |
eq/like/between |
精确/模糊/范围 |
inForm |
是否表单字段 |
true/false |
生成表单项 |
inAdd |
新增表单显示 |
true/false |
|
inEdit |
编辑表单显示 |
true/false |
|
required |
是否必填 |
true/false |
生成校验注解 |
dictType |
字典类型 |
字典标识 |
有值=字典下拉,否则普通输入 |
relation |
关联选择配置 |
对象 |
有值=弹出选择框 |
component |
前端组件类型 |
input/select/inputNumber/datetime/textarea |
默认根据类型推断 |
width |
表格列宽 |
数字(px) |
默认auto |
sort |
排序 |
数字 |
越小越靠前 |
excelExport |
Excel导出 |
true/false |
默认true |
lockRule |
操作锁定规则 |
对象 |
有值=按此字段值控制行级操作权限 |
4. 字段清单
4.1 主表 t_ecs_attend
fields:
# ---------- 主键 ----------
- fieldName: attendId
columnName: attend_id
fieldType: Long
inDb: true
inTable: false
inForm: false
remark: 主键,详情时传递
# ---------- 学员关联 ----------
- fieldName: userId
columnName: user_id
fieldType: Long
inDb: true
inTable: false
inQuery: false
inForm: true
inAdd: true
inEdit: false
required: true
relation:
table: t_pt_user_account
idField: pt_user_id
nameField: real_name
title: 选择学员
path: /backstage/userAccount/selectUserAccount
cascade:
dependsOn: classId
description: 选择班级后,只能选择该班级下的学员
component: userSelect
remark: 学员Id(关联学员表,级联依赖班级)
- fieldName: userNumb
column_name: user_numb
fieldType: String
inDb: true
inTable: true
inQuery: true
queryType: like
inForm: false
component: input
width: 120
sort: 4
excelExport: true
remark: 学号(冗余存储)
- fieldName: realName
columnName: real_name
fieldType: String
inDb: true
inTable: true
inQuery: true
queryType: like
inForm: false
component: input
width: 120
sort: 3
excelExport: true
remark: 学员姓名(冗余存储)
# ---------- 班级关联 ----------
- fieldName: classId
columnName: class_id
fieldType: Long
inDb: true
inTable: false
inQuery: false
inForm: true
inAdd: true
inEdit: false
required: true
relation:
table: t_ecs_class
idField: class_id
nameField: class_name
title: 选择班级
path: /ecs/class/selectClass
component: classSelect
remark: 班级Id(关联班级表)
- fieldName: className
columnName: class_name
fieldType: String
inDb: true
inTable: true
inQuery: true
queryType: like
inForm: false
component: input
width: 150
sort: 1
excelExport: true
remark: 班级名称(冗余存储)
# ---------- 教室关联 ----------
- fieldName: roomId
columnName: room_id
fieldType: Long
inDb: true
inTable: false
inQuery: false
inForm: true
inAdd: true
inEdit: false
required: true
relation:
table: t_pt_room
idField: room_id
nameField: room_name
title: 选择教室
path: /backstage/room/selectRoom
component: roomSelect
remark: 教室Id(关联教室表)
- fieldName: roomName
columnName: room_name
fieldType: String
inDb: true
inTable: true
inQuery: false
inForm: false
component: input
width: 150
sort: 5
excelExport: true
remark: 教室名称(冗余存储)
# ---------- 考勤信息 ----------
- fieldName: checkTime
columnName: check_time
fieldType: Date
inDb: true
inTable: true
inQuery: false
inForm: true
inAdd: true
inEdit: false
required: true
component: datetime
width: 180
sort: 6
excelExport: true
remark: 考勤时间
- fieldName: checkType
columnName: check_type
fieldType: Integer
inDb: true
inTable: false
inQuery: false
inForm: true
inAdd: true
inEdit: false
required: true
dictType: check_type
component: select
excelExport: true
remark: 考勤方式:0-刷卡,1-人脸
- fieldName: uploadTime
columnName: upload_time
fieldType: Date
inDb: true
inTable: true
inQuery: false
inForm: false
component: datetime
width: 180
sort: 7
excelExport: true
remark: 上传时间
# ---------- 推送状态 ----------
- fieldName: pushStatus
columnName: push_status
fieldType: Integer
inDb: true
inTable: true
inQuery: true
queryType: eq
inForm: false
required: false
dictType: push_status
component: select
width: 100
sort: 8
excelExport: true
remark: 推送状态:0-未推送,1-推送成功,2-推送失败
- fieldName: pushTime
columnName: push_time
fieldType: Date
inDb: true
inTable: true
inQuery: false
inForm: false
component: datetime
width: 180
sort: 9
excelExport: true
remark: 推送时间
- fieldName: pushRetry
columnName: push_retry
fieldType: Integer
inDb: true
inTable: false
inQuery: false
inForm: false
component: inputNumber
width: 80
excelExport: false
remark: 推送尝试次数
# ---------- 公共字段(所有表统一包含,多租户表增加 tenant_id) ----------
# 通用字段定义(无需在字段清单中重复写,建表时自动追加):
# | 字段 | Java类型 | 说明 |
# | ------------- | --------------- | ------------------ |
# | del_flag | Integer | 逻辑删除:0-未删除,1-已删除 |
# | create_dept | Long | 创建部门 |
# | create_by | Long | 创建者 |
# | create_time | Date | 创建时间 |
# | update_by | Long | 最后修改者 |
# | update_time | Date | 最后修改时间 |
# | tenant_id | Long | 租户ID(多租户表包含) |
- fieldName: delFlag
columnName: del_flag
fieldType: Integer
inDb: true
inTable: false
inForm: false
- fieldName: createTime
columnName: create_time
fieldType: Date
inDb: true
inTable: false
inQuery: false
inForm: false
component: datetime
5. VO 结构
5.1 主表列表 VO
AttendVo:
- attendId # 主键
- className # 班级名称
- realName # 学员姓名
- userNumb # 学号
- roomName # 教室名称
- checkTime # 考勤时间
- uploadTime # 上传时间
- pushStatus # 推送状态
- pushTime # 推送时间
5.2 主表明细 VO
AttendDetailVo:
includes: AttendVo
additional:
- userId # 学员Id
- userNumb # 学号
- realName # 学员姓名
- classId # 班级Id
- className # 班级名称
- roomId # 教室Id
- roomName # 教室名称
- checkTime # 考勤时间
- checkType # 考勤方式
- uploadTime # 上传时间
- pushStatus # 推送状态
- pushTime # 推送时间
- pushRetry # 推送尝试次数
6. 特殊需求
special:
excelImport: false # 不支持导入
excelExport: true # 支持导出
# 手工考勤新增时的特殊规则
addRules:
- fieldName: roomId
required: true
message: 请选择教室
- fieldName: classId
required: true
message: 请选择班级
- fieldName: userId
required: true
message: 请选择学员
cascade: true
dependsOn: classId
description: 先选班级,再选该班级下的学员
- fieldName: checkTime
required: true
message: 请填写考勤时间
- fieldName: checkType
required: true
message: 请选择考勤方式
# 级联选择规则
cascadeRules:
- field: userId
dependsOn: classId
description: 选择班级后,学员列表过滤为该班级下的学员
apiPath: /backstage/userAccount/selectUserAccount
apiParams:
classId: ${classId}
dubboExpose: false # 不暴露 Dubbo 服务
7. 字典项
| 字典类型 |
枚举值 |
说明 |
check_type |
0=刷卡, 1=人脸 |
考勤方式 |
push_status |
0=未推送, 1=推送成功, 2=推送失败 |
推送状态 |
8. 建表语句
通用字段:所有表统一包含以下字段(建表语句自动追加,无需在字段清单中重复):
| 字段 |
类型 |
说明 |
| del_flag |
character(1 char) |
逻辑删除:0-未删除,1-已删除 |
| create_dept |
bigint |
创建部门 |
| create_by |
bigint |
创建者 |
| create_time |
timestamp |
创建时间 |
| update_by |
bigint |
更新者 |
| update_time |
timestamp |
更新时间 |
| tenant_id |
bigint |
租户ID(多租户表) |
8.1 主表 t_ecs_attend
-- ============================================
-- ECS 考勤记录表(kingbase/人大金仓)
-- ============================================
CREATE TABLE "dbo"."t_ecs_attend" (
"attend_id" bigint NOT NULL,
"user_id" bigint NOT NULL,
"user_numb" character varying(50 char) NOT NULL DEFAULT ''::varchar,
"real_name" character varying(100 char) NOT NULL DEFAULT ''::varchar,
"class_id" bigint NOT NULL,
"class_name" character varying(100 char) NOT NULL DEFAULT ''::varchar,
"room_id" bigint NOT NULL,
"room_name" character varying(100 char) NOT NULL DEFAULT ''::varchar,
"check_time" timestamp NOT NULL,
"check_type" integer NOT NULL DEFAULT 0,
"upload_time" timestamp,
"push_status" integer NOT NULL DEFAULT 0,
"push_time" timestamp,
"push_retry" integer NOT NULL DEFAULT 0,
-- 通用字段(自动追加)
"del_flag" character(1 char) NOT NULL DEFAULT '0'::bpchar,
"create_dept" bigint,
"create_by" bigint,
"create_time" timestamp,
"update_by" bigint,
"update_time" timestamp,
"tenant_id" bigint,
CONSTRAINT "t_ecs_attend_pkey" PRIMARY KEY ("attend_id")
);
-- 表注释
ALTER TABLE "dbo"."t_ecs_attend" COMMENT 'ECS考勤记录表';
-- 列注释
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "attend_id" COMMENT '主键';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "user_id" COMMENT '学员Id';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "user_numb" COMMENT '学号';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "real_name" COMMENT '学员姓名';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "class_id" COMMENT '班级Id';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "class_name" COMMENT '班级名称';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "room_id" COMMENT '教室Id';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "room_name" COMMENT '教室名称';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "check_time" COMMENT '考勤时间';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "check_type" COMMENT '考勤方式:0-刷卡,1-人脸';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "upload_time" COMMENT '上传时间';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "push_status" COMMENT '推送状态:0-未推送,1-推送成功,2-推送失败';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "push_time" COMMENT '推送时间';
ALTER TABLE "dbo"."t_ecs_attend" MODIFY "push_retry" COMMENT '推送尝试次数';
-- 索引
CREATE INDEX "idx_ecs_attend_class_id" ON "dbo"."t_ecs_attend" ("class_id");
CREATE INDEX "idx_ecs_attend_user_id" ON "dbo"."t_ecs_attend" ("user_id");
CREATE INDEX "idx_ecs_attend_check_time" ON "dbo"."t_ecs_attend" ("check_time");
CREATE INDEX "idx_ecs_attend_push_status" ON "dbo"."t_ecs_attend" ("push_status");
9. 备注
- 数据冗余设计:学员姓名(
realName)、学号(userNumb)、班级名称(className)、教室名称(roomName)采用冗余存储策略,避免关联查询性能问题。当学员/班级/教室信息变更时需考虑是否同步更新历史记录。
- 只读模型:考勤记录主要由设备自动上传,不支持编辑和删除操作,确保数据的不可篡改性。本模块提供查看、查询、导出功能。
- 推送机制:
pushStatus 记录推送状态,pushRetry 记录重试次数,支持后续定时任务扫描推送失败记录进行重试。
- 手工考勤:新增操作即「手工考勤」,用于补签场景。表单填写顺序为:选择教室 → 选择班级 → 选择学员(级联:选完班级后只能选该班级下的学员) → 选择考勤方式 → 填写考勤时间。
- 关联实体说明:
- 教室 → 关联
t_pt_room 表(通过 backstage 模块的 RemotePtRoomService)
- 班级 → 关联
t_ecs_class 表(ECS 模块内部)
- 学员 → 关联
t_pt_user_account 表(通过 backstage 模块的 RemoteUserAccountService),级联依赖班级,只显示所选班级下的学员
- 级联选择:userId 级联依赖 classId,前端实现时班级选择变更后需清空学员已选值,并按新班级过滤学员列表。