Files

357 lines
8.5 KiB
Markdown
Raw Permalink Normal View History

# X-Server Mobile 企业工具系统
## 项目概述
一个基于飞书的企业内部H5移动工具平台,采用多租户架构,支持审批流程引擎和多种业务应用。
**技术栈:**
- 前端:React 18 + TypeScript + Vite + Ant Design Mobile
- 后端:PHP 8.5 + Webman 2.x + MySQL + Redis
- 部署:Docker + OpenResty + frpc (开发环境)
**支持语言:**
- 🇨🇳 简体中文 (zh)
- 🇬🇧 English (en)
- 🇷🇺 Русский (ru)
- 🇪🇸 Español (es)
- 🇫🇷 Français (fr)
## 国际化 (i18n)
### 前端国际化
**位置:** `frontend/src/i18n/`
**使用方式:**
```tsx
import { useTranslation } from 'react-i18next'
function MyComponent() {
const { t } = useTranslation()
return <div>{t('common.confirm')}</div>
}
```
**切换语言:**
```tsx
import { showLanguageSwitcher } from '@/components/LanguageSwitcher'
// 显示语言选择弹窗
showLanguageSwitcher()
```
**语言存储:** 浏览器 localStorage,键名为 `i18nextLng`
### 后端国际化
**位置:** `backend/lang/`
**使用方式:**
```php
use App\Util\Lang;
// 获取翻译
$message = Lang::get('common.confirm');
// 带参数的翻译
$message = Lang::get('approval.status', ['status' => 'pending']);
// 检查翻译是否存在
if (Lang::has('common.submit')) {
// ...
}
```
**设置语言:**
```php
// 从请求检测语言
$locale = Lang::detectFromRequest();
Lang::setLocale($locale);
```
## 项目关键特性
### 1. 多租户架构
- 用户全局唯一,关联多个公司
- 租户切换功能
- 公司级数据隔离
### 2. 审批流程引擎
**支持节点类型:**
- 单人审批 (single_approve)
- 会签 (and_sign) - 所有人通过
- 或签 (or_sign) - 任一人通过
- 通知节点 (notify)
**审批状态:**
- pending: 待审批
- approved: 已通过
- rejected: 已拒绝
- cancelled: 已撤销
**关键文件:**
- `backend/app/Service/ApprovalService.php` - 审批核心逻辑
- `backend/app/Model/ApprovalOrder.php` - 审批单模型
- `frontend/src/modules/approval/` - 前端审批模块
### 3. 飞书集成
**飞书免登:**
- 回调地址:`/api/v1/auth/feishu-login`
- 配置项:
- `FEISHU_APP_ID` - 飞书应用 ID
- `FEISHU_APP_SECRET` - 飞书应用密钥
- `FEISHU_ENCRYPT_KEY` - 加密密钥
- `FEISHU_VERIFICATION_TOKEN` - 验证令牌
### 4. 数据库设计
**核心表:**
- `users` - 用户表(全局唯一)
- `companies` - 公司表
- `user_company` - 用户公司关联表
- `approval_flows` - 审批流程定义
- `approval_nodes` - 审批节点
- `approval_orders` - 审批单
- `approval_records` - 审批记录
- `business_trips` - 出差申请
- `business_trip_items` - 出差明细
## 目录结构
```
x-server-mobile/
├── frontend/ # React 前端
│ ├── src/
│ │ ├── i18n/ # 国际化配置
│ │ │ ├── locales/ # 翻译文件
│ │ │ └── index.ts
│ │ ├── components/ # 通用组件
│ │ │ ├── layout/ # 布局组件
│ │ │ └── LanguageSwitcher/
│ │ ├── modules/ # 业务模块
│ │ │ └── approval/ # 审批模块
│ │ ├── pages/ # 页面组件
│ │ ├── stores/ # 状态管理
│ │ ├── router/ # 路由配置
│ │ └── utils/ # 工具函数
│ └── package.json
├── backend/ # PHP 后端
│ ├── app/
│ │ ├── Controller/ # 控制器
│ │ ├── Model/ # 数据模型
│ │ ├── Service/ # 业务逻辑
│ │ ├── Util/ # 工具类
│ │ │ ├── Lang.php # 国际化工具
│ │ │ └── Db.php # 数据库连接
│ │ └── Middleware/ # 中间件
│ ├── config/ # 配置文件
│ ├── lang/ # 语言文件
│ ├── database/migrations/ # 数据库迁移
│ ├── composer.json
│ └── Dockerfile
├── docker-compose.yml # Docker 编排
├── nginx/ # OpenResty 配置
├── frpc/ # frpc 配置
└── IMPLEMENTATION_PLAN.md # 实现计划
```
## 开发环境设置
### 端口分配
| 服务 | 端口 |
|------|------|
| Frontend (Vite) | 5173 |
| Backend (Webman) | 8787 |
| OpenResty | 8080 |
| MySQL | 3306 |
| Redis | 6379 |
### 环境变量
**前端 (frontend/.env):**
```env
VITE_API_BASE_URL=http://localhost:8787/api/v1
```
**后端 (backend/.env):**
```env
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=x_server_mobile
DB_USERNAME=root
DB_PASSWORD=mysql_xEsdPa
REDIS_HOST=redis
REDIS_PORT=6379
APP_DEBUG=true
# 飞书配置
FEISHU_APP_ID=cli_xxxxxxxxxxxxx
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx
FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx
```
### 反向代理配置(开发环境)
**frpc 配置:** `frpc/frpc-dev.ini`
```ini
[common]
server_addr = your-frp-server.com
server_port = 7000
token = your-frp-token
[x-server-api-dev]
type = http
local_ip = 127.0.0.1
local_port = 8080
custom_domains = api-dev.x-server.your-domain.com
```
**OpenResty 配置:** `nginx/x-server-api.conf`
```nginx
server {
listen 8080;
server_name api.x-server.local;
location /api/ {
proxy_pass http://127.0.0.1:8787/api/;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Tenant-Key';
}
}
```
## API 接口
### 认证接口
- `POST /api/v1/auth/login` - 用户名密码登录
- `POST /api/v1/auth/feishu-login` - 飞书免登
### 用户接口
- `GET /api/v1/user/info` - 获取用户信息
- `GET /api/v1/user/menu` - 获取用户菜单
- `GET /api/v1/user/companies` - 获取公司列表
- `POST /api/v1/user/switch-company` - 切换公司
### 审批接口
- `GET /api/v1/approval/list` - 审批列表
- `GET /api/v1/approval/detail/{id}` - 审批详情
- `POST /api/v1/approval/submit` - 提交审批
- `POST /api/v1/approval/approve/{id}` - 审批通过
- `POST /api/v1/approval/reject/{id}` - 审批拒绝
- `POST /api/v1/approval/cancel/{id}` - 撤销申请
### 出差接口
- `GET /api/v1/business-trip/list` - 出差列表
- `GET /api/v1/business-trip/detail/{id}` - 出差详情
- `POST /api/v1/business-trip/apply` - 申请出差
- `PUT /api/v1/business-trip/{id}` - 更新申请
## 开发指南
### 前端开发
```bash
cd frontend
npm install # 安装依赖
npm run dev # 启动开发服务器
npm run build # 构建生产版本
```
### 后端开发
```bash
cd backend
composer install # 安装依赖
php start.php start # 启动 Webman
php start.php stop # 停止 Webman
```
### Docker 开发
```bash
# 启动所有服务
docker compose up -d
# 仅启动后端
docker compose up -d backend
# 查看日志
docker logs x-server-backend -f
# 重启服务
docker compose restart backend
```
## 常见问题
### Q: 如何添加新的翻译文本?
**前端:** 在 `frontend/src/i18n/locales/` 对应语言的 JSON 文件中添加
```json
{
"myModule": {
"myKey": "翻译文本"
}
}
```
**后端:** 在 `backend/lang/` 对应语言的 PHP 文件中添加
```php
return [
'myModule' => [
'myKey' => '翻译文本',
],
];
```
### Q: 如何添加新的应用模块?
1. 在 `frontend/src/pages/` 创建新页面
2. 在 `frontend/src/router/index.tsx` 添加路由
3. 在 `backend/app/Controller/` 创建控制器
4. 在 `backend/config/route.php` 添加 API 路由
### Q: 数据库连接失败怎么办?
1. 检查 MySQL 容器是否运行:`docker ps | grep mysql`
2. 检查数据库配置:`backend/.env`
3. 检查网络连接:`docker network ls | grep 1panel-network`
### Q: 前端页面白屏?
1. 检查浏览器控制台错误
2. 检查 React 版本:确保是 18.3.1
3. 检查路由配置
4. 尝试清除缓存:`rm -rf frontend/node_modules/.vite`
## 安全建议
1. **生产环境务必使用 HTTPS**
2. **定期更新依赖包**
3. **配置防火墙规则**
4. **使用强密码**
5. **定期备份数据库**
6. **不要在代码中硬编码敏感信息**
## 更新日志
### 2024-02-24
- ✅ 升级 PHP 到 8.5
- ✅ 添加 5 语言国际化支持
- ✅ 配置 Docker 开发环境
- ✅ 实现审批流程引擎基础框架
- ✅ 完成前端基础页面和路由