# 企业内部工具系统 - 实现计划 ## 项目概述 开发一个企业内部工具系统平台,以出差审批为首个功能模块,后续可持续扩展新功能。系统主要支持移动 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. **飞书集成测试**:验证飞书免登和消息推送