DIP1 生产环境外部服务集成指南¶
文档编号:DOC-D01-EXT
版本:V1.0
创建日期:2026-08-11
最后更新:2026-08-11
目标读者:TL(技术负责人)/ 运维人员
前置要求:DIP1 后端服务已部署运行
概述¶
本文档提供 DIP1 生产环境所需外部服务的完整集成指南,包括:
- Cloudflare R2 - 对象存储服务(图片、附件等)
- WhatsApp Business API - OTP 验证码发送
- 前端三端部署 - OPR 管理后台 / WKR 师傅端 / CST 客户端
每项集成均包含: - ✅ 前置条件检查 - ✅ 逐步操作指令(可复制粘贴) - ✅ 验证方法 - ✅ 常见问题排查
第一部分:Cloudflare R2 存储服务集成¶
1.1 前置条件¶
| 条件 | 说明 | 验证方式 |
|---|---|---|
| Cloudflare 账号 | 免费版即可 | 访问 https://dash.cloudflare.com |
| 已创建 R2 Bucket | 存储桶名称需与配置一致 | R2 Dashboard 查看 |
| Access Key | 用于 API 认证 | 创建 API Token 获取 |
1.2 操作步骤¶
步骤 1:登录 Cloudflare Dashboard¶
- 访问 https://dash.cloudflare.com
- 使用邮箱密码登录
步骤 2:创建 R2 Bucket¶
- 左侧菜单点击 R2
- 点击 Create bucket 创建存储桶
- 填写信息:
- Bucket name:
dip1-assets-prod(生产环境)或dip1-assets-staging(测试环境) - Region: 选择最近区域(自动选择)
- 点击 Create bucket 确认
步骤 3:获取 Access Key¶
- 进入 R2 → Settings → API
- 点击 Create API token
- 选择权限:
- Permission: Object Read & Write
- TTL: 选择有效期(建议 30 天或自定义)
- 创建后请立即保存以下信息:
- Access Key ID(保存,仅显示一次)
- Secret Access Key(保存,仅显示一次)
步骤 4:获取 Account ID¶
- 点击 Cloudflare 首页
- 在 URL 中找到 Account ID(格式:
https://dash.cloudflare.com/?to=/:account/r2) - 或在 Overview 页面底部找到 Account ID
步骤 5:配置公开访问域名(可选)¶
- 进入 Bucket → Settings → Public access
- 启用 Custom Domains 或使用默认
pub-bucket.r2.dev域名 - 记录公开访问 URL(如
https://assets.weavely.hk)
1.3 配置环境变量¶
编辑 .env.prod.local 文件,填写以下配置:
# Cloudflare R2 配置
# 从 Cloudflare Dashboard 获取这些值
R2_ACCOUNT_ID=<你的AccountID> # Example: abc123def456
R2_ACCESS_KEY_ID=<你的AccessKeyID> # Example: ABCDEF123456
R2_SECRET_ACCESS_KEY=<你的SecretAccessKey> # Example: abc123def456...
R2_BUCKET=dip1-assets-prod # 与步骤 2 一致
R2_PUBLIC_URL=https://assets.weavely.hk # 你的公开访问域名
1.4 部署生效¶
# 重新构建并启动 API 服务
cd dip1
docker compose -f docker-compose.prod.yml --env-file .env.prod.local up -d --build
1.5 验证集成¶
方法 1:API 测试¶
# 调用上传接口(需先登录获取 token)
# 1. 获取 token
curl -X POST "http://localhost:8000/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"user_id":"你的管理员账号","password":"密码"}'
# 2. 使用 token 上传文件
curl -X POST "http://localhost:8000/api/v1/files/upload" \
-H "Authorization: Bearer <token>" \
-F "file=@test.jpg"
方法 2:代码测试¶
# 在 API 容器内运行测试
docker exec -it dip1-api-1 python -c "
from app.infrastructure.storage import get_r2_client
r2 = get_r2_client()
# 测试上传
result = r2.upload_file(
key='test/hello.txt',
file_bytes=b'Hello DIP1!',
content_type='text/plain'
)
print('上传成功:', result)
# 测试下载
content = r2.download_file('test/hello.txt')
print('下载内容:', content)
# 测试删除
r2.delete_file('test/hello.txt')
print('删除成功')
"
方法 3:检查 Cloudflare Dashboard¶
- 访问 https://dash.cloudflare.com/?to=/:account/r2
- 选择
dip1-assets-prodbucket - 查看 Files 列表确认文件已上传
1.6 常见问题¶
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 403 Access Denied | Access Key 权限不足 | 检查 Key 权限是否包含 Object Write |
| 404 Bucket Not Found | Bucket 名称错误 | 核对 R2_BUCKET 变量 |
| 签名验证失败 | 时间戳偏差 | 同步服务器时间 |
| 超时无响应 | 网络问题 | 检查防火墙和代理设置 |
第二部分:WhatsApp Business API 集成¶
2.1 前置条件¶
| 条件 | 说明 | 验证方式 |
|---|---|---|
| Meta Business 账号 | 免费注册 | https://business.facebook.com |
| WhatsApp Business API 访问权限 | 需要申请 | Meta for Developers 后台 |
| 已验证的手机号 | 用于发送 OTP | 完成号码验证流程 |
| 模板审核通过 | OTP 模板需 Meta 审核 | 在 WhatsApp Manager 查看 |
2.2 操作步骤¶
步骤 1:创建 Meta 开发者账号¶
- 访问 https://developers.facebook.com
- 使用 Facebook 账号登录(如无则新建)
- 完成安全验证(手机号验证)
步骤 2:创建 Business 账号¶
- 访问 https://business.facebook.com
- 点击 Create Business Account
- 填写业务信息:
- Business name: 织布鸟智居科技有限公司
- Business email: t***@weavely.hk
- Business phone: +852XXXXXXX
- 完成验证(邮箱/手机号)
步骤 3:申请 WhatsApp API 访问¶
- 访问 https://developers.facebook.com/apps
- 创建新 App:
- 选择 Business 类型
- 填写 App 名称:
weavely-dip1 - 在 App Dashboard 左侧菜单找到 Add Products → WhatsApp
- 点击 Set up 开始配置
步骤 4:配置 WhatsApp 产品¶
- 选择 WhatsApp Business Platform
- 创建新的产品实例
- 添加手机号:
- 点击 Add phone number
- 填写准备用于业务的手机号(需海外号码,如香港号码)
- 完成短信验证
- 记录以下信息:
- Phone Number ID(格式:
123456789012345) - WABA ID(可选)
步骤 5:创建 Access Token¶
- 在 App Dashboard → Settings → Basic
- 找到 App Secret 并保存
- 生成 Access Token:
- 访问 https://developers.facebook.com/tools/explorer
- 选择你的 App 和 Page
- 生成 Access Token(需包含
whatsapp_business_messaging权限) - 重要:Access Token 有效期 60 天,需定期刷新
步骤 6:创建 OTP 模板¶
- 进入 App → WhatsApp → Manager
- 点击 Template → Create template
- 创建模板:
- Template name:
otp_login - Category: 选择 Authentication 或 Utility
- Language: English(或添加中文支持)
- Body:
Your verification code is {{1}}. Do not share this code. - 变量
{{1}}对应 OTP 验证码 - 提交审核(通常 1-2 个工作日)
- 审核通过后模板即可使用
步骤 7:配置环境变量¶
编辑 .env.prod.local 文件:
# WhatsApp Business API 配置
# 从 Meta Developer Portal 获取
WHATSAPP_ACCESS_TOKEN=<你的Access Token> # 从 Graph API Explorer 生成
WHATSAPP_PHONE_NUMBER_ID=<你的Phone Number ID> # 从 WhatsApp Manager 获取
WHATSAPP_API_VERSION=v18.0 # 最新稳定版本
2.3 部署生效¶
# 重新构建并启动 API 服务
cd dip1
docker compose -f docker-compose.prod.yml --env-file .env.prod.local up -d --build
2.4 验证集成¶
方法 1:Mock 模式测试(开发阶段)¶
# 在未配置真实凭据时,系统自动使用 Mock 模式
# 发送 OTP 请求
curl -X POST "http://localhost:8000/api/v1/auth/otp/send?phone=+85292230009&purpose=login"
# 查看容器日志,会显示 Mock 的验证码
docker logs dip1-api-1 --tail 20
# 输出示例: [MOCK WHATSAPP] OTP sent to 85292230009: 123456
方法 2:真实 API 测试¶
# 配置好真实凭据后,发送 OTP 请求
curl -X POST "http://localhost:8000/api/v1/auth/otp/send?phone=+8529XXXXXXXX&purpose=login"
# 检查响应
# 成功: {"status":"sent","message_id":"..."
# 失败: {"status":"error","error":"错误信息"}
方法 3:代码测试¶
# 在 API 容器内运行测试
docker exec -it dip1-api-1 python -c "
import asyncio
from app.infrastructure.otp import get_otp_provider
async def test():
provider = get_otp_provider()
# 发送 OTP
result = await provider.send_otp_code(
phone_number='+85292230009',
otp_code='123456'
)
print('发送结果:', result)
# 如果是 Mock 模式,会返回验证码
if hasattr(provider, 'otp_code'):
print('验证码:', result.get('otp_code'))
asyncio.run(test())
"
2.5 Access Token 刷新¶
Token 有效期:60 天
刷新方法:
1. 手动刷新:
- 访问 https://developers.facebook.com/tools/explorer
- 重新生成 Access Token
- 更新 .env.prod.local 中的 WHATSAPP_ACCESS_TOKEN
- 自动刷新(建议长期运行时实现):
- 可实现定时任务,在 Token 过期前 7 天自动刷新
- 或监控 API 返回的错误码,触发刷新流程
2.6 常见问题¶
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 401 Invalid Token | Token 过期或无效 | 重新生成 Token |
| 404 Not Found | Phone Number ID 错误 | 核对 WHATSAPP_PHONE_NUMBER_ID |
| 400 Template Not Found | 模板名称错误或未审核 | 检查模板名称和审核状态 |
| 消息未送达 | 号码格式错误 | 使用 E.164 格式(国家代码+号码) |
| 频率限制 | 发送过于频繁 | 遵守 OTP_RATE_LIMIT_PER_HOUR 设置 |
第三部分:前端三端部署¶
3.1 整体架构¶
┌─────────────────────────────────────────────────────────────┐
│ DIP1 前端三端部署 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ OPR-Admin(运营后台) │ │
│ │ ├── 技术栈: Next.js 14 + React + Tailwind CSS │ │
│ │ ├── 部署方式: Docker 容器 / Vercel / Cloudflare │ │
│ │ ├── 域名: admin.weavely.hk │ │
│ │ └── 用户: OL(运营) / TL(技术) / BO(业务) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ WKR-App(师傅端) │ │
│ │ ├── 技术栈: React Native + Expo + NativeWind │ │
│ │ ├── 部署方式: EAS Build → App Store / Google Play │ │
│ │ ├── 域名: wkr.weavely.hk (API) │ │
│ │ └── 用户: FL(师傅) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ CST-App(客户端) │ │
│ │ ├── 技术栈: React Native + Expo + NativeWind │ │
│ │ ├── 部署方式: EAS Build → App Store / Google Play │ │
│ │ ├── 域名: cst.weavely.hk (API) │ │
│ │ └── 用户: Customer(客户) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
3.2 环境依赖检查¶
通用依赖¶
| 工具 | 版本要求 | 安装命令 | 验证命令 |
|---|---|---|---|
| Node.js | >= 20 LTS | fnm install 20 或官网下载 |
node --version |
| pnpm | >= 9.x | corepack enable && corepack prepare pnpm@latest --activate |
pnpm --version |
| Git | >= 2.x | 官网下载 | git --version |
| Docker Desktop | >= 4.x | 官网下载 | docker --version |
OPR-Admin 额外依赖¶
| 工具 | 版本要求 | 说明 |
|---|---|---|
| Nginx | >= 1.24 | 可选,用于 Docker 部署反向代理 |
| SSL 证书 | Let's Encrypt / Cloudflare | HTTPS 必需 |
WKR/CST Mobile 额外依赖¶
| 工具 | 版本要求 | 安装命令 | 说明 |
|---|---|---|---|
| Expo CLI | >= 0.18.x | npm i -g expo-cli |
React Native 开发工具 |
| EAS CLI | >= 13.x | npm i -g eas-cli |
Expo 云端构建 |
| Xcode | >= 15.4 | Mac App Store | iOS 构建(仅 macOS) |
| Android Studio | Hedgehog+ | 官网下载 | Android 模拟器 |
| Apple Developer | $99/年 | 注册账号 | App Store 发布 |
| Google Play Console | $25 一次性 | 注册账号 | Google Play 发布 |
3.3 OPR-Admin 部署¶
方式 A:Docker 部署(推荐)¶
步骤 1:进入前端目录
cd dip1/frontend/apps/opr-admin
步骤 2:创建生产配置
创建 .env.production 文件:
# API 配置
NEXT_PUBLIC_API_URL=https://api.weavely.hk/api/v1
# 应用配置
NEXT_PUBLIC_APP_NAME=织布鸟运营后台
NEXT_PUBLIC_ENV=production
# 其他配置...
步骤 3:构建 Docker 镜像
# 在 opr-admin 目录创建 Dockerfile
cat > Dockerfile << 'EOF'
# 构建阶段
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
# 运行阶段
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
PORT=3000
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/next.config.mjs ./
EXPOSE 3000
CMD ["node", "node_modules/.bin/next", "start"]
EOF
步骤 4:构建并运行
# 构建镜像
docker build -t weavely/opr-admin:latest .
# 运行容器
docker run -d \
--name opr-admin \
-p 3000:3000 \
-e NEXT_PUBLIC_API_URL=https://api.weavely.hk/api/v1 \
weavely/opr-admin:latest
步骤 5:配置 Nginx 反向代理(可选)
# /etc/nginx/conf.d/opr-admin.conf
server {
listen 443 ssl http2;
server_name admin.weavely.hk;
ssl_certificate /etc/ssl/certs/admin.weavely.hk.pem;
ssl_certificate_key /etc/ssl/private/admin.weavely.hk.key;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
方式 B:Vercel 部署(更简单)¶
步骤 1:登录 Vercel
# 安装 Vercel CLI
npm i -g vercel
# 登录
vercel login
步骤 2:部署
cd dip1/frontend/apps/opr-admin
# 首次部署
vercel
# 配置环境变量后重新部署
vercel --prod
步骤 3:绑定域名
- 访问 https://vercel.com/dashboard
- 选择项目 → Settings → Domains
- 添加域名
admin.weavely.hk - 在 Cloudflare DNS 添加 CNAME 记录
步骤 4:配置环境变量
- Vercel Dashboard → Project → Settings → Environment Variables
- 添加:
NEXT_PUBLIC_API_URL=https://api.weavely.hk/api/v1
3.4 WKR-App 师傅端部署¶
前置条件¶
- Apple Developer 账号(iOS 发布)
- Google Play Console 账号(Android 发布)
- Expo EAS 账号
- 已配置 Google Services / Apple Sign In(如需要)
步骤 1:配置 EAS¶
# 进入师傅端目录
cd dip1/frontend/apps/wkr-app
# 登录 Expo
expo login
# 输入 Expo 账号凭据
# 配置 EAS 项目
eas build:configure
步骤 2:配置 eas.json¶
{
"cli": {
"version": ">= 13.0.0"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"env": {
"API_URL": "https://api.weavely.hk/api/v1"
}
},
"preview": {
"distribution": "internal",
"android": {
"buildType": "apk"
},
"ios": {
"simulator": true
},
"env": {
"API_URL": "https://api.weavely.hk/api/v1"
}
},
"production": {
"android": {
"buildType": "app-bundle"
},
"ios": {
"buildConfiguration": "Release"
},
"env": {
"API_URL": "https://api.weavely.hk/api/v1"
}
}
},
"submit": {
"production": {
"android": {
"serviceAccountKeyPath": "./google-services.json",
"track": "internal"
},
"ios": {
"appleId": "your-team-id@weavely.hk",
"ascAppId": "1234567890",
"appleTeamId": "YOUR_TEAM_ID"
}
}
}
}
步骤 3:构建 Android APK(内部测试)¶
# 构建 preview 版本(APK 格式,可直接安装)
eas build --platform android --profile preview
# 等待构建完成,下载 APK 文件
# 扫描二维码或点击下载链接获取 APK
步骤 4:构建 iOS IPA(内部测试)¶
# 构建 preview 版本
eas build --platform ios --profile preview
# 注意:iOS 构建需要 Apple 开发者账号配置
# 在 Apple Developer 添加测试设备 UDID
步骤 5:发布到 App Store / Google Play¶
# 1. 构建生产版本
eas build --platform all --profile production
# 2. 提交到商店
# Google Play
eas submit --platform android --profile production
# App Store
eas submit --platform ios --profile production
3.5 CST-App 客户端部署¶
步骤与 WKR-App 相同¶
# 进入客户端目录
cd dip1/frontend/apps/cst-app
# 配置 EAS
eas build:configure
# 构建 Android
eas build --platform android --profile preview
# 构建 iOS
eas build --platform ios --profile preview
# 发布
eas submit --platform all --profile production
3.6 部署验证清单¶
OPR-Admin 验证¶
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| 页面加载 | 访问 https://admin.weavely.hk | 页面正常显示 |
| 登录功能 | 使用管理员账号登录 | 登录成功跳转首页 |
| API 连通 | 打开浏览器 DevTools 查看网络请求 | API 返回 200 |
| 样式正常 | 检查所有页面样式 | 无错位、无破损 |
WKR-App 验证¶
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| App 安装 | 在师傅手机安装 APK/IPA | App 正常安装 |
| 登录功能 | 使用师傅账号登录 | 登录成功显示订单列表 |
| 接单功能 | 师傅点击接单 | 状态变更为"进行中" |
| 打卡功能 | L6 阶段打卡 | 上传照片成功 |
| 完成功能 | L8 阶段完成 | 订单状态变更为"已完成" |
CST-App 验证¶
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| App 安装 | 在客户手机安装 APK/IPA | App 正常安装 |
| 注册功能 | 新客户手机号注册 | OTP 验证后注册成功 |
| 登录功能 | 使用客户账号登录 | 登录成功显示订单列表 |
| 询价功能 | 选择服务提交询价 | 询价单提交成功 |
| 查看订单 | 查看订单状态更新 | 实时显示师傅位置 |
| 评分功能 | 完成后评分 | 评分提交成功 |
3.7 常见问题¶
| 问题 | 原因 | 解决方案 |
|---|---|---|
| OPR-Admin 空白页 | API URL 配置错误 | 检查 NEXT_PUBLIC_API_URL |
| WKR/CST 无法登录 | API 域名不可达 | 检查 HTTPS 证书和 DNS |
| Expo 构建失败 | 依赖版本冲突 | 清理缓存后重试:expo doctor --fix |
| Google Play 提交失败 | 签名证书过期 | 生成新签名证书 |
| App Store 提交被拒 | 审核不符合规则 | 查看审核反馈并修改 |
附录¶
A. 完整环境变量清单¶
# ====== 基础配置 ======
ENV=prod
TZ=Asia/Hong_Kong
APP_VERSION=2.0.0
APP_SECRET_KEY=<强密钥>
# ====== CORS ======
CORS_ORIGINS=["https://admin.weavely.hk","https://wkr.weavely.hk","https://cst.weavely.hk"]
# ====== 数据库 ======
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db
DB_POOL_SIZE=20
DB_MAX_OVERFLOW=40
# ====== Redis ======
REDIS_URL=redis://host:6379/0
# ====== Cloudflare R2 ======
R2_ACCOUNT_ID=<account_id>
R2_ACCESS_KEY_ID=<access_key>
R2_SECRET_ACCESS_KEY=<secret_key>
R2_BUCKET=dip1-assets-prod
R2_PUBLIC_URL=https://assets.weavely.hk
# ====== WhatsApp Business API ======
WHATSAPP_ACCESS_TOKEN=<access_token>
WHATSAPP_PHONE_NUMBER_ID=<phone_number_id>
WHATSAPP_API_VERSION=v18.0
# ====== JWT 配置 ======
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_TTL_MIN=15
JWT_REFRESH_TOKEN_TTL_DAY=30
# ====== OTP 配置 ======
OTP_TTL_SECONDS=300
OTP_RATE_LIMIT_PER_HOUR=5
# ====== Expo/EAS ======
EXPO_USERNAME=weavely-dip1
EXPO_PROJECT_ID_WKR=<wkr_project_id>
EXPO_PROJECT_ID_CST=<cst_project_id>
# ====== 推送服务 ======
EXPO_PUSH_AUTH_TOKEN=<push_token>
# ====== 可观测性 ======
SENTRY_DSN=<sentry_dsn>
LOG_LEVEL=WARNING
B. 快速部署命令汇总¶
# 1. 克隆并配置
git clone <repo>/dip1.git
cd dip1
cp .env.prod.local .env.prod
# 编辑 .env.prod 填入真实凭据
# 2. 启动后端
docker compose -f docker-compose.prod.yml --env-file .env.prod up -d --build
# 3. 数据库迁移
docker exec dip1-api-1 alembic upgrade head
# 4. 种子数据
docker exec dip1-api-1 python -m app.infrastructure.db.seed.cli
# 5. 验证健康检查
curl http://localhost:8000/health
# 6. 部署 OPR-Admin(Docker)
cd frontend/apps/opr-admin
docker build -t weavely/opr-admin .
docker run -d -p 3000:3000 weavely/opr-admin
# 7. 构建 WKR-App
cd frontend/apps/wkr-app
eas build --platform android --profile preview
# 8. 构建 CST-App
cd frontend/apps/cst-app
eas build --platform android --profile preview
C. 文档索引¶
| 文档 | 路径 | 说明 |
|---|---|---|
| DIP1-ARC 架构设计 | docs/DIP1-ARC-架构设计.md |
系统架构、ADR 决策 |
| DIP1-P3 技术基础设施 | docs/DIP1-P3-技术基础设施.md |
开发环境、CI/CD |
| DIP1-OPS 管理员手册 | docs/DIP1-OPS-生产环境管理员操作手册.md |
运维操作指南 |
| DIP1-IMP 实施指南 | docs/DIP1-IMP-Code-Agent实施指南.md |
项目计划 |
修订记录¶
| 版本 | 日期 | 修订人 | 修订内容 |
|---|---|---|---|
| V1.0 | 2026-08-11 | DT | 初始版本,集成 R2/WhatsApp/前端三端部署 |
本指南为 DIP1 生产环境外部服务集成文档,由听写 DT 维护。
如有疑问请联系 TL 或 DT 获取技术支持。