Files
x-server-mobile/docs/IMPLEMENTATION_PLAN.md
root 4ceb5eac7e chore: 重组项目文件结构,文档和部署文件归档
文件结构优化:
- docs/ 归档所有项目文档(PROJECT.md, PROJECT_ISSUES.md 等)
- deploy/ 归档所有部署相关文件(docker-compose.prod.yml, nginx 配置等)
- scripts/ 归档脚本文件(deploy.sh, rollback.sh)
- tests/ 归档测试文件(test_data.php)

更新引用路径:
- CLAUDE.md 更新文档路径引用
- 部署文档更新配置文件路径引用

清理文件:
- 移除非必要的测试文件(TestController, 测试脚本等)
- 移除重复/错误的目录

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 18:01:17 +08:00

602 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 企业内部工具系统 - 实现计划
## 项目概述
开发一个企业内部工具系统平台,以出差审批为首个功能模块,后续可持续扩展新功能。系统主要支持移动 H5,嵌入飞书应用中使用。
### 核心目标
- **H5 移动端优先**:专注于移动端体验,PC 端后期扩展
- 从工具台层面设计可扩展的页面结构
- **审批模块作为独立通用工具**:支持多样化审批场景,业务可复用
- 良好的飞书集成能力(多公司、多应用架构)
---
## 技术方案
### 技术架构
#### 前端技术栈(H5 移动端)
| 技术 | 用途 | 说明 |
|------|------|------|
| React 18 | 前端框架 | 配合 TypeScript |
| Ant Design Mobile | UI 组件库 | 移动端组件库 |
| Vant | 补充组件 | 必要时补充使用 |
| Vite | 构建工具 | 快速开发体验 |
| React Router | 路由管理 | 支持多页面应用 |
| Zustand / Jotai | 状态管理 | 轻量级方案 |
| React Query | 数据请求 | 服务端状态管理 |
| PostCSS + pxtorem | 移动端适配 | rem 转换 |
| VConsole | 调试工具 | 移动端调试 |
#### 后端技术栈
| 技术 | 用途 | 说明 |
|------|------|------|
| Webman | PHP 框架 | 高性能常驻内存框架 |
| MySQL | 数据库 | 关系型数据库 |
| Redis | 缓存 | 会话、缓存存储 |
| JWT | 认证 | Token 认证机制 |
### 多租户架构设计
**核心概念**:
- 系统**不按公司隔离用户**,用户全局唯一
- 用户关联所属公司,用于选择对应飞书应用配置
- 审批流程跨公司,只识别人员
- 飞书仅提供:系统入口 + 人员识别鉴权
**数据模型**:
```sql
-- 公司表(飞书应用配置)
CREATE TABLE company (
id BIGINT PRIMARY KEY,
name VARCHAR(100),
feishu_app_id VARCHAR(100),
feishu_app_secret VARCHAR(255),
feishu_tenant_key VARCHAR(100),
status TINYINT DEFAULT 1
);
-- 用户表(全局用户)
CREATE TABLE user (
id BIGINT PRIMARY KEY,
company_id BIGINT, -- 所属公司
feishu_user_id VARCHAR(100), -- 飞书用户ID
feishu_union_id VARCHAR(100),-- 飞书UnionID(跨应用唯一)
name VARCHAR(50),
email VARCHAR(100),
phone VARCHAR(20),
avatar VARCHAR(255),
status TINYINT DEFAULT 1
);
-- 用户与飞书应用关联(支持用户切换不同公司应用)
CREATE TABLE user_feishu_binding (
id BIGINT PRIMARY KEY,
user_id BIGINT,
company_id BIGINT,
feishu_open_id VARCHAR(100),
created_at TIMESTAMP
);
```
### 项目目录结构(前后端分离)
```
x-server-mobile/ # 项目根目录
├── frontend/ # 前端项目(React + Vite)
│ ├── src/
│ │ ├── components/ # 通用组件
│ │ │ ├── approval/ # 审批组件(可复用)
│ │ │ ├── layout/ # 布局组件
│ │ │ └── common/ # 通用组件
│ │ ├── pages/ # 页面
│ │ │ ├── dashboard/ # 工具台首页
│ │ │ ├── business-trip/ # 出差审批
│ │ │ └── profile/ # 个人中心
│ │ ├── hooks/ # 自定义 Hooks
│ │ ├── services/ # API 服务
│ │ ├── stores/ # 状态管理
│ │ ├── utils/ # 工具函数
│ │ ├── types/ # TypeScript 类型
│ │ └── config/ # 配置文件
│ ├── public/
│ ├── package.json
│ └── vite.config.ts
│
└── backend/ # 后端项目(Webman)
├── app/
│ ├── controller/
│ ├── model/
│ ├── service/
│ ├── middleware/
│ └── util/
├── config/
├── routes/
├── support/
├── composer.json
└── start.php
```
### 后端项目结构(Webman)
```
backend/
├── app/
│ ├── controller/
│ │ ├── ApprovalController.php # 审批控制器
│ │ ├── BusinessTripController.php # 出差审批控制器
│ │ ├── UserController.php # 用户控制器
│ │ ├── CompanyController.php # 公司管理控制器
│ │ └── BaseController.php # 基础控制器
│ ├── model/
│ │ ├── Approval.php # 审批模型
│ │ ├── ApprovalNode.php # 审批节点模型
│ │ ├── BusinessTrip.php # 出差模型
│ │ ├── User.php # 用户模型
│ │ ├── Company.php # 公司模型
│ │ └── UserFeishuBinding.php # 用户飞书绑定模型
│ ├── service/
│ │ ├── ApprovalService.php # 审批服务
│ │ ├── FeishuService.php # 飞书服务(多应用)
│ │ ├── FeishuAppManager.php # 飞书应用配置管理
│ │ ├── UserService.php # 用户服务
│ │ └── CompanyService.php # 公司服务
│ ├── middleware/
│ │ ├── AuthMiddleware.php # 认证中间件
│ │ ├── CompanyResolveMiddleware.php # 公司识别中间件
│ │ └── CorsMiddleware.php # 跨域中间件
│ └── util/
│ ├── JwtUtil.php # JWT工具
│ └── Response.php # 响应封装
├── config/
│ ├── route.php # 路由配置
│ ├── database.php # 数据库配置
│ ├── redis.php # Redis配置
│ └── feishu.php # 飞书应用配置模板
├── routes/
│ └── api.php # API路由定义
└── support/
└── Bootstrap.php # 启动文件
```
### API 接口设计
#### 通用 API 规范
```
基础URL: /api/v1
响应格式:
{
"code": 0, // 0表示成功
"message": "success",
"data": {}
}
```
#### 审批相关接口
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /approval/list | 获取审批列表 |
| GET | /approval/detail/:id | 获取审批详情 |
| POST | /approval/submit | 提交审批申请 |
| POST | /approval/approve/:id | 审批通过 |
| POST | /approval/reject/:id | 审批拒绝 |
| POST | /approval/cancel/:id | 撤销申请 |
| GET | /approval/flow/:type | 获取审批流程配置 |
#### 出差审批接口
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /business-trip/list | 获取出差列表 |
| GET | /business-trip/detail/:id | 获取出差详情 |
| POST | /business-trip/apply | 提交出差申请 |
| PUT | /business-trip/:id | 更新出差申请(草稿状态) |
#### 用户认证接口(多飞书应用)
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /auth/login | 用户登录 |
| POST | /auth/feishu-login | 飞书免登(自动识别公司应用) |
| GET | /user/info | 获取用户信息 |
| GET | /user/menu | 获取用户菜单权限 |
| GET | /user/companies | 获取用户可切换的公司列表 |
| POST | /user/switch-company | 切换当前公司 |
#### 飞书应用管理接口(管理端)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /admin/company/list | 获取公司列表 |
| POST | /admin/company/add | 添加公司飞书应用配置 |
| PUT | /admin/company/:id | 更新公司飞书配置 |
| DELETE | /admin/company/:id | 删除公司配置 |
---
## 功能模块设计
### 1. 工具台架构(Dashboard - H5 移动端)
**设计理念**:工具台作为统一入口,支持模块化扩展,专注于移动端体验
```
工具台首页(H5)
├── 顶部导航栏
│ ├── Logo + 系统名称
│ ├── 搜索框(全局搜索)
│ ├── 通知图标
│ └── 用户头像
├── 主内容区
│ ├── 待办事项卡片(横向滚动)
│ ├── 快捷入口(九宫格/宫格)
│ ├── 数据统计卡片
│ └── 最新动态列表
└── 底部导航栏(TabBar)
├── 首页
├── 应用(宫格展开所有工具)
├── 消息
└── 我的
```
**移动端适配要点**:
- 使用 TabBar 替代侧边栏(符合移动端习惯)
- 750px 设计稿 → rem 自适应转换
- 触摸手势支持(下拉刷新、上拉加载)
- 安全区域适配(刘海屏、底部横条)
**关键文件**:
- `src/pages/dashboard/index.tsx` - 工具台主页
- `src/components/layout/MobileLayout.tsx` - 移动端主布局
- `src/components/layout/TabBar.tsx` - 底部导航栏
- `src/components/layout/Header.tsx` - 顶部栏
### 2. 通用审批模块设计(独立工具)
**设计理念**:审批模块作为独立的通用工具,与具体业务解耦,支持多样化的审批场景
**核心特性**:
- ✅ 业务无关:不绑定特定业务表单和流程
- ✅ 流程灵活:支持单级、多级、会签、或签、抄送等任意组合
- ✅ 动态配置:审批流程可动态配置和调整
- ✅ 易于集成:任何业务都可快速接入审批模块
**核心数据模型**:
```typescript
// 审批流程节点类型
enum ApprovalNodeType {
APPROVER = 'approver', // 审批人(单人)
AND_APPROVE = 'and_approve', // 会签(需所有人通过)
OR_APPROVE = 'or_approve', // 或签(任一人通过)
NOTIFY = 'notify' // 抄送(通知用)
}
// 审批单状态
enum ApprovalStatus {
DRAFT = 'draft', // 草稿
PENDING = 'pending', // 审批中
APPROVED = 'approved', // 已通过
REJECTED = 'rejected', // 已拒绝
CANCELLED = 'cancelled' // 已撤销
}
// 审批流程配置(业务无关)
interface ApprovalFlow {
id: string;
businessType: string; // 业务类型标识(如:business-trip, purchase)
name: string;
nodes: ApprovalNode[]; // 流程节点
}
// 审批节点
interface ApprovalNode {
id: string;
type: ApprovalNodeType;
approvers: User[]; // 审批人列表
order: number; // 节点顺序
conditions?: any; // 条件判断(可选,用于条件分支)
}
// 审批单(业务通用)
interface ApprovalOrder {
id: string;
businessType: string; // 业务类型
businessId: string; // 业务单据ID
title: string; // 审批标题
applicant: User; // 申请人
status: ApprovalStatus;
currentNodes: string[]; // 当前待审批节点ID
flowId: string; // 使用的流程ID
formData: any; // 业务表单数据(JSON存储)
attachments: Attachment[]; // 附件
timeline: ApprovalTimeline[]; // 审批轨迹
}
```
**审批模块架构**:
```
src/modules/approval/ # 审批模块(独立)
├── components/ # UI组件
│ ├── ApprovalFlow.tsx # 流程可视化
│ ├── ApprovalDetail.tsx # 审批详情
│ ├── ApprovalList.tsx # 审批列表
│ └── ApprovalAction.tsx # 审批操作
├── hooks/ # 自定义Hooks
│ ├── useApprovalSubmit.ts # 提交审批
│ ├── useApprovalAction.ts # 审批操作
│ └── useApprovalList.ts # 获取列表
├── services/ # API服务
│ └── approval.ts
├── types/ # 类型定义
│ └── index.ts
└── utils/ # 工具函数
├── flowParser.ts # 流程解析
└── statusCalculator.ts # 状态计算
```
**业务接入示例(出差审批)**:
```typescript
// 业务模块只需要调用审批模块的Hook
import { useApprovalSubmit } from '@/modules/approval/hooks'
function BusinessTripApply() {
const { submitApproval } = useApprovalSubmit('business-trip')
const handleSubmit = async (formData: BusinessTripFormData) => {
// 1. 先保存业务数据
const businessTripId = await saveBusinessTrip(formData)
// 2. 提交审批(传入业务类型和业务ID)
await submitApproval({
businessId: businessTripId,
title: `出差申请 - ${formData.destination}`,
formData: formData,
flowType: 'default' // 使用的流程模板
})
}
}
```
### 3. 出差审批模块
**页面结构**:
```
出差审批
├── 申请列表页
│ ├── 我发起的
│ ├── 待我审批
│ ├── 我已审批
│ └── 抄送我的
├── 申请表单页
│ ├── 基本信息(出差事由、时间、地点)
│ ├── 行程明细
│ ├── 费用预算
│ └── 附件上传
└── 审批详情页
├── 表单内容展示
├── 流程进度可视化
├── 审批历史
└── 操作按钮
```
**关键文件**:
- `src/pages/business-trip/list.tsx` - 列表页
- `src/pages/business-trip/apply.tsx` - 申请表单
- `src/pages/business-trip/detail.tsx` - 详情页
- `src/pages/business-trip/types.ts` - 出差相关类型
### 4. 飞书集成(多应用架构)
**集成要点**:
#### 后端 - 多飞书应用管理
```php
// 飞书应用管理器
class FeishuAppManager
{
// 根据飞书租户Key获取公司配置
public function getCompanyByTenantKey(string $tenantKey): Company
{
// 从数据库查询对应的飞书应用配置
}
// 获取指定公司的飞书 access_token
public function getAccessToken(int $companyId): string
{
// 缓存 access_token,过期自动刷新
}
// 根据用户ID获取其所属公司的飞书配置
public function getUserFeishuConfig(int $userId): array
{
// 返回用户所属公司的飞书 AppID、AppSecret 等
}
}
```
#### 前端 - 飞书 SDK 封装
```typescript
// src/utils/feishu.ts
export const FeishuSDK = {
// 获取免登授权码
getAuthCode: () => { /* ... */ },
// 判断是否在飞书环境
isFeishuEnv: () => { /* ... */ },
// 获取当前租户信息(用于后端识别公司)
getTenantContext: () => {
// 从飞书容器获取 tenant_key 或其他标识
}
}
```
#### 飞书免登流程(多应用)
```
1. 用户在飞书中打开应用
2. 前端获取 auth_code 和 tenant_key
3. 调用后端 /auth/feishu-login
4. 后端根据 tenant_key 查询对应公司配置
5. 使用该公司的 AppSecret 换取用户信息
6. 生成 JWT Token(包含 user_id 和 company_id)
7. 返回登录信息
```
---
## 实施步骤
### 阶段一:项目初始化
**前端:**
1. 初始化 Vite + React + TypeScript 项目
2. 安装 Ant Design 及相关依赖
3. 配置路由、状态管理、请求库(axios + React Query)
4. 配置 Tailwind CSS
**后端:**
1. 安装 Webman 框架
2. 配置 MySQL、Redis 连接
3. 配置 JWT 认证
4. 设置 CORS 中间件
5. **创建多租户数据表(company, user, user_feishu_binding)**
### 阶段二:工具台框架(H5)
**前端:**
1. 实现 MobileLayout 移动端布局组件
2. 实现 TabBar 底部导航栏
3. 实现 Header 组件
4. 创建工具台首页 Dashboard(H5 适配)
5. 配置 rem 移动端适配
**后端:**
1. 实现 /auth/login 登录接口
2. **实现 /auth/feishu-login 飞书免登(多应用识别)**
3. 实现 /user/info 用户信息接口
4. 实现 /user/menu 菜单权限接口
5. **实现 FeishuAppManager 服务(多应用配置管理)**
6. **实现 CompanyResolveMiddleware 中间件**
### 阶段三:独立审批模块(通用工具)
**前端:**
1. 创建 `src/modules/approval/` 独立模块目录
2. 定义审批相关 TypeScript 类型(业务无关)
3. 实现 ApprovalFlow 流程可视化组件
4. 实现 ApprovalDetail 详情页(通用)
5. 实现 ApprovalList 列表页(通用)
6. 实现 ApprovalAction 操作组件
7. **封装审批 Hooks(useApprovalSubmit, useApprovalAction)**
8. **提供业务接入示例**
**后端:**
1. 设计审批流程数据表(approval_flow, approval_node)
2. 设计审批单数据表(approval_order, approval_record)
3. 实现审批服务层逻辑(单级、多级、会签、或签)
4. **确保业务无关性,通过 businessType + businessId 关联业务**
5. 实现审批相关 API 接口
### 阶段四:出差审批业务(作为审批模块的使用示例)
**前端:**
1. 创建出差申请表单页面
2. **调用审批模块的 useApprovalSubmit Hook**
3. 创建出差审批列表(复用审批模块组件)
4. 创建出差审批详情(复用审批模块组件 + 业务表单展示)
**后端:**
1. 设计出差数据表(business_trip, business_trip_itinerary)
2. 实现出差业务逻辑(与审批解耦)
3. 实现出差相关 API 接口
4. **配置出差审批的默认流程模板**
### 阶段五:飞书集成与 H5 适配(多应用架构)
**前端:**
1. 集成飞书 JSAPI SDK
2. 实现飞书免登逻辑(获取 tenant_key)
3. **H5 移动端样式优化**
4. **配置 pxtorem(750px 设计稿适配)**
5. **安全区域适配(刘海屏、底部横条)**
6. 集成 VConsole 调试工具
**后端:**
1. **实现 FeishuService(支持多应用配置)**
2. **实现飞书应用配置管理接口(增删改查)**
3. **实现用户切换公司功能**
4. **实现飞书消息推送(根据用户所属公司推送)**
---
## 待确认问题
1. **飞书应用配置**:是否有飞书应用的 App ID、App Secret?
2. **权限设计**:是否需要 RBAC 权限系统?
3. **数据 Mock**:开发阶段是否需要 Mock 数据?
4. **部署环境**:开发/测试/生产环境配置?
---
## 关键文件清单
### 前端核心文件(H5)
| 文件路径 | 说明 |
|---------|------|
| `src/App.tsx` | 应用入口 |
| `src/main.tsx` | React 挂载点 |
| `src/router/index.tsx` | 路由配置 |
| `src/components/layout/MobileLayout.tsx` | 移动端主布局 |
| `src/components/layout/TabBar.tsx` | 底部导航栏 |
| `src/components/layout/Header.tsx` | 顶部栏 |
| `src/pages/dashboard/index.tsx` | 工具台首页 |
| `src/modules/approval/` | **审批模块(独立)** |
| `src/pages/business-trip/` | 出差审批业务 |
| `src/services/api.ts` | API 基础配置 |
| `src/utils/feishu.ts` | 飞书 SDK 封装 |
| `src/config/rem.ts` | rem 转换配置 |
| `package.json` | 项目依赖 |
| `vite.config.ts` | Vite 配置 |
| `tsconfig.json` | TypeScript 配置 |
| `postcss.config.js` | PostCSS 配置(pxtorem) |
### 后端核心文件
| 文件路径 | 说明 |
|---------|------|
| `app/controller/BaseController.php` | 基础控制器 |
| `app/controller/ApprovalController.php` | 审批控制器 |
| `app/controller/BusinessTripController.php` | 出差审批控制器 |
| `app/controller/UserController.php` | 用户控制器 |
| `app/model/Approval.php` | 审批模型 |
| `app/model/ApprovalNode.php` | 审批节点模型 |
| `app/service/ApprovalService.php` | 审批服务 |
| `app/service/FeishuService.php` | 飞书服务 |
| `app/middleware/AuthMiddleware.php` | 认证中间件 |
| `config/route.php` | 路由配置 |
| `config/database.php` | 数据库配置 |
| `routes/api.php` | API 路由定义 |
---
## 验证计划
### 前端验证(H5)
1. **运行项目**:`npm run dev` 确保项目启动
2. **路由测试**:访问各个页面确保路由正常
3. **审批模块测试**:验证审批组件的通用性和可复用性
4. **H5 适配测试**:
- 测试不同屏幕尺寸(375px - 768px)
- 测试刘海屏和底部横条适配
- 测试触摸手势交互
5. **飞书环境测试**:
- 在飞书中测试免登
- 在飞书中测试 H5 适配
- 测试多公司应用切换
6. **真机测试**:在真实移动设备上测试
### 后端验证
1. **启动 Webman**:`php start.php start` 确保服务启动
2. **API 测试**:使用 Postman/Apifox 测试各接口
3. **数据库测试**:验证数据表创建和 CRUD 操作
4. **认证测试**:验证 JWT 认证流程
5. **多租户测试**:
- 测试多公司飞书应用配置
- 测试跨公司审批流程
6. **飞书集成测试**:验证飞书免登和消息推送