|
|
# 考勤相关功能
|
|
|
|
|
|
> 模块编码:attendance
|
|
|
> 端侧:微信小程序
|
|
|
> 关联文档:01-模块划分.md(v4.0)、02-功能清单-小程序端.md(§5)、03-业务流转逻辑-小程序端.md(§5)、05-接口规范.md(§9)、06-项目技术要求.md
|
|
|
> 强制规范遵循 `07-前端界面开发规范.md`
|
|
|
|
|
|
## 功能概览
|
|
|
|
|
|
| 项目 | 说明 |
|
|
|
|------|------|
|
|
|
| 菜单名称 | 考勤打卡 |
|
|
|
| 子菜单 | 上班打卡 / 下班打卡 / 打卡记录 / 异常申诉 / 考勤日历 / 考勤审核 |
|
|
|
| 功能编号 | MP-AT-01 ~ MP-AT-06 |
|
|
|
| 权限编码 | attendance:record:*、attendance:appeal:*、attendance:supplement:* |
|
|
|
|
|
|
## 页面清单
|
|
|
|
|
|
### 页面1:上班打卡
|
|
|
|
|
|
- **页面路径**:`/pages/attendance/clock-in`
|
|
|
- **适用角色**:全部
|
|
|
- **页面元素**:
|
|
|
- 当前时间显示(大字时钟)
|
|
|
- 打卡状态指示(未打卡/已打卡)
|
|
|
- 蓝牙扫描状态指示器
|
|
|
- 当前打卡点名称
|
|
|
- 蓝牙信号强度显示
|
|
|
- 打卡按钮
|
|
|
- 补录/申诉入口
|
|
|
- **查询条件**:无
|
|
|
- **列表字段**:无
|
|
|
- **界面布局**:
|
|
|
- 顶部:当前时间大字显示
|
|
|
- 中部:打卡点信息 + 蓝牙状态
|
|
|
- 底部:打卡按钮(圆形大按钮)
|
|
|
- **操作按钮**:
|
|
|
- 「上班打卡」→ 记录上班打卡(权限:attendance:record:create)
|
|
|
- 「异常申诉」→ 跳转异常申诉页(蓝牙未检测到时显示)
|
|
|
|
|
|
**蓝牙策略判断逻辑**:
|
|
|
- 调用 `GET /system/bluetooth-policy → attendance_check`
|
|
|
- 策略=REQUIRED:必须连接指定打卡点蓝牙Beacon后才可打卡
|
|
|
- 验证Beacon属于本人班组打卡点
|
|
|
- 打卡成功记录 `check_method=BLUETOOTH`
|
|
|
- 策略=OPTIONAL:可选蓝牙打卡或手动打卡
|
|
|
- 手动打卡:`check_method=MANUAL`
|
|
|
|
|
|
**需求追溯**:
|
|
|
|
|
|
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|
|
|
|------------|----------|----------|----------|----------|
|
|
|
| MP-AT-01 | 上班打卡 | 02-小程序端 §5 | 记录操作日志 | 考勤记录、打卡点管理 |
|
|
|
|
|
|
#### 交互流程要求
|
|
|
|
|
|
1. **页面加载流程**:页面加载时获取当前时间→查询蓝牙策略→策略=REQUIRED自动启动蓝牙扫描;显示打卡状态(已打卡/未打卡)
|
|
|
2. **查询/筛选交互流程**:无筛选操作
|
|
|
3. **表单填写与提交流程**:点击「上班打卡」→策略=REQUIRED自动扫描蓝牙→检测到打卡点Beacon→打卡成功(check_method=BLUETOOTH);策略=OPTIONAL选择打卡方式→蓝牙/手动打卡
|
|
|
4. **弹窗/弹层交互流程**:打卡成功弹出成功提示(显示打卡时间);蓝牙未检测到弹出提示"未检测到打卡点蓝牙"
|
|
|
5. **行内操作流程**:点击打卡按钮→执行打卡流程→显示结果;点击异常申诉→跳转异常申诉页
|
|
|
6. **异常与错误处理**:蓝牙未开启提示"请开启手机蓝牙";打卡失败显示重试;已打卡提示"今日已打卡";离线时数据暂存本地联网后同步
|
|
|
7. **联动/级联交互**:蓝牙策略与打卡流程联动;打卡状态实时更新
|
|
|
8. **权限控制交互表现**:所有登录用户可打卡;蓝牙权限被拒引导开启
|
|
|
|
|
|
#### 前端硬性约束
|
|
|
|
|
|
- **H1 防重复提交**:打卡按钮点击后立即 `loading=true` + `disabled=true` 防止重复点击;使用 pending 请求去重机制(同一请求未完成前不发送新请求);支持 `wx.requestTask.abort()` 取消前一次未完成的请求
|
|
|
- **H2 超时控制**:GET 请求超时 15s、POST 请求超时 30s;请求耗时 >3s 时自动调用 `wx.showLoading({ title: '加载中...', mask: true })` 提示用户等待
|
|
|
- **H3 二次确认**:无危险操作,无需二次确认
|
|
|
- **H4 脏数据检测**:本页面为操作型页面,无需表单脏数据检测
|
|
|
- **H7 文件上传**:无上传操作
|
|
|
- **H8 操作反馈**:打卡成功调用 `wx.showToast({ title: '打卡成功', icon: 'success' })`;网络异常时提示"网络异常,请检查网络后重试",提供重试按钮;离线暂存成功提示"已暂存本地,联网后将自动同步"
|
|
|
- **通用约束**:使用 uni-ui 组件库;所有可点击元素触控区域 ≥44px;下拉刷新操作需防重复触发
|
|
|
|
|
|
#### 组件规范
|
|
|
|
|
|
| 元素 | 组件 | 配置参数 |
|
|
|
|------|------|----------|
|
|
|
| 当前时间 | `text` | font-size="48px",font-weight="bold",动态更新 |
|
|
|
| 打卡状态 | `uni-tag` | type: success(已打卡)/warning(未打卡) |
|
|
|
| 打卡按钮 | `button` | type="primary",圆形大按钮,size=120px |
|
|
|
| 蓝牙状态指示 | `uni-icons` | type="bluetooth",size="22" |
|
|
|
| 打卡点名称 | `text` | font-size="14px" |
|
|
|
| 异常申诉 | `button` | type="default",size="mini" |
|
|
|
| 打卡结果 | `uni-popup` | type="dialog",显示打卡时间 |
|
|
|
|
|
|
#### 校验规则
|
|
|
|
|
|
| 字段 | 规则 | 错误提示 |
|
|
|
|------|------|----------|
|
|
|
| 蓝牙状态 | 策略=REQUIRED须开启蓝牙 | "请开启手机蓝牙" |
|
|
|
| Beacon验证 | 须属于本人班组打卡点 | "未检测到有效打卡点" |
|
|
|
| 打卡状态 | 未打卡才可打卡 | "今日已打卡" |
|
|
|
| 打卡时间 | 自动记录精确到秒 | — |
|
|
|
|
|
|
#### 响应式布局
|
|
|
|
|
|
- **适配机型**:iPhone SE(375px)~ iPad mini(768px),打卡按钮居中
|
|
|
- **横竖屏适配策略**:竖屏垂直居中布局;横屏信息与按钮并排
|
|
|
- **手势交互规范**:打卡按钮≥120px可点击区域;申诉按钮≥44px
|
|
|
- **安全区域**:底部按钮适配底部安全区
|
|
|
|
|
|
---
|
|
|
|
|
|
### 页面2:下班打卡
|
|
|
|
|
|
- **页面路径**:`/pages/attendance/clock-out`
|
|
|
- **适用角色**:全部
|
|
|
- **页面元素**:
|
|
|
- 当前时间显示(大字时钟)
|
|
|
- 打卡状态指示(未打卡/已打卡)
|
|
|
- 上班打卡时间显示
|
|
|
- 蓝牙扫描状态指示器
|
|
|
- 当前打卡点名称
|
|
|
- 打卡按钮
|
|
|
- 补录/申诉入口
|
|
|
- **查询条件**:无
|
|
|
- **列表字段**:无
|
|
|
- **界面布局**:
|
|
|
- 顶部:当前时间 + 上班打卡时间
|
|
|
- 中部:打卡点信息 + 蓝牙状态
|
|
|
- 底部:打卡按钮(圆形大按钮)
|
|
|
- **操作按钮**:
|
|
|
- 「下班打卡」→ 记录下班打卡(权限:attendance:record:create)
|
|
|
- 「异常申诉」→ 跳转异常申诉页
|
|
|
|
|
|
**需求追溯**:
|
|
|
|
|
|
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|
|
|
|------------|----------|----------|----------|----------|
|
|
|
| MP-AT-02 | 下班打卡 | 02-小程序端 §5 | 记录操作日志 | 考勤记录 |
|
|
|
|
|
|
#### 交互流程要求
|
|
|
|
|
|
1. **页面加载流程**:页面加载时获取当前时间和上班打卡时间→查询蓝牙策略→自动扫描蓝牙(策略=REQUIRED);显示打卡状态
|
|
|
2. **查询/筛选交互流程**:无筛选操作
|
|
|
3. **表单填写与提交流程**:点击「下班打卡」→策略=REQUIRED自动扫描蓝牙→打卡成功;策略=OPTIONAL选择打卡方式→打卡
|
|
|
4. **弹窗/弹层交互流程**:打卡成功弹出成功提示(显示上下班时间);蓝牙未检测到弹出提示
|
|
|
5. **行内操作流程**:点击打卡按钮→执行打卡→显示结果;点击异常申诉→跳转异常申诉页
|
|
|
6. **异常与错误处理**:蓝牙未开启提示;下班未打上班卡提示"请先完成上班打卡";离线暂存
|
|
|
7. **联动/级联交互**:上班打卡时间与下班打卡联动展示
|
|
|
8. **权限控制交互表现**:所有登录用户可打卡
|
|
|
|
|
|
#### 前端硬性约束
|
|
|
|
|
|
- **H1 防重复提交**:打卡按钮点击后立即 `loading=true` + `disabled=true` 防止重复点击;使用 pending 请求去重机制(同一请求未完成前不发送新请求);支持 `wx.requestTask.abort()` 取消前一次未完成的请求
|
|
|
- **H2 超时控制**:GET 请求超时 15s、POST 请求超时 30s;请求耗时 >3s 时自动调用 `wx.showLoading({ title: '加载中...', mask: true })` 提示用户等待
|
|
|
- **H3 二次确认**:无危险操作,无需二次确认
|
|
|
- **H4 脏数据检测**:本页面为操作型页面,无需表单脏数据检测
|
|
|
- **H7 文件上传**:无上传操作
|
|
|
- **H8 操作反馈**:打卡成功调用 `wx.showToast({ title: '打卡成功', icon: 'success' })`;网络异常时提示"网络异常,请检查网络后重试",提供重试按钮;离线暂存成功提示"已暂存本地,联网后将自动同步"
|
|
|
- **通用约束**:使用 uni-ui 组件库;所有可点击元素触控区域 ≥44px
|
|
|
|
|
|
#### 组件规范
|
|
|
|
|
|
| 元素 | 组件 | 配置参数 |
|
|
|
|------|------|----------|
|
|
|
| 当前时间 | `text` | font-size="48px",font-weight="bold" |
|
|
|
| 上班打卡时间 | `text` | font-size="14px",color="#666" |
|
|
|
| 打卡状态 | `uni-tag` | type: success(已打卡)/warning(未打卡) |
|
|
|
| 打卡按钮 | `button` | type="primary",圆形大按钮,size=120px |
|
|
|
| 蓝牙状态指示 | `uni-icons` | type="bluetooth",size="22" |
|
|
|
| 异常申诉 | `button` | type="default",size="mini" |
|
|
|
| 打卡结果 | `uni-popup` | type="dialog" |
|
|
|
|
|
|
#### 校验规则
|
|
|
|
|
|
| 字段 | 规则 | 错误提示 |
|
|
|
|------|------|----------|
|
|
|
| 上班打卡 | 须先完成上班打卡 | "请先完成上班打卡" |
|
|
|
| 蓝牙状态 | 策略=REQUIRED须蓝牙连接 | "请开启手机蓝牙" |
|
|
|
| 打卡状态 | 未打卡才可打卡 | "今日已打卡" |
|
|
|
|
|
|
#### 响应式布局
|
|
|
|
|
|
- **适配机型**:iPhone SE(375px)~ iPad mini(768px),打卡按钮居中
|
|
|
- **横竖屏适配策略**:竖屏垂直居中布局;横屏信息与按钮并排
|
|
|
- **手势交互规范**:打卡按钮≥120px可点击区域
|
|
|
- **安全区域**:底部按钮适配底部安全区
|
|
|
|
|
|
---
|
|
|
|
|
|
### 页面3:打卡记录
|
|
|
|
|
|
- **页面路径**:`/pages/attendance/records`
|
|
|
- **适用角色**:全部
|
|
|
- **页面元素**:
|
|
|
- 月份选择器
|
|
|
- 统计信息卡片(出勤天数/迟到/早退/缺卡)
|
|
|
- 打卡记录列表
|
|
|
- 记录详情弹窗
|
|
|
- **查询条件**:
|
|
|
- 月份筛选
|
|
|
- 状态筛选(全部/正常/迟到/早退/缺卡/补录)
|
|
|
- **列表字段**:
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| 日期 | 日期 | 打卡日期 |
|
|
|
| 上班时间 | 时间 | 上班打卡时间 |
|
|
|
| 下班时间 | 时间 | 下班打卡时间 |
|
|
|
| 打卡方式 | 标签 | 蓝牙/手动/补录 |
|
|
|
| 状态 | 标签 | 正常/迟到/早退/缺卡 |
|
|
|
|
|
|
- **界面布局**:
|
|
|
- 顶部:月份选择器 + 统计数字横向排列
|
|
|
- 中部:按日期分组的打卡记录列表
|
|
|
- 底部:无操作栏
|
|
|
- **操作按钮**:
|
|
|
- 「查看详情」→ 查看打卡详情(含打卡点、蓝牙信息等)
|
|
|
- 「异常申诉」→ 对异常记录发起申诉
|
|
|
|
|
|
**需求追溯**:
|
|
|
|
|
|
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|
|
|
|------------|----------|----------|----------|----------|
|
|
|
| MP-AT-03 | 打卡记录 | 02-小程序端 §5 | 无 | 考勤日历 |
|
|
|
|
|
|
#### 交互流程要求
|
|
|
|
|
|
1. **页面加载流程**:页面加载时获取当月打卡记录和统计→渲染月份选择器和记录列表
|
|
|
2. **查询/筛选交互流程**:切换月份→重新加载;状态筛选(全部/正常/迟到/早退/缺卡/补录)→过滤记录
|
|
|
3. **表单填写与提交流程**:无表单提交操作
|
|
|
4. **弹窗/弹层交互流程**:点击查看详情→弹出打卡详情弹窗(含打卡点、蓝牙信息)
|
|
|
5. **行内操作流程**:点击查看详情→查看详情弹窗;点击异常申诉→跳转异常申诉页
|
|
|
6. **异常与错误处理**:记录加载失败显示重试;无记录显示空状态
|
|
|
7. **联动/级联交互**:月份和状态筛选与列表数据联动
|
|
|
8. **权限控制交互表现**:仅可查看本人打卡记录
|
|
|
|
|
|
#### 前端硬性约束
|
|
|
|
|
|
- **H1 防重复提交**:月份切换/状态筛选时防重复请求;列表加载期间禁用筛选操作;使用 pending 请求去重
|
|
|
- **H2 超时控制**:GET 请求超时 15s;列表加载 >3s 时调用 `wx.showLoading({ title: '加载中...', mask: true })`
|
|
|
- **H3 二次确认**:无危险操作,无需二次确认
|
|
|
- **H4 脏数据检测**:本页面为列表查看页,无需表单脏数据检测
|
|
|
- **H7 文件上传**:无上传操作
|
|
|
- **H8 操作反馈**:加载成功无提示(静默刷新);加载失败调用 `wx.showToast({ title: '加载失败', icon: 'none' })` 并显示重试按钮;网络异常时提示"网络异常,请检查网络后重试"
|
|
|
- **通用约束**:使用 uni-ui 组件库;所有可点击元素触控区域 ≥44px;下拉刷新需防重复触发(refreshing 标志位)
|
|
|
|
|
|
#### 组件规范
|
|
|
|
|
|
| 元素 | 组件 | 配置参数 |
|
|
|
|------|------|----------|
|
|
|
| 月份选择器 | `uni-datetime-picker` | type="date",fields="month" |
|
|
|
| 统计卡片 | `uni-card` | mode="center",四列等宽 |
|
|
|
| 状态筛选 | `uni-segmented-control` | :values="['全部','正常','迟到','早退','缺卡','补录']" |
|
|
|
| 记录列表 | `uni-list` + `uni-list-item` | clickable=true |
|
|
|
| 状态标签 | `uni-tag` | type: success(正常)/warning(迟到/早退)/error(缺卡)/primary(补录) |
|
|
|
| 详情弹窗 | `uni-popup` | type="bottom",显示打卡详情 |
|
|
|
| 打卡方式标签 | `uni-tag` | type: primary(蓝牙)/default(手动)/warning(补录),size="mini" |
|
|
|
|
|
|
#### 校验规则
|
|
|
|
|
|
| 字段 | 规则 | 错误提示 |
|
|
|
|------|------|----------|
|
|
|
| 记录列表 | 加载失败允许重试 | "加载失败,请重试" |
|
|
|
|
|
|
#### 响应式布局
|
|
|
|
|
|
- **适配机型**:iPhone SE(375px)~ iPad mini(768px),卡片宽度自适应
|
|
|
- **横竖屏适配策略**:竖屏单列列表;横屏双列卡片
|
|
|
- **手势交互规范**:记录项可点击区域≥44px
|
|
|
- **安全区域**:底部适配底部安全区
|
|
|
|
|
|
---
|
|
|
|
|
|
### 页面4:异常申诉
|
|
|
|
|
|
- **页面路径**:`/pages/attendance/appeal`
|
|
|
- **适用角色**:全部(蓝牙失灵/系统宕机时)
|
|
|
- **页面元素**:
|
|
|
- 异常日期选择
|
|
|
- 异常类型选择(上班/下班/全天)
|
|
|
- 异常原因选择(蓝牙故障/手机异常/系统异常/忘记打卡/其他)
|
|
|
- 补充说明输入框(多行文本)
|
|
|
- 照片上传区(补充证据,≤9张)
|
|
|
- 提交按钮
|
|
|
- **查询条件**:无
|
|
|
- **列表字段**:无
|
|
|
- **界面布局**:
|
|
|
- 顶部:申诉模式提示
|
|
|
- 中部:原因选择 + 说明填写 + 照片上传
|
|
|
- 底部:提交按钮
|
|
|
- **操作按钮**:
|
|
|
- 「提交申诉」→ 提交打卡异常申诉(权限:attendance:appeal:create)
|
|
|
- 申诉提交后等待主管审核(Web/小程序均可审核)
|
|
|
|
|
|
**需求追溯**:
|
|
|
|
|
|
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|
|
|
|------------|----------|----------|----------|----------|
|
|
|
| MP-AT-04 | 异常申诉 | 02-小程序端 §5 | 主管审核 | 考勤审核 |
|
|
|
|
|
|
#### 交互流程要求
|
|
|
|
|
|
1. **页面加载流程**:页面加载时初始化表单,获取异常类型字典
|
|
|
2. **查询/筛选交互流程**:无筛选操作
|
|
|
3. **表单填写与提交流程**:选择异常日期→选择异常类型(上班/下班/全天)→选择异常原因→填写补充说明→上传照片→点击提交申诉→确认弹窗→提交成功等待审核
|
|
|
4. **弹窗/弹层交互流程**:点击上传弹出选择(拍照/相册);提交前弹出确认弹窗
|
|
|
5. **行内操作流程**:选择日期→选择类型→选择原因→填写说明→上传照片→提交
|
|
|
6. **异常与错误处理**:图片上传失败提示重传;提交失败显示重试;离线暂存本地
|
|
|
7. **联动/级联交互**:异常类型与日期选择联动
|
|
|
8. **权限控制交互表现**:所有用户可提交异常申诉
|
|
|
|
|
|
#### 前端硬性约束
|
|
|
|
|
|
- **H1 防重复提交**:提交按钮点击后立即 `loading=true` + `disabled=true` 防止重复提交;使用 pending 请求去重机制(提交请求未返回前禁用按钮);支持 `wx.requestTask.abort()` 取消前一次未完成的提交
|
|
|
- **H2 超时控制**:GET 请求超时 15s、POST 请求超时 30s、文件上传超时 60s;上传耗时 >3s 时调用 `wx.showLoading({ title: '上传中...', mask: true })`
|
|
|
- **H3 二次确认**:提交申诉前必须调用 `wx.showModal({ title: '确认提交', content: '提交后将等待主管审核,确认提交申诉?', confirmText: '确认', cancelText: '取消' })` 进行二次确认,明确告知操作后果
|
|
|
- **H4 脏数据检测**:页面进入时对表单数据做 deep clone 快照;用户编辑过程中维护 isDirty 状态;`onUnload` / `onBackPress` 生命周期中检测到 isDirty 时弹出 `wx.showModal` 提示"未保存的修改将丢失,确定离开吗?",用户确认后才允许离开
|
|
|
- **H7 文件上传**:单张图片 ≤10MB,超出时提示"图片大小不能超过10MB"并阻止上传;使用 `uni-file-picker` 的 `onProgress` 回调显示上传进度条;支持多图队列上传
|
|
|
- **H8 操作反馈**:提交成功调用 `wx.showToast({ title: '申诉已提交,请等待审核', icon: 'success' })`;网络异常时调用 `wx.showToast({ title: '网络异常,请检查网络后重试', icon: 'none' })` 并提供重试按钮;离线暂存提示"已暂存本地,联网后将自动同步"
|
|
|
- **通用约束**:使用 uni-ui 组件库;所有可点击元素触控区域 ≥44px;选择器/输入框/按钮均 ≥44px
|
|
|
|
|
|
#### 组件规范
|
|
|
|
|
|
| 元素 | 组件 | 配置参数 |
|
|
|
|------|------|----------|
|
|
|
| 异常日期 | `uni-datetime-picker` | type="date" |
|
|
|
| 异常类型 | `uni-data-select` | :localdata="[{value:'clock_in',text:'上班'},{value:'clock_out',text:'下班'},{value:'all_day',text:'全天'}]" |
|
|
|
| 异常原因 | `uni-data-select` | :localdata="[{value:'bluetooth',text:'蓝牙故障'},{value:'phone',text:'手机异常'},{value:'system',text:'系统异常'},{value:'forget',text:'忘记打卡'},{value:'other',text:'其他'}]" |
|
|
|
| 补充说明 | `uni-easyinput` | type="textarea",maxlength="200",:showWordLimit="true" |
|
|
|
| 照片上传 | `uni-file-picker` | limit="9",file-mediatype="image" |
|
|
|
| 提交按钮 | `button` | type="primary",:loading="submitting" |
|
|
|
| 确认弹窗 | `uni-popup` | type="dialog" |
|
|
|
|
|
|
#### 校验规则
|
|
|
|
|
|
| 字段 | 规则 | 错误提示 |
|
|
|
|------|------|----------|
|
|
|
| 异常日期 | 必选 | "请选择异常日期" |
|
|
|
| 异常类型 | 必选 | "请选择异常类型" |
|
|
|
| 异常原因 | 必选 | "请选择异常原因" |
|
|
|
| 补充说明 | 最多200字 | "补充说明不能超过200字" |
|
|
|
| 照片 | 最多9张 | "照片最多上传9张" |
|
|
|
|
|
|
#### 响应式布局
|
|
|
|
|
|
- **适配机型**:iPhone SE(375px)~ iPad mini(768px),表单宽度自适应
|
|
|
- **横竖屏适配策略**:竖屏垂直布局;横屏表单水平分组
|
|
|
- **手势交互规范**:选择器≥44px;提交按钮≥44px
|
|
|
- **安全区域**:底部提交按钮适配底部安全区
|
|
|
|
|
|
---
|
|
|
|
|
|
### 页面5:考勤日历
|
|
|
|
|
|
- **页面路径**:`/pages/attendance/calendar`
|
|
|
- **适用角色**:全部
|
|
|
- **页面元素**:
|
|
|
- 月历视图(日历格子)
|
|
|
- 每日状态标记(颜色点)
|
|
|
- 点击日期显示详情弹窗
|
|
|
- 图例说明
|
|
|
- **查询条件**:
|
|
|
- 月份切换(左右滑动)
|
|
|
- **列表字段**:无(日历模式)
|
|
|
- **界面布局**:
|
|
|
- 顶部:月份切换 + 统计信息
|
|
|
- 中部:月历网格,每日格子中用颜色点标记状态
|
|
|
- 绿色:正常
|
|
|
- 黄色:迟到/早退
|
|
|
- 红色:缺卡
|
|
|
- 蓝色:补录
|
|
|
- 灰色:休息日
|
|
|
- 底部:图例说明
|
|
|
- **操作按钮**:
|
|
|
- 「点击日期」→ 显示当日打卡详情弹窗
|
|
|
|
|
|
**需求追溯**:
|
|
|
|
|
|
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|
|
|
|------------|----------|----------|----------|----------|
|
|
|
| MP-AT-05 | 考勤日历 | 02-小程序端 §5 | 无 | 打卡记录 |
|
|
|
|
|
|
#### 交互流程要求
|
|
|
|
|
|
1. **页面加载流程**:页面加载时获取当月考勤日历数据→渲染月历视图和每日状态标记
|
|
|
2. **查询/筛选交互流程**:左右滑动切换月份→重新加载月历数据
|
|
|
3. **表单填写与提交流程**:无表单提交操作
|
|
|
4. **弹窗/弹层交互流程**:点击日期→弹出当日打卡详情弹窗(上班/下班时间、打卡方式、状态)
|
|
|
5. **行内操作流程**:点击日期→查看详情弹窗;左右滑动切换月份
|
|
|
6. **异常与错误处理**:日历数据加载失败显示重试
|
|
|
7. **联动/级联交互**:月份切换与日历数据联动
|
|
|
8. **权限控制交互表现**:仅可查看本人考勤日历
|
|
|
|
|
|
#### 前端硬性约束
|
|
|
|
|
|
- **H1 防重复提交**:月份切换(左右滑动)时防重复请求;滑动切换期间锁定请求,避免连续滑动触发多次请求
|
|
|
- **H2 超时控制**:GET 请求超时 15s;日历数据加载 >3s 时调用 `wx.showLoading({ title: '加载中...', mask: true })`
|
|
|
- **H3 二次确认**:无危险操作,无需二次确认
|
|
|
- **H4 脏数据检测**:本页面为只读详情页,无需表单脏数据检测
|
|
|
- **H7 文件上传**:无上传操作
|
|
|
- **H8 操作反馈**:加载成功无提示(静默刷新);加载失败调用 `wx.showToast({ title: '日历加载失败', icon: 'none' })` 并显示重试按钮;网络异常时提示"网络异常,请检查网络后重试"
|
|
|
- **通用约束**:使用 uni-ui 组件库;日期格子可点击区域 ≥44px
|
|
|
|
|
|
#### 组件规范
|
|
|
|
|
|
| 元素 | 组件 | 配置参数 |
|
|
|
|------|------|----------|
|
|
|
| 月历视图 | 自定义日历组件 | 7列网格,日期格子44px |
|
|
|
| 状态标记点 | `view` | 圆形8px,颜色动态(绿/黄/红/蓝/灰) |
|
|
|
| 月份切换 | `uni-icons` | type="left"/"right",size="20",@click切换 |
|
|
|
| 详情弹窗 | `uni-popup` | type="bottom",显示当日打卡详情 |
|
|
|
| 图例说明 | `view` + `text` | 水平排列,颜色点+文字 |
|
|
|
|
|
|
#### 校验规则
|
|
|
|
|
|
| 字段 | 规则 | 错误提示 |
|
|
|
|------|------|----------|
|
|
|
| 日历数据 | 加载失败允许重试 | "日历加载失败,请重试" |
|
|
|
| 日期选择 | 只能查看,不可选择未来日期 | — |
|
|
|
|
|
|
#### 响应式布局
|
|
|
|
|
|
- **适配机型**:iPhone SE(375px)~ iPad mini(768px),日历网格宽度自适应
|
|
|
- **横竖屏适配策略**:竖屏7列日历网格;横屏日历宽度适当增大,详情弹窗更宽
|
|
|
- **手势交互规范**:日期格子≥44px;左右滑动切换月份;点击日期≥44px
|
|
|
- **安全区域**:底部图例适配底部安全区
|
|
|
|
|
|
---
|
|
|
|
|
|
### 页面6:考勤审核
|
|
|
|
|
|
- **页面路径**:`/pages/attendance/review`
|
|
|
- **适用角色**:主管
|
|
|
- **页面元素**:
|
|
|
- 待审核申诉列表
|
|
|
- 申诉详情查看
|
|
|
- 审核操作区(通过/驳回)
|
|
|
- 驳回原因输入框
|
|
|
- **查询条件**:
|
|
|
- 状态筛选(待审核/已通过/已驳回)
|
|
|
- 日期筛选
|
|
|
- 人员筛选
|
|
|
- **列表字段**:
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|------|------|------|
|
|
|
| 申诉人 | 文本 | 员工姓名 |
|
|
|
| 申诉日期 | 日期 | 异常打卡日期 |
|
|
|
| 异常类型 | 标签 | 上班/下班/全天 |
|
|
|
| 申诉原因 | 文本 | 原因摘要 |
|
|
|
| 提交时间 | 时间 | 申诉提交时间 |
|
|
|
| 审核状态 | 标签 | 待审核/已通过/已驳回 |
|
|
|
|
|
|
- **界面布局**:
|
|
|
- 顶部:筛选条件
|
|
|
- 中部:申诉卡片列表
|
|
|
- 底部:审核操作按钮(通过/驳回)
|
|
|
- **操作按钮**:
|
|
|
- 「通过」→ 系统自动补录打卡记录,标注"补录"(权限:attendance:appeal:approve)
|
|
|
- 「驳回」→ 填写驳回原因,通知员工
|
|
|
|
|
|
**审核流程**:
|
|
|
```
|
|
|
员工提交异常申诉(小程序端)
|
|
|
│
|
|
|
主管审核(Web+小程序均可)
|
|
|
│
|
|
|
┌─审核通过─┐ ┌─审核驳回─┐
|
|
|
系统自动补录 通知员工
|
|
|
打卡记录 申诉未通过
|
|
|
标注"补录" 记录审核日志
|
|
|
记录审核日志
|
|
|
```
|
|
|
|
|
|
**需求追溯**:
|
|
|
|
|
|
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|
|
|
|------------|----------|----------|----------|----------|
|
|
|
| MP-AT-06 | 考勤审核 | 02-小程序端 §5 | 补录打卡记录 | 操作日志、考勤管理(Web端) |
|
|
|
|
|
|
#### 交互流程要求
|
|
|
|
|
|
1. **页面加载流程**:页面加载时获取待审核申诉列表→显示骨架屏→渲染筛选条件和申诉列表
|
|
|
2. **查询/筛选交互流程**:状态/日期/人员筛选→切换筛选重新加载列表;下拉刷新
|
|
|
3. **表单填写与提交流程**:查看申诉详情→点击通过→系统自动补录打卡记录;点击驳回→填写驳回原因→确认驳回→通知员工
|
|
|
4. **弹窗/弹层交互流程**:点击通过弹出确认弹窗"确认通过申诉?";点击驳回弹出驳回原因输入弹窗
|
|
|
5. **行内操作流程**:点击通过→确认→补录生效;点击驳回→填写原因→确认→通知员工
|
|
|
6. **异常与错误处理**:审核操作失败显示重试;申诉已处理提示"该申诉已处理"
|
|
|
7. **联动/级联交互**:审核通过后自动补录打卡记录,标记is_supplement=true
|
|
|
8. **权限控制交互表现**:仅主管可操作;无attendance:appeal:approve权限时按钮置灰
|
|
|
|
|
|
#### 前端硬性约束
|
|
|
|
|
|
- **H1 防重复提交**:通过/驳回按钮点击后立即 `loading=true` + `disabled=true` 防止重复操作;使用 pending 请求去重机制(审核请求未返回前禁用按钮);筛选切换时防重复请求
|
|
|
- **H2 超时控制**:GET 请求超时 15s、POST 请求超时 30s;列表加载/审核操作 >3s 时调用 `wx.showLoading({ title: '处理中...', mask: true })`
|
|
|
- **H3 二次确认**:审核通过前必须调用 `wx.showModal({ title: '确认通过', content: '确认通过该申诉?通过后系统将自动补录打卡记录。', confirmText: '通过', cancelText: '取消' })`;驳回前必须调用 `wx.showModal({ title: '确认驳回', content: '确认驳回该申诉?驳回后将通知员工重新处理。', confirmText: '驳回', cancelText: '取消' })`
|
|
|
- **H4 脏数据检测**:驳回原因输入框维护 isDirty 状态;用户输入驳回原因但未提交就离开时,在 `onUnload` / `onBackPress` 中弹出提示
|
|
|
- **H7 文件上传**:无上传操作
|
|
|
- **H8 操作反馈**:审核通过成功调用 `wx.showToast({ title: '已通过,已自动补录打卡记录', icon: 'success' })`;审核驳回成功调用 `wx.showToast({ title: '已驳回', icon: 'success' })`;网络异常时调用 `wx.showToast({ title: '网络异常,请检查网络后重试', icon: 'none' })` 并提供重试按钮
|
|
|
- **通用约束**:使用 uni-ui 组件库;所有可点击元素触控区域 ≥44px;通过/驳回按钮 ≥44px;下拉刷新需防重复触发(refreshing 标志位)
|
|
|
|
|
|
#### 组件规范
|
|
|
|
|
|
| 元素 | 组件 | 配置参数 |
|
|
|
|------|------|----------|
|
|
|
| 筛选条件 | `uni-data-select` | 状态/日期/人员三个选择器 |
|
|
|
| 申诉列表 | `uni-list` + `uni-list-item` | clickable=true |
|
|
|
| 审核状态标签 | `uni-tag` | type: warning(待审核)/success(已通过)/error(已驳回) |
|
|
|
| 通过按钮 | `button` | type="primary",size="mini",@click="approve" |
|
|
|
| 驳回按钮 | `button` | type="warn",size="mini",@click="reject" |
|
|
|
| 驳回原因弹窗 | `uni-popup` | type="bottom",含文本输入和确认按钮 |
|
|
|
| 驳回原因输入 | `uni-easyinput` | type="textarea",maxlength="200" |
|
|
|
| 确认弹窗 | `uni-popup` | type="dialog" |
|
|
|
| 下拉刷新 | `uni-refresher` | @onRefresh回调 |
|
|
|
|
|
|
#### 校验规则
|
|
|
|
|
|
| 字段 | 规则 | 错误提示 |
|
|
|
|------|------|----------|
|
|
|
| 驳回原因 | 驳回时必填 | "请填写驳回原因" |
|
|
|
| 驳回原因 | 最多200字 | "驳回原因不能超过200字" |
|
|
|
| 审核状态 | 须为待审核状态 | "该申诉已处理" |
|
|
|
|
|
|
#### 响应式布局
|
|
|
|
|
|
- **适配机型**:iPhone SE(375px)~ iPad mini(768px),列表宽度自适应
|
|
|
- **横竖屏适配策略**:竖屏单列卡片;横屏双列卡片+底部弹窗更宽
|
|
|
- **手势交互规范**:申诉项可点击区域≥44px;通过/驳回按钮≥44px
|
|
|
- **安全区域**:底部操作区域适配底部安全区
|
|
|
|
|
|
---
|
|
|
|
|
|
## 业务规则
|
|
|
|
|
|
1. **蓝牙策略**:考勤打卡受蓝牙策略控制(`GET /system/bluetooth-policy → attendance_check`)
|
|
|
2. **蓝牙强制打卡**:策略=REQUIRED时,必须在指定打卡点连接蓝牙Beacon后才可打卡
|
|
|
- 验证Beacon属于本人班组打卡点
|
|
|
- 打卡成功记录 `check_method=BLUETOOTH` + Beacon标识
|
|
|
3. **非强制蓝牙**:策略=OPTIONAL时,可选蓝牙打卡或手动打卡(`check_method=MANUAL`)
|
|
|
4. **打卡点验证**:蓝牙打卡时验证Beacon属于本人班组绑定的打卡点
|
|
|
5. **打卡时间**:自动记录精确到秒
|
|
|
6. **异常申诉审核**:主管在Web端或小程序端均可审核
|
|
|
7. **补录标记**:审核通过后系统自动补录打卡记录,标记 `is_supplement=true`
|
|
|
8. **操作日志**:所有打卡操作记录审计日志
|
|
|
9. **双端审批**:打卡异常申诉支持Web+小程序双端审核
|
|
|
|
|
|
## 状态流转
|
|
|
|
|
|
### 打卡状态
|
|
|
|
|
|
```
|
|
|
未打卡 → 已打卡(正常/迟到/早退)
|
|
|
↓
|
|
|
缺卡 → 异常申诉 → 审核通过 → 补录打卡(标记补录)
|
|
|
→ 审核驳回 → 保持缺卡
|
|
|
```
|
|
|
|
|
|
### 申诉审核状态
|
|
|
|
|
|
```
|
|
|
待审核 → 审核通过 → 系统补录打卡记录
|
|
|
→ 审核驳回 → 通知员工
|
|
|
```
|