d37d82bc13
- 更新环境对比表,增加测试环境 - 添加 Git 分支模型说明 - 更新文档引用链接
11 KiB
11 KiB
X-Server Mobile 项目文档
项目概述
这是一个基于飞书的企业内部H5移动工具平台,采用多租户架构,支持审批流程引擎。
关键特性:
- 支持5种语言:中文、英文、俄语、西语、法语
- 多租户架构(用户全局唯一,关联多个公司)
- 审批流程引擎(单人审批、会签、或签、通知)
- 飞书免登集成
技术栈:
- 前端:React 18.3.1 + TypeScript + Vite + Ant Design Mobile
- 后端:PHP 8.5 + Webman 2.x + MySQL + Redis
- 部署:Docker
国际化 (i18n) - 重要!
前端
- 配置:
frontend/src/i18n/ - 翻译文件:
frontend/src/i18n/locales/{zh,en,ru,es,fr}.json - 语言切换:
- 首页右上角国旗按钮
- 个人中心 -> 语言设置
- 存储位置:localStorage
i18nextLng
使用方式:
import { useTranslation } from 'react-i18next'
const { t } = useTranslation()
<div>{t('common.confirm')}</div>
后端
- 翻译文件:
backend/lang/{zh,en,ru,es,fr}.php - 工具类:
backend/app/Util/Lang.php
使用方式:
use App\Util\Lang;
$message = Lang::get('common.confirm');
Lang::setLocale('en');
目录结构
/www/x-server-mobile/
├── frontend/ # React 前端 (运行在 5173)
│ ├── src/
│ │ ├── i18n/ # 国际化配置
│ │ ├── components/ # 组件
│ │ ├── pages/ # 页面
│ │ ├── modules/ # 业务模块 (approval等)
│ │ └── router/ # 路由
│ └── package.json
├── backend/ # PHP 后端 (运行在 8787)
│ ├── app/
│ │ ├── Controller/ # 控制器 (PascalCase命名)
│ │ ├── Model/ # 模型 (PascalCase命名)
│ │ ├── Service/ # 服务层
│ │ ├── Util/ # 工具类
│ │ └── Middleware/ # 中间件
│ ├── config/ # 配置
│ ├── lang/ # 语言文件
│ └── composer.json
├── docker-compose.yml # Docker 编排
├── nginx/ # OpenResty 配置
├── frpc/ # frpc 配置
├── docs/ # 项目文档
│ ├── PROJECT.md # 项目详细文档
│ ├── ENVIRONMENT.md # 环境配置说明(开发/生产对比)
│ ├── FEISHU_LOGIN_EXPERIENCE.md # 飞书登录实现经验(重要)
│ ├── feishu-qrcode-login.md # 飞书扫码登录原始文档
│ ├── PROJECT_ISSUES.md # 历史问题汇总
│ ├── GIT_WORKFLOW.md # Git 工作流程
│ └── IMPLEMENTATION_PLAN.md # 实现计划
环境配置
端口
- Frontend (Vite): 5173
- Backend (Webman): 8787
- OpenResty: 8080
- MySQL: 3306
- Redis: 6379
数据库
- 数据库名:xserver
- 密码:mysql_xEsdPa
- 容器名:1Panel-mysql-409s
- 网络:1panel-network
Docker 容器
- 后端容器:x-server-backend
- 使用 Dockerfile:
backend/Dockerfile - PHP 版本:8.5
关键文件路径
前端关键文件
- 入口:
frontend/src/main.tsx - SDK 引入:
frontend/index.html(飞书 H5 JSSDK + QR SDK) - 路由:
frontend/src/router/index.tsx - 布局:
frontend/src/components/layout/ - 状态管理:
frontend/src/stores/ - API 封装:
frontend/src/services/api.ts(含 401 token 刷新) - 登录页:
frontend/src/pages/login/index.tsx - 扫码登录:
frontend/src/pages/login/QRCodeLogin.tsx - 环境检测:
frontend/src/pages/feishu-env-test.tsx - rem 适配:
frontend/src/utils/rem.ts
后端关键文件
- 入口:
backend/start.php - 路由:
backend/config/route.php - 数据库配置:
backend/config/database.php - Redis 配置:
backend/config/redis.php - 容器配置:
backend/config/container.php
重要配置文件
- Docker 编排:
docker-compose.yml - OpenResty 配置:
nginx/x-server-api.conf - frpc 配置:
frpc/frpc-dev.ini
审批流程引擎
节点类型
single_approve- 单人审批and_sign- 会签(所有人通过)or_sign- 或签(任一人通过)notify- 通知节点
状态
- pending: 待审批
- approved: 已通过
- rejected: 已拒绝
- cancelled: 已撤销
关键文件
- 服务:
backend/app/Service/ApprovalService.php - 控制器:
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)
测试数据
运行测试数据脚本:
docker exec x-server-backend php test_data.php
该脚本会创建:
- 2 个待审批的订单(其他用户提交,用户1审批)
- 1 个已通过的订单(用户1已审批)
- 1 个已拒绝的订单(用户1已拒绝)
飞书集成
登录方式
支持两种飞书登录方式:
| 方式 | 使用场景 | SDK |
|---|---|---|
| 飞书内免登 | 用户在飞书客户端内打开应用,自动登录 | H5 JSSDK (h5-js-sdk-1.5.19.js) |
| 飞书外扫码登录 | 用户在普通浏览器中打开,用飞书扫码登录 | QR SDK (LarkSSOSDKWebQRCode-1.0.3.js) |
核心接口
POST /api/v1/auth/feishu-login- 飞书免登/扫码登录GET /api/v1/auth/feishu-config?company=2- 获取公司飞书应用配置POST /api/v1/auth/qrcode-login- 生成扫码登录二维码GET /api/v1/auth/qrcode-login/status?session_id=xxx- 轮询扫码状态GET /login/callback- 飞书授权回调
URL 参数
| 参数 | 说明 | 示例 |
|---|---|---|
company |
公司ID(必需) | ?company=2 |
app_id |
飞书应用ID(可选) | ?app_id=cli_xxx |
redirect |
登录成功后跳转地址 | ?redirect=/dashboard |
Token 自动刷新
- API 返回 401 时,在飞书环境中自动调用免登刷新 token
- 刷新成功后自动重试原始请求,用户无感知
- 使用
_retry标记防止死循环
详细文档
飞书登录完整实现经验:docs/FEISHU_LOGIN_EXPERIENCE.md
环境变量
FEISHU_APP_ID=cli_xxxxxxxxxxxxx
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx
FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx
常用命令
前端
cd /www/x-server-mobile/frontend
npm install
npm run dev
npm run build
后端
cd /www/x-server-mobile/backend
composer install
php start.php start
php start.php stop
Docker
cd /www/x-server-mobile
docker compose up -d
docker compose restart backend
docker logs x-server-backend -f
反向代理配置(开发环境)
用户已有 frpc 和 OpenResty,配置用于调试飞书登录。
- OpenResty 监听 8080,代理到 8787
- frpc 将 8080 暴露到公网
- 飞书回调地址配置为公网域名
环境对比
| 项目 | 开发环境 | 测试环境 | 生产环境 |
|---|---|---|---|
| 分支 | feature/* |
develop |
master |
| 域名 | xsm.dev.hnxinyouhe.com |
待配置 | uniservice-mobile.hnxinyouhe.com |
| 服务器 | 本地 WSL2 | 待配置 | 45.153.130.80 |
| 调试模式 | APP_DEBUG=true |
APP_DEBUG=true |
APP_DEBUG=false |
详细说明: docs/ENVIRONMENT.md
Git 工作流程: docs/GIT_WORKFLOW.md
Webman 框架要点
PSR-4 自动加载
- 目录名必须是 PascalCase(Controller、Model、Service、Util)
数据库连接
- 使用 Webman 官方
webman/database包 - 使用
support\Dbfacade 进行数据库操作 - 使用
Db::connection()获取数据库连接进行事务处理
Bootstrap 接口
- 方法签名:
public static function start(?\Workerman\Worker $worker): void
官方依赖包
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
前端框架要点
React 版本
- 必须使用 React 18.3.1(不能用19)
- @types/react 和 @types/react-dom 也要用 v18
Ant Design Mobile
- 必须导入全局样式:
import 'antd-mobile/es/global' - DatePicker 使用
visible属性控制弹框显示
Zustand 状态管理
- 登录时必须调用
login(user, token)方法设置状态 - Token 存储在 localStorage,key 为
token
类型定义
User.id是number类型(后端返回整型)User.company_id是number类型(数据库字段名)
语言切换位置
- 首页 - 右上角显示当前语言国旗,点击切换
- 个人中心 -> 语言设置
当前开发状态
- ✅ 前端基础框架搭建完成
- ✅ 后端 API 框架搭建完成
- ✅ 5语言国际化支持完成
- ✅ Docker 开发环境配置完成
- ✅ 飞书登录完成
- ✅ 飞书内免登(静默授权)
- ✅ 飞书外扫码登录
- ✅ Token 过期自动刷新(飞书环境)
- ✅ 多租户支持(company 参数)
- ✅ 审批流程引擎完成
- ✅ 通用审批列表页(我发起的/待我审批/我已审批)
- ✅ 通用审批详情页(支持审批通过/拒绝/撤销操作)
- ✅ 出差申请功能完成
- ✅ 出差申请页(含行程管理、审批人选择、抄送人选择)
- ✅ 草稿自动保存/恢复功能
- ✅ 默认审批人自动加载
下一步工作
- 完善审批流程的会签、或签逻辑测试
- 实现公司切换功能
- 完善权限控制
- 添加更多业务类型(费用报销、请假申请、采购申请)
Git 分支模型
项目采用三分支模型:
master (生产)
↑
发布合并
↑
develop (开发集成)
↑
功能合并
↑
┌─┴─┬─┴─┬─┴─┐
feature/* (个人功能分支)
工作流程:
- 从
develop创建feature/xxx分支开发 - 完成后合并到
develop进行团队测试 - 测试通过后合并到
master发布
详细说明: docs/GIT_WORKFLOW.md
快速参考
查看问题汇总
所有历史问题已整理在 docs/PROJECT_ISSUES.md 文件中。
飞书登录文档
飞书登录完整实现经验和调试技巧:docs/FEISHU_LOGIN_EXPERIENCE.md
让 CLAUDE 加载问题文档
请参考 docs/PROJECT_ISSUES.md 中的问题汇总
请参考 docs/FEISHU_LOGIN_EXPERIENCE.md 中的飞书登录经验
调试后端
# 查看日志
docker logs x-server-backend -f --tail 50
# 重启后端
docker compose restart backend
# 复制文件到容器
docker cp host_file x-server-backend:/app/app/service/xxx.php
# 重载 workers(不重启整个服务)
docker exec x-server-backend php /app/webman reload
数据库操作
# 进入 MySQL 容器
docker exec -it 1Panel-mysql-409s mysql -uroot -pmysql_xEsdPa xserver
# 运行测试数据脚本
docker exec x-server-backend php /app/test_data.php