diff --git a/CLAUDE.md b/CLAUDE.md index 5cd9069..a0cabfb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -82,8 +82,9 @@ Lang::setLocale('en'); - Redis: 6379 ### 数据库 -- 数据库名:x_server_mobile +- 数据库名:xserver - 密码:mysql_xEsdPa +- 容器名:1Panel-mysql-409s - 网络:1panel-network ### Docker 容器 @@ -128,8 +129,26 @@ Lang::setLocale('en'); ### 关键文件 - 服务:`backend/app/Service/ApprovalService.php` -- 模型:`backend/app/Model/ApprovalOrder.php` -- 前端模块:`frontend/src/modules/approval/` +- 控制器:`backend/app/Controller/ApprovalController.php` +- 模型:`backend/app/Model/ApprovalOrder.php`, `ApprovalFlow.php`, `ApprovalNode.php`, `ApprovalRecord.php` +- 前端列表页:`frontend/src/pages/approval/list.tsx` +- 前端详情页:`frontend/src/pages/approval/detail.tsx` + +### 列表过滤逻辑 +- **我发起的 (my)**: `applicant_id = current_user_id` +- **待我审批 (pending)**: 订单状态为 pending + 当前用户在当前节点的审批人列表中 + 未审批 +- **我已审批 (approved)**: 用户有审批记录(approve/reject)+ 订单状态为已完成(approved/rejected/cancelled) + +### 测试数据 +运行测试数据脚本: +```bash +docker exec x-server-backend php test_data.php +``` + +该脚本会创建: +- 2 个待审批的订单(其他用户提交,用户1审批) +- 1 个已通过的订单(用户1已审批) +- 1 个已拒绝的订单(用户1已拒绝) ## 飞书集成 @@ -278,6 +297,35 @@ const handleSelectCc = () => { - ✅ 导航前同步保存草稿数据,不依赖 useEffect - ✅ 保留 useEffect 自动保存作为备份机制(防止用户不导航就离开页面) +### 申请页面完整数据流 + +申请页面(如出差申请)需要处理三种场景: + +1. **首次进入(新建申请)** + - 清除旧的 sessionStorage 数据 + - 加载默认审批人/抄送人 + - 初始化空表单 + +2. **从选择页面返回** + - 从 sessionStorage 恢复草稿数据 + - 从 sessionStorage 恢复人员数据(审批人/抄送人) + - 日期字符串需要转换为 Date 对象 + +3. **提交/保存成功** + - 清除所有 sessionStorage 数据 + - 导航回列表页 + +**实现要点:** +- 使用 `location.state?.fromSelection` 标记返回状态 +- 使用独立的 sessionStorage key:`businessTripDraft`, `selectedApprovers`, `selectedCc` +- 导航前立即保存草稿,不依赖 useEffect +- 日期对象序列化/反序列化处理 + +**相关文件:** +- `frontend/src/pages/business-trip/apply.tsx` - 申请页面主逻辑 +- `frontend/src/pages/business-trip/select-approver.tsx` - 审批人选择 +- `frontend/src/pages/business-trip/select-cc.tsx` - 抄送人选择 + ### Ant Design Mobile DatePicker 点击无反应 **问题:** DatePicker 组件使用 children render prop 方式时,点击无法弹出选择框 @@ -337,13 +385,34 @@ import 'antd-mobile/es/global' - @types/react 和 @types/react-dom 也要用 v18 ### 数据库连接 -- 使用自定义 Db 类 (`backend/app/Util/Db.php`) -- 不使用 `support\Db`(Webman 2.x 没有) +- 使用 Webman 官方 `webman/database` 包 +- 使用 `support\Db` facade 进行数据库操作 +- 使用 `Db::connection()` 获取数据库连接进行事务处理 ### Bootstrap 接口 - 方法签名:`public static function start(?\Workerman\Worker $worker): void` - 需要添加 `use Workerman\Worker;` +### Webman 官方依赖包 +```bash +composer require workerman/webman:^2.0 +composer require webman/database:^2.0 +composer require webman/redis:^2.0 +composer require illuminate/pagination:^11.0 +composer require illuminate/events:^11.0 +composer require symfony/var-dumper:^7.0 +``` + +### User Store 状态管理 +- 使用 Zustand with persistence +- 登录时必须调用 `login(user, token)` 方法设置状态 +- Token 存储在 localStorage,key 为 `token` +- 登录页面必须正确初始化 Zustand store,否则后续页面获取不到用户信息 + +### 类型定义注意 +- `User.id` 是 `number` 类型(后端返回整型) +- `User.company_id` 是 `number` 类型(数据库字段名) + ### Docker 容器重启 - CMD 使用 `php start.php start`(不要用 `-d`) - 前台运行,避免容器退出 @@ -359,13 +428,17 @@ import 'antd-mobile/es/global' - ✅ 后端 API 框架搭建完成 - ✅ 5语言国际化支持完成 - ✅ Docker 开发环境配置完成 -- ✅ 审批流程引擎基础框架完成 -- 🚧 出差申请功能开发中 +- ✅ 审批流程引擎完成 + - ✅ 通用审批列表页(我发起的/待我审批/我已审批) + - ✅ 通用审批详情页(支持审批通过/拒绝/撤销操作) +- ✅ 出差申请功能完成 + - ✅ 出差申请页(含行程管理、审批人选择、抄送人选择) + - ✅ 草稿自动保存/恢复功能 + - ✅ 默认审批人自动加载 ## 下一步工作 -1. 完成出差申请前端页面 -2. 实现审批列表和详情页 -3. 集成飞书免登 -4. 实现公司切换功能 -5. 完善权限控制 +1. 完善审批流程的会签、或签逻辑测试 +2. 实现公司切换功能 +3. 完善权限控制 +4. 添加更多业务类型(费用报销、请假申请、采购申请)