首次调用 API #
同事会平台开放 API 兼容 HTTP REST 风格的多端接入,5 类端(小程序 / 支付宝 / 鸿蒙 / App / 电脑网页)通过统一 base URL 访问。 公开端点无需鉴权,限流 60/60s/IP;管理端点需后台 Bearer Token。
1. Base URL
所有公开端点共享同一基址,按环境区分。
| PARAM | VALUE |
|---|---|
base_url REQUIRED string | 生产: https://www.xiaoniao.online测试: https://staging.xiaoniao.online |
api_prefix REQUIRED string | 所有平台 API 前缀: /api/v1(亦支持 /api 双前缀) |
content_type REQUIRED string | 所有请求 / 响应统一 JSON: application/json; charset=utf-8 |
version string | 本文档对应 API 版本: v1.0(基线稳定) |
1.1 三行代码(任选一种)
# 公开端点:GET 平台基础信息 curl -sS https://www.xiaoniao.online/api/v1/platform/settings # 期望响应:HTTP 200 + 标准信封
import requests res = requests.get('https://www.xiaoniao.online/api/v1/platform/settings') data = res.json()['data'] print(data['name'], data['supportEmail'])
// 浏览器 / Node 18+ const { data } = await fetch('https://www.xiaoniao.online/api/v1/platform/settings').then(r => r.json()); console.log(data.name, data.supportEmail);
2. 鉴权说明 #
Authorization 头不传亦可。
1. 后台登录
POST /api/v1/admin/login → 拿 access_token2.
Authorization: Bearer <token> 携带3. 鉴权声明由服务端统一校验(Access Token 有效期内有效,2 小时自动过期)
4. 完整管理端 API 见 管理后台 → 平台 API 库
3. 平台基础信息 #
平台级元数据(名称 / 客服 / 时区 / 版权 / SEO 等 9 字段)的统一读取入口。多端共用,任意客户端首次启动应缓存 5-10 分钟。
3.1 响应字段(9 字段 + 审计列)
| FIELD | TYPE | DESCRIPTION |
|---|---|---|
name REQUIRED | string | 平台名称(全局唯一) |
shortName | string | null | 平台简称(顶部 logo 旁文字) |
supportEmail | string | null | 客服邮箱(公开给所有端) |
supportPhone | string | null | 客服电话 |
defaultLanguage | enum: zh-CN / zh-TW / en | 新用户默认语言 |
defaultTimezone | string (IANA) | 默认时区,默认 Asia/Shanghai |
copyright | string | null | 版权信息(关于页脚) |
seoKeywords | string | null | SEO 关键字(逗号分隔) |
brandColorToken | string | 平台主色(设计令牌),默认 --sky-500 |
updatedBy | string | null | 最近更新人(仅管理端写入) |
updatedAt | iso8601 | 最近更新时间 |
3.2 多端调用示例
curl -sS https://www.xiaoniao.online/api/v1/platform/settings
import requests res = requests.get('https://www.xiaoniao.online/api/v1/platform/settings', timeout=5) data = res.json()['data'] print(f"平台:{data['name']}, 客服:{data['supportEmail']}")
// 浏览器 / Node 18+ SSR const r = await fetch('https://www.xiaoniao.online/api/v1/platform/settings'); const { data } = await r.json();
wx.request({
url: 'https://www.xiaoniao.online/api/v1/platform/settings',
method: 'GET',
success: (r) => { if (r.data.code === 0) wx.setStorageSync('pf', r.data.data); }
});
my.request({
url: 'https://www.xiaoniao.online/api/v1/platform/settings',
method: 'GET',
success: (r) => { if (r.data.code === 0) my.setStorageSync({ key: 'pf', data: r.data.data }); }
});
import { http } from '@kit.NetworkKit'; const req = http.createHttp(); const resp = await req.request('https://www.xiaoniao.online/api/v1/platform/settings', { method: http.RequestMethod.GET }); const body = JSON.parse(resp.result as string); req.destroy();
3.3 响应示例 实时同步中…
/api/v1/platform/settings(失败时展示静态示例){
"code": 0,
"message": "success",
"data": {
"id": 1,
"name": "同事会 · 多企业版",
"shortName": "同事会·多企业版",
"supportEmail": "support@xiaoniao.online",
"supportPhone": "400-800-2026",
"defaultLanguage": "zh-CN",
"defaultTimezone": "Asia/Shanghai",
"copyright": "© 2026 同事会平台",
"seoKeywords": null,
"brandColorToken": "--sky-500",
"updatedBy": "admin",
"updatedAt": "2026-08-21T17:11:47",
"createdAt": "2026-08-21T16:59:19"
}
}
4. 生成小程序码 #
「关于同事会」弹窗内显示,扫码直接进入小程序首页。基于微信 getUnlimitedQRCode,失败降级到普通 QR 码。
响应字段
| FIELD | TYPE | DESCRIPTION |
|---|---|---|
qrType | string | wxacode(微信小程序码) 或 qrcode(降级普通 QR) |
qrPngBase64 | string (data URL) | base64 编码 PNG,可直接 <img src="..."> 渲染 |
hint | string | UI 提示文案 |
curl -sS https://www.xiaoniao.online/api/v1/system/miniprogram-qrcode \
| python -m json.tool | head -5
5. 创建扫码登录 ticket #
电脑端生成二维码 → 微信/支付宝扫一扫 → 跳小程序授权 → 回调 ticket → 电脑端每 2s 轮询 scan-status 检测登录态。
GET /scan-ticket → 拿 ticket + 二维码 PNG → 用户扫码 → 小程序识别 ticket 并发起 scan-confirm 写入状态 → 电脑端 GET /scan-status/{ticket} 查到 status=confirmed 即跳后台。6. 轮询扫码状态 #
响应
{
"status": "pending", // pending / confirmed / expired
"token": "eyJ...", // confirmed 后才有
"user": { "id": 34, "name": "秦剑" }
}
7. 健康检查 #
curl -sS https://www.xiaoniao.online/health # → {"status":"ok","service":"tongshihui-python","version":"1.0.0"}
8. 错误码 #
| HTTP | code | 含义 | 处理建议 |
|---|---|---|---|
| 200 | 0 | 成功 | 取 data |
| 200 | 非 0 | 业务错误(如平台名称为空) | toast message,不重试 |
| 401 | — | 未携带/无效 token(管理端点) | 重新登录 |
| 403 | — | 权限不足 | 联系 superadmin |
| 429 | — | 限流命中 | 退避 60s 后重试 |
| 500 | — | 服务器内部错误 | 5min 内自动恢复 |
9. 限流 #
| 端点 | 维度 | 阈值 | 超出行为 |
|---|---|---|---|
公开 GET /api/v1/platform/settings | 客户端 IP | 60 / 60s | HTTP 429 |
小程序码 GET /api/v1/system/miniprogram-qrcode | 客户端 IP | 10 / 60s | HTTP 429 |
扫码 ticket GET /api/v1/system/scan-ticket | 客户端 IP | 30 / 60s | HTTP 429 |
扫码状态 GET /api/v1/system/scan-status/{ticket} | — | — | 反向代理层兜底 |
健康检查 GET /health | — | — | 反向代理层兜底 |
10. 铁律边界 #
- ❌ 在小程序里写
mysqldb.connect(...).query("SELECT * FROM platform_settings") - ❌ App 通过内网绕过 API 网关直连生产 MySQL
- ❌ 把数据库连接串写进客户端代码
- ❌ 用任何 ORM 直连
platform_settings表
/api/v1/... 前缀,便于网关白名单、限流、审计。
11. OAuth2 扫码授权登录(外部接入应用) #
外部系统(网页 / H5)可复用同事会主系统的登录认证能力,让用户用同事会小程序扫码完成授权登录,拿到仅限本应用域有效的 Bearer Token。类比微信一键授权,但 token 做了域隔离 + scope 最小化授权。
status=published),否则所有 OAuth 端点返回 403。
client_id 绑定),不能跨应用互用;② client_secret 真实值仅存服务器 .env,DB 仅存掩码;③ CORS 严禁 allow_origins=["*"],外部域名须登记进 allowed_origins 审核通过。
11.1 端到端流程
11.2 端点清单(公开,无需后台登录态)
11.3 获取登录二维码
curl -sS "https://www.xiaoniao.online/api/v1/oauth/scan-ticket?client_id=oauth_yxtss_cashier"
响应字段
| FIELD | TYPE | DESCRIPTION |
|---|---|---|
ticket | string | 扫码凭据(24 位 hex),绑定 client_id,5 分钟过期 |
qrType | string | wxacode(微信小程序码,太阳码)或 h5_webpage_fallback(降级普通二维码) |
qrPngBase64 | string (data URL) | 二维码 PNG,直接 <img src> 渲染 |
appName | string | 应用名称(小程序授权页展示) |
scopes | string[] | 应用登记的授权范围(如 workbench:view);由后台编辑应用勾选 scopes 保存时同步写入 module_auth(subject_type=oauth_client、只读授权),是 token 获得 scope 的唯一来源;未勾选则 token scope=[],调受保护接口返回 403 |
expireSeconds | int | 二维码有效期(300s) |
11.4 小程序扫码确认(回调主系统)
{
"openId": "oKn9p3...", // 小程序登录态 open_id
"client_id": "oauth_yxtss_cashier" // 须与 ticket 绑定一致,否则 400
}
403),随后签发域隔离 token(携带 client_id + iss + scope)。11.5 轮询拿 token(一次性消费)
curl -sS "https://www.xiaoniao.online/api/v1/oauth/scan-status/{ticket}"
{
"status": "confirmed",
"token": "eyJ...", // Bearer Token,2h 过期
"userId": 34,
"clientId": "oauth_yxtss_cashier"
}
11.6 Token 结构(域隔离 + scope)
{
"sub": "user:34",
"user_id": 34,
"open_id": "oKn9p3...",
"client_id": "oauth_yxtss_cashier", // 域隔离核心:token 仅限此应用
"iss": "https://www.xiaoniao.online", // 签发方
"aud": "admin",
"scope": ["workbench:view"], // 授权范围,由 module_auth 推导(后台勾选 scopes 保存即写入授权记录)
"role": "admin", "admin_role": "superadmin",
"jti": "...", "exp": 1234567890
}
| 声明 | 含义 | 校验 |
|---|---|---|
client_id | 绑定的外部应用 | 请求方 client_id 必须一致,否则 401 |
iss | 签发方 | 必须为 https://www.xiaoniao.online,否则 401 |
scope | 授权范围 | {module_key}:view|operate,缺所需 scope → 403 |
11.7 跨域 token 兑换
跨域跳转(应用 X → 应用 Y):应用 Y 拒收域 X 的 token(401),前端回主系统 POST /oauth/exchange 兑换域 Y 的 token。
curl -sS -X POST https://www.xiaoniao.online/api/v1/oauth/exchange \
-H "Authorization: Bearer <source_token>" \
-H "Content-Type: application/json" \
-d '{"target_client_id":"yxtss_report","scope":"report:view"}'
12. 跨域访问(CORS) #
外部应用网页用 fetch 调主系统 API 时受浏览器同源策略约束,须通过 CORS 放行。
| 项 | 策略 |
|---|---|
allow_origins | 静态白名单(xiaoniao.online / ai.yuexinghome.com)+ 动态:已审核通过(published)的 oauth 应用 allowed_origins,后台 60s 刷新缓存 |
allow_credentials | true(响应 Access-Control-Allow-Credentials: true) |
allow_methods / allow_headers | * / * |
* | 严禁 allow_origins=["*"](与 credentials 组合是致命漏洞) |
allowed_origins(如 https://cashier.yuexinghome.com);② 审核通过(published);③ 后台 60s 内自动合并进 CORS;④ 未登记域名请求无 CORS 头 → 浏览器拦截。CORS blocked 先确认域名已登记且 status=published,并等待 ≤60s 缓存刷新;仍不行联系 superadmin。13. 外部系统对接指南(代收款 YXTSS 示例) #
- 登记应用:业务研发中心 → 外部接入应用 → 新建,填
module_key=oauth_yxtss_cashier、allowed_origins=[https://cashier.yuexinghome.com]、redirect_uris(当前未启用——内网部署不支持服务端主动回调,采用前端轮询模型)、scopes=[workbench:view]。 - 审核:superadmin 点「批准」→
status=published。client_secret真实值服务端写入.env,DB 仅存掩码。 - 展示登录二维码:前端
GET /oauth/scan-ticket?client_id=oauth_yxtss_cashier→ 渲染qrPngBase64。 - 轮询 token:每 2s
GET /oauth/scan-status/{ticket},status=confirmed取token(一次性)。 - 调用 API:
Authorization: Bearer <token>调主系统业务接口;验证器自动做 client_id + iss + scope 校验。 - 跨域跳转:跳另一应用前先
POST /oauth/exchange兑换目标域 token。
// 1) 拿二维码 const { data } = await fetch(`/api/v1/oauth/scan-ticket?client_id=oauth_yxtss_cashier`).then(r => r.json()); document.querySelector('#qr').src = data.qrPngBase64; // 2) 轮询 const t = setInterval(async () => { const s = await fetch(`/api/v1/oauth/scan-status/${data.ticket}`).then(r => r.json()); if (s.data?.status === 'confirmed') { clearInterval(t); localStorage.setItem('oauth_token', s.data.token); } }, 2000);
14. 变更记录 #
| 版本 | 日期 | 概要 |
|---|---|---|
| v1.0 | 2026-08-21 | 首版发布。5 个公开端点 + 9 字段基础信息 API + 渲染样式 V1.0 |
| v1.1 | 2026-08-25 | 新增 OAuth2 扫码授权登录(6 端点 + token 域隔离 / scope)、跨域访问(CORS)动态白名单、外部系统对接指南(代收款 YXTSS 示例)三章节;与后端 P2–P5 实现对齐 |
同事会平台 · 标准 API 文档 v1.0 · 渲染样式 V1.0 · 2026-08-21
配套规范:平台设计令牌 · 治理标识:system_constants.doc_api_standard.render_version=v1.0