|
@@ -36,6 +36,155 @@
|
|
|
- **说明**:
|
|
- **说明**:
|
|
|
- 用户调用:仅允许 `type = MESSAGE`
|
|
- 用户调用:仅允许 `type = MESSAGE`
|
|
|
- 应用调用:支持 `MESSAGE` / `NOTIFICATION` / 广播
|
|
- 应用调用:支持 `MESSAGE` / `NOTIFICATION` / 广播
|
|
|
|
|
+ - **用户申请通知**:`type = MESSAGE` 且 `content_type = USER_NOTIFICATION`,在私信会话中以通知卡片样式展示(标题 + 结构化内容 + 操作按钮);需跳转业务页时配合 `app_id`、`auto_sso`、`target_url`(后端生成 `action_url`)
|
|
|
|
|
+
|
|
|
|
|
+#### 调用约定
|
|
|
|
|
+
|
|
|
|
|
+| 项目 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| **方法 / 路径** | `POST {{API_BASE_URL}}/messages/` |
|
|
|
|
|
+| **Content-Type** | `application/json` |
|
|
|
|
|
+| **用户调用** | `Authorization: Bearer <JWT_TOKEN>`;**仅允许** `type = MESSAGE`,禁止 `NOTIFICATION` |
|
|
|
|
|
+| **应用调用** | `X-App-Id`(字符串 app_id)、`X-Timestamp`(Unix 秒)、`X-Sign`;签名:`HMAC-SHA256(app_secret, 待签名字符串)`,待签名字符串为按键名字母序拼接的 `app_id=...×tamp=...`(不含 `sign` 本身) |
|
|
|
|
|
+
|
|
|
|
|
+#### 请求体字段(MessageCreate)
|
|
|
|
|
+
|
|
|
|
|
+| 字段 | 必填 | 说明 |
|
|
|
|
|
+|------|------|------|
|
|
|
|
|
+| `type` | 是 | `MESSAGE` / `NOTIFICATION` |
|
|
|
|
|
+| `title` | 是 | 标题,最长 255 |
|
|
|
|
|
+| `content` | 是 | 字符串或 JSON 对象(对象会序列化为 JSON 字符串落库) |
|
|
|
|
|
+| `content_type` | 否 | 默认 `TEXT`;`IMAGE` / `VIDEO` / `FILE` / `USER_NOTIFICATION` |
|
|
|
|
|
+| `receiver_id` | 条件 | 统一平台用户 ID;与 `app_id`+`app_user_id` 二选一(**广播时不要填**) |
|
|
|
|
|
+| `app_id` | 条件 | 应用字符串 ID;与 `app_user_id` 联用解析接收者;用户发 `USER_NOTIFICATION` 且 `auto_sso` 时需填 |
|
|
|
|
|
+| `app_user_id` | 条件 | 业务账号,须在映射表存在 |
|
|
|
|
|
+| `sender_app_user_id` | 否 | 应用发信时可选:发起人业务账号,解析后写入 `sender_id` 用于审计和会话聚合;用户 JWT 发信忽略 |
|
|
|
|
|
+| `is_broadcast` | 否 | `true` 时向全员发通知;**仅** `type = NOTIFICATION` + **应用签名**;勿填接收者 |
|
|
|
|
|
+| `auto_sso` | 否 | 与 `target_url` 配合;`NOTIFICATION` 或 `USER_NOTIFICATION` 时可自动生成 `action_url`(jump) |
|
|
|
|
|
+| `target_url` | 否 | 业务落地页 URL(`auto_sso = true` 时使用) |
|
|
|
|
|
+| `action_url` / `action_text` | 否 | 自定义按钮;接收端点击若走 `callback-url`,需为后端识别的 jump 格式 |
|
|
|
|
|
+
|
|
|
|
|
+**接收者规则(非广播)**:必须提供 `receiver_id`,**或**同时提供 `app_id` + `app_user_id`。
|
|
|
|
|
+**应用 + `app_user_id`**:Body 中的 `app_id` 必须与 `X-App-Id` 一致,否则 403。
|
|
|
|
|
+
|
|
|
|
|
+**常见错误**:`403`(无权限 / 类型不允许 / app_id 不匹配)、`404`(用户或映射不存在)、`422`(校验失败,如缺接收者)。
|
|
|
|
|
+
|
|
|
|
|
+#### 签名生成示例(Python)
|
|
|
|
|
+
|
|
|
|
|
+```python
|
|
|
|
|
+import hmac, hashlib, time
|
|
|
|
|
+
|
|
|
|
|
+app_id = "your_app_id_string"
|
|
|
|
|
+app_secret = "your_app_secret"
|
|
|
|
|
+timestamp = str(int(time.time()))
|
|
|
|
|
+query_string = f"app_id={app_id}×tamp={timestamp}"
|
|
|
|
|
+sign = hmac.new(
|
|
|
|
|
+ app_secret.encode("utf-8"),
|
|
|
|
|
+ query_string.encode("utf-8"),
|
|
|
|
|
+ hashlib.sha256,
|
|
|
|
|
+).hexdigest()
|
|
|
|
|
+# 请求头: X-App-Id, X-Timestamp, X-Sign=sign
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### Python 完整调用(requests)
|
|
|
|
|
+
|
|
|
|
|
+依赖:`pip install requests`。将 `API_BASE`、`APP_ID`、`APP_SECRET`、用户示例中的 `ACCESS_TOKEN` 换成实际值。
|
|
|
|
|
+
|
|
|
|
|
+```python
|
|
|
|
|
+import hmac
|
|
|
|
|
+import hashlib
|
|
|
|
|
+import time
|
|
|
|
|
+import requests
|
|
|
|
|
+
|
|
|
|
|
+API_BASE = "https://your-host.example.com/api/v1" # 无尾斜杠
|
|
|
|
|
+APP_ID = "your_app_id_string"
|
|
|
|
|
+APP_SECRET = "your_app_secret"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def app_sign_headers() -> dict:
|
|
|
|
|
+ ts = str(int(time.time()))
|
|
|
|
|
+ query_string = f"app_id={APP_ID}×tamp={ts}"
|
|
|
|
|
+ sign = hmac.new(
|
|
|
|
|
+ APP_SECRET.encode("utf-8"),
|
|
|
|
|
+ query_string.encode("utf-8"),
|
|
|
|
|
+ hashlib.sha256,
|
|
|
|
|
+ ).hexdigest()
|
|
|
|
|
+ return {
|
|
|
|
|
+ "X-App-Id": APP_ID,
|
|
|
|
|
+ "X-Timestamp": ts,
|
|
|
|
|
+ "X-Sign": sign,
|
|
|
|
|
+ "Content-Type": "application/json",
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def send_notification_by_app_user() -> dict:
|
|
|
|
|
+ """应用签名:按 app_user_id 发送通知"""
|
|
|
|
|
+ url = f"{API_BASE}/messages/"
|
|
|
|
|
+ payload = {
|
|
|
|
|
+ "app_id": APP_ID,
|
|
|
|
|
+ "app_user_id": "zhangsan_oa",
|
|
|
|
|
+ "type": "NOTIFICATION",
|
|
|
|
|
+ "content_type": "TEXT",
|
|
|
|
|
+ "title": "审批通知",
|
|
|
|
|
+ "content": "您有一条待审批任务",
|
|
|
|
|
+ "auto_sso": True,
|
|
|
|
|
+ "target_url": "https://biz.example.com/todo/123",
|
|
|
|
|
+ "action_text": "立即处理",
|
|
|
|
|
+ }
|
|
|
|
|
+ r = requests.post(url, headers=app_sign_headers(), json=payload, timeout=30)
|
|
|
|
|
+ r.raise_for_status()
|
|
|
|
|
+ return r.json()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def send_user_notification_by_app(app_user_id: str, sender_app_user_id: str = None) -> dict:
|
|
|
|
|
+ """应用发 USER_NOTIFICATION:代发起人通知接收者(如 OA 代张三通知李四)"""
|
|
|
|
|
+ url = f"{API_BASE}/messages/"
|
|
|
|
|
+ payload = {
|
|
|
|
|
+ "app_id": APP_ID,
|
|
|
|
|
+ "app_user_id": app_user_id,
|
|
|
|
|
+ "type": "MESSAGE",
|
|
|
|
|
+ "content_type": "USER_NOTIFICATION",
|
|
|
|
|
+ "title": "请假申请",
|
|
|
|
|
+ "content": {"applyType": "LEAVE", "days": 2, "businessId": 123},
|
|
|
|
|
+ "auto_sso": True,
|
|
|
|
|
+ "target_url": "https://biz.example.com/leave/123",
|
|
|
|
|
+ "action_text": "去审批",
|
|
|
|
|
+ }
|
|
|
|
|
+ if sender_app_user_id:
|
|
|
|
|
+ payload["sender_app_user_id"] = sender_app_user_id
|
|
|
|
|
+ r = requests.post(url, headers=app_sign_headers(), json=payload, timeout=30)
|
|
|
|
|
+ r.raise_for_status()
|
|
|
|
|
+ return r.json()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def send_user_notification(access_token: str) -> dict:
|
|
|
|
|
+ """用户 Bearer:发送 USER_NOTIFICATION(用户本人发,如重新提醒)"""
|
|
|
|
|
+ url = f"{API_BASE}/messages/"
|
|
|
|
|
+ headers = {
|
|
|
|
|
+ "Authorization": f"Bearer {access_token}",
|
|
|
|
|
+ "Content-Type": "application/json",
|
|
|
|
|
+ }
|
|
|
|
|
+ payload = {
|
|
|
|
|
+ "receiver_id": 2048,
|
|
|
|
|
+ "type": "MESSAGE",
|
|
|
|
|
+ "content_type": "USER_NOTIFICATION",
|
|
|
|
|
+ "app_id": "oa_system",
|
|
|
|
|
+ "title": "请假申请",
|
|
|
|
|
+ "content": {"applyType": "LEAVE", "days": 2, "businessId": 123},
|
|
|
|
|
+ "auto_sso": True,
|
|
|
|
|
+ "target_url": "https://biz.example.com/leave/123",
|
|
|
|
|
+ "action_text": "去审批",
|
|
|
|
|
+ }
|
|
|
|
|
+ r = requests.post(url, headers=headers, json=payload, timeout=30)
|
|
|
|
|
+ r.raise_for_status()
|
|
|
|
|
+ return r.json()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+if __name__ == "__main__":
|
|
|
|
|
+ print(send_notification_by_app_user())
|
|
|
|
|
+ # print(send_user_notification_by_app("lisi_manager", "zhangsan_oa"))
|
|
|
|
|
+ # print(send_user_notification("eyJhbGciOiJIUzI1NiIsInR5cCI6..."))
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
用户私信示例:
|
|
用户私信示例:
|
|
|
|
|
|
|
@@ -53,16 +202,127 @@ Content-Type: application/json
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-通知示例(应用签名场景):
|
|
|
|
|
|
|
+响应示例(MessageResponse):
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "id": 501,
|
|
|
|
|
+ "sender_id": 10001,
|
|
|
|
|
+ "receiver_id": 2048,
|
|
|
|
|
+ "app_id": null,
|
|
|
|
|
+ "app_name": null,
|
|
|
|
|
+ "type": "MESSAGE",
|
|
|
|
|
+ "content_type": "TEXT",
|
|
|
|
|
+ "title": "私信",
|
|
|
|
|
+ "content": "你好,这是一条私信",
|
|
|
|
|
+ "action_url": null,
|
|
|
|
|
+ "action_text": null,
|
|
|
|
|
+ "is_read": false,
|
|
|
|
|
+ "created_at": "2026-03-18T09:59:00",
|
|
|
|
|
+ "read_at": null
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+应用发 USER_NOTIFICATION 示例(应用签名,按 app_user_id 接收,可选 sender_app_user_id):
|
|
|
|
|
|
|
|
```http
|
|
```http
|
|
|
POST {{API_BASE_URL}}/messages/
|
|
POST {{API_BASE_URL}}/messages/
|
|
|
X-App-Id: your_app_id
|
|
X-App-Id: your_app_id
|
|
|
-X-Timestamp: 1700000000
|
|
|
|
|
-X-Sign: your_hmac_sign
|
|
|
|
|
|
|
+X-Timestamp: 1708848000
|
|
|
|
|
+X-Sign: <HMAC-SHA256>
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "app_id": "oa_system",
|
|
|
|
|
+ "app_user_id": "lisi_manager",
|
|
|
|
|
+ "sender_app_user_id": "zhangsan_oa",
|
|
|
|
|
+ "type": "MESSAGE",
|
|
|
|
|
+ "content_type": "USER_NOTIFICATION",
|
|
|
|
|
+ "title": "请假申请",
|
|
|
|
|
+ "content": {"applyType":"LEAVE","days":2,"businessId":123},
|
|
|
|
|
+ "auto_sso": true,
|
|
|
|
|
+ "target_url": "https://biz.example.com/leave/123",
|
|
|
|
|
+ "action_text": "去审批"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+用户发 USER_NOTIFICATION 示例(用户 Token,如重新提醒):
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST {{API_BASE_URL}}/messages/
|
|
|
|
|
+Authorization: Bearer xxx
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "receiver_id": 2048,
|
|
|
|
|
+ "type": "MESSAGE",
|
|
|
|
|
+ "content_type": "USER_NOTIFICATION",
|
|
|
|
|
+ "app_id": "oa_system",
|
|
|
|
|
+ "title": "请假申请",
|
|
|
|
|
+ "content": {"applyType":"LEAVE","days":2,"businessId":123},
|
|
|
|
|
+ "auto_sso": true,
|
|
|
|
|
+ "target_url": "https://biz.example.com/leave/123",
|
|
|
|
|
+ "action_text": "去审批"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+- **`content_type`**:`USER_NOTIFICATION`,用于在私信界面渲染通知样式(与 `type=NOTIFICATION` 的系统通知会话不同,仍归属与对方的私信会话)。
|
|
|
|
|
+- **`content`**:可为 JSON 对象;服务端序列化为 JSON 字符串;客户端可解析后逐项展示。
|
|
|
|
|
+- **`auto_sso` + `target_url` + `app_id`**:后端生成 `action_url`(jump 链接);接收者点击按钮时应调用 `GET {{API_BASE_URL}}/messages/{message_id}/callback-url` 获取带 ticket 的 `callback_url` 再打开。
|
|
|
|
|
+
|
|
|
|
|
+响应字段与普通私信一致,`content_type` 为 `USER_NOTIFICATION`,`action_url` / `action_text` 按请求生成。
|
|
|
|
|
+
|
|
|
|
|
+通知示例(应用签名 + 按 `app_user_id` 投递):
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST {{API_BASE_URL}}/messages/
|
|
|
|
|
+X-App-Id: your_app_id_string
|
|
|
|
|
+X-Timestamp: 1708848000
|
|
|
|
|
+X-Sign: <HMAC-SHA256 十六进制>
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "app_id": "your_app_id_string",
|
|
|
|
|
+ "app_user_id": "zhangsan_oa",
|
|
|
|
|
+ "type": "NOTIFICATION",
|
|
|
|
|
+ "content_type": "TEXT",
|
|
|
|
|
+ "title": "审批通知",
|
|
|
|
|
+ "content": "您有一条待审批任务",
|
|
|
|
|
+ "auto_sso": true,
|
|
|
|
|
+ "target_url": "https://biz.example.com/todo/123",
|
|
|
|
|
+ "action_text": "立即处理"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+广播示例(应用签名,全员 `NOTIFICATION`):
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST {{API_BASE_URL}}/messages/
|
|
|
|
|
+X-App-Id: your_app_id_string
|
|
|
|
|
+X-Timestamp: 1708848000
|
|
|
|
|
+X-Sign: <HMAC-SHA256 十六进制>
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "type": "NOTIFICATION",
|
|
|
|
|
+ "is_broadcast": true,
|
|
|
|
|
+ "content_type": "TEXT",
|
|
|
|
|
+ "title": "系统公告",
|
|
|
|
|
+ "content": "这是一条全员通知"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+通知示例(应用签名 + 已知平台 `receiver_id`):
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST {{API_BASE_URL}}/messages/
|
|
|
|
|
+X-App-Id: your_app_id_string
|
|
|
|
|
+X-Timestamp: 1708848000
|
|
|
|
|
+X-Sign: <HMAC-SHA256 十六进制>
|
|
|
Content-Type: application/json
|
|
Content-Type: application/json
|
|
|
|
|
|
|
|
{
|
|
{
|
|
|
|
|
+ "receiver_id": 2048,
|
|
|
"type": "NOTIFICATION",
|
|
"type": "NOTIFICATION",
|
|
|
"content_type": "TEXT",
|
|
"content_type": "TEXT",
|
|
|
"title": "审批通知",
|
|
"title": "审批通知",
|
|
@@ -73,6 +333,27 @@ Content-Type: application/json
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+响应示例(MessageResponse,与上例类似):
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "id": 10001,
|
|
|
|
|
+ "sender_id": null,
|
|
|
|
|
+ "receiver_id": 2048,
|
|
|
|
|
+ "app_id": 101,
|
|
|
|
|
+ "app_name": "OA系统",
|
|
|
|
|
+ "type": "NOTIFICATION",
|
|
|
|
|
+ "content_type": "TEXT",
|
|
|
|
|
+ "title": "审批通知",
|
|
|
|
|
+ "content": "您有一条待审批任务",
|
|
|
|
|
+ "action_url": "/api/v1/simple/sso/jump?app_id=oa_system&redirect_to=https%3A%2F%2Fbiz.example.com%2Ftodo%2F123",
|
|
|
|
|
+ "action_text": "立即处理",
|
|
|
|
|
+ "is_read": false,
|
|
|
|
|
+ "created_at": "2026-03-18T10:02:00",
|
|
|
|
|
+ "read_at": null
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
### 3.2 通知回调 URL
|
|
### 3.2 通知回调 URL
|
|
|
|
|
|
|
|
- **接口**:`GET {{API_BASE_URL}}/messages/{message_id}/callback-url`
|
|
- **接口**:`GET {{API_BASE_URL}}/messages/{message_id}/callback-url`
|
|
@@ -164,6 +445,36 @@ Authorization: Bearer <JWT_TOKEN>
|
|
|
- `other_user_id < 0`:按应用拆分的系统通知会话
|
|
- `other_user_id < 0`:按应用拆分的系统通知会话
|
|
|
- `other_user_id = 0`:兼容历史统一系统会话
|
|
- `other_user_id = 0`:兼容历史统一系统会话
|
|
|
|
|
|
|
|
|
|
+请求示例(私信):
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+GET {{API_BASE_URL}}/messages/history/2048?skip=0&limit=50 HTTP/1.1
|
|
|
|
|
+Authorization: Bearer <JWT_TOKEN>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+响应示例(MessageResponse 列表):
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+[
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": 501,
|
|
|
|
|
+ "sender_id": 10001,
|
|
|
|
|
+ "receiver_id": 2048,
|
|
|
|
|
+ "app_id": null,
|
|
|
|
|
+ "app_name": null,
|
|
|
|
|
+ "type": "MESSAGE",
|
|
|
|
|
+ "content_type": "TEXT",
|
|
|
|
|
+ "title": "私信",
|
|
|
|
|
+ "content": "你好",
|
|
|
|
|
+ "action_url": null,
|
|
|
|
|
+ "action_text": null,
|
|
|
|
|
+ "is_read": true,
|
|
|
|
|
+ "created_at": "2026-03-18T09:59:00",
|
|
|
|
|
+ "read_at": "2026-03-18T10:00:00"
|
|
|
|
|
+ }
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## 5. WebSocket 通信接口详情
|
|
## 5. WebSocket 通信接口详情
|
|
@@ -206,7 +517,7 @@ Authorization: Bearer <JWT_TOKEN>
|
|
|
|------|------|------|
|
|
|------|------|------|
|
|
|
| `id` | number | 消息 ID |
|
|
| `id` | number | 消息 ID |
|
|
|
| `type` | string | **消息业务类型**:`MESSAGE`(私信)/ `NOTIFICATION`(通知) |
|
|
| `type` | string | **消息业务类型**:`MESSAGE`(私信)/ `NOTIFICATION`(通知) |
|
|
|
-| `content_type` | string | 内容类型:`TEXT` / `IMAGE` / `VIDEO` / `FILE` |
|
|
|
|
|
|
|
+| `content_type` | string | 内容类型:`TEXT` / `IMAGE` / `VIDEO` / `FILE` / `USER_NOTIFICATION`(用户私信中的申请通知样式) |
|
|
|
| `title` | string | 标题(私信/通知均可能有) |
|
|
| `title` | string | 标题(私信/通知均可能有) |
|
|
|
| `content` | string | 文本内容;若为多媒体类型,服务端会下发**预签名 URL**(或兼容历史的完整 URL) |
|
|
| `content` | string | 文本内容;若为多媒体类型,服务端会下发**预签名 URL**(或兼容历史的完整 URL) |
|
|
|
| `sender_id` | number \| null | 发送者用户 ID;通知通常为 `null`(系统/应用发出) |
|
|
| `sender_id` | number \| null | 发送者用户 ID;通知通常为 `null`(系统/应用发出) |
|
|
@@ -222,7 +533,7 @@ Authorization: Bearer <JWT_TOKEN>
|
|
|
只看 `data` 即可,不需要额外接口:
|
|
只看 `data` 即可,不需要额外接口:
|
|
|
|
|
|
|
|
1. **优先看 `data.type`**
|
|
1. **优先看 `data.type`**
|
|
|
- - `data.type === "MESSAGE"`:这是 **私信**
|
|
|
|
|
|
|
+ - `data.type === "MESSAGE"`:这是 **私信**(若 `data.content_type === "USER_NOTIFICATION"`,为私信中的「申请通知」样式,仍按对方用户会话归类)
|
|
|
- `data.type === "NOTIFICATION"`:这是 **通知**(应用或系统)
|
|
- `data.type === "NOTIFICATION"`:这是 **通知**(应用或系统)
|
|
|
|
|
|
|
|
2. **通知里区分“哪个应用”的通知**
|
|
2. **通知里区分“哪个应用”的通知**
|
|
@@ -253,7 +564,7 @@ type WsEvent = {
|
|
|
data: {
|
|
data: {
|
|
|
id: number
|
|
id: number
|
|
|
type: 'MESSAGE' | 'NOTIFICATION'
|
|
type: 'MESSAGE' | 'NOTIFICATION'
|
|
|
- content_type: 'TEXT' | 'IMAGE' | 'VIDEO' | 'FILE'
|
|
|
|
|
|
|
+ content_type: 'TEXT' | 'IMAGE' | 'VIDEO' | 'FILE' | 'USER_NOTIFICATION'
|
|
|
title: string
|
|
title: string
|
|
|
content: string
|
|
content: string
|
|
|
sender_id: number | null
|
|
sender_id: number | null
|
|
@@ -312,7 +623,7 @@ type WsPush =
|
|
|
type WsMessageData = {
|
|
type WsMessageData = {
|
|
|
id: number
|
|
id: number
|
|
|
type: 'MESSAGE' | 'NOTIFICATION'
|
|
type: 'MESSAGE' | 'NOTIFICATION'
|
|
|
- content_type: 'TEXT' | 'IMAGE' | 'VIDEO' | 'FILE'
|
|
|
|
|
|
|
+ content_type: 'TEXT' | 'IMAGE' | 'VIDEO' | 'FILE' | 'USER_NOTIFICATION'
|
|
|
title: string
|
|
title: string
|
|
|
content: string
|
|
content: string
|
|
|
sender_id: number | null
|
|
sender_id: number | null
|
|
@@ -526,6 +837,32 @@ export function startMessageWs(token: string) {
|
|
|
- **接口**:`GET {{API_BASE_URL}}/users/?skip=0&limit=20&keyword=张三`
|
|
- **接口**:`GET {{API_BASE_URL}}/users/?skip=0&limit=20&keyword=张三`
|
|
|
- **用途**:管理端完整分页检索
|
|
- **用途**:管理端完整分页检索
|
|
|
|
|
|
|
|
|
|
+请求示例:
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+GET {{API_BASE_URL}}/users/?skip=0&limit=20&keyword=张三 HTTP/1.1
|
|
|
|
|
+Authorization: Bearer <JWT_TOKEN>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+响应示例:
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "total": 100,
|
|
|
|
|
+ "items": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": 2048,
|
|
|
|
|
+ "mobile": "13800138000",
|
|
|
|
|
+ "name": "张三",
|
|
|
|
|
+ "english_name": "zhangsan",
|
|
|
|
|
+ "status": "ACTIVE",
|
|
|
|
|
+ "role": "ORDINARY_USER",
|
|
|
|
|
+ "is_deleted": 0
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## 7. 应用中心(快捷导航)接口
|
|
## 7. 应用中心(快捷导航)接口
|
|
@@ -534,6 +871,7 @@ export function startMessageWs(token: string) {
|
|
|
|
|
|
|
|
- **接口**:`GET {{API_BASE_URL}}/simple/me/launchpad-apps`
|
|
- **接口**:`GET {{API_BASE_URL}}/simple/me/launchpad-apps`
|
|
|
- **说明**:返回当前用户可见且已激活的快捷导航应用(包含分类和描述)
|
|
- **说明**:返回当前用户可见且已激活的快捷导航应用(包含分类和描述)
|
|
|
|
|
+- **说明补充**:该接口是为“快捷导航页”服务的“可见应用列表”接口,不支持按关键字检索应用。若需要应用检索,请使用 `GET {{API_BASE_URL}}/apps/?search=关键字`(受权限约束)。
|
|
|
|
|
|
|
|
响应示例:
|
|
响应示例:
|
|
|
|
|
|
|
@@ -560,6 +898,28 @@ export function startMessageWs(token: string) {
|
|
|
|
|
|
|
|
客户端在“快捷导航”点击应用后,调用统一 SSO 登录接口获取 `redirect_url` 并跳转。
|
|
客户端在“快捷导航”点击应用后,调用统一 SSO 登录接口获取 `redirect_url` 并跳转。
|
|
|
|
|
|
|
|
|
|
+SSO 登录请求示例:
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST {{API_BASE_URL}}/simple/sso-login
|
|
|
|
|
+Authorization: Bearer <JWT_TOKEN>
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "app_id": "oa_system",
|
|
|
|
|
+ "username": "",
|
|
|
|
|
+ "password": ""
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+响应示例:
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "redirect_url": "https://oa.example.com/callback?ticket=abc123"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## 8. 实战接入建议
|
|
## 8. 实战接入建议
|