Files
x-server-mobile/CLAUDE.md
T
root d37d82bc13 docs: 更新 CLAUDE.md 添加 Git 分支模型说明
- 更新环境对比表,增加测试环境
- 添加 Git 分支模型说明
- 更新文档引用链接
2026-02-28 11:35:43 +08:00

11 KiB
Raw Blame History

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,配置用于调试飞书登录。

  1. OpenResty 监听 8080,代理到 8787
  2. frpc 将 8080 暴露到公网
  3. 飞书回调地址配置为公网域名

环境对比

项目 开发环境 测试环境 生产环境
分支 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\Db facade 进行数据库操作
  • 使用 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 类型(数据库字段名)

语言切换位置

  1. 首页 - 右上角显示当前语言国旗,点击切换
  2. 个人中心 -> 语言设置

当前开发状态

  • ✅ 前端基础框架搭建完成
  • ✅ 后端 API 框架搭建完成
  • ✅ 5语言国际化支持完成
  • ✅ Docker 开发环境配置完成
  • ✅ 飞书登录完成
    • ✅ 飞书内免登(静默授权)
    • ✅ 飞书外扫码登录
    • ✅ Token 过期自动刷新(飞书环境)
    • ✅ 多租户支持(company 参数)
  • ✅ 审批流程引擎完成
    • ✅ 通用审批列表页(我发起的/待我审批/我已审批)
    • ✅ 通用审批详情页(支持审批通过/拒绝/撤销操作)
  • ✅ 出差申请功能完成
    • ✅ 出差申请页(含行程管理、审批人选择、抄送人选择)
    • ✅ 草稿自动保存/恢复功能
    • ✅ 默认审批人自动加载

下一步工作

  1. 完善审批流程的会签、或签逻辑测试
  2. 实现公司切换功能
  3. 完善权限控制
  4. 添加更多业务类型(费用报销、请假申请、采购申请)

Git 分支模型

项目采用三分支模型:

master (生产)
  ↑
  发布合并
  ↑
develop (开发集成)
  ↑
  功能合并
  ↑
┌─┴─┬─┴─┬─┴─┐
feature/* (个人功能分支)

工作流程:

  1. 从 develop 创建 feature/xxx 分支开发
  2. 完成后合并到 develop 进行团队测试
  3. 测试通过后合并到 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