Compare commits
25
Commits
cae5039afe
...
e5fbca735d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5fbca735d | ||
|
|
2728f35069 | ||
|
|
ff432bc3ce | ||
|
|
ca3957e3b3 | ||
|
|
80c802af20 | ||
|
|
a9a4970d9f | ||
|
|
f1dfffcfb5 | ||
|
|
1d433971d4 | ||
|
|
cfab33f45a | ||
|
|
367bed2940 | ||
|
|
1c2132eebc | ||
|
|
bafaf2d7b9 | ||
|
|
05f4087240 | ||
|
|
b9dc56eccf | ||
|
|
926b4bbd81 | ||
|
|
75d1aabcb0 | ||
|
|
928a45ecfb | ||
|
|
51fee50343 | ||
|
|
1f3a98605e | ||
|
|
14ee3d937f | ||
|
|
085a48c3d9 | ||
|
|
6b2f1e06e0 | ||
|
|
98234db263 | ||
|
|
e0a6ee27bc | ||
|
|
23afc1b7f1 |
+248
-38
@@ -60,9 +60,35 @@ API Key 可以被客户端应用提取,因此不能把它当成用户密码或
|
|||||||
| WebSocket(支持自定义 Header 的原生客户端) | `wss://{host}/{api_path}v0/channels` | Upgrade Header `X-MeetingIM-APIKey` | 同上 |
|
| WebSocket(支持自定义 Header 的原生客户端) | `wss://{host}/{api_path}v0/channels` | Upgrade Header `X-MeetingIM-APIKey` | 同上 |
|
||||||
| 产品 HTTP | `https://{host}/{api_path}v1/im/*` | `Authorization: Bearer <params.token>` | 好友、群、收藏、搜索、工作台和设置 |
|
| 产品 HTTP | `https://{host}/{api_path}v1/im/*` | `Authorization: Bearer <params.token>` | 好友、群、收藏、搜索、工作台和设置 |
|
||||||
| 文件 HTTP | `POST /v0/file/u/`、`GET /v0/file/s/{file_id}` | 当前用 `X-MeetingIM-Auth: token <base64_token>` | 文件上传下载;禁止 Query 传 Token |
|
| 文件 HTTP | `POST /v0/file/u/`、`GET /v0/file/s/{file_id}` | 当前用 `X-MeetingIM-Auth: token <base64_token>` | 文件上传下载;禁止 Query 传 Token |
|
||||||
|
| 用户条款 | `https://{host}/legal/user-terms` | 无需认证、无需 API Key | 登录、注册页通过浏览器或 WebView 打开 |
|
||||||
|
| 隐私政策 | `https://{host}/legal/privacy-policy` | 无需认证、无需 API Key | 登录、注册及设置页通过浏览器或 WebView 打开 |
|
||||||
|
|
||||||
HTTP 请求统一通过 `X-MeetingIM-APIKey` 携带。浏览器 WebSocket 无法设置自定义 Upgrade Header 时才使用 `apikey` Query;日志和监控必须对该参数脱敏。产品 HTTP 还必须带 `X-IM-Schema: 1` 和 `X-Request-ID`;写操作带 `Idempotency-Key`。生产环境只允许 HTTPS/WSS。Token、密码、验证码、证件号不得写入 URL、普通日志、埋点或崩溃报告。
|
HTTP 请求统一通过 `X-MeetingIM-APIKey` 携带。浏览器 WebSocket 无法设置自定义 Upgrade Header 时才使用 `apikey` Query;日志和监控必须对该参数脱敏。产品 HTTP 还必须带 `X-IM-Schema: 1` 和 `X-Request-ID`;写操作带 `Idempotency-Key`。生产环境只允许 HTTPS/WSS。Token、密码、验证码、证件号不得写入 URL、普通日志、埋点或崩溃报告。
|
||||||
|
|
||||||
|
#### 0.2.3 用户条款与隐私政策公开页面
|
||||||
|
|
||||||
|
客户端不解析或内置协议正文,只保存以下 HTTPS 地址并直接打开:
|
||||||
|
|
||||||
|
| 页面 | 通用地址 | 测试/生产域名示例 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 用户条款 | `https://{host}/legal/user-terms` | `https://api.118im.com/legal/user-terms` |
|
||||||
|
| 隐私政策 | `https://{host}/legal/privacy-policy` | `https://api.118im.com/legal/privacy-policy` |
|
||||||
|
|
||||||
|
两个页面支持 `GET`、`HEAD`,返回 `text/html; charset=utf-8`,不要求 `X-MeetingIM-APIKey`、`X-IM-Schema` 或用户 Token。客户端登录前即可访问;链接应使用系统浏览器或支持 HTTPS 的 WebView 打开,不要把协议正文缓存为业务数据。服务端通过 ETag 和短时公共缓存控制版本刷新,协议更新并重新发布服务后客户端仍使用同一 URL。
|
||||||
|
|
||||||
|
客户端不需要硬编码协议域名。`POST /v1/im/tenants/resolve` 的 `data.endpoints` 会同步返回:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"legal": {
|
||||||
|
"user_terms": "https://api.example.com/legal/user-terms",
|
||||||
|
"privacy_policy": "https://api.example.com/legal/privacy-policy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
登录、注册页点击对应文字时直接打开上述 URL,不附加 Token、API Key 或租户参数,并允许用户滚动、缩放和返回。
|
||||||
|
|
||||||
WebSocket Upgrade 阶段由 `server/hdl_websock.go` 先调用 `checkAPIKey`。缺少或无效时不会建立 WebSocket,直接返回 HTTP 403:
|
WebSocket Upgrade 阶段由 `server/hdl_websock.go` 先调用 `checkAPIKey`。缺少或无效时不会建立 WebSocket,直接返回 HTTP 403:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -212,6 +238,18 @@ WebSocket Upgrade 阶段由 `server/hdl_websock.go` 先调用 `checkAPIKey`。
|
|||||||
|
|
||||||
订阅成功后才允许 `{pub}`、`note read/recv` 等会话操作。断线恢复必须重新执行 `WebSocket Upgrade -> hi -> token login -> sub me -> 恢复 Topic`,同一连接内不得跳过 `hi` 或切换企业码。
|
订阅成功后才允许 `{pub}`、`note read/recv` 等会话操作。断线恢复必须重新执行 `WebSocket Upgrade -> hi -> token login -> sub me -> 恢复 Topic`,同一连接内不得跳过 `hi` 或切换企业码。
|
||||||
|
|
||||||
|
##### 0.5.1.1 WebSocket 心跳与在线状态
|
||||||
|
|
||||||
|
当前 IM 长连接心跳使用 WebSocket 协议层 Ping/Pong,不使用业务 JSON 消息做保活。服务端每 30 秒发送一次 WebSocket Ping 帧(`pingPeriod=30s`),并期望客户端在 45 秒读超时窗口内返回 Pong(`idleSessionTimeout=45s`);如果没有收到 Pong,或底层读写失败,服务端会关闭当前 Session。
|
||||||
|
|
||||||
|
客户端要求:
|
||||||
|
|
||||||
|
1. 使用系统 WebSocket 库时,必须确认库会自动回复 Pong;如果库不会自动回复,需要在收到 Ping 时显式发送 Pong。
|
||||||
|
2. 不要把 `{"note":{"what":"kp"}}` 当作心跳。`kp/kpa/kpv` 只是“正在输入/正在录音/正在视频输入”等 UI 状态通知,不落库,也不能替代 WebSocket Pong。
|
||||||
|
3. 连接关闭或报错后,客户端本地应立即把 IM 长连接视为离线,并按指数退避重连。重连成功后完整执行 `WebSocket Upgrade -> hi -> token login -> sub me -> sub topics -> get data/del`,用本地最后完整持久化的 `seq + 1` 增量补消息。
|
||||||
|
4. 服务端收到任意客户端上行 JSON 消息或 WebSocket Pong 后,都会刷新在线状态。当前在线状态写入 Redis,默认 TTL 为 120 秒,用于好友在线状态、群成员在线状态等展示。
|
||||||
|
5. iOS/Android 进入后台后系统可能挂起 WebSocket。后台场景以推送唤醒和前台重连补偿为主,不要求客户端在后台无限重连。
|
||||||
|
|
||||||
#### 0.5.2 Long Polling 兼容流程:先取得的是 sid
|
#### 0.5.2 Long Polling 兼容流程:先取得的是 sid
|
||||||
|
|
||||||
如果客户端无法使用 WebSocket,可以使用现有 `/v0/channels/lp`。该模式确实需要“先请求取得一个值”,但取得的是短期 Session ID `sid`,API Key 仍然必须由客户端预先持有。
|
如果客户端无法使用 WebSocket,可以使用现有 `/v0/channels/lp`。该模式确实需要“先请求取得一个值”,但取得的是短期 Session ID `sid`,API Key 仍然必须由客户端预先持有。
|
||||||
@@ -316,7 +354,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
##### 0.5.4.3.1 会话内系统提示和可点击动作消息
|
##### 0.5.4.3.1 会话内系统提示和可点击动作消息
|
||||||
|
|
||||||
截图中的灰色提示、入群邀请说明、好友已添加提示等属于会话内系统消息,必须进入对应 P2P 或群 Topic 的消息流,占用 `seq`,参与历史拉取、重连补偿和多端同步。它们不是 `info` 实时业务事件,也不是系统通知列表记录;`info` 只负责触发刷新,真正需要在聊天窗口长期展示的内容必须以 `{data}` 下发并入库。
|
截图中的灰色提示、群内邀请确认说明、好友已添加提示等属于会话内系统消息,必须进入对应 P2P 或群 Topic 的消息流,占用 `seq`,参与历史拉取、重连补偿和多端同步。它们不是 `info` 实时业务事件,也不是系统通知列表记录;`info` 只负责触发刷新,真正需要在聊天窗口长期展示的内容必须以 `{data}` 下发并入库。发给被邀请人的“加入群聊”邀请卡片不写入邀请人与被邀请人的 P2P 会话,展示以 `GET /v1/im/system-notifications` 返回的系统通知记录为准。
|
||||||
|
|
||||||
客户端不得主动发送 `system_notice`、`system_action`;这两类消息只能由服务端受控身份生成。服务端下发时 `data.from` 可以为空,客户端以 `head.x-im-from="system"` 判断系统身份,不依赖真实用户头像。客户端收到未知 `template` 或未知 `action.type` 时,展示 `content.text`,忽略不可识别动作,不允许执行任意 URL、脚本或非白名单路由。
|
客户端不得主动发送 `system_notice`、`system_action`;这两类消息只能由服务端受控身份生成。服务端下发时 `data.from` 可以为空,客户端以 `head.x-im-from="system"` 判断系统身份,不依赖真实用户头像。客户端收到未知 `template` 或未知 `action.type` 时,展示 `content.text`,忽略不可识别动作,不允许执行任意 URL、脚本或非白名单路由。
|
||||||
|
|
||||||
@@ -357,6 +395,8 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| 删除单条/多条消息 | `{"del":{"id":"del-1","topic":"grp...","what":"msg","delseq":[{"low":12,"hi":13}],"hard":false}}` | `{"ctrl":{"id":"del-1","code":200,"text":"ok","params":{"del":3}}}`;其他端可能收到 `{"pres":{"topic":"grp...","what":"del","seq":3}}` |
|
| 删除单条/多条消息 | `{"del":{"id":"del-1","topic":"grp...","what":"msg","delseq":[{"low":12,"hi":13}],"hard":false}}` | `{"ctrl":{"id":"del-1","code":200,"text":"ok","params":{"del":3}}}`;其他端可能收到 `{"pres":{"topic":"grp...","what":"del","seq":3}}` |
|
||||||
| 清空当前用户视图 | `{"del":{"id":"del-all-1","topic":"p2p...","what":"msg","delseq":[{"low":1,"hi":126}],"hard":false}}` | `{"ctrl":{"id":"del-all-1","code":200,"text":"ok","params":{"del":4}}}` |
|
| 清空当前用户视图 | `{"del":{"id":"del-all-1","topic":"p2p...","what":"msg","delseq":[{"low":1,"hi":126}],"hard":false}}` | `{"ctrl":{"id":"del-all-1","code":200,"text":"ok","params":{"del":4}}}` |
|
||||||
|
|
||||||
|
`kp/kpa/kpv` 只表示输入态、录音态、视频输入态等短暂 UI 状态,不能作为长连接心跳。长连接保活必须依赖 0.5.1.1 中的 WebSocket Ping/Pong。
|
||||||
|
|
||||||
##### 0.5.4.5 Topic 资料、个人群设置和标签
|
##### 0.5.4.5 Topic 资料、个人群设置和标签
|
||||||
|
|
||||||
| 场景 | 客户端发送 | 服务端返回/下行示例 |
|
| 场景 | 客户端发送 | 服务端返回/下行示例 |
|
||||||
@@ -453,7 +493,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
客户端侧要求:
|
客户端侧要求:
|
||||||
|
|
||||||
- App 集成 JPush SDK,初始化使用极光 `AppKey`,不接触 `MasterSecret`。
|
- App 集成 JPush SDK,初始化使用极光 `AppKey`,不接触 `MasterSecret`。
|
||||||
- 登录 IM 后将极光 alias 绑定为当前 `user_id`,例如 `usr...`;同一用户多设备允许绑定同一个 alias。
|
- 登录 IM 后将极光 alias 绑定为当前 `user_id` 的安全别名:`user_id.replace("-", ".").replace("_", "|")`,例如 `usrd6Ag5opa-ww` 绑定为 `usrd6Ag5opa.ww`;同一用户多设备允许绑定同一个 alias。
|
||||||
- SDK 返回 `registration_id` 后调用 `PUT /v1/im/devices/{device_id}/push-token` 上报,`provider` 固定传 `jpush`。
|
- SDK 返回 `registration_id` 后调用 `PUT /v1/im/devices/{device_id}/push-token` 上报,`provider` 固定传 `jpush`。
|
||||||
- 点击 Push 后按 `extras.type` 跳转,再按服务端数据补偿,不能只凭 Push payload 渲染最终状态。
|
- 点击 Push 后按 `extras.type` 跳转,再按服务端数据补偿,不能只凭 Push payload 渲染最终状态。
|
||||||
|
|
||||||
@@ -590,7 +630,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| WebSocket `acc new` | `{"acc":{"id":"acc-1","user":"new","scheme":"basic","username":"alice","phone":"15500000000","secret":"base64(alice:password)","login":true,"cred":[{"meth":"tel","val":"15500000000","resp":"verification_token","params":{"challenge_id":"chg_123"}}]}}` | `{"ctrl":{"id":"acc-1","code":200,"params":{"user":"usr...","username":"alice","token":"token...","expires":"2026-09-03T09:00:00Z"}}}` |
|
| WebSocket `acc new` | `{"acc":{"id":"acc-1","user":"new","scheme":"basic","username":"alice","phone":"15500000000","secret":"base64(alice:password)","login":true,"cred":[{"meth":"tel","val":"15500000000","resp":"verification_token","params":{"challenge_id":"chg_123"}}]}}` | `{"ctrl":{"id":"acc-1","code":200,"params":{"user":"usr...","username":"alice","token":"token...","expires":"2026-09-03T09:00:00Z"}}}` |
|
||||||
| `POST /v0/channels/lp` | Long Polling 首包 `{"hi":{"id":"hi-1","ver":"0.25","tenant":"default"}}` | `{"ctrl":{"id":"hi-1","code":201,"params":{"sid":"lp_sid_123"}}}` |
|
| `POST /v0/channels/lp` | Long Polling 首包 `{"hi":{"id":"hi-1","ver":"0.25","tenant":"default"}}` | `{"ctrl":{"id":"hi-1","code":201,"params":{"sid":"lp_sid_123"}}}` |
|
||||||
| `POST /v0/file/u/` | Multipart 文件;Header `X-MeetingIM-Auth: token <base64_token>`;业务表单可带 `purpose=chat_file&topic=grp...` | `{"ctrl":{"code":200,"params":{"url":"/v0/file/s/file123","name":"a.pdf","size":1024,"mime":"application/pdf"}}}` |
|
| `POST /v0/file/u/` | Multipart 文件;Header `X-MeetingIM-Auth: token <base64_token>`;业务表单可带 `purpose=chat_file&topic=grp...` | `{"ctrl":{"code":200,"params":{"url":"/v0/file/s/file123","name":"a.pdf","size":1024,"mime":"application/pdf"}}}` |
|
||||||
| `GET /v0/file/s/{file_id}` | Header `X-MeetingIM-Auth: token <base64_token>`,可带 `Range: bytes=0-` | 返回文件字节流;失败返回 `FILE_FORBIDDEN` 或 `FILE_UNAVAILABLE` |
|
| `GET /v0/file/s/{file_id}` | Header `X-MeetingIM-Auth: token <base64_token>`,可带 `Range: bytes=0-` | 对象存储模式下鉴权通过后返回 302 到短期签名 URL;客户端跟随 Location 获取文件 |
|
||||||
|
|
||||||
### 0.6 Topic 与产品消息
|
### 0.6 Topic 与产品消息
|
||||||
|
|
||||||
@@ -658,7 +698,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
"data": {
|
"data": {
|
||||||
"tenant": {"code": "acme", "name": "示例企业", "tenant_desc": null, "branding": {}},
|
"tenant": {"code": "acme", "name": "示例企业", "tenant_desc": null, "branding": {}},
|
||||||
"endpoints": {
|
"endpoints": {
|
||||||
"websocket": "wss://im.example.com/v0/channels",
|
"websocket": "wss://im.example.com/v0/channels?apikey=AQ...",
|
||||||
"api": "https://im.example.com/v1/im",
|
"api": "https://im.example.com/v1/im",
|
||||||
"file": "https://im.example.com/v0/file"
|
"file": "https://im.example.com/v0/file"
|
||||||
},
|
},
|
||||||
@@ -955,7 +995,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
| 接口 | 输入示例 | 成功 `data` 示例 |
|
| 接口 | 输入示例 | 成功 `data` 示例 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `POST /v1/im/tenants/resolve` | Header `X-Tenant-Code: default`;Body `{"tenant_code":"default","platform":"ios","app_version":"1.0.0"}` | `{"tenant":{"code":"default","name":"Default Tenant","tenant_desc":null,"branding":{}},"endpoints":{"websocket":"wss://api.118im.com/v0/channels","api":"https://api.118im.com/v1/im","file":"https://api.118im.com/v0/file"},"auth_methods":["password","sms"],"password_policy":{"min_length":8,"max_length":64},"app_update":{"type":"none"}}` |
|
| `POST /v1/im/tenants/resolve` | Header `X-Tenant-Code: default`;Body `{"tenant_code":"default","platform":"ios","app_version":"1.0.0"}` | `{"tenant":{"code":"default","name":"Default Tenant","tenant_desc":null,"branding":{}},"endpoints":{"websocket":"wss://api.118im.com/v0/channels?apikey=AQ...","api":"https://api.118im.com/v1/im","file":"https://api.118im.com/v0/file"},"auth_methods":["password","sms"],"password_policy":{"min_length":8,"max_length":64},"app_update":{"type":"none"}}` |
|
||||||
| `POST /v1/im/public/uploads` 企业注册/反馈附件上传 | Multipart `purpose=enterprise_license\|tenant_entry_feedback`、`file=@license.png` | `{"file_id":"file_01K...","purpose":"enterprise_license","mime_type":"image/png","size":1024000,"expires_at":"2026-08-25T08:30:15Z"}` |
|
| `POST /v1/im/public/uploads` 企业注册/反馈附件上传 | Multipart `purpose=enterprise_license\|tenant_entry_feedback`、`file=@license.png` | `{"file_id":"file_01K...","purpose":"enterprise_license","mime_type":"image/png","size":1024000,"expires_at":"2026-08-25T08:30:15Z"}` |
|
||||||
| `POST /v1/im/tenant-applications` 企业注册申请 | `{"credit_code":"91310000MA1K000000","enterprise_email":"admin@example.com","license_file_id":"file_01K...","tenant_code_hint":"acme","client_context":{"platform":"android","app_version":"1.0.0"}}` | `{"application_id":"entapp_01K...","status":"received","estimated_review_hours":24,"submitted_at":"2026-08-24T08:30:15.123Z"}` |
|
| `POST /v1/im/tenant-applications` 企业注册申请 | `{"credit_code":"91310000MA1K000000","enterprise_email":"admin@example.com","license_file_id":"file_01K...","tenant_code_hint":"acme","client_context":{"platform":"android","app_version":"1.0.0"}}` | `{"application_id":"entapp_01K...","status":"received","estimated_review_hours":24,"submitted_at":"2026-08-24T08:30:15.123Z"}` |
|
||||||
| `POST /v1/im/tenant-entry-feedback` 企业入口问题反馈 | `{"description":"企业码 acme 提示不可用,无法进入企业。","contact":"user@example.com","tenant_code_hint":"acme","screenshot_file_ids":["file_01K..."],"client_context":{"platform":"ios","app_version":"1.0.0"}}` | `{"feedback_id":"entryfb_01K...","status":"received","submitted_at":"2026-08-24T08:35:15.123Z"}` |
|
| `POST /v1/im/tenant-entry-feedback` 企业入口问题反馈 | `{"description":"企业码 acme 提示不可用,无法进入企业。","contact":"user@example.com","tenant_code_hint":"acme","screenshot_file_ids":["file_01K..."],"client_context":{"platform":"ios","app_version":"1.0.0"}}` | `{"feedback_id":"entryfb_01K...","status":"received","submitted_at":"2026-08-24T08:35:15.123Z"}` |
|
||||||
@@ -965,8 +1005,8 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| `POST /v1/im/auth/password-reset/challenges/{challenge_id}/verify` | `{"code":"123456"}` | `{"reset_token":"reset_token_123","expires_in_seconds":300}` |
|
| `POST /v1/im/auth/password-reset/challenges/{challenge_id}/verify` | `{"code":"123456"}` | `{"reset_token":"reset_token_123","expires_in_seconds":300}` |
|
||||||
| `POST /v1/im/auth/password-reset/confirm` | `{"reset_token":"reset_token_123","new_password":"NewPass123"}` | `{"status":"ok"}` |
|
| `POST /v1/im/auth/password-reset/confirm` | `{"reset_token":"reset_token_123","new_password":"NewPass123"}` | `{"status":"ok"}` |
|
||||||
| `POST /admin/v1/tenant/users/{user_id}/reset-password` 管理后台 | `{"new_password":"AdminReset123","reason":"用户无手机号无法自助找回"}` | `{"user_id":"usr...","status":"reset","auth_version":2}` |
|
| `POST /admin/v1/tenant/users/{user_id}/reset-password` 管理后台 | `{"new_password":"AdminReset123","reason":"用户无手机号无法自助找回"}` | `{"user_id":"usr...","status":"reset","auth_version":2}` |
|
||||||
| `POST /v1/im/auth/logout` 待实现 | `{}` | `{"status":"ok"}` |
|
| `POST /v1/im/auth/logout` | `{}` | `{"status":"ok"}` |
|
||||||
| `GET /v1/im/app/releases/latest?platform=ios\|android¤t_version=1.0.0&channel=stable` | Query only | `{"platform":"ios","channel":"stable","latest_version":"1.0.0","min_supported_version":"1.0.0","update_type":"none","package_url":"","store_url":"","release_notes":"当前已是最新版本。","remind_after_seconds":0}` |
|
| `GET /v1/im/app/releases/latest?platform=ios\|android¤t_version=1.0.0&channel=stable` | Query only | `{"current_version":"1.0.0","has_update":true,"force_update":false,"platform":"ios","channel":"stable","latest_version":"1.1.0","min_supported_version":"1.0.0","update_type":"recommended","package_url":"","store_url":"https://apps.apple.com/app/id...","release_notes":"修复已知问题。","remind_after_seconds":86400}` |
|
||||||
|
|
||||||
## 2. 消息首页、全局导航与系统通知
|
## 2. 消息首页、全局导航与系统通知
|
||||||
|
|
||||||
@@ -1344,8 +1384,8 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
**状态:新增。**
|
**状态:新增。**
|
||||||
|
|
||||||
- `POST /v1/im/messages/forward`,Body `{"mode":"separate","sources":[{"topic":"p2p...","seq":12}],"target_topics":["grp..."],"comment":"..."}`。`seq` 兼容数字和字符串;P2P 源会话也可以传对方 `usr...` 用户 ID,服务端会归一化为 P2P topic。
|
- `POST /v1/im/messages/forward`,Body `{"mode":"separate","sources":[{"topic":"p2p...","seq":12}],"target_topics":["grp..."],"comment":"..."}`。`seq` 兼容数字和字符串;P2P 源会话也可以传对方 `usr...` 用户 ID,服务端会归一化为 P2P topic。
|
||||||
- 返回每个目标和源消息的 `client_mid/seq/status`;服务端保持源顺序,重新生成目标消息,不能复用原 `seq`。
|
- 返回每个目标和源消息的 `client_mid/seq/status`;`status` 取值为 `sent`、`pending`、`failed`。`pending` 表示服务端已分配 `seq/client_mid`,但 Kafka 投递结果暂不确定,客户端应按“发送中”展示,保留同一个 `Idempotency-Key` 重试或等待后续消息同步,不要立即生成第二条本地消息。服务端保持源顺序,重新生成目标消息,不能复用原 `seq`。
|
||||||
- 附件必须建立新的授权引用;原消息已撤回、过期或不可见时该项失败。留言作为每个目标的一条独立文本消息发送。
|
- 附件必须建立新的授权引用;原消息已撤回、过期或不可见时该项失败。留言作为每个目标的一条独立文本消息发送,返回项可带 `comment_client_mid/comment_seq/comment_status/comment_reason`;转发消息本身仍保持原 `head/content`,不得把留言包装进图片、文件等原消息 `content`。
|
||||||
|
|
||||||
### 4.20 转发—合并转发—多选状态.png
|
### 4.20 转发—合并转发—多选状态.png
|
||||||
|
|
||||||
@@ -1396,7 +1436,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增产品通讯录接口。**
|
**状态:新增产品通讯录接口。**
|
||||||
|
|
||||||
- 好友列表:`GET /v1/im/friends?query=&initial=&cursor=`,返回 `user_id,display_name,remark,avatar_file_id,initial,online_visibility`;显示名优先级为备注名、昵称、账号。
|
- 好友列表:`GET /v1/im/friends?query=&initial=&cursor=`,返回 `user_id,display_name,remark,avatar_file_id,initial,online,online_visibility`;好友展示名统一读取 `display_name`,服务端按当前登录人计算,优先级为备注名、昵称、账号。`remark` 仅用于备注编辑页回显,`nickname` 表示对方自己设置的昵称,不应直接作为好友列表或单聊标题的最终展示名。
|
||||||
- 分页:`next_cursor` 当前按最后一条好友的 `peer_id` 生成,客户端必须作为不透明字符串原样回传,不要自行解析、排序或拼接。
|
- 分页:`next_cursor` 当前按最后一条好友的 `peer_id` 生成,客户端必须作为不透明字符串原样回传,不要自行解析、排序或拼接。
|
||||||
- 组织成员:`GET /v1/im/organization/members?query=&department_id=&cursor=`;好友和组织成员是两种关系,前端不得混为一个可发消息权限。
|
- 组织成员:`GET /v1/im/organization/members?query=&department_id=&cursor=`;好友和组织成员是两种关系,前端不得混为一个可发消息权限。
|
||||||
- 新朋友、群列表、文件助手和系统消息入口由 `GET /v1/im/bootstrap` 的 `entries` 控制显示,初始红点由 `entry_badges` 和各入口 `unread_count` 返回。新朋友待处理数使用业务统计;文件助手当前返回 `topic:"slf", unread_source:"topic"`;系统消息当前返回 `topic:"sys", unread_source:"business"`,未读来自系统通知业务表。列表缓存以租户和用户隔离。
|
- 新朋友、群列表、文件助手和系统消息入口由 `GET /v1/im/bootstrap` 的 `entries` 控制显示,初始红点由 `entry_badges` 和各入口 `unread_count` 返回。新朋友待处理数使用业务统计;文件助手当前返回 `topic:"slf", unread_source:"topic"`;系统消息当前返回 `topic:"sys", unread_source:"business"`,未读来自系统通知业务表。列表缓存以租户和用户隔离。
|
||||||
@@ -1458,7 +1498,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增。**
|
**状态:新增。**
|
||||||
|
|
||||||
- `GET /v1/im/users/{identifier}/profile` 返回按当前查看人裁剪后的 `display_name,remark,avatar_file_id,gender,region,public_account,signature,relationship,capabilities`;`identifier` 可传 `user_id`、`username` 或 `public_account`。
|
- `GET /v1/im/users/{identifier}/profile` 返回按当前查看人裁剪后的 `display_name,remark,avatar_file_id,gender,region,public_account,signature,relationship,capabilities`;`identifier` 可传 `user_id`、`username` 或 `public_account`。个人资料页头部和单聊标题统一使用 `display_name`,需要展示对方原始昵称时再使用 `nickname`。
|
||||||
- 查看该用户二维码调用 `POST /v1/im/users/{identifier}/qrcodes`,Body `{"purpose":"add_friend","expires_in_seconds":86400}`;前端在个人信息页只有用户名时直接把用户名作为 `identifier` 传入即可。服务端解析到真实用户后生成二维码,并按资料可见性与 `add_me_methods.qr` 做权限校验。
|
- 查看该用户二维码调用 `POST /v1/im/users/{identifier}/qrcodes`,Body `{"purpose":"add_friend","expires_in_seconds":86400}`;前端在个人信息页只有用户名时直接把用户名作为 `identifier` 传入即可。服务端解析到真实用户后生成二维码,并按资料可见性与 `add_me_methods.qr` 做权限校验。
|
||||||
- 发消息使用返回的 P2P `topic`;没有 Topic 时调用 `POST /v1/im/conversations/p2p`,Body `{"peer_user_id":"..."}` 并由服务端验证好友关系。
|
- 发消息使用返回的 P2P `topic`;没有 Topic 时调用 `POST /v1/im/conversations/p2p`,Body `{"peer_user_id":"..."}` 并由服务端验证好友关系。
|
||||||
- 音视频按钮只按 `capabilities.can_call` 展示,真正呼叫时再次鉴权。隐藏字段必须从响应中省略,不能只由前端遮挡。
|
- 音视频按钮只按 `capabilities.can_call` 展示,真正呼叫时再次鉴权。隐藏字段必须从响应中省略,不能只由前端遮挡。
|
||||||
@@ -1593,7 +1633,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增邀请卡片和加入接口。**
|
**状态:新增邀请卡片和加入接口。**
|
||||||
|
|
||||||
- 邀请卡展示以群邀请接口返回和系统通知记录为准;相关实时刷新使用 `info.what="group"` 群业务事件。
|
- 邀请卡展示以群邀请接口返回和系统通知记录为准;系统通知 `event_type=group.invitation.created`,`action.type=group_invitation_accept`,`action.invitation_id` 用于点击加入,`action.topic` 为目标群。相关实时刷新使用 `info.what="group"` 群业务事件。
|
||||||
- 点击加入:`POST /v1/im/group-invitations/{invitation_id}/accept`,带幂等键;返回 `status=joined|pending_approval` 和 `topic`。
|
- 点击加入:`POST /v1/im/group-invitations/{invitation_id}/accept`,带幂等键;返回 `status=joined|pending_approval` 和 `topic`。
|
||||||
- 服务端校验邀请租户、有效期、群状态、成员资格和成员数上限;重复加入返回当前状态,过期返回 `INVITATION_EXPIRED`。
|
- 服务端校验邀请租户、有效期、群状态、成员资格和成员数上限;重复加入返回当前状态,过期返回 `INVITATION_EXPIRED`。
|
||||||
|
|
||||||
@@ -1613,7 +1653,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增。**
|
**状态:新增。**
|
||||||
|
|
||||||
- `GET /v1/im/groups/{topic}/join-requests?status=pending&cursor=` 返回申请人、邀请人、来源、时间、状态和 `version`。
|
- `GET /v1/im/groups/{topic}/join-requests?status=pending&cursor=` 返回申请人、邀请人、来源、时间、状态和 `version`;申请人展示字段直接带 `display_name/avatar_file_id/user`,邀请人展示字段带 `inviter_display_name/inviter_avatar_file_id/inviter`。
|
||||||
- 同意:`POST /v1/im/groups/{topic}/join-requests/{id}/accept`;拒绝:`POST /v1/im/groups/{topic}/join-requests/{id}/reject`,带幂等键与 `version`。
|
- 同意:`POST /v1/im/groups/{topic}/join-requests/{id}/accept`;拒绝:`POST /v1/im/groups/{topic}/join-requests/{id}/reject`,带幂等键与 `version`。
|
||||||
- 仅群主/管理员可处理;同意时原子校验群成员上限。并发处理返回 `REQUEST_ALREADY_HANDLED` 和最终状态。
|
- 仅群主/管理员可处理;同意时原子校验群成员上限。并发处理返回 `REQUEST_ALREADY_HANDLED` 和最终状态。
|
||||||
|
|
||||||
@@ -1694,6 +1734,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
- `PUT /v1/im/groups/{topic}/members/me/profile`,Body `{"nickname":"...","version":n}`。
|
- `PUT /v1/im/groups/{topic}/members/me/profile`,Body `{"nickname":"...","version":n}`。
|
||||||
- 服务端校验成员资格、长度和敏感词,返回 `nickname,version,updated_at` 并推送成员资料变化。
|
- 服务端校验成员资格、长度和敏感词,返回 `nickname,version,updated_at` 并推送成员资料变化。
|
||||||
- 该昵称仅作用当前群,不能修改全局用户昵称或其他群资料。
|
- 该昵称仅作用当前群,不能修改全局用户昵称或其他群资料。
|
||||||
|
- 群成员列表和群成员资料中的 `display_name` 仍由服务端按当前登录人计算,好友备注优先;群内昵称单独返回为 `group_nickname`,前端不要用 `nickname/group_nickname` 覆盖 `display_name`。
|
||||||
|
|
||||||
### 6.14 群简介.png
|
### 6.14 群简介.png
|
||||||
|
|
||||||
@@ -1837,8 +1878,8 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:需改造。**
|
**状态:需改造。**
|
||||||
|
|
||||||
- 先用 `purpose=group_file,topic=...` 上传,再 `POST /v1/im/groups/{topic}/files`,Body `{"file_id":"..."}` 建立群文件记录。
|
- 先用 `purpose=group_file,topic=...` 上传,再 `POST /v1/im/groups/{topic}/files`,Body `{"file_id":"...","file_name":"方案.pdf","mime_type":"application/pdf","file_size":1024}` 建立群文件记录。
|
||||||
- 服务端校验 `member_upload_files`、单文件上限、租户总存储和群成员身份;成功返回完整群文件项。
|
- 服务端校验 `member_upload_files`、文件是否已上传完成、`file_name` 长度不超过 255、`mime_type` 长度不超过 128、`file_size` 非负且与上传记录一致、单文件上限、租户总存储和群成员身份;成功返回完整群文件项。
|
||||||
- 上传失败可复用 `upload_id`;登记失败不得在列表显示,孤立文件按 TTL 回收。
|
- 上传失败可复用 `upload_id`;登记失败不得在列表显示,孤立文件按 TTL 回收。
|
||||||
|
|
||||||
### 6.29 接口示例
|
### 6.29 接口示例
|
||||||
@@ -1865,13 +1906,13 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| `PATCH /v1/im/groups/{topic}/member-settings` | `{"pinned":true,"mute_notifications":false,"version":1}` | `{"topic":"grp...","pinned":true,"mute_notifications":false,"version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
| `PATCH /v1/im/groups/{topic}/member-settings` | `{"pinned":true,"mute_notifications":false,"version":1}` | `{"topic":"grp...","pinned":true,"mute_notifications":false,"version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `PUT /v1/im/groups/{topic}/members/me/profile` | `{"nickname":"我在群里的昵称","version":1}` | `{"nickname":"我在群里的昵称","version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
| `PUT /v1/im/groups/{topic}/members/me/profile` | `{"nickname":"我在群里的昵称","version":1}` | `{"nickname":"我在群里的昵称","version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `POST /v1/im/groups/{topic}/leave` | `{}` | `{"topic":"grp...","status":"left"}` |
|
| `POST /v1/im/groups/{topic}/leave` | `{}` | `{"topic":"grp...","status":"left"}` |
|
||||||
| `GET /v1/im/groups/{topic}/members?query=&cursor=&mentionable=true` | Query only | `{"topic":"grp...","items":[{"user_id":"usr...","display_name":"张三","avatar_file_id":"","role":"member","mentionable":true,"acs":{"want":"JRWP","given":"JRWP","mode":"JRWP"}}],"next_cursor":"","permissions":{"can_mention_all":true}}` |
|
| `GET /v1/im/groups/{topic}/members?query=&cursor=&mentionable=true` | Query only | `{"topic":"grp...","items":[{"user_id":"usr...","display_name":"张三","group_nickname":"小张","avatar_file_id":"","role":"member","mentionable":true,"acs":{"want":"JRWP","given":"JRWP","mode":"JRWP"}}],"next_cursor":"","permissions":{"can_mention_all":true}}` |
|
||||||
| `GET /v1/im/groups/{topic}/members/{user_id}/profile` | Path topic/user;`topic` 必须是 `grp...`,不能传 `usr...` | `{"topic":"grp...","user_id":"usr...","display_name":"张三","group_nickname":"小张","role":"member","relationship":"friend","capabilities":{"can_send":true,"can_call":true}}` |
|
| `GET /v1/im/groups/{topic}/members/{user_id}/profile` | Path topic/user;`topic` 必须是 `grp...`,不能传 `usr...` | `{"topic":"grp...","user_id":"usr...","display_name":"张三","group_nickname":"小张","role":"member","relationship":"friend","capabilities":{"can_send":true,"can_call":true}}` |
|
||||||
| `POST /v1/im/groups/{topic}/qrcodes` | `{"expires_in_seconds":86400}` | `{"qr_token":"token...","qr_payload":"im://qr?token=...&purpose=join_group","expires_at":"2026-08-21T09:00:00Z","group_snapshot":{"topic":"grp...","name":"项目群","member_count":2}}` |
|
| `POST /v1/im/groups/{topic}/qrcodes` | `{"expires_in_seconds":86400}` | `{"qr_token":"token...","qr_payload":"im://qr?token=...&purpose=join_group","expires_at":"2026-08-21T09:00:00Z","group_snapshot":{"topic":"grp...","name":"项目群","member_count":2}}` |
|
||||||
| `POST /v1/im/groups/{topic}/invitations` | `{"user_ids":["usr..."],"message":"进群一起讨论"}` | `{"topic":"grp...","items":[{"user_id":"usr...","status":"joined","invitation_id":"ginv_1"}]}` |
|
| `POST /v1/im/groups/{topic}/invitations` | `{"user_ids":["usr..."],"message":"进群一起讨论"}` | `{"topic":"grp...","items":[{"user_id":"usr...","status":"joined","invitation_id":"ginv_1"}]}` |
|
||||||
| `POST /v1/im/group-invitations/{invitation_id}/accept` 待实现 | `{}` | `{"invitation_id":"ginv_1","status":"joined","topic":"grp..."}` |
|
| `POST /v1/im/group-invitations/{invitation_id}/accept` 待实现 | `{}` | `{"invitation_id":"ginv_1","status":"joined","topic":"grp..."}` |
|
||||||
| `POST /v1/im/groups/{topic}/join-requests` | `{"message":"申请入群","source":"qr","qr_token":"token..."}` | `{"request_id":"gjr_1","topic":"grp...","status":"pending","created_at":"2026-08-20T09:00:00Z","version":1}` |
|
| `POST /v1/im/groups/{topic}/join-requests` | `{"message":"申请入群","source":"qr","qr_token":"token..."}` | `{"request_id":"gjr_1","topic":"grp...","status":"pending","created_at":"2026-08-20T09:00:00Z","version":1}` |
|
||||||
| `GET /v1/im/groups/{topic}/join-requests?status=pending&cursor=` | Query only | `{"topic":"grp...","items":[{"request_id":"gjr_1","applicant":{"user_id":"usr...","display_name":"张三"},"status":"pending","source":"qr","created_at":"2026-08-20T09:00:00Z","version":1}],"next_cursor":""}` |
|
| `GET /v1/im/groups/{topic}/join-requests?status=pending&cursor=` | Query only | `{"topic":"grp...","items":[{"request_id":"gjr_1","user_id":"usr...","display_name":"张三","avatar_file_id":"avatar.jpg","user":{"user_id":"usr...","display_name":"张三","avatar_file_id":"avatar.jpg"},"inviter_id":"usr_inviter","inviter_display_name":"李四","inviter_avatar_file_id":"inviter.jpg","inviter":{"user_id":"usr_inviter","display_name":"李四","avatar_file_id":"inviter.jpg"},"status":"pending","source":"invitation","created_at":"2026-08-20T09:00:00Z","version":1}],"next_cursor":""}` |
|
||||||
| `POST /v1/im/groups/{topic}/join-requests/{id}/accept` | `{"version":1}` | `{"request_id":"gjr_1","topic":"grp...","status":"accepted","handled_at":"2026-08-20T09:00:00Z","version":2}` |
|
| `POST /v1/im/groups/{topic}/join-requests/{id}/accept` | `{"version":1}` | `{"request_id":"gjr_1","topic":"grp...","status":"accepted","handled_at":"2026-08-20T09:00:00Z","version":2}` |
|
||||||
| `POST /v1/im/groups/{topic}/join-requests/{id}/reject` | `{"version":1,"reason":"人数已满"}` | `{"request_id":"gjr_1","topic":"grp...","status":"rejected","handled_at":"2026-08-20T09:00:00Z","version":2}` |
|
| `POST /v1/im/groups/{topic}/join-requests/{id}/reject` | `{"version":1,"reason":"人数已满"}` | `{"request_id":"gjr_1","topic":"grp...","status":"rejected","handled_at":"2026-08-20T09:00:00Z","version":2}` |
|
||||||
| `GET /v1/im/groups/{topic}/summary` | Path topic | `{"topic":"grp...","pending_join_request_count":0,"announcement":{"announcement_id":"ann_1","content":"公告"},"permissions":{"can_manage_members":true}}` |
|
| `GET /v1/im/groups/{topic}/summary` | Path topic | `{"topic":"grp...","pending_join_request_count":0,"announcement":{"announcement_id":"ann_1","content":"公告"},"permissions":{"can_manage_members":true}}` |
|
||||||
@@ -2069,10 +2110,10 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| `GET /v1/im/favorites/{favorite_id}` | Path favorite ID | `{"favorite_id":"fav_1","type":"file","snapshot":{"file_id":"file_1","name":"a.pdf"},"source":{"topic":"grp...","seq":12},"availability":"available"}` |
|
| `GET /v1/im/favorites/{favorite_id}` | Path favorite ID | `{"favorite_id":"fav_1","type":"file","snapshot":{"file_id":"file_1","name":"a.pdf"},"source":{"topic":"grp...","seq":12},"availability":"available"}` |
|
||||||
| `DELETE /v1/im/favorites/{favorite_id}` | Path favorite ID | `{"favorite_id":"fav_1","deleted":true}` |
|
| `DELETE /v1/im/favorites/{favorite_id}` | Path favorite ID | `{"favorite_id":"fav_1","deleted":true}` |
|
||||||
| `POST /v1/im/favorites/batch-delete` | `{"favorite_ids":["fav_1","fav_2"]}` | `{"items":[{"favorite_id":"fav_1","deleted":true},{"favorite_id":"fav_2","deleted":true}],"failed":[]}` |
|
| `POST /v1/im/favorites/batch-delete` | `{"favorite_ids":["fav_1","fav_2"]}` | `{"items":[{"favorite_id":"fav_1","deleted":true},{"favorite_id":"fav_2","deleted":true}],"failed":[]}` |
|
||||||
| `POST /v1/im/favorites/forward` | `{"favorite_ids":["fav_1"],"target_topics":["grp..."],"comment":"转给你"}` | `{"items":[{"favorite_id":"fav_1","target_topic":"grp...","status":"sent","seq":20}],"failed":[]}` |
|
| `POST /v1/im/favorites/forward` | `{"favorite_ids":["fav_1"],"target_topics":["grp..."],"comment":"转给你"}` | `{"items":[{"favorite_id":"fav_1","target_topic":"grp...","status":"sent","seq":20,"comment_seq":19,"comment_status":"sent"}],"failed":[]}`;Kafka 投递结果不确定时返回 `status:"pending"`、`reason:"MESSAGE_PERSIST_PENDING"` |
|
||||||
| `GET /v1/im/forward-targets?query=&cursor=` | Query only | `{"items":[{"topic":"grp...","type":"group","display_name":"项目群","avatar_file_id":"","can_receive_forward":true},{"topic":"slf","type":"file_assistant","display_name":"文件助手","can_receive_forward":true}],"next_cursor":"","has_more":false}` |
|
| `GET /v1/im/forward-targets?query=&cursor=` | Query only | `{"items":[{"topic":"grp...","type":"group","display_name":"项目群","avatar_file_id":"","can_receive_forward":true},{"topic":"slf","type":"file_assistant","display_name":"文件助手","can_receive_forward":true}],"next_cursor":"","has_more":false}` |
|
||||||
| `POST /v1/im/messages/forward` 逐条转发 | `{"mode":"separate","sources":[{"topic":"grp...","seq":12}],"target_topics":["usr..."],"comment":""}` | `{"items":[{"source":{"topic":"grp...","seq":12},"target_topic":"p2p...","client_mid":"mid_1","seq":30,"status":"sent"}],"failed":[]}` |
|
| `POST /v1/im/messages/forward` 逐条转发 | `{"mode":"separate","sources":[{"topic":"grp...","seq":12}],"target_topics":["usr..."],"comment":"转给你"}` | `{"items":[{"source":{"topic":"grp...","seq":12},"target_topic":"p2p...","client_mid":"mid_1","seq":30,"status":"sent","comment_seq":29,"comment_status":"sent"}],"failed":[]}`;Kafka 投递结果不确定时返回 `status:"pending"`、`reason:"MESSAGE_PERSIST_PENDING"` |
|
||||||
| `POST /v1/im/messages/forward` 合并转发 | `{"mode":"bundle","sources":[{"topic":"grp...","seq":12},{"topic":"grp...","seq":13}],"target_topics":["usr..."],"comment":""}` | `{"items":[{"sources":[{"topic":"grp...","seq":12},{"topic":"grp...","seq":13}],"target_topic":"p2p...","client_mid":"mid_1","seq":31,"status":"sent","mode":"bundle","bundle_id":"fbundle_1"}],"failed":[]}` |
|
| `POST /v1/im/messages/forward` 合并转发 | `{"mode":"bundle","sources":[{"topic":"grp...","seq":12},{"topic":"grp...","seq":13}],"target_topics":["usr..."],"comment":"转给你"}` | `{"items":[{"sources":[{"topic":"grp...","seq":12},{"topic":"grp...","seq":13}],"target_topic":"p2p...","client_mid":"mid_1","seq":31,"status":"sent","mode":"bundle","bundle_id":"fbundle_1","comment_seq":30,"comment_status":"sent"}],"failed":[]}`;Kafka 投递结果不确定时返回 `status:"pending"`、`reason:"MESSAGE_PERSIST_PENDING"` |
|
||||||
| `GET /v1/im/forward-bundles/{bundle_id}?cursor=` 待实现 | Query only | `{"bundle_id":"fbundle_1","title":"聊天记录","item_count":2,"items":[{"from_display":"张三","ts":"2026-08-20T09:00:00Z","summary":"文本摘要"}],"next_cursor":""}` |
|
| `GET /v1/im/forward-bundles/{bundle_id}?cursor=` 待实现 | Query only | `{"bundle_id":"fbundle_1","title":"聊天记录","item_count":2,"items":[{"from_display":"张三","ts":"2026-08-20T09:00:00Z","summary":"文本摘要"}],"next_cursor":""}` |
|
||||||
| `POST /v1/im/security/urls/check` | `{"url":"https://example.com","source":"favorite"}` | `{"url":"https://example.com","decision":"allow","risk_level":"low","reason":"ok","source":"favorite"}` |
|
| `POST /v1/im/security/urls/check` | `{"url":"https://example.com","source":"favorite"}` | `{"url":"https://example.com","decision":"allow","risk_level":"low","reason":"ok","source":"favorite"}` |
|
||||||
|
|
||||||
@@ -2218,10 +2259,10 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增。**
|
**状态:新增。**
|
||||||
|
|
||||||
- `GET /v1/im/workbench` 返回 `modules[{code,name,icon_file_id,route,unread_count,enabled,permission}]`、布局版本和企业配置。
|
- `GET /v1/im/workbench` 返回 `modules[{code,name,icon_file_id,route,sort_order,unread_count,enabled,permission}]`、布局版本和企业配置;服务端按 `sort_order ASC` 返回,默认顺序为打卡、月报、日报、部门框架、举报信箱、会议通知、会议笔记。`meetings` 模块的 `unread_count` 由服务端按未读系统通知实时补齐。
|
||||||
- `GET /v1/im/bootstrap` 返回 `entry_badges.workbench_total_unread`,用于工作台一级入口总红点;总数只汇总当前用户可见且 `enabled=true` 的工作台模块。
|
- `GET /v1/im/bootstrap` 返回 `entry_badges.workbench_total_unread`,用于工作台一级入口总红点;当前只汇总“会议通知”模块的未读通知,会议笔记、日报、月报、打卡、部门框架和举报信箱均不产生工作台通知数。
|
||||||
- 服务端按当前 Token 的租户、组织角色和功能开关裁剪;前端只接受白名单内部 `route`,禁止直接执行服务端任意 URL。
|
- 服务端按当前 Token 的租户、组织角色和功能开关裁剪;前端只接受白名单内部 `route`,禁止直接执行服务端任意 URL。
|
||||||
- 工作台一级总未读以 `GET /v1/im/bootstrap` 和 `GET /v1/im/workbench` 返回为准;若后续启用 `workbench.badge.updated`,应按 0.5.4.6 的 `info.what="im"` 业务事件下发。切租户必须重新加载,不复用另一企业工作台。
|
- 工作台一级总未读以 `GET /v1/im/bootstrap` 和 `GET /v1/im/workbench` 返回为准;当前只有会议通知可接收移动端通知,其他工作台模块在进入页面时主动拉取数据刷新。若后续启用 `workbench.badge.updated`,应按 0.5.4.6 的 `info.what="im"` 业务事件下发。切租户必须重新加载,不复用另一企业工作台。
|
||||||
|
|
||||||
### 9.2 部门组织框架.png
|
### 9.2 部门组织框架.png
|
||||||
|
|
||||||
@@ -2251,7 +2292,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增。**
|
**状态:新增。**
|
||||||
|
|
||||||
- 创建:`POST /v1/im/meetings`,Body `{"title":"...","start_at":"...","end_at":"...","location":"...","attendee_user_ids":[],"reminder_minutes":[]}`。
|
- 创建:`POST /v1/im/meetings`,Body `{"title":"...","start_at":"...","end_at":"...","location":"...","recorder_user_id":"usr_me","attendee_user_ids":[],"reminder_minutes":[]}`;`recorder_user_id` 未传时服务端默认使用当前发起人。
|
||||||
- 详情:`GET /v1/im/meetings/{meeting_id}` 返回会议、参会人的 `response=pending|accepted|declined|tentative`、权限和 `version`。
|
- 详情:`GET /v1/im/meetings/{meeting_id}` 返回会议、参会人的 `response=pending|accepted|declined|tentative`、权限和 `version`。
|
||||||
- 更新/取消:`PATCH /v1/im/meetings/{id}`、`POST /v1/im/meetings/{id}/cancel`;提醒未响应者 `POST /v1/im/meetings/{id}/reminders`。所有写操作带幂等键并生成通知和审计。
|
- 更新/取消:`PATCH /v1/im/meetings/{id}`、`POST /v1/im/meetings/{id}/cancel`;提醒未响应者 `POST /v1/im/meetings/{id}/reminders`。所有写操作带幂等键并生成通知和审计。
|
||||||
- 主动下行:参会人收到 `info.what="im"`,事件为 `meeting.created/updated/canceled/reminded/response.updated`,payload 包含 `meeting_id,version,state`;前端收到后刷新会议列表或会议详情。除操作者外,当前会写入系统通知列表。
|
- 主动下行:参会人收到 `info.what="im"`,事件为 `meeting.created/updated/canceled/reminded/response.updated`,payload 包含 `meeting_id,version,state`;前端收到后刷新会议列表或会议详情。除操作者外,当前会写入系统通知列表。
|
||||||
@@ -2352,7 +2393,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
**状态:新增。**
|
**状态:新增。**
|
||||||
|
|
||||||
- 页面配置:`GET /v1/im/executive-mailbox/config` 返回 `enabled,allow_anonymous,required_fields,max_length,attachment_policy,notice`。
|
- 页面配置:`GET /v1/im/executive-mailbox/config` 返回 `enabled,allow_anonymous,required_fields,max_length,attachment_policy,notice`。
|
||||||
- 提交:`POST /v1/im/executive-mailbox/submissions`,Body `{"subject":"...","content":"...","anonymous":false,"attachment_file_ids":[]}`,带幂等键。
|
- 提交:`POST /v1/im/executive-mailbox/submissions`,Body `{"subject":"...","content":"...","anonymous":false,"attachment_file_ids":[]}`,带幂等键。`subject` 最多 200 字符,`content` 最多 5000 字符;超限返回 `VALIDATION_FAILED`,不返回 500。
|
||||||
- 成功仅返回 `submission_id,status:"received",submitted_at`;匿名模式下业务接收方不见身份,但安全审计是否保留内部追踪按企业政策执行并提前告知。
|
- 成功仅返回 `submission_id,status:"received",submitted_at`;匿名模式下业务接收方不见身份,但安全审计是否保留内部追踪按企业政策执行并提前告知。
|
||||||
|
|
||||||
### 9.13 总经理信箱-文案提示.png
|
### 9.13 总经理信箱-文案提示.png
|
||||||
@@ -2364,7 +2405,174 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
- 文案使用 9.12 配置中的 `notice{title,content,updated_at}`,由租户后台配置;客户端不得硬编码实名/匿名承诺。
|
- 文案使用 9.12 配置中的 `notice{title,content,updated_at}`,由租户后台配置;客户端不得硬编码实名/匿名承诺。
|
||||||
- 提交按钮前必须展示当前版本文案;请求可携带 `notice_version`,服务端发现关键政策已变更时返回 `NOTICE_RECONFIRM_REQUIRED`。
|
- 提交按钮前必须展示当前版本文案;请求可携带 `notice_version`,服务端发现关键政策已变更时返回 `NOTICE_RECONFIRM_REQUIRED`。
|
||||||
|
|
||||||
### 9.14 接口示例
|
### 9.14 会议笔记
|
||||||
|
|
||||||
|
会议笔记属于企业工作台模块,复用会议主数据和统一文件能力。服务端负责判断会议是否结束、当前用户是否与会议有关、是否为会议记录员,以及文件查看和操作权限;客户端只根据响应中的状态与 `permissions` 展示页面,不自行推导权限。
|
||||||
|
|
||||||
|
本模块遵循主文档第 0 章的公共约定:产品 HTTP 使用 `X-MeetingIM-APIKey`、`X-IM-Schema: 1`、`X-Request-ID` 和 `Authorization: Bearer <token>`;写操作额外使用 `Idempotency-Key`;成功和失败响应均使用统一包裹结构。
|
||||||
|
|
||||||
|
会议笔记不产生移动端通知、不写入会议通知未读数,也不增加工作台底部 Tab 红点。客户端进入会议笔记列表或详情页时主动请求最新数据;从上传、预览或下载页面返回后,只刷新当前会议笔记页面。
|
||||||
|
|
||||||
|
### 9.14.1 会议笔记-工作台入口.png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-工作台入口.png" alt="会议笔记-工作台入口" width="360">
|
||||||
|
|
||||||
|
**状态:工作台接口需改造。**
|
||||||
|
|
||||||
|
- `GET /v1/im/workbench` 的 `modules` 增加 `code="meeting_notes"`、`route="/meeting-notes"`。服务端按租户功能开关和当前用户权限决定是否返回该入口。
|
||||||
|
- 会议笔记模块固定返回 `unread_count=0`,不参与 `GET /v1/im/bootstrap` 的 `entry_badges.workbench_total_unread` 汇总。
|
||||||
|
- 当前工作台红点只对应“会议通知”模块的未读通知。日报、月报、打卡、部门框架、举报信箱和会议笔记均不产生工作台通知数。
|
||||||
|
- 客户端点击入口后请求 `GET /v1/im/meeting-notes`。切换企业后必须清空原租户的会议笔记缓存并重新加载。
|
||||||
|
|
||||||
|
### 9.14.2 会议笔记-列表.png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-列表.png" alt="会议笔记-列表" width="360">
|
||||||
|
|
||||||
|
**状态:新增。**
|
||||||
|
|
||||||
|
- 列表:`GET /v1/im/meeting-notes?query=&cursor=&limit=20`。接口只返回当前用户作为发起人、会议记录员或参会人的已结束会议,不返回未开始、进行中或已取消会议。
|
||||||
|
- `query` 支持匹配会议主题、发起人、会议记录员、参会人和地点;搜索范围仍受当前用户会议可见权限限制。
|
||||||
|
- 列表按 `end_at` 倒序排列,分页使用不透明 `cursor`。客户端不得用本地时间过滤会议状态或自行扩大搜索范围。
|
||||||
|
- 已结束但尚未上传笔记的会议仍返回,使用 `note_status="empty"`、`file_count=0`;客户端展示会议基础信息,进入详情后显示“暂无笔记”。
|
||||||
|
- `permissions.can_view=true` 决定是否允许进入详情;`permissions.can_upload` 只对当前会议记录员为 `true`。普通参会人可以进入详情,但不显示上传按钮。
|
||||||
|
- `state="ended"` 是服务端按会议状态及服务端当前时间计算或持久化的有效状态。服务端必须以 `end_at` 和取消状态为准,不能信任客户端传入的“已结束”条件。
|
||||||
|
|
||||||
|
### 9.14.3 会议笔记-发布页面.png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-发布页面.png" alt="会议笔记-发布页面" width="360">
|
||||||
|
|
||||||
|
**状态:现有会议创建接口需改造。**
|
||||||
|
|
||||||
|
- 页面字段顺序为发起人、地点、会议记录员、参会人、开始时间、时长、会议主题。会议记录员默认显示当前会议发起人。
|
||||||
|
- 创建仍使用 `POST /v1/im/meetings`,请求新增 `recorder_user_id`。客户端未传或传空字符串时,服务端默认使用当前登录用户;客户端不能通过 `organizer_id` 伪造发起人。
|
||||||
|
- 服务端校验会议记录员属于当前租户且账号有效。首版允许会议记录员是发起人或参会人;若选择了非参会人,服务端自动加入参会人列表并在响应中返回最终名单。
|
||||||
|
- 服务端保存的会议必须有 `recorder_user_id`;创建请求可省略该字段以使用发起人默认值。`attendee_user_ids`、`start_at`、`end_at` 和 `title` 为必填业务数据,`location` 可为空,且 `end_at` 必须晚于 `start_at`。
|
||||||
|
- 创建成功后的会议通知仍统一归属“会议通知”模块;会议笔记模块不额外生成通知或未读数。
|
||||||
|
- `PATCH /v1/im/meetings/{meeting_id}` 支持在会议结束前修改 `recorder_user_id`,并使用 `version` 做乐观锁。会议结束后返回 `MEETING_CLOSED`。
|
||||||
|
|
||||||
|
### 9.14.4 会议笔记-详情页.png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-详情页.png" alt="会议笔记-详情页" width="360">
|
||||||
|
|
||||||
|
**状态:新增。**
|
||||||
|
|
||||||
|
- 详情:`GET /v1/im/meetings/{meeting_id}/notes`,一次返回会议基础信息、发起人、会议记录员、参会人、文件列表、笔记状态和当前用户权限。
|
||||||
|
- 会议基础信息与会议通知页面共用 `im_meetings` 和 `im_meeting_participants` 数据,不复制会议标题、时间和成员快照作为另一份可编辑主数据。
|
||||||
|
- 当前用户为会议记录员且会议已结束时,`permissions.can_upload=true`,客户端展示“上传文件”;其他用户不展示该按钮。
|
||||||
|
- 上传文件先调用 `POST /v0/file/u/`,Multipart 携带 `purpose=meeting_note` 和 `meeting_id`;上传成功取得 `file_id` 后,再调用 `POST /v1/im/meetings/{meeting_id}/notes/files` 建立会议笔记文件记录。
|
||||||
|
- 文件登记成功后才进入详情列表。上传成功但登记失败的临时文件不得展示,并由服务端按临时文件 TTL 回收。
|
||||||
|
- 当前会议记录员可替换或删除自己登记的文件;所有写操作均需 `Idempotency-Key`,服务端记录操作审计。
|
||||||
|
|
||||||
|
### 9.14.5 会议笔记-详情页(普通成员).png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-详情页(普通成员).png" alt="会议笔记-详情页(普通成员)" width="360">
|
||||||
|
|
||||||
|
**状态:新增权限响应。**
|
||||||
|
|
||||||
|
- 普通参会人调用与 9.14.4 相同的详情接口。响应中 `permissions.can_view=true`、`can_upload=false`、`can_replace=false`、`can_delete=false`。
|
||||||
|
- 没有已上传文件时返回 `note_status="empty"` 和空数组 `files=[]`,客户端展示“暂无笔记”,不把空状态当作请求失败。
|
||||||
|
- 有文件时普通参会人只展示文件名、大小、类型、上传人、上传时间和预览入口,不展示上传、替换、删除按钮。
|
||||||
|
- 服务端必须在文件登记、替换、删除、预览和下载接口逐次校验会议关系及角色。隐藏客户端按钮不能代替服务端鉴权。
|
||||||
|
- 与会议无关、已离开可见范围或跨租户的用户统一返回 `RESOURCE_NOT_FOUND` 或 `FORBIDDEN`,不得通过 `meeting_id`、`note_file_id` 或 `file_id` 探测资源。
|
||||||
|
|
||||||
|
### 9.14.6 会议笔记-详情页-在线预览.png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-详情页-在线预览.png" alt="会议笔记-详情页-在线预览" width="360">
|
||||||
|
|
||||||
|
**状态:基础文件读取已实现;会议笔记 ACL 和预览转换新增。**
|
||||||
|
|
||||||
|
- 文件项返回 `preview.status=ready|processing|unsupported|failed`、`preview.mode=native|converted|download_only` 和可选 `preview_file_id`,客户端根据状态选择直接预览、轮询转换状态或提示暂不支持。
|
||||||
|
- 原生可预览文件使用受认证的 `GET /v0/file/s/{file_id}`;转换预览使用 `GET /v0/file/s/{preview_file_id}`。对象存储模式下服务端鉴权通过后返回 302 到短期签名 URL,客户端跟随 `Location` 获取文件内容。
|
||||||
|
- 服务端不得返回长期有效的公共下载 URL。客户端缓存键至少包含 `tenant_code + user_id + file_id + etag`,退出登录或切换企业时清理受控缓存。
|
||||||
|
- `preview.status="processing"` 时客户端可在当前详情页低频刷新,建议 2 秒后开始、最长 30 秒;离开页面立即停止轮询。
|
||||||
|
|
||||||
|
### 9.14.7 会议笔记-详情页-文件下载中.png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-详情页-文件下载中.png" alt="会议笔记-详情页-文件下载中" width="360">
|
||||||
|
|
||||||
|
**状态:复用统一下载任务;会议笔记 ACL 新增。**
|
||||||
|
|
||||||
|
- 下载使用 `GET /v0/file/s/{file_id}`,Header 传 API Key 与 `X-MeetingIM-Auth: token <base64_token>`,并支持 `Range` 和 `If-Range` 断点续传;对象存储模式下客户端跟随 302 `Location`。
|
||||||
|
- 下载任务保存 `file_id,etag,total_bytes,downloaded_bytes,temp_path,state`。Token 更新后使用新 Token 续传,禁止把 Token 写入任务文件或日志。
|
||||||
|
- 服务端在每次下载及续传时重新校验会议可见权限。返回 `FILE_FORBIDDEN` 时客户端停止重试;返回 `FILE_UNAVAILABLE` 时标记文件失效并刷新详情。
|
||||||
|
- 下载进度属于客户端本地状态,不更新会议笔记业务状态、不产生工作台通知,也不写入未读数。
|
||||||
|
|
||||||
|
### 9.14.8 会议笔记-文件预览.png
|
||||||
|
|
||||||
|
<img src="images/会议笔记-文件预览.png" alt="会议笔记-文件预览" width="360">
|
||||||
|
|
||||||
|
**状态:客户端预览页;服务端复用 9.14.6 文件读取协议。**
|
||||||
|
|
||||||
|
- 预览页展示服务端返回的安全文件名和实际内容;标题不得直接信任未经清理的上传文件名。
|
||||||
|
- 图片、PDF、文本等受支持类型在应用内预览;Office 等类型优先使用受控转换文件,无法转换时按 `preview.mode="download_only"` 提示下载后打开。
|
||||||
|
- 文件被删除、审核拒绝、转换失败或权限撤销时,服务端返回稳定 `reason`,客户端关闭预览并刷新详情,不能继续显示旧的授权链接。
|
||||||
|
- 从预览页返回详情后调用 `GET /v1/im/meetings/{meeting_id}/notes` 获取最新文件状态。
|
||||||
|
|
||||||
|
### 9.14.9 接口示例
|
||||||
|
|
||||||
|
以下示例用于会议笔记 HTTP 联调快速查阅。成功响应统一包裹为 `{"code":0,"data":示例,"request_id":"...","server_time":"..."}`,下表只展示 `data`。
|
||||||
|
|
||||||
|
#### 9.14.9.1 工作台、会议记录员与会议笔记
|
||||||
|
|
||||||
|
| 接口 | 输入示例 | 成功 `data` 示例 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `GET /v1/im/workbench` 需改造 | Query only | `{"layout_version":2,"modules":[{"code":"meeting_notifications","name":"会议通知","route":"/meetings","unread_count":3,"enabled":true,"permission":"enabled"},{"code":"meeting_notes","name":"会议笔记","route":"/meeting-notes","unread_count":0,"enabled":true,"permission":"enabled"}]}` |
|
||||||
|
| `POST /v1/im/meetings` 需改造 | Header `Idempotency-Key`;Body `{"title":"项目周会","start_at":"2026-09-05T10:00:00+08:00","end_at":"2026-09-05T10:30:00+08:00","location":"会议室 A","recorder_user_id":"usr_me","attendee_user_ids":["usr_2"],"reminder_minutes":[10]}` | `{"meeting_id":"mtg_1","title":"项目周会","organizer":{"user_id":"usr_me","display_name":"张三"},"recorder":{"user_id":"usr_me","display_name":"张三"},"start_at":"2026-09-05T02:00:00Z","end_at":"2026-09-05T02:30:00Z","state":"scheduled","participants":[{"user_id":"usr_me","response":"accepted"},{"user_id":"usr_2","response":"pending"}],"permissions":{"can_update":true,"can_cancel":true},"version":1}` |
|
||||||
|
| `PATCH /v1/im/meetings/{meeting_id}` 需改造 | Header `Idempotency-Key`;Body `{"recorder_user_id":"usr_2","version":1}` | `{"meeting_id":"mtg_1","recorder":{"user_id":"usr_2","display_name":"李四"},"version":2,"updated_at":"2026-09-05T01:30:00Z"}` |
|
||||||
|
| `GET /v1/im/meeting-notes?query=&cursor=&limit=20` 新增 | Query only | `{"items":[{"meeting_id":"mtg_1","title":"项目周会","organizer":{"user_id":"usr_me","display_name":"张三"},"recorder":{"user_id":"usr_me","display_name":"张三"},"start_at":"2026-09-05T02:00:00Z","end_at":"2026-09-05T02:30:00Z","location":"会议室 A","state":"ended","participant_count":2,"participant_names":["张三","李四"],"note_status":"empty","file_count":0,"permissions":{"can_view":true,"can_upload":true}}],"next_cursor":"","has_more":false}` |
|
||||||
|
| `GET /v1/im/meetings/{meeting_id}/notes` 新增 | Path meeting ID | `{"meeting":{"meeting_id":"mtg_1","title":"项目周会","organizer":{"user_id":"usr_me","display_name":"张三"},"recorder":{"user_id":"usr_me","display_name":"张三"},"start_at":"2026-09-05T02:00:00Z","end_at":"2026-09-05T02:30:00Z","location":"会议室 A","state":"ended","participants":[{"user_id":"usr_me","display_name":"张三"},{"user_id":"usr_2","display_name":"李四"}]},"note_status":"available","files":[{"note_file_id":"mnote_1","file_id":"file_1","name":"会议纪要.pdf","size":204800,"mime":"application/pdf","uploader":{"user_id":"usr_me","display_name":"张三"},"created_at":"2026-09-05T03:00:00Z","version":1,"preview":{"status":"ready","mode":"native","preview_file_id":"file_1"},"permissions":{"can_preview":true,"can_download":true,"can_replace":true,"can_delete":true}}],"permissions":{"can_view":true,"can_upload":true},"version":1}` |
|
||||||
|
| `POST /v0/file/u/` | Multipart 文件;字段 `purpose=meeting_note`、`meeting_id=mtg_1`;Header `X-MeetingIM-Auth` | `{"ctrl":{"code":200,"params":{"file_id":"file_1","url":"/v0/file/s/file_1","name":"会议纪要.pdf","size":204800,"mime":"application/pdf"}}}` |
|
||||||
|
| `POST /v1/im/meetings/{meeting_id}/notes/files` 新增 | Header `Idempotency-Key`;Body `{"file_id":"file_1"}` | `{"note_file_id":"mnote_1","meeting_id":"mtg_1","file_id":"file_1","name":"会议纪要.pdf","size":204800,"mime":"application/pdf","created_at":"2026-09-05T03:00:00Z","version":1,"preview":{"status":"processing","mode":"converted"}}` |
|
||||||
|
| `PUT /v1/im/meetings/{meeting_id}/notes/files/{note_file_id}` 新增 | Header `Idempotency-Key`;Body `{"file_id":"file_2","version":1}` | `{"note_file_id":"mnote_1","meeting_id":"mtg_1","file_id":"file_2","name":"会议纪要-v2.pdf","version":2,"updated_at":"2026-09-05T03:10:00Z"}` |
|
||||||
|
| `DELETE /v1/im/meetings/{meeting_id}/notes/files/{note_file_id}` 新增 | Header `Idempotency-Key`;Query `version=2` | `{"note_file_id":"mnote_1","deleted":true,"deleted_at":"2026-09-05T03:20:00Z"}` |
|
||||||
|
| `GET /v0/file/s/{file_id}` | Header `X-MeetingIM-Auth`;可带 `Range: bytes=0-` | 对象存储模式下鉴权通过后返回 302 到短期签名 URL;客户端跟随 Location 获取文件内容 |
|
||||||
|
|
||||||
|
### 9.14.10 字段与状态约定
|
||||||
|
|
||||||
|
| 字段 | 取值 | 前端处理 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `meeting.state` | `scheduled`、`in_progress`、`ended`、`canceled` | 会议笔记列表只展示 `ended` |
|
||||||
|
| `note_status` | `empty`、`available` | `empty` 展示“暂无笔记”,`available` 展示文件列表 |
|
||||||
|
| `preview.status` | `ready`、`processing`、`unsupported`、`failed` | 分别进入预览、短时刷新、仅下载提示、失败提示 |
|
||||||
|
| `preview.mode` | `native`、`converted`、`download_only` | 使用原文件、转换文件或仅提供下载 |
|
||||||
|
| `permissions.can_view` | Boolean | 是否可以查看当前会议笔记 |
|
||||||
|
| `permissions.can_upload` | Boolean | 是否显示并允许使用上传按钮,仅会议记录员为 `true` |
|
||||||
|
| `permissions.can_replace` | Boolean | 是否允许替换当前笔记文件 |
|
||||||
|
| `permissions.can_delete` | Boolean | 是否允许删除当前笔记文件 |
|
||||||
|
| `permissions.can_preview` | Boolean | 是否允许预览当前文件 |
|
||||||
|
| `permissions.can_download` | Boolean | 是否允许下载当前文件;首版普通参会人若产品要求“只能预览”,该值返回 `false` |
|
||||||
|
|
||||||
|
客户端必须以服务端返回的 `permissions` 为准。特别是普通参会人“只能预览”的要求,由文件项 `can_preview=true,can_download=false` 表达;即使预览底层使用文件读取接口,客户端也不得提供导出、系统分享或保存到相册入口。
|
||||||
|
|
||||||
|
### 9.14.11 错误码与客户端处理
|
||||||
|
|
||||||
|
| `reason` | 典型 HTTP 状态 | 场景 | 客户端处理 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `MEETING_NOT_ENDED` | 409 | 未结束会议上传或登记笔记 | 提示“会议结束后可上传笔记”,刷新会议详情 |
|
||||||
|
| `MEETING_CLOSED` | 409 | 会议结束后修改记录员或会议数据 | 切换为只读并刷新详情 |
|
||||||
|
| `NOT_MEETING_RECORDER` | 403 | 非记录员上传、替换或删除文件 | 隐藏操作入口并刷新权限 |
|
||||||
|
| `MEETING_NOTE_VERSION_CONFLICT` | 409 | 替换或删除时版本过期 | 拉取最新详情,不自动覆盖 |
|
||||||
|
| `MEETING_NOTE_FILE_INVALID` | 400 | 文件未上传完成、用途不符或不属于当前租户 | 提示重新上传 |
|
||||||
|
| `FILE_PREVIEW_PROCESSING` | 409 | 转换预览尚未完成 | 保持当前页并按退避策略刷新 |
|
||||||
|
| `FILE_PREVIEW_UNSUPPORTED` | 422 | 文件类型不支持在线预览 | 根据 `can_download` 决定是否提供下载 |
|
||||||
|
| `FILE_FORBIDDEN` | 403 | 当前用户无文件访问权限 | 关闭预览或停止下载并刷新详情 |
|
||||||
|
| `FILE_UNAVAILABLE` | 404/410 | 文件被删除、失效或审核拒绝 | 标记不可用并刷新文件列表 |
|
||||||
|
| `RESOURCE_NOT_FOUND` | 404 | 会议或笔记不可见、跨租户访问 | 返回列表,不提示资源是否真实存在 |
|
||||||
|
|
||||||
|
### 9.14.12 前后端联调与验收要点
|
||||||
|
|
||||||
|
1. 发起会议时不传 `recorder_user_id`,响应中的记录员必须默认为当前发起人;指定其他记录员时,响应返回最终记录员和参会人名单。
|
||||||
|
2. 会议笔记列表只包含与当前用户有关的已结束会议;已结束但无文件的会议仍展示,详情为空状态。
|
||||||
|
3. 记录员进入详情显示上传按钮,普通参会人进入同一会议不显示上传按钮;直接调用写接口仍必须被服务端拒绝。
|
||||||
|
4. 普通参会人只允许在线预览时,响应为 `can_preview=true,can_download=false`,客户端不展示下载、分享或导出入口。
|
||||||
|
5. 文件上传成功但会议笔记登记失败时,详情列表不出现该文件;重复登记同一幂等键返回首次结果。
|
||||||
|
6. 文件替换和删除必须校验 `version`;旧版本请求返回冲突,不能覆盖新文件。
|
||||||
|
7. 进入列表、进入详情以及从上传/预览/下载页面返回时均主动刷新;断开 WebSocket 不影响会议笔记数据获取。
|
||||||
|
8. 会议笔记新增、替换、删除均不产生 Push、会议通知未读或工作台红点;工作台红点只随会议通知模块变化。
|
||||||
|
9. 跨租户、无关用户和已撤销权限用户无法通过会议 ID 或文件 ID 查看、预览、下载会议笔记。
|
||||||
|
10. 切换企业或退出登录后,会议笔记列表、详情、预览文件和下载临时数据按租户及账号隔离清理。
|
||||||
|
|
||||||
|
### 9.15 接口示例
|
||||||
|
|
||||||
以下示例用于本章 HTTP 联调快速查阅。除特别说明外:
|
以下示例用于本章 HTTP 联调快速查阅。除特别说明外:
|
||||||
|
|
||||||
@@ -2374,11 +2582,11 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
- 失败响应统一包裹为 `{"code":30000,"reason":"MALFORMED_REQUEST","message":"...","details":{},"request_id":"...","server_time":"..."}`。
|
- 失败响应统一包裹为 `{"code":30000,"reason":"MALFORMED_REQUEST","message":"...","details":{},"request_id":"...","server_time":"..."}`。
|
||||||
- 标注“待实现/需修复”的接口是产品目标协议,前端可按示例准备,但联调前以后端发布状态为准。
|
- 标注“待实现/需修复”的接口是产品目标协议,前端可按示例准备,但联调前以后端发布状态为准。
|
||||||
|
|
||||||
#### 9.14.1 工作台、组织、打卡、会议、日报、月报、信箱
|
#### 9.15.1 工作台、组织、打卡、会议、日报、月报、信箱
|
||||||
|
|
||||||
| 接口 | 输入示例 | 成功 `data` 示例 |
|
| 接口 | 输入示例 | 成功 `data` 示例 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `GET /v1/im/workbench` | Query only | `{"layout_version":1,"modules":[{"code":"organization","name":"组织架构","icon_file_id":"","route":"/organization","unread_count":0,"enabled":true,"permission":"enabled"},{"code":"attendance","name":"打卡考勤","icon_file_id":"","route":"/attendance","unread_count":0,"enabled":true,"permission":"enabled"}],"enterprise":{"tenant_code":"default","feature_flags":{"organization":true,"attendance":true,"meetings":true}}}` |
|
| `GET /v1/im/workbench` | Query only | `{"layout_version":2,"modules":[{"code":"attendance","name":"打卡","icon_file_id":"","route":"/attendance","sort_order":10,"unread_count":0,"enabled":true,"permission":"enabled"},{"code":"monthly_reports","name":"月报","icon_file_id":"","route":"/reports/monthly","sort_order":20,"unread_count":0,"enabled":true,"permission":"enabled"},{"code":"daily_reports","name":"日报","icon_file_id":"","route":"/reports/daily","sort_order":30,"unread_count":0,"enabled":true,"permission":"enabled"},{"code":"organization","name":"部门框架","icon_file_id":"","route":"/organization","sort_order":40,"unread_count":0,"enabled":true,"permission":"enabled"},{"code":"executive_mailbox","name":"举报信箱","icon_file_id":"","route":"/executive-mailbox","sort_order":50,"unread_count":0,"enabled":true,"permission":"enabled"},{"code":"meetings","name":"会议通知","icon_file_id":"","route":"/meetings","sort_order":60,"unread_count":3,"enabled":true,"permission":"enabled"},{"code":"meeting_notes","name":"会议笔记","icon_file_id":"","route":"/meeting-notes","sort_order":70,"unread_count":0,"enabled":true,"permission":"enabled"}],"enterprise":{"tenant_code":"default","feature_flags":{"organization":true,"attendance":true,"meetings":true,"meeting_notes":true}}}` |
|
||||||
| `GET /v1/im/organization/departments?parent_id=root&cursor=` | Query only | `{"items":[{"department_id":"dep_1","name":"研发部","parent_id":"root","child_count":0,"member_count":12,"version":1}],"next_cursor":""}` |
|
| `GET /v1/im/organization/departments?parent_id=root&cursor=` | Query only | `{"items":[{"department_id":"dep_1","name":"研发部","parent_id":"root","child_count":0,"member_count":12,"version":1}],"next_cursor":""}` |
|
||||||
| `GET /v1/im/organization/departments/{id}/members?cursor=` | Query only | `{"items":[{"user_id":"usr...","display_name":"张三","avatar_file_id":"","department_id":"dep_1","title":"工程师","can_contact":true}],"next_cursor":""}` |
|
| `GET /v1/im/organization/departments/{id}/members?cursor=` | Query only | `{"items":[{"user_id":"usr...","display_name":"张三","avatar_file_id":"","department_id":"dep_1","title":"工程师","can_contact":true}],"next_cursor":""}` |
|
||||||
| `GET /v1/im/organization/members?query=&department_id=&cursor=` 待实现/可由部门成员接口替代 | Query only | `{"items":[{"user_id":"usr...","display_name":"张三","department_id":"dep_1","department_name":"研发部","can_contact":true}],"next_cursor":""}` |
|
| `GET /v1/im/organization/members?query=&department_id=&cursor=` 待实现/可由部门成员接口替代 | Query only | `{"items":[{"user_id":"usr...","display_name":"张三","department_id":"dep_1","department_name":"研发部","can_contact":true}],"next_cursor":""}` |
|
||||||
@@ -2390,7 +2598,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| `POST /v1/im/attendance/appeals` | Header `Idempotency-Key`;Body `{"record_id":"evt_...","appeal_type":"missing_checkin","reason":"外出拜访客户,忘记打卡","target_action":"check_in","target_time":"2026-08-31T09:00:00+08:00","attachment_file_ids":["file_1"]}` | `{"appeal_id":"atta_...","record_id":"evt_...","user_id":"usr...","appeal_type":"missing_checkin","reason":"外出拜访客户,忘记打卡","target_action":"check_in","target_time":"2026-08-31T01:00:00Z","attachment_file_ids":["file_1"],"status":"pending","submitted_at":"2026-08-31T03:00:00Z","version":1}` |
|
| `POST /v1/im/attendance/appeals` | Header `Idempotency-Key`;Body `{"record_id":"evt_...","appeal_type":"missing_checkin","reason":"外出拜访客户,忘记打卡","target_action":"check_in","target_time":"2026-08-31T09:00:00+08:00","attachment_file_ids":["file_1"]}` | `{"appeal_id":"atta_...","record_id":"evt_...","user_id":"usr...","appeal_type":"missing_checkin","reason":"外出拜访客户,忘记打卡","target_action":"check_in","target_time":"2026-08-31T01:00:00Z","attachment_file_ids":["file_1"],"status":"pending","submitted_at":"2026-08-31T03:00:00Z","version":1}` |
|
||||||
| `GET /v1/im/attendance/appeals?scope=mine&status=pending&cursor=` | Query only | `{"items":[{"appeal_id":"atta_...","record_id":"evt_...","user_id":"usr...","appeal_type":"missing_checkin","status":"pending","submitted_at":"2026-08-31T03:00:00Z","version":1}],"next_cursor":"","has_more":false}` |
|
| `GET /v1/im/attendance/appeals?scope=mine&status=pending&cursor=` | Query only | `{"items":[{"appeal_id":"atta_...","record_id":"evt_...","user_id":"usr...","appeal_type":"missing_checkin","status":"pending","submitted_at":"2026-08-31T03:00:00Z","version":1}],"next_cursor":"","has_more":false}` |
|
||||||
| `GET /v1/im/meetings?cursor=` 待补列表 | Query only | `{"items":[{"meeting_id":"mtg_1","title":"周会","start_at":"2026-08-21T10:00:00Z","end_at":"2026-08-21T10:30:00Z","my_response":"pending","state":"scheduled"}],"next_cursor":""}` |
|
| `GET /v1/im/meetings?cursor=` 待补列表 | Query only | `{"items":[{"meeting_id":"mtg_1","title":"周会","start_at":"2026-08-21T10:00:00Z","end_at":"2026-08-21T10:30:00Z","my_response":"pending","state":"scheduled"}],"next_cursor":""}` |
|
||||||
| `POST /v1/im/meetings` | `{"title":"周会","start_at":"2026-08-21T10:00:00Z","end_at":"2026-08-21T10:30:00Z","location":"线上","attendee_user_ids":["usr..."],"reminder_minutes":[10]}` | `{"meeting_id":"mtg_1","title":"周会","start_at":"2026-08-21T10:00:00Z","end_at":"2026-08-21T10:30:00Z","location":"线上","participants":[{"user_id":"usr_me","response":"accepted"},{"user_id":"usr...","response":"pending"}],"permissions":{"can_update":true,"can_cancel":true,"can_remind":true,"can_respond":false},"version":1}` |
|
| `POST /v1/im/meetings` | `{"title":"周会","start_at":"2026-08-21T10:00:00Z","end_at":"2026-08-21T10:30:00Z","location":"线上","recorder_user_id":"usr_me","attendee_user_ids":["usr..."],"reminder_minutes":[10]}` | `{"meeting_id":"mtg_1","title":"周会","recorder":{"user_id":"usr_me","display_name":"张三"},"start_at":"2026-08-21T10:00:00Z","end_at":"2026-08-21T10:30:00Z","location":"线上","participants":[{"user_id":"usr_me","response":"accepted"},{"user_id":"usr...","response":"pending"}],"permissions":{"can_update":true,"can_cancel":true,"can_remind":true,"can_respond":false},"version":1}` |
|
||||||
| `GET /v1/im/meetings/{meeting_id}` | Path meeting ID | `{"meeting_id":"mtg_1","title":"周会","participants":[{"user_id":"usr...","response":"pending"}],"permissions":{"can_respond":true},"version":1}` |
|
| `GET /v1/im/meetings/{meeting_id}` | Path meeting ID | `{"meeting_id":"mtg_1","title":"周会","participants":[{"user_id":"usr...","response":"pending"}],"permissions":{"can_respond":true},"version":1}` |
|
||||||
| `PATCH /v1/im/meetings/{id}` | `{"title":"新标题","version":1}` | `{"meeting_id":"mtg_1","title":"新标题","version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
| `PATCH /v1/im/meetings/{id}` | `{"title":"新标题","version":1}` | `{"meeting_id":"mtg_1","title":"新标题","version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `POST /v1/im/meetings/{id}/cancel` | `{"version":2,"reason":"时间冲突"}` | `{"meeting_id":"mtg_1","state":"cancelled","version":3}` |
|
| `POST /v1/im/meetings/{id}/cancel` | `{"version":2,"reason":"时间冲突"}` | `{"meeting_id":"mtg_1","state":"cancelled","version":3}` |
|
||||||
@@ -2486,7 +2694,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
**状态:菜单纯客户端;数据接口部分新增。**
|
**状态:菜单纯客户端;数据接口部分新增。**
|
||||||
|
|
||||||
- 菜单来自 `bootstrap.settings_menu`,安全、通知、隐私、通用、关于按权限展示。系统通知权限状态由 iOS API 读取,不由服务端伪造。
|
- 菜单来自 `bootstrap.settings_menu`,安全、通知、隐私、通用、关于按权限展示。系统通知权限状态由 iOS API 读取,不由服务端伪造。
|
||||||
- 退出:`POST /v1/im/auth/logout` 撤销当前登录 Token 对应的设备会话,成功或 Token 已失效后关闭 WS、清安全存储和本租户用户缓存。
|
- 退出:`POST /v1/im/auth/logout` 将当前登录 Token 的 SHA-256 摘要写入 Redis 撤销集合,TTL 与 Token 剩余有效期一致,不影响同账号其他设备。成功后关闭 WS、清安全存储和本租户用户缓存;请求须带 `Authorization: Bearer <token>` 和 `Idempotency-Key`。
|
||||||
- 多设备退出使用 `DELETE /v1/im/security/sessions/{session_id}`,需二次验证。
|
- 多设备退出使用 `DELETE /v1/im/security/sessions/{session_id}`,需二次验证。
|
||||||
|
|
||||||
### 10.8 设置(安卓).png
|
### 10.8 设置(安卓).png
|
||||||
@@ -2513,8 +2721,10 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增 App 配置接口。**
|
**状态:新增 App 配置接口。**
|
||||||
|
|
||||||
- `GET /v1/im/app/releases/latest?platform=ios|android¤t_version=1.0.0&channel=stable`,未登录可在企业解析后调用。
|
- `GET /v1/im/app/releases/latest?platform=ios|android¤t_version=1.0.0&channel=stable`,全局公共接口,不依赖租户解析。`current_version` 必传,使用数字点分版本号(如 `1.2.0`)。
|
||||||
- 返回 `latest_version,min_supported_version,update_type=none|optional|required,release_notes,store_url,package_url,checksum,published_at`。
|
- 服务端返回 `has_update`、`force_update` 和 `update_type=none|recommended|force`;iOS 客户端使用 `store_url` 跳转 App Store。
|
||||||
|
- 版本策略由 Admin 在 `hotgo.im_app_releases` 统一管理,IM Server 通过 HMAC 内部配置接口读取,不从租户库查询。
|
||||||
|
- 返回 `current_version,has_update,force_update,latest_version,min_supported_version,update_type=none|recommended|force,release_notes,store_url,package_url,checksum,published_at`。
|
||||||
- 客户端按平台只打开受信任商店/签名下载地址;Android 包必须校验签名和 checksum,服务端 URL 使用允许域名。
|
- 客户端按平台只打开受信任商店/签名下载地址;Android 包必须校验签名和 checksum,服务端 URL 使用允许域名。
|
||||||
|
|
||||||
### 10.11 发现新版本.png
|
### 10.11 发现新版本.png
|
||||||
@@ -2532,7 +2742,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
|
|
||||||
**状态:新增。**
|
**状态:新增。**
|
||||||
|
|
||||||
- `GET /v1/im/me/privacy` 返回 `add_me_methods,profile_visibility,last_seen_visibility,read_receipts,version` 和各字段 `editable`。
|
- `GET /v1/im/me/privacy` 返回 `add_me_methods,profile_visibility,last_seen_visibility,read_receipts,group_invite_verification,version` 和各字段 `editable`;`group_invite_verification=true` 表示别人邀请我入群时需要走入群审批。
|
||||||
- `PATCH /v1/im/me/privacy` 只提交变更字段和 `version`;成功返回完整最新配置并向其他设备推送 `privacy.updated`。
|
- `PATCH /v1/im/me/privacy` 只提交变更字段和 `version`;成功返回完整最新配置并向其他设备推送 `privacy.updated`。
|
||||||
- 黑名单入口使用 5.12。服务端在搜索、主页、回执等实际读写路径执行隐私规则,不能只保存开关。
|
- 黑名单入口使用 5.12。服务端在搜索、主页、回执等实际读写路径执行隐私规则,不能只保存开关。
|
||||||
|
|
||||||
@@ -2640,8 +2850,8 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| `GET /v1/im/me` | Query only | `{"user_id":"usr...","profile":{"public_account":"usr...","nickname":"张三","avatar_file_id":"","signature":"","version":1},"profile_version":1,"realname":{"status":"unverified"},"youth_mode":{"enabled":false}}` |
|
| `GET /v1/im/me` | Query only | `{"user_id":"usr...","profile":{"public_account":"usr...","nickname":"张三","avatar_file_id":"","signature":"","version":1},"profile_version":1,"realname":{"status":"unverified"},"youth_mode":{"enabled":false}}` |
|
||||||
| `GET /v1/im/me/profile` | Query only | `{"avatar_file_id":"","nickname":"张三","birth_date":"1990-01-01","signature":"签名","gender":"male","region":"上海","email":"a@example.com","public_account":"usr...","version":1,"field_rules":{"nickname":{"min_length":1,"max_length":32},"signature":{"max_length":120}}}` |
|
| `GET /v1/im/me/profile` | Query only | `{"avatar_file_id":"","nickname":"张三","birth_date":"1990-01-01","signature":"签名","gender":"male","region":"上海","email":"a@example.com","public_account":"usr...","version":1,"field_rules":{"nickname":{"min_length":1,"max_length":32},"signature":{"max_length":120}}}` |
|
||||||
| `PATCH /v1/im/me/profile` | `{"nickname":"新昵称","signature":"新签名","version":1}` | `{"avatar_file_id":"","nickname":"新昵称","signature":"新签名","version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
| `PATCH /v1/im/me/profile` | `{"nickname":"新昵称","signature":"新签名","version":1}` | `{"avatar_file_id":"","nickname":"新昵称","signature":"新签名","version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `GET /v1/im/me/privacy` | Query only | `{"add_me_methods":{"account":true,"phone":true,"qr":true,"group":true},"profile_visibility":"friends","last_seen_visibility":"friends","read_receipts":true,"version":1,"editable":{"add_me_methods":true,"profile_visibility":true,"last_seen_visibility":true,"read_receipts":true}}` |
|
| `GET /v1/im/me/privacy` | Query only | `{"add_me_methods":{"account":true,"phone":true,"qr":true,"group":true},"profile_visibility":"friends","last_seen_visibility":"friends","read_receipts":true,"group_invite_verification":false,"version":1,"editable":{"add_me_methods":true,"profile_visibility":true,"last_seen_visibility":true,"read_receipts":true,"group_invite_verification":true}}` |
|
||||||
| `PATCH /v1/im/me/privacy` | `{"add_me_methods":{"phone":false},"read_receipts":false,"version":1}` | `{"add_me_methods":{"account":true,"phone":false,"qr":true,"group":true},"read_receipts":false,"version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
| `PATCH /v1/im/me/privacy` | `{"add_me_methods":{"phone":false},"read_receipts":false,"group_invite_verification":true,"version":1}` | `{"add_me_methods":{"account":true,"phone":false,"qr":true,"group":true},"read_receipts":false,"group_invite_verification":true,"version":2,"updated_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `GET /v1/im/settings/youth-mode` | Query only | `{"enabled":false,"policy_version":1,"restrictions":["night_quiet","content_filter","payment_guard"],"restriction_items":[{"code":"night_quiet","title":"深夜免打扰","description":"夜间减少消息提醒打扰,帮助用户保持健康作息。","enforced":false},{"code":"content_filter","title":"内容过滤","description":"对不适合青少年的内容进行识别和限制展示。","enforced":false},{"code":"payment_guard","title":"支付守护","description":"限制或确认支付、充值等敏感消费行为。","enforced":false}],"password_set":false,"can_enable":false,"updated_at":"2026-08-20T09:00:00Z"}` |
|
| `GET /v1/im/settings/youth-mode` | Query only | `{"enabled":false,"policy_version":1,"restrictions":["night_quiet","content_filter","payment_guard"],"restriction_items":[{"code":"night_quiet","title":"深夜免打扰","description":"夜间减少消息提醒打扰,帮助用户保持健康作息。","enforced":false},{"code":"content_filter","title":"内容过滤","description":"对不适合青少年的内容进行识别和限制展示。","enforced":false},{"code":"payment_guard","title":"支付守护","description":"限制或确认支付、充值等敏感消费行为。","enforced":false}],"password_set":false,"can_enable":false,"updated_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `POST /v1/im/settings/independent-password` | `{"password":"1234","purpose":"youth_mode","action_token":"action_token"}` | `{"status":"ok","password_set":true,"purpose":"youth_mode","enable_action_token":"enable_token","enable_action_expires_at":"2026-08-20T09:05:00Z","next_action":"enable_youth_mode"}` |
|
| `POST /v1/im/settings/independent-password` | `{"password":"1234","purpose":"youth_mode","action_token":"action_token"}` | `{"status":"ok","password_set":true,"purpose":"youth_mode","enable_action_token":"enable_token","enable_action_expires_at":"2026-08-20T09:05:00Z","next_action":"enable_youth_mode"}` |
|
||||||
| `POST /v1/im/settings/independent-password/verify` | `{"password":"1234","purpose":"close_youth_mode"}` | `{"action_token":"action_token","action":"close_youth_mode","expires_at":"2026-08-20T09:05:00Z"}` |
|
| `POST /v1/im/settings/independent-password/verify` | `{"password":"1234","purpose":"close_youth_mode"}` | `{"action_token":"action_token","action":"close_youth_mode","expires_at":"2026-08-20T09:05:00Z"}` |
|
||||||
@@ -2655,7 +2865,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| `GET /v1/im/security/realname` | Query only | `{"status":"unverified","can_submit":true}` |
|
| `GET /v1/im/security/realname` | Query only | `{"status":"unverified","can_submit":true}` |
|
||||||
| `POST /v1/im/security/realname/submissions` | `{"name":"张三","id_type":"cn_id","id_number":"110101199001011234"}` | `{"submission_id":"rn_1","status":"pending","can_submit":false}` |
|
| `POST /v1/im/security/realname/submissions` | `{"name":"张三","id_type":"cn_id","id_number":"110101199001011234"}` | `{"submission_id":"rn_1","status":"pending","can_submit":false}` |
|
||||||
| `POST /v1/im/security/realname/appeals` 待实现 | `{"reason":"证件变更","description":"需要更正实名信息","action_token":"action_token"}` | `{"appeal_id":"rna_1","status":"pending","submitted_at":"2026-08-20T09:00:00Z"}` |
|
| `POST /v1/im/security/realname/appeals` 待实现 | `{"reason":"证件变更","description":"需要更正实名信息","action_token":"action_token"}` | `{"appeal_id":"rna_1","status":"pending","submitted_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `PUT /v1/im/devices/{device_id}/push-token` | `{"provider":"fcm","token":"push_token","platform":"android","app_version":"1.0.0"}` | `{"device_id":"device_1","provider":"fcm","platform":"android","app_version":"1.0.0","updated_at":"2026-08-20T09:00:00Z"}` |
|
| `PUT /v1/im/devices/{device_id}/push-token` | `{"provider":"jpush","token":"registration_id","platform":"android","app_version":"1.0.0","push_env":"test","sdk_version":"5.0.0","notification_permission":"granted"}` | `{"device_id":"device_1","provider":"jpush","platform":"android","app_version":"1.0.0","updated_at":"2026-08-20T09:00:00Z"}` |
|
||||||
| `DELETE /v1/im/security/sessions/{session_id}` 待实现 | Header `X-Action-Token: action_token` | `{"session_id":"sess_1","revoked":true}` |
|
| `DELETE /v1/im/security/sessions/{session_id}` 待实现 | Header `X-Action-Token: action_token` | `{"session_id":"sess_1","revoked":true}` |
|
||||||
|
|
||||||
## 11. 反诈安全、举报与意见反馈
|
## 11. 反诈安全、举报与意见反馈
|
||||||
@@ -2749,12 +2959,12 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| P0 | 企业码解析、验证码、密码重置、二次认证、Token `auth_version`、登录换新和撤销 | 1.1~1.11、10.7~10.8 |
|
| P0 | 企业码解析、验证码、密码重置、二次认证、Token `auth_version`、登录换新和撤销 | 1.1~1.11、10.7~10.8 |
|
||||||
| P0 | 普通用户禁止发布系统 Topic;系统通知和业务事件可信生产通道 | 2.5、3.1~3.5、6.4、11.1 |
|
| P0 | 普通用户禁止发布系统 Topic;系统通知和业务事件可信生产通道 | 2.5、3.1~3.5、6.4、11.1 |
|
||||||
| P0 | 消息 `x-im-schema/type/client-mid` 校验和服务端幂等 | 2~4 章 |
|
| P0 | 消息 `x-im-schema/type/client-mid` 校验和服务端幂等 | 2~4 章 |
|
||||||
| P0 | 文件资源级 ACL、Range、ETag、用途绑定和租户存储配额 | 3.6、4.10~4.14、6.27~7.16、11.4~11.5 |
|
| P0 | 文件资源级 ACL、Range、ETag、用途绑定和租户存储配额 | 3.6、4.10~4.14、6.27~7.16、9.14、11.4~11.5 |
|
||||||
| P1 | 好友申请、好友关系、黑名单状态机 | 第 3、5 章 |
|
| P1 | 好友申请、好友关系、黑名单状态机 | 第 3、5 章 |
|
||||||
| P1 | 群成员、角色、禁言、公告、邀请审批和配额 | 第 6 章 |
|
| P1 | 群成员、角色、禁言、公告、邀请审批和配额 | 第 6 章 |
|
||||||
| P1 | 收藏、转发和聊天记录搜索 | 第 4、7 章 |
|
| P1 | 收藏、转发和聊天记录搜索 | 第 4、7 章 |
|
||||||
| P1 | 通话媒体状态、结果消息、Push 来电 | 第 8 章 |
|
| P1 | 通话媒体状态、结果消息、Push 来电 | 第 8 章 |
|
||||||
| P2 | 工作台、组织、会议、日报、月报、信箱 | 第 9 章 |
|
| P2 | 工作台、组织、会议、会议笔记、日报、月报、信箱 | 第 9 章 |
|
||||||
| P2 | 隐私、青少年模式、反诈、举报、反馈 | 第 10、11 章 |
|
| P2 | 隐私、青少年模式、反诈、举报、反馈 | 第 10、11 章 |
|
||||||
|
|
||||||
### 12.3 前后端联调最低验收用例
|
### 12.3 前后端联调最低验收用例
|
||||||
|
|||||||
+2
-2
@@ -39,7 +39,7 @@
|
|||||||
| 群文件列表、登记、删除 | 已实现 | 新增 `GET/POST/DELETE /v1/im/groups/{topic}/files`,复用现有群文件表。 |
|
| 群文件列表、登记、删除 | 已实现 | 新增 `GET/POST/DELETE /v1/im/groups/{topic}/files`,复用现有群文件表。 |
|
||||||
| 普通消息转发 | 未实现 | 待下一步接入消息快照、目标权限校验和消息落库。 |
|
| 普通消息转发 | 未实现 | 待下一步接入消息快照、目标权限校验和消息落库。 |
|
||||||
| 合并转发 Bundle 详情 | 未实现 | 待下一步新增 bundle 表和详情接口。 |
|
| 合并转发 Bundle 详情 | 未实现 | 待下一步新增 bundle 表和详情接口。 |
|
||||||
| 登出与指定会话撤销 | 未实现 | 当前 token 缺少独立 session 标识,需要先统一 session 模型。 |
|
| 登出与指定会话撤销 | 部分实现 | `POST /v1/im/auth/logout` 已通过 Redis 精准撤销当前 token;按 session ID 撤销指定设备仍待统一 session 模型。 |
|
||||||
| 列表 `has_more` 统一 | 部分实现 | 新增/触达接口已补,历史接口需继续横向清理。 |
|
| 列表 `has_more` 统一 | 部分实现 | 新增/触达接口已补,历史接口需继续横向清理。 |
|
||||||
| 风控 token 单次消费接入业务接口 | 未实现 | 待和具体业务动作一起接入。 |
|
| 风控 token 单次消费接入业务接口 | 未实现 | 待和具体业务动作一起接入。 |
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
| 模块 | 优先级 | 开发项 | 是否依赖第三方 | 当前状态 |
|
| 模块 | 优先级 | 开发项 | 是否依赖第三方 | 当前状态 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| 账号安全 | P0 | 登出与指定会话撤销 | 否 | 文档有接口,代码未见路由 |
|
| 账号安全 | P0 | 登出与指定会话撤销 | 否 | 当前 token 登出已实现;指定 session 撤销待实现 |
|
||||||
| 消息转发 | P0 | 普通消息转发 | 否 | 仅转发目标接口已实现 |
|
| 消息转发 | P0 | 普通消息转发 | 否 | 仅转发目标接口已实现 |
|
||||||
| 消息转发 | P0 | 合并转发 Bundle 详情 | 否 | 文档有接口,代码未见路由 |
|
| 消息转发 | P0 | 合并转发 Bundle 详情 | 否 | 文档有接口,代码未见路由 |
|
||||||
| 群聊 | P0 | 群文件列表、登记、删除 | 否 | 路径已不误兜底,但业务未实现 |
|
| 群聊 | P0 | 群文件列表、登记、删除 | 否 | 路径已不误兜底,但业务未实现 |
|
||||||
|
|||||||
+11
-9
@@ -732,6 +732,7 @@ CREATE TABLE IF NOT EXISTS tinode.im_user_privacy_settings (
|
|||||||
profile_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
profile_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
||||||
last_seen_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
last_seen_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
||||||
read_receipts TINYINT NOT NULL DEFAULT 1,
|
read_receipts TINYINT NOT NULL DEFAULT 1,
|
||||||
|
group_invite_verification TINYINT NOT NULL DEFAULT 0,
|
||||||
version INT NOT NULL DEFAULT 1,
|
version INT NOT NULL DEFAULT 1,
|
||||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||||
@@ -739,7 +740,8 @@ CREATE TABLE IF NOT EXISTS tinode.im_user_privacy_settings (
|
|||||||
UNIQUE INDEX uk_im_user_privacy_settings_user (user_id)
|
UNIQUE INDEX uk_im_user_privacy_settings_user (user_id)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS tinode.im_app_releases (
|
-- 全局客户端版本策略属于 Admin 控制库,不按租户拆分。
|
||||||
|
CREATE TABLE IF NOT EXISTS hotgo.im_app_releases (
|
||||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||||
platform VARCHAR(32) NOT NULL,
|
platform VARCHAR(32) NOT NULL,
|
||||||
channel VARCHAR(32) NOT NULL DEFAULT 'stable',
|
channel VARCHAR(32) NOT NULL DEFAULT 'stable',
|
||||||
@@ -993,13 +995,13 @@ ON DUPLICATE KEY UPDATE updated_at = CURRENT_TIMESTAMP(3);
|
|||||||
|
|
||||||
INSERT INTO tinode.im_workbench_apps(code, name, route, sort_order, unread_key, enabled, permission)
|
INSERT INTO tinode.im_workbench_apps(code, name, route, sort_order, unread_key, enabled, permission)
|
||||||
VALUES
|
VALUES
|
||||||
('organization', '组织架构', '/organization', 10, 'organization', 1, 'enabled'),
|
('attendance', '打卡', '/attendance', 10, 'attendance', 1, 'enabled'),
|
||||||
('attendance', '打卡', '/attendance', 20, 'attendance', 1, 'enabled'),
|
('monthly_reports', '月报', '/reports/monthly', 20, 'monthly_reports', 1, 'enabled'),
|
||||||
('meetings', '会议通知', '/meetings', 30, 'meetings', 1, 'enabled'),
|
('daily_reports', '日报', '/reports/daily', 30, 'daily_reports', 1, 'enabled'),
|
||||||
('meeting_notes', '会议笔记', '/meeting-notes', 35, '', 1, 'enabled'),
|
('organization', '部门框架', '/organization', 40, 'organization', 1, 'enabled'),
|
||||||
('daily_reports', '日报', '/reports/daily', 40, 'daily_reports', 1, 'enabled'),
|
('executive_mailbox', '举报信箱', '/executive-mailbox', 50, 'executive_mailbox', 1, 'enabled'),
|
||||||
('monthly_reports', '月报', '/reports/monthly', 50, 'monthly_reports', 1, 'enabled'),
|
('meetings', '会议通知', '/meetings', 60, 'meetings', 1, 'enabled'),
|
||||||
('executive_mailbox', '总经理信箱', '/executive-mailbox', 60, 'executive_mailbox', 1, 'enabled')
|
('meeting_notes', '会议笔记', '/meeting-notes', 70, '', 1, 'enabled')
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
name = VALUES(name),
|
name = VALUES(name),
|
||||||
route = VALUES(route),
|
route = VALUES(route),
|
||||||
@@ -1019,7 +1021,7 @@ INSERT INTO tinode.im_mailbox_config(id, enabled, allow_anonymous, required_fiel
|
|||||||
VALUES (1, 1, 1, '["subject","content"]', 5000, '{"max_files":5,"purpose":"executive_mailbox"}', '总经理信箱', '请如实填写诉求,匿名提交将按企业政策保护展示身份。')
|
VALUES (1, 1, 1, '["subject","content"]', 5000, '{"max_files":5,"purpose":"executive_mailbox"}', '总经理信箱', '请如实填写诉求,匿名提交将按企业政策保护展示身份。')
|
||||||
ON DUPLICATE KEY UPDATE updated_at = updated_at;
|
ON DUPLICATE KEY UPDATE updated_at = updated_at;
|
||||||
|
|
||||||
INSERT INTO tinode.im_app_releases(platform, channel, latest_version, min_supported_version, update_type, release_notes, remind_after_seconds)
|
INSERT INTO hotgo.im_app_releases(platform, channel, latest_version, min_supported_version, update_type, release_notes, remind_after_seconds)
|
||||||
VALUES
|
VALUES
|
||||||
('ios', 'stable', '1.0.0', '1.0.0', 'none', '当前已是最新版本。', 0),
|
('ios', 'stable', '1.0.0', '1.0.0', 'none', '当前已是最新版本。', 0),
|
||||||
('android', 'stable', '1.0.0', '1.0.0', 'none', '当前已是最新版本。', 0)
|
('android', 'stable', '1.0.0', '1.0.0', 'none', '当前已是最新版本。', 0)
|
||||||
|
|||||||
+5
-5
@@ -27,13 +27,13 @@
|
|||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| P0 | 真实短信供应商发送、失败重试、发送审计 | 1.4、1.7、1.10 | 当前测试码 `123456` 可联调,但生产短信未完成 | 依赖第三方,暂留后续增强池 |
|
| P0 | 真实短信供应商发送、失败重试、发送审计 | 1.4、1.7、1.10 | 当前测试码 `123456` 可联调,但生产短信未完成 | 依赖第三方,暂留后续增强池 |
|
||||||
| P0 | 消息转发落地接口 | 4.18、4.19、4.20 | 仅 `forward-targets` 已实现,`POST /v1/im/messages/forward`、`GET /v1/im/forward-bundles/{id}` 未实现 | 已抽入 `IM-增强项第一批开发.md` |
|
| P0 | 消息转发落地接口 | 4.18、4.19、4.20 | 仅 `forward-targets` 已实现,`POST /v1/im/messages/forward`、`GET /v1/im/forward-bundles/{id}` 未实现 | 已抽入 `IM-增强项第一批开发.md` |
|
||||||
| P0 | 登出与会话撤销 | 10.7 | `POST /v1/im/auth/logout`、`DELETE /v1/im/security/sessions/{id}` 未见路由 | 已抽入 `IM-增强项第一批开发.md` |
|
| P0 | 指定会话撤销 | 10.7 | `POST /v1/im/auth/logout` 已实现;`DELETE /v1/im/security/sessions/{id}` 未见路由 | 已抽入 `IM-增强项第一批开发.md` |
|
||||||
|
|
||||||
### 0.3 已抽入第一批开发的项目
|
### 0.3 已抽入第一批开发的项目
|
||||||
|
|
||||||
以下项目已经从本文档的普通后续增强池中抽出,形成专项开发文档 `docs/IM-增强项第一批开发.md`。其中已落地项已移入各章“当前已完成基线”;仍未完全落地的项目继续以第一批开发文档作为实现、验收和同步更新依据。
|
以下项目已经从本文档的普通后续增强池中抽出,形成专项开发文档 `docs/IM-增强项第一批开发.md`。其中已落地项已移入各章“当前已完成基线”;仍未完全落地的项目继续以第一批开发文档作为实现、验收和同步更新依据。
|
||||||
|
|
||||||
1. 仍待落地:登出与指定会话撤销。
|
1. 仍待落地:按 session ID 撤销指定设备;当前 token 登出已完成。
|
||||||
2. 仍待落地:普通消息转发。
|
2. 仍待落地:普通消息转发。
|
||||||
3. 仍待落地:合并转发 Bundle 详情。
|
3. 仍待落地:合并转发 Bundle 详情。
|
||||||
4. 已落地:群文件列表、登记和删除。
|
4. 已落地:群文件列表、登记和删除。
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| P0 | 真实短信供应商发送通道 | 当前为测试码联调模式;生产必须接短信服务商、模板、签名、失败重试和发送审计。 | 真实手机号收到验证码;供应商失败返回稳定 JSON,告警可观测。 |
|
| P0 | 真实短信供应商发送通道 | 当前为测试码联调模式;生产必须接短信服务商、模板、签名、失败重试和发送审计。 | 真实手机号收到验证码;供应商失败返回稳定 JSON,告警可观测。 |
|
||||||
| P0 | 验证码多维限频 | 需要按租户、手机号、IP、设备、场景组合限频,并接 Redis 或落库。 | 高频请求返回 `VERIFICATION_RATE_LIMITED`,不同场景互不误伤。 |
|
| P0 | 验证码多维限频 | 需要按租户、手机号、IP、设备、场景组合限频,并接 Redis 或落库。 | 高频请求返回 `VERIFICATION_RATE_LIMITED`,不同场景互不误伤。 |
|
||||||
| P0 | 登出与会话撤销 | 对接文档已有 `POST /v1/im/auth/logout` 和 `DELETE /v1/im/security/sessions/{id}`,代码未见路由。 | 当前设备退出不影响其他设备;删除指定 session 后该设备 token 立即失效。 |
|
| P0 | 指定会话撤销 | `POST /v1/im/auth/logout` 已通过 Redis 撤销当前 token;`DELETE /v1/im/security/sessions/{id}` 尚未实现。 | 当前设备退出不影响其他设备;删除指定 session 后该设备 token 立即失效。 |
|
||||||
| P1 | 实名后台审核流转 | 当前支持实名提交、状态查询和申诉提交,后续需要后台审核、驳回原因、通过状态变更和申诉处理工单。 | 审核通过后 `realname.status=verified`;驳回可再次提交;申诉有处理状态。 |
|
| P1 | 实名后台审核流转 | 当前支持实名提交、状态查询和申诉提交,后续需要后台审核、驳回原因、通过状态变更和申诉处理工单。 | 审核通过后 `realname.status=verified`;驳回可再次提交;申诉有处理状态。 |
|
||||||
| P1 | 安全事件通知覆盖扩展 | 风险确认已接入通知;密码重置、实名审核、独立密码变更、新设备登录仍需补齐。 | `/v1/im/system-notifications` 可看到对应事件且重试不重复入箱。 |
|
| P1 | 安全事件通知覆盖扩展 | 风险确认已接入通知;密码重置、实名审核、独立密码变更、新设备登录仍需补齐。 | `/v1/im/system-notifications` 可看到对应事件且重试不重复入箱。 |
|
||||||
| P1 | API Key 轮换策略 | 当前 API Key 校验兼容现有逻辑,尚未实现最低可接受序号或撤销表。 | 旧序号 Key 可按配置禁用,新 Key 不影响正常客户端。 |
|
| P1 | API Key 轮换策略 | 当前 API Key 校验兼容现有逻辑,尚未实现最低可接受序号或撤销表。 | 旧序号 Key 可按配置禁用,新 Key 不影响正常客户端。 |
|
||||||
@@ -303,7 +303,7 @@
|
|||||||
|
|
||||||
1. 个人资料 `GET/PATCH /v1/im/me/profile`、个人页 `GET /v1/im/me` 已具备。
|
1. 个人资料 `GET/PATCH /v1/im/me/profile`、个人页 `GET /v1/im/me` 已具备。
|
||||||
2. 隐私设置 `GET/PATCH /v1/im/me/privacy` 已具备,支持版本冲突控制。
|
2. 隐私设置 `GET/PATCH /v1/im/me/privacy` 已具备,支持版本冲突控制。
|
||||||
3. 最新版本检查 `GET /v1/im/app/releases/latest` 已具备,支持未登录按租户解析调用。
|
3. 最新版本检查 `GET /v1/im/app/releases/latest` 已具备,版本策略为全局配置,不依赖租户解析。
|
||||||
4. 青少年模式查询、开启、关闭接口已具备,复用敏感操作 `action_token` 和独立密码校验链路。
|
4. 青少年模式查询、开启、关闭接口已具备,复用敏感操作 `action_token` 和独立密码校验链路。
|
||||||
5. 设备 Push Token 覆盖写入 `PUT /v1/im/devices/{device_id}/push-token` 已具备。
|
5. 设备 Push Token 覆盖写入 `PUT /v1/im/devices/{device_id}/push-token` 已具备。
|
||||||
6. FCM 已优先使用产品 `im_device_push_tokens` 数据源,并支持通过环境变量注入 Firebase 凭据。
|
6. FCM 已优先使用产品 `im_device_push_tokens` 数据源,并支持通过环境变量注入 Firebase 凭据。
|
||||||
@@ -313,7 +313,7 @@
|
|||||||
|
|
||||||
| 优先级 | 增强项 | 说明 | 建议验收点 |
|
| 优先级 | 增强项 | 说明 | 建议验收点 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| P0 | 精准登出与会话撤销 | `auth/logout` 与 `security/sessions/{id}` 未见路由,现有 token 主要靠 `auth_version` 批量失效。 | 当前设备退出不影响其他设备;删除指定 session 后该设备 token 立即失效。 |
|
| P0 | 指定会话撤销 | `auth/logout` 已通过 Redis token 摘要黑名单精准实现;`security/sessions/{id}` 仍未实现。 | 当前设备退出不影响其他设备;删除指定 session 后该设备 token 立即失效。 |
|
||||||
| P0 | 个人资料变更实时同步 | 资料、头像、隐私变更后需要向多端推送 `profile.updated`、`privacy.updated`。 | 同账号多端无需重登即可刷新设置。 |
|
| P0 | 个人资料变更实时同步 | 资料、头像、隐私变更后需要向多端推送 `profile.updated`、`privacy.updated`。 | 同账号多端无需重登即可刷新设置。 |
|
||||||
| P0 | 青少年模式策略配置化 | 当前返回默认 restrictions,后续需要后台按租户配置可用时段、内容限制、消费保护等规则。 | 不同租户返回不同限制策略且能热更新。 |
|
| P0 | 青少年模式策略配置化 | 当前返回默认 restrictions,后续需要后台按租户配置可用时段、内容限制、消费保护等规则。 | 不同租户返回不同限制策略且能热更新。 |
|
||||||
| P0 | Push Token 生命周期 | 当前可覆盖写入,后续需要 token 失效回收、设备解绑、平台厂商错误码处理。 | 推送失败后自动禁用无效 token,重新登录可恢复。 |
|
| P0 | Push Token 生命周期 | 当前可覆盖写入,后续需要 token 失效回收、设备解绑、平台厂商错误码处理。 | 推送失败后自动禁用无效 token,重新登录可恢复。 |
|
||||||
|
|||||||
@@ -41,17 +41,16 @@ ServerComMessage
|
|||||||
2. `sess.bkgTimer` — 后台超时定时器
|
2. `sess.bkgTimer` — 后台超时定时器
|
||||||
3. `sess.stop` — 停止信号
|
3. `sess.stop` — 停止信号
|
||||||
4. `sess.detach` — 取消订阅
|
4. `sess.detach` — 取消订阅
|
||||||
5. `ticker` — Ping 帧(每 `pongWait * 9/10` 发送一次)
|
5. `ticker` — Ping 帧(每 30s 发送一次)
|
||||||
|
|
||||||
### Keep-Alive
|
### Keep-Alive
|
||||||
|
|
||||||
| 参数 | 值 | 说明 |
|
| 参数 | 值 | 说明 |
|
||||||
|------|-----|------|
|
|------|-----|------|
|
||||||
| `writeWait` | 10s | 写超时 |
|
| `writeWait` | 10s | 写超时 |
|
||||||
| `pongWait` | `idleSessionTimeout` | 期望收到 Pong 的时间(默认 180s) |
|
| `pongWait` | `idleSessionTimeout` | 期望收到 Pong 的时间(当前默认 45s) |
|
||||||
| `pingPeriod` | `pongWait * 9/10` | Ping 间隔(约 162s) |
|
| `pingPeriod` | 30s | WebSocket Ping 间隔 |
|
||||||
| `pingPeriod` | `pongWait * 9/10` | Ping 间隔(约 162s) |
|
| 心跳探测 | WebSocket Ping/Pong | 当前 IM 长连接保活以协议层 Ping/Pong 为准;业务 `note kp/kpa/kpv` 不能替代 Pong |
|
||||||
| 心跳探测 | `0x31` / `0x30` | 网络探针(单字节) |
|
|
||||||
|
|
||||||
### 缓冲区设置
|
### 缓冲区设置
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,524 @@
|
|||||||
|
{\rtf1\ansi\ansicpg936\cocoartf2821
|
||||||
|
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\froman\fcharset0 Times-Roman;}
|
||||||
|
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
|
||||||
|
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;}
|
||||||
|
\paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
||||||
|
\deftab720
|
||||||
|
\pard\pardeftab720\partightenfactor0
|
||||||
|
|
||||||
|
\f0\fs24 \cf0 \expnd0\expndtw0\kerning0
|
||||||
|
\outl0\strokewidth0 \strokec2 \uc0\u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u26381 \u21153 \u21327 \u35758 \
|
||||||
|
\uc0\u21069 \u35328 \
|
||||||
|
\
|
||||||
|
\uc0\u27426 \u36814 \u24744 \u20351 \u29992 \u12304 \u28023 \u21475 \u24066 \u26539 \u32676 \u32593 \u32476 \u31185 \u25216 \u26377 \u38480 \u20844 \u21496 \u12305 \u20844 \u21496 \u65288 \u19979 \u31216 \'93\u25105 \u20844 \u21496 \'94\u25110 \'93\u25105 \u20204 \'94\u65289 \u20026 \u24744 \u25552 \u20379 \u30340 \u31508 \u22696 \u35759 \u20351 \u30340 \u26381 \u21153 \u65281 \
|
||||||
|
\
|
||||||
|
\uc0\u29305 \u21035 \u25552 \u31034 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u20026 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u65288 \u20197 \u19979 \u31616 \u31216 \'93\u26412 \u36719 \u20214 \'94\u65289 \u21450 \u26381 \u21153 \u65292 \u24744 \u24212 \u24403 \u38405 \u35835 \u24182 \u36981 \u23432 \u12298 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u26381 \u21153 \u21327 \u35758 \u12299 \u65288 \u20197 \u19979 \u31616 \u31216 \'93\u26412 \u21327 \u35758 \'94\u65289 \u12290 \u35831 \u24744 \u21153 \u24517 \u20180 \u32454 \u38405 \u35835 \u12289 \u20805 \u20998 \u29702 \u35299 \u26412 \u21327 \u35758 \u21508 \u26465 \u27454 \u20869 \u23481 \u65292 \u29305 \u21035 \u26159 \u35905 \u20813 \u25110 \u32773 \u38480 \u21046 \u25105 \u20844 \u21496 \u36131 \u20219 \u30340 \u26465 \u27454 \u12289 \u23545 \u29992 \u25143 \u26435 \u21033 \u36827 \u34892 \u38480 \u21046 \u30340 \u26465 \u27454 \u12289 \u32422 \u23450 \u31649 \u36758 \u19982 \u27861 \u24459 \u36866 \u29992 \u26465 \u27454 \u65292 \u20197 \u21450 \u24320 \u36890 \u25110 \u20351 \u29992 \u26576 \u39033 \u26381 \u21153 \u30340 \u21333 \u29420 \u21327 \u35758 \u12290 \u38480 \u21046 \u12289 \u20813 \u36131 \u26465 \u27454 \u25110 \u32773 \u20854 \u20182 \u28041 \u21450 \u24744 \u37325 \u22823 \u26435 \u30410 \u30340 \u26465 \u27454 \u21487 \u33021 \u20197 \u21152 \u31895 \u31561 \u24418 \u24335 \u25552 \u31034 \u24744 \u37325 \u28857 \u27880 \u24847 \u12290 \u22914 \u24744 \u23545 \u26412 \u21327 \u35758 \u26377 \u20219 \u20309 \u30097 \u38382 \u65292 \u21487 \u36890 \u36807 \u25991 \u26411 \u32852 \u31995 \u26041 \u24335 \u32852 \u31995 \u25105 \u20204 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u38500 \u38750 \u24744 \u24050 \u38405 \u35835 \u24182 \u25509 \u21463 \u26412 \u21327 \u35758 \u25152 \u26377 \u26465 \u27454 \u65292 \u21542 \u21017 \u24744 \u26080 \u26435 \u27880 \u20876 \u25110 \u30331 \u24405 \u20351 \u29992 \u26412 \u36719 \u20214 \u21450 \u30456 \u20851 \u26381 \u21153 \u12290 \u24744 \u28857 \u20987 \'93\u21516 \u24847 \'94\u65292 \u25110 \u32773 \u24744 \u27880 \u20876 \u25110 \u30331 \u24405 \u26412 \u36719 \u20214 \u30340 \u34892 \u20026 \u65292 \u25110 \u32773 \u20854 \u20182 \u26126 \u31034 \u25110 \u32773 \u40664 \u31034 \u26041 \u24335 \u34920 \u31034 \u25509 \u21463 \u26412 \u21327 \u35758 \u30340 \u34892 \u20026 \u21363 \u35270 \u20026 \u24744 \u24050 \u38405 \u35835 \u24182 \u21516 \u24847 \u25509 \u21463 \u26412 \u21327 \u35758 \u30340 \u32422 \u26463 \u12290 \u26412 \u21327 \u35758 \u21363 \u22312 \u24744 \u19982 \u25105 \u20844 \u21496 \u20043 \u38388 \u20135 \u29983 \u27861 \u24459 \u25928 \u21147 \u65292 \u25104 \u20026 \u23545 \u21452 \u26041 \u22343 \u20855 \u26377 \u32422 \u26463 \u21147 \u30340 \u27861 \u24459 \u25991 \u20214 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u22914 \u26524 \u24744 \u26410 \u28385 18\u21608 \u23681 \u65292 \u25110 \u23384 \u22312 \u20854 \u20182 \u19981 \u20855 \u22791 \u19982 \u29992 \u25143 \u34892 \u20026 \u30456 \u36866 \u24212 \u30340 \u27665 \u20107 \u34892 \u20026 \u33021 \u21147 \u30340 \u24773 \u24418 \u65292 \u35831 \u22312 \u27861 \u23450 \u30417 \u25252 \u20154 \u30340 \u38506 \u21516 \u12289 \u25351 \u23548 \u19979 \u38405 \u35835 \u26412 \u21327 \u35758 \u65292 \u24182 \u29305 \u21035 \u27880 \u24847 \u26410 \u25104 \u24180 \u20154 \u20351 \u29992 \u26465 \u27454 \u65292 \u22312 \u30830 \u20445 \u30417 \u25252 \u20154 \u21516 \u24847 \u26412 \u21327 \u35758 \u20869 \u23481 \u21518 \u20351 \u29992 \u26412 \u36719 \u20214 \u12290 \u24744 \u21450 \u24744 \u30340 \u30417 \u25252 \u20154 \u24212 \u20381 \u29031 \u27861 \u24459 \u27861 \u35268 \u35268 \u23450 \u65292 \u25215 \u25285 \u21516 \u24847 \u26412 \u21327 \u35758 \u21450 \u20351 \u29992 \u26412 \u36719 \u20214 \u32780 \u23548 \u33268 \u30340 \u30456 \u24212 \u21518 \u26524 \u12290 \
|
||||||
|
\uc0\u19968 \u12289 \u21327 \u35758 \u30340 \u33539 \u22260 \
|
||||||
|
\
|
||||||
|
1.1 \uc0\u21327 \u35758 \u36866 \u29992 \u20027 \u20307 \u33539 \u22260 \
|
||||||
|
\uc0\u26412 \u21327 \u35758 \u26159 \u24744 \u19982 \u25105 \u20204 \u20043 \u38388 \u20851 \u20110 \u24744 \u19979 \u36733 \u12289 \u23433 \u35013 \u12289 \u27880 \u20876 \u12289 \u30331 \u24405 \u12289 \u20351 \u29992 \u26412 \u36719 \u20214 \u20197 \u21450 \u20351 \u29992 \u25105 \u20204 \u25552 \u20379 \u30340 \u30456 \u20851 \u26381 \u21153 \u25152 \u35746 \u31435 \u30340 \u21327 \u35758 \u12290 \u21253 \u25324 \u26412 \u21327 \u35758 \u27491 \u25991 \u12289 \u12298 \u38544 \u31169 \u21327 \u35758 \u12299 \u21450 \u25105 \u20844 \u21496 \u24050 \u32463 \u21457 \u24067 \u30340 \u25110 \u23558 \u26469 \u21487 \u33021 \u21457 \u24067 /\u26356 \u26032 \u30340 \u24182 \u37319 \u21462 \u21512 \u29702 \u36884 \u24452 \u36890 \u30693 \u30340 \u21508 \u31867 \u35268 \u21017 \u12289 \u35268 \u33539 \u12289 \u36890 \u30693 \u31561 \u12290 \
|
||||||
|
\
|
||||||
|
1.2 \uc0\u21327 \u35758 \u20851 \u31995 \
|
||||||
|
\uc0\u26412 \u21327 \u35758 \u20869 \u23481 \u21516 \u26102 \u21253 \u25324 \u25105 \u20204 \u21487 \u33021 \u19981 \u26029 \u21457 \u24067 \u30340 \u20851 \u20110 \u26412 \u26381 \u21153 \u30340 \u30456 \u20851 \u21327 \u35758 \u12289 \u19994 \u21153 \u35268 \u21017 \u12289 \u36890 \u30693 \u31561 \u20869 \u23481 \u12290 \u19978 \u36848 \u20869 \u23481 \u19968 \u32463 \u27491 \u24335 \u21457 \u24067 \u65292 \u21363 \u20026 \u26412 \u21327 \u35758 \u19981 \u21487 \u20998 \u21106 \u30340 \u32452 \u25104 \u37096 \u20998 \u65292 \u24744 \u21516 \u26679 \u24212 \u24403 \u36981 \u23432 \u12290 \
|
||||||
|
\
|
||||||
|
1.3 \uc0\u30456 \u20851 \u23450 \u20041 \
|
||||||
|
\'93\uc0\u25105 \u20844 \u21496 \u25110 \u25105 \u20204 \'94\u65292 \u26159 \u25351 \u31508 \u22696 \u35759 \u20351 \u21450 \u30456 \u20851 \u26381 \u21153 \u21487 \u33021 \u23384 \u22312 \u30340 \u36816 \u33829 \u20851 \u32852 \u21333 \u20301 \u65292 \u21363 \u12304 \u28023 \u21475 \u24066 \u26539 \u32676 \u32593 \u32476 \u31185 \u25216 \u26377 \u38480 \u20844 \u21496 \u12305 \u20844 \u21496 \u21450 \u20854 \u20851 \u32852 \u20844 \u21496 \u12290 \
|
||||||
|
\'93\uc0\u29992 \u25143 \'94\u65292 \u26159 \u25351 \u20351 \u29992 \u26412 \u36719 \u20214 \u21450 \u30456 \u20851 \u26381 \u21153 \u30340 \u20351 \u29992 \u32773 \u65292 \u22312 \u26412 \u21327 \u35758 \u20013 \u26356 \u22810 \u22320 \u31216 \u20026 \'93\u24744 \'94\u12290 \
|
||||||
|
\'93\uc0\u26381 \u21153 \'94\u65292 \u26159 \u25351 \u25105 \u20204 \u21521 \u24744 \u25552 \u20379 \u30340 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u30456 \u20851 \u26381 \u21153 \u65292 \u20855 \u20307 \u20197 \u25105 \u20204 \u23454 \u38469 \u25552 \u20379 \u30340 \u20026 \u20934 \u12290 \u21516 \u26102 \u65292 \u25105 \u20204 \u26377 \u26435 \u23545 \u25552 \u20379 \u30340 \u36719 \u20214 \u26381 \u21153 \u36827 \u34892 \u22686 \u21152 \u12289 \u20851 \u20572 \u25110 \u20854 \u20182 \u35843 \u25972 \u12290 \
|
||||||
|
\'93\uc0\u36134 \u21495 \'94\u65292 \u25351 \u29992 \u25143 \u22312 \u20351 \u29992 \u26381 \u21153 \u26102 \u21487 \u33021 \u38656 \u35201 \u27880 \u20876 \u30340 \u36134 \u21495 \u12290 \u29992 \u25143 \u21487 \u22312 \u26412 \u36719 \u20214 \u27880 \u20876 \u24182 \u33719 \u24471 \u30340 \u36134 \u21495 \u65292 \u20316 \u20026 \u30331 \u24405 \u24182 \u20351 \u29992 \u26412 \u36719 \u20214 \u30340 \u20973 \u35777 \u12290 \
|
||||||
|
\uc0\u20108 \u12289 \u20851 \u20110 \u26412 \u26381 \u21153 \
|
||||||
|
\
|
||||||
|
2.1 \uc0\u26412 \u26381 \u21153 \u30340 \u20869 \u23481 \
|
||||||
|
\uc0\u26412 \u26381 \u21153 \u20869 \u23481 \u26159 \u25351 \u25105 \u20204 \u21521 \u29992 \u25143 \u25552 \u20379 \u30340 \u36328 \u24179 \u21488 \u30340 \u36890 \u35759 \u24037 \u20855 \u65288 \u20197 \u19979 \u31616 \u31216 \'93\u31508 \u22696 \u35759 \u20351 \'94\u65289 \u65292 \u25903 \u25345 \u21333 \u20154 \u12289 \u22810 \u20154 \u21442 \u19982 \u65292 \u22312 \u21457 \u36865 \u35821 \u38899 \u30701 \u20449 \u12289 \u35270 \u39057 \u12289 \u22270 \u29255 \u21644 \u25991 \u23383 \u31561 \u21363 \u26102 \u36890 \u35759 \u26381 \u21153 \u30340 \u22522 \u30784 \u19978 \u65292 \u21516 \u26102 \u20026 \u29992 \u25143 \u25552 \u20379 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u32593 \u32476 \u23186 \u20307 \u12289 \u20114 \u32852 \u32593 \u22686 \u20540 \u12289 \u20114 \u21160 \u23089 \u20048 \u12289 \u30005 \u23376 \u21830 \u21153 \u12289 \u30005 \u23376 \u38065 \u21253 \u12289 \u24320 \u25918 \u24179 \u21488 \u12289 \u19982 \u20854 \u20182 \u36719 \u20214 \u25110 \u30828 \u20214 \u20449 \u24687 \u20114 \u36890 \u31561 \u21151 \u33021 \u25110 \u20869 \u23481 \u30340 \u36719 \u20214 \u35768 \u21487 \u21450 \u26381 \u21153 \u65288 \u20197 \u19979 \u31616 \u31216 \'93\u26412 \u26381 \u21153 \'94\u65289 \u21644 \u24191 \u21578 \u31561 \u26381 \u21153 \u65288 \u20197 \u19979 \u31616 \u31216 \'93\u26412 \u26381 \u21153 \'94\u65289 \u12290 \
|
||||||
|
\
|
||||||
|
2.2 \uc0\u26412 \u26381 \u21153 \u30340 \u24418 \u24335 \
|
||||||
|
\
|
||||||
|
2.2.1 \uc0\u24744 \u20351 \u29992 \u26412 \u26381 \u21153 \u38656 \u35201 \u19979 \u36733 \u31508 \u22696 \u35759 \u20351 \u23458 \u25143 \u31471 \u36719 \u20214 \u65292 \u23545 \u20110 \u36825 \u20123 \u36719 \u20214 \u65292 \u25105 \u20204 \u32473 \u20104 \u24744 \u19968 \u39033 \u20010 \u20154 \u30340 \u12289 \u19981 \u21487 \u36716 \u35753 \u21450 \u38750 \u25490 \u20182 \u24615 \u30340 \u35768 \u21487 \u12290 \u24744 \u20165 \u21487 \u20026 \u35775 \u38382 \u25110 \u20351 \u29992 \u26412 \u26381 \u21153 \u30340 \u30446 \u30340 \u32780 \u20351 \u29992 \u36825 \u20123 \u36719 \u20214 \u21450 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
2.2.2 \uc0\u26412 \u26381 \u21153 \u20013 \u31508 \u22696 \u35759 \u20351 \u23458 \u25143 \u31471 \u36719 \u20214 \u21487 \u33021 \u20250 \u25552 \u20379 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 iOS\u12289 Android\u12289 Windows\u12289 Mac\u31561 \u22810 \u20010 \u24212 \u29992 \u29256 \u26412 \u65292 \u29992 \u25143 \u24517 \u39035 \u36873 \u25321 \u19982 \u25152 \u23433 \u35013 \u32456 \u31471 \u35774 \u22791 \u30456 \u21305 \u37197 \u30340 \u36719 \u20214 \u29256 \u26412 \u12290 \
|
||||||
|
\
|
||||||
|
2.3 \uc0\u26412 \u26381 \u21153 \u35768 \u21487 \u30340 \u33539 \u22260 \
|
||||||
|
\
|
||||||
|
2.3.1 \uc0\u25105 \u20204 \u32473 \u20104 \u24744 \u19968 \u39033 \u20010 \u20154 \u30340 \u12289 \u19981 \u21487 \u36716 \u35753 \u21450 \u38750 \u25490 \u20182 \u24615 \u30340 \u35768 \u21487 \u65292 \u20197 \u20351 \u29992 \u26412 \u36719 \u20214 \u12290 \u24744 \u21487 \u20197 \u20026 \u38750 \u21830 \u19994 \u30446 \u30340 \u22312 \u21333 \u19968 \u21488 \u32456 \u31471 \u35774 \u22791 \u19978 \u23433 \u35013 \u12289 \u20351 \u29992 \u12289 \u26174 \u31034 \u12289 \u36816 \u34892 \u26412 \u36719 \u20214 \u12290 \
|
||||||
|
\
|
||||||
|
2.3.2 \uc0\u26412 \u26465 \u21450 \u26412 \u21327 \u35758 \u20854 \u20182 \u26465 \u27454 \u26410 \u26126 \u30830 \u25480 \u26435 \u30340 \u20854 \u20182 \u19968 \u20999 \u26435 \u21033 \u20173 \u30001 \u25105 \u20204 \u20445 \u30041 \u65292 \u24744 \u22312 \u34892 \u20351 \u36825 \u20123 \u26435 \u21033 \u26102 \u39035 \u21478 \u22806 \u21462 \u24471 \u25105 \u20204 \u30340 \u20070 \u38754 \u35768 \u21487 \u12290 \u25105 \u20204 \u22914 \u26524 \u26410 \u34892 \u20351 \u21069 \u36848 \u20219 \u20309 \u26435 \u21033 \u65292 \u24182 \u19981 \u26500 \u25104 \u23545 \u35813 \u26435 \u21033 \u30340 \u25918 \u24323 \u12290 \
|
||||||
|
\
|
||||||
|
2.4 \uc0\u25353 \u29616 \u29366 \u25552 \u20379 \u26381 \u21153 \
|
||||||
|
\uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u31508 \u22696 \u35759 \u20351 \u30340 \u26381 \u21153 \u26159 \u25353 \u29031 \u29616 \u26377 \u25216 \u26415 \u21644 \u26465 \u20214 \u25152 \u33021 \u36798 \u21040 \u30340 \u29616 \u29366 \u25552 \u20379 \u30340 \u12290 \u31508 \u22696 \u35759 \u20351 \u20250 \u23613 \u26368 \u22823 \u21162 \u21147 \u21521 \u24744 \u25552 \u20379 \u26381 \u21153 \u65292 \u30830 \u20445 \u26381 \u21153 \u30340 \u36830 \u32493 \u24615 \u21644 \u23433 \u20840 \u24615 \u65307 \u20294 \u31508 \u22696 \u35759 \u20351 \u19981 \u33021 \u38543 \u26102 \u39044 \u35265 \u21644 \u38450 \u33539 \u27861 \u24459 \u12289 \u25216 \u26415 \u20197 \u21450 \u20854 \u20182 \u39118 \u38505 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u19981 \u21487 \u25239 \u21147 \u12289 \u30149 \u27602 \u12289 \u26408 \u39532 \u12289 \u40657 \u23458 \u25915 \u20987 \u12289 \u31995 \u32479 \u19981 \u31283 \u23450 \u12289 \u31532 \u19977 \u26041 \u26381 \u21153 \u32570 \u38519 \u12289 \u25919 \u24220 \u34892 \u20026 \u31561 \u21407 \u22240 \u21487 \u33021 \u23548 \u33268 \u30340 \u26381 \u21153 \u20013 \u26029 \u12289 \u25968 \u25454 \u20002 \u22833 \u20197 \u21450 \u20854 \u20182 \u30340 \u25439 \u22833 \u21644 \u39118 \u38505 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u19977 \u12289 \u36719 \u20214 \u30340 \u33719 \u21462 \u19982 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
3.1 \uc0\u24744 \u21487 \u20197 \u30452 \u25509 \u20174 \u25105 \u20204 \u30340 \u32593 \u31449 \u19978 \u33719 \u21462 \u26412 \u36719 \u20214 \u65292 \u20063 \u21487 \u20197 \u20174 \u24471 \u21040 \u25105 \u20204 \u25480 \u26435 \u30340 \u31532 \u19977 \u26041 \u33719 \u21462 \u12290 \
|
||||||
|
\
|
||||||
|
3.2 \uc0\u22914 \u26524 \u24744 \u20174 \u26410 \u32463 \u25105 \u20204 \u25480 \u26435 \u30340 \u31532 \u19977 \u26041 \u33719 \u21462 \u26412 \u36719 \u20214 \u25110 \u19982 \u26412 \u36719 \u20214 \u21517 \u31216 \u30456 \u21516 \u30340 \u23433 \u35013 \u31243 \u24207 \u65292 \u25105 \u20204 \u26080 \u27861 \u20445 \u35777 \u35813 \u36719 \u20214 \u33021 \u22815 \u27491 \u24120 \u20351 \u29992 \u65292 \u24182 \u23545 \u22240 \u27492 \u32473 \u24744 \u36896 \u25104 \u30340 \u25439 \u22833 \u19981 \u20104 \u36127 \u36131 \u12290 \
|
||||||
|
\
|
||||||
|
3.3 \uc0\u25105 \u20204 \u21487 \u33021 \u20026 \u19981 \u21516 \u30340 \u32456 \u31471 \u35774 \u22791 \u24320 \u21457 \u20102 \u19981 \u21516 \u30340 \u36719 \u20214 \u29256 \u26412 \u65292 \u24744 \u24212 \u24403 \u26681 \u25454 \u23454 \u38469 \u24773 \u20917 \u36873 \u25321 \u19979 \u36733 \u21512 \u36866 \u30340 \u29256 \u26412 \u36827 \u34892 \u23433 \u35013 \u12290 \
|
||||||
|
\
|
||||||
|
3.4 \uc0\u19979 \u36733 \u23433 \u35013 \u31243 \u24207 \u21518 \u65292 \u24744 \u38656 \u35201 \u25353 \u29031 \u35813 \u31243 \u24207 \u25552 \u31034 \u30340 \u27493 \u39588 \u27491 \u30830 \u23433 \u35013 \u12290 \
|
||||||
|
\
|
||||||
|
3.5 \uc0\u20026 \u25552 \u20379 \u26356 \u21152 \u20248 \u36136 \u12289 \u23433 \u20840 \u30340 \u26381 \u21153 \u65292 \u22312 \u26412 \u36719 \u20214 \u23433 \u35013 \u26102 \u25105 \u20204 \u21487 \u33021 \u20250 \u25512 \u33616 \u24744 \u23433 \u35013 \u20854 \u20182 \u36719 \u20214 \u65292 \u24744 \u21487 \u20197 \u36873 \u25321 \u23433 \u35013 \u25110 \u19981 \u23433 \u35013 \u12290 \
|
||||||
|
\
|
||||||
|
3.6 \uc0\u20026 \u20102 \u25913 \u21892 \u29992 \u25143 \u20307 \u39564 \u12289 \u20445 \u35777 \u26381 \u21153 \u30340 \u23433 \u20840 \u24615 \u21450 \u20135 \u21697 \u21151 \u33021 \u30340 \u19968 \u33268 \u24615 \u65292 \u25105 \u20204 \u21487 \u33021 \u20250 \u19981 \u26102 \u23545 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u36827 \u34892 \u26356 \u26032 \u12290 \u25105 \u20204 \u26377 \u26435 \u19981 \u32463 \u36807 \u21521 \u24744 \u29305 \u21035 \u36890 \u30693 \u32780 \u23545 \u36719 \u20214 \u36827 \u34892 \u26356 \u26032 \u65292 \u25110 \u32773 \u23545 \u36719 \u20214 \u30340 \u37096 \u20998 \u21151 \u33021 \u25928 \u26524 \u36827 \u34892 \u25913 \u21464 \u25110 \u38480 \u21046 \u12290 \u24744 \u24212 \u24403 \u23558 \u30456 \u20851 \u36719 \u20214 \u26356 \u26032 \u21040 \u26368 \u26032 \u29256 \u26412 \u65292 \u21542 \u21017 \u25105 \u20204 \u24182 \u19981 \u20445 \u35777 \u20854 \u33021 \u27491 \u24120 \u20351 \u29992 \u12290 \
|
||||||
|
\
|
||||||
|
3.7 \uc0\u22914 \u26524 \u24744 \u19981 \u20877 \u38656 \u35201 \u20351 \u29992 \u26412 \u36719 \u20214 \u25110 \u32773 \u38656 \u35201 \u23433 \u35013 \u26032 \u29256 \u36719 \u20214 \u65292 \u21487 \u20197 \u33258 \u34892 \u21368 \u36733 \u12290 \u22914 \u26524 \u24744 \u24895 \u24847 \u24110 \u21161 \u25105 \u20204 \u25913 \u36827 \u20135 \u21697 \u26381 \u21153 \u65292 \u35831 \u21578 \u30693 \u21368 \u36733 \u30340 \u21407 \u22240 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u22235 \u12289 \u29992 \u25143 \u20010 \u20154 \u20449 \u24687 \u20445 \u25252 \
|
||||||
|
\
|
||||||
|
4.1 \uc0\u20445 \u25252 \u29992 \u25143 \u20010 \u20154 \u20449 \u24687 \u26159 \u25105 \u20204 \u30340 \u19968 \u39033 \u22522 \u26412 \u21407 \u21017 \u65292 \u25105 \u20204 \u23558 \u25353 \u29031 \u26412 \u21327 \u35758 \u30340 \u35268 \u23450 \u25910 \u38598 \u12289 \u20351 \u29992 \u12289 \u23384 \u20648 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u24182 \u20250 \u37319 \u21462 \u21512 \u29702 \u30340 \u25514 \u26045 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
4.2 \uc0\u24744 \u22312 \u27880 \u20876 \u36134 \u21495 \u25110 \u20351 \u29992 \u26412 \u26381 \u21153 \u30340 \u36807 \u31243 \u20013 \u65292 \u38656 \u35201 \u25552 \u20379 \u19968 \u20123 \u24517 \u35201 \u30340 \u20449 \u24687 \u65292 \u20363 \u22914 \u65306 \u20026 \u21521 \u24744 \u25552 \u20379 \u36134 \u21495 \u27880 \u20876 \u26381 \u21153 \u25110 \u36827 \u34892 \u29992 \u25143 \u36523 \u20221 \u35782 \u21035 \u65292 \u38656 \u35201 \u24744 \u22635 \u20889 \u25163 \u26426 \u21495 \u30721 \u12289 \u36523 \u20221 \u35777 \u21495 \u30721 \u31561 \u65307 \u31508 \u22696 \u35759 \u20351 \u26576 \u20123 \u21151 \u33021 \u21487 \u33021 \u38656 \u35201 \u25910 \u38598 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u21253 \u25324 \u65306 \u26165 \u31216 \u12289 \u22836 \u20687 \u12289 \u25163 \u26426 \u21495 \u12289 \u36523 \u20221 \u35777 \u21495 \u12289 \u21152 \u20837 \u32676 \u32452 \u12289 \u22909 \u21451 \u20851 \u31995 \u31561 \u12290 \u33509 \u22269 \u23478 \u27861 \u24459 \u27861 \u35268 \u25110 \u25919 \u31574 \u26377 \u29305 \u27530 \u35268 \u23450 \u30340 \u65292 \u24744 \u38656 \u35201 \u25552 \u20379 \u30495 \u23454 \u30340 \u36523 \u20221 \u20449 \u24687 \u12290 \u33509 \u24744 \u25552 \u20379 \u30340 \u20449 \u24687 \u19981 \u23436 \u25972 \u65292 \u21017 \u26080 \u27861 \u20351 \u29992 \u26412 \u26381 \u21153 \u25110 \u22312 \u20351 \u29992 \u36807 \u31243 \u20013 \u21463 \u21040 \u38480 \u21046 \u12290 \u24744 \u20102 \u35299 \u24182 \u21516 \u24847 \u65292 \u24744 \u26377 \u20041 \u21153 \u20445 \u25345 \u24744 \u25552 \u20379 \u20449 \u24687 \u30340 \u30495 \u23454 \u24615 \u12289 \u26377 \u25928 \u24615 \u21450 \u23436 \u25972 \u24615 \u12290 \
|
||||||
|
\
|
||||||
|
4.3 \uc0\u19968 \u33324 \u24773 \u20917 \u19979 \u65292 \u24744 \u21487 \u38543 \u26102 \u26597 \u30475 \u12289 \u20462 \u25913 \u33258 \u24049 \u25552 \u20132 \u30340 \u20449 \u24687 \u65292 \u20294 \u20986 \u20110 \u23433 \u20840 \u24615 \u21644 \u36523 \u20221 \u35782 \u21035 \u65288 \u22914 \u21495 \u30721 \u30003 \u35785 \u26381 \u21153 \u65289 \u30340 \u32771 \u34385 \u65292 \u24744 \u21487 \u33021 \u26080 \u27861 \u20462 \u25913 \u27880 \u20876 \u26102 \u25552 \u20379 \u30340 \u21021 \u22987 \u27880 \u20876 \u20449 \u24687 \u21450 \u20854 \u20182 \u39564 \u35777 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
4.4 \uc0\u25105 \u20204 \u23558 \u36816 \u29992 \u21508 \u31181 \u23433 \u20840 \u25216 \u26415 \u21644 \u31243 \u24207 \u24314 \u31435 \u23436 \u21892 \u30340 \u31649 \u29702 \u21046 \u24230 \u26469 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u20197 \u20813 \u36973 \u21463 \u26410 \u32463 \u25480 \u26435 \u30340 \u35775 \u38382 \u12289 \u20351 \u29992 \u25110 \u27844 \u38706 \u12290 \
|
||||||
|
\
|
||||||
|
4.5 \uc0\u26410 \u32463 \u24744 \u30340 \u21516 \u24847 \u65292 \u25105 \u20204 \u19981 \u20250 \u23558 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u36716 \u31227 \u25110 \u25259 \u38706 \u32473 \u20219 \u20309 \u38750 \u20851 \u32852 \u30340 \u31532 \u19977 \u26041 \u65292 \u38500 \u38750 \u65306 \
|
||||||
|
\uc0\u65288 1\u65289 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u25110 \u27861 \u38498 \u12289 \u25919 \u24220 \u26426 \u20851 \u35201 \u27714 \u65307 \
|
||||||
|
\uc0\u65288 2\u65289 \u20026 \u23436 \u25104 \u21512 \u24182 \u12289 \u20998 \u31435 \u12289 \u25910 \u36141 \u25110 \u36164 \u20135 \u36716 \u35753 \u32780 \u36716 \u31227 \u65307 \
|
||||||
|
\uc0\u65288 3\u65289 \u20026 \u25552 \u20379 \u24744 \u35201 \u27714 \u30340 \u26381 \u21153 \u25152 \u24517 \u38656 \u65307 \
|
||||||
|
\uc0\u65288 4\u65289 \u20381 \u25454 \u20854 \u20182 \u30456 \u20851 \u21327 \u35758 \u35268 \u21017 \u21487 \u20197 \u36716 \u31227 \u25110 \u25259 \u38706 \u32473 \u20219 \u20309 \u31532 \u19977 \u26041 \u30340 \u24773 \u24418 \u12290 \
|
||||||
|
\
|
||||||
|
4.6 \uc0\u25105 \u20204 \u38750 \u24120 \u37325 \u35270 \u23545 \u26410 \u25104 \u24180 \u20154 \u20010 \u20154 \u20449 \u24687 \u30340 \u20445 \u25252 \u12290 \u33509 \u24744 \u26159 18\u21608 \u23681 \u20197 \u19979 \u30340 \u26410 \u25104 \u24180 \u20154 \u65292 \u22312 \u20351 \u29992 \u25105 \u20204 \u30340 \u26381 \u21153 \u21069 \u65292 \u24212 \u20107 \u20808 \u21462 \u24471 \u24744 \u23478 \u38271 \u25110 \u27861 \u23450 \u30417 \u25252 \u20154 \u30340 \u20070 \u38754 \u21516 \u24847 \u12290 \
|
||||||
|
\
|
||||||
|
4.7 \uc0\u25105 \u20204 \u21487 \u33021 \u20250 \u22312 \u21521 \u24744 \u25552 \u20379 \u26381 \u21153 \u30340 \u36807 \u31243 \u20043 \u20013 \u25152 \u25910 \u38598 \u30340 \u20449 \u24687 \u29992 \u20316 \u19979 \u21015 \u29992 \u36884 \u65306 \
|
||||||
|
(1) \uc0\u21521 \u24744 \u25552 \u20379 \u26381 \u21153 \u65307 \
|
||||||
|
(2) \uc0\u22312 \u25105 \u20204 \u25552 \u20379 \u26381 \u21153 \u26102 \u65292 \u29992 \u20110 \u36523 \u20221 \u39564 \u35777 \u12289 \u23458 \u25143 \u26381 \u21153 \u12289 \u23433 \u20840 \u38450 \u33539 \u12289 \u35784 \u39575 \u30417 \u27979 \u12289 \u23384 \u26723 \u21644 \u22791 \u20221 \u29992 \u36884 \u65292 \u30830 \u20445 \u25105 \u20204 \u21521 \u24744 \u25552 \u20379 \u30340 \u20135 \u21697 \u21644 \u26381 \u21153 \u30340 \u23433 \u20840 \u24615 ;\
|
||||||
|
(3) \uc0\u24110 \u21161 \u25105 \u20204 \u35774 \u35745 \u26032 \u26381 \u21153 \u65292 \u25913 \u36827 \u25105 \u20204 \u29616 \u26377 \u26381 \u21153 \u65307 \
|
||||||
|
(4) \uc0\u20351 \u25105 \u20204 \u26356 \u21152 \u20102 \u35299 \u24744 \u22914 \u20309 \u25509 \u20837 \u21644 \u20351 \u29992 \u25105 \u20204 \u30340 \u26381 \u21153 \u65292 \u20174 \u32780 \u38024 \u23545 \u24615 \u22320 \u22238 \u24212 \u24744 \u30340 \u20010 \u24615 \u21270 \u38656 \u27714 \u65292 \u20363 \u22914 \u35821 \u35328 \u35774 \u32622 \u12289 \u20301 \u32622 \u35774 \u32622 \u12289 \u20010 \u24615 \u21270 \u30340 \u24110 \u21161 \u26381 \u21153 \u21644 \u25351 \u23548 \u65292 \u25110 \u23545 \u24744 \u21644 \u20854 \u20182 \u29992 \u25143 \u20316 \u20986 \u20854 \u20182 \u26041 \u38754 \u30340 \u22238 \u24212 \u65307 \
|
||||||
|
(5) \uc0\u21521 \u24744 \u25552 \u20379 \u19982 \u24744 \u26356 \u21152 \u30456 \u20851 \u30340 \u24191 \u21578 \u20197 \u26367 \u20195 \u26222 \u36941 \u25237 \u25918 \u30340 \u24191 \u21578 \u65307 \u35780 \u20272 \u25105 \u20204 \u26381 \u21153 \u20013 \u30340 \u24191 \u21578 \u21644 \u20854 \u20182 \u20419 \u38144 \u21450 \u25512 \u24191 \u27963 \u21160 \u30340 \u25928 \u26524 \u65292 \u24182 \u21152 \u20197 \u25913 \u36827 \u65307 \
|
||||||
|
(6) \uc0\u36719 \u20214 \u35748 \u35777 \u25110 \u31649 \u29702 \u36719 \u20214 \u21319 \u32423 \u65307 \
|
||||||
|
(7) \uc0\u35753 \u24744 \u21442 \u19982 \u26377 \u20851 \u25105 \u20204 \u20135 \u21697 \u21644 \u26381 \u21153 \u30340 \u35843 \u26597 \u12290 \
|
||||||
|
\
|
||||||
|
## \uc0\u20116 \u12289 \u20027 \u26435 \u21033 \u20041 \u21153 \u26465 \u27454 \
|
||||||
|
\
|
||||||
|
5.1 \uc0\u36134 \u21495 \u20351 \u29992 \u35268 \u33539 \
|
||||||
|
\
|
||||||
|
5.1.1 \uc0\u24744 \u22312 \u20351 \u29992 \u26412 \u26381 \u21153 \u21069 \u38656 \u35201 \u27880 \u20876 \u19968 \u20010 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u12290 \u26412 \u36719 \u20214 \u20026 \u24744 \u25552 \u20379 \u27880 \u20876 \u21450 \u30331 \u24405 \u36890 \u36947 \u65292 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u36890 \u36807 \u25163 \u26426 \u21495 \u30721 \u36827 \u34892 \u27880 \u20876 \u65292 \u24744 \u21487 \u25353 \u29031 \u39029 \u38754 \u25552 \u31034 \u22635 \u20889 \u20449 \u24687 \u12289 \u38405 \u35835 \u24182 \u21516 \u24847 \u26412 \u21327 \u35758 \u65292 \u22312 \u23436 \u25104 \u20840 \u37096 \u27880 \u20876 \u30331 \u24405 \u31243 \u24207 \u21518 \u65292 \u25104 \u20026 \u26412 \u36719 \u20214 \u29992 \u25143 \u12290 \u21478 \u22806 \u25105 \u20204 \u26377 \u26435 \u26681 \u25454 \u29992 \u25143 \u38656 \u27714 \u25110 \u20135 \u21697 \u38656 \u35201 \u23545 \u36134 \u21495 \u27880 \u20876 \u30340 \u26041 \u24335 \u36827 \u34892 \u21464 \u26356 \u65292 \u20851 \u20110 \u24744 \u20351 \u29992 \u36134 \u21495 \u30340 \u20855 \u20307 \u35268 \u21017 \u65292 \u35831 \u36981 \u23432 \u30456 \u20851 \u36134 \u21495 \u20351 \u29992 \u21327 \u35758 \u20197 \u21450 \u25105 \u20204 \u20026 \u27492 \u21457 \u24067 \u30340 \u19987 \u39033 \u35268 \u21017 \u12290 \
|
||||||
|
\
|
||||||
|
5.1.2 \uc0\u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u30340 \u25152 \u26377 \u26435 \u24402 \u25105 \u20204 \u20844 \u21496 \u25152 \u26377 \u65292 \u29992 \u25143 \u23436 \u25104 \u30003 \u35831 \u27880 \u20876 \u25163 \u32493 \u21518 \u65292 \u20165 \u33719 \u24471 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u30340 \u20351 \u29992 \u26435 \u65292 \u19988 \u35813 \u20351 \u29992 \u26435 \u20165 \u23646 \u20110 \u21021 \u22987 \u30003 \u35831 \u27880 \u20876 \u20154 \u12290 \u21516 \u26102 \u65292 \u21021 \u22987 \u30003 \u35831 \u27880 \u20876 \u20154 \u19981 \u24471 \u36192 \u19982 \u12289 \u20511 \u29992 \u12289 \u20986 \u31199 \u12289 \u36716 \u35753 \u25110 \u21806 \u21334 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u25110 \u32773 \u20197 \u20854 \u20182 \u26041 \u24335 \u35768 \u21487 \u38750 \u21021 \u22987 \u30003 \u35831 \u27880 \u20876 \u20154 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u12290 \u38750 \u21021 \u22987 \u30003 \u35831 \u27880 \u20876 \u20154 \u19981 \u24471 \u36890 \u36807 \u21463 \u36192 \u12289 \u32487 \u25215 \u12289 \u25215 \u31199 \u12289 \u21463 \u35753 \u25110 \u32773 \u20854 \u20182 \u20219 \u20309 \u26041 \u24335 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u12290 \u22914 \u25105 \u20204 \u21028 \u26029 \u24744 \u36134 \u21495 \u30340 \u20351 \u29992 \u21487 \u33021 \u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u12289 \u21361 \u21450 \u24744 \u30340 \u36134 \u21495 \u23433 \u20840 \u21450 /\u25110 \u26412 \u36719 \u20214 \u20449 \u24687 \u23433 \u20840 \u30340 \u65292 \u25105 \u20204 \u21487 \u25298 \u32477 \u25552 \u20379 \u30456 \u24212 \u26381 \u21153 \u25110 \u32456 \u27490 \u26412 \u21327 \u35758 \u12290 \u25105 \u20204 \u26377 \u26435 \u35270 \u24773 \u20917 \u23553 \u31105 \u25110 \u27880 \u38144 \u12289 \u22238 \u25910 \u35813 \u36134 \u21495 \u65292 \u30001 \u27492 \u24102 \u26469 \u30340 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u20869 \u23481 \u12289 \u34394 \u25311 \u36130 \u20135 \u28165 \u31354 \u31561 \u25439 \u22833 \u30001 \u24744 \u26412 \u20154 \u21450 \u35813 \u36134 \u21495 \u20351 \u29992 \u32773 \u33258 \u34892 \u25215 \u25285 \u12290 \
|
||||||
|
\
|
||||||
|
5.1.3 \uc0\u24744 \u27880 \u20876 \u33719 \u24471 \u30340 \u36134 \u21495 \u12289 \u35774 \u32622 \u30340 \u23494 \u30721 \u26159 \u24744 \u30331 \u24405 \u24182 \u20197 \u29992 \u25143 \u36523 \u20221 \u20351 \u29992 \u26412 \u36719 \u20214 \u30340 \u20973 \u35777 \u65292 \u24744 \u30340 \u36134 \u25143 \u20165 \u38480 \u24744 \u26412 \u20154 \u20351 \u29992 \u65292 \u24744 \u26377 \u36131 \u20219 \u22949 \u21892 \u20445 \u31649 \u24744 \u30340 \u27880 \u20876 \u29992 \u25143 \u20449 \u24687 \u21450 \u29992 \u25143 \u23494 \u30721 \u30340 \u23433 \u20840 \u65292 \u24744 \u38656 \u35201 \u23545 \u24744 \u30340 \u27880 \u20876 \u29992 \u25143 \u20197 \u21450 \u23494 \u30721 \u19979 \u30340 \u34892 \u20026 \u25215 \u25285 \u27861 \u24459 \u36131 \u20219 \u12290 \u24744 \u21516 \u24847 \u22312 \u20219 \u20309 \u24773 \u20917 \u19979 \u19981 \u21521 \u20182 \u20154 \u27844 \u38706 \u29992 \u25143 \u21450 \u23494 \u30721 \u20449 \u24687 \u12290 \u24403 \u22312 \u24744 \u24576 \u30097 \u20182 \u20154 \u22312 \u20351 \u29992 \u24744 \u30340 \u36134 \u21495 \u26102 \u65292 \u24744 \u24212 \u31435 \u21363 \u36890 \u30693 \u25105 \u20204 \u12290 \
|
||||||
|
\
|
||||||
|
5.1.4 \uc0\u29992 \u25143 \u27880 \u20876 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u21518 \u22914 \u26524 \u38271 \u26399 \u65288 \u36229 \u36807 \u12304 6\u12305 \u20010 \u26376 \u65289 \u19981 \u30331 \u24405 \u35813 \u36134 \u21495 \u65292 \u25105 \u20204 \u26377 \u26435 \u22238 \u25910 \u35813 \u36134 \u21495 \u65292 \u20197 \u20813 \u36896 \u25104 \u36164 \u28304 \u28010 \u36153 \u65292 \u30001 \u27492 \u24102 \u26469 \u30340 \u20219 \u20309 \u25439 \u22833 \u22343 \u30001 \u29992 \u25143 \u33258 \u34892 \u25215 \u25285 \u12290 \
|
||||||
|
\
|
||||||
|
5.1.5 \uc0\u25105 \u20204 \u29305 \u21035 \u25552 \u37266 \u65292 \u24744 \u24212 \u22949 \u21892 \u20445 \u31649 \u24744 \u30340 \u36134 \u21495 \u21644 \u23494 \u30721 \u12290 \u24403 \u24744 \u20351 \u29992 \u23436 \u26412 \u26381 \u21153 \u21518 \u65292 \u24212 \u23433 \u20840 \u36864 \u20986 \u12290 \u24744 \u39035 \u23545 \u36134 \u21495 \u36827 \u34892 \u30340 \u25152 \u26377 \u27963 \u21160 \u21644 \u34892 \u20026 \u36127 \u36131 \u65292 \u22240 \u24744 \u20445 \u31649 \u19981 \u21892 \u23548 \u33268 \u36973 \u21463 \u36134 \u21495 \u25110 \u23494 \u30721 \u22833 \u31363 \u12289 \u36134 \u21495 \u34987 \u38750 \u27861 \u20351 \u29992 \u65292 \u30456 \u20851 \u36131 \u20219 \u30001 \u24744 \u33258 \u34892 \u25215 \u25285 \u65292 \u24744 \u21487 \u36890 \u36807 \u21496 \u27861 \u12289 \u34892 \u25919 \u31561 \u25937 \u27982 \u36884 \u24452 \u21521 \u20405 \u26435 \u34892 \u20026 \u20154 \u36861 \u20607 \u12290 \
|
||||||
|
5.1.6\uc0\u24744 \u19981 \u24471 \u24694 \u24847 \u27880 \u20876 \u36134 \u21495 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u39057 \u32321 \u27880 \u20876 \u12289 \u25209 \u37327 \u27880 \u20876 \u12289 \u20351 \u29992 \u20182 \u20154 \u36523 \u20221 \u27880 \u20876 \u25110 \u20854 \u20182 \u19981 \u20197 \u27491 \u24120 \u20351 \u29992 \u26412 \u36719 \u20214 \u26381 \u21153 \u20026 \u30446 \u30340 \u30340 \u36134 \u21495 \u27880 \u20876 \u34892 \u20026 \u12290 \u38500 \u27492 \u22806 \u65292 \u24744 \u30340 \u36134 \u25143 \u19981 \u24471 \u20197 \u20219 \u20309 \u26041 \u24335 \u36716 \u35753 \u65292 \u21542 \u21017 \u25105 \u20204 \u26377 \u26435 \u36861 \u31350 \u24744 \u30340 \u36829 \u32422 \u36131 \u20219 \u65292 \u19988 \u30001 \u27492 \u20135 \u29983 \u30340 \u36131 \u20219 \u21450 \u21518 \u26524 \u22343 \u30001 \u24744 \u33258 \u34892 \u25215 \u25285 \u12290 \
|
||||||
|
\
|
||||||
|
5.2 \uc0\u29992 \u25143 \u27880 \u24847 \u20107 \u39033 \
|
||||||
|
\
|
||||||
|
5.2.1 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65306 \u20026 \u20102 \u21521 \u24744 \u25552 \u20379 \u26377 \u25928 \u30340 \u26381 \u21153 \u65292 \u26412 \u36719 \u20214 \u20250 \u21033 \u29992 \u24744 \u32456 \u31471 \u35774 \u22791 \u30340 \u22788 \u29702 \u22120 \u21644 \u24102 \u23485 \u31561 \u36164 \u28304 \u12290 \u26412 \u36719 \u20214 \u20351 \u29992 \u36807 \u31243 \u20013 \u21487 \u33021 \u20135 \u29983 \u25968 \u25454 \u27969 \u37327 \u30340 \u36153 \u29992 \u65292 \u29992 \u25143 \u38656 \u33258 \u34892 \u21521 \u36816 \u33829 \u21830 \u20102 \u35299 \u30456 \u20851 \u36164 \u36153 \u20449 \u24687 \u65292 \u24182 \u33258 \u34892 \u25215 \u25285 \u30456 \u20851 \u36153 \u29992 \u12290 \
|
||||||
|
\
|
||||||
|
5.2.2 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65306 \u26412 \u36719 \u20214 \u30340 \u26576 \u20123 \u21151 \u33021 \u21487 \u33021 \u20250 \u35753 \u31532 \u19977 \u26041 \u30693 \u26195 \u29992 \u25143 \u30340 \u20449 \u24687 \u65292 \u20363 \u22914 \u65306 \u29992 \u25143 \u36873 \u25321 \u31508 \u22696 \u35759 \u20351 \u19982 \u20854 \u20182 \u36719 \u20214 \u25110 \u30828 \u20214 \u20449 \u24687 \u20114 \u36890 \u21518 \u65292 \u20854 \u20182 \u36719 \u20214 \u25110 \u30828 \u20214 \u30340 \u25552 \u20379 \u26041 \u21487 \u20197 \u33719 \u21462 \u29992 \u25143 \u22312 \u31508 \u22696 \u35759 \u20351 \u20027 \u21160 \u20844 \u24320 \u25110 \u20256 \u36755 \u30340 \u30456 \u20851 \u20449 \u24687 \u65292 \u29992 \u25143 \u22312 \u36873 \u25321 \u21069 \u24212 \u20805 \u20998 \u20102 \u35299 \u20854 \u20182 \u36719 \u20214 \u25110 \u30828 \u20214 \u30340 \u20135 \u21697 \u21151 \u33021 \u21450 \u20449 \u24687 \u20445 \u25252 \u31574 \u30053 \u12290 \
|
||||||
|
\
|
||||||
|
5.2.3 \uc0\u24744 \u22312 \u20351 \u29992 \u26412 \u36719 \u20214 \u26576 \u19968 \u29305 \u23450 \u26381 \u21153 \u26102 \u65292 \u35813 \u26381 \u21153 \u21487 \u33021 \u20250 \u21478 \u26377 \u21333 \u29420 \u30340 \u21327 \u35758 \u12289 \u30456 \u20851 \u19994 \u21153 \u35268 \u21017 \u31561 \u65288 \u20197 \u19979 \u32479 \u31216 \u20026 \'93\u21333 \u29420 \u21327 \u35758 \'94\u65289 \u65292 \u24744 \u22312 \u20351 \u29992 \u35813 \u39033 \u26381 \u21153 \u21069 \u35831 \u38405 \u35835 \u24182 \u21516 \u24847 \u30456 \u20851 \u30340 \u21333 \u29420 \u21327 \u35758 \u65307 \u24744 \u20351 \u29992 \u21069 \u36848 \u29305 \u23450 \u26381 \u21153 \u65292 \u21363 \u35270 \u20026 \u24744 \u25509 \u21463 \u30456 \u20851 \u21333 \u29420 \u21327 \u35758 \u12290 \u20363 \u22914 \u65306 \u22914 \u26524 \u24744 \u38656 \u35201 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u25903 \u20184 \u30456 \u20851 \u26381 \u21153 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u31508 \u22696 \u35759 \u20351 \u32418 \u21253 \u12289 \u36716 \u36134 \u12289 \u25910 \u27454 \u12289 \u20805 \u20540 \u12289 \u25552 \u29616 \u31561 \u25903 \u20184 \u26381 \u21153 \u65289 \u26102 \u65292 \u38656 \u38405 \u35835 \u24182 \u36981 \u23432 \u12298 \u31508 \u22696 \u35759 \u20351 \u25903 \u20184 \u26381 \u21153 \u21327 \u35758 \u12299 \u65307 \u24744 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u25903 \u20184 \u30456 \u20851 \u26381 \u21153 \u65292 \u21363 \u35270 \u20026 \u24744 \u25509 \u21463 \u12298 \u31508 \u22696 \u35759 \u20351 \u25903 \u20184 \u26381 \u21153 \u21327 \u35758 \u12299 \u12290 \
|
||||||
|
\
|
||||||
|
5.2.4 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u25105 \u20204 \u23558 \u23613 \u20854 \u21830 \u19994 \u19978 \u30340 \u21512 \u29702 \u21162 \u21147 \u20445 \u38556 \u24744 \u22312 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u20013 \u30340 \u25968 \u25454 \u23384 \u20648 \u23433 \u20840 \u65292 \u20294 \u26159 \u65292 \u25105 \u20204 \u24182 \u19981 \u33021 \u23601 \u27492 \u25552 \u20379 \u23436 \u20840 \u20445 \u35777 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u20197 \u19979 \u24773 \u24418 \u65306 \
|
||||||
|
\
|
||||||
|
5.2.4.1 \uc0\u25105 \u20204 \u19981 \u23545 \u24744 \u22312 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u20013 \u30456 \u20851 \u25968 \u25454 \u30340 \u21024 \u38500 \u25110 \u23384 \u20648 \u22833 \u36133 \u36127 \u36131 \u65307 \
|
||||||
|
\
|
||||||
|
5.2.4.2 \uc0\u25105 \u20204 \u26377 \u26435 \u26681 \u25454 \u23454 \u38469 \u24773 \u20917 \u33258 \u34892 \u20915 \u23450 \u21333 \u20010 \u29992 \u25143 \u22312 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u20013 \u25968 \u25454 \u30340 \u26368 \u38271 \u23384 \u20648 \u26399 \u38480 \u65292 \u24182 \u22312 \u26381 \u21153 \u22120 \u19978 \u20026 \u20854 \u20998 \u37197 \u25968 \u25454 \u26368 \u22823 \u23384 \u20648 \u31354 \u38388 \u31561 \u12290 \u24744 \u21487 \u26681 \u25454 \u33258 \u24049 \u30340 \u38656 \u35201 \u33258 \u34892 \u22791 \u20221 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u20013 \u30340 \u30456 \u20851 \u25968 \u25454 \u65307 \
|
||||||
|
\
|
||||||
|
5.2.4.3 \uc0\u22914 \u26524 \u24744 \u20572 \u27490 \u20351 \u29992 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u25110 \u26381 \u21153 \u34987 \u32456 \u27490 \u25110 \u21462 \u28040 \u65292 \u25105 \u20204 \u21487 \u20197 \u20174 \u26381 \u21153 \u22120 \u19978 \u27704 \u20037 \u22320 \u21024 \u38500 \u24744 \u30340 \u25968 \u25454 \u12290 \u26381 \u21153 \u20572 \u27490 \u12289 \u32456 \u27490 \u25110 \u21462 \u28040 \u21518 \u65292 \u25105 \u20204 \u27809 \u26377 \u20041 \u21153 \u21521 \u24744 \u36820 \u36824 \u20219 \u20309 \u25968 \u25454 \u12290 \
|
||||||
|
\
|
||||||
|
5.2.5 \uc0\u29992 \u25143 \u22312 \u20351 \u29992 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u26102 \u65292 \u38656 \u33258 \u34892 \u25215 \u25285 \u22914 \u19979 \u26469 \u33258 \u25105 \u20204 \u19981 \u21487 \u25511 \u21046 \u30340 \u39118 \u38505 \u20869 \u23481 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \
|
||||||
|
\
|
||||||
|
5.2.5.1 \uc0\u30001 \u20110 \u19981 \u21487 \u25239 \u21147 \u22240 \u32032 \u21487 \u33021 \u23548 \u33268 \u30340 \u20010 \u20154 \u20449 \u24687 \u20002 \u22833 \u12289 \u27844 \u38706 \u31561 \u39118 \u38505 \u65307 \
|
||||||
|
\
|
||||||
|
5.2.5.2 \uc0\u29992 \u25143 \u24517 \u39035 \u36873 \u25321 \u19982 \u25152 \u23433 \u35013 \u32456 \u31471 \u35774 \u22791 \u30456 \u21305 \u37197 \u30340 \u36719 \u20214 \u29256 \u26412 \u65292 \u21542 \u21017 \u65292 \u30001 \u20110 \u36719 \u20214 \u19982 \u32456 \u31471 \u35774 \u22791 \u22411 \u21495 \u19981 \u21305 \u37197 \u25152 \u23548 \u33268 \u30340 \u20219 \u20309 \u38382 \u39064 \u25110 \u25439 \u23475 \u65292 \u22343 \u30001 \u29992 \u25143 \u33258 \u34892 \u25215 \u25285 \u65307 \
|
||||||
|
\
|
||||||
|
5.2.5.3 \uc0\u29992 \u25143 \u22312 \u20351 \u29992 \u26412 \u36719 \u20214 \u35775 \u38382 \u31532 \u19977 \u26041 \u32593 \u31449 \u26102 \u65292 \u22240 \u31532 \u19977 \u26041 \u32593 \u31449 \u21450 \u30456 \u20851 \u20869 \u23481 \u25152 \u21487 \u33021 \u23548 \u33268 \u30340 \u39118 \u38505 \u65292 \u30001 \u29992 \u25143 \u33258 \u34892 \u25215 \u25285 \u65307 \
|
||||||
|
\
|
||||||
|
5.2.5.4 \uc0\u29992 \u25143 \u21457 \u24067 \u30340 \u20869 \u23481 \u34987 \u20182 \u20154 \u36716 \u21457 \u12289 \u20998 \u20139 \u65292 \u22240 \u27492 \u31867 \u20256 \u25773 \u21487 \u33021 \u24102 \u26469 \u30340 \u39118 \u38505 \u21644 \u36131 \u20219 \u65307 \
|
||||||
|
\
|
||||||
|
5.2.5.5 \uc0\u30001 \u20110 \u26080 \u32447 \u32593 \u32476 \u20449 \u21495 \u19981 \u31283 \u23450 \u12289 \u26080 \u32447 \u32593 \u32476 \u24102 \u23485 \u23567 \u31561 \u21407 \u22240 \u65292 \u25152 \u24341 \u36215 \u30340 \u31508 \u22696 \u35759 \u20351 \u30331 \u24405 \u22833 \u36133 \u12289 \u36164 \u26009 \u21516 \u27493 \u19981 \u23436 \u25972 \u12289 \u39029 \u38754 \u25171 \u24320 \u36895 \u24230 \u24930 \u31561 \u39118 \u38505 \u12290 \
|
||||||
|
\
|
||||||
|
5.2.6 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u31508 \u22696 \u35759 \u20351 \u21487 \u33021 \u20250 \u19981 \u26102 \u21457 \u24067 \u24182 \u25191 \u34892 \u19968 \u20123 \u29992 \u25143 \u22870 \u21169 \u27963 \u21160 \u65292 \u30456 \u20851 \u27963 \u21160 \u30340 \u20855 \u20307 \u35268 \u21017 \u30340 \u21046 \u23450 \u26435 \u21644 \u26368 \u32456 \u35299 \u37322 \u26435 \u24402 \u25105 \u20204 \u25152 \u26377 \u65292 \u25105 \u20204 \u26377 \u26435 \u26681 \u25454 \u33258 \u24049 \u30340 \u21028 \u26029 \u20915 \u23450 \u25552 \u21069 \u32456 \u27490 \u27963 \u21160 \u25110 \u24310 \u38271 \u27963 \u21160 \u26102 \u38388 \u12290 \u21516 \u19968 \u31508 \u22696 \u35759 \u20351 \u29992 \u25143 \u21517 \u12289 \u21516 \u19968 \u25163 \u26426 \u21495 \u12289 \u21516 \u19968 \u36523 \u20221 \u35777 \u21495 \u30721 \u12289 \u21516 \u19968 \u25163 \u26426 \u35774 \u22791 \u22343 \u35270 \u20026 \u21516 \u19968 \u29992 \u25143 \u12290 \u22914 \u26524 \u25105 \u20204 \u21457 \u29616 \u26377 \u29992 \u25143 \u21033 \u29992 \u19981 \u27491 \u24403 \u25163 \u27573 \u21442 \u19982 \u27963 \u21160 \u65292 \u25110 \u32773 \u22914 \u26524 \u29992 \u25143 \u23384 \u22312 \u25110 \u28041 \u23244 \u36829 \u27861 \u36829 \u35268 \u34892 \u20026 \u24773 \u20917 \u65288 \u21253 \u25324 \u19981 \u38480 \u20110 \u27927 \u38065 \u12289 \u22806 \u25346 \u12289 \u20316 \u24330 \u12289 \u22871 \u29616 \u12289 \u36172 \u21338 \u12289 \u21047 \u22870 \u21169 \u31867 \u30340 \u27963 \u21160 \u12289 \u20854 \u20182 \u39118 \u38505 \u34892 \u20026 \u65289 \u65292 \u25105 \u20204 \u26377 \u26435 \u21462 \u28040 \u24744 \u21442 \u19982 \u27963 \u21160 \u30340 \u36164 \u26684 \u65292 \u24182 \u26377 \u26435 \u36861 \u22238 \u24744 \u24050 \u32463 \u33719 \u24471 \u30340 \u22870 \u21169 \u25110 \u20195 \u24065 \u25110 \u20854 \u20182 \u22870 \u21697 \u12290 \u22914 \u26524 \u22240 \u38750 \u23454 \u21517 \u35748 \u35777 \u23548 \u33268 \u24744 \u26080 \u27861 \u21442 \u19982 \u27963 \u21160 \u30340 \u65292 \u35270 \u20026 \u24744 \u33258 \u21160 \u25918 \u24323 \u27963 \u21160 \u36164 \u26684 \u12290 \
|
||||||
|
\
|
||||||
|
5.3 \uc0\u31532 \u19977 \u26041 \u20135 \u21697 \u21644 \u26381 \u21153 \
|
||||||
|
\
|
||||||
|
5.3.1 \uc0\u24744 \u22312 \u20351 \u29992 \u26412 \u36719 \u20214 \u31532 \u19977 \u26041 \u25552 \u20379 \u30340 \u20135 \u21697 \u25110 \u26381 \u21153 \u26102 \u65292 \u38500 \u36981 \u23432 \u26412 \u21327 \u35758 \u32422 \u23450 \u22806 \u65292 \u36824 \u24212 \u36981 \u23432 \u31532 \u19977 \u26041 \u30340 \u29992 \u25143 \u21327 \u35758 \u12290 \u25105 \u20204 \u21644 \u31532 \u19977 \u26041 \u23545 \u21487 \u33021 \u20986 \u29616 \u30340 \u32416 \u32439 \u22312 \u27861 \u24459 \u35268 \u23450 \u21644 \u32422 \u23450 \u30340 \u33539 \u22260 \u20869 \u21508 \u33258 \u25215 \u25285 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
5.3.2 \uc0\u22240 \u29992 \u25143 \u20351 \u29992 \u26412 \u36719 \u20214 \u25110 \u35201 \u27714 \u25105 \u20204 \u25552 \u20379 \u29305 \u23450 \u26381 \u21153 \u26102 \u65292 \u26412 \u36719 \u20214 \u21487 \u33021 \u20250 \u35843 \u29992 \u31532 \u19977 \u26041 \u31995 \u32479 \u25110 \u32773 \u36890 \u36807 \u31532 \u19977 \u26041 \u25903 \u25345 \u29992 \u25143 \u30340 \u20351 \u29992 \u25110 \u35775 \u38382 \u65292 \u20351 \u29992 \u25110 \u35775 \u38382 \u30340 \u32467 \u26524 \u30001 \u35813 \u31532 \u19977 \u26041 \u25552 \u20379 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u31532 \u19977 \u26041 \u36890 \u36807 \u31508 \u22696 \u35759 \u20351 \u24320 \u25918 \u24179 \u21488 \u25509 \u20837 \u30340 \u20869 \u23481 \u31561 \u65289 \u65292 \u25105 \u20204 \u19981 \u20445 \u35777 \u36890 \u36807 \u31532 \u19977 \u26041 \u25552 \u20379 \u26381 \u21153 \u21450 \u20869 \u23481 \u30340 \u23433 \u20840 \u24615 \u12289 \u20934 \u30830 \u24615 \u12289 \u26377 \u25928 \u24615 \u21450 \u20854 \u23427 \u19981 \u30830 \u23450 \u30340 \u39118 \u38505 \u65292 \u24744 \u24212 \u33258 \u34892 \u21028 \u26029 \u27492 \u31867 \u31532 \u19977 \u26041 \u32593 \u31449 \u25110 \u32773 \u26381 \u21153 \u30340 \u23433 \u20840 \u24615 \u21644 \u21487 \u29992 \u24615 \u65292 \u24182 \u33258 \u34892 \u25215 \u25285 \u30456 \u20851 \u39118 \u38505 \u21644 \u36131 \u20219 \u65292 \u30001 \u27492 \u33509 \u24341 \u21457 \u30340 \u20219 \u20309 \u20105 \u35758 \u21450 \u25439 \u23475 \u65292 \u19982 \u25105 \u20204 \u26080 \u20851 \u65292 \u25105 \u20204 \u19981 \u25215 \u25285 \u20219 \u20309 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
5.3.3 \uc0\u31532 \u19977 \u26041 \u26381 \u21153 \u25552 \u20379 \u32773 \u21487 \u20197 \u36890 \u36807 \u26412 \u36719 \u20214 \u21521 \u24744 \u25552 \u20379 \u20135 \u21697 \u25110 \u32773 \u26381 \u21153 \u65292 \u27604 \u22914 \u24744 \u21487 \u20197 \u36141 \u20080 \u24182 \u20351 \u29992 \u31532 \u19977 \u26041 \u24320 \u21457 \u30340 \u24212 \u29992 \u31243 \u24207 \u12289 \u25509 \u21463 \u31532 \u19977 \u26041 \u25552 \u20379 \u30340 \u26381 \u21153 \u21450 \u20135 \u21697 \u65292 \u25110 \u32773 \u36890 \u36807 \u31508 \u22696 \u35759 \u20351 \u25480 \u26435 \u30331 \u24405 \u33021 \u21147 \u30331 \u24405 \u24182 \u20351 \u29992 \u20854 \u20182 \u20114 \u32852 \u32593 \u26381 \u21153 \u12290 \u22312 \u27492 \u36807 \u31243 \u20013 \u65292 \u31532 \u19977 \u26041 \u26381 \u21153 \u25552 \u20379 \u32773 \u21487 \u33021 \u20250 \u25910 \u38598 \u12289 \u20351 \u29992 \u21644 \u23384 \u20648 \u24744 \u30340 \u30456 \u20851 \u25968 \u25454 \u25110 \u20449 \u24687 \u65292 \u25105 \u20204 \u36890 \u36807 \u19982 \u31532 \u19977 \u26041 \u26381 \u21153 \u25552 \u20379 \u32773 \u31614 \u35746 \u30340 \u26377 \u20851 \u21327 \u35758 \u12289 \u31508 \u22696 \u35759 \u20351 \u30456 \u20851 \u35268 \u33539 \u20197 \u21450 \u21512 \u29702 \u30340 \u20135 \u21697 \u27969 \u31243 \u35774 \u35745 \u65292 \u20005 \u26684 \u35201 \u27714 \u31532 \u19977 \u26041 \u26381 \u21153 \u25552 \u20379 \u32773 \u33719 \u21462 \u24744 \u30340 \u20219 \u20309 \u25968 \u25454 \u22343 \u24212 \u36981 \u23432 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u30340 \u35268 \u23450 \u65292 \u24517 \u39035 \u20107 \u20808 \u33719 \u24471 \u24744 \u30340 \u26126 \u30830 \u21516 \u24847 \u65292 \u37319 \u21462 \u24517 \u35201 \u30340 \u25968 \u25454 \u20445 \u25252 \u25514 \u26045 \u65292 \u19988 \u20165 \u20026 \u20135 \u21697 \u25110 \u26381 \u21153 \u20043 \u30446 \u30340 \u21512 \u29702 \u20351 \u29992 \u24744 \u30340 \u30456 \u20851 \u25968 \u25454 \u65292 \u21521 \u24744 \u25552 \u20379 \u20462 \u25913 \u25110 \u21024 \u38500 \u33258 \u24049 \u25968 \u25454 \u30340 \u26041 \u24335 \u65292 \u24182 \u22312 \u20572 \u27490 \u26381 \u21153 \u26102 \u24517 \u39035 \u21024 \u38500 \u20840 \u37096 \u25968 \u25454 \u31561 \u65292 \u23613 \u26368 \u22823 \u21487 \u33021 \u20445 \u38556 \u24744 \u30340 \u25968 \u25454 \u21644 \u38544 \u31169 \u19981 \u21463 \u20405 \u29359 \u12290 \u24744 \u22312 \u25509 \u21463 \u25110 \u20351 \u29992 \u31532 \u19977 \u26041 \u20135 \u21697 \u25110 \u26381 \u21153 \u21069 \u24212 \u20805 \u20998 \u20102 \u35299 \u31532 \u19977 \u26041 \u20135 \u21697 \u25110 \u26381 \u21153 \u30340 \u26465 \u27454 \u21450 \u25919 \u31574 \u12290 \u22914 \u26524 \u24744 \u21457 \u29616 \u26377 \u31532 \u19977 \u26041 \u26381 \u21153 \u25552 \u20379 \u32773 \u23384 \u22312 \u30456 \u20851 \u36829 \u27861 \u36829 \u35268 \u34892 \u20026 \u65292 \u21487 \u20197 \u21521 \u25105 \u20204 \u25237 \u35785 \u65292 \u25105 \u20204 \u23558 \u26597 \u23454 \u21518 \u20104 \u20197 \u22788 \u29702 \u12290 \
|
||||||
|
\
|
||||||
|
5.3.4 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u25105 \u20204 \u26377 \u26435 \u20915 \u23450 \u23558 \u26412 \u36719 \u20214 \u20316 \u21830 \u19994 \u29992 \u36884 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u24320 \u21457 \u12289 \u20351 \u29992 \u26412 \u36719 \u20214 \u30340 \u37096 \u20998 \u26381 \u21153 \u20026 \u31532 \u19977 \u26041 \u20316 \u25512 \u24191 \u31561 \u65292 \u25105 \u20204 \u25215 \u35834 \u22312 \u25512 \u24191 \u36807 \u31243 \u20013 \u20005 \u26684 \u25353 \u29031 \u26412 \u21327 \u35758 \u32422 \u23450 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u21516 \u26102 \u24744 \u20063 \u21487 \u20197 \u26681 \u25454 \u31995 \u32479 \u35774 \u32622 \u36873 \u25321 \u23631 \u34109 \u12289 \u25298 \u32477 \u25509 \u25910 \u30456 \u20851 \u25512 \u24191 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
5.4\uc0\u36134 \u21495 \u20449 \u24687 \u35774 \u32622 \u21450 \u32500 \u25252 \
|
||||||
|
\
|
||||||
|
5.4.1\uc0\u24744 \u22312 \u27880 \u20876 \u25110 \u20351 \u29992 \u26412 \u36719 \u20214 \u26102 \u35774 \u32622 \u30340 \u21517 \u31216 \u12289 \u22836 \u20687 \u21644 \u31616 \u20171 \u31561 \u36134 \u21495 \u20449 \u24687 \u36164 \u26009 \u24212 \u36981 \u23432 \u27861 \u24459 \u27861 \u35268 \u12289 \u31038 \u20250 \u36947 \u24503 \u39118 \u23578 \u21644 \u20449 \u24687 \u30495 \u23454 \u24615 \u31561 \u21407 \u21017 \u65292 \u19981 \u24471 \u20986 \u29616 \u19981 \u33391 \u20449 \u24687 \u65292 \u19981 \u24471 \u20882 \u29992 \u20182 \u20154 \u22995 \u21517 \u12289 \u21517 \u31216 \u12289 \u23383 \u21495 \u12289 \u22836 \u20687 \u31561 \u25110 \u37319 \u21462 \u20854 \u20182 \u36275 \u20197 \u24341 \u36215 \u28151 \u28102 \u30340 \u26041 \u24335 \u35774 \u32622 \u36134 \u21495 \u65292 \u19981 \u24471 \u20405 \u23475 \u31532 \u19977 \u26041 \u30340 \u21512 \u27861 \u26435 \u30410 \u12290 \
|
||||||
|
\
|
||||||
|
5.4.2\uc0\u22312 \u20351 \u29992 \u26412 \u36719 \u20214 \u26381 \u21153 \u26102 \u65292 \u24744 \u24212 \u24403 \u25353 \u26412 \u36719 \u20214 \u39029 \u38754 \u30340 \u25552 \u31034 \u20934 \u30830 \u23436 \u25972 \u22320 \u25552 \u20379 \u24744 \u30340 \u20449 \u24687 \u65288 \u21253 \u25324 \u24744 \u30340 \u22995 \u21517 \u21450 \u30005 \u23376 \u37038 \u20214 \u22320 \u22336 \u12289 \u32852 \u31995 \u30005 \u35805 \u12289 \u32852 \u31995 \u22320 \u22336 \u31561 \u65289 \u65292 \u20197 \u20415 \u26412 \u36719 \u20214 \u25110 \u20854 \u20182 \u29992 \u25143 \u19982 \u24744 \u32852 \u31995 \u12290 \
|
||||||
|
\
|
||||||
|
5.4.3\uc0\u24744 \u24212 \u24403 \u21450 \u26102 \u26356 \u26032 \u24744 \u25552 \u20379 \u30340 \u20449 \u24687 \u65292 \u22312 \u27861 \u24459 \u26377 \u26126 \u30830 \u35268 \u23450 \u35201 \u27714 \u26412 \u36719 \u20214 \u24517 \u39035 \u23545 \u29992 \u25143 \u30340 \u20449 \u24687 \u36827 \u34892 \u26680 \u23454 \u30340 \u24773 \u20917 \u19979 \u65292 \u26412 \u36719 \u20214 \u23558 \u20381 \u27861 \u19981 \u26102 \u22320 \u23545 \u24744 \u30340 \u20449 \u24687 \u36827 \u34892 \u26816 \u26597 \u26680 \u23454 \u65292 \u24744 \u24212 \u24403 \u37197 \u21512 \u25552 \u20379 \u26368 \u26032 \u12289 \u30495 \u23454 \u12289 \u23436 \u25972 \u12289 \u26377 \u25928 \u30340 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
5.4.4\uc0\u22914 \u26412 \u36719 \u20214 \u25353 \u24744 \u26368 \u21518 \u19968 \u27425 \u25552 \u20379 \u30340 \u20449 \u24687 \u19982 \u24744 \u32852 \u31995 \u26410 \u26524 \u12289 \u24744 \u26410 \u25353 \u26412 \u36719 \u20214 \u30340 \u35201 \u27714 \u21450 \u26102 \u25552 \u20379 \u20449 \u24687 \u12289 \u24744 \u25552 \u20379 \u30340 \u20449 \u24687 \u23384 \u22312 \u26126 \u26174 \u19981 \u23454 \u25110 \u34892 \u25919 \u21496 \u27861 \u26426 \u20851 \u26680 \u23454 \u24744 \u25552 \u20379 \u30340 \u20449 \u24687 \u26080 \u25928 \u30340 \u65292 \u24744 \u23558 \u25215 \u25285 \u22240 \u27492 \u23545 \u24744 \u33258 \u36523 \u12289 \u20182 \u20154 \u21450 \u26412 \u36719 \u20214 \u36896 \u25104 \u30340 \u20840 \u37096 \u25439 \u22833 \u19982 \u19981 \u21033 \u21518 \u26524 \u12290 \u26412 \u36719 \u20214 \u21487 \u21521 \u24744 \u21457 \u20986 \u35810 \u38382 \u25110 \u35201 \u27714 \u25972 \u25913 \u30340 \u36890 \u30693 \u65292 \u24182 \u35201 \u27714 \u24744 \u36827 \u34892 \u37325 \u26032 \u35748 \u35777 \u65292 \u30452 \u33267 \u20013 \u27490 \u12289 \u32456 \u27490 \u23545 \u24744 \u25552 \u20379 \u37096 \u20998 \u25110 \u20840 \u37096 \u36719 \u20214 \u20135 \u21697 \u25110 \u26381 \u21153 \u65292 \u26412 \u36719 \u20214 \u23545 \u27492 \u19981 \u25215 \u25285 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
5.5\uc0\u36134 \u21495 \u27880 \u38144 \u21450 \u22238 \u25910 \
|
||||||
|
\
|
||||||
|
5.5.1\uc0\u24744 \u21487 \u20197 \u20381 \u29031 \u26412 \u36719 \u20214 \u30340 \u27969 \u31243 \u30003 \u35831 \u27880 \u38144 \u24744 \u30340 \u36134 \u21495 \u65292 \u20294 \u24744 \u20173 \u24212 \u23545 \u24744 \u22312 \u27880 \u38144 \u36134 \u21495 \u21069 \u25110 \u20351 \u29992 \u26412 \u36719 \u20214 \u26381 \u21153 \u26399 \u38388 \u30340 \u34892 \u20026 \u25215 \u25285 \u30456 \u24212 \u36131 \u20219 \u12290 \u27880 \u38144 \u25104 \u21151 \u21518 \u65292 \u38500 \u38750 \u27861 \u24459 \u27861 \u35268 \u21478 \u26377 \u35268 \u23450 \u65292 \u25105 \u20204 \u19981 \u20250 \u20026 \u24744 \u25552 \u20379 \u36134 \u21495 \u35760 \u24405 \u12289 \u20869 \u23481 \u12289 \u34394 \u25311 \u36130 \u20135 \u31561 \u24674 \u22797 \u25110 \u25552 \u20379 \u26381 \u21153 \u65292 \u35831 \u24744 \u35880 \u24910 \u25805 \u20316 \u12290 \
|
||||||
|
\
|
||||||
|
5.5.2\uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u20026 \u20102 \u20805 \u20998 \u20351 \u29992 \u36134 \u21495 \u36164 \u28304 \u65292 \u22914 \u24744 \u22312 \u27880 \u20876 \u21518 \u26410 \u21450 \u26102 \u36827 \u34892 \u21021 \u27425 \u30331 \u24405 \u20351 \u29992 \u25110 \u36830 \u32493 \u36229 \u36807 \u12304 6\u12305 \u20010 \u26376 \u26410 \u30331 \u24405 \u36134 \u21495 \u24182 \u20351 \u29992 \u65292 \u19988 \u19981 \u23384 \u22312 \u26410 \u21040 \u26399 \u25110 \u26410 \u23653 \u34892 \u23436 \u27605 \u30340 \u25345 \u32493 \u24615 \u26412 \u36719 \u20214 \u26381 \u21153 \u30340 \u65292 \u25105 \u20204 \u26377 \u26435 \u25910 \u22238 \u24744 \u30340 \u36134 \u21495 \u12290 \u22914 \u24744 \u30340 \u36134 \u21495 \u34987 \u25910 \u22238 \u65292 \u24744 \u26080 \u27861 \u36890 \u36807 \u24744 \u27492 \u21069 \u25345 \u26377 \u30340 \u36134 \u21495 \u30331 \u24405 \u24182 \u20351 \u29992 \u26412 \u36719 \u20214 \u65292 \u24744 \u36134 \u21495 \u19979 \u20445 \u23384 \u30340 \u20010 \u24615 \u21270 \u35774 \u32622 \u21644 \u20351 \u29992 \u35760 \u24405 \u20063 \u23558 \u26080 \u27861 \u24674 \u22797 \u12290 \
|
||||||
|
\
|
||||||
|
5.6\uc0\u36134 \u21495 \u36829 \u35268 \u22788 \u32622 \
|
||||||
|
\uc0\u33509 \u24744 \u22312 \u27880 \u20876 \u25110 \u20351 \u29992 \u26412 \u36719 \u20214 \u36134 \u21495 \u26102 \u65292 \u23384 \u22312 \u20219 \u20309 \u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u25110 \u19981 \u31526 \u21512 \u26412 \u21327 \u35758 \u32422 \u23450 \u30340 \u34892 \u20026 \u65292 \u25105 \u20204 \u26377 \u26435 \u19981 \u20104 \u27880 \u20876 \u65307 \u24050 \u32463 \u27880 \u20876 \u30340 \u65292 \u25105 \u20204 \u26377 \u26435 \u35270 \u24773 \u20917 \u35201 \u27714 \u29992 \u25143 \u38480 \u26399 \u25913 \u27491 \u12289 \u25110 \u21333 \u26041 \u37319 \u21462 \u30701 \u26399 \u23553 \u31105 \u12289 \u27704 \u20037 \u23553 \u31105 \u12289 \u27880 \u38144 \u36134 \u21495 \u31561 \u25514 \u26045 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20845 \u12289 \u29992 \u25143 \u34892 \u20026 \u35268 \u33539 \
|
||||||
|
\
|
||||||
|
6.1 \uc0\u20449 \u24687 \u20869 \u23481 \u35268 \u33539 \
|
||||||
|
\
|
||||||
|
6.1.1 \uc0\u26412 \u26465 \u25152 \u36848 \u20449 \u24687 \u20869 \u23481 \u26159 \u25351 \u29992 \u25143 \u20351 \u29992 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u36807 \u31243 \u20013 \u25152 \u21046 \u20316 \u12289 \u22797 \u21046 \u12289 \u21457 \u24067 \u12289 \u20256 \u25773 \u30340 \u20219 \u20309 \u20869 \u23481 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u12289 \u26165 \u31216 \u12289 \u22836 \u20687 \u12289 \u22995 \u21517 \u12289 \u29992 \u25143 \u35828 \u26126 \u31561 \u27880 \u20876 \u20449 \u24687 \u65292 \u25110 \u25991 \u23383 \u12289 \u35821 \u38899 \u12289 \u22270 \u29255 \u31561 \u21457 \u36865 \u12289 \u22238 \u22797 \u12289 \u22270 \u25991 \u21644 \u30456 \u20851 \u38142 \u25509 \u39029 \u38754 \u65292 \u20197 \u21450 \u20854 \u20182 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u25110 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u25152 \u20135 \u29983 \u30340 \u20869 \u23481 \u12290 \
|
||||||
|
\
|
||||||
|
6.1.2 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u31508 \u22696 \u35759 \u20351 \u19968 \u30452 \u33268 \u21147 \u20110 \u20026 \u29992 \u25143 \u25552 \u20379 \u25991 \u26126 \u20581 \u24247 \u12289 \u35268 \u33539 \u26377 \u24207 \u30340 \u32593 \u32476 \u29615 \u22659 \u65292 \u24744 \u19981 \u24471 \u21033 \u29992 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u25110 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u21046 \u20316 \u12289 \u22797 \u21046 \u12289 \u21457 \u24067 \u12289 \u20256 \u25773 \u22914 \u19979 \u24178 \u25200 \u31508 \u22696 \u35759 \u20351 \u27491 \u24120 \u36816 \u34892 \u65292 \u20197 \u21450 \u20405 \u29359 \u20854 \u20182 \u29992 \u25143 \u25110 \u31532 \u19977 \u26041 \u21512 \u27861 \u26435 \u30410 \u30340 \u20869 \u23481 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \
|
||||||
|
\
|
||||||
|
6.1.2.1 \uc0\u21457 \u24067 \u12289 \u20256 \u36865 \u12289 \u20256 \u25773 \u12289 \u23384 \u20648 \u36829 \u21453 \u22269 \u23478 \u27861 \u24459 \u27861 \u35268 \u31105 \u27490 \u30340 \u20869 \u23481 \u65306 \
|
||||||
|
\uc0\u65288 1\u65289 \u36829 \u21453 \u23466 \u27861 \u35268 \u23450 \u30340 \u22522 \u26412 \u21407 \u21017 \u65292 \u29053 \u21160 \u25239 \u25298 \u25110 \u32773 \u30772 \u22351 \u23466 \u27861 \u31561 \u27861 \u24459 \u27861 \u35268 \u23454 \u26045 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 2\u65289 \u21361 \u23475 \u22269 \u23478 \u23433 \u20840 \u65292 \u27844 \u38706 \u22269 \u23478 \u31192 \u23494 \u65292 \u39072 \u35206 \u22269 \u23478 \u25919 \u26435 \u65292 \u30772 \u22351 \u22269 \u23478 \u32479 \u19968 \u12289 \u20027 \u26435 \u21644 \u39046 \u22303 \u23436 \u25972 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 3\u65289 \u25439 \u23475 \u22269 \u23478 \u33635 \u35465 \u21644 \u21033 \u30410 \u12290 \u23459 \u25196 \u24656 \u24598 \u20027 \u20041 \u12289 \u26497 \u31471 \u20027 \u20041 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 4\u65289 \u35787 \u27585 \u27665 \u26063 \u20248 \u31168 \u25991 \u21270 \u20256 \u32479 \u65292 \u29053 \u21160 \u27665 \u26063 \u20167 \u24680 \u12289 \u27665 \u26063 \u27495 \u35270 \u65292 \u20405 \u23475 \u27665 \u26063 \u39118 \u20439 \u20064 \u24815 \u65292 \u27498 \u26354 \u27665 \u26063 \u21382 \u21490 \u21644 \u27665 \u26063 \u21382 \u21490 \u20154 \u29289 \u65292 \u20260 \u23475 \u27665 \u26063 \u24863 \u24773 \u65292 \u30772 \u22351 \u27665 \u26063 \u22242 \u32467 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 5\u65289 \u29053 \u21160 \u30772 \u22351 \u22269 \u23478 \u23447 \u25945 \u25919 \u31574 \u65292 \u23459 \u25196 \u23447 \u25945 \u29378 \u28909 \u65292 \u21361 \u23475 \u23447 \u25945 \u21644 \u30566 \u65292 \u20260 \u23475 \u20449 \u25945 \u20844 \u27665 \u23447 \u25945 \u24863 \u24773 \u65292 \u30772 \u22351 \u20449 \u25945 \u20844 \u27665 \u21644 \u19981 \u20449 \u25945 \u20844 \u27665 \u22242 \u32467 \u65292 \u23459 \u25196 \u37034 \u25945 \u21644 \u23553 \u24314 \u36855 \u20449 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 6\u65289 \u25955 \u24067 \u35875 \u35328 \u65292 \u21361 \u23475 \u31038 \u20250 \u20844 \u24503 \u65292 \u25200 \u20081 \u31038 \u20250 \u31209 \u24207 \u65292 \u30772 \u22351 \u31038 \u20250 \u31283 \u23450 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 7\u65289 \u25955 \u24067 \u28139 \u31229 \u12289 \u33394 \u24773 \u12289 \u36172 \u21338 \u12289 \u26292 \u21147 \u12289 \u24656 \u24598 \u65292 \u20256 \u25480 \u29359 \u32618 \u26041 \u27861 \u25110 \u32773 \u25945 \u21766 \u29359 \u32618 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 8\u65289 \u35837 \u35876 \u25110 \u32773 \u20398 \u36785 \u20182 \u20154 \u65292 \u20405 \u23475 \u20182 \u20154 \u21512 \u27861 \u26435 \u30410 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 9\u65289 \u29053 \u21160 \u38750 \u27861 \u38598 \u20250 \u12289 \u32467 \u31038 \u12289 \u28216 \u34892 \u12289 \u31034 \u23041 \u12289 \u32858 \u20247 \u25200 \u20081 \u31038 \u20250 \u31209 \u24207 \u65307 \
|
||||||
|
\uc0\u65288 10\u65289 \u20197 \u38750 \u27861 \u27665 \u38388 \u32452 \u32455 \u21517 \u20041 \u27963 \u21160 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 11\u65289 \u19981 \u31526 \u21512 \u12298 \u21363 \u26102 \u36890 \u35759 \u24037 \u20855 \u20844 \u20247 \u20449 \u24687 \u26381 \u21153 \u21457 \u23637 \u31649 \u29702 \u26242 \u34892 \u35268 \u23450 \u12299 \u21450 \u36981 \u23432 \u27861 \u24459 \u27861 \u35268 \u12289 \u31038 \u20250 \u20027 \u20041 \u21046 \u24230 \u12289 \u22269 \u23478 \u21033 \u30410 \u12289 \u20844 \u27665 \u21512 \u27861 \u21033 \u30410 \u12289 \u20844 \u20849 \u31209 \u24207 \u12289 \u31038 \u20250 \u36947 \u24503 \u39118 \u23578 \u21644 \u20449 \u24687 \u30495 \u23454 \u24615 \u31561 \'93\u19971 \u26465 \u24213 \u32447 \'94\u35201 \u27714 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 12\u65289 \u20405 \u23475 \u26410 \u25104 \u24180 \u20154 \u21512 \u27861 \u26435 \u30410 \u25110 \u32773 \u25439 \u23475 \u26410 \u25104 \u24180 \u20154 \u36523 \u24515 \u20581 \u24247 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 13\u65289 \u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u24213 \u32447 \u12289 \u31038 \u20250 \u20027 \u20041 \u21046 \u24230 \u24213 \u32447 \u12289 \u22269 \u23478 \u21033 \u30410 \u24213 \u32447 \u12289 \u20844 \u27665 \u21512 \u27861 \u26435 \u30410 \u24213 \u32447 \u12289 \u31038 \u20250 \u20844 \u20849 \u31209 \u24207 \u24213 \u32447 \u12289 \u36947 \u24503 \u39118 \u23578 \u24213 \u32447 \u21644 \u20449 \u24687 \u30495 \u23454 \u24615 \u24213 \u32447 \u30340 \'93\u19971 \u26465 \u24213 \u32447 \'94\u35201 \u27714 \u30340 \u65307 \
|
||||||
|
\uc0\u65288 14\u65289 \u21547 \u26377 \u27861 \u24459 \u12289 \u34892 \u25919 \u27861 \u35268 \u31105 \u27490 \u30340 \u20854 \u20182 \u20869 \u23481 \u30340 \u12290 \
|
||||||
|
\
|
||||||
|
6.1.2.2 \uc0\u21457 \u24067 \u12289 \u20256 \u36865 \u12289 \u20256 \u25773 \u12289 \u23384 \u20648 \u20405 \u29359 \u20182 \u20154 \u21517 \u35465 \u26435 \u12289 \u32918 \u20687 \u26435 \u12289 \u30693 \u35782 \u20135 \u26435 \u12289 \u21830 \u19994 \u31192 \u23494 \u31561 \u21512 \u27861 \u26435 \u21033 \u30340 \u20869 \u23481 \u65307 \
|
||||||
|
\
|
||||||
|
6.1.2.3 \uc0\u28041 \u21450 \u20182 \u20154 \u38544 \u31169 \u12289 \u20010 \u20154 \u20449 \u24687 \u25110 \u36164 \u26009 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.1.2.4 \uc0\u21457 \u34920 \u12289 \u20256 \u36865 \u12289 \u20256 \u25773 \u39578 \u25200 \u12289 \u24191 \u21578 \u20449 \u24687 \u12289 \u36807 \u24230 \u33829 \u38144 \u20449 \u24687 \u21450 \u22403 \u22334 \u20449 \u24687 \u25110 \u21547 \u26377 \u20219 \u20309 \u24615 \u25110 \u24615 \u26263 \u31034 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.1.2.5 \uc0\u20854 \u20182 \u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u12289 \u25919 \u31574 \u21450 \u20844 \u24207 \u33391 \u20439 \u12289 \u31038 \u20250 \u20844 \u24503 \u25110 \u24178 \u25200 \u31508 \u22696 \u35759 \u20351 \u27491 \u24120 \u36816 \u34892 \u21644 \u20405 \u29359 \u20854 \u20182 \u29992 \u25143 \u25110 \u31532 \u19977 \u26041 \u21512 \u27861 \u26435 \u30410 \u20869 \u23481 \u30340 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
6.1.2.6 \uc0\u24744 \u36890 \u36807 \u26412 \u26381 \u21153 \u21457 \u36865 \u25110 \u20256 \u25773 \u30340 \u20869 \u23481 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u32593 \u39029 \u12289 \u25991 \u23383 \u12289 \u22270 \u29255 \u12289 \u38899 \u39057 \u12289 \u35270 \u39057 \u12289 \u22270 \u34920 \u31561 \u65289 \u22343 \u30001 \u24744 \u33258 \u34892 \u25215 \u25285 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
6.1.2.6.1 \uc0\u24744 \u21457 \u36865 \u25110 \u20256 \u25773 \u30340 \u20869 \u23481 \u24212 \u26377 \u21512 \u27861 \u26469 \u28304 \u65292 \u30456 \u20851 \u20869 \u23481 \u20026 \u24744 \u25152 \u26377 \u25110 \u24744 \u24050 \u33719 \u24471 \u26435 \u21033 \u20154 \u30340 \u25480 \u26435 \u12290 \
|
||||||
|
\
|
||||||
|
6.1.2.6.2 \uc0\u24744 \u21516 \u24847 \u31508 \u22696 \u35759 \u20351 \u21487 \u20026 \u23653 \u34892 \u26412 \u21327 \u35758 \u25110 \u25552 \u20379 \u26412 \u26381 \u21153 \u30340 \u30446 \u30340 \u32780 \u20351 \u29992 \u24744 \u21457 \u36865 \u25110 \u20256 \u25773 \u30340 \u20869 \u23481 \u12290 \
|
||||||
|
\
|
||||||
|
6.1.2.6.3 \uc0\u22914 \u26524 \u31508 \u22696 \u35759 \u20351 \u25910 \u21040 \u26435 \u21033 \u20154 \u36890 \u30693 \u65292 \u20027 \u24352 \u24744 \u21457 \u36865 \u25110 \u20256 \u25773 \u30340 \u20869 \u23481 \u20405 \u29359 \u20854 \u30456 \u20851 \u26435 \u21033 \u30340 \u65292 \u24744 \u21516 \u24847 \u31508 \u22696 \u35759 \u20351 \u26377 \u26435 \u36827 \u34892 \u29420 \u31435 \u21028 \u26029 \u24182 \u37319 \u21462 \u21024 \u38500 \u12289 \u23631 \u34109 \u25110 \u26029 \u24320 \u38142 \u25509 \u31561 \u25514 \u26045 \u12290 \
|
||||||
|
\
|
||||||
|
6.1.2.7 \uc0\u24744 \u20351 \u29992 \u26412 \u26381 \u21153 \u26102 \u19981 \u24471 \u36829 \u21453 \u22269 \u23478 \u27861 \u24459 \u27861 \u35268 \u12289 \u20405 \u29359 \u20182 \u20154 \u21512 \u27861 \u26435 \u30410 \u12290 \
|
||||||
|
\uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u22914 \u26524 \u24744 \u34987 \u20182 \u20154 \u25237 \u35785 \u20405 \u26435 \u25110 \u24744 \u25237 \u35785 \u20182 \u20154 \u20405 \u26435 \u65292 \u31508 \u22696 \u35759 \u20351 \u26377 \u26435 \u23558 \u20105 \u35758 \u20013 \u30456 \u20851 \u26041 \u30340 \u20027 \u20307 \u12289 \u32852 \u31995 \u26041 \u24335 \u12289 \u25237 \u35785 \u30456 \u20851 \u20869 \u23481 \u31561 \u24517 \u35201 \u20449 \u24687 \u25552 \u20379 \u32473 \u20854 \u20182 \u20105 \u35758 \u26041 \u25110 \u30456 \u20851 \u37096 \u38376 \u65292 \u20197 \u20415 \u21450 \u26102 \u35299 \u20915 \u25237 \u35785 \u32416 \u32439 \u65292 \u20445 \u25252 \u20182 \u20154 \u21512 \u27861 \u26435 \u30410 \u12290 \
|
||||||
|
\
|
||||||
|
6.2 \uc0\u36719 \u20214 \u20351 \u29992 \u35268 \u33539 \
|
||||||
|
\
|
||||||
|
6.2.1 \uc0\u38500 \u38750 \u27861 \u24459 \u20801 \u35768 \u25110 \u25105 \u20204 \u20070 \u38754 \u35768 \u21487 \u65292 \u24744 \u20351 \u29992 \u26412 \u36719 \u20214 \u36807 \u31243 \u20013 \u19981 \u24471 \u20174 \u20107 \u19979 \u21015 \u34892 \u20026 \u65306 \
|
||||||
|
\
|
||||||
|
6.2.1.1 \uc0\u21024 \u38500 \u26412 \u36719 \u20214 \u21450 \u20854 \u21103 \u26412 \u19978 \u20851 \u20110 \u33879 \u20316 \u26435 \u30340 \u20449 \u24687 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.2 \uc0\u23545 \u26412 \u36719 \u20214 \u36827 \u34892 \u21453 \u21521 \u24037 \u31243 \u12289 \u21453 \u21521 \u27719 \u32534 \u12289 \u21453 \u21521 \u32534 \u35793 \u65292 \u25110 \u32773 \u20197 \u20854 \u20182 \u26041 \u24335 \u23581 \u35797 \u21457 \u29616 \u26412 \u36719 \u20214 \u30340 \u28304 \u20195 \u30721 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.3 \uc0\u23545 \u25105 \u20204 \u20139 \u26377 \u30693 \u35782 \u20135 \u26435 \u30340 \u20869 \u23481 \u36827 \u34892 \u20351 \u29992 \u12289 \u20986 \u31199 \u12289 \u20986 \u20511 \u12289 \u22797 \u21046 \u12289 \u20462 \u25913 \u12289 \u38142 \u25509 \u12289 \u36716 \u36733 \u12289 \u27719 \u32534 \u12289 \u21457 \u34920 \u12289 \u20986 \u29256 \u12289 \u24314 \u31435 \u38236 \u20687 \u31449 \u28857 \u31561 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.4 \uc0\u23545 \u26412 \u36719 \u20214 \u25110 \u32773 \u26412 \u36719 \u20214 \u36816 \u34892 \u36807 \u31243 \u20013 \u37322 \u25918 \u21040 \u20219 \u20309 \u32456 \u31471 \u20869 \u23384 \u20013 \u30340 \u25968 \u25454 \u12289 \u36719 \u20214 \u36816 \u34892 \u36807 \u31243 \u20013 \u23458 \u25143 \u31471 \u19982 \u26381 \u21153 \u22120 \u31471 \u30340 \u20132 \u20114 \u25968 \u25454 \u65292 \u20197 \u21450 \u26412 \u36719 \u20214 \u36816 \u34892 \u25152 \u24517 \u38656 \u30340 \u31995 \u32479 \u25968 \u25454 \u65292 \u36827 \u34892 \u22797 \u21046 \u12289 \u20462 \u25913 \u12289 \u22686 \u21152 \u12289 \u21024 \u38500 \u12289 \u25346 \u36733 \u36816 \u34892 \u25110 \u21019 \u24314 \u20219 \u20309 \u34893 \u29983 \u20316 \u21697 \u65292 \u24418 \u24335 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u20351 \u29992 \u25554 \u20214 \u12289 \u22806 \u25346 \u25110 \u38750 \u25105 \u20204 \u32463 \u25480 \u26435 \u30340 \u31532 \u19977 \u26041 \u24037 \u20855 /\u26381 \u21153 \u25509 \u20837 \u26412 \u36719 \u20214 \u21644 \u30456 \u20851 \u31995 \u32479 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.5 \uc0\u36890 \u36807 \u20462 \u25913 \u25110 \u20266 \u36896 \u36719 \u20214 \u36816 \u34892 \u20013 \u30340 \u25351 \u20196 \u12289 \u25968 \u25454 \u65292 \u22686 \u21152 \u12289 \u21024 \u38500 \u12289 \u25913 \u21464 \u36719 \u20214 \u30340 \u21151 \u33021 \u25110 \u36816 \u34892 \u25928 \u26524 \u65292 \u25110 \u32773 \u23558 \u29992 \u20110 \u19978 \u36848 \u30446 \u30340 \u30340 \u36719 \u20214 \u12289 \u26041 \u27861 \u36827 \u34892 \u36816 \u33829 \u25110 \u21521 \u20844 \u20247 \u20256 \u25773 \u65292 \u26080 \u35770 \u36825 \u20123 \u34892 \u20026 \u26159 \u21542 \u20026 \u21830 \u19994 \u30446 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.6 \uc0\u36890 \u36807 \u38750 \u25105 \u20204 \u24320 \u21457 \u12289 \u25480 \u26435 \u12289 \u35768 \u21487 \u30340 \u31532 \u19977 \u26041 \u36719 \u20214 \u12289 \u25554 \u20214 \u12289 \u22806 \u25346 \u12289 \u31995 \u32479 \u65292 \u30331 \u24405 \u25110 \u20351 \u29992 \u25105 \u20204 \u30340 \u36719 \u20214 \u21450 \u26381 \u21153 \u65292 \u25110 \u21046 \u20316 \u12289 \u21457 \u24067 \u12289 \u20256 \u25773 \u19978 \u36848 \u24037 \u20855 \u65292 \u25110 \u23545 \u26412 \u36719 \u20214 \u30340 \u27491 \u24120 \u36816 \u34892 \u36827 \u34892 \u24178 \u25200 \u12289 \u30772 \u22351 \u12289 \u20462 \u25913 \u25110 \u26045 \u21152 \u20854 \u20182 \u24433 \u21709 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.7 \uc0\u33258 \u34892 \u25110 \u32773 \u25480 \u26435 \u20182 \u20154 \u12289 \u31532 \u19977 \u26041 \u36719 \u20214 \u23545 \u26412 \u36719 \u20214 \u21450 \u20854 \u32452 \u20214 \u12289 \u27169 \u22359 \u12289 \u25968 \u25454 \u36827 \u34892 \u24178 \u25200 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.8 \uc0\u20197 \u20219 \u20309 \u26041 \u24335 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u30423 \u38142 \u12289 \u20887 \u20313 \u30423 \u21462 \u12289 \u38750 \u27861 \u25235 \u21462 \u12289 \u27169 \u25311 \u19979 \u36733 \u12289 \u28145 \u24230 \u38142 \u25509 \u12289 \u20551 \u20882 \u27880 \u20876 \u31561 \u65289 \u30452 \u25509 \u25110 \u38388 \u25509 \u30423 \u21462 \u26412 \u36719 \u20214 \u30340 \u35270 \u39057 \u12289 \u22270 \u25991 \u12289 \u29992 \u25143 \u20449 \u24687 \u31561 \u20449 \u24687 \u20869 \u23481 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.9 \uc0\u21033 \u29992 \u25110 \u38024 \u23545 \u26412 \u36719 \u20214 \u36827 \u34892 \u20219 \u20309 \u21361 \u23475 \u35745 \u31639 \u26426 \u32593 \u32476 \u23433 \u20840 \u30340 \u34892 \u20026 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \u38750 \u27861 \u20405 \u20837 \u32593 \u32476 \u12289 \u24178 \u25200 \u32593 \u32476 \u27491 \u24120 \u21151 \u33021 \u12289 \u31363 \u21462 \u32593 \u32476 \u25968 \u25454 \u31561 \u21361 \u23475 \u32593 \u32476 \u23433 \u20840 \u30340 \u27963 \u21160 \u65292 \u25110 \u20026 \u19978 \u36848 \u27963 \u21160 \u25552 \u20379 \u31243 \u24207 \u12289 \u24037 \u20855 \u31561 \u25903 \u25345 \u19982 \u24110 \u21161 \u65307 \u20225 \u22270 \u24178 \u28041 \u12289 \u30772 \u22351 \u26412 \u36719 \u20214 \u31995 \u32479 \u25110 \u32593 \u31449 \u30340 \u27491 \u24120 \u36816 \u34892 \u65292 \u25925 \u24847 \u20256 \u25773 \u24694 \u24847 \u31243 \u24207 \u25110 \u30149 \u27602 \u20197 \u21450 \u20854 \u20182 \u30772 \u22351 \u24178 \u25200 \u27491 \u24120 \u32593 \u32476 \u20449 \u24687 \u26381 \u21153 \u30340 \u34892 \u20026 \u31561 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.1.10 \uc0\u20854 \u20182 \u20197 \u20219 \u20309 \u19981 \u21512 \u27861 \u30340 \u26041 \u24335 \u12289 \u20026 \u20219 \u20309 \u19981 \u21512 \u27861 \u30340 \u30446 \u30340 \u12289 \u25110 \u19982 \u25105 \u20204 \u20026 \u27492 \u21046 \u23450 \u30340 \u20854 \u20182 \u35268 \u33539 \u21644 \u26631 \u20934 \u19981 \u19968 \u33268 \u30340 \u26041 \u24335 \u20351 \u29992 \u26412 \u36719 \u20214 \u21450 \u26410 \u32463 \u25105 \u20204 \u26126 \u30830 \u25480 \u26435 \u30340 \u34892 \u20026 \u12290 \
|
||||||
|
\
|
||||||
|
6.2.2 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u22522 \u20110 \u29992 \u25143 \u20307 \u39564 \u12289 \u31508 \u22696 \u35759 \u20351 \u25110 \u30456 \u20851 \u26381 \u21153 \u24179 \u21488 \u36816 \u33829 \u23433 \u20840 \u12289 \u24179 \u21488 \u35268 \u21017 \u35201 \u27714 \u21450 \u20581 \u24247 \u21457 \u23637 \u31561 \u32508 \u21512 \u22240 \u32032 \u65292 \u25105 \u20204 \u26377 \u26435 \u36873 \u25321 \u25552 \u20379 \u26381 \u21153 \u30340 \u23545 \u35937 \u65292 \u26377 \u26435 \u20915 \u23450 \u21151 \u33021 \u35774 \u32622 \u65292 \u26377 \u26435 \u20915 \u23450 \u21151 \u33021 \u24320 \u25918 \u12289 \u25968 \u25454 \u25509 \u21475 \u21644 \u30456 \u20851 \u25968 \u25454 \u25259 \u38706 \u30340 \u23545 \u35937 \u21644 \u33539 \u22260 \u12290 \u38024 \u23545 \u20197 \u19979 \u24773 \u24418 \u65292 \u26377 \u26435 \u35270 \u20855 \u20307 \u24773 \u20917 \u20013 \u27490 \u25110 \u32456 \u27490 \u25552 \u20379 \u26412 \u26381 \u21153 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \
|
||||||
|
\
|
||||||
|
6.2.2.1 \uc0\u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u25110 \u26412 \u21327 \u35758 \u35268 \u23450 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.2.2 \uc0\u24433 \u21709 \u26381 \u21153 \u20307 \u39564 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.2.3 \uc0\u23384 \u22312 \u23433 \u20840 \u38544 \u24739 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.2.4 \uc0\u19982 \u31508 \u22696 \u35759 \u20351 \u25110 \u20854 \u26381 \u21153 \u24179 \u21488 \u24050 \u26377 \u20027 \u35201 \u21151 \u33021 \u25110 \u21151 \u33021 \u32452 \u20214 \u30456 \u20284 \u12289 \u30456 \u21516 \u65292 \u25110 \u21487 \u23454 \u29616 \u19978 \u36848 \u21151 \u33021 \u25110 \u21151 \u33021 \u32452 \u20214 \u30340 \u20027 \u35201 \u25928 \u29992 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.2.5 \uc0\u30028 \u38754 \u12289 \u39118 \u26684 \u12289 \u21151 \u33021 \u12289 \u25551 \u36848 \u25110 \u20351 \u29992 \u32773 \u20307 \u39564 \u19982 \u31508 \u22696 \u35759 \u20351 \u25110 \u20854 \u26381 \u21153 \u24179 \u21488 \u30456 \u20284 \u65292 \u21487 \u33021 \u36896 \u25104 \u31508 \u22696 \u35759 \u20351 \u29992 \u25143 \u35748 \u20026 \u20854 \u25152 \u20351 \u29992 \u30340 \u21151 \u33021 \u25110 \u26381 \u21153 \u26469 \u28304 \u20110 \u25105 \u20204 \u25110 \u32463 \u25105 \u20204 \u25480 \u26435 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6.2.2.6 \uc0\u36829 \u21453 \u31508 \u22696 \u35759 \u20351 \u25110 \u20854 \u26381 \u21153 \u24179 \u21488 \u36816 \u33829 \u21407 \u21017 \u65292 \u25110 \u19981 \u31526 \u21512 \u25105 \u20204 \u20854 \u20182 \u31649 \u29702 \u35201 \u27714 \u30340 \u12290 \
|
||||||
|
\
|
||||||
|
6.3 \uc0\u26381 \u21153 \u36816 \u33829 \u35268 \u33539 \
|
||||||
|
\
|
||||||
|
6.3.1 \uc0\u38500 \u38750 \u24744 \u19982 \u31508 \u22696 \u35759 \u20351 \u21478 \u26377 \u32422 \u23450 \u65292 \u24744 \u21516 \u24847 \u26412 \u26381 \u21153 \u20165 \u20026 \u24744 \u20010 \u20154 \u38750 \u21830 \u19994 \u24615 \u36136 \u30340 \u20351 \u29992 \u12290 \
|
||||||
|
\
|
||||||
|
6.3.2 \uc0\u24744 \u24212 \u24403 \u36890 \u36807 \u31508 \u22696 \u35759 \u20351 \u25552 \u20379 \u25110 \u35748 \u21487 \u30340 \u26041 \u24335 \u20351 \u29992 \u26412 \u26381 \u21153 \u12290 \u24744 \u20381 \u26412 \u21327 \u35758 \u26465 \u27454 \u25152 \u33719 \u24471 \u30340 \u26435 \u21033 \u19981 \u21487 \u36716 \u35753 \u12290 \
|
||||||
|
\
|
||||||
|
6.3.3 \uc0\u24744 \u19981 \u24471 \u20351 \u29992 \u26410 \u32463 \u31508 \u22696 \u35759 \u20351 \u25480 \u26435 \u30340 \u25554 \u20214 \u12289 \u22806 \u25346 \u25110 \u31532 \u19977 \u26041 \u24037 \u20855 \u23545 \u26412 \u21327 \u35758 \u39033 \u19979 \u30340 \u26381 \u21153 \u36827 \u34892 \u24178 \u25200 \u12289 \u30772 \u22351 \u12289 \u20462 \u25913 \u25110 \u26045 \u21152 \u20854 \u20182 \u24433 \u21709 \u12290 \
|
||||||
|
\
|
||||||
|
6.3.4 \uc0\u38500 \u38750 \u27861 \u24459 \u20801 \u35768 \u25110 \u25105 \u20204 \u20070 \u38754 \u35768 \u21487 \u65292 \u24744 \u20351 \u29992 \u26412 \u26381 \u21153 \u36807 \u31243 \u20013 \u19981 \u24471 \u20174 \u20107 \u19979 \u21015 \u34892 \u20026 \u65306 \
|
||||||
|
\
|
||||||
|
1) \uc0\u25552 \u20132 \u12289 \u21457 \u24067 \u34394 \u20551 \u20449 \u24687 \u65292 \u25110 \u20882 \u20805 \u12289 \u21033 \u29992 \u20182 \u20154 \u21517 \u20041 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
2) \uc0\u35825 \u23548 \u20854 \u20182 \u29992 \u25143 \u28857 \u20987 \u38142 \u25509 \u39029 \u38754 \u25110 \u20998 \u20139 \u20449 \u24687 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
3) \uc0\u34394 \u26500 \u20107 \u23454 \u12289 \u38544 \u30610 \u30495 \u30456 \u20197 \u35823 \u23548 \u12289 \u27450 \u39575 \u20182 \u20154 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
4) \uc0\u20405 \u29359 \u20182 \u20154 \u21517 \u35465 \u26435 \u12289 \u32918 \u20687 \u26435 \u12289 \u30693 \u35782 \u20135 \u26435 \u12289 \u21830 \u19994 \u31192 \u23494 \u31561 \u21512 \u27861 \u26435 \u21033 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
5) \uc0\u26410 \u32463 \u25105 \u20204 \u20070 \u38754 \u35768 \u21487 \u21033 \u29992 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u21644 \u20219 \u20309 \u21151 \u33021 \u65292 \u20197 \u21450 \u31532 \u19977 \u26041 \u36816 \u33829 \u24179 \u21488 \u36827 \u34892 \u25512 \u24191 \u25110 \u30456 \u20114 \u25512 \u24191 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
6) \uc0\u21033 \u29992 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u25110 \u26412 \u36719 \u20214 \u21450 \u26381 \u21153 \u20174 \u20107 \u20219 \u20309 \u36829 \u27861 \u29359 \u32618 \u27963 \u21160 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
8) \uc0\u20854 \u20182 \u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u35268 \u23450 \u12289 \u20405 \u29359 \u20854 \u20182 \u29992 \u25143 \u21512 \u27861 \u26435 \u30410 \u12289 \u24178 \u25200 \u20135 \u21697 \u27491 \u24120 \u36816 \u33829 \u25110 \u25105 \u20204 \u26410 \u26126 \u30830 \u25480 \u26435 \u30340 \u34892 \u20026 \u12290 \
|
||||||
|
\
|
||||||
|
6.3.5 \uc0\u24744 \u22312 \u20351 \u29992 \u26412 \u26381 \u21153 \u36807 \u31243 \u20013 \u24212 \u24403 \u36981 \u23432 \u24403 \u22320 \u30456 \u20851 \u30340 \u27861 \u24459 \u27861 \u35268 \u65292 \u24182 \u23562 \u37325 \u24403 \u22320 \u30340 \u36947 \u24503 \u21644 \u39118 \u20439 \u20064 \u24815 \u12290 \u22914 \u26524 \u24744 \u30340 \u34892 \u20026 \u36829 \u21453 \u20102 \u24403 \u22320 \u27861 \u24459 \u27861 \u35268 \u25110 \u36947 \u24503 \u39118 \u20439 \u65292 \u24744 \u24212 \u24403 \u20026 \u27492 \u21333 \u29420 \u25215 \u25285 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
6.3.6 \uc0\u24744 \u24212 \u36991 \u20813 \u22240 \u20351 \u29992 \u26412 \u26381 \u21153 \u32780 \u20351 \u31508 \u22696 \u35759 \u20351 \u21367 \u20837 \u25919 \u27835 \u21644 \u20844 \u20849 \u20107 \u20214 \u65292 \u21542 \u21017 \u31508 \u22696 \u35759 \u20351 \u26377 \u26435 \u26242 \u20572 \u25110 \u32456 \u27490 \u23545 \u24744 \u30340 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
6.4 \uc0\u23545 \u33258 \u24049 \u34892 \u20026 \u36127 \u36131 \
|
||||||
|
\uc0\u24744 \u20805 \u20998 \u20102 \u35299 \u24182 \u21516 \u24847 \u65292 \u24744 \u24517 \u39035 \u20026 \u33258 \u24049 \u27880 \u20876 \u36134 \u21495 \u19979 \u30340 \u19968 \u20999 \u34892 \u20026 \u36127 \u36131 \u65292 \u21253 \u25324 \u24744 \u25152 \u21457 \u34920 \u30340 \u20219 \u20309 \u20869 \u23481 \u20197 \u21450 \u30001 \u27492 \u20135 \u29983 \u30340 \u20219 \u20309 \u21518 \u26524 \u12290 \u24744 \u24212 \u23545 \u26412 \u26381 \u21153 \u20013 \u30340 \u20869 \u23481 \u33258 \u34892 \u21152 \u20197 \u21028 \u26029 \u65292 \u24182 \u25215 \u25285 \u22240 \u20351 \u29992 \u20869 \u23481 \u32780 \u24341 \u36215 \u30340 \u25152 \u26377 \u39118 \u38505 \u65292 \u21253 \u25324 \u22240 \u23545 \u20869 \u23481 \u30340 \u27491 \u30830 \u24615 \u12289 \u23436 \u25972 \u24615 \u25110 \u23454 \u29992 \u24615 \u30340 \u20381 \u36182 \u32780 \u20135 \u29983 \u30340 \u39118 \u38505 \u12290 \u25105 \u20204 \u26080 \u27861 \u19988 \u19981 \u20250 \u23545 \u22240 \u21069 \u36848 \u39118 \u38505 \u32780 \u23548 \u33268 \u30340 \u20219 \u20309 \u25439 \u22833 \u25110 \u25439 \u23475 \u25215 \u25285 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
6.5 \uc0\u36829 \u32422 \u22788 \u29702 \
|
||||||
|
\
|
||||||
|
6.5.1 \uc0\u22914 \u26524 \u25105 \u20204 \u21457 \u29616 \u25110 \u25910 \u21040 \u20182 \u20154 \u20030 \u25253 \u25110 \u25237 \u35785 \u29992 \u25143 \u36829 \u21453 \u26412 \u21327 \u35758 \u32422 \u23450 \u30340 \u65292 \u25105 \u20204 \u26377 \u26435 \u19981 \u32463 \u36890 \u30693 \u38543 \u26102 \u23545 \u30456 \u20851 \u20869 \u23481 \u36827 \u34892 \u21024 \u38500 \u12289 \u23631 \u34109 \u65292 \u24182 \u35270 \u34892 \u20026 \u24773 \u33410 \u23545 \u36829 \u35268 \u36134 \u21495 \u22788 \u20197 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u35686 \u21578 \u12289 \u38480 \u21046 \u25110 \u31105 \u27490 \u20351 \u29992 \u37096 \u20998 \u25110 \u20840 \u37096 \u21151 \u33021 \u12289 \u36134 \u21495 \u23553 \u31105 \u30452 \u33267 \u27880 \u38144 \u30340 \u22788 \u32602 \u65292 \u24182 \u20844 \u21578 \u22788 \u29702 \u32467 \u26524 \u12290 \
|
||||||
|
\
|
||||||
|
6.5.2 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u25105 \u20204 \u26377 \u26435 \u20381 \u25454 \u21512 \u29702 \u21028 \u26029 \u23545 \u36829 \u21453 \u26377 \u20851 \u27861 \u24459 \u27861 \u35268 \u25110 \u26412 \u21327 \u35758 \u35268 \u23450 \u30340 \u34892 \u20026 \u36827 \u34892 \u22788 \u32602 \u65292 \u23545 \u36829 \u27861 \u36829 \u35268 \u30340 \u20219 \u20309 \u29992 \u25143 \u37319 \u21462 \u36866 \u24403 \u30340 \u27861 \u24459 \u34892 \u21160 \u65292 \u24182 \u20381 \u25454 \u27861 \u24459 \u27861 \u35268 \u20445 \u23384 \u26377 \u20851 \u20449 \u24687 \u21521 \u26377 \u20851 \u37096 \u38376 \u25253 \u21578 \u31561 \u65292 \u29992 \u25143 \u24212 \u21333 \u29420 \u25215 \u25285 \u30001 \u27492 \u32780 \u20135 \u29983 \u30340 \u19968 \u20999 \u27861 \u24459 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
6.5.3 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u22240 \u24744 \u36829 \u21453 \u26412 \u21327 \u35758 \u25110 \u30456 \u20851 \u26381 \u21153 \u26465 \u27454 \u30340 \u35268 \u23450 \u65292 \u23548 \u33268 \u25110 \u20135 \u29983 \u31532 \u19977 \u26041 \u20027 \u24352 \u30340 \u20219 \u20309 \u32034 \u36180 \u12289 \u35201 \u27714 \u25110 \u25439 \u22833 \u65292 \u24744 \u24212 \u24403 \u29420 \u31435 \u25215 \u25285 \u36131 \u20219 \u65307 \u25105 \u20204 \u22240 \u27492 \u36973 \u21463 \u25439 \u22833 \u30340 \u65292 \u24744 \u20063 \u24212 \u24403 \u19968 \u24182 \u36180 \u20607 \u12290 \
|
||||||
|
\
|
||||||
|
6.5.4\uc0\u22914 \u24744 \u36829 \u21453 \u26412 \u21327 \u35758 \u32422 \u23450 \u65292 \u25105 \u20204 \u26377 \u26435 \u20316 \u20986 \u29420 \u31435 \u21028 \u26029 \u65292 \u31435 \u21363 \u26242 \u20572 \u25110 \u32456 \u27490 \u21521 \u24744 \u25552 \u20379 \u37096 \u20998 \u25110 \u20840 \u37096 \u26412 \u36719 \u20214 \u26381 \u21153 \u65292 \u21253 \u25324 \u31105 \u35328 \u12289 \u23631 \u34109 \u20449 \u24687 \u12289 \u21024 \u38500 \u21457 \u24067 \u20869 \u23481 \u12289 \u23553 \u31105 \u36134 \u21495 \u12289 \u27880 \u38144 \u36134 \u21495 \u31561 \u25514 \u26045 \u12290 \u24744 \u24212 \u33258 \u34892 \u25215 \u25285 \u33258 \u36523 \u25439 \u22833 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u34394 \u25311 \u36130 \u20135 \u28165 \u31354 \u12289 \u26080 \u27861 \u27491 \u24120 \u20351 \u29992 \u36134 \u21495 \u21450 \u30456 \u20851 \u26412 \u36719 \u20214 \u26381 \u21153 \u12289 \u26080 \u27861 \u27491 \u24120 \u33719 \u21462 \u24744 \u36134 \u21495 \u20869 \u36164 \u20135 \u25110 \u20854 \u20182 \u26435 \u30410 \u31561 \u65289 \u65292 \u20197 \u21450 \u30456 \u24212 \u27861 \u24459 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
6.5.5\uc0\u24744 \u25215 \u25285 \u27861 \u24459 \u36131 \u20219 \u30340 \u24418 \u24335 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \u23545 \u21463 \u21040 \u20405 \u23475 \u32773 \u36180 \u20607 \u25439 \u22833 \u12289 \u36180 \u31036 \u36947 \u27465 \u12289 \u28040 \u38500 \u24433 \u21709 \u12289 \u36820 \u36824 \u36130 \u20135 \u31561 \u12290 \u22914 \u24744 \u30340 \u34892 \u20026 \u32473 \u25105 \u20204 \u36896 \u25104 \u25439 \u22833 \u30340 \u65292 \u24744 \u24212 \u25215 \u25285 \u20840 \u37096 \u36180 \u20607 \u36131 \u20219 \u65292 \u21253 \u25324 \u34892 \u25919 \u22788 \u32602 \u25110 \u25439 \u23475 \u36180 \u20607 \u27454 \u31561 \u30452 \u25509 \u25439 \u22833 \u20197 \u21450 \u21830 \u35465 \u25439 \u22833 \u12289 \u21644 \u35299 \u27454 \u12289 \u24459 \u24072 \u36153 \u12289 \u35785 \u35772 \u36153 \u31561 \u38388 \u25509 \u25439 \u22833 \u12290 \
|
||||||
|
\
|
||||||
|
6.5.6\uc0\u24744 \u20805 \u20998 \u20102 \u35299 \u65292 \u20219 \u20309 \u21521 \u25105 \u20844 \u21496 \u30340 \u38599 \u21592 \u25110 \u39038 \u38382 \u31561 \u25552 \u20379 \u23454 \u29289 \u12289 \u29616 \u37329 \u12289 \u29616 \u37329 \u31561 \u20215 \u29289 \u12289 \u21171 \u21153 \u12289 \u26053 \u28216 \u31561 \u20215 \u20540 \u26126 \u26174 \u36229 \u20986 \u27491 \u24120 \u21830 \u21153 \u27965 \u35848 \u33539 \u30068 \u30340 \u21033 \u30410 \u65292 \u22343 \u35270 \u20026 \u21830 \u19994 \u36159 \u36162 \u34892 \u20026 \u12290 \u21457 \u29983 \u21069 \u36848 \u24773 \u24418 \u30340 \u65292 \u25105 \u20844 \u21496 \u21487 \u31435 \u21363 \u32456 \u27490 \u19982 \u24744 \u30340 \u25152 \u26377 \u21512 \u20316 \u24182 \u36861 \u31350 \u24744 \u30340 \u27861 \u24459 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
6.5.7\uc0\u24744 \u22240 \u36829 \u32422 \u23548 \u33268 \u25105 \u20204 \u32456 \u27490 \u26412 \u21327 \u35758 \u26102 \u65292 \u20986 \u20110 \u32500 \u25252 \u36719 \u20214 \u31209 \u24207 \u30340 \u30446 \u30340 \u65292 \u25105 \u20204 \u21487 \u26681 \u25454 \u19982 \u24744 \u22312 \u20854 \u20182 \u21327 \u35758 \u39033 \u19979 \u36798 \u25104 \u30340 \u32422 \u23450 \u32456 \u27490 \u19982 \u24744 \u22312 \u20854 \u20182 \u21327 \u35758 \u39033 \u19979 \u30340 \u21512 \u20316 \u12290 \u22914 \u24744 \u36829 \u21453 \u25105 \u20204 \u19982 \u24744 \u22312 \u20854 \u20182 \u21512 \u20316 \u39033 \u19979 \u35746 \u31435 \u30340 \u21327 \u35758 \u65292 \u25105 \u20204 \u20134 \u26377 \u26435 \u32456 \u27490 \u26412 \u21327 \u35758 \u12290 \u38500 \u21069 \u36848 \u21327 \u35758 \u32456 \u27490 \u22806 \u65292 \u25105 \u20204 \u20134 \u21487 \u20851 \u32852 \u36861 \u31350 \u24744 \u30340 \u36829 \u32422 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
6.5.8\uc0\u25105 \u20204 \u21487 \u23558 \u23545 \u24744 \u19978 \u36848 \u36829 \u32422 \u34892 \u20026 \u30340 \u22788 \u32622 \u20449 \u24687 \u65292 \u20197 \u21450 \u20854 \u20182 \u32463 \u22269 \u23478 \u34892 \u25919 \u25110 \u21496 \u27861 \u26426 \u20851 \u29983 \u25928 \u27861 \u24459 \u25991 \u20070 \u30830 \u35748 \u30340 \u36829 \u27861 \u20449 \u24687 \u65292 \u22312 \u26412 \u36719 \u20214 \u19978 \u20104 \u20197 \u20844 \u31034 \u12290 \u23545 \u28041 \u23244 \u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u30340 \u34892 \u20026 \u65292 \u25105 \u20204 \u26377 \u20041 \u21153 \u20445 \u23384 \u26377 \u20851 \u35760 \u24405 \u65292 \u21521 \u22269 \u23478 \u26377 \u20851 \u26426 \u20851 \u25253 \u21578 \u24182 \u37197 \u21512 \u35843 \u26597 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u19971 \u12289 \u30693 \u35782 \u20135 \u26435 \u22768 \u26126 \
|
||||||
|
\
|
||||||
|
7.1 \uc0\u31508 \u22696 \u35759 \u20351 \u22312 \u26412 \u26381 \u21153 \u20013 \u25552 \u20379 \u30340 \u20869 \u23481 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u32593 \u39029 \u12289 \u25991 \u23383 \u12289 \u22270 \u29255 \u12289 \u38899 \u39057 \u12289 \u35270 \u39057 \u12289 \u22270 \u34920 \u12289 \u25991 \u23383 \u34920 \u36848 \u21450 \u20854 \u32452 \u21512 \u12289 \u30028 \u38754 \u35774 \u35745 \u12289 \u29256 \u38754 \u26694 \u26550 \u12289 \u22270 \u26631 \u12289 \u21830 \u26631 \u31561 \u65289 \u30340 \u30693 \u35782 \u20135 \u26435 \u24402 \u31508 \u22696 \u35759 \u20351 \u25152 \u26377 \u65292 \u21463 \u20013 \u21326 \u20154 \u27665 \u20849 \u21644 \u22269 \u33879 \u20316 \u26435 \u27861 \u12289 \u21830 \u26631 \u27861 \u12289 \u19987 \u21033 \u27861 \u12289 \u21453 \u19981 \u27491 \u24403 \u31454 \u20105 \u27861 \u21450 \u22269 \u38469 \u26465 \u32422 \u31561 \u27861 \u24459 \u27861 \u35268 \u30340 \u20445 \u25252 \u12290 \u26410 \u32463 \u25105 \u20204 \u20070 \u38754 \u20801 \u35768 \u65292 \u29992 \u25143 \u19981 \u24471 \u20026 \u20219 \u20309 \u30446 \u30340 \u25797 \u33258 \u20351 \u29992 \u12289 \u22797 \u21046 \u12289 \u20877 \u36896 \u36825 \u20123 \u20869 \u23481 \u12289 \u25110 \u21019 \u36896 \u19982 \u20869 \u23481 \u26377 \u20851 \u30340 \u27966 \u29983 \u20135 \u21697 \u12290 \u29992 \u25143 \u22312 \u20351 \u29992 \u26412 \u26381 \u21153 \u20013 \u25152 \u20135 \u29983 \u30340 \u20869 \u23481 \u30340 \u30693 \u35782 \u20135 \u26435 \u24402 \u29992 \u25143 \u25110 \u30456 \u20851 \u26435 \u21033 \u20154 \u25152 \u26377 \u12290 \
|
||||||
|
\
|
||||||
|
7.2 \uc0\u38500 \u21478 \u26377 \u29305 \u21035 \u22768 \u26126 \u22806 \u65292 \u31508 \u22696 \u35759 \u20351 \u25552 \u20379 \u26412 \u26381 \u21153 \u26102 \u25152 \u20381 \u25454 \u36719 \u20214 \u30340 \u33879 \u20316 \u26435 \u12289 \u19987 \u21033 \u26435 \u21450 \u20854 \u20182 \u30693 \u35782 \u20135 \u26435 \u22343 \u24402 \u31508 \u22696 \u35759 \u20351 \u25152 \u26377 \u12290 \
|
||||||
|
\
|
||||||
|
7.3 \uc0\u31508 \u22696 \u35759 \u20351 \u22312 \u26412 \u26381 \u21153 \u20013 \u25152 \u20351 \u29992 \u30340 \'93\u31508 \u22696 \u35759 \u20351 \'94\u31561 \u24418 \u35937 \u31561 \u21830 \u19994 \u26631 \u35782 \u65292 \u20854 \u33879 \u20316 \u26435 \u25110 \u21830 \u26631 \u26435 \u24402 \u31508 \u22696 \u35759 \u20351 \u25152 \u26377 \u12290 \
|
||||||
|
\
|
||||||
|
7.4 \uc0\u19978 \u36848 \u21450 \u20854 \u20182 \u20219 \u20309 \u26412 \u26381 \u21153 \u21253 \u21547 \u30340 \u20869 \u23481 \u30340 \u30693 \u35782 \u20135 \u26435 \u22343 \u21463 \u21040 \u27861 \u24459 \u20445 \u25252 \u65292 \u26410 \u32463 \u31508 \u22696 \u35759 \u20351 \u12289 \u29992 \u25143 \u25110 \u30456 \u20851 \u26435 \u21033 \u20154 \u20070 \u38754 \u35768 \u21487 \u65292 \u20219 \u20309 \u20154 \u19981 \u24471 \u20197 \u20219 \u20309 \u24418 \u24335 \u36827 \u34892 \u20351 \u29992 \u25110 \u21019 \u20316 \u30456 \u20851 \u34893 \u29983 \u20316 \u21697 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20843 \u12289 \u32456 \u31471 \u23433 \u20840 \u36131 \u20219 \
|
||||||
|
\
|
||||||
|
8.1 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u26412 \u36719 \u20214 \u21516 \u22823 \u22810 \u25968 \u20114 \u32852 \u32593 \u36719 \u20214 \u19968 \u26679 \u65292 \u21487 \u33021 \u20250 \u21463 \u22810 \u31181 \u22240 \u32032 \u24433 \u21709 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u29992 \u25143 \u21407 \u22240 \u12289 \u32593 \u32476 \u26381 \u21153 \u36136 \u37327 \u12289 \u31038 \u20250 \u29615 \u22659 \u31561 \u65307 \u20063 \u21487 \u33021 \u20250 \u21463 \u21508 \u31181 \u23433 \u20840 \u38382 \u39064 \u30340 \u20405 \u25200 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u20182 \u20154 \u38750 \u27861 \u21033 \u29992 \u29992 \u25143 \u36164 \u26009 \u65292 \u36827 \u34892 \u29616 \u23454 \u20013 \u30340 \u39578 \u25200 \u65307 \u29992 \u25143 \u19979 \u36733 \u23433 \u35013 \u30340 \u20854 \u20182 \u36719 \u20214 \u25110 \u35775 \u38382 \u30340 \u20854 \u20182 \u32593 \u31449 \u20013 \u21487 \u33021 \u21547 \u26377 \u30149 \u27602 \u12289 \u26408 \u39532 \u31243 \u24207 \u25110 \u20854 \u20182 \u24694 \u24847 \u31243 \u24207 \u65292 \u23041 \u32961 \u24744 \u30340 \u32456 \u31471 \u35774 \u22791 \u20449 \u24687 \u21644 \u25968 \u25454 \u23433 \u20840 \u65292 \u32487 \u32780 \u24433 \u21709 \u26412 \u36719 \u20214 \u30340 \u27491 \u24120 \u20351 \u29992 \u31561 \u12290 \u22240 \u27492 \u65292 \u24744 \u24212 \u21152 \u24378 \u20449 \u24687 \u23433 \u20840 \u21450 \u20010 \u20154 \u20449 \u24687 \u30340 \u20445 \u25252 \u24847 \u35782 \u65292 \u27880 \u24847 \u23494 \u30721 \u20445 \u25252 \u65292 \u20197 \u20813 \u36973 \u21463 \u25439 \u22833 \u12290 \
|
||||||
|
\
|
||||||
|
8.2 \uc0\u24744 \u19981 \u24471 \u21046 \u20316 \u12289 \u21457 \u24067 \u12289 \u20351 \u29992 \u12289 \u20256 \u25773 \u29992 \u20110 \u31363 \u21462 \u31508 \u22696 \u35759 \u20351 \u36134 \u21495 \u21450 \u20182 \u20154 \u20010 \u20154 \u20449 \u24687 \u12289 \u36130 \u20135 \u30340 \u24694 \u24847 \u31243 \u24207 \u12290 \
|
||||||
|
\
|
||||||
|
8.3 \uc0\u32500 \u25252 \u36719 \u20214 \u23433 \u20840 \u19982 \u27491 \u24120 \u20351 \u29992 \u26159 \u25105 \u20204 \u21644 \u24744 \u30340 \u20849 \u21516 \u36131 \u20219 \u65292 \u25105 \u20204 \u23558 \u25353 \u29031 \u34892 \u19994 \u26631 \u20934 \u21512 \u29702 \u23457 \u24910 \u22320 \u37319 \u21462 \u24517 \u35201 \u25216 \u26415 \u25514 \u26045 \u20445 \u25252 \u24744 \u30340 \u32456 \u31471 \u35774 \u22791 \u20449 \u24687 \u21644 \u25968 \u25454 \u23433 \u20840 \u65292 \u20294 \u26159 \u24744 \u25215 \u35748 \u21644 \u21516 \u24847 \u25105 \u20204 \u24182 \u19981 \u33021 \u23601 \u27492 \u25552 \u20379 \u23436 \u20840 \u20445 \u35777 \u12290 \
|
||||||
|
\
|
||||||
|
8.4 \uc0\u22312 \u20219 \u20309 \u24773 \u20917 \u19979 \u65292 \u24744 \u19981 \u24212 \u36731 \u20449 \u20511 \u27454 \u12289 \u32034 \u35201 \u23494 \u30721 \u25110 \u20854 \u20182 \u28041 \u21450 \u36130 \u20135 \u30340 \u32593 \u32476 \u20449 \u24687 \u12290 \u28041 \u21450 \u36130 \u20135 \u25805 \u20316 \u30340 \u65292 \u35831 \u19968 \u23450 \u20808 \u26680 \u23454 \u23545 \u26041 \u36523 \u20221 \u65292 \u24182 \u35831 \u32463 \u24120 \u30041 \u24847 \u25105 \u20204 \u26377 \u20851 \u38450 \u33539 \u35784 \u39575 \u29359 \u32618 \u30340 \u25552 \u31034 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20061 \u12289 \u31532 \u19977 \u26041 \u36719 \u20214 \u25110 \u25216 \u26415 \
|
||||||
|
\
|
||||||
|
9.1 \uc0\u26412 \u36719 \u20214 \u21487 \u33021 \u20250 \u20351 \u29992 \u31532 \u19977 \u26041 \u36719 \u20214 \u25110 \u25216 \u26415 \u65288 \u21253 \u25324 \u26412 \u36719 \u20214 \u21487 \u33021 \u20351 \u29992 \u30340 \u24320 \u25918 \u28304 \u20195 \u30721 \u21644 \u20844 \u20849 \u39046 \u22495 \u20195 \u30721 \u31561 \u65292 \u19979 \u21516 \u65289 \u65292 \u36825 \u31181 \u20351 \u29992 \u24050 \u32463 \u33719 \u24471 \u21512 \u27861 \u25480 \u26435 \u12290 \
|
||||||
|
\
|
||||||
|
9.2 \uc0\u26412 \u36719 \u20214 \u22914 \u26524 \u20351 \u29992 \u20102 \u31532 \u19977 \u26041 \u30340 \u36719 \u20214 \u25110 \u25216 \u26415 \u65292 \u25105 \u20204 \u23558 \u25353 \u29031 \u30456 \u20851 \u27861 \u35268 \u25110 \u32422 \u23450 \u65292 \u23545 \u30456 \u20851 \u30340 \u21327 \u35758 \u25110 \u20854 \u20182 \u25991 \u20214 \u65292 \u21487 \u33021 \u36890 \u36807 \u26412 \u21327 \u35758 \u38468 \u20214 \u12289 \u22312 \u26412 \u36719 \u20214 \u23433 \u35013 \u21253 \u29305 \u23450 \u25991 \u20214 \u22841 \u20013 \u25171 \u21253 \u12289 \u25110 \u36890 \u36807 \u24320 \u28304 \u36719 \u20214 \u39029 \u38754 \u31561 \u24418 \u24335 \u36827 \u34892 \u23637 \u31034 \u65292 \u23427 \u20204 \u21487 \u33021 \u20250 \u20197 \'93\u36719 \u20214 \u20351 \u29992 \u35768 \u21487 \u21327 \u35758 \'94\u12289 \'93\u25480 \u26435 \u21327 \u35758 \'94\u12289 \'93\u24320 \u25918 \u28304 \u20195 \u30721 \u35768 \u21487 \u35777 \'94\u25110 \u20854 \u20182 \u24418 \u24335 \u26469 \u34920 \u36798 \u12290 \u21069 \u36848 \u36890 \u36807 \u21508 \u31181 \u24418 \u24335 \u23637 \u31034 \u30340 \u30456 \u20851 \u21327 \u35758 \u12289 \u20854 \u20182 \u25991 \u20214 \u21450 \u32593 \u39029 \u65292 \u22343 \u26159 \u26412 \u21327 \u35758 \u19981 \u21487 \u20998 \u21106 \u30340 \u32452 \u25104 \u37096 \u20998 \u65292 \u19982 \u26412 \u21327 \u35758 \u20855 \u26377 \u21516 \u31561 \u30340 \u27861 \u24459 \u25928 \u21147 \u65292 \u24744 \u24212 \u24403 \u36981 \u23432 \u36825 \u20123 \u35201 \u27714 \u12290 \u22914 \u26524 \u24744 \u27809 \u26377 \u36981 \u23432 \u36825 \u20123 \u35201 \u27714 \u65292 \u35813 \u31532 \u19977 \u26041 \u25110 \u32773 \u22269 \u23478 \u26426 \u20851 \u21487 \u33021 \u20250 \u23545 \u24744 \u25552 \u36215 \u35785 \u35772 \u12289 \u32602 \u27454 \u25110 \u37319 \u21462 \u20854 \u20182 \u21046 \u35009 \u25514 \u26045 \u65292 \u24182 \u35201 \u27714 \u25105 \u20204 \u32473 \u20104 \u37197 \u21512 \u65292 \u24744 \u24212 \u24403 \u33258 \u34892 \u25215 \u25285 \u27861 \u24459 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
9.3 \uc0\u22914 \u22240 \u26412 \u36719 \u20214 \u20351 \u29992 \u30340 \u31532 \u19977 \u26041 \u36719 \u20214 \u25110 \u25216 \u26415 \u24341 \u21457 \u30340 \u20219 \u20309 \u32416 \u32439 \u65292 \u24212 \u30001 \u35813 \u31532 \u19977 \u26041 \u36127 \u36131 \u35299 \u20915 \u65292 \u25105 \u20204 \u19981 \u25215 \u25285 \u20219 \u20309 \u36131 \u20219 \u12290 \u25105 \u20204 \u19981 \u23545 \u31532 \u19977 \u26041 \u36719 \u20214 \u25110 \u25216 \u26415 \u25552 \u20379 \u23458 \u26381 \u25903 \u25345 \u65292 \u33509 \u24744 \u38656 \u35201 \u33719 \u21462 \u25903 \u25345 \u65292 \u35831 \u19982 \u31532 \u19977 \u26041 \u32852 \u31995 \u12290 \
|
||||||
|
\
|
||||||
|
APP\uc0\u28041 \u21450 \u20869 \u23884 \u31532 \u19977 \u26041 \u20195 \u30721 \u12289 \u25554 \u20214 \u20256 \u36755 \u20010 \u20154 \u20449 \u24687 \u30340 \u24773 \u24418 \u36880 \u39033 \u21015 \u20030 \u22914 \u19979 \u65306 \
|
||||||
|
\
|
||||||
|
**Bugly SDK**\
|
||||||
|
\uc0\u20027 \u20307 \u65306 \u28145 \u22323 \u24066 \u33150 \u35759 \u35745 \u31639 \u26426 \u31995 \u32479 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\uc0\u29992 \u36884 \u65306 \u24212 \u29992 \u23849 \u28291 \u38382 \u39064 \u25429 \u33719 \
|
||||||
|
\uc0\u25910 \u38598 \u30340 \u20010 \u20154 \u20449 \u24687 \u31867 \u22411 \u65306 \u30828 \u20214 \u22411 \u21495 \u12289 \u35774 \u22791 MAC\u22320 \u22336 \u12289 \u21807 \u19968 \u35774 \u22791 \u35782 \u21035 \u30721 \u65288 \u22914 IMEI/MEID/ ANDROID ID /SN/OPENUDID/GUID\u12289 SIM\u21345 IMSI\u20449 \u24687 \u22312 \u20869 \u30340 \u25551 \u36848 \u20010 \u20154 \u24120 \u29992 \u35774 \u22791 \u22522 \u26412 \u24773 \u20917 \u30340 \u20449 \u24687 \u65289 \u12289 \u35774 \u22791 \u22411 \u21495 \u12289 \u35774 \u22791 \u21046 \u36896 \u21830 \u12289 \u25805 \u20316 \u31995 \u32479 \u21450 \u20854 \u29256 \u26412 \u65307 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 \
|
||||||
|
https://privacy.qq.com/document/preview/fc748b3d96224fdb825ea79e132c1a56\
|
||||||
|
\
|
||||||
|
**OPPO PUSH SDK**\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u26631 \u35782 \u31526 \u65288 \u22914 IMEI\u12289 OAID\u12289 \u30828 \u20214 \u24207 \u21015 \u21495 /Serial\u12289 IMSI\u12289 Android ID\u12289 GAID/AAID\u65289 \u12289 \u24212 \u29992 \u20449 \u24687 \u12289 \u32593 \u32476 \u20449 \u24687 \u12289 IP\u22320 \u22336 \u12289 \u35774 \u22791 \u20449 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 OPPO\u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u24191 \u19996 \u27431 \u29632 \u31227 \u21160 \u36890 \u20449 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://open.oppomobile.com/wiki/doc#id=10194\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://open.oppomobile.com/wiki/doc#id=10288\
|
||||||
|
\
|
||||||
|
**VIVO PUSH SDK**\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u20449 \u24687 \u12289 IMEI\u12289 OAID\u12289 GAID/AAID\u12289 Android ID\u12289 \u32593 \u32476 \u20449 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 VIVO\u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u32500 \u27779 \u31227 \u21160 \u36890 \u20449 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://dev.vivo.com.cn/documentCenter/doc/366\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://dev.vivo.com.cn/documentCenter/doc/652\
|
||||||
|
\
|
||||||
|
**\uc0\u21326 \u20026 PUSH SDK**\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u24212 \u29992 \u22522 \u26412 \u20449 \u24687 \u12289 \u24212 \u29992 \u20869 \u35774 \u22791 \u26631 \u35782 \u31526 \u12289 \u35774 \u22791 \u30340 \u30828 \u20214 \u20449 \u24687 \u12289 \u36719 \u20214 \u21015 \u34920 \u12289 \u31995 \u32479 \u22522 \u26412 \u20449 \u24687 \u21644 \u31995 \u32479 \u35774 \u32622 \u20449 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u21326 \u20026 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u21326 \u20026 \u36719 \u20214 \u25216 \u26415 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://developer.huawei.com/consumer/cn/doc/app/20213\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177\
|
||||||
|
\
|
||||||
|
**hmscore-base-sdk**\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u24212 \u29992 \u22522 \u26412 \u20449 \u24687 \u12289 \u24212 \u29992 \u20869 \u35774 \u22791 \u26631 \u35782 \u31526 \u12289 \u35774 \u22791 \u30340 \u30828 \u20214 \u20449 \u24687 \u12289 \u36719 \u20214 \u21015 \u34920 \u12289 \u31995 \u32479 \u22522 \u26412 \u20449 \u24687 \u21644 \u31995 \u32479 \u35774 \u32622 \u20449 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u21326 \u20026 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u21326 \u20026 \u36719 \u20214 \u25216 \u26415 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://developer.huawei.com/consumer/cn/doc/app/20213\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177\
|
||||||
|
\
|
||||||
|
**\uc0\u23567 \u31859 PUSH SDK**\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u26631 \u35782 \u31526 \u65288 \u22914 Android ID\u12289 OAID\u65289 \u12289 \u24212 \u29992 \u20449 \u24687 \u12289 \u35774 \u22791 \u20449 \u24687 \u12289 \u32593 \u32476 \u20449 \u24687 \u65288 \u26412 \u22320 \u22788 \u29702 \u65289 \u12289 SSID\
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u23567 \u31859 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u21271 \u20140 \u23567 \u31859 \u31227 \u21160 \u36719 \u20214 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://dev.mi.com/console/appservice/push.html\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://dev.mi.com/console/doc/detail?pId=1822\
|
||||||
|
\
|
||||||
|
**\uc0\u39749 \u26063 PUSH SDK**\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u26631 \u35782 \u31526 \u65288 \u22914 IMEI\u12289 MEID\u12289 \u30828 \u20214 \u24207 \u21015 \u21495 /Serial\u65289 \u12289 \u35774 \u22791 MAC\u22320 \u22336 \u12289 \u20301 \u32622 \u20449 \u24687 \u65288 \u22914 GPS\u65289 \u12289 WLAN\u25509 \u20837 \u28857 \u65288 \u22914 SSID\u12289 BSSID\u65289 \u12289 \u35774 \u22791 \u20449 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u39749 \u26063 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u29664 \u28023 \u24066 \u39749 \u26063 \u36890 \u35759 \u35774 \u22791 \u26377 \u38480 \u20844 \u21496 \u21450 \u20854 \u20851 \u32852 \u26041 \u65288 \u31616 \u31216 \u39749 \u26063 \u65289 \u12289 \u19982 \u39749 \u26063 \u24314 \u31435 \u21512 \u20316 \u30340 \u21512 \u20316 \u26041 \u20844 \u21496 \
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://open.flyme.cn/\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://open.flyme.cn/docs?id=202\
|
||||||
|
\
|
||||||
|
**\uc0\u39640 \u24503 PUSH SDK**\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u26631 \u35782 \u31526 (GAID/AAID)\u65292 \u24212 \u29992 Token\u12289 \u25512 \u36865 \u28040 \u24687 \u20869 \u23481 \
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u39640 \u24503 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u39640 \u24503 \u32456 \u31471 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://lbs.amap.com/\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://lbs.amap.com/pages/privacy/\
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u12289 \u19981 \u21487 \u25239 \u21147 \u21450 \u20854 \u20182 \u20813 \u36131 \u20107 \u30001 \
|
||||||
|
\
|
||||||
|
10.1 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u22312 \u20351 \u29992 \u26412 \u26381 \u21153 \u30340 \u36807 \u31243 \u20013 \u65292 \u21487 \u33021 \u20250 \u36935 \u21040 \u19981 \u21487 \u25239 \u21147 \u31561 \u39118 \u38505 \u22240 \u32032 \u65292 \u20351 \u26412 \u26381 \u21153 \u21457 \u29983 \u20013 \u26029 \u12290 \u19981 \u21487 \u25239 \u21147 \u26159 \u25351 \u19981 \u33021 \u39044 \u35265 \u12289 \u19981 \u33021 \u20811 \u26381 \u24182 \u19981 \u33021 \u36991 \u20813 \u19988 \u23545 \u19968 \u26041 \u25110 \u21452 \u26041 \u36896 \u25104 \u37325 \u22823 \u24433 \u21709 \u30340 \u23458 \u35266 \u20107 \u20214 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u33258 \u28982 \u28798 \u23475 \u22914 \u27700 \u28798 \u12289 \u22320 \u38663 \u12289 \u30239 \u30123 \u27969 \u34892 \u21644 \u39118 \u26292 \u31561 \u20197 \u21450 \u31038 \u20250 \u20107 \u20214 \u22914 \u25112 \u20105 \u12289 \u21160 \u20081 \u12289 \u25919 \u24220 \u34892 \u20026 \u31561 \u12290 \u20986 \u29616 \u19978 \u36848 \u24773 \u20917 \u26102 \u65292 \u31508 \u22696 \u35759 \u20351 \u23558 \u21162 \u21147 \u22312 \u31532 \u19968 \u26102 \u38388 \u19982 \u30456 \u20851 \u21333 \u20301 \u37197 \u21512 \u65292 \u21450 \u26102 \u36827 \u34892 \u20462 \u22797 \u65292 \u20294 \u30001 \u27492 \u32473 \u24744 \u36896 \u25104 \u30340 \u25439 \u22833 \u31508 \u22696 \u35759 \u20351 \u22312 \u27861 \u24459 \u20801 \u35768 \u30340 \u33539 \u22260 \u20869 \u20813 \u36131 \u12290 \
|
||||||
|
\
|
||||||
|
10.2 \uc0\u22312 \u27861 \u24459 \u20801 \u35768 \u30340 \u33539 \u22260 \u20869 \u65292 \u31508 \u22696 \u35759 \u20351 \u23545 \u20197 \u19979 \u24773 \u24418 \u23548 \u33268 \u30340 \u26381 \u21153 \u20013 \u26029 \u25110 \u21463 \u38459 \u19981 \u25215 \u25285 \u36131 \u20219 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 1\u65289 \u21463 \u21040 \u35745 \u31639 \u26426 \u30149 \u27602 \u12289 \u26408 \u39532 \u25110 \u20854 \u20182 \u24694 \u24847 \u31243 \u24207 \u12289 \u40657 \u23458 \u25915 \u20987 \u30340 \u30772 \u22351 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 2\u65289 \u29992 \u25143 \u25110 \u31508 \u22696 \u35759 \u20351 \u30340 \u30005 \u33041 \u36719 \u20214 \u12289 \u31995 \u32479 \u12289 \u30828 \u20214 \u21644 \u36890 \u20449 \u32447 \u36335 \u20986 \u29616 \u25925 \u38556 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 3\u65289 \u29992 \u25143 \u25805 \u20316 \u19981 \u24403 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 4\u65289 \u29992 \u25143 \u36890 \u36807 \u38750 \u31508 \u22696 \u35759 \u20351 \u25480 \u26435 \u30340 \u26041 \u24335 \u20351 \u29992 \u26412 \u26381 \u21153 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 5\u65289 \u20854 \u20182 \u31508 \u22696 \u35759 \u20351 \u26080 \u27861 \u25511 \u21046 \u25110 \u21512 \u29702 \u39044 \u35265 \u30340 \u24773 \u24418 \u12290 \
|
||||||
|
\
|
||||||
|
10.3 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u22312 \u20351 \u29992 \u26412 \u26381 \u21153 \u30340 \u36807 \u31243 \u20013 \u65292 \u21487 \u33021 \u20250 \u36935 \u21040 \u32593 \u32476 \u20449 \u24687 \u25110 \u20854 \u20182 \u29992 \u25143 \u34892 \u20026 \u24102 \u26469 \u30340 \u39118 \u38505 \u65292 \u31508 \u22696 \u35759 \u20351 \u19981 \u23545 \u20219 \u20309 \u20449 \u24687 \u30340 \u30495 \u23454 \u24615 \u12289 \u36866 \u29992 \u24615 \u12289 \u21512 \u27861 \u24615 \u25215 \u25285 \u36131 \u20219 \u65292 \u20063 \u19981 \u23545 \u22240 \u20405 \u26435 \u34892 \u20026 \u32473 \u24744 \u36896 \u25104 \u30340 \u25439 \u23475 \u36127 \u36131 \u12290 \u36825 \u20123 \u39118 \u38505 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 1\u65289 \u26469 \u33258 \u20182 \u20154 \u21311 \u21517 \u25110 \u20882 \u21517 \u30340 \u21547 \u26377 \u23041 \u32961 \u12289 \u35837 \u35876 \u12289 \u20196 \u20154 \u21453 \u24863 \u25110 \u38750 \u27861 \u20869 \u23481 \u30340 \u20449 \u24687 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 2\u65289 \u22240 \u20351 \u29992 \u26412 \u21327 \u35758 \u39033 \u19979 \u30340 \u26381 \u21153 \u65292 \u36973 \u21463 \u20182 \u20154 \u35823 \u23548 \u12289 \u27450 \u35784 \u25110 \u20854 \u20182 \u23548 \u33268 \u25110 \u21487 \u33021 \u23548 \u33268 \u30340 \u20219 \u20309 \u24515 \u29702 \u12289 \u29983 \u29702 \u19978 \u30340 \u20260 \u23475 \u20197 \u21450 \u32463 \u27982 \u19978 \u30340 \u25439 \u22833 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 3\u65289 \u20854 \u20182 \u22240 \u32593 \u32476 \u20449 \u24687 \u25110 \u29992 \u25143 \u34892 \u20026 \u24341 \u36215 \u30340 \u39118 \u38505 \u12290 \
|
||||||
|
\
|
||||||
|
10.4 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u26412 \u26381 \u21153 \u24182 \u38750 \u20026 \u26576 \u20123 \u29305 \u23450 \u30446 \u30340 \u32780 \u35774 \u35745 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u26680 \u35774 \u26045 \u12289 \u20891 \u20107 \u29992 \u36884 \u12289 \u21307 \u30103 \u35774 \u26045 \u12289 \u20132 \u36890 \u36890 \u20449 \u31561 \u37325 \u35201 \u39046 \u22495 \u12290 \u22914 \u26524 \u22240 \u20026 \u36719 \u20214 \u25110 \u26381 \u21153 \u30340 \u21407 \u22240 \u23548 \u33268 \u19978 \u36848 \u25805 \u20316 \u22833 \u36133 \u32780 \u24102 \u26469 \u30340 \u20154 \u21592 \u20260 \u20129 \u12289 \u36130 \u20135 \u25439 \u22833 \u21644 \u29615 \u22659 \u27745 \u26579 \u31561 \u65292 \u31508 \u22696 \u35759 \u20351 \u19981 \u25215 \u25285 \u27861 \u24459 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
10.5 \uc0\u31508 \u22696 \u35759 \u20351 \u26681 \u25454 \u26412 \u21327 \u35758 \u32422 \u23450 \u33719 \u24471 \u22788 \u29702 \u36829 \u27861 \u36829 \u35268 \u20869 \u23481 \u30340 \u26435 \u21033 \u65292 \u35813 \u26435 \u21033 \u19981 \u26500 \u25104 \u31508 \u22696 \u35759 \u20351 \u30340 \u20041 \u21153 \u25110 \u25215 \u35834 \u65292 \u31508 \u22696 \u35759 \u20351 \u19981 \u33021 \u20445 \u35777 \u21450 \u26102 \u21457 \u29616 \u36829 \u27861 \u34892 \u20026 \u25110 \u36827 \u34892 \u30456 \u24212 \u22788 \u29702 \u12290 \
|
||||||
|
\
|
||||||
|
10.6 \uc0\u22312 \u20219 \u20309 \u24773 \u20917 \u19979 \u65292 \u24744 \u19981 \u24212 \u36731 \u20449 \u20511 \u27454 \u12289 \u32034 \u35201 \u23494 \u30721 \u25110 \u20854 \u20182 \u28041 \u21450 \u36130 \u20135 \u30340 \u32593 \u32476 \u20449 \u24687 \u12290 \u28041 \u21450 \u36130 \u20135 \u25805 \u20316 \u30340 \u65292 \u35831 \u19968 \u23450 \u20808 \u26680 \u23454 \u23545 \u26041 \u36523 \u20221 \u65292 \u24182 \u35831 \u32463 \u24120 \u30041 \u24847 \u31508 \u22696 \u35759 \u20351 \u26377 \u20851 \u38450 \u33539 \u35784 \u39575 \u29359 \u32618 \u30340 \u25552 \u31034 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u19968 \u12289 \u26381 \u21153 \u30340 \u21464 \u26356 \u12289 \u20013 \u26029 \u12289 \u32456 \u27490 \
|
||||||
|
\
|
||||||
|
11.1 \uc0\u31508 \u22696 \u35759 \u20351 \u21487 \u33021 \u20250 \u23545 \u26381 \u21153 \u20869 \u23481 \u36827 \u34892 \u21464 \u26356 \u65292 \u20063 \u21487 \u33021 \u20250 \u20013 \u26029 \u12289 \u20013 \u27490 \u25110 \u32456 \u27490 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
11.2 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u31508 \u22696 \u35759 \u20351 \u26377 \u26435 \u33258 \u20027 \u20915 \u23450 \u32463 \u33829 \u31574 \u30053 \u12290 \u22312 \u31508 \u22696 \u35759 \u20351 \u21457 \u29983 \u21512 \u24182 \u12289 \u20998 \u31435 \u12289 \u25910 \u36141 \u12289 \u36164 \u20135 \u36716 \u35753 \u26102 \u65292 \u31508 \u22696 \u35759 \u20351 \u21487 \u21521 \u31532 \u19977 \u26041 \u36716 \u35753 \u26412 \u26381 \u21153 \u19979 \u30456 \u20851 \u36164 \u20135 \u65307 \u31508 \u22696 \u35759 \u20351 \u20063 \u21487 \u22312 \u21333 \u26041 \u36890 \u30693 \u24744 \u21518 \u65292 \u23558 \u26412 \u21327 \u35758 \u19979 \u37096 \u20998 \u25110 \u20840 \u37096 \u26381 \u21153 \u36716 \u20132 \u30001 \u31532 \u19977 \u26041 \u32463 \u33829 \u25110 \u23653 \u34892 \u12290 \u20855 \u20307 \u21463 \u35753 \u20027 \u20307 \u20197 \u31508 \u22696 \u35759 \u20351 \u36890 \u30693 \u30340 \u20026 \u20934 \u12290 \
|
||||||
|
\
|
||||||
|
11.3 \uc0\u22914 \u21457 \u29983 \u19979 \u21015 \u20219 \u20309 \u19968 \u31181 \u24773 \u24418 \u65292 \u31508 \u22696 \u35759 \u20351 \u26377 \u26435 \u19981 \u32463 \u36890 \u30693 \u32780 \u20013 \u26029 \u25110 \u32456 \u27490 \u21521 \u24744 \u25552 \u20379 \u30340 \u26381 \u21153 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 1\u65289 \u26681 \u25454 \u27861 \u24459 \u35268 \u23450 \u24744 \u24212 \u25552 \u20132 \u30495 \u23454 \u20449 \u24687 \u65292 \u32780 \u24744 \u25552 \u20379 \u30340 \u20010 \u20154 \u36164 \u26009 \u19981 \u30495 \u23454 \u12289 \u25110 \u19982 \u27880 \u20876 \u26102 \u20449 \u24687 \u19981 \u19968 \u33268 \u21448 \u26410 \u33021 \u25552 \u20379 \u21512 \u29702 \u35777 \u26126 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 2\u65289 \u24744 \u36829 \u21453 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u25110 \u26412 \u21327 \u35758 \u30340 \u32422 \u23450 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 3\u65289 \u25353 \u29031 \u27861 \u24459 \u35268 \u23450 \u25110 \u20027 \u31649 \u37096 \u38376 \u30340 \u35201 \u27714 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 4\u65289 \u20986 \u20110 \u23433 \u20840 \u30340 \u21407 \u22240 \u25110 \u20854 \u20182 \u24517 \u35201 \u30340 \u24773 \u24418 \u12290 \
|
||||||
|
\
|
||||||
|
11.4 \uc0\u31508 \u22696 \u35759 \u20351 \u26377 \u26435 \u23545 \u37096 \u20998 \u26381 \u21153 \u36827 \u34892 \u25910 \u36153 \u12290 \u33509 \u24744 \u26410 \u25353 \u26102 \u36275 \u39069 \u20184 \u36153 \u65292 \u31508 \u22696 \u35759 \u20351 \u26377 \u26435 \u20013 \u26029 \u12289 \u20013 \u27490 \u25110 \u32456 \u27490 \u25552 \u20379 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
11.5 \uc0\u25105 \u20204 \u22987 \u32456 \u22312 \u19981 \u26029 \u21464 \u26356 \u21644 \u25913 \u36827 \u26412 \u36719 \u20214 \u26381 \u21153 \u65292 \u25105 \u20204 \u20250 \u23613 \u26368 \u22823 \u21162 \u21147 \u21521 \u24744 \u25552 \u20379 \u26381 \u21153 \u65292 \u30830 \u20445 \u26381 \u21153 \u30340 \u36830 \u36143 \u24615 \u21644 \u23433 \u20840 \u24615 \u12290 \u22522 \u20110 \u27492 \u65292 \u25105 \u20204 \u21487 \u33021 \u20250 \u23545 \u26412 \u36719 \u20214 \u36827 \u34892 \u26356 \u26032 \u65292 \u24744 \u24212 \u23558 \u36719 \u20214 \u26356 \u26032 \u21040 \u26368 \u26032 \u29256 \u26412 \u65292 \u21542 \u21017 \u25105 \u20204 \u19981 \u20445 \u35777 \u24744 \u21487 \u27491 \u24120 \u20351 \u29992 \u26412 \u36719 \u20214 \u12290 \
|
||||||
|
\
|
||||||
|
11.6 \uc0\u24744 \u29702 \u35299 \u24182 \u21516 \u24847 \u65292 \u25105 \u20844 \u21496 \u26681 \u25454 \u33258 \u36523 \u21830 \u19994 \u20915 \u31574 \u12289 \u25919 \u24220 \u34892 \u20026 \u12289 \u19981 \u21487 \u25239 \u21147 \u31561 \u21407 \u22240 \u21487 \u33021 \u20250 \u36873 \u25321 \u20013 \u27490 \u12289 \u20013 \u26029 \u21450 \u32456 \u27490 \u26412 \u36719 \u20214 \u30340 \u37096 \u20998 \u25110 \u20840 \u37096 \u26381 \u21153 \u12290 \u22914 \u26377 \u27492 \u31561 \u24773 \u24418 \u21457 \u29983 \u65292 \u25105 \u20204 \u20250 \u37319 \u21462 \u21512 \u29702 \u30340 \u26041 \u24335 \u24182 \u20197 \u21512 \u29702 \u30340 \u26399 \u38480 \u25552 \u21069 \u36890 \u30693 \u24744 \u65292 \u38500 \u27861 \u24459 \u27861 \u35268 \u21478 \u26377 \u35268 \u23450 \u22806 \u65292 \u25105 \u20204 \u19981 \u25215 \u25285 \u30001 \u27492 \u23545 \u24744 \u36896 \u25104 \u30340 \u25439 \u22833 \u12290 \
|
||||||
|
\
|
||||||
|
11.7 \uc0\u24744 \u26377 \u36131 \u20219 \u33258 \u34892 \u22791 \u20221 \u23384 \u20648 \u22312 \u26412 \u26381 \u21153 \u20013 \u30340 \u25968 \u25454 \u12290 \u22914 \u26524 \u24744 \u30340 \u26381 \u21153 \u34987 \u32456 \u27490 \u65292 \u31508 \u22696 \u35759 \u20351 \u21487 \u20197 \u20174 \u26381 \u21153 \u22120 \u19978 \u27704 \u20037 \u22320 \u21024 \u38500 \u24744 \u30340 \u25968 \u25454 \u65292 \u20294 \u27861 \u24459 \u27861 \u35268 \u21478 \u26377 \u35268 \u23450 \u30340 \u38500 \u22806 \u12290 \u26381 \u21153 \u32456 \u27490 \u21518 \u65292 \u31508 \u22696 \u35759 \u20351 \u27809 \u26377 \u20041 \u21153 \u21521 \u24744 \u36820 \u36824 \u25968 \u25454 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u20108 \u12289 \u26410 \u25104 \u24180 \u20154 \u20351 \u29992 \u26465 \u27454 \
|
||||||
|
\
|
||||||
|
12.1 \uc0\u33509 \u29992 \u25143 \u26410 \u28385 18\u21608 \u23681 \u65292 \u21017 \u20026 \u26410 \u25104 \u24180 \u20154 \u65292 \u24212 \u22312 \u30417 \u25252 \u20154 \u30417 \u25252 \u12289 \u25351 \u23548 \u19979 \u38405 \u35835 \u26412 \u21327 \u35758 \u21644 \u20351 \u29992 \u26412 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
12.2 \uc0\u26410 \u25104 \u24180 \u20154 \u29992 \u25143 \u28041 \u19990 \u26410 \u28145 \u65292 \u23481 \u26131 \u34987 \u32593 \u32476 \u34394 \u25311 \u36855 \u24785 \u65292 \u19988 \u22909 \u22855 \u24515 \u24378 \u65292 \u36935 \u20107 \u32570 \u20047 \u38543 \u26426 \u24212 \u21464 \u30340 \u22788 \u29702 \u33021 \u21147 \u65292 \u24456 \u23481 \u26131 \u34987 \u21035 \u26377 \u29992 \u24515 \u30340 \u20154 \u21033 \u29992 \u32780 \u21448 \u32570 \u20047 \u33258 \u25105 \u20445 \u25252 \u33021 \u21147 \u12290 \u22240 \u27492 \u65292 \u26410 \u25104 \u24180 \u20154 \u29992 \u25143 \u22312 \u20351 \u29992 \u26412 \u26381 \u21153 \u26102 \u24212 \u27880 \u24847 \u20197 \u19979 \u20107 \u39033 \u65292 \u25552 \u39640 \u23433 \u20840 \u24847 \u35782 \u65292 \u21152 \u24378 \u33258 \u25105 \u20445 \u25252 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 1\u65289 \u35748 \u28165 \u32593 \u32476 \u19990 \u30028 \u19982 \u29616 \u23454 \u19990 \u30028 \u30340 \u21306 \u21035 \u65292 \u36991 \u20813 \u27785 \u36855 \u20110 \u32593 \u32476 \u65292 \u24433 \u21709 \u26085 \u24120 \u30340 \u23398 \u20064 \u29983 \u27963 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 2\u65289 \u22635 \u20889 \u20010 \u20154 \u36164 \u26009 \u26102 \u65292 \u21152 \u24378 \u20010 \u20154 \u20445 \u25252 \u24847 \u35782 \u65292 \u20197 \u20813 \u19981 \u33391 \u20998 \u23376 \u23545 \u20010 \u20154 \u29983 \u27963 \u36896 \u25104 \u39578 \u25200 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 3\u65289 \u22312 \u30417 \u25252 \u20154 \u25110 \u32769 \u24072 \u30340 \u25351 \u23548 \u19979 \u65292 \u23398 \u20064 \u27491 \u30830 \u20351 \u29992 \u32593 \u32476 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u65288 4\u65289 \u36991 \u20813 \u19982 \u38476 \u29983 \u32593 \u21451 \u38543 \u24847 \u35265 \u38754 \u25110 \u21442 \u21152 \u32852 \u35850 \u27963 \u21160 \u65292 \u20197 \u20813 \u19981 \u27861 \u20998 \u23376 \u26377 \u26426 \u21487 \u20056 \u65292 \u21361 \u21450 \u33258 \u36523 \u23433 \u20840 \u12290 \
|
||||||
|
\
|
||||||
|
12.3 \uc0\u30417 \u25252 \u20154 \u12289 \u23398 \u26657 \u22343 \u24212 \u23545 \u26410 \u25104 \u24180 \u20154 \u20351 \u29992 \u26412 \u26381 \u21153 \u26102 \u22810 \u20570 \u24341 \u23548 \u12290 \u29305 \u21035 \u26159 \u23478 \u38271 \u24212 \u20851 \u24515 \u23376 \u22899 \u30340 \u25104 \u38271 \u65292 \u27880 \u24847 \u19982 \u23376 \u22899 \u30340 \u27807 \u36890 \u65292 \u25351 \u23548 \u23376 \u22899 \u19978 \u32593 \u24212 \u35813 \u27880 \u24847 \u30340 \u23433 \u20840 \u38382 \u39064 \u65292 \u38450 \u24739 \u20110 \u26410 \u28982 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u19977 \u12289 \u21327 \u35758 \u21464 \u26356 \u19982 \u32456 \u27490 \
|
||||||
|
13.1\uc0\u21327 \u35758 \u21464 \u26356 \u36890 \u30693 \
|
||||||
|
\uc0\u25105 \u20204 \u26377 \u26435 \u22312 \u24517 \u35201 \u26102 \u20462 \u25913 \u26412 \u21327 \u35758 \u20869 \u23481 \u65292 \u24182 \u23558 \u36890 \u36807 \u21512 \u29702 \u30340 \u26041 \u24335 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u26412 \u36719 \u20214 \u20844 \u21578 \u12289 \u31995 \u32479 \u28040 \u24687 \u12289 \u31449 \u20869 \u20449 \u12289 \u25163 \u26426 \u30701 \u20449 \u12289 \u30005 \u23376 \u37038 \u20214 \u31561 \u65289 \u21450 \u21512 \u29702 \u30340 \u26399 \u38480 \u25552 \u21069 \u36890 \u30693 \u24744 \u65292 \u35813 \u31561 \u36890 \u30693 \u20110 \u21457 \u36865 \u20043 \u26085 \u35270 \u20026 \u24050 \u36865 \u36798 \u24744 \u12290 \u24744 \u21487 \u20197 \u36890 \u36807 \u36719 \u20214 \u30456 \u20851 \u39029 \u38754 \u26597 \u38405 \u26368 \u26032 \u29256 \u26412 \u30340 \u21327 \u35758 \u20869 \u23481 \u12290 \
|
||||||
|
\
|
||||||
|
13.2\uc0\u21464 \u26356 \u21327 \u35758 \u29983 \u25928 \
|
||||||
|
\uc0\u26412 \u21327 \u35758 \u21464 \u26356 \u29983 \u25928 \u21518 \u65292 \u22914 \u24744 \u32487 \u32493 \u20351 \u29992 \u26412 \u36719 \u20214 \u65292 \u21363 \u35270 \u20026 \u24744 \u24050 \u25509 \u21463 \u20462 \u25913 \u21518 \u30340 \u21327 \u35758 \u12290 \u22914 \u24744 \u19981 \u25509 \u21463 \u20462 \u25913 \u21518 \u30340 \u21327 \u35758 \u65292 \u24212 \u24403 \u20572 \u27490 \u20351 \u29992 \u26412 \u36719 \u20214 \u65292 \u25105 \u20204 \u23558 \u26681 \u25454 \u20844 \u24179 \u21407 \u21017 \u19982 \u24744 \u32456 \u27490 \u21327 \u35758 \u12290 \
|
||||||
|
\
|
||||||
|
13.3\uc0\u21327 \u35758 \u32456 \u27490 \
|
||||||
|
\uc0\u24744 \u27880 \u38144 \u24744 \u30340 \u36134 \u21495 \u25110 \u25105 \u20204 \u36890 \u30693 \u24744 \u32456 \u27490 \u20026 \u24744 \u25552 \u20379 \u26412 \u36719 \u20214 \u26381 \u21153 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u23553 \u31105 \u36134 \u21495 \u12289 \u27880 \u38144 \u36134 \u21495 \u31561 \u65289 \u26102 \u65292 \u26412 \u21327 \u35758 \u23558 \u21516 \u26102 \u32456 \u27490 \u65292 \u25105 \u20204 \u23558 \u19981 \u20877 \u21478 \u34892 \u36890 \u30693 \u24744 \u32456 \u27490 \u26412 \u21327 \u35758 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u22235 \u12289 \u36890 \u30693 \
|
||||||
|
14.1\uc0\u32852 \u31995 \u26041 \u24335 \
|
||||||
|
14.1.1\uc0\u24744 \u22312 \u27880 \u20876 \u25104 \u20026 \u26412 \u36719 \u20214 \u29992 \u25143 \u65292 \u24182 \u25509 \u21463 \u26412 \u36719 \u20214 \u26381 \u21153 \u26102 \u65292 \u24744 \u24212 \u35813 \u21521 \u26412 \u36719 \u20214 \u25552 \u20379 \u30495 \u23454 \u26377 \u25928 \u30340 \u32852 \u31995 \u26041 \u24335 \u65288 \u21253 \u25324 \u24744 \u30340 \u30005 \u23376 \u37038 \u20214 \u22320 \u22336 \u12289 \u32852 \u31995 \u30005 \u35805 \u12289 \u32852 \u31995 \u22320 \u22336 \u31561 \u65289 \u65292 \u23545 \u20110 \u32852 \u31995 \u26041 \u24335 \u21457 \u29983 \u21464 \u26356 \u30340 \u65292 \u24744 \u26377 \u20041 \u21153 \u21450 \u26102 \u26356 \u26032 \u26377 \u20851 \u20449 \u24687 \u65292 \u24182 \u20445 \u25345 \u21487 \u34987 \u32852 \u31995 \u30340 \u29366 \u24577 \u12290 \
|
||||||
|
\
|
||||||
|
14.1.2\uc0\u24744 \u22312 \u27880 \u20876 \u26412 \u36719 \u20214 \u29992 \u25143 \u26102 \u29983 \u25104 \u30340 \u29992 \u20110 \u30331 \u38470 \u26412 \u36719 \u20214 \u25509 \u25910 \u31449 \u20869 \u20449 \u12289 \u31995 \u32479 \u28040 \u24687 \u30340 \u36134 \u21495 \u65292 \u20063 \u20316 \u20026 \u24744 \u30340 \u26377 \u25928 \u32852 \u31995 \u26041 \u24335 \u12290 \
|
||||||
|
\
|
||||||
|
14.1.3\uc0\u26412 \u36719 \u20214 \u23558 \u21521 \u24744 \u30340 \u19978 \u36848 \u32852 \u31995 \u26041 \u24335 \u30340 \u20854 \u20013 \u20043 \u19968 \u25110 \u20854 \u20013 \u33509 \u24178 \u21521 \u24744 \u36865 \u36798 \u21508 \u31867 \u36890 \u30693 \u65292 \u32780 \u27492 \u31867 \u36890 \u30693 \u30340 \u20869 \u23481 \u21487 \u33021 \u23545 \u24744 \u30340 \u26435 \u21033 \u20041 \u21153 \u20135 \u29983 \u37325 \u22823 \u30340 \u26377 \u21033 \u25110 \u19981 \u21033 \u24433 \u21709 \u65292 \u35831 \u24744 \u21153 \u24517 \u21450 \u26102 \u20851 \u27880 \u12290 \
|
||||||
|
\uc0\u24744 \u26377 \u26435 \u36890 \u36807 \u24744 \u27880 \u20876 \u26102 \u22635 \u20889 \u30340 \u25163 \u26426 \u21495 \u30721 \u25110 \u32773 \u30005 \u23376 \u37038 \u31665 \u33719 \u21462 \u24744 \u24863 \u20852 \u36259 \u30340 \u21830 \u21697 \u24191 \u21578 \u20449 \u24687 \u12289 \u20419 \u38144 \u20248 \u24800 \u31561 \u21830 \u19994 \u24615 \u20449 \u24687 \u65307 \u24744 \u22914 \u26524 \u19981 \u24895 \u24847 \u25509 \u25910 \u27492 \u31867 \u20449 \u24687 \u65292 \u24744 \u26377 \u26435 \u36890 \u36807 \u26412 \u36719 \u20214 \u25552 \u20379 \u30340 \u30456 \u24212 \u30340 \u36864 \u35746 \u21151 \u33021 \u36827 \u34892 \u36864 \u35746 \u12290 \
|
||||||
|
\
|
||||||
|
14.2\uc0\u36890 \u30693 \u36865 \u36798 \
|
||||||
|
14.2.1\uc0\u26412 \u36719 \u20214 \u36890 \u36807 \u19978 \u36848 \u32852 \u31995 \u26041 \u24335 \u21521 \u24744 \u21457 \u20986 \u36890 \u30693 \u65292 \u20854 \u20013 \u20197 \u30005 \u23376 \u30340 \u26041 \u24335 \u21457 \u20986 \u30340 \u20070 \u38754 \u36890 \u30693 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u22312 \u26412 \u36719 \u20214 \u20844 \u21578 \u65292 \u21521 \u24744 \u25552 \u20379 \u30340 \u32852 \u31995 \u30005 \u35805 \u21457 \u36865 \u25163 \u26426 \u30701 \u20449 \u65292 \u21521 \u24744 \u25552 \u20379 \u30340 \u30005 \u23376 \u37038 \u20214 \u22320 \u22336 \u21457 \u36865 \u30005 \u23376 \u37038 \u20214 \u65292 \u21521 \u24744 \u30340 \u36134 \u21495 \u21457 \u36865 \u20449 \u24687 \u12289 \u31995 \u32479 \u28040 \u24687 \u20197 \u21450 \u31449 \u20869 \u20449 \u20449 \u24687 \u65292 \u22312 \u21457 \u36865 \u25104 \u21151 \u21518 \u21363 \u35270 \u20026 \u36865 \u36798 \u65307 \u20197 \u32440 \u36136 \u36733 \u20307 \u21457 \u20986 \u30340 \u20070 \u38754 \u36890 \u30693 \u65292 \u25353 \u29031 \u25552 \u20379 \u32852 \u31995 \u22320 \u22336 \u20132 \u37038 \u21518 \u30340 \u31532 \u12304 7\u12305 \u20010 \u33258 \u28982 \u26085 \u21363 \u35270 \u20026 \u36865 \u36798 \u12290 \
|
||||||
|
\
|
||||||
|
14.2.2\uc0\u23545 \u20110 \u22312 \u26412 \u36719 \u20214 \u19978 \u22240 \u20132 \u26131 \u27963 \u21160 \u24341 \u36215 \u30340 \u20219 \u20309 \u32416 \u32439 \u65292 \u24744 \u21516 \u24847 \u21496 \u27861 \u26426 \u20851 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u20154 \u27665 \u27861 \u38498 \u65289 \u21487 \u20197 \u36890 \u36807 \u25163 \u26426 \u30701 \u20449 \u12289 \u30005 \u23376 \u37038 \u20214 \u31561 \u29616 \u20195 \u36890 \u35759 \u26041 \u24335 \u25110 \u37038 \u23492 \u26041 \u24335 \u21521 \u24744 \u36865 \u36798 \u27861 \u24459 \u25991 \u20070 \u65288 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u35785 \u35772 \u25991 \u20070 \u65289 \u12290 \u24744 \u25351 \u23450 \u25509 \u25910 \u27861 \u24459 \u25991 \u20070 \u30340 \u25163 \u26426 \u21495 \u30721 \u12289 \u30005 \u23376 \u37038 \u31665 \u25110 \u36719 \u20214 \u36134 \u21495 \u31561 \u32852 \u31995 \u26041 \u24335 \u20026 \u24744 \u22312 \u26412 \u36719 \u20214 \u27880 \u20876 \u12289 \u26356 \u26032 \u26102 \u25552 \u20379 \u30340 \u25163 \u26426 \u21495 \u30721 \u12289 \u30005 \u23376 \u37038 \u31665 \u32852 \u31995 \u26041 \u24335 \u20197 \u21450 \u22312 \u27880 \u20876 \u26412 \u36719 \u20214 \u29992 \u25143 \u26102 \u29983 \u25104 \u30340 \u36134 \u21495 \u65292 \u21496 \u27861 \u26426 \u20851 \u21521 \u19978 \u36848 \u32852 \u31995 \u26041 \u24335 \u21457 \u20986 \u27861 \u24459 \u25991 \u20070 \u21363 \u35270 \u20026 \u36865 \u36798 \u12290 \u24744 \u25351 \u23450 \u30340 \u37038 \u23492 \u22320 \u22336 \u20026 \u24744 \u30340 \u27861 \u23450 \u32852 \u31995 \u22320 \u22336 \u25110 \u24744 \u25552 \u20379 \u30340 \u26377 \u25928 \u32852 \u31995 \u22320 \u22336 \u12290 \
|
||||||
|
\
|
||||||
|
14.2.3\uc0\u24744 \u21516 \u24847 \u21496 \u27861 \u26426 \u20851 \u21487 \u37319 \u21462 \u20197 \u19978 \u19968 \u31181 \u25110 \u22810 \u31181 \u36865 \u36798 \u26041 \u24335 \u21521 \u24744 \u36865 \u36798 \u27861 \u24459 \u25991 \u20070 \u65292 \u21496 \u27861 \u26426 \u20851 \u37319 \u21462 \u22810 \u31181 \u26041 \u24335 \u21521 \u24744 \u36865 \u36798 \u27861 \u24459 \u25991 \u20070 \u65292 \u36865 \u36798 \u26102 \u38388 \u20197 \u19978 \u36848 \u36865 \u36798 \u26041 \u24335 \u20013 \u26368 \u20808 \u36865 \u36798 \u30340 \u20026 \u20934 \u12290 \
|
||||||
|
\uc0\u24744 \u21516 \u24847 \u19978 \u36848 \u36865 \u36798 \u26041 \u24335 \u36866 \u29992 \u20110 \u21508 \u20010 \u21496 \u27861 \u31243 \u24207 \u38454 \u27573 \u12290 \u22914 \u36827 \u20837 \u35785 \u35772 \u31243 \u24207 \u30340 \u65292 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u19968 \u23457 \u12289 \u20108 \u23457 \u12289 \u20877 \u23457 \u12289 \u25191 \u34892 \u20197 \u21450 \u30563 \u20419 \u31243 \u24207 \u31561 \u12290 \
|
||||||
|
\
|
||||||
|
14.2.4\uc0\u20320 \u24212 \u24403 \u20445 \u35777 \u25152 \u25552 \u20379 \u30340 \u32852 \u31995 \u26041 \u24335 \u26159 \u20934 \u30830 \u12289 \u26377 \u25928 \u30340 \u65292 \u24182 \u36827 \u34892 \u23454 \u26102 \u26356 \u26032 \u12290 \u22914 \u26524 \u22240 \u25552 \u20379 \u30340 \u32852 \u31995 \u26041 \u24335 \u19981 \u30830 \u20999 \u65292 \u25110 \u19981 \u21450 \u26102 \u21578 \u30693 \u21464 \u26356 \u21518 \u30340 \u32852 \u31995 \u26041 \u24335 \u65292 \u20351 \u27861 \u24459 \u25991 \u20070 \u26080 \u27861 \u36865 \u36798 \u25110 \u26410 \u21450 \u26102 \u36865 \u36798 \u65292 \u30001 \u24744 \u33258 \u34892 \u25215 \u25285 \u30001 \u27492 \u21487 \u33021 \u20135 \u29983 \u30340 \u27861 \u24459 \u21518 \u26524 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u20116 \u12289 \u20854 \u20182 \
|
||||||
|
15.1 \uc0\u24744 \u20351 \u29992 \u26412 \u36719 \u20214 \u21363 \u35270 \u20026 \u24744 \u24050 \u38405 \u35835 \u24182 \u21516 \u24847 \u21463 \u26412 \u21327 \u35758 \u30340 \u32422 \u26463 \u12290 \u25105 \u20204 \u26377 \u26435 \u22312 \u24517 \u35201 \u26102 \u20462 \u25913 \u26412 \u21327 \u35758 \u26465 \u27454 \u12290 \u24744 \u21487 \u20197 \u22312 \u26412 \u36719 \u20214 \u30340 \u26368 \u26032 \u29256 \u26412 \u20013 \u26597 \u38405 \u30456 \u20851 \u21327 \u35758 \u26465 \u27454 \u12290 \u26412 \u21327 \u35758 \u26465 \u27454 \u21464 \u26356 \u21518 \u65292 \u22914 \u26524 \u24744 \u32487 \u32493 \u20351 \u29992 \u26412 \u36719 \u20214 \u65292 \u21363 \u35270 \u20026 \u24744 \u24050 \u25509 \u21463 \u20462 \u25913 \u21518 \u30340 \u21327 \u35758 \u12290 \u22914 \u26524 \u24744 \u19981 \u25509 \u21463 \u20462 \u25913 \u21518 \u30340 \u21327 \u35758 \u65292 \u24212 \u24403 \u20572 \u27490 \u20351 \u29992 \u26412 \u36719 \u20214 \u12290 \
|
||||||
|
\
|
||||||
|
15.2 \uc0\u26412 \u21327 \u35758 \u30340 \u25104 \u31435 \u12289 \u29983 \u25928 \u12289 \u23653 \u34892 \u12289 \u35299 \u37322 \u21450 \u20105 \u35758 \u35299 \u20915 \u65292 \u36866 \u29992 \u20013 \u21326 \u20154 \u27665 \u20849 \u21644 \u22269 \u22823 \u38470 \u22320 \u21306 \u27861 \u24459 \u27861 \u35268 \u65307 \u22914 \u27861 \u24459 \u26080 \u30456 \u20851 \u35268 \u23450 \u30340 \u65292 \u21442 \u29031 \u21830 \u19994 \u24815 \u20363 \u21450 /\u25110 \u34892 \u19994 \u24815 \u20363 \u12290 \
|
||||||
|
\
|
||||||
|
15.3 \uc0\u33509 \u24744 \u21644 \u25105 \u20204 \u20043 \u38388 \u21457 \u29983 \u20219 \u20309 \u32416 \u32439 \u25110 \u20105 \u35758 \u65292 \u39318 \u20808 \u24212 \u21451 \u22909 \u21327 \u21830 \u35299 \u20915 \u65307 \u21327 \u21830 \u19981 \u25104 \u30340 \u65292 \u24744 \u21516 \u24847 \u23558 \u32416 \u32439 \u25110 \u20105 \u35758 \u25552 \u20132 \u25105 \u20844 \u21496 \u25152 \u22312 \u22320 \u20154 \u27665 \u27861 \u38498 \u31649 \u36758 \u12290 \
|
||||||
|
\
|
||||||
|
15.4 \uc0\u26412 \u21327 \u35758 \u25152 \u26377 \u26465 \u27454 \u30340 \u26631 \u39064 \u20165 \u20026 \u38405 \u35835 \u26041 \u20415 \u65292 \u26412 \u36523 \u24182 \u26080 \u23454 \u38469 \u21547 \u20041 \u65292 \u19981 \u33021 \u20316 \u20026 \u26412 \u21327 \u35758 \u21547 \u20041 \u35299 \u37322 \u30340 \u20381 \u25454 \u12290 \
|
||||||
|
\
|
||||||
|
15.5 \uc0\u26412 \u21327 \u35758 \u21487 \u33021 \u23384 \u22312 \u21253 \u25324 \u20013 \u25991 \u12289 \u33521 \u25991 \u22312 \u20869 \u30340 \u22810 \u31181 \u35821 \u35328 \u30340 \u29256 \u26412 \u65292 \u33509 \u23384 \u22312 \u20013 \u25991 \u29256 \u26412 \u19982 \u20854 \u20182 \u35821 \u35328 \u30340 \u29256 \u26412 \u30456 \u20914 \u31361 \u30340 \u22320 \u26041 \u65292 \u20197 \u20013 \u25991 \u29256 \u26412 \u20026 \u20934 \u12290 \
|
||||||
|
\
|
||||||
|
15.6 \uc0\u26412 \u21327 \u35758 \u26465 \u27454 \u26080 \u35770 \u22240 \u20309 \u31181 \u21407 \u22240 \u37096 \u20998 \u26080 \u25928 \u25110 \u19981 \u21487 \u25191 \u34892 \u65292 \u20854 \u20313 \u26465 \u27454 \u20173 \u26377 \u25928 \u65292 \u23545 \u21452 \u26041 \u20855 \u26377 \u32422 \u26463 \u21147 \u12290 \
|
||||||
|
\
|
||||||
|
15.7 \uc0\u22914 \u24744 \u23545 \u26412 \u21327 \u35758 \u26377 \u20219 \u20309 \u24847 \u35265 \u25110 \u24314 \u35758 \u65292 \u24744 \u21487 \u36890 \u36807 \u26412 \u24179 \u21488 \u32852 \u31995 \u25105 \u20204 \u65292 \u32852 \u31995 \u26041 \u24335 \u20026 \u12304 fengqunwangluo2025@163.com\u12305 \u65292 \u25105 \u20204 \u20250 \u32473 \u20104 \u24744 \u24517 \u35201 \u30340 \u24110 \u21161 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u33258 \u21551 \u21160 \u25110 \u20851 \u32852 \u21551 \u21160 \u35828 \u26126 \
|
||||||
|
\
|
||||||
|
\uc0\u25512 \u36865 \u30456 \u20851 :\u20026 \u30830 \u20445 \u26412 \u24212 \u29992 \u22788 \u20110 \u21518 \u21488 \u25110 \u21518 \u21488 \u36816 \u34892 \u29366 \u24577 \u19979 \u21487 \u27491 \u24120 \u25509 \u25910 \u21040 \u23458 \u25143 \u31471 \u25512 \u36865 \u30340 \u24191 \u25773 \u20449 \u24687 \u65292 \u26412 \u24212 \u29992 \u39035 \u20351 \u29992 (\u33258 \u21551 \u21160 )\u33021 \u21147 \u65292 \u23558 \u23384 \u22312 \u19968 \u23450 \u39057 \u29575 \u36890 \u36807 \u31995 \u32479 \u21457 \u36865 \u24191 \u25773 \u21796 \u37266 \u26412 \u24212 \u29992 \u33258 \u21551 \u21160 \u25110 \u20851 \u32852 \u21551 \u21160 \u34892 \u20026 \u65292 \u26159 \u22240 \u23454 \u29616 \u21151 \u33021 \u21450 \u26381 \u21153 \u25152 \u24517 \u35201 \u30340 ;\u24403 \u24744 \u25171 \u24320 \u20869 \u23481 \u31867 \u25512 \u36865 \u28040 \u24687 \u65292 \u22312 \u24449 \u24471 \u24744 \u30340 \u26126 \u30830 \u21516 \u24847 \u21518 \u65292 \u20250 \u36339 \u36716 \u25171 \u24320 \u30456 \u20851 \u20869 \u23481 \u12290 \u22312 \u26410 \u24449 \u24471 \u24744 \u21516 \u24847 \u30340 \u24773 \u20917 \u19979 \u65292 \u21017 \u19981 \u20250 \u26377 \u20851 \u32852 \u21551 \u21160 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u35835 \u21462 \u21098 \u36148 \u26495 \u20449 \u24687 \u65306 \
|
||||||
|
\
|
||||||
|
1\uc0\u12289 \u29992 \u20110 \u22797 \u21046 \u65288 \u25163 \u26426 \u21495 \u12289 id\u65289 \u26041 \u20415 \u29992 \u29992 \u25143 \u25628 \u32034 \u28155 \u21152 \u22909 \u21451 \
|
||||||
|
\
|
||||||
|
2\uc0\u12289 \u29992 \u20110 \u22797 \u21046 \u65288 \u24179 \u21488 \u32852 \u31995 \u26041 \u24335 \u65289 \u26041 \u20415 \u29992 \u25143 \u25552 \u20132 \u24847 \u35265 \u21453 \u39304 \u12289 \u20030 \u25253 \u31561 }
|
||||||
@@ -0,0 +1,442 @@
|
|||||||
|
{\rtf1\ansi\ansicpg936\cocoartf2821
|
||||||
|
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\froman\fcharset0 Times-Roman;}
|
||||||
|
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
|
||||||
|
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;}
|
||||||
|
\paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
||||||
|
\deftab720
|
||||||
|
\pard\pardeftab720\partightenfactor0
|
||||||
|
|
||||||
|
\f0\fs24 \cf0 \expnd0\expndtw0\kerning0
|
||||||
|
\outl0\strokewidth0 \strokec2 \
|
||||||
|
\uc0\u23562 \u25964 \u30340 \u31508 \u22696 \u35759 \u20351 \u29992 \u25143 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u27426 \u36814 \u24744 \u20351 \u29992 \u28023 \u21475 \u24066 \u26539 \u32676 \u32593 \u32476 \u31185 \u25216 \u26377 \u38480 \u20844 \u21496 \u25552 \u20379 \u30340 \'93\u31508 \u22696 \u35759 \u20351 \'94\u36719 \u20214 \u21450 \u30456 \u20851 \u26381 \u21153 \u65281 \u20316 \u20026 \'93\u31508 \u22696 \u35759 \u20351 \'94\u30340 \u24320 \u21457 \u32773 \u65288 \u20197 \u19979 \u31616 \u31216 \'93\u25105 \u20204 \'94\u65289 \u65292 \u25105 \u20204 \u28145 \u30693 \u20010 \u20154 \u20449 \u24687 \u23545 \u24744 \u30340 \u37325 \u35201 \u24615 \u65292 \u24182 \u20250 \u23613 \u21147 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u23433 \u20840 \u21487 \u38752 \u12290 \u25105 \u20204 \u33268 \u21147 \u20110 \u32500 \u25345 \u24744 \u23545 \u25105 \u20204 \u30340 \u20449 \u20219 \u65292 \u24682 \u23432 \u20197 \u19979 \u21407 \u21017 \u65292 \u20445 \u25252 \u21644 \u22788 \u29702 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65306 \u26435 \u36131 \u19968 \u33268 \u21407 \u21017 \u65292 \u30446 \u30340 \u26126 \u30830 \u21407 \u21017 \u65292 \u36873 \u25321 \u21516 \u24847 \u21407 \u21017 \u65292 \u26368 \u23569 \u24517 \u35201 \u21407 \u21017 \u65292 \u30830 \u20445 \u23433 \u20840 \u21407 \u21017 \u65292 \u20027 \u20307 \u21442 \u19982 \u21407 \u21017 \u65292 \u20844 \u24320 \u36879 \u26126 \u21407 \u21017 \u12290 \u21516 \u26102 \u25105 \u20204 \u25215 \u35834 \u65292 \u25105 \u20204 \u23558 \u25353 \u19994 \u30028 \u25104 \u29087 \u30340 \u23433 \u20840 \u35299 \u20915 \u26041 \u26696 \u65292 \u37319 \u21462 \u30456 \u24212 \u30340 \u23433 \u20840 \u20445 \u25252 \u25514 \u26045 \u26469 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u29256 \u26412 \u29983 \u25928 \u26085 \u26399 \u65306 2025\u24180 8\u26376 1\u26085 \
|
||||||
|
\
|
||||||
|
\uc0\u22914 \u24744 \u26377 \u20219 \u20309 \u30097 \u38382 \u12289 \u24847 \u35265 \u25110 \u24314 \u35758 \u65292 \u24744 \u21487 \u36890 \u36807 \u20197 \u19979 \u32852 \u31995 \u26041 \u24335 \u19982 \u25105 \u20204 \u32852 \u31995 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u32852 \u31995 \u37038 \u31665 \u65306 fengqunwangluo2025@163.com\
|
||||||
|
\
|
||||||
|
\uc0\u32852 \u31995 \u22320 \u22336 \u65306 \u28023 \u21335 \u30465 \u28023 \u21475 \u24066 \u32654 \u20848 \u21306 \u28023 \u24220 \u34903 \u36947 \u28023 \u24220 \u36335 4\u21495 \u28023 \u21475 \u23486 \u39302 \u38468 \u27004 \u31532 4\u23618 C\u21306 \u31532 7\u38388 \
|
||||||
|
\
|
||||||
|
\uc0\u12304 \u29305 \u21035 \u25552 \u31034 \u12305 \
|
||||||
|
\
|
||||||
|
\uc0\u35831 \u24744 \u20180 \u32454 \u38405 \u35835 \u12298 \u38544 \u31169 \u25919 \u31574 \u12299 \u35814 \u32454 \u20102 \u35299 \u25105 \u20204 \u23545 \u20449 \u24687 \u30340 \u25910 \u38598 \u12289 \u20351 \u29992 \u12289 \u20445 \u23384 \u26041 \u24335 \u31561 \u65292 \u24182 \u30830 \u23450 \u20102 \u35299 \u25105 \u20204 \u23545 \u24744 \u20010 \u20154 \u20449 \u24687 \u30340 \u22788 \u29702 \u35268 \u21017 \u12290 \u23545 \u26412 \u25919 \u31574 \u20013 \u25105 \u20204 \u35748 \u20026 \u19982 \u24744 \u30340 \u26435 \u30410 \u23384 \u22312 \u37325 \u22823 \u20851 \u31995 \u30340 \u26465 \u27454 \u65292 \u25105 \u20204 \u37319 \u29992 \u23383 \u20307 \u21152 \u31895 \u24418 \u24335 \u25552 \u31034 \u24744 \u29305 \u21035 \u27880 \u24847 \u12290 \u25105 \u20204 \u24314 \u35758 \u24744 \u20180 \u32454 \u38405 \u35835 \u24182 \u29702 \u35299 \u26412 \u25919 \u31574 \u20840 \u37096 \u20869 \u23481 \u65292 \u23588 \u20854 \u26159 \u30830 \u20445 \u24050 \u20840 \u37096 \u30693 \u26195 \u24182 \u20805 \u20998 \u29702 \u35299 \u21152 \u31895 \u23383 \u20307 \u20869 \u23481 \u30340 \u21547 \u20041 \u21450 \u30456 \u24212 \u30340 \u27861 \u24459 \u21518 \u26524 \u65292 \u20197 \u20415 \u24744 \u23545 \u25105 \u20204 \u30340 \u26381 \u21153 \u20316 \u20986 \u36866 \u24403 \u30340 \u36873 \u25321 \u12290 \u26412 \u38544 \u31169 \u25919 \u31574 \u20013 \u28041 \u21450 \u30340 \u30456 \u20851 \u26415 \u35821 \u65292 \u25105 \u20204 \u23613 \u37327 \u20197 \u31616 \u26126 \u25212 \u35201 \u30340 \u34920 \u36848 \u65292 \u20197 \u20415 \u24744 \u26356 \u22909 \u22320 \u29702 \u35299 \u12290 \u28041 \u21450 \u20855 \u20307 \u30340 \u20135 \u21697 \u65288 \u25110 \u26381 \u21153 \u65289 \u65292 \u22914 \u27861 \u24459 \u12289 \u34892 \u25919 \u27861 \u35268 \u35268 \u23450 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u24212 \u24403 \u21462 \u24471 \u20010 \u20154 \u21333 \u29420 \u21516 \u24847 \u30340 \u65292 \u25105 \u20204 \u23558 \u26681 \u25454 \u24744 \u30340 \u23454 \u38469 \u20351 \u29992 \u24773 \u20917 \u21333 \u29420 \u24449 \u27714 \u24744 \u30340 \u21516 \u24847 \u12290 \u24744 \u20351 \u29992 \u25110 \u22312 \u25105 \u20204 \u26356 \u26032 \u26412 \u38544 \u31169 \u25919 \u31574 \u21518 \u65288 \u25105 \u20204 \u20250 \u21450 \u26102 \u25552 \u31034 \u24744 \u26356 \u26032 \u30340 \u24773 \u20917 \u65289 \u32487 \u32493 \u20351 \u29992 \u25105 \u20204 \u30340 \u20135 \u21697 \u19982 /\u25110 \u26381 \u21153 \u65292 \u21363 \u34920 \u31034 \u24744 \u21516 \u24847 \u26412 \u38544 \u31169 \u25919 \u31574 \u65288 \u21547 \u26356 \u26032 \u29256 \u26412 \u65289 \u20869 \u23481 \u65292 \u24182 \u19988 \u21516 \u24847 \u25105 \u20204 \u25353 \u29031 \u26412 \u38544 \u31169 \u25919 \u31574 \u25910 \u38598 \u12289 \u20351 \u29992 \u12289 \u20445 \u23384 \u21644 \u20849 \u20139 \u24744 \u30340 \u30456 \u20851 \u20449 \u24687 \u12290 \
|
||||||
|
\uc0\u22312 \u20351 \u29992 \u25105 \u20204 \u25552 \u20379 \u30340 \u21508 \u39033 \u20135 \u21697 \u25110 \u26381 \u21153 \u21069 \u65292 \u35831 \u24744 \u21153 \u24517 \u20180 \u32454 \u38405 \u35835 \u24182 \u36879 \u24443 \u29702 \u35299 \u26412 \u25919 \u31574 \u65292 \u22312 \u30830 \u35748 \u20805 \u20998 \u29702 \u35299 \u24182 \u21516 \u24847 \u21518 \u20351 \u29992 \u30456 \u20851 \u20135 \u21697 \u25110 \u26381 \u21153 \u12290 \u19968 \u26086 \u24744 \u24320 \u22987 \u20351 \u29992 \u25105 \u20204 \u21508 \u39033 \u20135 \u21697 \u25110 \u26381 \u21153 \u65292 \u21363 \u34920 \u31034 \u24744 \u24050 \u20805 \u20998 \u29702 \u35299 \u24182 \u21516 \u24847 \u20351 \u29992 \u25105 \u20204 \u30340 \u30456 \u20851 \u20135 \u21697 \u25110 \u26381 \u21153 \u65292 \u20197 \u21450 \u22312 \u20351 \u29992 \u30456 \u20851 \u20135 \u21697 \u25110 \u26381 \u21153 \u36807 \u31243 \u20013 \u25152 \u38656 \u30340 \u24517 \u35201 \u20010 \u20154 \u20449 \u24687 \u65292 \u24182 \u32473 \u20104 \u30456 \u24212 \u30340 \u25910 \u38598 \u20351 \u29992 \u25480 \u26435 \u12290 \u22914 \u23545 \u26412 \u25919 \u31574 \u20869 \u23481 \u26377 \u20219 \u20309 \u30097 \u38382 \u12289 \u24847 \u35265 \u25110 \u24314 \u35758 \u65292 \u24744 \u21487 \u20197 \u36890 \u36807 \u25105 \u20204 \u25552 \u20379 \u30340 \u32852 \u31995 \u26041 \u24335 \u21521 \u25105 \u20204 \u21672 \u35810 \u12290 \
|
||||||
|
\uc0\u20026 \u21327 \u21161 \u24744 \u20102 \u35299 \u25105 \u20204 \u38544 \u31169 \u20445 \u25252 \u25919 \u31574 \u65292 \u20197 \u19979 \u26159 \u26412 \u25919 \u31574 \u30340 \u35201 \u28857 \u35828 \u26126 \u65306 \
|
||||||
|
1\uc0\u12289 \u25105 \u20204 \u20250 \u36981 \u24490 \u38544 \u31169 \u20445 \u25252 \u25919 \u31574 \u25910 \u38598 \u12289 \u20351 \u29992 \u24744 \u30340 \u20449 \u24687 \u65292 \u20294 \u19981 \u20250 \u20165 \u22240 \u24744 \u21516 \u24847 \u26412 \u25919 \u31574 \u32780 \u37319 \u29992 \u24378 \u21046 \u25414 \u32465 \u30340 \u26041 \u24335 \u25910 \u38598 \u20840 \u37096 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
2\uc0\u12289 \u25105 \u20204 \u20250 \u36880 \u19968 \u35828 \u26126 \u25152 \u25910 \u38598 \u30340 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u31867 \u22411 \u21450 \u20854 \u23545 \u24212 \u30340 \u29992 \u36884 \u65292 \u20197 \u20415 \u24744 \u20102 \u35299 \u25105 \u20204 \u38024 \u23545 \u26576 \u19968 \u29305 \u23450 \u21151 \u33021 \u25910 \u38598 \u30340 \u20855 \u20307 \u20010 \u20154 \u20449 \u24687 \u31867 \u21035 \u12289 \u20351 \u29992 \u29702 \u30001 \u21450 \u25910 \u38598 \u26041 \u24335 \u12290 \
|
||||||
|
3\uc0\u12289 \u24744 \u21487 \u20197 \u35775 \u38382 \u12289 \u26356 \u27491 \u12289 \u21024 \u38500 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12289 \u25913 \u21464 \u24744 \u25480 \u26435 \u21516 \u24847 \u30340 \u33539 \u22260 \u20197 \u21450 \u35831 \u27714 \u27880 \u38144 \u36134 \u25143 \u65292 \u25105 \u20204 \u20026 \u24744 \u25552 \u20379 \u20102 \u34892 \u20351 \u36825 \u20123 \u26435 \u21033 \u30340 \u36884 \u24452 \u12290 \
|
||||||
|
4\uc0\u12289 \u38500 \u38750 \u20877 \u27425 \u24449 \u24471 \u24744 \u30340 \u21516 \u24847 \u65292 \u25105 \u20204 \u19981 \u20250 \u23558 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u29992 \u20110 \u26412 \u25919 \u31574 \u26410 \u36733 \u26126 \u30340 \u20854 \u20182 \u30446 \u30340 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u24341 \u35328 \
|
||||||
|
\
|
||||||
|
\uc0\u31508 \u22696 \u35759 \u20351 \u37325 \u35270 \u29992 \u25143 \u20449 \u24687 \u23433 \u20840 \u19982 \u38544 \u31169 \u20445 \u25252 \u65292 \u31469 \u23613 \u20840 \u21147 \u36890 \u36807 \u21512 \u29702 \u26377 \u25928 \u30340 \u20449 \u24687 \u23433 \u20840 \u25216 \u26415 \u21450 \u31649 \u29702 \u27969 \u31243 \u65292 \u38450 \u27490 \u24744 \u30340 \u20449 \u24687 \u27844 \u38706 \u12289 \u25439 \u27585 \u12289 \u20002 \u22833 \u65307 \u20026 \u24744 \u25552 \u20379 \u20415 \u21033 \u30340 \u20449 \u24687 \u31649 \u29702 \u36873 \u39033 \u65292 \u22686 \u24378 \u24744 \u23545 \u20449 \u24687 \u31649 \u29702 \u30340 \u20415 \u25463 \u24615 \u65307 \u20445 \u25252 \u24744 \u30340 \u36890 \u20449 \u31192 \u23494 \u65292 \u20445 \u38556 \u24744 \u30340 \u20449 \u24687 \u21450 \u36890 \u20449 \u23433 \u20840 \u12290 \u31508 \u22696 \u35759 \u20351 \u20005 \u26684 \u36981 \u23432 \u27861 \u24459 \u27861 \u35268 \u65292 \u20165 \u25910 \u38598 \u24517 \u35201 \u30340 \u20449 \u24687 \u65292 \u24182 \u25552 \u21319 \u20449 \u24687 \u22788 \u29702 \u36879 \u26126 \u24230 \u65292 \u22312 \u20135 \u21697 \u25110 \u26381 \u21153 \u24320 \u21457 \u30340 \u21508 \u20010 \u29615 \u33410 \u65292 \u32508 \u21512 \u27861 \u24459 \u12289 \u20135 \u21697 \u12289 \u35774 \u35745 \u31561 \u22810 \u26041 \u22240 \u32032 \u65292 \u34701 \u20837 \u38544 \u31169 \u20445 \u25252 \u30340 \u29702 \u24565 \u65292 \u20026 \u24744 \u25552 \u20379 \u26356 \u21152 \u23433 \u20840 \u12289 \u21487 \u38752 \u30340 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u21046 \u23450 \u24182 \u36981 \u24490 \u26412 \u12298 \u38544 \u31169 \u25919 \u31574 \u12299 \u65288 \u20197 \u19979 \u31616 \u31216 \'93\u26412 \u25919 \u31574 \'94\u65289 \u65292 \u20027 \u35201 \u21521 \u24744 \u35828 \u26126 \u65306 \
|
||||||
|
\
|
||||||
|
\'95 \uc0\u25105 \u20204 \u25910 \u38598 \u21738 \u20123 \u20449 \u24687 \u65307 \
|
||||||
|
\'95 \uc0\u25105 \u20204 \u25910 \u38598 \u20449 \u24687 \u30340 \u29992 \u36884 \u65307 \
|
||||||
|
\'95 \uc0\u25105 \u20204 \u22914 \u20309 \u20849 \u20139 \u12289 \u36716 \u35753 \u12289 \u20844 \u24320 \u25259 \u38706 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65307 \
|
||||||
|
\'95 \uc0\u25105 \u20204 \u22914 \u20309 \u20445 \u23384 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65307 \
|
||||||
|
\'95 \uc0\u25105 \u20204 \u22914 \u20309 \u20351 \u29992 Cookie\u21644 \u21516 \u31867 \u25216 \u26415 \u65307 \
|
||||||
|
\'95 \uc0\u24744 \u22914 \u20309 \u31649 \u29702 \u20010 \u20154 \u20449 \u24687 \u65307 \
|
||||||
|
\'95 \uc0\u26410 \u25104 \u24180 \u20154 \u20010 \u20154 \u20449 \u24687 \u20445 \u25252 \u65307 \
|
||||||
|
\'95 \uc0\u36890 \u30693 \u21644 \u20462 \u35746 \u65307 \
|
||||||
|
\'95 \uc0\u22914 \u20309 \u32852 \u31995 \u25105 \u20204 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u19968 \u12289 \u20010 \u20154 \u20449 \u24687 \u30340 \u23450 \u20041 \u19982 \u33539 \u22260 \
|
||||||
|
\
|
||||||
|
\uc0\u38500 \u21478 \u26377 \u32422 \u23450 \u22806 \u65292 \u26412 \u25919 \u31574 \u25152 \u29992 \u26415 \u35821 \u20855 \u26377 \u20197 \u19979 \u23450 \u20041 \u12290 \
|
||||||
|
\
|
||||||
|
1.1 \uc0\u20010 \u20154 \u20449 \u24687 \u65306 \u26159 \u25351 \u20197 \u30005 \u23376 \u25110 \u32773 \u20854 \u20182 \u26041 \u24335 \u35760 \u24405 \u30340 \u33021 \u22815 \u21333 \u29420 \u25110 \u32773 \u19982 \u20854 \u20182 \u20449 \u24687 \u32467 \u21512 \u35782 \u21035 \u33258 \u28982 \u20154 \u20010 \u20154 \u36523 \u20221 \u25110 \u32773 \u21453 \u26144 \u29305 \u23450 \u33258 \u28982 \u20154 \u27963 \u21160 \u24773 \u20917 \u30340 \u21508 \u31181 \u20449 \u24687 \u12290 \u26412 \u38544 \u31169 \u25919 \u31574 \u20013 \u28041 \u21450 \u30340 \u20010 \u20154 \u20449 \u24687 \u21253 \u25324 \u33258 \u28982 \u20154 \u30340 \u22995 \u21517 \u12289 \u26165 \u31216 \u12289 \u20986 \u29983 \u26085 \u26399 \u12289 \u22269 \u31821 \u12289 \u36523 \u20221 \u35777 \u20214 \u21495 \u30721 \u21644 \u26377 \u25928 \u26399 \u12289 \u24615 \u21035 \u12289 \u24180 \u40836 \u12289 \u20010 \u20154 \u29983 \u29289 \u35782 \u21035 \u20449 \u24687 \u12289 \u20303 \u22336 \u22320 \u25110 \u24037 \u20316 \u21333 \u20301 \u22320 \u22336 \u12289 \u30005 \u35805 \u21495 \u30721 \u12289 \u20844 \u21496 \u12289 \u26426 \u26500 \u12289 \u32844 \u19994 \u12290 \
|
||||||
|
\
|
||||||
|
1.2 \uc0\u20010 \u20154 \u25935 \u24863 \u20449 \u24687 \u65306 \u26159 \u25351 \u19968 \u26086 \u27844 \u38706 \u12289 \u38750 \u27861 \u25552 \u20379 \u25110 \u28389 \u29992 \u21487 \u33021 \u21361 \u23475 \u20154 \u36523 \u21644 \u36130 \u20135 \u23433 \u20840 \u65292 \u26497 \u26131 \u23548 \u33268 \u20010 \u20154 \u21517 \u35465 \u12289 \u36523 \u24515 \u20581 \u24247 \u21463 \u21040 \u25439 \u23475 \u25110 \u27495 \u35270 \u24615 \u24453 \u36935 \u31561 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \u20363 \u22914 \u65292 \u20010 \u20154 \u25935 \u24863 \u20449 \u24687 \u21253 \u25324 \u36523 \u20221 \u35777 \u20214 \u21495 \u30721 \u12289 \u20010 \u20154 \u29983 \u29289 \u35782 \u21035 \u20449 \u24687 \u12289 \u38134 \u34892 \u36134 \u21495 \u12289 \u36890 \u20449 \u20869 \u23481 \u12289 \u20581 \u24247 \u29983 \u29702 \u20449 \u24687 \u31561 \u12290 \u25925 \u24744 \u24212 \u33258 \u34892 \u35880 \u24910 \u21028 \u26029 \u30830 \u23450 \u30456 \u20851 \u20449 \u24687 \u30340 \u30495 \u23454 \u24615 \u12289 \u21512 \u27861 \u24615 \u21644 \u26377 \u25928 \u24615 \u65292 \u24182 \u33258 \u34892 \u25215 \u25285 \u22240 \u27492 \u20135 \u29983 \u30340 \u36131 \u20219 \u19982 \u25439 \u22833 \u12290 \
|
||||||
|
\
|
||||||
|
1.3 \uc0\u21311 \u21517 \u21270 \u22788 \u29702 \u21518 \u30340 \u20449 \u24687 \u65292 \u21363 \u36890 \u36807 \u23545 \u20010 \u20154 \u20449 \u24687 \u30340 \u25216 \u26415 \u22788 \u29702 \u65292 \u20351 \u24471 \u20010 \u20154 \u20449 \u24687 \u20027 \u20307 \u26080 \u27861 \u34987 \u35782 \u21035 \u65292 \u19988 \u22788 \u29702 \u21518 \u19981 \u33021 \u34987 \u22797 \u21407 \u30340 \u20449 \u24687 \u65292 \u21311 \u21517 \u21270 \u22788 \u29702 \u21518 \u30340 \u20449 \u24687 \u19981 \u23646 \u20110 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
1.4 \uc0\u20854 \u20182 \u26080 \u27861 \u35782 \u21035 \u29305 \u23450 \u33258 \u28982 \u20154 \u36523 \u20221 \u25110 \u32773 \u21453 \u26144 \u29305 \u23450 \u33258 \u28982 \u20154 \u27963 \u21160 \u24773 \u20917 \u30340 \u20449 \u24687 \u19981 \u23646 \u20110 \u20010 \u20154 \u20449 \u24687 \u12290 \u38500 \u19978 \u36848 \u23450 \u20041 \u22806 \u65292 \u26412 \u25919 \u31574 \u25152 \u29992 \u20854 \u20182 \u26415 \u35821 \u19982 \u12298 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u26381 \u21153 \u21327 \u35758 \u12299 \u20013 \u30340 \u26415 \u35821 \u20855 \u26377 \u30456 \u21516 \u30340 \u28085 \u20041 \u12290 \u22914 \u24744 \u26377 \u38382 \u39064 \u65292 \u35831 \u32852 \u31995 \u25105 \u20204 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20108 \u12289 \u25105 \u20204 \u25910 \u38598 \u30340 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
2.1 \uc0\u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u21151 \u33021 \u20998 \u20026 \u26680 \u24515 \u21151 \u33021 \u21644 \u38468 \u21152 \u21151 \u33021 \u65292 \u25105 \u20204 \u23558 \u35814 \u32454 \u21521 \u24744 \u35828 \u26126 \u21508 \u19994 \u21153 \u21151 \u33021 \u25152 \u25910 \u38598 \u30340 \u20010 \u20154 \u20449 \u24687 \u20197 \u21450 \u25910 \u38598 \u26041 \u27861 \u12289 \u30446 \u30340 \u65292 \u25298 \u32477 \u25552 \u20379 \u30340 \u24433 \u21709 \u31561 \u12290 \u19994 \u21153 \u21151 \u33021 \u20855 \u20307 \u21253 \u25324 \u65306 \
|
||||||
|
\
|
||||||
|
2.1.1 \uc0\u26680 \u24515 \u21151 \u33021 \u65292 \u21253 \u25324 \u21019 \u24314 \u36134 \u21495 \u24182 \u23436 \u21892 \u36164 \u26009 \u12289 \u20250 \u35805 \u21151 \u33021 \u12289 \u21457 \u29616 \u21151 \u33021 \u12290 \
|
||||||
|
\
|
||||||
|
2.1.2 \uc0\u38468 \u21152 \u21151 \u33021 \u65292 \u21253 \u25324 \u20010 \u20154 \u20027 \u39029 \u12289 \u36523 \u20221 \u35748 \u35777 \u12290 \
|
||||||
|
\
|
||||||
|
2.2 \uc0\u24744 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u26680 \u24515 \u21151 \u33021 \u21069 \u65292 \u38656 \u35201 \u21019 \u24314 \u36134 \u21495 \u24182 \u23436 \u21892 \u20010 \u20154 \u36164 \u26009 \u12290 \u36890 \u36807 \u29992 \u25143 \u20027 \u21160 \u25552 \u20379 \u30340 \u26041 \u24335 \u65292 \u25105 \u20204 \u20250 \u25910 \u38598 \u24744 \u30340 \u20197 \u19979 \u20449 \u24687 \u65306 \
|
||||||
|
\
|
||||||
|
2.2.1 \uc0\u24744 \u38656 \u35201 \u21521 \u25105 \u20204 \u25552 \u20379 \u24744 \u30340 \u25163 \u26426 \u21495 \u30721 \u65292 \u24182 \u35774 \u32622 \u24744 \u22312 \u31508 \u22696 \u35759 \u20351 \u30340 \u29992 \u25143 \u23494 \u30721 \u12290 \u25163 \u26426 \u21495 \u30721 \u30830 \u23450 \u21518 \u65292 \u26242 \u26102 \u26080 \u27861 \u20462 \u25913 \u12290 \u22914 \u26524 \u24744 \u25298 \u32477 \u25552 \u20379 \u25163 \u26426 \u21495 \u30721 \u31508 \u22696 \u35759 \u20351 \u23558 \u26080 \u27861 \u20026 \u24744 \u21019 \u24314 \u36134 \u21495 \u24182 \u25552 \u20379 \u26381 \u21153 \u12290 \u21516 \u26102 \u65292 \u20026 \u20102 \u20445 \u35777 \u36719 \u20214 \u27491 \u24120 \u36816 \u34892 \u65292 \u25105 \u20204 \u23558 \u20250 \u37319 \u38598 \u24744 \u30340 \u35774 \u22791 \u20449 \u24687 \u65292 \u20855 \u20307 \u21253 \u25324 \u65306 iOS\u31995 \u32479 \u65306 SDK\u29256 \u26412 \u12289 \u35774 \u22791 \u29992 \u25143 \u21517 \u12289 \u25163 \u26426 \u22411 \u21495 \u12289 \u31995 \u32479 \u22411 \u21495 \u12289 \u38142 \u25509 \u30340 \u26080 \u32447 MAC\u22320 \u22336 \u12289 \u35774 \u22791 \u38543 \u26426 \u24207 \u21015 \u21495 \u12289 IMSI\u12289 SIM\u21345 \u22269 \u23478 \u12289 \u30913 \u30424 \u24635 \u31354 \u38388 \u12289 \u36816 \u34892 \u20869 \u23384 \u12289 \u30005 \u27744 \u30005 \u37327 \u12289 \u32593 \u32476 \u29615 \u22659 \u12289 \u36816 \u33829 \u21830 \u12289 \u31995 \u32479 \u29256 \u26412 \u12289 CPU\u22411 \u21495 \u12289 \u23631 \u24149 \u20998 \u36776 \u29575 \u12289 IMEI\u12289 \u25163 \u26426 \u21697 \u29260 \u12289 \u24179 \u21488 \u31867 \u22411 \u12289 \u35774 \u22791 \u24207 \u21015 \u21495 \u31561 \u12290 \
|
||||||
|
\
|
||||||
|
2.2.2 \uc0\u24744 \u20351 \u29992 \u20250 \u35805 \u21151 \u33021 \u36827 \u34892 \u35821 \u38899 \u36890 \u35805 \u12289 \u21457 \u36865 \u35821 \u38899 \u20449 \u24687 \u12289 \u25293 \u25668 \u21450 \u30456 \u20876 \u26102 \u65307 \u25105 \u20204 \u20250 \u35843 \u29992 \u24744 \u20197 \u19979 \u35774 \u22791 \u26435 \u38480 \u65306 \u35774 \u22791 \u40614 \u20811 \u39118 \u26435 \u38480 \u12289 \u31995 \u32479 \u30456 \u20876 \u26435 \u38480 \u12289 \u31995 \u32479 \u25668 \u20687 \u22836 \u26435 \u38480 \u12290 \u19978 \u36848 \u21151 \u33021 \u21487 \u33021 \u38656 \u35201 \u24744 \u22312 \u24744 \u30340 \u35774 \u22791 \u20013 \u21521 \u25105 \u20204 \u24320 \u21551 \u24744 \u30340 \u30456 \u26426 \u65288 \u25668 \u20687 \u22836 \u65289 \u12289 \u30456 \u20876 \u65288 \u22270 \u29255 \u24211 \u65289 \u12289 \u40614 \u20811 \u39118 \u20197 \u21450 \u36890 \u35759 \u24405 \u30340 \u35775 \u38382 \u26435 \u38480 \u65292 \u20197 \u23454 \u29616 \u36825 \u20123 \u21151 \u33021 \u25152 \u28041 \u21450 \u30340 \u20449 \u24687 \u30340 \u25910 \u38598 \u21644 \u20351 \u29992 \u12290 \u35831 \u24744 \u27880 \u24847 \u65292 \u24744 \u24320 \u21551 \u36825 \u20123 \u26435 \u38480 \u21363 \u20195 \u34920 \u24744 \u25480 \u26435 \u25105 \u20204 \u21487 \u20197 \u25910 \u38598 \u21644 \u20351 \u29992 \u36825 \u20123 \u20010 \u20154 \u20449 \u24687 \u26469 \u23454 \u29616 \u19978 \u36848 \u30340 \u21151 \u33021 \u65292 \u24744 \u20851 \u38381 \u26435 \u38480 \u21363 \u20195 \u34920 \u24744 \u21462 \u28040 \u20102 \u36825 \u20123 \u25480 \u26435 \u65292 \u21017 \u25105 \u20204 \u23558 \u19981 \u20877 \u32487 \u32493 \u25910 \u38598 \u21644 \u20351 \u29992 \u24744 \u30340 \u36825 \u20123 \u20010 \u20154 \u20449 \u24687 \u65292 \u20063 \u26080 \u27861 \u20026 \u24744 \u25552 \u20379 \u19978 \u36848 \u19982 \u36825 \u20123 \u25480 \u26435 \u25152 \u23545 \u24212 \u30340 \u21151 \u33021 \u12290 \u24744 \u20851 \u38381 \u26435 \u38480 \u30340 \u20915 \u23450 \u19981 \u20250 \u24433 \u21709 \u27492 \u21069 \u22522 \u20110 \u24744 \u30340 \u25480 \u26435 \u25152 \u36827 \u34892 \u30340 \u20010 \u20154 \u20449 \u24687 \u30340 \u22788 \u29702 \u12290 \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
2.3 \uc0\u20026 \u20102 \u25552 \u39640 \u24744 \u30340 \u31038 \u20132 \u23646 \u24615 \u65292 \u22312 \u31038 \u32676 \u20013 \u32467 \u23454 \u26356 \u22810 \u24535 \u21516 \u36947 \u21512 \u30340 \u26379 \u21451 \u65292 \u25105 \u20204 \u22312 \u20197 \u19979 \u38468 \u21152 \u21151 \u33021 \u20013 \u21487 \u33021 \u20250 \u25910 \u38598 \u21644 \u20351 \u29992 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \u22914 \u26524 \u24744 \u19981 \u25552 \u20379 \u36825 \u20123 \u20010 \u20154 \u20449 \u24687 \u65292 \u24744 \u20381 \u28982 \u21487 \u20197 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u30340 \u26680 \u24515 \u21151 \u33021 \u12290 \
|
||||||
|
\
|
||||||
|
2.3.1 \uc0\u24744 \u21487 \u20197 \u36873 \u25321 \u21521 \u25105 \u20204 \u25552 \u20379 \u26165 \u31216 \u12289 \u22995 \u21517 \u12289 \u24615 \u21035 \u12289 \u24180 \u40836 \u12289 \u25152 \u22312 \u22320 \u12289 \u34892 \u19994 \u12289 \u20844 \u21496 /\u26426 \u26500 \u12289 \u32844 \u19994 \u12290 \u24744 \u21487 \u20197 \u22312 \u20010 \u20154 \u20027 \u39029 \u36164 \u26009 \u20013 \u36873 \u25321 \u26159 \u21542 \u22635 \u20889 \u19978 \u36848 \u20449 \u24687 \u12290 \u22914 \u24744 \u25552 \u20379 \u19978 \u36848 \u20449 \u24687 \u65292 \u21487 \u20197 \u20351 \u20854 \u20182 \u29992 \u25143 \u23545 \u24744 \u26377 \u26356 \u20840 \u38754 \u30340 \u20102 \u35299 \u12290 \u24744 \u20063 \u21487 \u20197 \u22312 \u24744 \u30340 \u20010 \u20154 \u20027 \u39029 \u20013 \u23558 \u19978 \u36848 \u38544 \u31169 \u20107 \u39033 \u35774 \u32622 \u20026 \u25152 \u26377 \u20154 /\u20165 \u22909 \u21451 /\u20165 \u33258 \u24049 \u21487 \u35265 \u12290 \
|
||||||
|
\
|
||||||
|
2.4 \uc0\u24744 \u21487 \u20197 \u36873 \u25321 \u30003 \u35831 \u20010 \u20154 \u21152 V\u35748 \u35777 \u65292 \u30003 \u35831 \u21152 V\u35748 \u35777 \u24744 \u38656 \u35201 \u25552 \u20379 \u24744 \u30340 \u20010 \u20154 \u31616 \u20171 \u12289 \u26165 \u31216 \u12289 \u24182 \u19978 \u20256 \u32844 \u20301 \u12289 \u25216 \u33021 \u35777 \u26126 \u26448 \u26009 \u65292 \u21253 \u21547 \u22995 \u21517 \u12289 \u20844 \u21496 /\u32452 \u32455 \u20449 \u24687 \u12289 \u32844 \u20301 \u20449 \u24687 \u30340 \u21152 \u30422 \u20844 \u31456 \u30340 \u25130 \u22270 \u26448 \u26009 \u12289 \u20844 \u24320 \u21487 \u26597 \u30340 \u23448 \u26041 \u20010 \u20154 \u20449 \u24687 \u39029 \u25130 \u22270 \u26448 \u26009 \u12290 \u25104 \u20026 \u31508 \u22696 \u35759 \u20351 \u35748 \u35777 \u20250 \u21592 \u21487 \u20197 \u25552 \u21319 \u22312 \u31038 \u32676 \u30340 \u20010 \u20154 \u31038 \u20132 \u23646 \u24615 \u12290 \
|
||||||
|
\
|
||||||
|
2.5 \uc0\u20026 \u20102 \u24110 \u21161 \u24744 \u26356 \u22909 \u22320 \u20351 \u29992 \u25105 \u20204 \u30340 \u20135 \u21697 \u25110 \u26381 \u21153 \u65292 \u25105 \u20204 \u36824 \u20250 \u25910 \u38598 \u21253 \u25324 \u65306 \u24744 \u30340 \u22909 \u21451 \u21015 \u34920 \u12289 \u32676 \u21015 \u34920 \u20449 \u24687 \u12289 \u22768 \u32441 \u29305 \u24449 \u20540 \u20449 \u24687 \u12290 \u20026 \u30830 \u20445 \u24744 \u20351 \u29992 \u25105 \u20204 \u26381 \u21153 \u26102 \u33021 \u19982 \u24744 \u35748 \u35782 \u30340 \u20154 \u36827 \u34892 \u32852 \u31995 \u65292 \u22914 \u24744 \u36873 \u25321 \u24320 \u21551 \u23548 \u20837 \u36890 \u35759 \u24405 \u21151 \u33021 \u65292 \u25105 \u20204 \u21487 \u33021 \u23545 \u24744 \u32852 \u31995 \u20154 \u30340 \u22995 \u21517 \u21644 \u30005 \u35805 \u21495 \u30721 \u36827 \u34892 \u21152 \u23494 \u65292 \u24182 \u20165 \u25910 \u38598 \u21152 \u23494 \u21518 \u30340 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
2.6 \uc0\u25105 \u20204 \u21487 \u33021 \u20250 \u33719 \u24471 \u24744 \u22312 \u20351 \u29992 \u31532 \u19977 \u26041 \u21512 \u20316 \u20249 \u20276 \u26381 \u21153 \u26102 \u25152 \u20135 \u29983 \u25110 \u20998 \u20139 \u30340 \u20449 \u24687 \u12290 \u21253 \u25324 \u65306 \u24744 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u24080 \u25143 \u30331 \u24405 \u31532 \u19977 \u26041 \u21512 \u20316 \u20249 \u20276 \u26381 \u21153 \u26102 \u65292 \u25110 \u32773 \u24744 \u20351 \u29992 \u31532 \u19977 \u26041 \u21512 \u20316 \u20249 \u20276 \u26381 \u21153 \u36134 \u25143 \u30331 \u24405 \u31508 \u22696 \u35759 \u20351 \u26102 \u65292 \u25105 \u20204 \u20250 \u33719 \u24471 \u24744 \u30331 \u24405 \u31532 \u19977 \u26041 \u21512 \u20316 \u20249 \u20276 \u26381 \u21153 \u30340 \u21517 \u31216 \u12289 \u30331 \u24405 \u26102 \u38388 \u25110 \u30331 \u24405 \u31508 \u22696 \u35759 \u20351 \u30340 \u30331 \u24405 \u26102 \u38388 \u65292 \u26041 \u20415 \u24744 \u36827 \u34892 \u25480 \u26435 \u31649 \u29702 \u12290 \u35831 \u24744 \u20180 \u32454 \u38405 \u35835 \u31532 \u19977 \u26041 \u21512 \u20316 \u20249 \u20276 \u26381 \u21153 \u30340 \u29992 \u25143 \u21327 \u35758 \u25110 \u38544 \u31169 \u25919 \u31574 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u30340 \u20135 \u21697 \u22312 \u24212 \u29992 \u36816 \u34892 \u26399 \u38388 \u38656 \u35201 \u25910 \u38598 \u24744 \u30340 \u35774 \u22791 \u21807 \u19968 \u35782 \u21035 \u30721 \u65288 MAC\u22320 \u22336 \u21450 IMEI/IDFA\u12289 SIM \u21345 IMSI \u20449 \u24687 \u12289 OAID\u12289 ANDROID ID\u65289 \u20197 \u25552 \u20379 \u32479 \u35745 \u20998 \u26512 \u31561 \u26381 \u21153 \u65292 \u24182 \u36890 \u36807 \u24212 \u29992 \u21551 \u21160 \u25968 \u25454 \u21450 \u24322 \u24120 \u38169 \u35823 \u26085 \u24535 \u20998 \u26512 \u25913 \u36827 \u24615 \u33021 \u21644 \u29992 \u25143 \u20307 \u39564 \u65292 \u20026 \u29992 \u25143 \u25552 \u20379 \u26356 \u22909 \u30340 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
APP\uc0\u28041 \u21450 \u23884 \u20837 \u31532 \u19977 \u26041 \u20195 \u30721 \u12289 \u25554 \u20214 \u20256 \u36755 \u20010 \u20154 \u20449 \u24687 \u30340 \u24773 \u24418 \u36880 \u39033 \u21015 \u20030 \u22914 \u19979 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u33719 \u21462 \u35774 \u22791 \u30340 \u20256 \u24863 \u22120 \
|
||||||
|
\
|
||||||
|
\uc0\u29992 \u36884 \u65306 \u33719 \u21462 \u35774 \u22791 \u30340 \u20256 \u24863 \u22120 \u21015 \u34920 \u20026 \u20102 \u26816 \u27979 \u12289 \u38450 \u27490 \u23433 \u21331 \u27169 \u25311 \u22120 \u31561 \u19977 \u26041 \u27169 \u25311 \u22120 \u30340 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
Bugly SDK\
|
||||||
|
\
|
||||||
|
\uc0\u20027 \u20307 \u65306 \u28145 \u22323 \u24066 \u33150 \u35759 \u35745 \u31639 \u26426 \u31995 \u32479 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\
|
||||||
|
\uc0\u29992 \u36884 \u65306 \u24212 \u29992 \u23849 \u28291 \u38382 \u39064 \u25429 \u33719 \
|
||||||
|
\
|
||||||
|
\uc0\u25910 \u38598 \u30340 \u20010 \u20154 \u20449 \u24687 \u31867 \u22411 \u65306 \u30828 \u20214 \u22411 \u21495 \u12289 \u35774 \u22791 MAC\u22320 \u22336 \u12289 \u21807 \u19968 \u35774 \u22791 \u35782 \u21035 \u30721 \u65288 \u22914 IMEI/MEID/ ANDROID ID /SN/OPENUDID/GUID\u12289 SIM\u21345 IMSI\u20449 \u24687 \u22312 \u20869 \u30340 \u25551 \u36848 \u20010 \u20154 \u24120 \u29992 \u35774 \u22791 \u22522 \u26412 \u24773 \u20917 \u30340 \u20449 \u24687 \u65289 \u12289 \u35774 \u22791 \u22411 \u21495 \u12289 \u35774 \u22791 \u21046 \u36896 \u21830 \u12289 \u25805 \u20316 \u31995 \u32479 \u21450 \u20854 \u29256 \u26412 \u65307 \
|
||||||
|
\
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 \
|
||||||
|
\
|
||||||
|
https://privacy.qq.com/document/preview/fc748b3d96224fdb825ea79e132c1a56\
|
||||||
|
\
|
||||||
|
OPPO PUSH SDK\
|
||||||
|
\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u26631 \u35782 \u31526 \u65288 \u22914 IMEI\u12289 OAID\u12289 \u30828 \u20214 \u24207 \u21015 \u21495 /Serial\u12289 IMSI\u12289 Android ID\u12289 GAID/AAID\u65289 \u12289 \u24212 \u29992 \u20449 \u24687 \u12289 \u32593 \u32476 \u20449 \u24687 \u12289 IP\u22320 \u22336 \u12289 \u35774 \u22791 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 OPPO\u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u24191 \u19996 \u27426 \u22826 \u31185 \u25216 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://open.oppomobile.com/wiki/doc#id=10194\
|
||||||
|
\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://open.oppomobile.com/new/developmentDoc/info?id=11228\
|
||||||
|
\
|
||||||
|
VIVO PUSH SDK\
|
||||||
|
\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u20449 \u24687 \u12289 IMEI\u12289 OAID\u12289 GAID/AAID\u12289 Android ID\u12289 \u32593 \u32476 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 VIVO\u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u32500 \u27779 \u31227 \u21160 \u36890 \u20449 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://dev.vivo.com.cn/documentCenter/doc/366\
|
||||||
|
\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://dev.vivo.com.cn/documentCenter/doc/652\
|
||||||
|
\
|
||||||
|
\uc0\u21326 \u20026 PUSH SDK\
|
||||||
|
\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u24212 \u29992 \u22522 \u26412 \u20449 \u24687 \u12289 \u24212 \u29992 \u20869 \u35774 \u22791 \u26631 \u35782 \u31526 \u12289 \u35774 \u22791 \u30340 \u30828 \u20214 \u20449 \u24687 \u12289 \u36719 \u20214 \u21015 \u34920 \u12289 \u31995 \u32479 \u22522 \u26412 \u20449 \u24687 \u21644 \u31995 \u32479 \u35774 \u32622 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u21326 \u20026 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u21326 \u20026 \u36719 \u20214 \u25216 \u26415 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://developer.huawei.com/consumer/cn/doc/app/20213\
|
||||||
|
\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177\
|
||||||
|
\
|
||||||
|
hmscore-base-sdk\
|
||||||
|
\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u24212 \u29992 \u22522 \u26412 \u20449 \u24687 \u12289 \u24212 \u29992 \u20869 \u35774 \u22791 \u26631 \u35782 \u31526 \u12289 \u35774 \u22791 \u30340 \u30828 \u20214 \u20449 \u24687 \u12289 \u36719 \u20214 \u21015 \u34920 \u12289 \u31995 \u32479 \u22522 \u26412 \u20449 \u24687 \u21644 \u31995 \u32479 \u35774 \u32622 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u21326 \u20026 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u21326 \u20026 \u36719 \u20214 \u25216 \u26415 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://developer.huawei.com/consumer/cn/doc/app/20213\
|
||||||
|
\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177\
|
||||||
|
\
|
||||||
|
\uc0\u23567 \u31859 PUSH SDK\
|
||||||
|
\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u26631 \u35782 \u31526 \u65288 \u22914 Android ID\u12289 OAID\u65289 \u12289 \u24212 \u29992 \u20449 \u24687 \u12289 \u35774 \u22791 \u20449 \u24687 \u12289 \u32593 \u32476 \u20449 \u24687 \u65288 \u26412 \u22320 \u22788 \u29702 \u65289 \u12289 SSID\
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u23567 \u31859 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u21271 \u20140 \u23567 \u31859 \u31227 \u21160 \u36719 \u20214 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://dev.mi.com/console/appservice/push.html\
|
||||||
|
\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://dev.mi.com/console/doc/detail?pId=1822\
|
||||||
|
\
|
||||||
|
\uc0\u33635 \u32768 PUSH SDK\
|
||||||
|
\
|
||||||
|
\uc0\u28041 \u21450 \u20010 \u20154 \u20449 \u24687 \u65306 \u35774 \u22791 \u26631 \u35782 \u31526 (GAID/AAID)\u65292 \u24212 \u29992 Token\u12289 \u25512 \u36865 \u28040 \u24687 \u20869 \u23481 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u30446 \u30340 \u65306 \u25512 \u36865 \u28040 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u20351 \u29992 \u22330 \u26223 \u65306 \u22312 \u33635 \u32768 \u25163 \u26426 \u32456 \u31471 \u25512 \u36865 \u28040 \u24687 \u26102 \u20351 \u29992 \
|
||||||
|
\
|
||||||
|
\uc0\u31532 \u19977 \u26041 \u20027 \u20307 \u65306 \u33635 \u32768 \u32456 \u31471 \u26377 \u38480 \u20844 \u21496 \
|
||||||
|
\
|
||||||
|
\uc0\u25910 \u38598 \u26041 \u24335 \u65306 SDK\u33258 \u34892 \u37319 \u38598 \
|
||||||
|
\
|
||||||
|
\uc0\u23448 \u32593 \u38142 \u25509 \u65306 https://lbs.amap.com/\
|
||||||
|
\
|
||||||
|
\uc0\u38544 \u31169 \u25919 \u31574 \u65306 https://lbs.amap.com/pages/privacy/\
|
||||||
|
\
|
||||||
|
\uc0\u24744 \u25552 \u20379 \u30340 \u19978 \u36848 \u20449 \u24687 \u23558 \u22312 \u24744 \u20351 \u29992 \u26412 \u26381 \u21153 \u26399 \u38388 \u25345 \u32493 \u25480 \u26435 \u25105 \u20204 \u20351 \u29992 \u65292 \u20026 \u26041 \u20415 \u24744 \u31649 \u29702 \u36719 \u20214 \u36134 \u25143 \u65292 \u25105 \u20204 \u20250 \u22312 \u36719 \u20214 \u36134 \u25143 \u26381 \u21153 \u20013 \u21516 \u27493 \u24182 \u26174 \u31034 \u24744 \u30340 \u27880 \u20876 \u20449 \u24687 \u65292 \u21253 \u25324 \u36890 \u36807 \u36719 \u20214 \u36134 \u25143 \u38598 \u20013 \u23637 \u31034 \u24744 \u30340 \u20010 \u20154 \u36164 \u26009 \u12289 \u20139 \u21463 \u26435 \u30410 \u31561 \u12290 \u22312 \u24744 \u20027 \u21160 \u27880 \u38144 \u36134 \u21495 \u26102 \u65292 \u25105 \u20204 \u23558 \u26681 \u25454 \u36866 \u29992 \u27861 \u24459 \u27861 \u35268 \u30340 \u35201 \u27714 \u31435 \u21363 \u20351 \u20854 \u21311 \u21517 \u25110 \u21024 \u38500 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u19977 \u12289 \u25105 \u20204 \u22914 \u20309 \u20351 \u29992 \u25910 \u38598 \u30340 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u20005 \u26684 \u36981 \u23432 \u27861 \u24459 \u27861 \u35268 \u30340 \u35268 \u23450 \u21450 \u19982 \u29992 \u25143 \u30340 \u32422 \u23450 \u65292 \u23558 \u25910 \u38598 \u30340 \u20449 \u24687 \u29992 \u20110 \u20197 \u19979 \u29992 \u36884 \u12290 \u33509 \u25105 \u20204 \u36229 \u20986 \u20197 \u19979 \u29992 \u36884 \u20351 \u29992 \u24744 \u30340 \u20449 \u24687 \u65292 \u25105 \u20204 \u23558 \u20877 \u27425 \u21521 \u24744 \u36827 \u34892 \u35828 \u26126 \u65292 \u24182 \u24449 \u24471 \u24744 \u30340 \u21516 \u24847 \u12290 \
|
||||||
|
\
|
||||||
|
3.1 \uc0\u21521 \u24744 \u25552 \u20379 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
3.2 \uc0\u28385 \u36275 \u24744 \u30340 \u38656 \u27714 \u12290 \u20363 \u22914 \u65292 \u35821 \u35328 \u35774 \u23450 \u12289 \u20301 \u32622 \u35774 \u23450 \u12289 \u24110 \u21161 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
3.3 \uc0\u20135 \u21697 \u24320 \u21457 \u21644 \u26381 \u21153 \u20248 \u21270 \u12290 \u20363 \u22914 \u65292 \u24403 \u25105 \u20204 \u30340 \u31995 \u32479 \u21457 \u29983 \u25925 \u38556 \u26102 \u65292 \u25105 \u20204 \u20250 \u35760 \u24405 \u21644 \u20998 \u26512 \u31995 \u32479 \u25925 \u38556 \u26102 \u20135 \u29983 \u30340 \u20449 \u24687 \u65292 \u20248 \u21270 \u25105 \u20204 \u30340 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
3.4 \uc0\u23433 \u20840 \u20445 \u38556 \u12290 \u20363 \u22914 \u65292 \u25105 \u20204 \u20250 \u23558 \u24744 \u30340 \u20449 \u24687 \u29992 \u20110 \u36523 \u20221 \u39564 \u35777 \u12289 \u23433 \u20840 \u38450 \u33539 \u12289 \u21453 \u35784 \u39575 \u30417 \u27979 \u12289 \u23384 \u26723 \u22791 \u20221 \u12289 \u23458 \u25143 \u30340 \u23433 \u20840 \u26381 \u21153 \u31561 \u29992 \u36884 \u12290 \u20363 \u22914 \u65292 \u24744 \u19979 \u36733 \u25110 \u23433 \u35013 \u30340 \u23433 \u20840 \u36719 \u20214 \u20250 \u23545 \u24694 \u24847 \u31243 \u24207 \u25110 \u30149 \u27602 \u36827 \u34892 \u26816 \u27979 \u65292 \u25110 \u20026 \u24744 \u35782 \u21035 \u35784 \u39575 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
3.5 \uc0\u35780 \u20272 \u12289 \u25913 \u21892 \u25105 \u20204 \u30340 \u24191 \u21578 \u25237 \u25918 \u21644 \u20854 \u20182 \u20419 \u38144 \u21450 \u25512 \u24191 \u27963 \u21160 \u30340 \u25928 \u26524 \u12290 \
|
||||||
|
\
|
||||||
|
3.6 \uc0\u31649 \u29702 \u36719 \u20214 \u12290 \u20363 \u22914 \u65292 \u36827 \u34892 \u36719 \u20214 \u35748 \u35777 \u12289 \u36719 \u20214 \u21319 \u32423 \u31561 \u12290 \
|
||||||
|
\
|
||||||
|
3.7 \uc0\u36992 \u35831 \u24744 \u21442 \u19982 \u26377 \u20851 \u25105 \u20204 \u26381 \u21153 \u30340 \u35843 \u26597 \u12290 \u20026 \u20102 \u35753 \u24744 \u26377 \u26356 \u22909 \u30340 \u20307 \u39564 \u12289 \u25913 \u21892 \u25105 \u20204 \u30340 \u26381 \u21153 \u25110 \u32463 \u24744 \u21516 \u24847 \u30340 \u20854 \u20182 \u29992 \u36884 \u65292 \u22312 \u31526 \u21512 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u30340 \u21069 \u25552 \u19979 \u65292 \u25105 \u20204 \u21487 \u33021 \u23558 \u36890 \u36807 \u26576 \u20123 \u26381 \u21153 \u25152 \u25910 \u38598 \u30340 \u20449 \u24687 \u29992 \u20110 \u25105 \u20204 \u30340 \u20854 \u20182 \u26381 \u21153 \u12290 \u20363 \u22914 \u65292 \u23558 \u24744 \u22312 \u20351 \u29992 \u25105 \u20204 \u26576 \u39033 \u26381 \u21153 \u26102 \u30340 \u20449 \u24687 \u65292 \u29992 \u20110 \u29992 \u25143 \u30740 \u31350 \u20998 \u26512 \u19982 \u32479 \u35745 \u31561 \u26381 \u21153 \u12290 \u20026 \u20102 \u30830 \u20445 \u26381 \u21153 \u30340 \u23433 \u20840 \u65292 \u24110 \u21161 \u25105 \u20204 \u26356 \u22909 \u22320 \u20102 \u35299 \u25105 \u20204 \u24212 \u29992 \u31243 \u24207 \u30340 \u36816 \u34892 \u24773 \u20917 \u65292 \u25105 \u20204 \u21487 \u33021 \u35760 \u24405 \u30456 \u20851 \u20449 \u24687 \u65292 \u20363 \u22914 \u65292 \u24744 \u20351 \u29992 \u24212 \u29992 \u31243 \u24207 \u30340 \u39057 \u29575 \u12289 \u25925 \u38556 \u20449 \u24687 \u12289 \u24635 \u20307 \u20351 \u29992 \u24773 \u20917 \u12289 \u24615 \u33021 \u25968 \u25454 \u20197 \u21450 \u24212 \u29992 \u31243 \u24207 \u30340 \u26469 \u28304 \u12290 \u25105 \u20204 \u19981 \u20250 \u23558 \u25105 \u20204 \u23384 \u20648 \u22312 \u20998 \u26512 \u36719 \u20214 \u20013 \u30340 \u20449 \u24687 \u19982 \u24744 \u22312 \u24212 \u29992 \u31243 \u24207 \u20013 \u25552 \u20379 \u30340 \u20010 \u20154 \u36523 \u20221 \u20449 \u24687 \u30456 \u32467 \u21512 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u22235 \u12289 \u25105 \u20204 \u22914 \u20309 \u20849 \u20139 \u12289 \u36716 \u35753 \u12289 \u20844 \u24320 \u25259 \u38706 \u24744 \u30340 \u20449 \u24687 \
|
||||||
|
4.1 \uc0\u25105 \u20204 \u23558 \u36981 \u23432 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u65292 \u23545 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u20104 \u20197 \u20445 \u23494 \u12290 \u38500 \u20197 \u19979 \u24773 \u20917 \u22806 \u65292 \u25105 \u20204 \u19981 \u20250 \u21521 \u20854 \u20182 \u20154 \u20849 \u20139 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65306 \
|
||||||
|
A. \uc0\u21482 \u26377 \u20849 \u20139 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u25165 \u33021 \u25552 \u20379 \u24744 \u25152 \u38656 \u35201 \u30340 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
B. \uc0\u20026 \u20102 \u25552 \u21319 \u25105 \u20204 \u30340 \u20135 \u21697 \u21450 \u26381 \u21153 \u36136 \u37327 \u25110 \u21521 \u24744 \u25552 \u20379 \u20840 \u26032 \u30340 \u20135 \u21697 \u21450 \u26381 \u21153 \u65292 \u25105 \u20204 \u20250 \u22312 \u20851 \u32852 \u20844 \u21496 \u20869 \u37096 \u20849 \u20139 \u24744 \u30340 \u30456 \u20851 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
C. \uc0\u24744 \u36890 \u36807 \u31508 \u22696 \u35759 \u20351 \u36719 \u20214 \u20351 \u29992 \u31532 \u19977 \u26041 \u26381 \u21153 \u26102 \u65292 \u31508 \u22696 \u35759 \u20351 \u20250 \u25353 \u29031 \'93\u20010 \u20154 \u20449 \u24687 \u30340 \u25910 \u38598 \'94\u26465 \u27454 \u21015 \u26126 \u30340 \u20849 \u20139 \u20869 \u23481 \u19982 \u25552 \u20379 \u26381 \u21153 \u30340 \u31532 \u19977 \u26041 \u25110 \u21512 \u20316 \u20249 \u20276 \u65288 \u24191 \u21578 \u12289 \u20998 \u26512 \u26381 \u21153 \u31867 \u30340 \u25480 \u26435 \u21512 \u20316 \u20249 \u20276 \u12289 \u20379 \u24212 \u21830 \u12289 \u26381 \u21153 \u25552 \u20379 \u21830 \u21644 \u20854 \u20182 \u21512 \u20316 \u20249 \u20276 \u65289 \u20849 \u20139 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
D. \uc0\u20026 \u32500 \u25252 \u29992 \u25143 \u21512 \u27861 \u26435 \u30410 \u65292 \u22312 \u21327 \u21161 \u22788 \u29702 \u19982 \u24744 \u26377 \u20851 \u30340 \u32416 \u32439 \u25110 \u20105 \u35758 \u26102 \u65292 \u25105 \u20204 \u21487 \u33021 \u21521 \u19982 \u24744 \u23384 \u22312 \u21033 \u23475 \u20851 \u31995 \u30340 \u31532 \u19977 \u26041 \u25552 \u20379 \u35299 \u20915 \u32416 \u32439 \u25110 \u20105 \u35758 \u25152 \u24517 \u38656 \u30340 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
E. \uc0\u26681 \u25454 \u27861 \u24459 \u35268 \u23450 \u65292 \u21009 \u20107 \u20390 \u26597 \u26426 \u20851 \u20026 \u35843 \u26597 \u29359 \u32618 \u65292 \u20381 \u27861 \u23450 \u31243 \u24207 \u35843 \u21462 \u30340 \u24517 \u35201 \u20010 \u20154 \u20449 \u24687 \u65292 \u25110 \u34892 \u25919 \u26426 \u20851 \u12289 \u21496 \u27861 \u26426 \u26500 \u65292 \u20381 \u27861 \u23450 \u31243 \u24207 \u24182 \u32463 \u24744 \u25480 \u26435 \u21516 \u24847 \u35843 \u21462 \u30340 \u24517 \u35201 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
F. \uc0\u22312 \u27861 \u24459 \u35201 \u27714 \u25110 \u20801 \u35768 \u30340 \u33539 \u22260 \u20869 \u65292 \u20026 \u20102 \u20445 \u25252 \u31038 \u20250 \u20844 \u20849 \u21033 \u30410 \u12289 \u36130 \u20135 \u25110 \u23433 \u20840 \u32780 \u25552 \u20379 \u24517 \u35201 \u30340 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
G. \uc0\u22312 \u27861 \u23450 \u24773 \u24418 \u19979 \u30340 \u20849 \u20139 \u65306 \u25105 \u20204 \u21487 \u33021 \u20250 \u26681 \u25454 \u27861 \u24459 \u27861 \u35268 \u35268 \u23450 \u12289 \u35785 \u35772 \u20105 \u35758 \u35299 \u20915 \u38656 \u35201 \u65292 \u25110 \u25353 \u34892 \u25919 \u12289 \u21496 \u27861 \u26426 \u20851 \u20381 \u27861 \u25552 \u20986 \u30340 \u35201 \u27714 \u65292 \u23545 \u22806 \u20849 \u20139 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
H. \uc0\u21478 \u34892 \u33719 \u24471 \u24744 \u30340 \u26126 \u30830 \u21516 \u24847 \u25110 \u25480 \u26435 \u12290 \
|
||||||
|
\
|
||||||
|
4.2 \uc0\u38750 \u32463 \u27861 \u23450 \u31243 \u24207 \u25110 \u33719 \u24471 \u24744 \u30340 \u21516 \u24847 \u65292 \u25105 \u20204 \u19981 \u20250 \u23558 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u25552 \u20379 \u32473 \u20219 \u20309 \u31532 \u19977 \u26041 \u26426 \u26500 \u25110 \u20010 \u20154 \u12290 \u23545 \u25105 \u20204 \u19982 \u20043 \u20849 \u20139 \u20010 \u20154 \u20449 \u24687 \u30340 \u20844 \u21496 \u12289 \u32452 \u32455 \u21644 \u20010 \u20154 \u65292 \u25105 \u20204 \u20250 \u19982 \u20043 \u31614 \u32626 \u20005 \u26684 \u30340 \u20445 \u23494 \u21327 \u35758 \u65292 \u35201 \u27714 \u20182 \u20204 \u25353 \u29031 \u25105 \u20204 \u30340 \u35828 \u26126 \u12289 \u26412 \u38544 \u31169 \u25919 \u31574 \u21450 \u20854 \u20182 \u20219 \u20309 \u30456 \u20851 \u30340 \u20445 \u23494 \u21644 \u23433 \u20840 \u25514 \u26045 \u26469 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
4.3 \uc0\u25105 \u20204 \u23558 \u36981 \u23432 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u65292 \u23545 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u20104 \u20197 \u20445 \u23494 \u12290 \u38500 \u38750 \u20107 \u20808 \u33719 \u24471 \u24744 \u30340 \u26126 \u30830 \u21516 \u24847 \u25110 \u25480 \u26435 \u65292 \u25110 \u20381 \u29031 \u27861 \u24459 \u35268 \u23450 \u25152 \u24517 \u39035 \u65292 \u25105 \u20204 \u19981 \u20250 \u20844 \u24320 \u25259 \u38706 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
4.4 \uc0\u21478 \u22806 \u65292 \u26681 \u25454 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u21450 \u22269 \u23478 \u26631 \u20934 \u65292 \u20197 \u19979 \u24773 \u24418 \u20013 \u65292 \u25105 \u20204 \u21487 \u33021 \u20250 \u20849 \u20139 \u12289 \u36716 \u35753 \u12289 \u20844 \u24320 \u25259 \u38706 \u20010 \u20154 \u20449 \u24687 \u26080 \u38656 \u20107 \u20808 \u24449 \u24471 \u20010 \u20154 \u20449 \u24687 \u20027 \u20307 \u30340 \u25480 \u26435 \u21516 \u24847 \u65306 \
|
||||||
|
A. \uc0\u19982 \u22269 \u23478 \u23433 \u20840 \u12289 \u22269 \u38450 \u23433 \u20840 \u30452 \u25509 \u30456 \u20851 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
B. \uc0\u19982 \u20844 \u20849 \u23433 \u20840 \u12289 \u20844 \u20849 \u21355 \u29983 \u12289 \u37325 \u22823 \u20844 \u20849 \u21033 \u30410 \u30452 \u25509 \u30456 \u20851 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
C. \uc0\u19982 \u29359 \u32618 \u20390 \u26597 \u12289 \u36215 \u35785 \u12289 \u23457 \u21028 \u21644 \u21028 \u20915 \u25191 \u34892 \u31561 \u30452 \u25509 \u30456 \u20851 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
D. \uc0\u20986 \u20110 \u32500 \u25252 \u20010 \u20154 \u20449 \u24687 \u20027 \u20307 \u25110 \u20854 \u20182 \u20010 \u20154 \u30340 \u29983 \u21629 \u12289 \u36130 \u20135 \u31561 \u37325 \u22823 \u21512 \u27861 \u26435 \u30410 \u20294 \u21448 \u24456 \u38590 \u24471 \u21040 \u26412 \u20154 \u21516 \u24847 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
E. \uc0\u20010 \u20154 \u20449 \u24687 \u20027 \u20307 \u33258 \u34892 \u21521 \u31038 \u20250 \u20844 \u20247 \u20844 \u24320 \u30340 \u20010 \u20154 \u20449 \u24687 \u65307 \
|
||||||
|
\
|
||||||
|
F. \uc0\u20174 \u21512 \u27861 \u20844 \u24320 \u25259 \u38706 \u30340 \u20449 \u24687 \u20013 \u25910 \u38598 \u20010 \u20154 \u20449 \u24687 \u30340 \u65292 \u22914 \u21512 \u27861 \u30340 \u26032 \u38395 \u25253 \u36947 \u12289 \u25919 \u24220 \u20449 \u24687 \u20844 \u24320 \u31561 \u28192 \u36947 \u12290 \
|
||||||
|
\
|
||||||
|
4.5 \uc0\u22914 \u21457 \u29983 \u25910 \u36141 \u12289 \u20860 \u24182 \u12289 \u37325 \u32452 \u31561 \u21464 \u26356 \u65292 \u25105 \u20204 \u20250 \u35201 \u27714 \u21464 \u26356 \u21518 \u30340 \u20027 \u20307 \u20381 \u28982 \u36981 \u23432 \u26412 \u38544 \u31169 \u25919 \u31574 \u32422 \u23450 \u65292 \u23653 \u34892 \u21407 \u26377 \u36131 \u20219 \u21450 \u20041 \u21153 \u12290 \u22914 \u21464 \u26356 \u21518 \u30340 \u20027 \u20307 \u38656 \u21464 \u26356 \u20010 \u20154 \u20449 \u24687 \u20351 \u29992 \u30446 \u30340 \u65292 \u25105 \u20204 \u20250 \u35201 \u27714 \u20854 \u20107 \u20808 \u33719 \u24471 \u24744 \u30340 \u26126 \u31034 \u21516 \u24847 \u12290 \u23545 \u20869 \u32780 \u35328 \u65292 \u22312 \u20043 \u21069 \u30340 \u25910 \u36141 \u12289 \u20860 \u24182 \u27963 \u21160 \u20013 \u65292 \u23545 \u20110 \u34987 \u25910 \u36141 \u12289 \u34987 \u20860 \u24182 \u23545 \u35937 \u31649 \u29702 \u30340 \u25968 \u25454 (\u21253 \u25324 \u29992 \u25143 \u25968 \u25454 )\u22343 \u37319 \u29992 \u19982 \u31508 \u22696 \u35759 \u20351 \u33258 \u26377 \u25968 \u25454 \u30456 \u21516 \u30340 \u26631 \u20934 \u21644 \u35201 \u27714 \u36827 \u34892 \u22788 \u29702 \u21644 \u20445 \u25252 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20116 \u12289 \u25105 \u20204 \u22914 \u20309 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u20026 \u24744 \u30340 \u20449 \u24687 \u25552 \u20379 \u30456 \u24212 \u30340 \u23433 \u20840 \u20445 \u38556 \u65292 \u20197 \u38450 \u27490 \u20449 \u24687 \u30340 \u20002 \u22833 \u12289 \u19981 \u24403 \u20351 \u29992 \u12289 \u26410 \u32463 \u25480 \u26435 \u35775 \u38382 \u25110 \u25259 \u38706 \u12290 \
|
||||||
|
5.1 \uc0\u25105 \u20204 \u20005 \u26684 \u36981 \u23432 \u27861 \u24459 \u27861 \u35268 \u20445 \u25252 \u29992 \u25143 \u30340 \u36890 \u20449 \u31192 \u23494 \u12290 \
|
||||||
|
\
|
||||||
|
5.2 \uc0\u25105 \u20204 \u23558 \u22312 \u21512 \u29702 \u30340 \u23433 \u20840 \u27700 \u24179 \u20869 \u20351 \u29992 \u21508 \u31181 \u23433 \u20840 \u20445 \u25252 \u25514 \u26045 \u20197 \u20445 \u38556 \u20449 \u24687 \u30340 \u23433 \u20840 \u12290 \u20363 \u22914 \u65292 \u25105 \u20204 \u20351 \u29992 \u21152 \u23494 \u25216 \u26415 \u65288 \u20363 \u22914 \u65306 TLS\u12289 SSL\u65289 \u12289 \u21311 \u21517 \u21270 \u22788 \u29702 \u31561 \u25163 \u27573 \u26469 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
5.3 \uc0\u25105 \u20204 \u24314 \u31435 \u19987 \u38376 \u30340 \u31649 \u29702 \u21046 \u24230 \u12289 \u27969 \u31243 \u21644 \u32452 \u32455 \u30830 \u20445 \u20449 \u24687 \u23433 \u20840 \u12290 \u20363 \u22914 \u65292 \u25105 \u20204 \u20005 \u26684 \u38480 \u21046 \u35775 \u38382 \u20449 \u24687 \u30340 \u20154 \u21592 \u33539 \u22260 \u65292 \u35201 \u27714 \u20182 \u20204 \u36981 \u23432 \u20445 \u23494 \u20041 \u21153 \u65292 \u24182 \u36827 \u34892 \u23457 \u26597 \u12290 \
|
||||||
|
\
|
||||||
|
5.4 \uc0\u33509 \u21457 \u29983 \u20010 \u20154 \u20449 \u24687 \u27844 \u38706 \u31561 \u23433 \u20840 \u20107 \u20214 \u65292 \u25105 \u20204 \u20250 \u21551 \u21160 \u24212 \u24613 \u39044 \u26696 \u65292 \u38459 \u27490 \u23433 \u20840 \u20107 \u20214 \u25193 \u22823 \u65292 \u24182 \u20197 \u25512 \u36865 \u36890 \u30693 \u12289 \u20844 \u21578 \u31561 \u24418 \u24335 \u21578 \u30693 \u24744 \u12290 \
|
||||||
|
\
|
||||||
|
5.5 \uc0\u25105 \u20204 \u20250 \u37319 \u21462 \u19968 \u20999 \u21512 \u29702 \u21487 \u34892 \u30340 \u25514 \u26045 \u65292 \u30830 \u20445 \u26410 \u25910 \u38598 \u26080 \u20851 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \u25105 \u20204 \u21482 \u20250 \u22312 \u36798 \u25104 \u26412 \u38544 \u31169 \u25919 \u31574 \u25152 \u36848 \u30446 \u30340 \u25152 \u38656 \u30340 \u26399 \u38480 \u20869 \u20445 \u30041 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u38500 \u38750 \u38656 \u35201 \u24310 \u38271 \u20445 \u30041 \u26399 \u25110 \u21463 \u21040 \u27861 \u24459 \u30340 \u20801 \u35768 \u12290 \
|
||||||
|
\
|
||||||
|
5.6 \uc0\u20114 \u32852 \u32593 \u24182 \u38750 \u32477 \u23545 \u23433 \u20840 \u30340 \u29615 \u22659 \u65292 \u32780 \u19988 \u30005 \u23376 \u37038 \u20214 \u12289 \u21363 \u26102 \u36890 \u35759 \u12289 \u31038 \u20132 \u36719 \u20214 \u31561 \u19982 \u20854 \u20182 \u29992 \u25143 \u30340 \u20132 \u27969 \u26041 \u24335 \u26080 \u27861 \u30830 \u23450 \u26159 \u21542 \u23436 \u20840 \u21152 \u23494 \u65292 \u25105 \u20204 \u24314 \u35758 \u24744 \u20351 \u29992 \u27492 \u31867 \u24037 \u20855 \u26102 \u35831 \u20351 \u29992 \u22797 \u26434 \u23494 \u30721 \u65292 \u24182 \u27880 \u24847 \u20445 \u25252 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u23433 \u20840 \u12290 \
|
||||||
|
\
|
||||||
|
5.7 \uc0\u20114 \u32852 \u32593 \u29615 \u22659 \u24182 \u38750 \u30334 \u20998 \u20043 \u30334 \u23433 \u20840 \u65292 \u25105 \u20204 \u23558 \u23613 \u21147 \u30830 \u20445 \u25110 \u25285 \u20445 \u24744 \u21457 \u36865 \u32473 \u25105 \u20204 \u30340 \u20219 \u20309 \u20449 \u24687 \u30340 \u23433 \u20840 \u24615 \u12290 \u22914 \u26524 \u25105 \u20204 \u30340 \u29289 \u29702 \u12289 \u25216 \u26415 \u12289 \u25110 \u31649 \u29702 \u38450 \u25252 \u35774 \u26045 \u36973 \u21040 \u30772 \u22351 \u65292 \u33268 \u20449 \u24687 \u34987 \u38750 \u25480 \u26435 \u35775 \u38382 \u12289 \u20844 \u24320 \u25259 \u38706 \u12289 \u31713 \u25913 \u12289 \u25110 \u27585 \u22351 \u65292 \u23548 \u33268 \u24744 \u30340 \u21512 \u27861 \u26435 \u30410 \u21463 \u25439 \u65292 \u25105 \u20204 \u23558 \u25215 \u25285 \u30456 \u24212 \u30340 \u27861 \u24459 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20845 \u12289 \u25105 \u20204 \u22914 \u20309 \u20445 \u23384 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
6.1 \uc0\u23384 \u20648 \u20449 \u24687 \u30340 \u22320 \u28857 \u65306 \u25105 \u20204 \u20250 \u25353 \u29031 \u27861 \u24459 \u27861 \u35268 \u35268 \u23450 \u65292 \u23558 \u22659 \u20869 \u25910 \u38598 \u30340 \u29992 \u25143 \u20010 \u20154 \u20449 \u24687 \u23384 \u20648 \u20110 \u20013 \u22269 \u22659 \u20869 \u12290 \u22914 \u28041 \u21450 \u21521 \u22659 \u22806 \u20256 \u36755 \u20010 \u20154 \u20449 \u24687 \u65292 \u25105 \u20204 \u23558 \u26126 \u30830 \u21521 \u24744 \u21578 \u30693 \u20010 \u20154 \u20449 \u24687 \u20986 \u22659 \u30340 \u30446 \u30340 \u12289 \u25509 \u25910 \u26041 \u12289 \u23433 \u20840 \u20445 \u38556 \u25514 \u26045 \u31561 \u24773 \u20917 \u65292 \u24182 \u21478 \u34892 \u24449 \u24471 \u24744 \u30340 \u21516 \u24847 \u12290 \
|
||||||
|
\
|
||||||
|
6.2 \uc0\u23384 \u20648 \u20449 \u24687 \u30340 \u26399 \u38480 \u19968 \u33324 \u32780 \u35328 \u65292 \u25105 \u20204 \u20165 \u20026 \u23454 \u29616 \u30446 \u30340 \u25152 \u24517 \u38656 \u30340 \u26368 \u30701 \u26102 \u38388 \u20445 \u30041 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u38500 \u38750 \u27861 \u24459 \u26377 \u24378 \u21046 \u30340 \u30041 \u23384 \u35201 \u27714 \u12290 \u20294 \u22312 \u19979 \u21015 \u24773 \u20917 \u19979 \u65292 \u25105 \u20204 \u26377 \u21487 \u33021 \u22240 \u38656 \u31526 \u21512 \u27861 \u24459 \u35201 \u27714 \u65292 \u26356 \u25913 \u20010 \u20154 \u20449 \u24687 \u30340 \u23384 \u20648 \u26102 \u38388 \u65306 \
|
||||||
|
A. \uc0\u20026 \u36981 \u23432 \u36866 \u29992 \u30340 \u27861 \u24459 \u27861 \u35268 \u31561 \u26377 \u20851 \u35268 \u23450 \u65307 \
|
||||||
|
\
|
||||||
|
B. \uc0\u20026 \u36981 \u23432 \u27861 \u38498 \u21028 \u20915 \u12289 \u35009 \u23450 \u25110 \u20854 \u20182 \u27861 \u24459 \u31243 \u24207 \u30340 \u35268 \u23450 \u65307 \
|
||||||
|
\
|
||||||
|
C. \uc0\u20026 \u36981 \u23432 \u30456 \u20851 \u25919 \u24220 \u26426 \u20851 \u25110 \u27861 \u23450 \u25480 \u26435 \u32452 \u32455 \u30340 \u35201 \u27714 \u65307 \
|
||||||
|
\
|
||||||
|
D. \uc0\u25105 \u20204 \u26377 \u29702 \u30001 \u30830 \u20449 \u38656 \u35201 \u36981 \u23432 \u27861 \u24459 \u27861 \u35268 \u31561 \u26377 \u20851 \u35268 \u23450 \u65307 \
|
||||||
|
\
|
||||||
|
E. \uc0\u20026 \u25191 \u34892 \u30456 \u20851 \u26381 \u21153 \u21327 \u35758 \u25110 \u26412 \u25919 \u31574 \u12289 \u32500 \u25252 \u31038 \u20250 \u20844 \u20849 \u21033 \u30410 \u65292 \u20026 \u20445 \u25252 \u25105 \u20204 \u30340 \u23458 \u25143 \u12289 \u25105 \u20204 \u25110 \u25105 \u20204 \u30340 \u20851 \u32852 \u20844 \u21496 \u12289 \u20854 \u20182 \u29992 \u25143 \u25110 \u38599 \u21592 \u30340 \u20154 \u36523 \u36130 \u20135 \u23433 \u20840 \u25110 \u20854 \u20182 \u21512 \u27861 \u26435 \u30410 \u25152 \u21512 \u29702 \u24517 \u38656 \u30340 \u29992 \u36884 \u12290 \
|
||||||
|
\
|
||||||
|
6.3 \uc0\u35831 \u24744 \u27880 \u24847 \u65292 \u24744 \u22312 \u20351 \u29992 \u25105 \u20204 \u30340 \u26381 \u21153 \u26399 \u38388 \u65292 \u25105 \u20204 \u20165 \u22312 \u27861 \u24459 \u27861 \u35268 \u35268 \u23450 \u12289 \u30417 \u31649 \u35201 \u27714 \u21450 \u20026 \u23454 \u29616 \u26412 \u26465 \u27454 \u22768 \u26126 \u30340 \u30446 \u30340 \u25152 \u24517 \u38656 \u30340 \u26102 \u38480 \u20869 \u20445 \u30041 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u22312 \u24744 \u27880 \u38144 \u36134 \u21495 \u21518 \u65292 \u25105 \u20204 \u20165 \u22312 \u27861 \u24459 \u27861 \u35268 \u35268 \u23450 \u12289 \u30417 \u31649 \u35201 \u27714 \u30340 \u26399 \u38480 \u20869 \u20445 \u30041 \u20010 \u20154 \u20449 \u24687 \u65292 \u19988 \u19981 \u20250 \u24320 \u23637 \u38500 \u23384 \u20648 \u21644 \u37319 \u21462 \u24517 \u35201 \u30340 \u23433 \u20840 \u20445 \u25252 \u25514 \u26045 \u20043 \u22806 \u30340 \u22788 \u29702 \u27963 \u21160 \u65292 \u20294 \u24050 \u32463 \u21311 \u21517 \u21270 \u22788 \u29702 \u21518 \u30340 \u20010 \u20154 \u20449 \u24687 \u38500 \u22806 \u12290 \u24403 \u24744 \u25104 \u21151 \u27880 \u38144 \u31508 \u22696 \u35759 \u20351 \u36134 \u25143 \u25110 \u36229 \u20986 \u20445 \u30041 \u26399 \u38388 \u21518 \u65292 \u25105 \u20204 \u23558 \u23545 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u36827 \u34892 \u21024 \u38500 \u25110 \u21311 \u21517 \u21270 \u22788 \u29702 \u12290 \
|
||||||
|
\
|
||||||
|
6.4 \uc0\u24403 \u25105 \u20204 \u30340 \u20135 \u21697 \u25110 \u26381 \u21153 \u21457 \u29983 \u20572 \u27490 \u36816 \u33829 \u30340 \u24773 \u24418 \u26102 \u65292 \u25105 \u20204 \u23558 \u37319 \u21462 \u20363 \u22914 \u65292 \u25512 \u36865 \u36890 \u30693 \u12289 \u20844 \u21578 \u31561 \u24418 \u24335 \u36890 \u30693 \u24744 \u65292 \u24182 \u22312 \u21512 \u29702 \u30340 \u26399 \u38480 \u20869 \u21024 \u38500 \u25110 \u21311 \u21517 \u21270 \u22788 \u29702 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u19971 \u12289 \u25105 \u20204 \u22914 \u20309 \u20351 \u29992 Cookie\u21450 \u21516 \u31867 \u25216 \u26415 \
|
||||||
|
\
|
||||||
|
7.1 \uc0\u20026 \u23454 \u29616 \u24744 \u32852 \u26426 \u20307 \u39564 \u38656 \u27714 \u65292 \u20351 \u24744 \u33719 \u24471 \u26356 \u36731 \u26494 \u30340 \u35775 \u38382 \u20307 \u39564 \u12290 \u25105 \u20204 \u20250 \u22312 \u24744 \u30340 \u35745 \u31639 \u26426 \u25110 \u31227 \u21160 \u35774 \u22791 \u19978 \u21457 \u36865 \u19968 \u20010 \u25110 \u22810 \u20010 \u21517 \u20026 Cookies\u30340 \u23567 \u25968 \u25454 \u25991 \u20214 \u65292 \u25351 \u23450 \u32473 \u24744 \u30340 Cookies \u26159 \u21807 \u19968 \u30340 \u65292 \u23427 \u21482 \u33021 \u34987 \u23558 Cookies\u21457 \u24067 \u32473 \u24744 \u30340 \u22495 \u20013 \u30340 Web\u26381 \u21153 \u22120 \u35835 \u21462 \u12290 \u25105 \u20204 \u21521 \u24744 \u21457 \u36865 Cookies\u26159 \u20026 \u20102 \u31616 \u21270 \u24744 \u37325 \u22797 \u30331 \u24405 \u30340 \u27493 \u39588 \u12289 \u23384 \u20648 \u24744 \u30340 \u20559 \u22909 \u25968 \u25454 \u36827 \u32780 \u24110 \u21161 \u21028 \u26029 \u24744 \u30340 \u30331 \u24405 \u29366 \u24577 \u20197 \u21450 \u36134 \u25143 \u25110 \u25968 \u25454 \u23433 \u20840 \u12290 \
|
||||||
|
\
|
||||||
|
7.2 \uc0\u25105 \u20204 \u19981 \u20250 \u23558 Cookies \u29992 \u20110 \u26412 \u38544 \u31169 \u25919 \u31574 \u25152 \u36848 \u30446 \u30340 \u20043 \u22806 \u30340 \u20219 \u20309 \u29992 \u36884 \u12290 \u24744 \u21487 \u26681 \u25454 \u33258 \u24049 \u30340 \u20559 \u22909 \u31649 \u29702 \u25110 \u21024 \u38500 Cookies\u12290 \u21478 \u22806 \u65292 \u24744 \u20063 \u21487 \u20197 \u28165 \u38500 \u36719 \u20214 \u20869 \u20445 \u23384 \u30340 \u25152 \u26377 Cookies\u12290 \u20294 \u22914 \u26524 \u24744 \u36825 \u20040 \u20570 \u65292 \u24744 \u21487 \u33021 \u38656 \u35201 \u22312 \u27599 \u19968 \u27425 \u35775 \u38382 \u36719 \u20214 \u26102 \u20146 \u33258 \u26356 \u25913 \u29992 \u25143 \u35774 \u32622 \u65292 \u32780 \u19988 \u24744 \u20043 \u21069 \u25152 \u35760 \u24405 \u30340 \u30456 \u24212 \u20449 \u24687 \u20063 \u22343 \u20250 \u34987 \u21024 \u38500 \u65292 \u24182 \u19988 \u21487 \u33021 \u20250 \u23545 \u24744 \u25152 \u20351 \u29992 \u26381 \u21153 \u30340 \u23433 \u20840 \u24615 \u26377 \u19968 \u23450 \u24433 \u21709 \u12290 \
|
||||||
|
\
|
||||||
|
7.3 \uc0\u32593 \u32476 Beacon\u21644 \u21516 \u31867 \u25216 \u26415 \u30340 \u20351 \u29992 \u38500 Cookies \u22806 \u65292 \u25105 \u20204 \u36824 \u20250 \u22312 \u32593 \u31449 \u19978 \u20351 \u29992 \u32593 \u32476 Beacon\u31561 \u20854 \u20182 \u21516 \u31867 \u25216 \u26415 \u12290 \u25105 \u20204 \u30340 \u32593 \u39029 \u19978 \u24120 \u20250 \u21253 \u21547 \u19968 \u20123 \u30005 \u23376 \u22270 \u20687 \u65288 \u31216 \u20026 "\u21333 \u20687 \u32032 " GIF \u25991 \u20214 \u25110 "\u32593 \u32476 Beacon"\u65289 \u12290 \u20351 \u29992 \u32593 \u32476 Beacon\u21487 \u20197 \u35745 \u31639 \u27983 \u35272 \u32593 \u39029 \u30340 \u29992 \u25143 \u25110 \u35775 \u38382 \u26576 \u20123 Cookies\u65292 \u24182 \u36890 \u36807 \u24471 \u21040 \u30340 Cookies\u20449 \u24687 \u65292 \u20026 \u24744 \u25552 \u20379 \u26381 \u21153 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20843 \u12289 \u24744 \u22914 \u20309 \u31649 \u29702 \u33258 \u24049 \u30340 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
\uc0\u24744 \u21487 \u20197 \u36890 \u36807 \u20197 \u19979 \u26041 \u24335 \u35775 \u38382 \u21450 \u31649 \u29702 \u24744 \u30340 \u20449 \u24687 \u65306 \
|
||||||
|
\
|
||||||
|
8.1 \uc0\u26597 \u35810 \u12289 \u26356 \u27491 \u21644 \u34917 \u20805 \u24744 \u30340 \u20449 \u24687 \u24744 \u26377 \u26435 \u26597 \u35810 \u12289 \u26356 \u27491 \u25110 \u34917 \u20805 \u24744 \u30340 \u20449 \u24687 \u12290 \u24744 \u21487 \u20197 \u36890 \u36807 \u20197 \u19979 \u26041 \u24335 \u33258 \u34892 \u36827 \u34892 \u65306 \u30331 \u24405 \u31508 \u22696 \u35759 \u20351 \u23458 \u25143 \u31471 \u65292 \u36827 \u20837 \'93\u25105 \u30340 \'94\u65292 \u28857 \u20987 \u29992 \u25143 \u21517 \u23545 \u20010 \u20154 \u36164 \u26009 \u12289 \u22522 \u26412 \u20449 \u24687 \u12289 \u35748 \u35777 \u20449 \u24687 \u12289 \u20010 \u20154 \u36164 \u26009 \u31561 \u36827 \u34892 \u26597 \u35810 \u12289 \u26356 \u27491 \u25110 \u34917 \u20805 \u65307 \
|
||||||
|
\
|
||||||
|
8.2 \uc0\u21024 \u38500 \u24744 \u30340 \u20449 \u24687 \u24744 \u21487 \u20197 \u36890 \u36807 \'938.1\u26597 \u35810 \u12289 \u26356 \u27491 \u21644 \u34917 \u20805 \u24744 \u30340 \u20449 \u24687 \'94\u20013 \u21015 \u26126 \u30340 \u26041 \u24335 \u21024 \u38500 \u24744 \u30340 \u37096 \u20998 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u22312 \u20197 \u19979 \u24773 \u24418 \u20013 \u65292 \u24744 \u21487 \u20197 \u21521 \u25105 \u20204 \u25552 \u20986 \u21024 \u38500 \u20010 \u20154 \u20449 \u24687 \u30340 \u35831 \u27714 \u65306 \
|
||||||
|
\
|
||||||
|
A. \uc0\u22914 \u26524 \u25105 \u20204 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u30340 \u34892 \u20026 \u36829 \u21453 \u27861 \u24459 \u27861 \u35268 \u65307 \
|
||||||
|
\
|
||||||
|
B. \uc0\u22914 \u26524 \u25105 \u20204 \u25910 \u38598 \u12289 \u20351 \u29992 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u21364 \u26410 \u24449 \u24471 \u24744 \u30340 \u26126 \u30830 \u21516 \u24847 \u65307 \
|
||||||
|
\
|
||||||
|
C. \uc0\u22914 \u26524 \u25105 \u20204 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u30340 \u34892 \u20026 \u20005 \u37325 \u36829 \u21453 \u20102 \u19982 \u24744 \u30340 \u32422 \u23450 \u65307 \
|
||||||
|
\
|
||||||
|
D. \uc0\u22914 \u26524 \u24744 \u19981 \u20877 \u20351 \u29992 \u25105 \u20204 \u30340 \u20135 \u21697 \u25110 \u26381 \u21153 \u65292 \u25110 \u24744 \u20027 \u21160 \u27880 \u38144 \u20102 \u36134 \u21495 \u65307 \
|
||||||
|
\
|
||||||
|
E. \uc0\u22914 \u26524 \u25105 \u20204 \u27704 \u20037 \u19981 \u20877 \u20026 \u24744 \u25552 \u20379 \u20135 \u21697 \u25110 \u26381 \u21153 \u12290 \
|
||||||
|
\uc0\u33509 \u25105 \u20204 \u20915 \u23450 \u21709 \u24212 \u24744 \u30340 \u21024 \u38500 \u35831 \u27714 \u65292 \u25105 \u20204 \u36824 \u23558 \u21516 \u26102 \u23613 \u21487 \u33021 \u36890 \u30693 \u20174 \u25105 \u20204 \u22788 \u33719 \u24471 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u30340 \u20027 \u20307 \u65292 \u24182 \u35201 \u27714 \u20854 \u21450 \u26102 \u21024 \u38500 \u65288 \u38500 \u38750 \u27861 \u24459 \u27861 \u35268 \u21478 \u26377 \u35268 \u23450 \u65292 \u25110 \u36825 \u20123 \u20027 \u20307 \u24050 \u29420 \u31435 \u33719 \u24471 \u24744 \u30340 \u25480 \u26435 \u65289 \u12290 \u24403 \u24744 \u25110 \u25105 \u20204 \u21327 \u21161 \u24744 \u21024 \u38500 \u30456 \u20851 \u20449 \u24687 \u21518 \u65292 \u22240 \u20026 \u36866 \u29992 \u30340 \u27861 \u24459 \u21644 \u23433 \u20840 \u25216 \u26415 \u65292 \u25105 \u20204 \u21487 \u33021 \u26080 \u27861 \u31435 \u21363 \u20174 \u22791 \u20221 \u31995 \u32479 \u20013 \u21024 \u38500 \u30456 \u24212 \u30340 \u20449 \u24687 \u65292 \u25105 \u20204 \u23558 \u23433 \u20840 \u22320 \u23384 \u20648 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u24182 \u23558 \u20854 \u19982 \u20219 \u20309 \u36827 \u19968 \u27493 \u22788 \u29702 \u38548 \u31163 \u65292 \u30452 \u21040 \u22791 \u20221 \u21487 \u20197 \u28165 \u38500 \u25110 \u23454 \u29616 \u21311 \u21517 \u12290 \
|
||||||
|
\
|
||||||
|
8.3 \uc0\u25913 \u21464 \u24744 \u25480 \u26435 \u21516 \u24847 \u30340 \u33539 \u22260 \
|
||||||
|
\
|
||||||
|
\uc0\u27599 \u20010 \u19994 \u21153 \u21151 \u33021 \u38656 \u35201 \u19968 \u20123 \u22522 \u26412 \u30340 \u20010 \u20154 \u20449 \u24687 \u25165 \u33021 \u24471 \u20197 \u23436 \u25104 \u65288 \u35265 \u26412 \u38544 \u31169 \u25919 \u31574 \'93\u31532 \u19968 \u26465 \u25105 \u20204 \u25910 \u38598 \u30340 \u20449 \u24687 \'94\u65289 \u12290 \u38500 \u27492 \u20043 \u22806 \u65292 \u24744 \u21487 \u20197 \u22312 \u31508 \u22696 \u35759 \u20351 \u23458 \u25143 \u31471 \'93\u25105 \u30340 -\u35774 \u32622 -\u38544 \u31169 \u35774 \u32622 \'94\u20013 \u35774 \u32622 \u25110 \u25913 \u21464 \u24744 \u30340 \u26234 \u33021 \u31227 \u21160 \u35774 \u22791 \u30340 \u35774 \u32622 \u31561 \u26041 \u24335 \u32473 \u20104 \u25110 \u25910 \u22238 \u24744 \u30340 \u25480 \u26435 \u21516 \u24847 \u30340 \u33539 \u22260 \u12290 \u24403 \u24744 \u25910 \u22238 \u21516 \u24847 \u21518 \u65292 \u25105 \u20204 \u23558 \u19981 \u20877 \u22788 \u29702 \u30456 \u24212 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \u20294 \u24744 \u25910 \u22238 \u21516 \u24847 \u30340 \u20915 \u23450 \u65292 \u19981 \u20250 \u24433 \u21709 \u27492 \u21069 \u22522 \u20110 \u24744 \u30340 \u25480 \u26435 \u32780 \u24320 \u23637 \u30340 \u20010 \u20154 \u20449 \u24687 \u22788 \u29702 \u12290 \
|
||||||
|
\
|
||||||
|
8.4 \uc0\u27880 \u38144 \u24744 \u30340 \u36134 \u25143 \
|
||||||
|
\
|
||||||
|
\uc0\u24744 \u21487 \u20197 \u36890 \u36807 \u20197 \u19979 \u26041 \u24335 \u30003 \u35831 \u27880 \u38144 \u24744 \u30340 \u36134 \u25143 \u65306 \
|
||||||
|
\
|
||||||
|
\uc0\u30331 \u24405 \u31508 \u22696 \u35759 \u20351 \u23448 \u32593 \u24182 \u36873 \u25321 \u32852 \u31995 \u23458 \u26381 \u23547 \u27714 \u24110 \u21161 \u65292 \u21327 \u21161 \u24744 \u30003 \u35831 \u27880 \u38144 \u24744 \u30340 \u36134 \u25143 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u22312 \u24744 \u20027 \u21160 \u27880 \u38144 \u36134 \u25143 \u20043 \u21518 \u65292 \u25105 \u20204 \u23558 \u20572 \u27490 \u20026 \u24744 \u25552 \u20379 \u20135 \u21697 \u25110 \u26381 \u21153 \u65292 \u26681 \u25454 \u36866 \u29992 \u27861 \u24459 \u30340 \u35201 \u27714 \u21024 \u38500 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u25110 \u20351 \u20854 \u21311 \u21517 \u21270 \u22788 \u29702 \u12290 \
|
||||||
|
\
|
||||||
|
8.5 \uc0\u32422 \u26463 \u20449 \u24687 \u31995 \u32479 \u33258 \u21160 \u20915 \u31574 \
|
||||||
|
\
|
||||||
|
\uc0\u22312 \u26576 \u20123 \u19994 \u21153 \u21151 \u33021 \u20013 \u65292 \u25105 \u20204 \u21487 \u33021 \u20165 \u20381 \u25454 \u20449 \u24687 \u31995 \u32479 \u12289 \u31639 \u27861 \u31561 \u22312 \u20869 \u30340 \u38750 \u20154 \u24037 \u33258 \u21160 \u20915 \u31574 \u26426 \u21046 \u20570 \u20986 \u20915 \u23450 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u22914 \u26524 \u36825 \u20123 \u20915 \u23450 \u26174 \u33879 \u24433 \u21709 \u24744 \u30340 \u21512 \u27861 \u26435 \u30410 \u65292 \u24744 \u26377 \u26435 \u35201 \u27714 \u25105 \u20204 \u20570 \u20986 \u35299 \u37322 \u65292 \u25105 \u20204 \u20063 \u23558 \u22312 \u19981 \u20405 \u23475 \u31508 \u22696 \u35759 \u20351 \u21830 \u19994 \u31192 \u23494 \u25110 \u20854 \u20182 \u29992 \u25143 \u26435 \u30410 \u12289 \u31038 \u20250 \u20844 \u20849 \u21033 \u30410 \u30340 \u21069 \u25552 \u19979 \u25552 \u20379 \u30003 \u35785 \u26041 \u27861 \u12290 \
|
||||||
|
\
|
||||||
|
8.6 \uc0\u21709 \u24212 \u24744 \u30340 \u19978 \u36848 \u35831 \u27714 \
|
||||||
|
\
|
||||||
|
\uc0\u20026 \u20445 \u38556 \u23433 \u20840 \u65292 \u24744 \u21487 \u33021 \u38656 \u35201 \u25552 \u20379 \u20070 \u38754 \u35831 \u27714 \u65292 \u25110 \u20197 \u20854 \u20182 \u26041 \u24335 \u35777 \u26126 \u24744 \u30340 \u36523 \u20221 \u12290 \u25105 \u20204 \u21487 \u33021 \u20250 \u20808 \u35201 \u27714 \u24744 \u39564 \u35777 \u33258 \u24049 \u30340 \u36523 \u20221 \u65292 \u28982 \u21518 \u20877 \u22788 \u29702 \u24744 \u30340 \u35831 \u27714 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u23558 \u22312 15\u22825 \u20869 \u20570 \u20986 \u31572 \u22797 \u12290 \u22914 \u24744 \u19981 \u28385 \u24847 \u65292 \u36824 \u21487 \u20197 \u36890 \u36807 \u23458 \u26381 \u37038 \u31665 \u21457 \u36215 \u25237 \u35785 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u23545 \u20110 \u24744 \u21512 \u29702 \u30340 \u35831 \u27714 \u65292 \u25105 \u20204 \u21407 \u21017 \u19978 \u19981 \u25910 \u21462 \u36153 \u29992 \u65292 \u20294 \u23545 \u22810 \u27425 \u37325 \u22797 \u12289 \u36229 \u20986 \u21512 \u29702 \u38480 \u24230 \u30340 \u35831 \u27714 \u65292 \u25105 \u20204 \u23558 \u35270 \u24773 \u25910 \u21462 \u19968 \u23450 \u25104 \u26412 \u36153 \u29992 \u12290 \u23545 \u20110 \u37027 \u20123 \u26080 \u31471 \u37325 \u22797 \u12289 \u38656 \u35201 \u36807 \u22810 \u25216 \u26415 \u25163 \u27573 \u65288 \u20363 \u22914 \u65292 \u38656 \u35201 \u24320 \u21457 \u26032 \u31995 \u32479 \u25110 \u20174 \u26681 \u26412 \u19978 \u25913 \u21464 \u29616 \u34892 \u24815 \u20363 \u65289 \u12289 \u32473 \u20182 \u20154 \u21512 \u27861 \u26435 \u30410 \u24102 \u26469 \u39118 \u38505 \u25110 \u32773 \u38750 \u24120 \u19981 \u20999 \u23454 \u38469 \u30340 \u35831 \u27714 \u65292 \u25105 \u20204 \u21487 \u33021 \u20250 \u20104 \u20197 \u25298 \u32477 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u22312 \u20197 \u19979 \u24773 \u24418 \u20013 \u65292 \u25353 \u29031 \u27861 \u24459 \u27861 \u35268 \u35201 \u27714 \u65292 \u25105 \u20204 \u23558 \u26080 \u27861 \u21709 \u24212 \u24744 \u30340 \u35831 \u27714 \u65306 \
|
||||||
|
\
|
||||||
|
A. \uc0\u19982 \u22269 \u23478 \u23433 \u20840 \u12289 \u22269 \u38450 \u23433 \u20840 \u26377 \u20851 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
B. \uc0\u19982 \u20844 \u20849 \u23433 \u20840 \u12289 \u20844 \u20849 \u21355 \u29983 \u12289 \u37325 \u22823 \u20844 \u20849 \u21033 \u30410 \u26377 \u20851 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
C. \uc0\u19982 \u29359 \u32618 \u20390 \u26597 \u12289 \u36215 \u35785 \u12289 \u23457 \u21028 \u21644 \u25191 \u34892 \u21028 \u20915 \u31561 \u26377 \u20851 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
D. \uc0\u26377 \u20805 \u20998 \u35777 \u25454 \u34920 \u26126 \u20010 \u20154 \u20449 \u24687 \u20027 \u20307 \u23384 \u22312 \u20027 \u35266 \u24694 \u24847 \u25110 \u28389 \u29992 \u26435 \u21033 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
E. \uc0\u21709 \u24212 \u24744 \u30340 \u35831 \u27714 \u23558 \u23548 \u33268 \u24744 \u25110 \u20854 \u20182 \u20010 \u20154 \u12289 \u32452 \u32455 \u30340 \u21512 \u27861 \u26435 \u30410 \u21463 \u21040 \u20005 \u37325 \u25439 \u23475 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
F. \uc0\u28041 \u21450 \u21830 \u19994 \u31192 \u23494 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
G. \uc0\u19982 \u25105 \u20204 \u23653 \u34892 \u27861 \u24459 \u27861 \u35268 \u35268 \u23450 \u30340 \u20041 \u21153 \u30456 \u20851 \u30340 \u65307 \
|
||||||
|
\
|
||||||
|
H. \uc0\u20986 \u20110 \u32500 \u25252 \u24744 \u25110 \u20854 \u20182 \u20010 \u20154 \u30340 \u29983 \u21629 \u12289 \u36130 \u20135 \u31561 \u37325 \u22823 \u21512 \u27861 \u26435 \u30410 \u20294 \u21448 \u24456 \u38590 \u24471 \u21040 \u24744 \u26412 \u20154 \u21516 \u24847 \u30340 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u20061 \u12289 \u24744 \u20849 \u20139 \u30340 \u20449 \u24687 \
|
||||||
|
\
|
||||||
|
9.1 \uc0\u24744 \u21487 \u20197 \u22522 \u20110 \u25105 \u20204 \u30340 \u26381 \u21153 \u19982 \u20182 \u20154 \u12289 \u31038 \u20132 \u32593 \u32476 \u20998 \u20139 \u24744 \u30340 \u30456 \u20851 \u20449 \u24687 \u65292 \u36825 \u20854 \u20013 \u21487 \u33021 \u21253 \u21547 \u24744 \u30340 \u20010 \u20154 \u36523 \u20221 \u20449 \u24687 \u12289 \u20010 \u20154 \u36130 \u20135 \u20449 \u24687 \u31561 \u25935 \u24863 \u20449 \u24687 \u65292 \u24182 \u33258 \u20027 \u36873 \u25321 \u20998 \u20139 \u30340 \u23545 \u35937 \u20316 \u20026 \u33021 \u22815 \u30475 \u21040 \u24744 \u20449 \u24687 \u30340 \u31532 \u19977 \u26041 \u12290 \
|
||||||
|
\
|
||||||
|
9.2 \uc0\u24403 \u24744 \u19982 \u20182 \u20154 \u12289 \u31038 \u20132 \u32593 \u32476 \u25110 \u31532 \u19977 \u26041 \u26381 \u21153 \u25552 \u20379 \u21830 \u20849 \u20139 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u25110 \u32467 \u21512 \u31532 \u19977 \u26041 \u30340 \u26381 \u21153 \u20351 \u29992 \u12289 \u25110 \u20351 \u29992 \u31532 \u19977 \u26041 \u30340 \u26381 \u21153 \u38142 \u25509 \u26102 \u65292 \u24744 \u21487 \u33021 \u20250 \u25259 \u38706 \u25110 \u20351 \u31532 \u19977 \u26041 \u33719 \u21462 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
9.3 \uc0\u25105 \u20204 \u24314 \u35758 \u24744 \u26597 \u30475 \u27492 \u31867 \u31038 \u20132 \u32593 \u32476 \u25110 \u31532 \u19977 \u26041 \u26381 \u21153 \u25552 \u20379 \u21830 \u30340 \u38544 \u31169 \u22768 \u26126 \u65292 \u20197 \u20102 \u35299 \u20182 \u20204 \u22914 \u20309 \u22788 \u29702 \u24744 \u30340 \u20449 \u24687 \u12290 \u23545 \u20110 \u24744 \u20351 \u29992 \u31532 \u19977 \u26041 \u26381 \u21153 \u26102 \u21521 \u20854 \u25552 \u20379 \u25110 \u19982 \u20182 \u20154 \u20998 \u20139 \u20010 \u20154 \u20449 \u24687 \u32780 \u20135 \u29983 \u30340 \u21518 \u26524 \u30001 \u24744 \u33258 \u34892 \u25215 \u25285 \u65292 \u24182 \u30001 \u30456 \u24212 \u36131 \u20219 \u26041 \u22312 \u27861 \u24459 \u35268 \u23450 \u33539 \u22260 \u20869 \u25215 \u25285 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
9.4 \uc0\u24403 \u24744 \u22312 \u31508 \u22696 \u35759 \u20351 \u24179 \u21488 \u20844 \u24320 \u20998 \u20139 \u20219 \u20309 \u20449 \u24687 \u26102 \u65292 \u20219 \u20309 \u20154 \u37117 \u21487 \u33021 \u22312 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u24179 \u21488 \u26102 \u26597 \u30475 \u25110 \u35775 \u38382 \u36825 \u20123 \u20449 \u24687 \u65292 \u22914 \u24744 \u22312 \u31508 \u22696 \u35759 \u20351 \u24179 \u21488 \u19978 \u20256 \u30340 \u29031 \u29255 \u12289 \u35780 \u20215 \u31561 \u20449 \u24687 \u12290 \u24744 \u22312 \u20351 \u29992 \u25105 \u20204 \u26381 \u21153 \u26102 \u33258 \u24895 \u20849 \u20139 \u30340 \u20449 \u24687 \u65292 \u21487 \u33021 \u20250 \u28041 \u21450 \u24744 \u25110 \u20182 \u20154 \u30340 \u20010 \u20154 \u20449 \u24687 \u65292 \u35831 \u24744 \u35880 \u24910 \u36873 \u25321 \u24182 \u33258 \u34892 \u25215 \u25285 \u36131 \u20219 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u12289 \u26410 \u25104 \u24180 \u20154 \u20445 \u25252 \
|
||||||
|
\
|
||||||
|
10.1 \uc0\u25105 \u20204 \u38750 \u24120 \u37325 \u35270 \u23545 \u26410 \u25104 \u24180 \u20154 \u20010 \u20154 \u20449 \u24687 \u30340 \u20445 \u25252 \u12290 \u26681 \u25454 \u30456 \u20851 \u27861 \u24459 \u27861 \u35268 \u30340 \u35268 \u23450 \u65292 \u33509 \u24744 \u26159 18\u21608 \u23681 \u20197 \u19979 \u30340 \u26410 \u25104 \u24180 \u20154 \u65292 \u22312 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u30340 \u26381 \u21153 \u21069 \u65292 \u24212 \u20107 \u20808 \u21462 \u24471 \u24744 \u30340 \u23478 \u38271 \u25110 \u27861 \u23450 \u30417 \u25252 \u20154 \u30340 \u21516 \u24847 \u12290 \u33509 \u24744 \u26159 \u26410 \u28385 14\u21608 \u23681 \u30340 \u26410 \u25104 \u24180 \u20154 \u65292 \u24744 \u30340 \u30417 \u25252 \u20154 \u38656 \u35201 \u20180 \u32454 \u38405 \u35835 \u26412 \u25919 \u31574 \u24182 \u21516 \u24847 \u24744 \u20381 \u29031 \u26412 \u25919 \u31574 \u36866 \u29992 \u31508 \u22696 \u35759 \u20351 \u24179 \u21488 \u12290 \
|
||||||
|
\
|
||||||
|
10.2 \uc0\u25105 \u20204 \u19981 \u20250 \u20027 \u21160 \u30452 \u25509 \u21521 \u26410 \u25104 \u24180 \u20154 \u25910 \u38598 \u20854 \u20010 \u20154 \u20449 \u24687 \u12290 \u23545 \u20110 \u32463 \u30417 \u25252 \u20154 \u21516 \u24847 \u32780 \u25910 \u38598 \u26410 \u25104 \u24180 \u20154 \u20010 \u20154 \u20449 \u24687 \u30340 \u24773 \u20917 \u65292 \u25105 \u20204 \u21482 \u20250 \u22312 \u21463 \u21040 \u27861 \u24459 \u20801 \u35768 \u12289 \u30417 \u25252 \u20154 \u21516 \u24847 \u25110 \u32773 \u20445 \u25252 \u26410 \u25104 \u24180 \u20154 \u25152 \u24517 \u35201 \u30340 \u24773 \u20917 \u19979 \u20351 \u29992 \u12289 \u20849 \u20139 \u12289 \u36716 \u35753 \u25110 \u25259 \u38706 \u27492 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
10.3 \uc0\u22914 \u26524 \u26377 \u20107 \u23454 \u35777 \u26126 \u26410 \u25104 \u24180 \u20154 \u24182 \u26410 \u21462 \u24471 \u30417 \u25252 \u20154 \u21516 \u24847 \u30340 \u24773 \u20917 \u19979 \u27880 \u20876 \u20351 \u29992 \u20102 \u25105 \u20204 \u30340 \u20135 \u21697 \u19982 /\u25110 \u26381 \u21153 \u65292 \u25105 \u20204 \u20250 \u19982 \u30456 \u20851 \u30417 \u25252 \u20154 \u21327 \u21830 \u65292 \u24182 \u35774 \u27861 \u23613 \u24555 \u21024 \u38500 \u30456 \u20851 \u20010 \u20154 \u20449 \u24687 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u19968 \u12289 \u36866 \u29992 \u33539 \u22260 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u30340 \u25152 \u26377 \u26381 \u21153 \u22343 \u36866 \u29992 \u26412 \u25919 \u31574 \u12290 \u20294 \u26576 \u20123 \u26381 \u21153 \u26377 \u20854 \u29305 \u23450 \u30340 \u38544 \u31169 \u25351 \u24341 /\u22768 \u26126 \u65292 \u35813 \u29305 \u23450 \u38544 \u31169 \u25351 \u24341 /\u22768 \u26126 \u26356 \u20855 \u20307 \u22320 \u35828 \u26126 \u25105 \u20204 \u22312 \u35813 \u26381 \u21153 \u20013 \u22914 \u20309 \u22788 \u29702 \u24744 \u30340 \u20449 \u24687 \u12290 \u22914 \u26412 \u25919 \u31574 \u19982 \u29305 \u23450 \u26381 \u21153 \u30340 \u38544 \u31169 \u25351 \u24341 /\u22768 \u26126 \u26377 \u19981 \u19968 \u33268 \u20043 \u22788 \u65292 \u35831 \u20197 \u35813 \u29305 \u23450 \u38544 \u31169 \u25351 \u24341 /\u22768 \u26126 \u20026 \u20934 \u12290 \u35831 \u24744 \u27880 \u24847 \u65292 \u26412 \u25919 \u31574 \u19981 \u36866 \u29992 \u30001 \u20854 \u20182 \u20844 \u21496 \u25110 \u20010 \u20154 \u25552 \u20379 \u30340 \u26381 \u21153 \u12290 \u20363 \u22914 \u65292 \u24744 \u36890 \u36807 \u20351 \u29992 \u31508 \u22696 \u35759 \u20351 \u24080 \u21495 \u30331 \u24405 \u20854 \u20182 \u20844 \u21496 \u25110 \u20010 \u20154 \u25552 \u20379 \u30340 \u26381 \u21153 \u12290 \u24744 \u20351 \u29992 \u35813 \u31561 \u31532 \u19977 \u26041 \u26381 \u21153 \u39035 \u21463 \u20854 \u38544 \u31169 \u25919 \u31574 \u65288 \u32780 \u38750 \u26412 \u25919 \u31574 \u65289 \u32422 \u26463 \u65292 \u24744 \u38656 \u35201 \u20180 \u32454 \u38405 \u35835 \u20854 \u25919 \u31574 \u20869 \u23481 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u20108 \u12289 \u36890 \u30693 \u21644 \u20462 \u35746 \
|
||||||
|
\
|
||||||
|
12.1 \uc0\u20026 \u32473 \u24744 \u25552 \u20379 \u26356 \u22909 \u30340 \u26381 \u21153 \u20197 \u21450 \u38543 \u30528 \u31508 \u22696 \u35759 \u20351 \u19994 \u21153 \u30340 \u21457 \u23637 \u65292 \u26412 \u38544 \u31169 \u25919 \u31574 \u20063 \u20250 \u38543 \u20043 \u26356 \u26032 \u12290 \u20294 \u26410 \u32463 \u24744 \u26126 \u30830 \u21516 \u24847 \u65292 \u25105 \u20204 \u19981 \u20250 \u21066 \u20943 \u24744 \u20381 \u25454 \u26412 \u38544 \u31169 \u25919 \u31574 \u25152 \u24212 \u20139 \u26377 \u30340 \u26435 \u21033 \u12290 \u25105 \u20204 \u20250 \u36890 \u36807 \u22312 \u31508 \u22696 \u35759 \u20351 \u23448 \u26041 \u32593 \u31449 \u12289 \u31508 \u22696 \u35759 \u20351 \u31227 \u21160 \u31471 \u19978 \u21457 \u20986 \u26356 \u26032 \u29256 \u26412 \u24182 \u22312 \u29983 \u25928 \u21069 \u36890 \u36807 \u32593 \u31449 \u20844 \u21578 \u25110 \u20197 \u20854 \u20182 \u36866 \u24403 \u26041 \u24335 \u25552 \u37266 \u24744 \u30456 \u20851 \u20869 \u23481 \u30340 \u26356 \u26032 \u65292 \u20063 \u35831 \u24744 \u35775 \u38382 \u21450 \u26102 \u20102 \u35299 \u26368 \u26032 \u30340 \u38544 \u31169 \u25919 \u31574 \u12290 \
|
||||||
|
\
|
||||||
|
12.2 \uc0\u23545 \u20110 \u37325 \u22823 \u21464 \u26356 \u65292 \u25105 \u20204 \u36824 \u20250 \u25552 \u20379 \u26356 \u20026 \u26174 \u33879 \u30340 \u36890 \u30693 \u65288 \u25105 \u20204 \u20250 \u36890 \u36807 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u37038 \u20214 \u12289 \u30701 \u20449 \u25110 \u22312 \u27983 \u35272 \u39029 \u38754 \u20570 \u29305 \u21035 \u25552 \u31034 \u31561 \u26041 \u24335 \u65292 \u35828 \u26126 \u38544 \u31169 \u25919 \u31574 \u30340 \u20855 \u20307 \u21464 \u26356 \u20869 \u23481 \u65289 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u26412 \u38544 \u31169 \u25919 \u31574 \u25152 \u25351 \u30340 \u37325 \u22823 \u21464 \u26356 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \
|
||||||
|
\
|
||||||
|
A. \uc0\u25105 \u20204 \u30340 \u26381 \u21153 \u27169 \u24335 \u21457 \u29983 \u37325 \u22823 \u21464 \u21270 \u12290 \u22914 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u30340 \u30446 \u30340 \u12289 \u22788 \u29702 \u30340 \u20010 \u20154 \u20449 \u24687 \u31867 \u22411 \u12289 \u20010 \u20154 \u20449 \u24687 \u30340 \u20351 \u29992 \u26041 \u24335 \u31561 \u65307 \
|
||||||
|
\
|
||||||
|
B. \uc0\u25105 \u20204 \u22312 \u25152 \u26377 \u26435 \u32467 \u26500 \u12289 \u32452 \u32455 \u26550 \u26500 \u31561 \u26041 \u38754 \u21457 \u29983 \u37325 \u22823 \u21464 \u21270 \u12290 \u22914 \u19994 \u21153 \u35843 \u25972 \u12289 \u30772 \u20135 \u24182 \u36141 \u31561 \u24341 \u36215 \u30340 \u25152 \u26377 \u32773 \u21464 \u26356 \u31561 \u65307 \
|
||||||
|
\
|
||||||
|
C. \uc0\u20010 \u20154 \u20449 \u24687 \u20849 \u20139 \u12289 \u36716 \u35753 \u25110 \u20844 \u24320 \u25259 \u38706 \u30340 \u20027 \u35201 \u23545 \u35937 \u21457 \u29983 \u21464 \u21270 \u65307 \
|
||||||
|
\
|
||||||
|
D. \uc0\u24744 \u21442 \u19982 \u20010 \u20154 \u20449 \u24687 \u22788 \u29702 \u26041 \u38754 \u30340 \u26435 \u21033 \u21450 \u20854 \u34892 \u20351 \u26041 \u24335 \u21457 \u29983 \u37325 \u22823 \u21464 \u21270 \u65307 \
|
||||||
|
\
|
||||||
|
E. \uc0\u25105 \u20204 \u36127 \u36131 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u23433 \u20840 \u30340 \u36131 \u20219 \u37096 \u38376 \u12289 \u32852 \u32476 \u26041 \u24335 \u21450 \u25237 \u35785 \u28192 \u36947 \u21457 \u29983 \u21464 \u21270 \u26102 \u65307 \
|
||||||
|
\
|
||||||
|
F. \uc0\u20010 \u20154 \u20449 \u24687 \u23433 \u20840 \u24433 \u21709 \u35780 \u20272 \u25253 \u21578 \u34920 \u26126 \u23384 \u22312 \u39640 \u39118 \u38505 \u26102 \u12290 \
|
||||||
|
\
|
||||||
|
12.3 \uc0\u25105 \u20204 \u36824 \u20250 \u23558 \u26412 \u38544 \u31169 \u25919 \u31574 \u30340 \u26087 \u29256 \u26412 \u23384 \u26723 \u65292 \u20379 \u24744 \u26597 \u38405 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u19977 \u12289 \u26412 \u38544 \u31169 \u25919 \u31574 \u22914 \u20309 \u26356 \u26032 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u30340 \u38544 \u31169 \u20445 \u25252 \u25919 \u31574 \u21487 \u33021 \u21464 \u26356 \u12290 \u26410 \u32463 \u24744 \u26126 \u30830 \u21516 \u24847 \u65292 \u25105 \u20204 \u19981 \u20250 \u38480 \u21046 \u24744 \u25353 \u29031 \u26412 \u38544 \u31169 \u25919 \u31574 \u25152 \u24212 \u20139 \u26377 \u30340 \u26435 \u21033 \u12290 \u23545 \u20110 \u37325 \u22823 \u21464 \u26356 \u65292 \u25105 \u20204 \u20250 \u25552 \u20379 \u26174 \u33879 \u30340 \u36890 \u30693 \u65288 \u21253 \u25324 \u36890 \u36807 \u25105 \u20204 \u20844 \u31034 \u30340 \u26041 \u24335 \u36827 \u34892 \u36890 \u30693 \u29978 \u33267 \u21521 \u24744 \u25552 \u20379 \u24377 \u31383 \u25552 \u31034 \u65289 \u12290 \u26412 \u25919 \u31574 \u25152 \u25351 \u30340 \u37325 \u22823 \u21464 \u26356 \u21253 \u25324 \u20294 \u19981 \u38480 \u20110 \u65306 \
|
||||||
|
13.1 \uc0\u25105 \u20204 \u30340 \u26381 \u21153 \u27169 \u24335 \u21457 \u29983 \u37325 \u22823 \u21464 \u21270 \u12290 \u22914 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u30340 \u30446 \u30340 \u12289 \u22788 \u29702 \u30340 \u20010 \u20154 \u20449 \u24687 \u31867 \u22411 \u12289 \u20010 \u20154 \u20449 \u24687 \u30340 \u20351 \u29992 \u26041 \u24335 \u31561 \u12290 \
|
||||||
|
\
|
||||||
|
13.2 \uc0\u25105 \u20204 \u22312 \u25511 \u21046 \u26435 \u31561 \u26041 \u38754 \u21457 \u29983 \u37325 \u22823 \u21464 \u21270 \u12290 \u22914 \u24182 \u36141 \u12289 \u37325 \u32452 \u31561 \u24341 \u36215 \u30340 \u25152 \u26377 \u32773 \u21464 \u26356 \u31561 \u12290 \
|
||||||
|
\
|
||||||
|
13.3 \uc0\u20010 \u20154 \u20449 \u24687 \u20849 \u20139 \u12289 \u36716 \u35753 \u25110 \u20844 \u24320 \u25259 \u38706 \u30340 \u20027 \u35201 \u23545 \u35937 \u21457 \u29983 \u21464 \u21270 \u12290 \
|
||||||
|
\
|
||||||
|
13.4 \uc0\u24744 \u21442 \u19982 \u20010 \u20154 \u20449 \u24687 \u22788 \u29702 \u26041 \u38754 \u30340 \u26435 \u21033 \u21450 \u20854 \u34892 \u20351 \u26041 \u24335 \u21457 \u29983 \u37325 \u22823 \u21464 \u21270 \u12290 \
|
||||||
|
\
|
||||||
|
13.5 \uc0\u25105 \u20204 \u36127 \u36131 \u22788 \u29702 \u20010 \u20154 \u20449 \u24687 \u23433 \u20840 \u30340 \u36131 \u20219 \u37096 \u38376 \u12289 \u32852 \u32476 \u26041 \u24335 \u21450 \u25237 \u35785 \u28192 \u36947 \u21457 \u29983 \u21464 \u21270 \u26102 \u12290 \
|
||||||
|
\
|
||||||
|
13.6 \uc0\u20010 \u20154 \u20449 \u24687 \u23433 \u20840 \u24433 \u21709 \u35780 \u20272 \u25253 \u21578 \u34920 \u26126 \u23384 \u22312 \u39640 \u39118 \u38505 \u26102 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u25105 \u20204 \u36824 \u20250 \u23558 \u26412 \u38544 \u31169 \u25919 \u31574 \u30340 \u26087 \u29256 \u26412 \u23384 \u26723 \u65292 \u20379 \u24744 \u26597 \u38405 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u22235 \u12289 \u22914 \u20309 \u32852 \u31995 \u25105 \u20204 \
|
||||||
|
\
|
||||||
|
14.1 \uc0\u22914 \u24744 \u23545 \u26412 \u38544 \u31169 \u25919 \u31574 \u25110 \u24744 \u20010 \u20154 \u20449 \u24687 \u30340 \u30456 \u20851 \u20107 \u23452 \u26377 \u20219 \u20309 \u38382 \u39064 \u12289 \u24847 \u35265 \u25110 \u24314 \u35758 \u65292 \u35831 \u32852 \u31995 \u31508 \u22696 \u35759 \u20351 \u23458 \u26381 \u65288 \u32852 \u31995 \u37038 \u31665 \u65306 \u12304 fengqunwangluo2025@163.com\u12305 \u65289 \u12290 \
|
||||||
|
\
|
||||||
|
14.2 \uc0\u19968 \u33324 \u24773 \u20917 \u19979 \u65292 \u25105 \u20204 \u23558 \u22312 15\u22825 \u20869 \u22238 \u22797 \u21644 \u22788 \u29702 \u24744 \u30340 \u30097 \u38382 \u12289 \u24847 \u35265 \u25110 \u24314 \u35758 \u12290 \u38656 \u27880 \u24847 \u30340 \u26159 \u65292 \u25105 \u20204 \u21487 \u33021 \u19981 \u20250 \u22238 \u22797 \u19982 \u26412 \u25919 \u31574 \u25110 \u24744 \u30340 \u20010 \u20154 \u20449 \u24687 \u26435 \u21033 \u26080 \u20851 \u30340 \u38382 \u39064 \u12290 \u22914 \u26524 \u24744 \u23545 \u25105 \u20204 \u30340 \u22238 \u22797 \u19981 \u28385 \u24847 \u65292 \u29305 \u21035 \u26159 \u25105 \u20204 \u30340 \u20010 \u20154 \u20449 \u24687 \u22788 \u29702 \u34892 \u20026 \u25439 \u23475 \u20102 \u24744 \u30340 \u21512 \u27861 \u26435 \u30410 \u65292 \u24744 \u36824 \u21487 \u20197 \u21521 \u32593 \u20449 \u12289 \u30005 \u20449 \u12289 \u20844 \u23433 \u21450 \u24037 \u21830 \u31561 \u30417 \u31649 \u37096 \u38376 \u36827 \u34892 \u25237 \u35785 \u25110 \u20030 \u25253 \u12290 \u25110 \u36890 \u36807 \u21521 \u25105 \u20204 \u25152 \u22312 \u22320 \u26377 \u31649 \u36758 \u26435 \u30340 \u27861 \u38498 \u25552 \u36215 \u35785 \u35772 \u26469 \u23547 \u27714 \u35299 \u20915 \u26041 \u26696 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u21313 \u20116 \u12289 \u38468 \u21017 \
|
||||||
|
15.1 \uc0\u26412 \u25919 \u31574 \u30340 \u35299 \u37322 \u21450 \u20105 \u35758 \u35299 \u20915 \u22343 \u24212 \u36866 \u29992 \u20013 \u21326 \u20154 \u27665 \u20849 \u21644 \u22269 \u27861 \u24459 \u12290 \u19982 \u26412 \u25919 \u31574 \u30456 \u20851 \u30340 \u20219 \u20309 \u32416 \u32439 \u65292 \u21452 \u26041 \u24212 \u32463 \u21451 \u22909 \u21327 \u21830 \u35299 \u20915 \u65307 \u33509 \u19981 \u33021 \u21327 \u21830 \u35299 \u20915 \u65292 \u24744 \u22312 \u27492 \u21516 \u24847 \u23558 \u20105 \u35758 \u25552 \u20132 \u33267 \u25105 \u20204 \u20844 \u21496 \u25152 \u22312 \u22320 \u20154 \u27665 \u27861 \u38498 \u25552 \u36215 \u35785 \u35772 \u12290 \
|
||||||
|
\
|
||||||
|
15.2 \uc0\u22914 \u26524 \u26377 \u31649 \u36758 \u26435 \u30340 \u20219 \u20309 \u27861 \u38498 \u35009 \u23450 \u25110 \u21028 \u20915 \u26412 \u25919 \u31574 \u30340 \u20219 \u20309 \u26465 \u27454 \u26080 \u25928 \u65292 \u21017 \u35813 \u26465 \u27454 \u23558 \u20174 \u26412 \u25919 \u31574 \u20013 \u31227 \u38500 \u65292 \u20294 \u35813 \u26465 \u27454 \u30340 \u26080 \u25928 \u19981 \u24433 \u21709 \u26412 \u25919 \u31574 \u20854 \u20313 \u26465 \u27454 \u30340 \u25928 \u21147 \u12290 \u26412 \u25919 \u31574 \u30340 \u20854 \u20313 \u26465 \u27454 \u23558 \u32487 \u32493 \u25191 \u34892 \u12290 \
|
||||||
|
\
|
||||||
|
15.3 \uc0\u26412 \u25919 \u31574 \u30340 \u26631 \u39064 \u20165 \u20026 \u26041 \u20415 \u38405 \u35835 \u32780 \u35774 \u35745 \u65292 \u19981 \u24433 \u21709 \u26412 \u25919 \u31574 \u20219 \u20309 \u26465 \u27454 \u30340 \u21547 \u20041 \u25110 \u35299 \u37322 \u12290 \
|
||||||
|
\
|
||||||
|
\uc0\u24320 \u21457 \u32773 \u21517 \u31216 \u65306 \u12304 \u28023 \u21475 \u24066 \u26539 \u32676 \u32593 \u32476 \u31185 \u25216 \u26377 \u38480 \u20844 \u21496 \u12305 }
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
-- Update workbench module order to match the mobile workbench layout.
|
||||||
|
-- Order: 打卡、月报、日报、部门框架、举报信箱、会议通知、会议笔记.
|
||||||
|
|
||||||
|
UPDATE tinode.im_workbench_apps
|
||||||
|
SET sort_order = CASE code
|
||||||
|
WHEN 'attendance' THEN 10
|
||||||
|
WHEN 'monthly_reports' THEN 20
|
||||||
|
WHEN 'daily_reports' THEN 30
|
||||||
|
WHEN 'organization' THEN 40
|
||||||
|
WHEN 'executive_mailbox' THEN 50
|
||||||
|
WHEN 'meetings' THEN 60
|
||||||
|
WHEN 'meeting_notes' THEN 70
|
||||||
|
ELSE sort_order
|
||||||
|
END,
|
||||||
|
name = CASE code
|
||||||
|
WHEN 'organization' THEN '部门框架'
|
||||||
|
WHEN 'executive_mailbox' THEN '举报信箱'
|
||||||
|
ELSE name
|
||||||
|
END,
|
||||||
|
updated_at = CURRENT_TIMESTAMP(3)
|
||||||
|
WHERE code IN (
|
||||||
|
'attendance',
|
||||||
|
'monthly_reports',
|
||||||
|
'daily_reports',
|
||||||
|
'organization',
|
||||||
|
'executive_mailbox',
|
||||||
|
'meetings',
|
||||||
|
'meeting_notes'
|
||||||
|
);
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-- Add personal privacy switch for requiring approval when others invite the user into a group.
|
||||||
|
-- Default is off to preserve existing behavior.
|
||||||
|
|
||||||
|
SET @im_sql = (
|
||||||
|
SELECT IF(
|
||||||
|
COUNT(*) = 0,
|
||||||
|
'ALTER TABLE tinode.im_user_privacy_settings ADD COLUMN group_invite_verification TINYINT NOT NULL DEFAULT 0 AFTER read_receipts',
|
||||||
|
'SELECT 1'
|
||||||
|
)
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'tinode'
|
||||||
|
AND table_name = 'im_user_privacy_settings'
|
||||||
|
AND column_name = 'group_invite_verification'
|
||||||
|
);
|
||||||
|
PREPARE im_stmt FROM @im_sql;
|
||||||
|
EXECUTE im_stmt;
|
||||||
|
DEALLOCATE PREPARE im_stmt;
|
||||||
@@ -24,7 +24,15 @@
|
|||||||
- iOS:配置 APNs 证书或 Token Authentication,申请通知权限。
|
- iOS:配置 APNs 证书或 Token Authentication,申请通知权限。
|
||||||
- HarmonyOS:按鸿蒙 SDK 文档初始化并配置通知分类。
|
- HarmonyOS:按鸿蒙 SDK 文档初始化并配置通知分类。
|
||||||
|
|
||||||
客户端启动后取得 `registration_id`,登录 IM 后把 alias 绑定为当前 `user_id`。同一用户多设备允许绑定同一个 alias。
|
客户端启动后取得 `registration_id`,登录 IM 后把 alias 绑定为当前 `user_id` 的极光安全别名。同一用户多设备允许绑定同一个 alias。
|
||||||
|
|
||||||
|
极光 alias 不支持中横线 `-` 和下划线 `_`,而 IM `user_id` 可能包含这两个字符。客户端和后端统一使用以下映射:
|
||||||
|
|
||||||
|
```text
|
||||||
|
jpush_alias = user_id.replace("-", ".").replace("_", "|")
|
||||||
|
```
|
||||||
|
|
||||||
|
示例:`usrd6Ag5opa-ww` 对应极光 alias `usrd6Ag5opa.ww`。
|
||||||
|
|
||||||
### 2.2 上报 Push Token
|
### 2.2 上报 Push Token
|
||||||
|
|
||||||
@@ -306,7 +314,7 @@ Content-Type: application/json
|
|||||||
| 步骤 | 操作 | 验证 |
|
| 步骤 | 操作 | 验证 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| 1 | 客户端初始化 JPush SDK | 能拿到 `registration_id`。 |
|
| 1 | 客户端初始化 JPush SDK | 能拿到 `registration_id`。 |
|
||||||
| 2 | 登录 IM 并绑定 alias=`user_id` | 极光控制台能查到别名或设备。 |
|
| 2 | 登录 IM 并绑定 alias=`user_id.replace("-", ".").replace("_", "|")` | 极光控制台能查到别名或设备。 |
|
||||||
| 3 | 调用设备上报接口 | 服务端设备记录 provider=`jpush`。 |
|
| 3 | 调用设备上报接口 | 服务端设备记录 provider=`jpush`。 |
|
||||||
| 4 | 目标用户退出或断网 | IM 判断为离线或不可 WS 投递。 |
|
| 4 | 目标用户退出或断网 | IM 判断为离线或不可 WS 投递。 |
|
||||||
| 5 | 发送 P2P 消息 | 离线用户收到 Push。 |
|
| 5 | 发送 P2P 消息 | 离线用户收到 Push。 |
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
| `jpush_apns_production` | `false/true` | iOS APNs 环境,测试包用 false,生产包用 true。 |
|
| `jpush_apns_production` | `false/true` | iOS APNs 环境,测试包用 false,生产包用 true。 |
|
||||||
| `jpush_default_ttl_seconds` | `86400` | 离线 Push 默认保留时长。 |
|
| `jpush_default_ttl_seconds` | `86400` | 离线 Push 默认保留时长。 |
|
||||||
| `jpush_call_ttl_seconds` | `60` | 来电 Push 保留时长,建议短一些。 |
|
| `jpush_call_ttl_seconds` | `60` | 来电 Push 保留时长,建议短一些。 |
|
||||||
| `jpush_use_alias` | `true` | 是否优先使用 alias=user_id 投递。 |
|
| `jpush_use_alias` | `true` | 是否优先使用极光安全 alias 投递。 |
|
||||||
| `jpush_test_model` | `false` | 极光测试模式,仅联调测试设备时开启。 |
|
| `jpush_test_model` | `false` | 极光测试模式,仅联调测试设备时开启。 |
|
||||||
| `jpush_classification` | `1` | 重要业务通知建议按系统消息分类处理,需结合厂商通道规则确认。 |
|
| `jpush_classification` | `1` | 重要业务通知建议按系统消息分类处理,需结合厂商通道规则确认。 |
|
||||||
| `jpush_log_payload` | `false` | 生产关闭 payload 明文日志,避免敏感信息进入日志。 |
|
| `jpush_log_payload` | `false` | 生产关闭 payload 明文日志,避免敏感信息进入日志。 |
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
2. 初始化 SDK 使用 `jpush_app_key`。
|
2. 初始化 SDK 使用 `jpush_app_key`。
|
||||||
3. 申请系统通知权限。
|
3. 申请系统通知权限。
|
||||||
4. 取得 `registration_id`。
|
4. 取得 `registration_id`。
|
||||||
5. 登录 IM 后绑定 alias,建议 alias 使用当前 IM `user_id`,例如 `usr...`。
|
5. 登录 IM 后绑定 alias。极光 alias 不支持中横线 `-` 和下划线 `_`,客户端必须将当前 IM `user_id` 转成极光安全别名:`user_id.replace("-", ".").replace("_", "|")`。示例:`usrd6Ag5opa-ww` 对应 `usrd6Ag5opa.ww`。
|
||||||
6. 调用 IM 后端设备接口上报 Push Token。
|
6. 调用 IM 后端设备接口上报 Push Token。
|
||||||
|
|
||||||
### 4.2 设备上报
|
### 4.2 设备上报
|
||||||
@@ -357,7 +357,7 @@ Push 中的 `topic`、`seq`、`call_id` 只用于定位和补偿,不作为业
|
|||||||
|
|
||||||
| 验收项 | 期望结果 |
|
| 验收项 | 期望结果 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 客户端初始化 | SDK 返回 registration_id,alias 绑定为当前 `usr...`。 |
|
| 客户端初始化 | SDK 返回 registration_id,alias 绑定为 `user_id.replace("-", ".").replace("_", "|")`。 |
|
||||||
| 设备上报 | `PUT /v1/im/devices/{device_id}/push-token` 返回成功,服务端记录 provider=`jpush`。 |
|
| 设备上报 | `PUT /v1/im/devices/{device_id}/push-token` 返回成功,服务端记录 provider=`jpush`。 |
|
||||||
| 普通离线消息 | 用户离线后收到 Push,点击后进入会话并补齐 Topic seq。 |
|
| 普通离线消息 | 用户离线后收到 Push,点击后进入会话并补齐 Topic seq。 |
|
||||||
| 群 @ 提醒 | 被 @ 用户离线时只收到一次提醒,重连后定位到对应消息。 |
|
| 群 @ 提醒 | 被 @ 用户离线时只收到一次提醒,重连后定位到对应消息。 |
|
||||||
|
|||||||
@@ -383,6 +383,7 @@ func main() {
|
|||||||
profile_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
profile_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
||||||
last_seen_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
last_seen_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
||||||
read_receipts TINYINT NOT NULL DEFAULT 1,
|
read_receipts TINYINT NOT NULL DEFAULT 1,
|
||||||
|
group_invite_verification TINYINT NOT NULL DEFAULT 0,
|
||||||
version INT NOT NULL DEFAULT 1,
|
version INT NOT NULL DEFAULT 1,
|
||||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||||
@@ -539,6 +540,7 @@ func main() {
|
|||||||
"ALTER TABLE tinode.im_youth_mode_settings ADD COLUMN enabled_at DATETIME(3) AFTER restrictions",
|
"ALTER TABLE tinode.im_youth_mode_settings ADD COLUMN enabled_at DATETIME(3) AFTER restrictions",
|
||||||
"ALTER TABLE tinode.im_users ADD COLUMN phone VARCHAR(32) NULL AFTER useragent",
|
"ALTER TABLE tinode.im_users ADD COLUMN phone VARCHAR(32) NULL AFTER useragent",
|
||||||
"ALTER TABLE tinode.im_user_profiles ADD COLUMN email VARCHAR(128) NOT NULL DEFAULT '' AFTER region",
|
"ALTER TABLE tinode.im_user_profiles ADD COLUMN email VARCHAR(128) NOT NULL DEFAULT '' AFTER region",
|
||||||
|
"ALTER TABLE tinode.im_user_privacy_settings ADD COLUMN group_invite_verification TINYINT NOT NULL DEFAULT 0 AFTER read_receipts",
|
||||||
} {
|
} {
|
||||||
if _, err = db.Exec(stmt); err != nil && !strings.Contains(err.Error(), "Duplicate column name") {
|
if _, err = db.Exec(stmt); err != nil && !strings.Contains(err.Error(), "Duplicate column name") {
|
||||||
fatal(fmt.Errorf("exec failed: %s: %w", stmt, err))
|
fatal(fmt.Errorf("exec failed: %s: %w", stmt, err))
|
||||||
@@ -556,11 +558,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
if _, err = db.Exec(`INSERT INTO tinode.im_workbench_apps(code,name,route,sort_order,unread_key,enabled,permission)
|
if _, err = db.Exec(`INSERT INTO tinode.im_workbench_apps(code,name,route,sort_order,unread_key,enabled,permission)
|
||||||
VALUES
|
VALUES
|
||||||
('organization','组织架构','/organization',10,'organization',1,'enabled'),
|
('attendance','打卡','/attendance',10,'attendance',1,'enabled'),
|
||||||
('meetings','会议通知','/meetings',20,'meetings',1,'enabled'),
|
('monthly_reports','月报','/reports/monthly',20,'monthly_reports',1,'enabled'),
|
||||||
('daily_reports','日报','/reports/daily',30,'daily_reports',1,'enabled'),
|
('daily_reports','日报','/reports/daily',30,'daily_reports',1,'enabled'),
|
||||||
('monthly_reports','月报','/reports/monthly',40,'monthly_reports',1,'enabled'),
|
('organization','部门框架','/organization',40,'organization',1,'enabled'),
|
||||||
('executive_mailbox','总经理信箱','/executive-mailbox',50,'executive_mailbox',1,'enabled')
|
('executive_mailbox','举报信箱','/executive-mailbox',50,'executive_mailbox',1,'enabled'),
|
||||||
|
('meetings','会议通知','/meetings',60,'meetings',1,'enabled'),
|
||||||
|
('meeting_notes','会议笔记','/meeting-notes',70,'',1,'enabled')
|
||||||
ON DUPLICATE KEY UPDATE name=VALUES(name),route=VALUES(route),sort_order=VALUES(sort_order),unread_key=VALUES(unread_key),updated_at=CURRENT_TIMESTAMP(3)`); err != nil {
|
ON DUPLICATE KEY UPDATE name=VALUES(name),route=VALUES(route),sort_order=VALUES(sort_order),unread_key=VALUES(unread_key),updated_at=CURRENT_TIMESTAMP(3)`); err != nil {
|
||||||
fatal(err)
|
fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,6 +186,42 @@ func (c *adminInternalClient) TenantLoginIPWhitelist(id types.TenantID) (*tenant
|
|||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *adminInternalClient) LatestAppRelease(platform, channel string) (*types.AppRelease, error) {
|
||||||
|
query := url.Values{}
|
||||||
|
query.Set("platform", strings.ToLower(strings.TrimSpace(platform)))
|
||||||
|
query.Set("channel", strings.ToLower(strings.TrimSpace(channel)))
|
||||||
|
var dto struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Platform string `json:"platform"`
|
||||||
|
Channel string `json:"channel"`
|
||||||
|
LatestVersion string `json:"latest_version"`
|
||||||
|
MinSupportedVersion string `json:"min_supported_version"`
|
||||||
|
UpdateType string `json:"update_type"`
|
||||||
|
ReleaseNotes string `json:"release_notes"`
|
||||||
|
StoreURL string `json:"store_url"`
|
||||||
|
PackageURL string `json:"package_url"`
|
||||||
|
Checksum string `json:"checksum"`
|
||||||
|
RemindAfterSeconds int `json:"remind_after_seconds"`
|
||||||
|
PublishedAt string `json:"published_at"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
}
|
||||||
|
if err := c.getJSON("/internal/im-config/app/releases/latest", query, &dto); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
parseTime := func(raw string) time.Time {
|
||||||
|
parsed, _ := time.Parse(time.RFC3339Nano, raw)
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
return &types.AppRelease{
|
||||||
|
ID: dto.ID, Platform: dto.Platform, Channel: dto.Channel,
|
||||||
|
LatestVersion: dto.LatestVersion, MinSupportedVersion: dto.MinSupportedVersion,
|
||||||
|
UpdateType: dto.UpdateType, ReleaseNotes: dto.ReleaseNotes, StoreURL: dto.StoreURL,
|
||||||
|
PackageURL: dto.PackageURL, Checksum: dto.Checksum, RemindAfterSeconds: dto.RemindAfterSeconds,
|
||||||
|
PublishedAt: parseTime(dto.PublishedAt), CreatedAt: parseTime(dto.CreatedAt), UpdatedAt: parseTime(dto.UpdatedAt),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *adminInternalClient) getJSON(path string, query url.Values, out any) error {
|
func (c *adminInternalClient) getJSON(path string, query url.Values, out any) error {
|
||||||
if c == nil || c.http == nil {
|
if c == nil || c.http == nil {
|
||||||
return types.ErrUnsupported
|
return types.ErrUnsupported
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAdminInternalClientLatestAppRelease(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.Path != "/internal/im-config/app/releases/latest" {
|
||||||
|
t.Errorf("unexpected path: %s", r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.URL.Query().Get("platform") != "ios" || r.URL.Query().Get("channel") != "stable" {
|
||||||
|
t.Errorf("unexpected query: %s", r.URL.RawQuery)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.Header.Get(internalHeaderSignature) == "" {
|
||||||
|
t.Error("internal request must be signed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||||
|
"code": 0,
|
||||||
|
"data": map[string]any{
|
||||||
|
"id": 1, "platform": "ios", "channel": "stable",
|
||||||
|
"latest_version": "2.0.0", "min_supported_version": "1.5.0",
|
||||||
|
"update_type": "recommended", "store_url": "https://apps.apple.com/app/id123",
|
||||||
|
"published_at": "2026-09-12T10:00:00Z",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
client := &adminInternalClient{
|
||||||
|
config: adminInternalAPIConfig{BaseURL: server.URL, ServiceName: "im-server", Secret: "test-secret"},
|
||||||
|
http: server.Client(),
|
||||||
|
}
|
||||||
|
release, err := client.LatestAppRelease(" IOS ", "STABLE")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if release.LatestVersion != "2.0.0" || release.StoreURL != "https://apps.apple.com/app/id123" || release.PublishedAt.IsZero() {
|
||||||
|
t.Fatalf("unexpected release: %#v", release)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -147,6 +147,11 @@ func (ta *authenticator) Authenticate(ctx auth.AuthContext, token []byte) (*auth
|
|||||||
|
|
||||||
features := auth.Feature(tl.Features)
|
features := auth.Feature(tl.Features)
|
||||||
if features&auth.FeatureNoLogin == 0 {
|
if features&auth.FeatureNoLogin == 0 {
|
||||||
|
if revoked, enabled, err := store.IsLoginTokenRevoked(types.TenantID(tl.TenantID), token); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
} else if enabled && revoked {
|
||||||
|
return nil, nil, types.ErrFailed
|
||||||
|
}
|
||||||
if store.Security == nil {
|
if store.Security == nil {
|
||||||
return nil, nil, types.ErrInternal
|
return nil, nil, types.ErrInternal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,22 +95,23 @@ func TestGroupMessageQuerySupportsOperationalFilters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUserQuerySupportsKeywordAndUserIDs(t *testing.T) {
|
func TestUserQuerySupportsKeywordAndUserIDs(t *testing.T) {
|
||||||
req := httptest.NewRequest("GET", "/?keyword=alice&user_ids=101,202", nil)
|
req := httptest.NewRequest("GET", "/?keyword=alice&user_ids=101,202&account_no=1000", nil)
|
||||||
query, countQuery, args, _, _, err := buildInternalAdminListQuery(req, usersInternalQuerySpec(), "")
|
query, countQuery, args, _, _, err := buildInternalAdminListQuery(req, usersInternalQuerySpec(), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, clause := range []string{"CONCAT_WS(' ',u.username,p.nickname,u.phone) LIKE ?", "u.id IN (?,?)"} {
|
for _, clause := range []string{"CONCAT_WS(' ',u.username,p.nickname,u.phone,CAST(u.account_no AS CHAR)) LIKE ?", "u.id IN (?,?)", "u.account_no = ?"} {
|
||||||
if !strings.Contains(query, clause) || !strings.Contains(countQuery, clause) {
|
if !strings.Contains(query, clause) || !strings.Contains(countQuery, clause) {
|
||||||
t.Fatalf("user query missing %q: %s", clause, query)
|
t.Fatalf("user query missing %q: %s", clause, query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
want := []any{int64(101), int64(202), "%alice%"}
|
want := []any{int64(101), int64(202), int64(1000), "%alice%"}
|
||||||
if !reflect.DeepEqual(args, want) {
|
if !reflect.DeepEqual(args, want) {
|
||||||
t.Fatalf("unexpected filter arguments: got %#v, want %#v", args, want)
|
t.Fatalf("unexpected filter arguments: got %#v, want %#v", args, want)
|
||||||
}
|
}
|
||||||
for _, field := range []string{
|
for _, field := range []string{
|
||||||
"AS avatar",
|
"AS avatar",
|
||||||
|
"u.account_no AS display_no",
|
||||||
"AS register_type",
|
"AS register_type",
|
||||||
"im_registration_invite_uses",
|
"im_registration_invite_uses",
|
||||||
"im_fileuploads AS avatar",
|
"im_fileuploads AS avatar",
|
||||||
|
|||||||
@@ -385,6 +385,7 @@ type TenantBusinessAdapter interface {
|
|||||||
TenantGroupJoinRequestList(t.TenantID, string, string, string, int) ([]t.GroupJoinRequest, string, error)
|
TenantGroupJoinRequestList(t.TenantID, string, string, string, int) ([]t.GroupJoinRequest, string, error)
|
||||||
TenantGroupJoinRequestResolve(t.TenantID, string, string, t.Uid, string, string, int, any, time.Time) (*t.GroupJoinRequest, error)
|
TenantGroupJoinRequestResolve(t.TenantID, string, string, t.Uid, string, string, int, any, time.Time) (*t.GroupJoinRequest, error)
|
||||||
TenantGroupAnnouncementLatest(t.TenantID, string) (*t.GroupAnnouncement, error)
|
TenantGroupAnnouncementLatest(t.TenantID, string) (*t.GroupAnnouncement, error)
|
||||||
|
TenantGroupAnnouncementGet(t.TenantID, string, string) (*t.GroupAnnouncement, error)
|
||||||
TenantGroupAnnouncementPut(t.TenantID, *t.GroupAnnouncement, int) (*t.GroupAnnouncement, error)
|
TenantGroupAnnouncementPut(t.TenantID, *t.GroupAnnouncement, int) (*t.GroupAnnouncement, error)
|
||||||
TenantGroupAnnouncementRead(t.TenantID, string, string, t.Uid, time.Time) error
|
TenantGroupAnnouncementRead(t.TenantID, string, string, t.Uid, time.Time) error
|
||||||
TenantGroupMuteList(t.TenantID, string, string, int) ([]t.GroupMute, string, error)
|
TenantGroupMuteList(t.TenantID, string, string, int) ([]t.GroupMute, string, error)
|
||||||
@@ -444,7 +445,6 @@ type TenantBusinessAdapter interface {
|
|||||||
TenantUserProfileUpdate(t.TenantID, t.Uid, t.UserProfilePatch) (*t.UserProfile, error)
|
TenantUserProfileUpdate(t.TenantID, t.Uid, t.UserProfilePatch) (*t.UserProfile, error)
|
||||||
TenantUserPrivacyGet(t.TenantID, t.Uid) (*t.UserPrivacySettings, error)
|
TenantUserPrivacyGet(t.TenantID, t.Uid) (*t.UserPrivacySettings, error)
|
||||||
TenantUserPrivacyUpdate(t.TenantID, t.Uid, t.UserPrivacyPatch) (*t.UserPrivacySettings, error)
|
TenantUserPrivacyUpdate(t.TenantID, t.Uid, t.UserPrivacyPatch) (*t.UserPrivacySettings, error)
|
||||||
TenantAppReleaseLatest(t.TenantID, string, string) (*t.AppRelease, error)
|
|
||||||
TenantDevicePushTokenUpsert(t.TenantID, *t.DevicePushToken) (*t.DevicePushToken, error)
|
TenantDevicePushTokenUpsert(t.TenantID, *t.DevicePushToken) (*t.DevicePushToken, error)
|
||||||
TenantRiskChallengeCreate(t.TenantID, *t.RiskChallenge) (*t.RiskChallenge, error)
|
TenantRiskChallengeCreate(t.TenantID, *t.RiskChallenge) (*t.RiskChallenge, error)
|
||||||
TenantRiskChallengeConfirm(t.TenantID, t.Uid, string, string, string, time.Time) (*t.RiskChallenge, error)
|
TenantRiskChallengeConfirm(t.TenantID, t.Uid, string, string, string, time.Time) (*t.RiskChallenge, error)
|
||||||
|
|||||||
+190
-31
@@ -9,6 +9,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -72,6 +73,27 @@ func quoteIdent(name string) string {
|
|||||||
return "`" + strings.ReplaceAll(name, "`", "``") + "`"
|
return "`" + strings.ReplaceAll(name, "`", "``") + "`"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseFileUID(fid string) t.Uid {
|
||||||
|
name := strings.TrimSpace(fid)
|
||||||
|
id := t.ParseUid(name)
|
||||||
|
if !id.IsZero() {
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
if dot := strings.LastIndexByte(name, '.'); dot > 0 {
|
||||||
|
ext := name[dot+1:]
|
||||||
|
if len(ext) == 0 || len(ext) > 16 {
|
||||||
|
return t.ZeroUid
|
||||||
|
}
|
||||||
|
for _, r := range ext {
|
||||||
|
if (r < 'A' || r > 'Z') && (r < 'a' || r > 'z') && (r < '0' || r > '9') {
|
||||||
|
return t.ZeroUid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t.ParseUid(name[:dot])
|
||||||
|
}
|
||||||
|
return t.ZeroUid
|
||||||
|
}
|
||||||
|
|
||||||
type configType struct {
|
type configType struct {
|
||||||
// DB connection settings.
|
// DB connection settings.
|
||||||
// See https://pkg.go.dev/github.com/go-sql-driver/mysql#Config
|
// See https://pkg.go.dev/github.com/go-sql-driver/mysql#Config
|
||||||
@@ -742,6 +764,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
|||||||
if _, err = tx.Exec(
|
if _, err = tx.Exec(
|
||||||
`CREATE TABLE im_users(
|
`CREATE TABLE im_users(
|
||||||
id BIGINT NOT NULL,
|
id BIGINT NOT NULL,
|
||||||
|
account_no INT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
username VARCHAR(32) NOT NULL,
|
username VARCHAR(32) NOT NULL,
|
||||||
createdat DATETIME(3) NOT NULL,
|
createdat DATETIME(3) NOT NULL,
|
||||||
updatedat DATETIME(3) NOT NULL,
|
updatedat DATETIME(3) NOT NULL,
|
||||||
@@ -754,6 +777,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
|||||||
public JSON,
|
public JSON,
|
||||||
trusted JSON,
|
trusted JSON,
|
||||||
PRIMARY KEY(id),
|
PRIMARY KEY(id),
|
||||||
|
UNIQUE INDEX uk_im_users_account_no(account_no),
|
||||||
UNIQUE INDEX users_username(username),
|
UNIQUE INDEX users_username(username),
|
||||||
UNIQUE INDEX users_phone(phone),
|
UNIQUE INDEX users_phone(phone),
|
||||||
INDEX users_state_stateat(state, stateat),
|
INDEX users_state_stateat(state, stateat),
|
||||||
@@ -1087,6 +1111,9 @@ func (a *adapter) UpgradeDb() error {
|
|||||||
if err := a.ensureMessageTopicSeqIndex(); err != nil {
|
if err := a.ensureMessageTopicSeqIndex(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := a.ensureTopicNameUniqueIndex(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := a.ensureTopicSeqMatchesMessages(); err != nil {
|
if err := a.ensureTopicSeqMatchesMessages(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1115,6 +1142,97 @@ func (a *adapter) ensureMessageTopicSeqIndex() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *adapter) ensureTopicNameUniqueIndex() error {
|
||||||
|
ctx := context.Background()
|
||||||
|
conn, err := a.db.Connx(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
tenantScoped, err := identityColumnExists(ctx, conn, "im_topics", "tenant_id")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int
|
||||||
|
if tenantScoped {
|
||||||
|
if err = conn.QueryRowContext(ctx,
|
||||||
|
`SELECT COUNT(*) FROM information_schema.statistics
|
||||||
|
WHERE table_schema=DATABASE() AND table_name='im_topics' AND index_name='uk_topics_tenant_name' AND non_unique=0`,
|
||||||
|
).Scan(&count); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if _, err = conn.ExecContext(ctx, `UPDATE im_topics AS keep_t
|
||||||
|
JOIN (
|
||||||
|
SELECT tenant_id,name,MIN(id) AS keep_id,
|
||||||
|
MAX(seqid) AS seqid,MAX(delid) AS delid,
|
||||||
|
MAX(COALESCE(touchedat,'1000-01-01')) AS touchedat,
|
||||||
|
MAX(updatedat) AS updatedat
|
||||||
|
FROM im_topics GROUP BY tenant_id,name HAVING COUNT(*)>1
|
||||||
|
) AS dup ON dup.keep_id=keep_t.id
|
||||||
|
SET keep_t.seqid=GREATEST(keep_t.seqid,dup.seqid),
|
||||||
|
keep_t.delid=GREATEST(keep_t.delid,dup.delid),
|
||||||
|
keep_t.touchedat=NULLIF(GREATEST(COALESCE(keep_t.touchedat,'1000-01-01'),dup.touchedat),'1000-01-01'),
|
||||||
|
keep_t.updatedat=GREATEST(keep_t.updatedat,dup.updatedat)`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = conn.ExecContext(ctx, `DELETE t FROM im_topics AS t
|
||||||
|
JOIN (
|
||||||
|
SELECT tenant_id,name,MIN(id) AS keep_id
|
||||||
|
FROM im_topics GROUP BY tenant_id,name HAVING COUNT(*)>1
|
||||||
|
) AS dup ON dup.tenant_id=t.tenant_id AND dup.name=t.name AND t.id<>dup.keep_id`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = conn.ExecContext(ctx, "ALTER TABLE im_topics ADD UNIQUE INDEX uk_topics_tenant_name(tenant_id, name)")
|
||||||
|
if isDupe(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = conn.QueryRowContext(ctx,
|
||||||
|
`SELECT COUNT(*) FROM information_schema.statistics
|
||||||
|
WHERE table_schema=DATABASE() AND table_name='im_topics' AND index_name='topics_name' AND non_unique=0`,
|
||||||
|
).Scan(&count); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if _, err = conn.ExecContext(ctx, `UPDATE im_topics AS keep_t
|
||||||
|
JOIN (
|
||||||
|
SELECT name,MIN(id) AS keep_id,
|
||||||
|
MAX(seqid) AS seqid,MAX(delid) AS delid,
|
||||||
|
MAX(COALESCE(touchedat,'1000-01-01')) AS touchedat,
|
||||||
|
MAX(updatedat) AS updatedat
|
||||||
|
FROM im_topics GROUP BY name HAVING COUNT(*)>1
|
||||||
|
) AS dup ON dup.keep_id=keep_t.id
|
||||||
|
SET keep_t.seqid=GREATEST(keep_t.seqid,dup.seqid),
|
||||||
|
keep_t.delid=GREATEST(keep_t.delid,dup.delid),
|
||||||
|
keep_t.touchedat=NULLIF(GREATEST(COALESCE(keep_t.touchedat,'1000-01-01'),dup.touchedat),'1000-01-01'),
|
||||||
|
keep_t.updatedat=GREATEST(keep_t.updatedat,dup.updatedat)`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = conn.ExecContext(ctx, `DELETE t FROM im_topics AS t
|
||||||
|
JOIN (
|
||||||
|
SELECT name,MIN(id) AS keep_id
|
||||||
|
FROM im_topics GROUP BY name HAVING COUNT(*)>1
|
||||||
|
) AS dup ON dup.name=t.name AND t.id<>dup.keep_id`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = conn.ExecContext(ctx, "ALTER TABLE im_topics ADD UNIQUE INDEX topics_name(name)"); err != nil {
|
||||||
|
if isDupe(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *adapter) ensureTopicSeqMatchesMessages() error {
|
func (a *adapter) ensureTopicSeqMatchesMessages() error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
conn, err := a.db.Connx(ctx)
|
conn, err := a.db.Connx(ctx)
|
||||||
@@ -1241,13 +1359,13 @@ func createIMWorkbenchTables(tx *sql.Tx) error {
|
|||||||
_, err := tx.Exec(
|
_, err := tx.Exec(
|
||||||
`INSERT INTO im_workbench_apps(code,name,route,sort_order,unread_key,enabled,permission)
|
`INSERT INTO im_workbench_apps(code,name,route,sort_order,unread_key,enabled,permission)
|
||||||
VALUES
|
VALUES
|
||||||
('organization','组织架构','/organization',10,'organization',1,'enabled'),
|
('attendance','打卡','/attendance',10,'attendance',1,'enabled'),
|
||||||
('attendance','打卡','/attendance',20,'attendance',1,'enabled'),
|
('monthly_reports','月报','/reports/monthly',20,'monthly_reports',1,'enabled'),
|
||||||
('meetings','会议通知','/meetings',30,'meetings',1,'enabled'),
|
('daily_reports','日报','/reports/daily',30,'daily_reports',1,'enabled'),
|
||||||
('meeting_notes','会议笔记','/meeting-notes',35,'',1,'enabled'),
|
('organization','部门框架','/organization',40,'organization',1,'enabled'),
|
||||||
('daily_reports','日报','/reports/daily',40,'daily_reports',1,'enabled'),
|
('executive_mailbox','举报信箱','/executive-mailbox',50,'executive_mailbox',1,'enabled'),
|
||||||
('monthly_reports','月报','/reports/monthly',50,'monthly_reports',1,'enabled'),
|
('meetings','会议通知','/meetings',60,'meetings',1,'enabled'),
|
||||||
('executive_mailbox','总经理信箱','/executive-mailbox',60,'executive_mailbox',1,'enabled')
|
('meeting_notes','会议笔记','/meeting-notes',70,'',1,'enabled')
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
name=VALUES(name),
|
name=VALUES(name),
|
||||||
route=VALUES(route),
|
route=VALUES(route),
|
||||||
@@ -1607,7 +1725,7 @@ func ensureIMMeetingNotesTables(db *sqlx.DB) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err := db.Exec(`INSERT INTO im_workbench_apps(code,name,route,sort_order,unread_key,enabled,permission)
|
_, err := db.Exec(`INSERT INTO im_workbench_apps(code,name,route,sort_order,unread_key,enabled,permission)
|
||||||
VALUES('meeting_notes','会议笔记','/meeting-notes',35,'',1,'enabled')
|
VALUES('meeting_notes','会议笔记','/meeting-notes',70,'',1,'enabled')
|
||||||
ON DUPLICATE KEY UPDATE name=VALUES(name),route=VALUES(route),sort_order=VALUES(sort_order),unread_key=VALUES(unread_key),updated_at=CURRENT_TIMESTAMP(3)`)
|
ON DUPLICATE KEY UPDATE name=VALUES(name),route=VALUES(route),sort_order=VALUES(sort_order),unread_key=VALUES(unread_key),updated_at=CURRENT_TIMESTAMP(3)`)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1733,30 +1851,13 @@ func createIMUserProductTables(tx *sql.Tx) error {
|
|||||||
profile_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
profile_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
||||||
last_seen_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
last_seen_visibility VARCHAR(32) NOT NULL DEFAULT 'friends',
|
||||||
read_receipts TINYINT NOT NULL DEFAULT 1,
|
read_receipts TINYINT NOT NULL DEFAULT 1,
|
||||||
|
group_invite_verification TINYINT NOT NULL DEFAULT 0,
|
||||||
version INT NOT NULL DEFAULT 1,
|
version INT NOT NULL DEFAULT 1,
|
||||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||||
PRIMARY KEY(id),
|
PRIMARY KEY(id),
|
||||||
UNIQUE INDEX uk_im_user_privacy_settings_user(user_id)
|
UNIQUE INDEX uk_im_user_privacy_settings_user(user_id)
|
||||||
)`,
|
)`,
|
||||||
`CREATE TABLE im_app_releases(
|
|
||||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
platform VARCHAR(32) NOT NULL,
|
|
||||||
channel VARCHAR(32) NOT NULL DEFAULT 'stable',
|
|
||||||
latest_version VARCHAR(64) NOT NULL,
|
|
||||||
min_supported_version VARCHAR(64) NOT NULL,
|
|
||||||
update_type VARCHAR(16) NOT NULL DEFAULT 'none',
|
|
||||||
release_notes TEXT NOT NULL,
|
|
||||||
store_url VARCHAR(512) NOT NULL DEFAULT '',
|
|
||||||
package_url VARCHAR(512) NOT NULL DEFAULT '',
|
|
||||||
checksum VARCHAR(128) NOT NULL DEFAULT '',
|
|
||||||
remind_after_seconds INT NOT NULL DEFAULT 0,
|
|
||||||
published_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
||||||
PRIMARY KEY(id),
|
|
||||||
UNIQUE INDEX uk_im_app_releases_platform_channel(platform, channel)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE im_device_push_tokens(
|
`CREATE TABLE im_device_push_tokens(
|
||||||
id BIGINT NOT NULL,
|
id BIGINT NOT NULL,
|
||||||
device_id VARCHAR(128) NOT NULL,
|
device_id VARCHAR(128) NOT NULL,
|
||||||
@@ -2209,8 +2310,18 @@ func (a *adapter) UserCreate(user *t.User) error {
|
|||||||
user.Phone = canonicalPhone
|
user.Phone = canonicalPhone
|
||||||
phone = canonicalPhone
|
phone = canonicalPhone
|
||||||
}
|
}
|
||||||
if _, err = tx.Exec("INSERT INTO im_users(id,username,createdat,updatedat,state,access,phone,public,trusted) VALUES(?,?,?,?,?,?,?,?,?)",
|
releaseAccountNoLock, err := lockUserAccountNoSequence(ctx, tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer releaseAccountNoLock()
|
||||||
|
accountNo, err := nextUserAccountNo(ctx, tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = tx.Exec("INSERT INTO im_users(id,account_no,username,createdat,updatedat,state,access,phone,public,trusted) VALUES(?,?,?,?,?,?,?,?,?,?)",
|
||||||
decoded_uid,
|
decoded_uid,
|
||||||
|
accountNo,
|
||||||
user.Username,
|
user.Username,
|
||||||
user.CreatedAt,
|
user.CreatedAt,
|
||||||
user.UpdatedAt,
|
user.UpdatedAt,
|
||||||
@@ -2239,6 +2350,34 @@ func (a *adapter) UserCreate(user *t.User) error {
|
|||||||
return tx.Commit()
|
return tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lockUserAccountNoSequence(ctx context.Context, tx *sqlx.Tx) (func(), error) {
|
||||||
|
var locked sql.NullInt64
|
||||||
|
if err := tx.QueryRowContext(ctx, "SELECT GET_LOCK(CONCAT(DATABASE(), ':im_users_account_no'), 10)").Scan(&locked); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !locked.Valid || locked.Int64 != 1 {
|
||||||
|
return nil, fmt.Errorf("lock user account number sequence timeout")
|
||||||
|
}
|
||||||
|
return func() {
|
||||||
|
_, _ = tx.ExecContext(ctx, "SELECT RELEASE_LOCK(CONCAT(DATABASE(), ':im_users_account_no'))")
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextUserAccountNo(ctx context.Context, tx *sqlx.Tx) (int64, error) {
|
||||||
|
var current sql.NullInt64
|
||||||
|
err := tx.QueryRowContext(ctx, "SELECT account_no FROM im_users ORDER BY account_no DESC LIMIT 1 FOR UPDATE").Scan(¤t)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return 1000, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if !current.Valid || current.Int64 < 999 {
|
||||||
|
return 1000, nil
|
||||||
|
}
|
||||||
|
return current.Int64 + 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TenantAuthAddRecord adds the user's Basic authentication record.
|
// TenantAuthAddRecord adds the user's Basic authentication record.
|
||||||
func (a *adapter) TenantAuthAddRecord(tenantID t.TenantID, uid t.Uid,
|
func (a *adapter) TenantAuthAddRecord(tenantID t.TenantID, uid t.Uid,
|
||||||
authLvl auth.Level, secret []byte, expires time.Time) error {
|
authLvl auth.Level, secret []byte, expires time.Time) error {
|
||||||
@@ -3144,6 +3283,7 @@ func (a *adapter) TopicsForUser(uid t.Uid, keepDeleted bool, opts *t.QueryOpt) (
|
|||||||
limit = a.maxResults
|
limit = a.maxResults
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q += " ORDER BY topic ASC, deletedat IS NULL DESC, updatedat DESC, id DESC"
|
||||||
if limit > 0 {
|
if limit > 0 {
|
||||||
q += " LIMIT ?"
|
q += " LIMIT ?"
|
||||||
args = append(args, limit)
|
args = append(args, limit)
|
||||||
@@ -3162,6 +3302,7 @@ func (a *adapter) TopicsForUser(uid t.Uid, keepDeleted bool, opts *t.QueryOpt) (
|
|||||||
// Fetch subscriptions. Two queries are needed: users table (p2p) and topics table (grp).
|
// Fetch subscriptions. Two queries are needed: users table (p2p) and topics table (grp).
|
||||||
// Prepare a list of separate subscriptions to users vs topics
|
// Prepare a list of separate subscriptions to users vs topics
|
||||||
join := make(map[string]t.Subscription) // Keeping these to make a join with table for .private and .access
|
join := make(map[string]t.Subscription) // Keeping these to make a join with table for .private and .access
|
||||||
|
p2pResolved := make(map[string]bool)
|
||||||
topq := make([]any, 0, 16)
|
topq := make([]any, 0, 16)
|
||||||
usrq := make([]any, 0, 16)
|
usrq := make([]any, 0, 16)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@@ -3171,7 +3312,12 @@ func (a *adapter) TopicsForUser(uid t.Uid, keepDeleted bool, opts *t.QueryOpt) (
|
|||||||
}
|
}
|
||||||
tname := sub.Topic
|
tname := sub.Topic
|
||||||
sub.User = uid.String()
|
sub.User = uid.String()
|
||||||
|
if !t.ParseUserId(tname).IsZero() {
|
||||||
|
// Legacy self-user subscriptions are not conversation entries.
|
||||||
|
continue
|
||||||
|
}
|
||||||
tcat := t.GetTopicCat(tname)
|
tcat := t.GetTopicCat(tname)
|
||||||
|
peerID := ""
|
||||||
|
|
||||||
if tcat == t.TopicCatMe || tcat == t.TopicCatFnd {
|
if tcat == t.TopicCatMe || tcat == t.TopicCatFnd {
|
||||||
// One of 'me', 'fnd' subscriptions, skip.
|
// One of 'me', 'fnd' subscriptions, skip.
|
||||||
@@ -3180,21 +3326,30 @@ func (a *adapter) TopicsForUser(uid t.Uid, keepDeleted bool, opts *t.QueryOpt) (
|
|||||||
} else if tcat == t.TopicCatP2P {
|
} else if tcat == t.TopicCatP2P {
|
||||||
// P2P subscription, find the other user to get user.Public and user.Trusted.
|
// P2P subscription, find the other user to get user.Public and user.Trusted.
|
||||||
uid1, uid2, _ := t.ParseP2P(tname)
|
uid1, uid2, _ := t.ParseP2P(tname)
|
||||||
|
p2pResolved[tname] = false
|
||||||
if uid1 == uid {
|
if uid1 == uid {
|
||||||
usrq = append(usrq, store.DecodeUid(uid2))
|
usrq = append(usrq, store.DecodeUid(uid2))
|
||||||
sub.SetWith(uid2.UserId())
|
peerID = uid2.UserId()
|
||||||
|
sub.SetWith(peerID)
|
||||||
} else {
|
} else {
|
||||||
usrq = append(usrq, store.DecodeUid(uid1))
|
usrq = append(usrq, store.DecodeUid(uid1))
|
||||||
sub.SetWith(uid1.UserId())
|
peerID = uid1.UserId()
|
||||||
|
sub.SetWith(peerID)
|
||||||
}
|
}
|
||||||
} else if tcat == t.TopicCatGrp {
|
} else if tcat == t.TopicCatGrp {
|
||||||
// Maybe convert channel name to group topic name.
|
// Maybe convert channel name to group topic name.
|
||||||
tname = t.ChnToGrp(tname)
|
tname = t.ChnToGrp(tname)
|
||||||
}
|
}
|
||||||
|
if _, exists := join[tname]; exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// No special handling needed for 'slf', 'sys' subscriptions.
|
// No special handling needed for 'slf', 'sys' subscriptions.
|
||||||
|
|
||||||
topq = append(topq, tname)
|
topq = append(topq, tname)
|
||||||
sub.Private = common.FromJSON(sub.Private)
|
sub.Private = common.FromJSON(sub.Private)
|
||||||
|
if tcat == t.TopicCatP2P {
|
||||||
|
sub.Private = ensureP2PPrivatePeer(sub.Private, peerID)
|
||||||
|
}
|
||||||
join[tname] = sub
|
join[tname] = sub
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -3312,6 +3467,7 @@ func (a *adapter) TopicsForUser(uid t.Uid, keepDeleted bool, opts *t.QueryOpt) (
|
|||||||
sub.SetDefaultAccess(usr2.Access.Auth, usr2.Access.Anon)
|
sub.SetDefaultAccess(usr2.Access.Auth, usr2.Access.Anon)
|
||||||
sub.SetLastSeenAndUA(usr2.lastSeen(), usr2.UserAgent)
|
sub.SetLastSeenAndUA(usr2.lastSeen(), usr2.UserAgent)
|
||||||
join[joinOn] = sub
|
join[joinOn] = sub
|
||||||
|
p2pResolved[joinOn] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -3326,6 +3482,9 @@ func (a *adapter) TopicsForUser(uid t.Uid, keepDeleted bool, opts *t.QueryOpt) (
|
|||||||
|
|
||||||
subs = make([]t.Subscription, 0, len(join))
|
subs = make([]t.Subscription, 0, len(join))
|
||||||
for _, sub := range join {
|
for _, sub := range join {
|
||||||
|
if t.GetTopicCat(sub.Topic) == t.TopicCatP2P && !p2pResolved[sub.Topic] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
subs = append(subs, sub)
|
subs = append(subs, sub)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4994,7 +5153,7 @@ func (a *adapter) FileFinishUpload(fd *t.FileDef, success bool, size int64) (*t.
|
|||||||
|
|
||||||
// FileGet fetches a record of a specific file
|
// FileGet fetches a record of a specific file
|
||||||
func (a *adapter) FileGet(fid string) (*t.FileDef, error) {
|
func (a *adapter) FileGet(fid string) (*t.FileDef, error) {
|
||||||
id := t.ParseUid(fid)
|
id := parseFileUID(fid)
|
||||||
if id.IsZero() {
|
if id.IsZero() {
|
||||||
return nil, t.ErrMalformed
|
return nil, t.ErrMalformed
|
||||||
}
|
}
|
||||||
@@ -5188,7 +5347,7 @@ func (a *adapter) FileUserHasAccess(fid string, uid t.Uid) (bool, error) {
|
|||||||
if uid.IsZero() {
|
if uid.IsZero() {
|
||||||
return false, t.ErrMalformed
|
return false, t.ErrMalformed
|
||||||
}
|
}
|
||||||
fileID := t.ParseUid(fid)
|
fileID := parseFileUID(fid)
|
||||||
if fileID.IsZero() {
|
if fileID.IsZero() {
|
||||||
return false, t.ErrMalformed
|
return false, t.ErrMalformed
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
//go:build mysql
|
||||||
|
// +build mysql
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/tinode/chat/server/store/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseFileUIDStripsPublicExtension(t *testing.T) {
|
||||||
|
uid := types.ParseUid("scH0N8guCHk")
|
||||||
|
if uid.IsZero() {
|
||||||
|
t.Fatal("test UID failed to parse")
|
||||||
|
}
|
||||||
|
if got := parseFileUID("scH0N8guCHk.bin"); got != uid {
|
||||||
|
t.Fatalf("parseFileUID()=%q, want %q", got.String(), uid.String())
|
||||||
|
}
|
||||||
|
if got := parseFileUID("scH0N8guCHk.jpg"); got != uid {
|
||||||
|
t.Fatalf("parseFileUID()=%q, want %q", got.String(), uid.String())
|
||||||
|
}
|
||||||
|
if got := parseFileUID("scH0N8guCHk"); got != uid {
|
||||||
|
t.Fatalf("parseFileUID()=%q, want %q", got.String(), uid.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,12 +9,18 @@ import (
|
|||||||
mysqldriver "github.com/go-sql-driver/mysql"
|
mysqldriver "github.com/go-sql-driver/mysql"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ignoreSQLError struct {
|
||||||
|
sql string
|
||||||
|
code uint16
|
||||||
|
}
|
||||||
|
|
||||||
func ensureIMRegistrationInviteControlTables(exec sqlExecutor) error {
|
func ensureIMRegistrationInviteControlTables(exec sqlExecutor) error {
|
||||||
statements := []string{
|
statements := []string{
|
||||||
`CREATE TABLE IF NOT EXISTS im_registration_invite_batches(
|
`CREATE TABLE IF NOT EXISTS im_registration_invite_batches(
|
||||||
id BIGINT NOT NULL,
|
id BIGINT NOT NULL,
|
||||||
tenant_id BIGINT NOT NULL,
|
tenant_id BIGINT NOT NULL,
|
||||||
quantity INT UNSIGNED NOT NULL,
|
quantity INT UNSIGNED NOT NULL,
|
||||||
|
max_uses_per_code INT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
idempotency_key VARCHAR(128) NOT NULL,
|
idempotency_key VARCHAR(128) NOT NULL,
|
||||||
expires_at DATETIME(3) NOT NULL,
|
expires_at DATETIME(3) NOT NULL,
|
||||||
created_by BIGINT NOT NULL,
|
created_by BIGINT NOT NULL,
|
||||||
@@ -32,6 +38,9 @@ func ensureIMRegistrationInviteControlTables(exec sqlExecutor) error {
|
|||||||
code CHAR(5) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
code CHAR(5) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||||
status VARCHAR(16) NOT NULL,
|
status VARCHAR(16) NOT NULL,
|
||||||
expires_at DATETIME(3) NOT NULL,
|
expires_at DATETIME(3) NOT NULL,
|
||||||
|
max_uses INT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
bound_user_id BIGINT NULL,
|
||||||
|
bound_user_label VARCHAR(128) NOT NULL DEFAULT '',
|
||||||
usage_count INT UNSIGNED NOT NULL DEFAULT 0,
|
usage_count INT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
last_used_at DATETIME(3) NULL,
|
last_used_at DATETIME(3) NULL,
|
||||||
created_by BIGINT NOT NULL,
|
created_by BIGINT NOT NULL,
|
||||||
@@ -40,6 +49,7 @@ func ensureIMRegistrationInviteControlTables(exec sqlExecutor) error {
|
|||||||
updated_at DATETIME(3) NOT NULL,
|
updated_at DATETIME(3) NOT NULL,
|
||||||
PRIMARY KEY(id),
|
PRIMARY KEY(id),
|
||||||
UNIQUE INDEX uk_im_registration_invite_code_tenant(tenant_id,code),
|
UNIQUE INDEX uk_im_registration_invite_code_tenant(tenant_id,code),
|
||||||
|
INDEX idx_im_registration_invite_tenant_bound_user(tenant_id,bound_user_id),
|
||||||
INDEX idx_im_registration_invite_tenant_status_expires(tenant_id,status,expires_at),
|
INDEX idx_im_registration_invite_tenant_status_expires(tenant_id,status,expires_at),
|
||||||
INDEX idx_im_registration_invite_tenant_batch(tenant_id,batch_id),
|
INDEX idx_im_registration_invite_tenant_batch(tenant_id,batch_id),
|
||||||
INDEX idx_im_registration_invite_tenant_created(tenant_id,created_at)
|
INDEX idx_im_registration_invite_tenant_created(tenant_id,created_at)
|
||||||
@@ -50,6 +60,29 @@ func ensureIMRegistrationInviteControlTables(exec sqlExecutor) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
alterStatements := []ignoreSQLError{
|
||||||
|
{`ALTER TABLE im_registration_invite_codes ADD COLUMN max_uses INT UNSIGNED NOT NULL DEFAULT 0 AFTER expires_at`, 1060},
|
||||||
|
{`ALTER TABLE im_registration_invite_codes ADD COLUMN bound_user_id BIGINT NULL AFTER max_uses`, 1060},
|
||||||
|
{`ALTER TABLE im_registration_invite_codes ADD COLUMN bound_user_label VARCHAR(128) NOT NULL DEFAULT '' AFTER bound_user_id`, 1060},
|
||||||
|
{`ALTER TABLE im_registration_invite_codes ADD INDEX idx_im_registration_invite_tenant_bound_user(tenant_id,bound_user_id)`, 1061},
|
||||||
|
{`ALTER TABLE im_registration_invite_batches ADD COLUMN max_uses_per_code INT UNSIGNED NOT NULL DEFAULT 0 AFTER quantity`, 1060},
|
||||||
|
}
|
||||||
|
for _, stmt := range alterStatements {
|
||||||
|
if err := execIgnoreMySQLError(exec, stmt.sql, stmt.code); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func execIgnoreMySQLError(exec sqlExecutor, statement string, code uint16) error {
|
||||||
|
if _, err := exec.Exec(statement); err != nil {
|
||||||
|
var mysqlErr *mysqldriver.MySQLError
|
||||||
|
if errors.As(err, &mysqlErr) && mysqlErr.Number == code {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package mysql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -60,8 +61,8 @@ func (a *adapter) TenantRegistrationInviteCreate(id t.TenantID, code *t.Registra
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
_, err = a.registrationInviteControlDB().ExecContext(ctx, `INSERT INTO im_registration_invite_codes
|
_, err = a.registrationInviteControlDB().ExecContext(ctx, `INSERT INTO im_registration_invite_codes
|
||||||
(id,tenant_id,batch_id,code,status,expires_at,usage_count,last_used_at,created_by,remark,created_at,updated_at)
|
(id,tenant_id,batch_id,code,status,expires_at,max_uses,usage_count,last_used_at,created_by,remark,created_at,updated_at)
|
||||||
VALUES(?,?,?,?,?,?,0,NULL,?,?,?,?)`, code.ID, id, code.BatchID, code.Code, code.Status, code.ExpiresAt,
|
VALUES(?,?,?,?,?,?,1,0,NULL,?,?,?,?)`, code.ID, id, code.BatchID, code.Code, code.Status, code.ExpiresAt,
|
||||||
code.CreatedBy, code.Remark, code.CreatedAt, code.UpdatedAt)
|
code.CreatedBy, code.Remark, code.CreatedAt, code.UpdatedAt)
|
||||||
if isDupe(err) {
|
if isDupe(err) {
|
||||||
return t.ErrDuplicate
|
return t.ErrDuplicate
|
||||||
@@ -128,8 +129,8 @@ func (a *adapter) TenantRegistrationInviteCreateBatch(id t.TenantID, batch *t.Re
|
|||||||
codes[i].Remark = batch.Remark
|
codes[i].Remark = batch.Remark
|
||||||
codes[i].CreatedAt, codes[i].UpdatedAt = now, now
|
codes[i].CreatedAt, codes[i].UpdatedAt = now, now
|
||||||
if _, err = tx.ExecContext(ctx, `INSERT INTO im_registration_invite_codes
|
if _, err = tx.ExecContext(ctx, `INSERT INTO im_registration_invite_codes
|
||||||
(id,tenant_id,batch_id,code,status,expires_at,usage_count,last_used_at,created_by,remark,created_at,updated_at)
|
(id,tenant_id,batch_id,code,status,expires_at,max_uses,usage_count,last_used_at,created_by,remark,created_at,updated_at)
|
||||||
VALUES(?,?,?,?,?,?,0,NULL,?,?,?,?)`, codes[i].ID, id, batch.ID, codes[i].Code, codes[i].Status,
|
VALUES(?,?,?,?,?,?,0,0,NULL,?,?,?,?)`, codes[i].ID, id, batch.ID, codes[i].Code, codes[i].Status,
|
||||||
codes[i].ExpiresAt, codes[i].CreatedBy, codes[i].Remark, now, now); err != nil {
|
codes[i].ExpiresAt, codes[i].CreatedBy, codes[i].Remark, now, now); err != nil {
|
||||||
if isDupe(err) {
|
if isDupe(err) {
|
||||||
return t.ErrDuplicate
|
return t.ErrDuplicate
|
||||||
@@ -156,7 +157,7 @@ func (a *adapter) TenantRegistrationInviteGetByCode(id t.TenantID, value string)
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
var code t.RegistrationInviteCode
|
var code t.RegistrationInviteCode
|
||||||
err = a.registrationInviteControlDB().GetContext(ctx, &code, `SELECT c.id,c.tenant_id,c.batch_id,c.code,c.status,c.expires_at,
|
err = a.registrationInviteControlDB().GetContext(ctx, &code, `SELECT c.id,c.tenant_id,c.batch_id,c.code,c.status,c.expires_at,c.max_uses,c.bound_user_id,
|
||||||
c.created_by,c.remark,c.created_at,c.updated_at,c.usage_count,c.last_used_at
|
c.created_by,c.remark,c.created_at,c.updated_at,c.usage_count,c.last_used_at
|
||||||
FROM im_registration_invite_codes AS c
|
FROM im_registration_invite_codes AS c
|
||||||
WHERE c.tenant_id=? AND c.code=? LIMIT 1`, id, value)
|
WHERE c.tenant_id=? AND c.code=? LIMIT 1`, id, value)
|
||||||
@@ -227,7 +228,7 @@ func (a *adapter) TenantRegistrationInviteList(id t.TenantID, opts t.Registratio
|
|||||||
}
|
}
|
||||||
queryArgs := append(append([]any{}, args...), opts.Limit, opts.Offset)
|
queryArgs := append(append([]any{}, args...), opts.Limit, opts.Offset)
|
||||||
var items []t.RegistrationInviteCode
|
var items []t.RegistrationInviteCode
|
||||||
err = controlDB.SelectContext(ctx, &items, `SELECT c.id,c.tenant_id,c.batch_id,c.code,c.status,c.expires_at,
|
err = controlDB.SelectContext(ctx, &items, `SELECT c.id,c.tenant_id,c.batch_id,c.code,c.status,c.expires_at,c.max_uses,c.bound_user_id,
|
||||||
c.created_by,c.remark,c.created_at,c.updated_at,c.usage_count,c.last_used_at
|
c.created_by,c.remark,c.created_at,c.updated_at,c.usage_count,c.last_used_at
|
||||||
FROM im_registration_invite_codes AS c
|
FROM im_registration_invite_codes AS c
|
||||||
WHERE `+filter+` ORDER BY c.created_at DESC,c.id DESC LIMIT ? OFFSET ?`, queryArgs...)
|
WHERE `+filter+` ORDER BY c.created_at DESC,c.id DESC LIMIT ? OFFSET ?`, queryArgs...)
|
||||||
@@ -348,12 +349,14 @@ func (a *adapter) TenantRegistrationInviteRecordUse(id t.TenantID, value string,
|
|||||||
ID int64 `db:"id"`
|
ID int64 `db:"id"`
|
||||||
Status t.RegistrationInviteStatus `db:"status"`
|
Status t.RegistrationInviteStatus `db:"status"`
|
||||||
ExpiresAt time.Time `db:"expires_at"`
|
ExpiresAt time.Time `db:"expires_at"`
|
||||||
|
MaxUses int `db:"max_uses"`
|
||||||
|
BoundUserID *int64 `db:"bound_user_id"`
|
||||||
}
|
}
|
||||||
ctx, cancel := a.getContext()
|
ctx, cancel := a.getContext()
|
||||||
if cancel != nil {
|
if cancel != nil {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
err = a.registrationInviteControlDB().GetContext(ctx, &row, `SELECT id,status,expires_at
|
err = a.registrationInviteControlDB().GetContext(ctx, &row, `SELECT id,status,expires_at,max_uses,bound_user_id
|
||||||
FROM im_registration_invite_codes WHERE tenant_id=? AND code=? LIMIT 1`, id, value)
|
FROM im_registration_invite_codes WHERE tenant_id=? AND code=? LIMIT 1`, id, value)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return t.ErrInviteInvalid
|
return t.ErrInviteInvalid
|
||||||
@@ -384,6 +387,16 @@ func (a *adapter) TenantRegistrationInviteRecordUse(id t.TenantID, value string,
|
|||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
if row.MaxUses > 0 {
|
||||||
|
var usedCount int
|
||||||
|
if err = tx.GetContext(txCtx, &usedCount,
|
||||||
|
"SELECT COUNT(*) FROM im_registration_invite_uses WHERE invite_code_id=?", row.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if usedCount >= row.MaxUses {
|
||||||
|
return t.ErrInviteInvalid
|
||||||
|
}
|
||||||
|
}
|
||||||
useID, err := nextSnowflakeID()
|
useID, err := nextSnowflakeID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -403,9 +416,17 @@ func (a *adapter) TenantRegistrationInviteRecordUse(id t.TenantID, value string,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if row.BoundUserID != nil && *row.BoundUserID > 0 {
|
||||||
|
boundUID := t.ParseUserId(strconv.FormatInt(*row.BoundUserID, 10))
|
||||||
|
if !boundUID.IsZero() && boundUID != uid {
|
||||||
|
if err = upsertFriendshipPairTx(tx, uid, boundUID, uid.P2PName(boundUID), now); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
eventID := t.StableEventID("registration-invite-use", id, row.ID, store.DecodeUid(uid))
|
eventID := t.StableEventID("registration-invite-use", id, row.ID, store.DecodeUid(uid))
|
||||||
if err = insertBusinessEventTx(tx, eventID, "user", uid.UserId(), uid, "registration.invite_used", map[string]any{
|
if err = insertBusinessEventTx(tx, eventID, "user", uid.UserId(), uid, "registration.invite_used", map[string]any{
|
||||||
"tenant_id": id, "invite_code_id": row.ID, "user_id": store.DecodeUid(uid),
|
"tenant_id": id, "invite_code_id": row.ID, "user_id": store.DecodeUid(uid), "bound_user_id": row.BoundUserID,
|
||||||
"request_id": requestID, "used_at": now,
|
"request_id": requestID, "used_at": now,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -413,6 +434,28 @@ func (a *adapter) TenantRegistrationInviteRecordUse(id t.TenantID, value string,
|
|||||||
return tx.Commit()
|
return tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func upsertFriendshipPairTx(tx *sqlx.Tx, uid1, uid2 t.Uid, topic string, now time.Time) error {
|
||||||
|
if uid1.IsZero() || uid2.IsZero() || uid1 == uid2 {
|
||||||
|
return t.ErrMalformed
|
||||||
|
}
|
||||||
|
if topic == "" {
|
||||||
|
topic = uid1.P2PName(uid2)
|
||||||
|
}
|
||||||
|
for _, pair := range [][2]t.Uid{{uid1, uid2}, {uid2, uid1}} {
|
||||||
|
friendshipID, err := nextSnowflakeID()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = tx.Exec(
|
||||||
|
"INSERT INTO im_friendships(id,user_id,peer_id,status,topic,created_at,updated_at) VALUES(?,?,?,?,?,?,?) "+
|
||||||
|
"ON DUPLICATE KEY UPDATE status=VALUES(status),topic=VALUES(topic),updated_at=VALUES(updated_at)",
|
||||||
|
friendshipID, decodeUID(pair[0]), decodeUID(pair[1]), t.RelationshipFriend, topic, now, now); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// TenantRegistrationInviteSyncUsage projects the tenant usage aggregate to the
|
// TenantRegistrationInviteSyncUsage projects the tenant usage aggregate to the
|
||||||
// control database. The overwrite is idempotent, so outbox retries are safe.
|
// control database. The overwrite is idempotent, so outbox retries are safe.
|
||||||
func (a *adapter) TenantRegistrationInviteSyncUsage(id t.TenantID, codeID int64) error {
|
func (a *adapter) TenantRegistrationInviteSyncUsage(id t.TenantID, codeID int64) error {
|
||||||
|
|||||||
@@ -55,6 +55,47 @@ func TestMessageSearchDoesNotClearScannedHead(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSearchPaginationCursorUsesLastReturnedRow(t *testing.T) {
|
||||||
|
source, err := os.ReadFile("tenant_adapter.go")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
body := string(source)
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
function string
|
||||||
|
forbidden string
|
||||||
|
required string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "p2p message search",
|
||||||
|
function: "func (a *adapter) TenantMessageSearch",
|
||||||
|
forbidden: "nextCursor = strconv.FormatInt(msg.SeqId, 10)",
|
||||||
|
required: "nextCursor = strconv.FormatInt(lastSeq, 10)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "group message search",
|
||||||
|
function: "func (a *adapter) tenantGroupMessageSearch",
|
||||||
|
forbidden: "nextCursor = strconv.FormatInt(msg.SeqId, 10)",
|
||||||
|
required: "nextCursor = strconv.FormatInt(lastSeq, 10)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "favorite list",
|
||||||
|
function: "func (a *adapter) TenantFavoriteList",
|
||||||
|
forbidden: "nextCursor = strconv.FormatInt(item.ID, 10)",
|
||||||
|
required: "nextCursor = strconv.FormatInt(lastID, 10)",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
fn := functionSource(t, body, tc.function)
|
||||||
|
if strings.Contains(fn, tc.forbidden) {
|
||||||
|
t.Fatalf("%s must not use the extra fetched row as next cursor", tc.name)
|
||||||
|
}
|
||||||
|
if !strings.Contains(fn, tc.required) {
|
||||||
|
t.Fatalf("%s must use the last returned row as next cursor", tc.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTenantFileAccessIncludesAvatarAudienceRules(t *testing.T) {
|
func TestTenantFileAccessIncludesAvatarAudienceRules(t *testing.T) {
|
||||||
source, err := os.ReadFile("tenant_adapter.go")
|
source, err := os.ReadFile("tenant_adapter.go")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -72,3 +113,16 @@ func TestTenantFileAccessIncludesAvatarAudienceRules(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func functionSource(t *testing.T, source, marker string) string {
|
||||||
|
t.Helper()
|
||||||
|
start := strings.Index(source, marker)
|
||||||
|
if start < 0 {
|
||||||
|
t.Fatalf("function %q not found", marker)
|
||||||
|
}
|
||||||
|
next := strings.Index(source[start+len(marker):], "\nfunc ")
|
||||||
|
if next < 0 {
|
||||||
|
return source[start:]
|
||||||
|
}
|
||||||
|
return source[start : start+len(marker)+next]
|
||||||
|
}
|
||||||
|
|||||||
@@ -150,6 +150,20 @@ func profilePublicFromFields(base any, nickname, avatarFileID, signature, gender
|
|||||||
return public
|
return public
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureP2PPrivatePeer(private any, peerID string) any {
|
||||||
|
if strings.TrimSpace(peerID) == "" {
|
||||||
|
return private
|
||||||
|
}
|
||||||
|
data, _ := private.(map[string]any)
|
||||||
|
if data == nil {
|
||||||
|
data = map[string]any{}
|
||||||
|
}
|
||||||
|
if _, ok := data["peer"]; !ok {
|
||||||
|
data["peer"] = peerID
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
func clearProfilePublicFields(public map[string]any) {
|
func clearProfilePublicFields(public map[string]any) {
|
||||||
for _, key := range []string{"display_name", "nickname", "fn", "name", "avatar_file_id", "photo", "avatar", "signature", "gender", "region", "public_account"} {
|
for _, key := range []string{"display_name", "nickname", "fn", "name", "avatar_file_id", "photo", "avatar", "signature", "gender", "region", "public_account"} {
|
||||||
delete(public, key)
|
delete(public, key)
|
||||||
@@ -929,6 +943,7 @@ func (a *adapter) TenantTopicsForUser(id t.TenantID, uid t.Uid, keepDeleted bool
|
|||||||
} else {
|
} else {
|
||||||
limit = a.maxResults
|
limit = a.maxResults
|
||||||
}
|
}
|
||||||
|
q += " ORDER BY topic ASC, deletedat IS NULL DESC, updatedat DESC, id DESC"
|
||||||
if limit > 0 {
|
if limit > 0 {
|
||||||
q += " LIMIT ?"
|
q += " LIMIT ?"
|
||||||
args = append(args, limit)
|
args = append(args, limit)
|
||||||
@@ -942,6 +957,7 @@ func (a *adapter) TenantTopicsForUser(id t.TenantID, uid t.Uid, keepDeleted bool
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
join := map[string]t.Subscription{}
|
join := map[string]t.Subscription{}
|
||||||
|
p2pResolved := map[string]bool{}
|
||||||
var topq, usrq []any
|
var topq, usrq []any
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var sub t.Subscription
|
var sub t.Subscription
|
||||||
@@ -951,23 +967,36 @@ func (a *adapter) TenantTopicsForUser(id t.TenantID, uid t.Uid, keepDeleted bool
|
|||||||
}
|
}
|
||||||
tname := sub.Topic
|
tname := sub.Topic
|
||||||
sub.User = uid.String()
|
sub.User = uid.String()
|
||||||
|
if !t.ParseUserId(tname).IsZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
peerID := ""
|
||||||
switch t.GetTopicCat(tname) {
|
switch t.GetTopicCat(tname) {
|
||||||
case t.TopicCatMe, t.TopicCatFnd:
|
case t.TopicCatMe, t.TopicCatFnd:
|
||||||
continue
|
continue
|
||||||
case t.TopicCatP2P:
|
case t.TopicCatP2P:
|
||||||
uid1, uid2, _ := t.ParseP2P(tname)
|
uid1, uid2, _ := t.ParseP2P(tname)
|
||||||
|
p2pResolved[tname] = false
|
||||||
if uid1 == uid {
|
if uid1 == uid {
|
||||||
usrq = append(usrq, decodeUID(uid2))
|
usrq = append(usrq, decodeUID(uid2))
|
||||||
sub.SetWith(uid2.UserId())
|
peerID = uid2.UserId()
|
||||||
|
sub.SetWith(peerID)
|
||||||
} else {
|
} else {
|
||||||
usrq = append(usrq, decodeUID(uid1))
|
usrq = append(usrq, decodeUID(uid1))
|
||||||
sub.SetWith(uid1.UserId())
|
peerID = uid1.UserId()
|
||||||
|
sub.SetWith(peerID)
|
||||||
}
|
}
|
||||||
case t.TopicCatGrp:
|
case t.TopicCatGrp:
|
||||||
tname = t.ChnToGrp(tname)
|
tname = t.ChnToGrp(tname)
|
||||||
}
|
}
|
||||||
|
if _, exists := join[tname]; exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
topq = append(topq, tname)
|
topq = append(topq, tname)
|
||||||
sub.Private = common.FromJSON(sub.Private)
|
sub.Private = common.FromJSON(sub.Private)
|
||||||
|
if t.GetTopicCat(sub.Topic) == t.TopicCatP2P {
|
||||||
|
sub.Private = ensureP2PPrivatePeer(sub.Private, peerID)
|
||||||
|
}
|
||||||
join[tname] = sub
|
join[tname] = sub
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
@@ -1047,6 +1076,7 @@ func (a *adapter) TenantTopicsForUser(id t.TenantID, uid t.Uid, keepDeleted bool
|
|||||||
sub.SetDefaultAccess(user.Access.Auth, user.Access.Anon)
|
sub.SetDefaultAccess(user.Access.Auth, user.Access.Anon)
|
||||||
sub.SetLastSeenAndUA(user.lastSeen(), user.UserAgent)
|
sub.SetLastSeenAndUA(user.lastSeen(), user.UserAgent)
|
||||||
join[joinOn] = sub
|
join[joinOn] = sub
|
||||||
|
p2pResolved[joinOn] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
@@ -1057,6 +1087,9 @@ func (a *adapter) TenantTopicsForUser(id t.TenantID, uid t.Uid, keepDeleted bool
|
|||||||
}
|
}
|
||||||
subs := make([]t.Subscription, 0, len(join))
|
subs := make([]t.Subscription, 0, len(join))
|
||||||
for _, sub := range join {
|
for _, sub := range join {
|
||||||
|
if t.GetTopicCat(sub.Topic) == t.TopicCatP2P && !p2pResolved[sub.Topic] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
subs = append(subs, sub)
|
subs = append(subs, sub)
|
||||||
}
|
}
|
||||||
return common.SelectEarliestUpdatedSubs(subs, opts, a.maxResults), nil
|
return common.SelectEarliestUpdatedSubs(subs, opts, a.maxResults), nil
|
||||||
@@ -2486,6 +2519,7 @@ func (a *adapter) TenantMessageSearch(id t.TenantID, topic string, uid t.Uid, qu
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
msgs := make([]t.Message, 0, limit)
|
msgs := make([]t.Message, 0, limit)
|
||||||
nextCursor := ""
|
nextCursor := ""
|
||||||
|
lastSeq := int64(0)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
row := struct {
|
row := struct {
|
||||||
t.Message
|
t.Message
|
||||||
@@ -2496,10 +2530,11 @@ func (a *adapter) TenantMessageSearch(id t.TenantID, topic string, uid t.Uid, qu
|
|||||||
}
|
}
|
||||||
msg := finalizeTenantMessage(id, row.Message, row.RecalledBy)
|
msg := finalizeTenantMessage(id, row.Message, row.RecalledBy)
|
||||||
if len(msgs) == limit {
|
if len(msgs) == limit {
|
||||||
nextCursor = strconv.FormatInt(msg.SeqId, 10)
|
nextCursor = strconv.FormatInt(lastSeq, 10)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
msgs = append(msgs, msg)
|
msgs = append(msgs, msg)
|
||||||
|
lastSeq = msg.SeqId
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
@@ -2546,6 +2581,7 @@ func (a *adapter) tenantGroupMessageSearch(id t.TenantID, topic string, uid t.Ui
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
msgs := make([]t.Message, 0, limit)
|
msgs := make([]t.Message, 0, limit)
|
||||||
nextCursor := ""
|
nextCursor := ""
|
||||||
|
lastSeq := int64(0)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
row := struct {
|
row := struct {
|
||||||
t.Message
|
t.Message
|
||||||
@@ -2556,10 +2592,11 @@ func (a *adapter) tenantGroupMessageSearch(id t.TenantID, topic string, uid t.Ui
|
|||||||
}
|
}
|
||||||
msg := normalizeGroupMessage(id, row.Message, row.RecalledBy)
|
msg := normalizeGroupMessage(id, row.Message, row.RecalledBy)
|
||||||
if len(msgs) == limit {
|
if len(msgs) == limit {
|
||||||
nextCursor = strconv.FormatInt(msg.SeqId, 10)
|
nextCursor = strconv.FormatInt(lastSeq, 10)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
msgs = append(msgs, msg)
|
msgs = append(msgs, msg)
|
||||||
|
lastSeq = msg.SeqId
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
@@ -6191,6 +6228,10 @@ func (a *adapter) TenantUserPrivacyUpdate(id t.TenantID, uid t.Uid, patch t.User
|
|||||||
sets = append(sets, "read_receipts=?")
|
sets = append(sets, "read_receipts=?")
|
||||||
args = append(args, *patch.ReadReceipts)
|
args = append(args, *patch.ReadReceipts)
|
||||||
}
|
}
|
||||||
|
if patch.GroupInviteVerification != nil {
|
||||||
|
sets = append(sets, "group_invite_verification=?")
|
||||||
|
args = append(args, *patch.GroupInviteVerification)
|
||||||
|
}
|
||||||
args = append(args, decodeUID(uid), patch.Version)
|
args = append(args, decodeUID(uid), patch.Version)
|
||||||
res, err := a.db.ExecContext(ctx, `UPDATE im_user_privacy_settings SET `+strings.Join(sets, ",")+` WHERE user_id=? AND version=?`, args...)
|
res, err := a.db.ExecContext(ctx, `UPDATE im_user_privacy_settings SET `+strings.Join(sets, ",")+` WHERE user_id=? AND version=?`, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -6203,68 +6244,6 @@ func (a *adapter) TenantUserPrivacyUpdate(id t.TenantID, uid t.Uid, patch t.User
|
|||||||
return a.userPrivacyByUID(ctx, uid)
|
return a.userPrivacyByUID(ctx, uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *adapter) TenantAppReleaseLatest(id t.TenantID, platform, channel string) (*t.AppRelease, error) {
|
|
||||||
if !a.tenantScopedDB {
|
|
||||||
tenantAdp, err := a.routedTenantAdapter(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if tenantAdp != a {
|
|
||||||
return tenantAdp.TenantAppReleaseLatest(id, platform, channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
platform = strings.ToLower(strings.TrimSpace(platform))
|
|
||||||
channel = strings.ToLower(strings.TrimSpace(channel))
|
|
||||||
if err := validTenant(id); err != nil || platform == "" || channel == "" {
|
|
||||||
return nil, t.ErrMalformed
|
|
||||||
}
|
|
||||||
ctx, cancel := a.getContext()
|
|
||||||
if cancel != nil {
|
|
||||||
defer cancel()
|
|
||||||
}
|
|
||||||
row := struct {
|
|
||||||
ID int64 `db:"id"`
|
|
||||||
Platform string `db:"platform"`
|
|
||||||
Channel string `db:"channel"`
|
|
||||||
LatestVersion string `db:"latest_version"`
|
|
||||||
MinSupportedVersion string `db:"min_supported_version"`
|
|
||||||
UpdateType string `db:"update_type"`
|
|
||||||
ReleaseNotes string `db:"release_notes"`
|
|
||||||
StoreURL string `db:"store_url"`
|
|
||||||
PackageURL string `db:"package_url"`
|
|
||||||
Checksum string `db:"checksum"`
|
|
||||||
RemindAfterSeconds int `db:"remind_after_seconds"`
|
|
||||||
PublishedAt time.Time `db:"published_at"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}{}
|
|
||||||
err := sqlx.GetContext(ctx, a.db, &row,
|
|
||||||
`SELECT id,platform,channel,latest_version,min_supported_version,update_type,release_notes,store_url,package_url,checksum,remind_after_seconds,published_at,created_at,updated_at
|
|
||||||
FROM im_app_releases WHERE platform=? AND channel=? LIMIT 1`, platform, channel)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return nil, t.ErrNotFound
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &t.AppRelease{
|
|
||||||
ID: row.ID,
|
|
||||||
Platform: row.Platform,
|
|
||||||
Channel: row.Channel,
|
|
||||||
LatestVersion: row.LatestVersion,
|
|
||||||
MinSupportedVersion: row.MinSupportedVersion,
|
|
||||||
UpdateType: row.UpdateType,
|
|
||||||
ReleaseNotes: row.ReleaseNotes,
|
|
||||||
StoreURL: row.StoreURL,
|
|
||||||
PackageURL: row.PackageURL,
|
|
||||||
Checksum: row.Checksum,
|
|
||||||
RemindAfterSeconds: row.RemindAfterSeconds,
|
|
||||||
PublishedAt: row.PublishedAt,
|
|
||||||
CreatedAt: row.CreatedAt,
|
|
||||||
UpdatedAt: row.UpdatedAt,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *adapter) TenantDevicePushTokenUpsert(id t.TenantID, token *t.DevicePushToken) (*t.DevicePushToken, error) {
|
func (a *adapter) TenantDevicePushTokenUpsert(id t.TenantID, token *t.DevicePushToken) (*t.DevicePushToken, error) {
|
||||||
if !a.tenantScopedDB {
|
if !a.tenantScopedDB {
|
||||||
tenantAdp, err := a.routedTenantAdapter(id)
|
tenantAdp, err := a.routedTenantAdapter(id)
|
||||||
@@ -6820,12 +6799,13 @@ func (a *adapter) userPrivacyByUID(ctx context.Context, uid t.Uid) (*t.UserPriva
|
|||||||
ProfileVisibility string `db:"profile_visibility"`
|
ProfileVisibility string `db:"profile_visibility"`
|
||||||
LastSeenVisibility string `db:"last_seen_visibility"`
|
LastSeenVisibility string `db:"last_seen_visibility"`
|
||||||
ReadReceipts bool `db:"read_receipts"`
|
ReadReceipts bool `db:"read_receipts"`
|
||||||
|
GroupInviteVerification bool `db:"group_invite_verification"`
|
||||||
Version int
|
Version int
|
||||||
CreatedAt time.Time `db:"created_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
}{}
|
}{}
|
||||||
if err := sqlx.GetContext(ctx, a.db, &row, `SELECT user_id,add_me_methods,profile_visibility,last_seen_visibility,
|
if err := sqlx.GetContext(ctx, a.db, &row, `SELECT user_id,add_me_methods,profile_visibility,last_seen_visibility,
|
||||||
read_receipts,version,created_at,updated_at FROM im_user_privacy_settings WHERE user_id=?`, decodeUID(uid)); err != nil {
|
read_receipts,group_invite_verification,version,created_at,updated_at FROM im_user_privacy_settings WHERE user_id=?`, decodeUID(uid)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
settings := &t.UserPrivacySettings{
|
settings := &t.UserPrivacySettings{
|
||||||
@@ -6834,6 +6814,7 @@ func (a *adapter) userPrivacyByUID(ctx context.Context, uid t.Uid) (*t.UserPriva
|
|||||||
ProfileVisibility: row.ProfileVisibility,
|
ProfileVisibility: row.ProfileVisibility,
|
||||||
LastSeenVisibility: row.LastSeenVisibility,
|
LastSeenVisibility: row.LastSeenVisibility,
|
||||||
ReadReceipts: row.ReadReceipts,
|
ReadReceipts: row.ReadReceipts,
|
||||||
|
GroupInviteVerification: row.GroupInviteVerification,
|
||||||
Version: row.Version,
|
Version: row.Version,
|
||||||
CreatedAt: row.CreatedAt,
|
CreatedAt: row.CreatedAt,
|
||||||
UpdatedAt: row.UpdatedAt,
|
UpdatedAt: row.UpdatedAt,
|
||||||
@@ -6844,7 +6825,7 @@ func (a *adapter) userPrivacyByUID(ctx context.Context, uid t.Uid) (*t.UserPriva
|
|||||||
|
|
||||||
func isAllowedWorkbenchRoute(route string) bool {
|
func isAllowedWorkbenchRoute(route string) bool {
|
||||||
switch route {
|
switch route {
|
||||||
case "/organization", "/attendance", "/meetings", "/reports/daily", "/reports/monthly", "/executive-mailbox":
|
case "/organization", "/attendance", "/meetings", "/meeting-notes", "/reports/daily", "/reports/monthly", "/executive-mailbox":
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
@@ -7230,6 +7211,7 @@ func (a *adapter) TenantFavoriteList(id t.TenantID, uid t.Uid, itemType, queryTe
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := make([]t.FavoriteItem, 0, limit)
|
items := make([]t.FavoriteItem, 0, limit)
|
||||||
nextCursor := ""
|
nextCursor := ""
|
||||||
|
lastID := int64(0)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
item, err := scanFavorite(rows)
|
item, err := scanFavorite(rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -7237,10 +7219,11 @@ func (a *adapter) TenantFavoriteList(id t.TenantID, uid t.Uid, itemType, queryTe
|
|||||||
}
|
}
|
||||||
item.TenantID = id
|
item.TenantID = id
|
||||||
if len(items) == limit {
|
if len(items) == limit {
|
||||||
nextCursor = strconv.FormatInt(item.ID, 10)
|
nextCursor = strconv.FormatInt(lastID, 10)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
|
lastID = item.ID
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
@@ -7678,7 +7661,7 @@ func (a *adapter) TenantFileGet(id t.TenantID, fid string) (*t.FileDef, error) {
|
|||||||
file, err := a.FileGet(fid)
|
file, err := a.FileGet(fid)
|
||||||
return stampTenantFile(id, file), err
|
return stampTenantFile(id, file), err
|
||||||
}
|
}
|
||||||
fileID := t.ParseUid(fid)
|
fileID := parseFileUID(fid)
|
||||||
if fileID.IsZero() {
|
if fileID.IsZero() {
|
||||||
return nil, t.ErrMalformed
|
return nil, t.ErrMalformed
|
||||||
}
|
}
|
||||||
@@ -7859,7 +7842,7 @@ func (a *adapter) TenantFileUserHasAccess(id t.TenantID, fid string, uid t.Uid)
|
|||||||
if a.tenantScopedDB {
|
if a.tenantScopedDB {
|
||||||
return a.FileUserHasAccess(fid, uid)
|
return a.FileUserHasAccess(fid, uid)
|
||||||
}
|
}
|
||||||
fileID := t.ParseUid(fid)
|
fileID := parseFileUID(fid)
|
||||||
if fileID.IsZero() {
|
if fileID.IsZero() {
|
||||||
return false, t.ErrMalformed
|
return false, t.ErrMalformed
|
||||||
}
|
}
|
||||||
@@ -9631,11 +9614,17 @@ func (a *adapter) TenantFriendshipDeletePair(id t.TenantID, uid1, uid2 t.Uid, no
|
|||||||
if cancel != nil {
|
if cancel != nil {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
_, err := a.db.ExecContext(ctx,
|
res, err := a.db.ExecContext(ctx,
|
||||||
"UPDATE im_friendships SET status=?,updated_at=? WHERE (user_id=? AND peer_id=?) OR (user_id=? AND peer_id=?)",
|
"UPDATE im_friendships SET status=?,updated_at=? WHERE (user_id=? AND peer_id=?) OR (user_id=? AND peer_id=?)",
|
||||||
t.RelationshipNone, now, decodeUID(uid1), decodeUID(uid2), decodeUID(uid2), decodeUID(uid1))
|
t.RelationshipNone, now, decodeUID(uid1), decodeUID(uid2), decodeUID(uid2), decodeUID(uid1))
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if affected, err := res.RowsAffected(); err == nil && affected == 0 {
|
||||||
|
return t.ErrNotFound
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *adapter) TenantUserBlockGet(id t.TenantID, blockerID, blockedID t.Uid) (*t.UserBlock, error) {
|
func (a *adapter) TenantUserBlockGet(id t.TenantID, blockerID, blockedID t.Uid) (*t.UserBlock, error) {
|
||||||
if !a.tenantScopedDB {
|
if !a.tenantScopedDB {
|
||||||
|
|||||||
@@ -419,16 +419,37 @@ func (a *adapter) TenantGroupInvitationCreate(id t.TenantID, inv *t.GroupInvitat
|
|||||||
if inv.ExpiresAt.IsZero() {
|
if inv.ExpiresAt.IsZero() {
|
||||||
inv.ExpiresAt = now.Add(7 * 24 * time.Hour)
|
inv.ExpiresAt = now.Add(7 * 24 * time.Hour)
|
||||||
}
|
}
|
||||||
ctx, cancel := a.getContext()
|
ctx, cancel := a.getContextForTx()
|
||||||
if cancel != nil {
|
if cancel != nil {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
_, err := a.db.ExecContext(ctx, `INSERT INTO im_group_invitations(invitation_id,topic,inviter_user_id,target_user_id,message,status,result,join_request_id,idempotency_key,expires_at,handled_at,created_at,updated_at)
|
tx, err := a.db.BeginTxx(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
_, err = tx.ExecContext(ctx, `INSERT INTO im_group_invitations(invitation_id,topic,inviter_user_id,target_user_id,message,status,result,join_request_id,idempotency_key,expires_at,handled_at,created_at,updated_at)
|
||||||
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
||||||
inv.InvitationID, inv.Topic, decodeUID(inv.InviterUserID), decodeUID(inv.TargetUserID), inv.Message, inv.Status, inv.Result, inv.JoinRequestID, inv.IdempotencyKey, inv.ExpiresAt, inv.HandledAt, now, now)
|
inv.InvitationID, inv.Topic, decodeUID(inv.InviterUserID), decodeUID(inv.TargetUserID), inv.Message, inv.Status, inv.Result, inv.JoinRequestID, inv.IdempotencyKey, inv.ExpiresAt, inv.HandledAt, now, now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if strings.TrimSpace(inv.JoinRequestID) != "" {
|
||||||
|
_, err = tx.ExecContext(ctx, `INSERT INTO im_group_join_requests(request_id,topic,applicant_user_id,inviter_user_id,source,qr_token_hash,message,status,reject_reason,expires_at,idempotency_key,version,created_at,updated_at)
|
||||||
|
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
||||||
|
inv.JoinRequestID, inv.Topic, decodeUID(inv.TargetUserID), nullableUID(inv.InviterUserID), "invitation", "", inv.Message, t.GroupJoinRequestStatusPending, "", inv.ExpiresAt, inv.IdempotencyKey, 1, now, now)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = insertGroupEventTx(tx, inv.Topic, inv.TargetUserID, "group.join_request.created", map[string]any{
|
||||||
|
"request_id": inv.JoinRequestID, "applicant_user_id": inv.TargetUserID.UserId(), "source": "invitation", "invitation_id": inv.InvitationID,
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = tx.Commit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return inv, nil
|
return inv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,6 +499,12 @@ func (a *adapter) TenantGroupInvitationAccept(id t.TenantID, invitationID string
|
|||||||
if inv.Status == t.GroupInvitationStatusJoined || inv.Result == "joined" {
|
if inv.Status == t.GroupInvitationStatusJoined || inv.Result == "joined" {
|
||||||
return &inv, nil
|
return &inv, nil
|
||||||
}
|
}
|
||||||
|
if strings.TrimSpace(inv.JoinRequestID) != "" {
|
||||||
|
if err = tx.Commit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &inv, nil
|
||||||
|
}
|
||||||
var deletedAt sql.NullTime
|
var deletedAt sql.NullTime
|
||||||
err = tx.QueryRowxContext(ctx, "SELECT deletedat FROM im_subscriptions WHERE topic=? AND userid=?",
|
err = tx.QueryRowxContext(ctx, "SELECT deletedat FROM im_subscriptions WHERE topic=? AND userid=?",
|
||||||
inv.Topic, decodeUID(uid)).Scan(&deletedAt)
|
inv.Topic, decodeUID(uid)).Scan(&deletedAt)
|
||||||
@@ -509,6 +536,14 @@ func (a *adapter) TenantGroupInvitationAccept(id t.TenantID, invitationID string
|
|||||||
t.GroupInvitationStatusJoined, "joined", now, now, inv.InvitationID); err != nil {
|
t.GroupInvitationStatusJoined, "joined", now, now, inv.InvitationID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if strings.TrimSpace(inv.JoinRequestID) != "" {
|
||||||
|
if _, err = tx.ExecContext(ctx, `UPDATE im_group_join_requests
|
||||||
|
SET status=?,handled_by=?,handled_at=?,updated_at=?,version=version+1
|
||||||
|
WHERE topic=? AND request_id=? AND status=?`,
|
||||||
|
t.GroupJoinRequestStatusAccepted, decodeUID(uid), now, now, inv.Topic, inv.JoinRequestID, t.GroupJoinRequestStatusPending); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
if err = insertGroupEventTx(tx, inv.Topic, uid, "group.member.joined", map[string]any{
|
if err = insertGroupEventTx(tx, inv.Topic, uid, "group.member.joined", map[string]any{
|
||||||
"user_id": uid.UserId(), "source": "invitation", "invitation_id": inv.InvitationID,
|
"user_id": uid.UserId(), "source": "invitation", "invitation_id": inv.InvitationID,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -698,6 +733,19 @@ func (a *adapter) TenantGroupAnnouncementLatest(id t.TenantID, topic string) (*t
|
|||||||
return a.groupAnnouncementByQuery(ctx, "SELECT "+groupAnnouncementSelectColumns+" FROM im_group_announcements WHERE topic=? AND status=? ORDER BY version DESC,id DESC LIMIT 1", topic, t.GroupAnnouncementStatusCurrent)
|
return a.groupAnnouncementByQuery(ctx, "SELECT "+groupAnnouncementSelectColumns+" FROM im_group_announcements WHERE topic=? AND status=? ORDER BY version DESC,id DESC LIMIT 1", topic, t.GroupAnnouncementStatusCurrent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *adapter) TenantGroupAnnouncementGet(id t.TenantID, topic, announcementID string) (*t.GroupAnnouncement, error) {
|
||||||
|
if tenantAdp, err := a.routeGroupTenant(id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if tenantAdp != a {
|
||||||
|
return tenantAdp.TenantGroupAnnouncementGet(id, topic, announcementID)
|
||||||
|
}
|
||||||
|
ctx, cancel := a.getContext()
|
||||||
|
if cancel != nil {
|
||||||
|
defer cancel()
|
||||||
|
}
|
||||||
|
return a.groupAnnouncementByQuery(ctx, "SELECT "+groupAnnouncementSelectColumns+" FROM im_group_announcements WHERE topic=? AND announcement_id=? LIMIT 1", topic, announcementID)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *adapter) TenantGroupAnnouncementPut(id t.TenantID, ann *t.GroupAnnouncement, expectedVersion int) (*t.GroupAnnouncement, error) {
|
func (a *adapter) TenantGroupAnnouncementPut(id t.TenantID, ann *t.GroupAnnouncement, expectedVersion int) (*t.GroupAnnouncement, error) {
|
||||||
if tenantAdp, err := a.routeGroupTenant(id); err != nil {
|
if tenantAdp, err := a.routeGroupTenant(id); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -289,8 +289,8 @@ func TestTenantAuthIsolation(t *testing.T) {
|
|||||||
userBID := userAID + 1
|
userBID := userAID + 1
|
||||||
for index, userID := range []int64{userAID, userBID} {
|
for index, userID := range []int64{userAID, userBID} {
|
||||||
tenantDB := quoteIdent(dbNames[index])
|
tenantDB := quoteIdent(dbNames[index])
|
||||||
if _, err := db.Exec("INSERT INTO "+tenantDB+".im_users(id,username,createdat,updatedat,state,access,phone,public,trusted) "+
|
if _, err := db.Exec("INSERT INTO "+tenantDB+".im_users(id,account_no,username,createdat,updatedat,state,access,phone,public,trusted) "+
|
||||||
"VALUES(?,?,?,?,?,?,?,?,?)", userID, "alice", now, now, types.StateOK, `{}`, "13800000000", nil, nil); err != nil {
|
"VALUES(?,?,?,?,?,?,?,?,?,?)", userID, 1000+index, "alice", now, now, types.StateOK, `{}`, "13800000000", nil, nil); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if _, err := db.Exec("INSERT INTO "+tenantDB+".im_auth(userid,authlvl,secret) VALUES(?,?,?)",
|
if _, err := db.Exec("INSERT INTO "+tenantDB+".im_auth(userid,authlvl,secret) VALUES(?,?,?)",
|
||||||
@@ -360,9 +360,9 @@ func TestTenantUserSearchMatchesUsernamePhoneAndPublicAccount(t *testing.T) {
|
|||||||
{targetID, "potter", "+8615500000002", `{"fn":"Potter"}`},
|
{targetID, "potter", "+8615500000002", `{"fn":"Potter"}`},
|
||||||
} {
|
} {
|
||||||
if _, err := db.Exec(
|
if _, err := db.Exec(
|
||||||
`INSERT INTO im_users(id,username,createdat,updatedat,state,access,phone,public,trusted)
|
`INSERT INTO im_users(id,account_no,username,createdat,updatedat,state,access,phone,public,trusted)
|
||||||
VALUES(?,?,?,?,?,?,?,?,?)`,
|
VALUES(?,?,?,?,?,?,?,?,?,?)`,
|
||||||
user.id, user.username, now, now, types.StateOK, `{"Auth":"JRWPAS","Anon":"N"}`, user.phone, user.public, `{}`); err != nil {
|
user.id, user.id%1000000, user.username, now, now, types.StateOK, `{"Auth":"JRWPAS","Anon":"N"}`, user.phone, user.public, `{}`); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if _, err := db.Exec(
|
if _, err := db.Exec(
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ func ensureUserIdentitySchema(db *sqlx.DB) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err = ensureUserAccountNoSchema(ctx, conn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if profilesExist {
|
if profilesExist {
|
||||||
if exists, err := identityColumnExists(ctx, conn, "im_user_profiles", "email"); err != nil {
|
if exists, err := identityColumnExists(ctx, conn, "im_user_profiles", "email"); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -568,6 +571,39 @@ func identityCandidates(ctx context.Context, conn *sqlx.Conn, scoped bool, metho
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureUserAccountNoSchema(ctx context.Context, conn *sqlx.Conn) error {
|
||||||
|
if exists, err := identityColumnExists(ctx, conn, "im_users", "account_no"); err != nil {
|
||||||
|
return err
|
||||||
|
} else if !exists {
|
||||||
|
if _, err = conn.ExecContext(ctx, "ALTER TABLE im_users ADD COLUMN account_no INT UNSIGNED NOT NULL DEFAULT 0 AFTER id"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var start int64 = 999
|
||||||
|
if err := conn.QueryRowContext(ctx, "SELECT GREATEST(COALESCE(MAX(account_no), 999), 999) FROM im_users WHERE account_no>0").Scan(&start); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := conn.ExecContext(ctx, `
|
||||||
|
UPDATE im_users AS u
|
||||||
|
JOIN (
|
||||||
|
SELECT ordered.id, (@im_user_account_no := @im_user_account_no + 1) AS next_no
|
||||||
|
FROM (SELECT id FROM im_users WHERE account_no=0 ORDER BY createdat, id) AS ordered
|
||||||
|
CROSS JOIN (SELECT @im_user_account_no := ?) AS vars
|
||||||
|
) AS seq ON seq.id=u.id
|
||||||
|
SET u.account_no=seq.next_no
|
||||||
|
WHERE u.account_no=0`, start); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exists, err := identityIndexExists(ctx, conn, "im_users", "uk_im_users_account_no"); err != nil {
|
||||||
|
return err
|
||||||
|
} else if !exists {
|
||||||
|
if _, err = conn.ExecContext(ctx, "CREATE UNIQUE INDEX uk_im_users_account_no ON im_users(account_no)"); err != nil {
|
||||||
|
return fmt.Errorf("create unique user account number index: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func identityTableExists(ctx context.Context, conn *sqlx.Conn, table string) (bool, error) {
|
func identityTableExists(ctx context.Context, conn *sqlx.Conn, table string) (bool, error) {
|
||||||
var exists int
|
var exists int
|
||||||
err := conn.QueryRowContext(ctx, `SELECT EXISTS(SELECT 1 FROM information_schema.tables
|
err := conn.QueryRowContext(ctx, `SELECT EXISTS(SELECT 1 FROM information_schema.tables
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ func largeFileServeHTTP(wrt http.ResponseWriter, req *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = authorizeLargeFileRequestURL(principal.TenantID, principal.UID, req.URL.String()); err != nil {
|
||||||
|
writeHttpResponse(decodeStoreError(err, "", now, nil), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Check if media handler redirects or adds headers.
|
// Check if media handler redirects or adds headers.
|
||||||
headers, statusCode, err := mh.Headers(principal.TenantID, req.Method, req.URL, req.Header, true)
|
headers, statusCode, err := mh.Headers(principal.TenantID, req.Method, req.URL, req.Header, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -517,6 +522,21 @@ func (*grpcNodeServer) LargeFileServe(req *pbx.FileDownReq, stream pbx.Node_Larg
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func authorizeLargeFileRequestURL(tenantID types.TenantID, uid types.Uid, rawURL string) error {
|
||||||
|
if store.Store == nil {
|
||||||
|
return types.ErrUnsupported
|
||||||
|
}
|
||||||
|
fid := store.Store.GetMediaHandler().GetIdFromUrl(rawURL)
|
||||||
|
if fid.IsZero() {
|
||||||
|
return types.ErrNotFound
|
||||||
|
}
|
||||||
|
fd, err := store.Files.Get(tenantID, fid.String())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return authorizeLargeFileDownload(tenantID, uid, rawURL, fd)
|
||||||
|
}
|
||||||
|
|
||||||
func authorizeLargeFileDownload(tenantID types.TenantID, uid types.Uid, rawURL string, fd *types.FileDef) error {
|
func authorizeLargeFileDownload(tenantID types.TenantID, uid types.Uid, rawURL string, fd *types.FileDef) error {
|
||||||
if fd == nil {
|
if fd == nil {
|
||||||
return types.ErrNotFound
|
return types.ErrNotFound
|
||||||
|
|||||||
@@ -24,10 +24,13 @@ import (
|
|||||||
type testLargeFileMediaHandler struct {
|
type testLargeFileMediaHandler struct {
|
||||||
def *types.FileDef
|
def *types.FileDef
|
||||||
data string
|
data string
|
||||||
|
fid types.Uid
|
||||||
|
headersCalled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *testLargeFileMediaHandler) Init(string) error { return nil }
|
func (h *testLargeFileMediaHandler) Init(string) error { return nil }
|
||||||
func (h *testLargeFileMediaHandler) Headers(types.TenantID, string, *url.URL, http.Header, bool) (http.Header, int, error) {
|
func (h *testLargeFileMediaHandler) Headers(types.TenantID, string, *url.URL, http.Header, bool) (http.Header, int, error) {
|
||||||
|
h.headersCalled = true
|
||||||
return nil, 0, nil
|
return nil, 0, nil
|
||||||
}
|
}
|
||||||
func (h *testLargeFileMediaHandler) Upload(def *types.FileDef, file io.Reader) (string, int64, error) {
|
func (h *testLargeFileMediaHandler) Upload(def *types.FileDef, file io.Reader) (string, int64, error) {
|
||||||
@@ -43,7 +46,7 @@ func (h *testLargeFileMediaHandler) Download(types.TenantID, string) (*types.Fil
|
|||||||
}
|
}
|
||||||
func (h *testLargeFileMediaHandler) Delete([]string) error { return nil }
|
func (h *testLargeFileMediaHandler) Delete([]string) error { return nil }
|
||||||
func (h *testLargeFileMediaHandler) GetIdFromUrl(string) types.Uid {
|
func (h *testLargeFileMediaHandler) GetIdFromUrl(string) types.Uid {
|
||||||
return types.ZeroUid
|
return h.fid
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAuthFileRequestFromSessionRequiresTenant(t *testing.T) {
|
func TestAuthFileRequestFromSessionRequiresTenant(t *testing.T) {
|
||||||
@@ -144,6 +147,43 @@ func TestAuthorizeLargeFileDownloadRejectsCrossTenant(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAuthorizeLargeFileRequestURLRequiresAccessBeforeRedirect(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
oldStore := store.Store
|
||||||
|
oldFiles := store.Files
|
||||||
|
defer func() {
|
||||||
|
store.Store = oldStore
|
||||||
|
store.Files = oldFiles
|
||||||
|
}()
|
||||||
|
|
||||||
|
fid := types.Uid(100)
|
||||||
|
handler := &testLargeFileMediaHandler{fid: fid}
|
||||||
|
mockStore := mock_store.NewMockPersistentStorageInterface(ctrl)
|
||||||
|
files := mock_store.NewMockFilePersistenceInterface(ctrl)
|
||||||
|
store.Store = mockStore
|
||||||
|
store.Files = files
|
||||||
|
|
||||||
|
fd := &types.FileDef{
|
||||||
|
ObjHeader: types.ObjHeader{Id: fid.String(), UpdatedAt: time.Date(2026, 8, 13, 9, 0, 0, 0, time.UTC)},
|
||||||
|
TenantID: 7,
|
||||||
|
Status: types.UploadCompleted,
|
||||||
|
MimeType: "image/jpeg",
|
||||||
|
Location: "image.jpeg",
|
||||||
|
}
|
||||||
|
mockStore.EXPECT().GetMediaHandler().Return(handler)
|
||||||
|
files.EXPECT().Get(types.TenantID(7), fid.String()).Return(fd, nil)
|
||||||
|
files.EXPECT().UserHasAccess(types.TenantID(7), fid.String(), types.Uid(42)).Return(false, nil)
|
||||||
|
|
||||||
|
if err := authorizeLargeFileRequestURL(7, 42, "/v0/file/s/file.jpeg"); err != types.ErrPermissionDenied {
|
||||||
|
t.Fatalf("expected permission denied, got %v", err)
|
||||||
|
}
|
||||||
|
if handler.headersCalled {
|
||||||
|
t.Fatal("media headers should not be called by authorization helper")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContentDispositionAttachmentSanitizesName(t *testing.T) {
|
func TestContentDispositionAttachmentSanitizesName(t *testing.T) {
|
||||||
fd := &types.FileDef{
|
fd := &types.FileDef{
|
||||||
ObjHeader: types.ObjHeader{Id: types.Uid(100).String()},
|
ObjHeader: types.ObjHeader{Id: types.Uid(100).String()},
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const (
|
|||||||
pongWait = idleSessionTimeout
|
pongWait = idleSessionTimeout
|
||||||
|
|
||||||
// Send pings to peer with this period. Must be less than pongWait.
|
// Send pings to peer with this period. Must be less than pongWait.
|
||||||
pingPeriod = (pongWait * 9) / 10
|
pingPeriod = 30 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
func (sess *Session) closeWS() {
|
func (sess *Session) closeWS() {
|
||||||
|
|||||||
+777
-96
File diff suppressed because it is too large
Load Diff
+1018
-30
File diff suppressed because it is too large
Load Diff
@@ -269,7 +269,7 @@ func internalAdminQuerySpec(resource string) (*internalQuerySpec, bool) {
|
|||||||
|
|
||||||
func usersInternalQuerySpec() *internalQuerySpec {
|
func usersInternalQuerySpec() *internalQuerySpec {
|
||||||
return &internalQuerySpec{
|
return &internalQuerySpec{
|
||||||
Select: `SELECT CAST(u.id AS CHAR) AS user_id,u.username,u.phone,u.state,u.stateat AS state_at,u.access,u.lastseen AS last_seen,u.useragent AS user_agent,u.public,u.trusted,
|
Select: `SELECT CAST(u.id AS CHAR) AS user_id,u.account_no AS display_no,u.username,u.phone,u.state,u.stateat AS state_at,u.access,u.lastseen AS last_seen,u.useragent AS user_agent,u.public,u.trusted,
|
||||||
p.nickname,p.public_account,p.gender,p.region,p.avatar_file_id,
|
p.nickname,p.public_account,p.gender,p.region,p.avatar_file_id,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
NULLIF(avatar.location,''),
|
NULLIF(avatar.location,''),
|
||||||
@@ -288,7 +288,7 @@ func usersInternalQuerySpec() *internalQuerySpec {
|
|||||||
From: "FROM im_users AS u LEFT JOIN im_user_profiles AS p ON p.user_id=u.id LEFT JOIN im_user_security AS sec ON sec.user_id=u.id LEFT JOIN im_fileuploads AS avatar ON avatar.id=CAST(p.avatar_file_id AS UNSIGNED) AND p.avatar_file_id REGEXP '^[0-9]+$'",
|
From: "FROM im_users AS u LEFT JOIN im_user_profiles AS p ON p.user_id=u.id LEFT JOIN im_user_security AS sec ON sec.user_id=u.id LEFT JOIN im_fileuploads AS avatar ON avatar.id=CAST(p.avatar_file_id AS UNSIGNED) AND p.avatar_file_id REGEXP '^[0-9]+$'",
|
||||||
DefaultSort: "ORDER BY u.id DESC",
|
DefaultSort: "ORDER BY u.id DESC",
|
||||||
DetailKey: "u.id",
|
DetailKey: "u.id",
|
||||||
Filters: []internalQueryFilter{{"user_id", "u.id", "=", "uid"}, {"user_ids", "u.id", "IN", "uid_list"}, {"keyword", "CONCAT_WS(' ',u.username,p.nickname,u.phone)", "LIKE", "string"}, {"nickname", "p.nickname", "LIKE", "string"}, {"auth_name", "u.username", "LIKE", "string"}, {"state", "u.state", "=", "int"}, {"created_at_start", "u.createdat", ">=", "time"}, {"created_at_end", "u.createdat", "<=", "time"}, {"last_seen_start", "u.lastseen", ">=", "time"}, {"last_seen_end", "u.lastseen", "<=", "time"}},
|
Filters: []internalQueryFilter{{"user_id", "u.id", "=", "uid"}, {"user_ids", "u.id", "IN", "uid_list"}, {"account_no", "u.account_no", "=", "int"}, {"keyword", "CONCAT_WS(' ',u.username,p.nickname,u.phone,CAST(u.account_no AS CHAR))", "LIKE", "string"}, {"nickname", "p.nickname", "LIKE", "string"}, {"auth_name", "u.username", "LIKE", "string"}, {"state", "u.state", "=", "int"}, {"created_at_start", "u.createdat", ">=", "time"}, {"created_at_end", "u.createdat", "<=", "time"}, {"last_seen_start", "u.lastseen", ">=", "time"}, {"last_seen_end", "u.lastseen", "<=", "time"}},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -229,8 +229,15 @@ func serveInternalUserCreate(wrt http.ResponseWriter, req *http.Request, tenantI
|
|||||||
writeInternalQueryError(wrt, req, err)
|
writeInternalQueryError(wrt, req, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
displayNo := int64(0)
|
||||||
|
if row, err := store.InternalAdminQueries.QueryOne(tenantID, "SELECT account_no FROM im_users WHERE id=?", []any{store.DecodeUid(created.Uid())}); err == nil {
|
||||||
|
displayNo, _ = numericID(row["account_no"])
|
||||||
|
} else {
|
||||||
|
logs.Warn.Printf("internal user create account number query failed tenant:%d user:%d err:%v", tenantID, store.DecodeUid(created.Uid()), err)
|
||||||
|
}
|
||||||
writeIMSuccess(wrt, req, map[string]any{
|
writeIMSuccess(wrt, req, map[string]any{
|
||||||
"user_id": store.DecodeUid(created.Uid()),
|
"user_id": store.DecodeUid(created.Uid()),
|
||||||
|
"display_no": displayNo,
|
||||||
"username": created.Username,
|
"username": created.Username,
|
||||||
"nickname": body.Nickname,
|
"nickname": body.Nickname,
|
||||||
"phone": created.Phone,
|
"phone": created.Phone,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const (
|
|||||||
configEventDictionaryUpdated = "dictionary.updated"
|
configEventDictionaryUpdated = "dictionary.updated"
|
||||||
configEventThirdPartyUpdated = "third_party.updated"
|
configEventThirdPartyUpdated = "third_party.updated"
|
||||||
configEventRegistrationUpdated = "registration.config.updated"
|
configEventRegistrationUpdated = "registration.config.updated"
|
||||||
|
configEventAppReleaseUpdated = "app.release.updated"
|
||||||
)
|
)
|
||||||
|
|
||||||
type configEventPayload struct {
|
type configEventPayload struct {
|
||||||
@@ -86,10 +87,13 @@ func executeKafkaConfigEvent(envelope kafkaEnvelope) error {
|
|||||||
store.InvalidateThirdPartyConfigCache(payload.Group)
|
store.InvalidateThirdPartyConfigCache(payload.Group)
|
||||||
case configEventRegistrationUpdated:
|
case configEventRegistrationUpdated:
|
||||||
store.InvalidateRegistrationConfigCache()
|
store.InvalidateRegistrationConfigCache()
|
||||||
|
case configEventAppReleaseUpdated:
|
||||||
|
store.InvalidateAppReleaseConfigCache()
|
||||||
default:
|
default:
|
||||||
store.InvalidateTenantConfigCache(tenantCode, tenantID)
|
store.InvalidateTenantConfigCache(tenantCode, tenantID)
|
||||||
store.InvalidateThirdPartyConfigCache(payload.Group)
|
store.InvalidateThirdPartyConfigCache(payload.Group)
|
||||||
store.InvalidateRegistrationConfigCache()
|
store.InvalidateRegistrationConfigCache()
|
||||||
|
store.InvalidateAppReleaseConfigCache()
|
||||||
}
|
}
|
||||||
logs.Info.Printf("kafka config event applied: event=%s type=%s tenant=%s group=%s", envelope.EventID, envelope.EventType, tenantCode, payload.Group)
|
logs.Info.Printf("kafka config event applied: event=%s type=%s tenant=%s group=%s", envelope.EventID, envelope.EventType, tenantCode, payload.Group)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -48,7 +48,10 @@ func saveMessageMaybeKafka(ctx context.Context, tenantID types.TenantID, msg *ty
|
|||||||
if runtimeReady && !claimed {
|
if runtimeReady && !claimed {
|
||||||
if claim != nil && claim.Seq > 0 {
|
if claim != nil && claim.Seq > 0 {
|
||||||
msg.SeqId = claim.Seq
|
msg.SeqId = claim.Seq
|
||||||
return &types.MessageSaveResult{SeqId: claim.Seq, Duplicate: true}, nil
|
return &types.MessageSaveResult{SeqId: claim.Seq, Duplicate: claim.Status == "done", Pending: claim.Status == "pending"}, nil
|
||||||
|
}
|
||||||
|
if claim != nil && claim.Status == "pending" {
|
||||||
|
return &types.MessageSaveResult{Pending: true}, types.ErrDuplicate
|
||||||
}
|
}
|
||||||
return nil, types.ErrDuplicate
|
return nil, types.ErrDuplicate
|
||||||
}
|
}
|
||||||
@@ -64,9 +67,12 @@ func saveMessageMaybeKafka(ctx context.Context, tenantID types.TenantID, msg *ty
|
|||||||
msg.InitTimes()
|
msg.InitTimes()
|
||||||
if err = enqueueKafkaMessagePersist(ctx, tenantID, msg, attachmentURLs, readBySender); err != nil {
|
if err = enqueueKafkaMessagePersist(ctx, tenantID, msg, attachmentURLs, readBySender); err != nil {
|
||||||
if clientMsgID != "" {
|
if clientMsgID != "" {
|
||||||
_ = store.MarkMessageUniqueFailed(tenantID, msg.Topic, fromUid, clientMsgID)
|
if markErr := store.MarkMessageUniquePending(tenantID, msg.Topic, fromUid, clientMsgID, msg.SeqId); markErr != nil {
|
||||||
|
logs.Warn.Printf("kafka message persist: failed to mark message unique key pending topic=%s seq=%d: %v", msg.Topic, msg.SeqId, markErr)
|
||||||
}
|
}
|
||||||
return nil, err
|
}
|
||||||
|
logs.Warn.Printf("kafka message persist: publish state unknown topic=%s seq=%d client_mid=%s err=%v", msg.Topic, msg.SeqId, clientMsgID, err)
|
||||||
|
return &types.MessageSaveResult{SeqId: msg.SeqId, Pending: true, MarkedReadBySender: readBySender && !fromUid.IsZero()}, err
|
||||||
}
|
}
|
||||||
if clientMsgID != "" {
|
if clientMsgID != "" {
|
||||||
if err = store.MarkMessageUniqueDone(tenantID, msg.Topic, fromUid, clientMsgID, msg.SeqId, ""); err != nil {
|
if err = store.MarkMessageUniqueDone(tenantID, msg.Topic, fromUid, clientMsgID, msg.SeqId, ""); err != nil {
|
||||||
|
|||||||
@@ -0,0 +1,450 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||||
|
<title></title>
|
||||||
|
<meta name="Generator" content="Cocoa HTML Writer">
|
||||||
|
<meta name="CocoaVersion" content="2575.7">
|
||||||
|
<style type="text/css">
|
||||||
|
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Times; -webkit-text-stroke: #000000; min-height: 14.0px}
|
||||||
|
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Times; -webkit-text-stroke: #000000}
|
||||||
|
span.s1 {font-kerning: none}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">尊敬的笔墨讯使用户:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">欢迎您使用海口市枫群网络科技有限公司提供的“笔墨讯使”软件及相关服务!作为“笔墨讯使”的开发者(以下简称“我们”),我们深知个人信息对您的重要性,并会尽力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护和处理您的个人信息:权责一致原则,目的明确原则,选择同意原则,最少必要原则,确保安全原则,主体参与原则,公开透明原则。同时我们承诺,我们将按业界成熟的安全解决方案,采取相应的安全保护措施来保护您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">版本生效日期:2025年8月1日</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">如您有任何疑问、意见或建议,您可通过以下联系方式与我们联系:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">联系邮箱:fengqunwangluo2025@163.com</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">联系地址:海南省海口市美兰区海府街道海府路4号海口宾馆附楼第4层C区第7间</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">【特别提示】</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">请您仔细阅读《隐私政策》详细了解我们对信息的收集、使用、保存方式等,并确定了解我们对您个人信息的处理规则。对本政策中我们认为与您的权益存在重大关系的条款,我们采用字体加粗形式提示您特别注意。我们建议您仔细阅读并理解本政策全部内容,尤其是确保已全部知晓并充分理解加粗字体内容的含义及相应的法律后果,以便您对我们的服务作出适当的选择。本隐私政策中涉及的相关术语,我们尽量以简明扼要的表述,以便您更好地理解。涉及具体的产品(或服务),如法律、行政法规规定处理个人信息应当取得个人单独同意的,我们将根据您的实际使用情况单独征求您的同意。您使用或在我们更新本隐私政策后(我们会及时提示您更新的情况)继续使用我们的产品与/或服务,即表示您同意本隐私政策(含更新版本)内容,并且同意我们按照本隐私政策收集、使用、保存和共享您的相关信息。</span></p>
|
||||||
|
<p class="p2"><span class="s1">在使用我们提供的各项产品或服务前,请您务必仔细阅读并透彻理解本政策,在确认充分理解并同意后使用相关产品或服务。一旦您开始使用我们各项产品或服务,即表示您已充分理解并同意使用我们的相关产品或服务,以及在使用相关产品或服务过程中所需的必要个人信息,并给予相应的收集使用授权。如对本政策内容有任何疑问、意见或建议,您可以通过我们提供的联系方式向我们咨询。</span></p>
|
||||||
|
<p class="p2"><span class="s1">为协助您了解我们隐私保护政策,以下是本政策的要点说明:</span></p>
|
||||||
|
<p class="p2"><span class="s1">1、我们会遵循隐私保护政策收集、使用您的信息,但不会仅因您同意本政策而采用强制捆绑的方式收集全部个人信息。</span></p>
|
||||||
|
<p class="p2"><span class="s1">2、我们会逐一说明所收集的您的个人信息类型及其对应的用途,以便您了解我们针对某一特定功能收集的具体个人信息类别、使用理由及收集方式。</span></p>
|
||||||
|
<p class="p2"><span class="s1">3、您可以访问、更正、删除您的个人信息、改变您授权同意的范围以及请求注销账户,我们为您提供了行使这些权利的途径。</span></p>
|
||||||
|
<p class="p2"><span class="s1">4、除非再次征得您的同意,我们不会将您的个人信息用于本政策未载明的其他目的。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">引言</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">笔墨讯使重视用户信息安全与隐私保护,竭尽全力通过合理有效的信息安全技术及管理流程,防止您的信息泄露、损毁、丢失;为您提供便利的信息管理选项,增强您对信息管理的便捷性;保护您的通信秘密,保障您的信息及通信安全。笔墨讯使严格遵守法律法规,仅收集必要的信息,并提升信息处理透明度,在产品或服务开发的各个环节,综合法律、产品、设计等多方因素,融入隐私保护的理念,为您提供更加安全、可靠的服务。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们制定并遵循本《隐私政策》(以下简称“本政策”),主要向您说明:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">• 我们收集哪些信息;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 我们收集信息的用途;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 我们如何共享、转让、公开披露您的个人信息;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 我们如何保存您的个人信息;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 我们如何使用Cookie和同类技术;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 您如何管理个人信息;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 未成年人个人信息保护;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 通知和修订;</span></p>
|
||||||
|
<p class="p2"><span class="s1">• 如何联系我们;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">一、个人信息的定义与范围</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">除另有约定外,本政策所用术语具有以下定义。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">1.1 个人信息:是指以电子或者其他方式记录的能够单独或者与其他信息结合识别自然人个人身份或者反映特定自然人活动情况的各种信息。本隐私政策中涉及的个人信息包括自然人的姓名、昵称、出生日期、国籍、身份证件号码和有效期、性别、年龄、个人生物识别信息、住址地或工作单位地址、电话号码、公司、机构、职业。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">1.2 个人敏感信息:是指一旦泄露、非法提供或滥用可能危害人身和财产安全,极易导致个人名誉、身心健康受到损害或歧视性待遇等的个人信息。例如,个人敏感信息包括身份证件号码、个人生物识别信息、银行账号、通信内容、健康生理信息等。故您应自行谨慎判断确定相关信息的真实性、合法性和有效性,并自行承担因此产生的责任与损失。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">1.3 匿名化处理后的信息,即通过对个人信息的技术处理,使得个人信息主体无法被识别,且处理后不能被复原的信息,匿名化处理后的信息不属于个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">1.4 其他无法识别特定自然人身份或者反映特定自然人活动情况的信息不属于个人信息。除上述定义外,本政策所用其他术语与《笔墨讯使软件服务协议》中的术语具有相同的涵义。如您有问题,请联系我们。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">二、我们收集的信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.1 笔墨讯使软件功能分为核心功能和附加功能,我们将详细向您说明各业务功能所收集的个人信息以及收集方法、目的,拒绝提供的影响等。业务功能具体包括:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.1.1 核心功能,包括创建账号并完善资料、会话功能、发现功能。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.1.2 附加功能,包括个人主页、身份认证。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.2 您使用笔墨讯使软件核心功能前,需要创建账号并完善个人资料。通过用户主动提供的方式,我们会收集您的以下信息:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.2.1 您需要向我们提供您的手机号码,并设置您在笔墨讯使的用户密码。手机号码确定后,暂时无法修改。如果您拒绝提供手机号码笔墨讯使将无法为您创建账号并提供服务。同时,为了保证软件正常运行,我们将会采集您的设备信息,具体包括: iOS系统:SDK版本、设备用户名、手机型号、系统型号、链接的无线MAC地址、设备随机序列号、IMSI、SIM卡国家、磁盘总空间、运行内存、电池电量、网络环境、运营商、系统版本、CPU型号、屏幕分辨率、IMEI、手机品牌、平台类型、设备序列号等。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.2.2 您使用会话功能进行语音通话、发送语音信息、拍摄及相册时;我们会调用您以下设备权限:设备麦克风权限、系统相册权限、系统摄像头权限。上述功能可能需要您在您的设备中向我们开启您的相机(摄像头)、相册(图片库)、麦克风以及通讯录的访问权限,以实现这些功能所涉及的信息的收集和使用。请您注意,您开启这些权限即代表您授权我们可以收集和使用这些个人信息来实现上述的功能,您关闭权限即代表您取消了这些授权,则我们将不再继续收集和使用您的这些个人信息,也无法为您提供上述与这些授权所对应的功能。您关闭权限的决定不会影响此前基于您的授权所进行的个人信息的处理。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.3 为了提高您的社交属性,在社群中结实更多志同道合的朋友,我们在以下附加功能中可能会收集和使用您的个人信息。如果您不提供这些个人信息,您依然可以使用笔墨讯使软件的核心功能。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.3.1 您可以选择向我们提供昵称、姓名、性别、年龄、所在地、行业、公司/机构、职业。您可以在个人主页资料中选择是否填写上述信息。如您提供上述信息,可以使其他用户对您有更全面的了解。您也可以在您的个人主页中将上述隐私事项设置为所有人/仅好友/仅自己可见。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.4 您可以选择申请个人加V认证,申请加V认证您需要提供您的个人简介、昵称、并上传职位、技能证明材料,包含姓名、公司/组织信息、职位信息的加盖公章的截图材料、公开可查的官方个人信息页截图材料。成为笔墨讯使认证会员可以提升在社群的个人社交属性。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.5 为了帮助您更好地使用我们的产品或服务,我们还会收集包括:您的好友列表、群列表信息、声纹特征值信息。为确保您使用我们服务时能与您认识的人进行联系,如您选择开启导入通讯录功能,我们可能对您联系人的姓名和电话号码进行加密,并仅收集加密后的信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">2.6 我们可能会获得您在使用第三方合作伙伴服务时所产生或分享的信息。包括:您使用笔墨讯使帐户登录第三方合作伙伴服务时,或者您使用第三方合作伙伴服务账户登录笔墨讯使时,我们会获得您登录第三方合作伙伴服务的名称、登录时间或登录笔墨讯使的登录时间,方便您进行授权管理。请您仔细阅读第三方合作伙伴服务的用户协议或隐私政策。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们的产品在应用运行期间需要收集您的设备唯一识别码(MAC地址及IMEI/IDFA、SIM 卡 IMSI 信息、OAID、ANDROID ID)以提供统计分析等服务,并通过应用启动数据及异常错误日志分析改进性能和用户体验,为用户提供更好的服务。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">APP涉及嵌入第三方代码、插件传输个人信息的情形逐项列举如下:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">获取设备的传感器</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">用途:获取设备的传感器列表 为了检测、防止安卓模拟器等三方模拟器的使用</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">Bugly SDK</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">主体:深圳市腾讯计算机系统有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">用途:应用崩溃问题捕获</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">收集的个人信息类型:硬件型号、设备MAC地址、唯一设备识别码 (如IMEI/MEID/ ANDROID ID /SN/OPENUDID/GUID、SIM卡IMSI信息在内的描述个人常用设备基本情况的信息)、设备型号、设备制造商、操作系统及其版本;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">官网链接:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">https://privacy.qq.com/document/preview/fc748b3d96224fdb825ea79e132c1a56</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">OPPO PUSH SDK</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">涉及个人信息:设备标识符(如IMEI、OAID、硬件序列号/Serial、IMSI、Android ID、GAID/AAID)、应用信息、网络信息、IP地址、设备信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用场景:在OPPO手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">第三方主体:广东欢太科技有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">官网链接:https://open.oppomobile.com/wiki/doc#id=10194</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">隐私政策:https://open.oppomobile.com/new/developmentDoc/info?id=11228</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">VIVO PUSH SDK</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">涉及个人信息:设备信息、IMEI、OAID、GAID/AAID、Android ID、网络信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用场景:在VIVO手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">第三方主体:维沃移动通信有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">官网链接:https://dev.vivo.com.cn/documentCenter/doc/366</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">隐私政策:https://dev.vivo.com.cn/documentCenter/doc/652</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">华为 PUSH SDK</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">涉及个人信息:应用基本信息、应用内设备标识符、设备的硬件信息、软件列表、系统基本信息和系统设置信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用场景:在华为手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">第三方主体:华为软件技术有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">官网链接:https://developer.huawei.com/consumer/cn/doc/app/20213</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">隐私政策:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">hmscore-base-sdk</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">涉及个人信息:应用基本信息、应用内设备标识符、设备的硬件信息、软件列表、系统基本信息和系统设置信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用场景:在华为手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">第三方主体:华为软件技术有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">官网链接:https://developer.huawei.com/consumer/cn/doc/app/20213</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">隐私政策:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">小米 PUSH SDK</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">涉及个人信息:设备标识符(如Android ID、OAID)、应用信息、设备信息、网络信息(本地处理)、SSID</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用场景:在小米手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">第三方主体:北京小米移动软件有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">官网链接:https://dev.mi.com/console/appservice/push.html</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">隐私政策:https://dev.mi.com/console/doc/detail?pId=1822</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">荣耀 PUSH SDK</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">涉及个人信息:设备标识符(GAID/AAID),应用Token、推送消息内容</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">使用场景:在荣耀手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">第三方主体:荣耀终端有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">官网链接:https://lbs.amap.com/</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">隐私政策:https://lbs.amap.com/pages/privacy/</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">您提供的上述信息将在您使用本服务期间持续授权我们使用,为方便您管理软件账户,我们会在软件账户服务中同步并显示您的注册信息,包括通过软件账户集中展示您的个人资料、享受权益等。在您主动注销账号时,我们将根据适用法律法规的要求立即使其匿名或删除您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">三、我们如何使用收集的信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们严格遵守法律法规的规定及与用户的约定,将收集的信息用于以下用途。若我们超出以下用途使用您的信息,我们将再次向您进行说明,并征得您的同意。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">3.1 向您提供服务。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">3.2 满足您的需求。例如,语言设定、位置设定、帮助服务。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">3.3 产品开发和服务优化。例如,当我们的系统发生故障时,我们会记录和分析系统故障时产生的信息,优化我们的服务。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">3.4 安全保障。例如,我们会将您的信息用于身份验证、安全防范、反诈骗监测、存档备份、客户的安全服务等用途。例如,您下载或安装的安全软件会对恶意程序或病毒进行检测,或为您识别诈骗信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">3.5 评估、改善我们的广告投放和其他促销及推广活动的效果。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">3.6 管理软件。例如,进行软件认证、软件升级等。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">3.7 邀请您参与有关我们服务的调查。 为了让您有更好的体验、改善我们的服务或经您同意的其他用途,在符合相关法律法规的前提下,我们可能将通过某些服务所收集的信息用于我们的其他服务。例如,将您在使用我们某项服务时的信息,用于用户研究分析与统计等服务。 为了确保服务的安全,帮助我们更好地了解我们应用程序的运行情况,我们可能记录相关信息,例如,您使用应用程序的频率、故障信息、总体使用情况、性能数据以及应用程序的来源。我们不会将我们存储在分析软件中的信息与您在应用程序中提供的个人身份信息相结合。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">四、我们如何共享、转让、公开披露您的信息</span></p>
|
||||||
|
<p class="p2"><span class="s1">4.1 我们将遵守相关法律法规,对您的个人信息予以保密。除以下情况外,我们不会向其他人共享您的个人信息:</span></p>
|
||||||
|
<p class="p2"><span class="s1">A. 只有共享您的个人信息,才能提供您所需要的服务。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">B. 为了提升我们的产品及服务质量或向您提供全新的产品及服务,我们会在关联公司内部共享您的相关信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">C. 您通过笔墨讯使软件使用第三方服务时,笔墨讯使会按照“个人信息的收集”条款列明的共享内容与提供服务的第三方或合作伙伴(广告、分析服务类的授权合作伙伴、供应商、服务提供商和其他合作伙伴)共享您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">D. 为维护用户合法权益,在协助处理与您有关的纠纷或争议时,我们可能向与您存在利害关系的第三方提供解决纠纷或争议所必需的信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">E. 根据法律规定,刑事侦查机关为调查犯罪,依法定程序调取的必要个人信息,或行政机关、司法机构,依法定程序并经您授权同意调取的必要个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">F. 在法律要求或允许的范围内,为了保护社会公共利益、财产或安全而提供必要的信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">G. 在法定情形下的共享:我们可能会根据法律法规规定、诉讼争议解决需要,或按行政、司法机关依法提出的要求,对外共享您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">H. 另行获得您的明确同意或授权。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">4.2 非经法定程序或获得您的同意,我们不会将您的个人信息提供给任何第三方机构或个人。对我们与之共享个人信息的公司、组织和个人,我们会与之签署严格的保密协议,要求他们按照我们的说明、本隐私政策及其他任何相关的保密和安全措施来处理个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">4.3 我们将遵守相关法律法规,对您的个人信息予以保密。除非事先获得您的明确同意或授权,或依照法律规定所必须,我们不会公开披露您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">4.4 另外,根据相关法律法规及国家标准,以下情形中,我们可能会共享、转让、公开披露个人信息无需事先征得个人信息主体的授权同意:</span></p>
|
||||||
|
<p class="p2"><span class="s1">A. 与国家安全、国防安全直接相关的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">B. 与公共安全、公共卫生、重大公共利益直接相关的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">C. 与犯罪侦查、起诉、审判和判决执行等直接相关的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">D. 出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">E. 个人信息主体自行向社会公众公开的个人信息;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">F. 从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">4.5 如发生收购、兼并、重组等变更,我们会要求变更后的主体依然遵守本隐私政策约定,履行原有责任及义务。如变更后的主体需变更个人信息使用目的,我们会要求其事先获得您的明示同意。对内而言,在之前的收购、兼并活动中,对于被收购、被兼并对象管理的数据(包括用户数据)均采用与笔墨讯使自有数据相同的标准和要求进行处理和保护。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">五、我们如何保护您的个人信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们为您的信息提供相应的安全保障,以防止信息的丢失、不当使用、未经授权访问或披露。</span></p>
|
||||||
|
<p class="p2"><span class="s1">5.1 我们严格遵守法律法规保护用户的通信秘密。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">5.2 我们将在合理的安全水平内使用各种安全保护措施以保障信息的安全。例如,我们使用加密技术(例如:TLS、SSL)、匿名化处理等手段来保护您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">5.3 我们建立专门的管理制度、流程和组织确保信息安全。例如,我们严格限制访问信息的人员范围,要求他们遵守保密义务,并进行审查。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">5.4 若发生个人信息泄露等安全事件,我们会启动应急预案,阻止安全事件扩大,并以推送通知、公告等形式告知您。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">5.5 我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本隐私政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">5.6 互联网并非绝对安全的环境,而且电子邮件、即时通讯、社交软件等与其他用户的交流方式无法确定是否完全加密,我们建议您使用此类工具时请使用复杂密码,并注意保护您的个人信息安全。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">5.7 互联网环境并非百分之百安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">六、我们如何保存您的个人信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">6.1 存储信息的地点:我们会按照法律法规规定,将境内收集的用户个人信息存储于中国境内。 如涉及向境外传输个人信息,我们将明确向您告知个人信息出境的目的、接收方、安全保障措施等情况,并另行征得您的同意。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">6.2 存储信息的期限一般而言,我们仅为实现目的所必需的最短时间保留您的个人信息,除非法律有强制的留存要求。但在下列情况下,我们有可能因需符合法律要求,更改个人信息的存储时间:</span></p>
|
||||||
|
<p class="p2"><span class="s1">A. 为遵守适用的法律法规等有关规定;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">B. 为遵守法院判决、裁定或其他法律程序的规定;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">C. 为遵守相关政府机关或法定授权组织的要求;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">D. 我们有理由确信需要遵守法律法规等有关规定;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">E. 为执行相关服务协议或本政策、维护社会公共利益,为保护我们的客户、我们或我们的关联公司、其他用户或雇员的人身财产安全或其他合法权益所合理必需的用途。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">6.3 请您注意,您在使用我们的服务期间,我们仅在法律法规规定、监管要求及为实现本条款声明的目的所必需的时限内保留您的个人信息,在您注销账号后,我们仅在法律法规规定、监管要求的期限内保留个人信息,且不会开展除存储和采取必要的安全保护措施之外的处理活动,但已经匿名化处理后的个人信息除外。当您成功注销笔墨讯使账户或超出保留期间后,我们将对您的个人信息进行删除或匿名化处理。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">6.4 当我们的产品或服务发生停止运营的情形时,我们将采取例如,推送通知、公告等形式通知您,并在合理的期限内删除或匿名化处理您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">七、我们如何使用Cookie及同类技术</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">7.1 为实现您联机体验需求,使您获得更轻松的访问体验。我们会在您的计算机或移动设备上发送一个或多个名为Cookies的小数据文件,指定给您的Cookies 是唯一的,它只能被将Cookies发布给您的域中的Web服务器读取。我们向您发送Cookies是为了简化您重复登录的步骤、存储您的偏好数据进而帮助判断您的登录状态以及账户或数据安全。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">7.2 我们不会将 Cookies 用于本隐私政策所述目的之外的任何用途。您可根据自己的偏好管理或删除 Cookies。另外,您也可以清除软件内保存的所有Cookies。但如果您这么做,您可能需要在每一次访问软件时亲自更改用户设置,而且您之前所记录的相应信息也均会被删除,并且可能会对您所使用服务的安全性有一定影响。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">7.3 网络Beacon和同类技术的使用 除Cookies 外,我们还会在网站上使用网络Beacon等其他同类技术。我们的网页上常会包含一些电子图像(称为"单像素" GIF 文件或 "网络 Beacon")。使用网络Beacon可以计算浏览网页的用户或访问某些Cookies,并通过得到的Cookies信息,为您提供服务。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">八、您如何管理自己的信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">您可以通过以下方式访问及管理您的信息:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">8.1 查询、更正和补充您的信息 您有权查询、更正或补充您的信息。您可以通过以下方式自行进行: 登录笔墨讯使客户端,进入“我的”,点击用户名对个人资料、基本信息、认证信息、个人资料等进行查询、更正或补充;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">8.2 删除您的信息 您可以通过“8.1查询、更正和补充您的信息”中列明的方式删除您的部分信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">在以下情形中,您可以向我们提出删除个人信息的请求:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">A. 如果我们处理个人信息的行为违反法律法规;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">B. 如果我们收集、使用您的个人信息,却未征得您的明确同意;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">C. 如果我们处理个人信息的行为严重违反了与您的约定;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">D. 如果您不再使用我们的产品或服务,或您主动注销了账号;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">E. 如果我们永久不再为您提供产品或服务。</span></p>
|
||||||
|
<p class="p2"><span class="s1">若我们决定响应您的删除请求,我们还将同时尽可能通知从我们处获得您的个人信息的主体,并要求其及时删除(除非法律法规另有规定,或这些主体已独立获得您的授权)。 当您或我们协助您删除相关信息后,因为适用的法律和安全技术,我们可能无法立即从备份系统中删除相应的信息,我们将安全地存储您的个人信息并将其与任何进一步处理隔离,直到备份可以清除或实现匿名。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">8.3 改变您授权同意的范围</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">每个业务功能需要一些基本的个人信息才能得以完成(见本隐私政策“第一条 我们收集的信息”)。除此之外,您可以在笔墨讯使客户端“我的-设置-隐私设置”中设置或改变您的智能移动设备的设置等方式给予或收回您的授权同意的范围。 当您收回同意后,我们将不再处理相应的个人信息。但您收回同意的决定,不会影响此前基于您的授权而开展的个人信息处理。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">8.4 注销您的账户</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">您可以通过以下方式申请注销您的账户:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">登录笔墨讯使官网并选择联系客服寻求帮助,协助您申请注销您的账户。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">在您主动注销账户之后,我们将停止为您提供产品或服务,根据适用法律的要求删除您的个人信息,或使其匿名化处理。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">8.5 约束信息系统自动决策</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制做出决定。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">如果这些决定显著影响您的合法权益,您有权要求我们做出解释,我们也将在不侵害笔墨讯使商业秘密或其他用户权益、社会公共利益的前提下提供申诉方法。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">8.6 响应您的上述请求</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们将在15天内做出答复。如您不满意,还可以通过客服邮箱发起投诉。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视情收取一定成本费用。对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">在以下情形中,按照法律法规要求,我们将无法响应您的请求:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">A. 与国家安全、国防安全有关的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">B. 与公共安全、公共卫生、重大公共利益有关的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">C. 与犯罪侦查、起诉、审判和执行判决等有关的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">D. 有充分证据表明个人信息主体存在主观恶意或滥用权利的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">E. 响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">F. 涉及商业秘密的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">G. 与我们履行法律法规规定的义务相关的;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">H. 出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">九、您共享的信息</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">9.1 您可以基于我们的服务与他人、社交网络分享您的相关信息,这其中可能包含您的个人身份信息、个人财产信息等敏感信息,并自主选择分享的对象作为能够看到您信息的第三方。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">9.2 当您与他人、社交网络或第三方服务提供商共享您的个人信息,或结合第三方的服务使用、或使用第三方的服务链接时,您可能会披露或使第三方获取您的个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">9.3 我们建议您查看此类社交网络或第三方服务提供商的隐私声明,以了解他们如何处理您的信息。对于您使用第三方服务时向其提供或与他人分享个人信息而产生的后果由您自行承担,并由相应责任方在法律规定范围内承担责任。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">9.4 当您在笔墨讯使平台公开分享任何信息时,任何人都可能在使用笔墨讯使平台时查看或访问这些信息,如您在笔墨讯使平台上传的照片、评价等信息。您在使用我们服务时自愿共享的信息,可能会涉及您或他人的个人信息,请您谨慎选择并自行承担责任。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">十、未成年人保护</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">10.1 我们非常重视对未成年人个人信息的保护。根据相关法律法规的规定,若您是18周岁以下的未成年人,在使用笔墨讯使的服务前,应事先取得您的家长或法定监护人的同意。若您是未满14周岁的未成年人,您的监护人需要仔细阅读本政策并同意您依照本政策适用笔墨讯使平台。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">10.2 我们不会主动直接向未成年人收集其个人信息。对于经监护人同意而收集未成年人个人信息的情况,我们只会在受到法律允许、监护人同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">10.3 如果有事实证明未成年人并未取得监护人同意的情况下注册使用了我们的产品与/或服务,我们会与相关监护人协商,并设法尽快删除相关个人信息。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">十一、适用范围</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们的所有服务均适用本政策。但某些服务有其特定的隐私指引/声明,该特定隐私指引/声明更具体地说明我们在该服务中如何处理您的信息。如本政策与特定服务的隐私指引/声明有不一致之处,请以该特定隐私指引/声明为准。 请您注意,本政策不适用由其他公司或个人提供的服务。例如,您通过使用笔墨讯使帐号登录其他公司或个人提供的服务。 您使用该等第三方服务须受其隐私政策(而非本政策)约束,您需要仔细阅读其政策内容。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">十二、通知和修订</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">12.1 为给您提供更好的服务以及随着笔墨讯使业务的发展,本隐私政策也会随之更新。但未经您明确同意,我们不会削减您依据本隐私政策所应享有的权利。我们会通过在笔墨讯使官方网站、笔墨讯使移动端上发出更新版本并在生效前通过网站公告或以其他适当方式提醒您相关内容的更新,也请您访问及时了解最新的隐私政策。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">12.2 对于重大变更,我们还会提供更为显著的通知(我们会通过包括但不限于邮件、短信或在浏览页面做特别提示等方式,说明隐私政策的具体变更内容)。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">本隐私政策所指的重大变更包括但不限于:</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">A. 我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">B. 我们在所有权结构、组织架构等方面发生重大变化。如业务调整、破产并购等引起的所有者变更等;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">C. 个人信息共享、转让或公开披露的主要对象发生变化;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">D. 您参与个人信息处理方面的权利及其行使方式发生重大变化;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">E. 我们负责处理个人信息安全的责任部门、联络方式及投诉渠道发生变化时;</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">F. 个人信息安全影响评估报告表明存在高风险时。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">12.3 我们还会将本隐私政策的旧版本存档,供您查阅。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">十三、本隐私政策如何更新</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们的隐私保护政策可能变更。未经您明确同意,我们不会限制您按照本隐私政策所应享有的权利。对于重大变更,我们会提供显著的通知(包括通过我们公示的方式进行通知甚至向您提供弹窗提示)。本政策所指的重大变更包括但不限于:</span></p>
|
||||||
|
<p class="p2"><span class="s1">13.1 我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">13.2 我们在控制权等方面发生重大变化。如并购、重组等引起的所有者变更等。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">13.3 个人信息共享、转让或公开披露的主要对象发生变化。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">13.4 您参与个人信息处理方面的权利及其行使方式发生重大变化。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">13.5 我们负责处理个人信息安全的责任部门、联络方式及投诉渠道发生变化时。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">13.6 个人信息安全影响评估报告表明存在高风险时。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">我们还会将本隐私政策的旧版本存档,供您查阅。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">十四、如何联系我们</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">14.1 如您对本隐私政策或您个人信息的相关事宜有任何问题、意见或建议,请联系笔墨讯使客服(联系邮箱:【fengqunwangluo2025@163.com】)。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">14.2 一般情况下,我们将在15天内回复和处理您的疑问、意见或建议。需注意的是,我们可能不会回复与本政策或您的个人信息权利无关的问题。如果您对我们的回复不满意,特别是我们的个人信息处理行为损害了您的合法权益,您还可以向网信、电信、公安及工商等监管部门进行投诉或举报。或通过向我们所在地有管辖权的法院提起诉讼来寻求解决方案。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">十五、附则</span></p>
|
||||||
|
<p class="p2"><span class="s1">15.1 本政策的解释及争议解决均应适用中华人民共和国法律。与本政策相关的任何纠纷,双方应经友好协商解决;若不能协商解决,您在此同意将争议提交至我们公司所在地人民法院提起诉讼。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">15.2 如果有管辖权的任何法院裁定或判决本政策的任何条款无效,则该条款将从本政策中移除,但该条款的无效不影响本政策其余条款的效力。本政策的其余条款将继续执行。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">15.3 本政策的标题仅为方便阅读而设计,不影响本政策任何条款的含义或解释。</span></p>
|
||||||
|
<p class="p1"><span class="s1"></span><br></p>
|
||||||
|
<p class="p2"><span class="s1">开发者名称:【海口市枫群网络科技有限公司】</span></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,532 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||||
|
<title></title>
|
||||||
|
<meta name="Generator" content="Cocoa HTML Writer">
|
||||||
|
<meta name="CocoaVersion" content="2575.7">
|
||||||
|
<style type="text/css">
|
||||||
|
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Times; -webkit-text-stroke: #000000}
|
||||||
|
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Times; -webkit-text-stroke: #000000; min-height: 14.0px}
|
||||||
|
span.s1 {font-kerning: none}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>笔墨讯使软件服务协议</span></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>前言</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">欢迎您使用【海口市枫群网络科技有限公司】公司(下称“我公司”或“我们”)为您提供的笔墨讯使的服务!</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">特别提示:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">为使用笔墨讯使软件(以下简称“本软件”)及服务,您应当阅读并遵守《笔墨讯使软件服务协议》(以下简称“本协议”)。请您务必仔细阅读、充分理解本协议各条款内容,特别是豁免或者限制我公司责任的条款、对用户权利进行限制的条款、约定管辖与法律适用条款,以及开通或使用某项服务的单独协议。限制、免责条款或者其他涉及您重大权益的条款可能以加粗等形式提示您重点注意。如您对本协议有任何疑问,可通过文末联系方式联系我们。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">除非您已阅读并接受本协议所有条款,否则您无权注册或登录使用本软件及相关服务。您点击“同意”,或者您注册或登录本软件的行为,或者其他明示或者默示方式表示接受本协议的行为即视为您已阅读并同意接受本协议的约束。本协议即在您与我公司之间产生法律效力,成为对双方均具有约束力的法律文件。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">如果您未满18周岁,或存在其他不具备与用户行为相适应的民事行为能力的情形,请在法定监护人的陪同、指导下阅读本协议,并特别注意未成年人使用条款,在确保监护人同意本协议内容后使用本软件。您及您的监护人应依照法律法规规定,承担同意本协议及使用本软件而导致的相应后果。</span></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>一、协议的范围</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">1.1 协议适用主体范围</span></p>
|
||||||
|
<p class="p1"><span class="s1">本协议是您与我们之间关于您下载、安装、注册、登录、使用本软件以及使用我们提供的相关服务所订立的协议。包括本协议正文、《隐私协议》及我公司已经发布的或将来可能发布/更新的并采取合理途径通知的各类规则、规范、通知等。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">1.2 协议关系</span></p>
|
||||||
|
<p class="p1"><span class="s1">本协议内容同时包括我们可能不断发布的关于本服务的相关协议、业务规则、通知等内容。上述内容一经正式发布,即为本协议不可分割的组成部分,您同样应当遵守。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">1.3 相关定义</span></p>
|
||||||
|
<p class="p1"><span class="s1">“我公司或我们”,是指笔墨讯使及相关服务可能存在的运营关联单位,即【海口市枫群网络科技有限公司】公司及其关联公司。</span></p>
|
||||||
|
<p class="p1"><span class="s1">“用户”,是指使用本软件及相关服务的使用者,在本协议中更多地称为“您”。</span></p>
|
||||||
|
<p class="p1"><span class="s1">“服务”,是指我们向您提供的笔墨讯使软件相关服务,具体以我们实际提供的为准。同时,我们有权对提供的软件服务进行增加、关停或其他调整。</span></p>
|
||||||
|
<p class="p1"><span class="s1">“账号”,指用户在使用服务时可能需要注册的账号。用户可在本软件注册并获得的账号,作为登录并使用本软件的凭证。</span></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>二、关于本服务</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.1 本服务的内容</span></p>
|
||||||
|
<p class="p1"><span class="s1">本服务内容是指我们向用户提供的跨平台的通讯工具(以下简称“笔墨讯使”),支持单人、多人参与,在发送语音短信、视频、图片和文字等即时通讯服务的基础上,同时为用户提供包括但不限于网络媒体、互联网增值、互动娱乐、电子商务、电子钱包、开放平台、与其他软件或硬件信息互通等功能或内容的软件许可及服务(以下简称“本服务”)和广告等服务(以下简称“本服务”)。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.2 本服务的形式</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.2.1 您使用本服务需要下载笔墨讯使客户端软件,对于这些软件,我们给予您一项个人的、不可转让及非排他性的许可。您仅可为访问或使用本服务的目的而使用这些软件及服务。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.2.2 本服务中笔墨讯使客户端软件可能会提供包括但不限于iOS、Android、Windows、Mac等多个应用版本,用户必须选择与所安装终端设备相匹配的软件版本。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.3 本服务许可的范围</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.3.1 我们给予您一项个人的、不可转让及非排他性的许可,以使用本软件。您可以为非商业目的在单一台终端设备上安装、使用、显示、运行本软件。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.3.2 本条及本协议其他条款未明确授权的其他一切权利仍由我们保留,您在行使这些权利时须另外取得我们的书面许可。我们如果未行使前述任何权利,并不构成对该权利的放弃。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2.4 按现状提供服务</span></p>
|
||||||
|
<p class="p1"><span class="s1">您理解并同意,笔墨讯使的服务是按照现有技术和条件所能达到的现状提供的。笔墨讯使会尽最大努力向您提供服务,确保服务的连续性和安全性;但笔墨讯使不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力、病毒、木马、黑客攻击、系统不稳定、第三方服务缺陷、政府行为等原因可能导致的服务中断、数据丢失以及其他的损失和风险。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">三、软件的获取与使用</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3.1 您可以直接从我们的网站上获取本软件,也可以从得到我们授权的第三方获取。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3.2 如果您从未经我们授权的第三方获取本软件或与本软件名称相同的安装程序,我们无法保证该软件能够正常使用,并对因此给您造成的损失不予负责。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3.3 我们可能为不同的终端设备开发了不同的软件版本,您应当根据实际情况选择下载合适的版本进行安装。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3.4 下载安装程序后,您需要按照该程序提示的步骤正确安装。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3.5 为提供更加优质、安全的服务,在本软件安装时我们可能会推荐您安装其他软件,您可以选择安装或不安装。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3.6 为了改善用户体验、保证服务的安全性及产品功能的一致性,我们可能会不时对笔墨讯使软件进行更新。我们有权不经过向您特别通知而对软件进行更新,或者对软件的部分功能效果进行改变或限制。您应当将相关软件更新到最新版本,否则我们并不保证其能正常使用。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3.7 如果您不再需要使用本软件或者需要安装新版软件,可以自行卸载。如果您愿意帮助我们改进产品服务,请告知卸载的原因。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>四、用户个人信息保护</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4.1 保护用户个人信息是我们的一项基本原则,我们将按照本协议的规定收集、使用、存储您的个人信息,并会采取合理的措施保护您的个人信息。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4.2 您在注册账号或使用本服务的过程中,需要提供一些必要的信息,例如:为向您提供账号注册服务或进行用户身份识别,需要您填写手机号码、身份证号码等;笔墨讯使某些功能可能需要收集您的个人信息包括:昵称、头像、手机号、身份证号、加入群组、好友关系等。若国家法律法规或政策有特殊规定的,您需要提供真实的身份信息。若您提供的信息不完整,则无法使用本服务或在使用过程中受到限制。您了解并同意,您有义务保持您提供信息的真实性、有效性及完整性。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4.3 一般情况下,您可随时查看、修改自己提交的信息,但出于安全性和身份识别(如号码申诉服务)的考虑,您可能无法修改注册时提供的初始注册信息及其他验证信息。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4.4 我们将运用各种安全技术和程序建立完善的管理制度来保护您的个人信息,以免遭受未经授权的访问、使用或泄露。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4.5 未经您的同意,我们不会将您的个人信息转移或披露给任何非关联的第三方,除非:</span></p>
|
||||||
|
<p class="p1"><span class="s1">(1)相关法律法规或法院、政府机关要求;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(2)为完成合并、分立、收购或资产转让而转移;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(3)为提供您要求的服务所必需;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(4)依据其他相关协议规则可以转移或披露给任何第三方的情形。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4.6 我们非常重视对未成年人个人信息的保护。若您是18周岁以下的未成年人,在使用我们的服务前,应事先取得您家长或法定监护人的书面同意。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4.7 我们可能会在向您提供服务的过程之中所收集的信息用作下列用途:</span></p>
|
||||||
|
<p class="p1"><span class="s1">(1) 向您提供服务;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(2) 在我们提供服务时,用于身份验证、客户服务、安全防范、诈骗监测、存档和备份用途,确保我们向您提供的产品和服务的安全性;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(3) 帮助我们设计新服务,改进我们现有服务;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(4) 使我们更加了解您如何接入和使用我们的服务,从而针对性地回应您的个性化需求,例如语言设置、位置设置、个性化的帮助服务和指导,或对您和其他用户作出其他方面的回应;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(5) 向您提供与您更加相关的广告以替代普遍投放的广告;评估我们服务中的广告和其他促销及推广活动的效果,并加以改进;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(6) 软件认证或管理软件升级;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(7) 让您参与有关我们产品和服务的调查。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">## 五、主权利义务条款</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.1 账号使用规范</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.1.1 您在使用本服务前需要注册一个笔墨讯使账号。本软件为您提供注册及登录通道,笔墨讯使账号通过手机号码进行注册,您可按照页面提示填写信息、阅读并同意本协议,在完成全部注册登录程序后,成为本软件用户。另外我们有权根据用户需求或产品需要对账号注册的方式进行变更,关于您使用账号的具体规则,请遵守相关账号使用协议以及我们为此发布的专项规则。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.1.2 笔墨讯使账号的所有权归我们公司所有,用户完成申请注册手续后,仅获得笔墨讯使账号的使用权,且该使用权仅属于初始申请注册人。同时,初始申请注册人不得赠与、借用、出租、转让或售卖笔墨讯使账号或者以其他方式许可非初始申请注册人使用笔墨讯使账号。非初始申请注册人不得通过受赠、继承、承租、受让或者其他任何方式使用笔墨讯使账号。如我们判断您账号的使用可能违反法律法规、危及您的账号安全及/或本软件信息安全的,我们可拒绝提供相应服务或终止本协议。我们有权视情况封禁或注销、回收该账号,由此带来的包括但不限于内容、虚拟财产清空等损失由您本人及该账号使用者自行承担。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.1.3 您注册获得的账号、设置的密码是您登录并以用户身份使用本软件的凭证,您的账户仅限您本人使用,您有责任妥善保管您的注册用户信息及用户密码的安全,您需要对您的注册用户以及密码下的行为承担法律责任。您同意在任何情况下不向他人泄露用户及密码信息。当在您怀疑他人在使用您的账号时,您应立即通知我们。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.1.4 用户注册笔墨讯使账号后如果长期(超过【6】个月)不登录该账号,我们有权回收该账号,以免造成资源浪费,由此带来的任何损失均由用户自行承担。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.1.5 我们特别提醒,您应妥善保管您的账号和密码。当您使用完本服务后,应安全退出。您须对账号进行的所有活动和行为负责,因您保管不善导致遭受账号或密码失窃、账号被非法使用,相关责任由您自行承担,您可通过司法、行政等救济途径向侵权行为人追偿。</span></p>
|
||||||
|
<p class="p1"><span class="s1">5.1.6您不得恶意注册账号,包括但不限于频繁注册、批量注册、使用他人身份注册或其他不以正常使用本软件服务为目的的账号注册行为。除此外,您的账户不得以任何方式转让,否则我们有权追究您的违约责任,且由此产生的责任及后果均由您自行承担。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2 用户注意事项</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.1 您理解并同意:为了向您提供有效的服务,本软件会利用您终端设备的处理器和带宽等资源。本软件使用过程中可能产生数据流量的费用,用户需自行向运营商了解相关资费信息,并自行承担相关费用。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.2 您理解并同意:本软件的某些功能可能会让第三方知晓用户的信息,例如:用户选择笔墨讯使与其他软件或硬件信息互通后,其他软件或硬件的提供方可以获取用户在笔墨讯使主动公开或传输的相关信息,用户在选择前应充分了解其他软件或硬件的产品功能及信息保护策略。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.3 您在使用本软件某一特定服务时,该服务可能会另有单独的协议、相关业务规则等(以下统称为“单独协议”),您在使用该项服务前请阅读并同意相关的单独协议;您使用前述特定服务,即视为您接受相关单独协议。例如:如果您需要使用笔墨讯使支付相关服务(包括但不限于笔墨讯使红包、转账、收款、充值、提现等支付服务)时,需阅读并遵守《笔墨讯使支付服务协议》;您使用笔墨讯使支付相关服务,即视为您接受《笔墨讯使支付服务协议》。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.4 您理解并同意我们将尽其商业上的合理努力保障您在本软件及服务中的数据存储安全,但是,我们并不能就此提供完全保证,包括但不限于以下情形:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.4.1 我们不对您在本软件及服务中相关数据的删除或存储失败负责;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.4.2 我们有权根据实际情况自行决定单个用户在本软件及服务中数据的最长存储期限,并在服务器上为其分配数据最大存储空间等。您可根据自己的需要自行备份本软件及服务中的相关数据;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.4.3 如果您停止使用本软件及服务或服务被终止或取消,我们可以从服务器上永久地删除您的数据。服务停止、终止或取消后,我们没有义务向您返还任何数据。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.5 用户在使用本软件及服务时,需自行承担如下来自我们不可控制的风险内容,包括但不限于:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.5.1 由于不可抗力因素可能导致的个人信息丢失、泄露等风险;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.5.2 用户必须选择与所安装终端设备相匹配的软件版本,否则,由于软件与终端设备型号不匹配所导致的任何问题或损害,均由用户自行承担;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.5.3 用户在使用本软件访问第三方网站时,因第三方网站及相关内容所可能导致的风险,由用户自行承担;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.5.4 用户发布的内容被他人转发、分享,因此类传播可能带来的风险和责任;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.5.5 由于无线网络信号不稳定、无线网络带宽小等原因,所引起的笔墨讯使登录失败、资料同步不完整、页面打开速度慢等风险。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.2.6 您理解并同意,笔墨讯使可能会不时发布并执行一些用户奖励活动,相关活动的具体规则的制定权和最终解释权归我们所有,我们有权根据自己的判断决定提前终止活动或延长活动时间。同一笔墨讯使用户名、同一手机号、同一身份证号码、同一手机设备均视为同一用户。如果我们发现有用户利用不正当手段参与活动,或者如果用户存在或涉嫌违法违规行为情况(包括不限于洗钱、外挂、作弊、套现、赌博、刷奖励类的活动、其他风险行为),我们有权取消您参与活动的资格,并有权追回您已经获得的奖励或代币或其他奖品。如果因非实名认证导致您无法参与活动的,视为您自动放弃活动资格。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.3 第三方产品和服务</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.3.1 您在使用本软件第三方提供的产品或服务时,除遵守本协议约定外,还应遵守第三方的用户协议。我们和第三方对可能出现的纠纷在法律规定和约定的范围内各自承担责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.3.2 因用户使用本软件或要求我们提供特定服务时,本软件可能会调用第三方系统或者通过第三方支持用户的使用或访问,使用或访问的结果由该第三方提供(包括但不限于第三方通过笔墨讯使开放平台接入的内容等),我们不保证通过第三方提供服务及内容的安全性、准确性、有效性及其它不确定的风险,您应自行判断此类第三方网站或者服务的安全性和可用性,并自行承担相关风险和责任,由此若引发的任何争议及损害,与我们无关,我们不承担任何责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.3.3 第三方服务提供者可以通过本软件向您提供产品或者服务,比如您可以购买并使用第三方开发的应用程序、接受第三方提供的服务及产品,或者通过笔墨讯使授权登录能力登录并使用其他互联网服务。在此过程中,第三方服务提供者可能会收集、使用和存储您的相关数据或信息,我们通过与第三方服务提供者签订的有关协议、笔墨讯使相关规范以及合理的产品流程设计,严格要求第三方服务提供者获取您的任何数据均应遵守相关法律法规的规定,必须事先获得您的明确同意,采取必要的数据保护措施,且仅为产品或服务之目的合理使用您的相关数据,向您提供修改或删除自己数据的方式,并在停止服务时必须删除全部数据等,尽最大可能保障您的数据和隐私不受侵犯。您在接受或使用第三方产品或服务前应充分了解第三方产品或服务的条款及政策。如果您发现有第三方服务提供者存在相关违法违规行为,可以向我们投诉,我们将查实后予以处理。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.3.4 您理解并同意,我们有权决定将本软件作商业用途,包括但不限于开发、使用本软件的部分服务为第三方作推广等,我们承诺在推广过程中严格按照本协议约定保护您的个人信息,同时您也可以根据系统设置选择屏蔽、拒绝接收相关推广信息。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.4账号信息设置及维护</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.4.1您在注册或使用本软件时设置的名称、头像和简介等账号信息资料应遵守法律法规、社会道德风尚和信息真实性等原则,不得出现不良信息,不得冒用他人姓名、名称、字号、头像等或采取其他足以引起混淆的方式设置账号,不得侵害第三方的合法权益。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.4.2在使用本软件服务时,您应当按本软件页面的提示准确完整地提供您的信息(包括您的姓名及电子邮件地址、联系电话、联系地址等),以便本软件或其他用户与您联系。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.4.3您应当及时更新您提供的信息,在法律有明确规定要求本软件必须对用户的信息进行核实的情况下,本软件将依法不时地对您的信息进行检查核实,您应当配合提供最新、真实、完整、有效的信息。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.4.4如本软件按您最后一次提供的信息与您联系未果、您未按本软件的要求及时提供信息、您提供的信息存在明显不实或行政司法机关核实您提供的信息无效的,您将承担因此对您自身、他人及本软件造成的全部损失与不利后果。本软件可向您发出询问或要求整改的通知,并要求您进行重新认证,直至中止、终止对您提供部分或全部软件产品或服务,本软件对此不承担责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.5账号注销及回收</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.5.1您可以依照本软件的流程申请注销您的账号,但您仍应对您在注销账号前或使用本软件服务期间的行为承担相应责任。注销成功后,除非法律法规另有规定,我们不会为您提供账号记录、内容、虚拟财产等恢复或提供服务,请您谨慎操作。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.5.2您理解并同意,为了充分使用账号资源,如您在注册后未及时进行初次登录使用或连续超过【6】个月未登录账号并使用,且不存在未到期或未履行完毕的持续性本软件服务的,我们有权收回您的账号。如您的账号被收回,您无法通过您此前持有的账号登录并使用本软件,您账号下保存的个性化设置和使用记录也将无法恢复。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5.6账号违规处置</span></p>
|
||||||
|
<p class="p1"><span class="s1">若您在注册或使用本软件账号时,存在任何违反法律法规或不符合本协议约定的行为,我们有权不予注册;已经注册的,我们有权视情况要求用户限期改正、或单方采取短期封禁、永久封禁、注销账号等措施。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>六、用户行为规范</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1 信息内容规范</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.1 本条所述信息内容是指用户使用本软件及服务过程中所制作、复制、发布、传播的任何内容,包括但不限于笔墨讯使账号、昵称、头像、姓名、用户说明等注册信息,或文字、语音、图片等发送、回复、图文和相关链接页面,以及其他使用笔墨讯使账号或本软件及服务所产生的内容。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2 您理解并同意,笔墨讯使一直致力于为用户提供文明健康、规范有序的网络环境,您不得利用笔墨讯使账号或本软件及服务制作、复制、发布、传播如下干扰笔墨讯使正常运行,以及侵犯其他用户或第三方合法权益的内容,包括但不限于:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.1 发布、传送、传播、存储违反国家法律法规禁止的内容:</span></p>
|
||||||
|
<p class="p1"><span class="s1">(1)违反宪法规定的基本原则,煽动抗拒或者破坏宪法等法律法规实施的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(2)危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一、主权和领土完整的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(3)损害国家荣誉和利益。宣扬恐怖主义、极端主义的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(4)诋毁民族优秀文化传统,煽动民族仇恨、民族歧视,侵害民族风俗习惯,歪曲民族历史和民族历史人物,伤害民族感情,破坏民族团结的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(5)煽动破坏国家宗教政策,宣扬宗教狂热,危害宗教和睦,伤害信教公民宗教感情,破坏信教公民和不信教公民团结,宣扬邪教和封建迷信的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(6)散布谣言,危害社会公德,扰乱社会秩序,破坏社会稳定的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(7)散布淫秽、色情、赌博、暴力、恐怖,传授犯罪方法或者教唆犯罪的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(8)诽谤或者侮辱他人,侵害他人合法权益的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(9)煽动非法集会、结社、游行、示威、聚众扰乱社会秩序;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(10)以非法民间组织名义活动的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(11)不符合《即时通讯工具公众信息服务发展管理暂行规定》及遵守法律法规、社会主义制度、国家利益、公民合法利益、公共秩序、社会道德风尚和信息真实性等“七条底线”要求的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(12)侵害未成年人合法权益或者损害未成年人身心健康的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(13)违反法律法规底线、社会主义制度底线、国家利益底线、公民合法权益底线、社会公共秩序底线、道德风尚底线和信息真实性底线的“七条底线”要求的;</span></p>
|
||||||
|
<p class="p1"><span class="s1">(14)含有法律、行政法规禁止的其他内容的。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.2 发布、传送、传播、存储侵犯他人名誉权、肖像权、知识产权、商业秘密等合法权利的内容;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.3 涉及他人隐私、个人信息或资料的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.4 发表、传送、传播骚扰、广告信息、过度营销信息及垃圾信息或含有任何性或性暗示的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.5 其他违反法律法规、政策及公序良俗、社会公德或干扰笔墨讯使正常运行和侵犯其他用户或第三方合法权益内容的信息。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.6 您通过本服务发送或传播的内容(包括但不限于网页、文字、图片、音频、视频、图表等)均由您自行承担责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.6.1 您发送或传播的内容应有合法来源,相关内容为您所有或您已获得权利人的授权。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.6.2 您同意笔墨讯使可为履行本协议或提供本服务的目的而使用您发送或传播的内容。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.6.3 如果笔墨讯使收到权利人通知,主张您发送或传播的内容侵犯其相关权利的,您同意笔墨讯使有权进行独立判断并采取删除、屏蔽或断开链接等措施。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.1.2.7 您使用本服务时不得违反国家法律法规、侵犯他人合法权益。</span></p>
|
||||||
|
<p class="p1"><span class="s1">您理解并同意,如果您被他人投诉侵权或您投诉他人侵权,笔墨讯使有权将争议中相关方的主体、联系方式、投诉相关内容等必要信息提供给其他争议方或相关部门,以便及时解决投诉纠纷,保护他人合法权益。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2 软件使用规范</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1 除非法律允许或我们书面许可,您使用本软件过程中不得从事下列行为:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.1 删除本软件及其副本上关于著作权的信息;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.2 对本软件进行反向工程、反向汇编、反向编译,或者以其他方式尝试发现本软件的源代码;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.3 对我们享有知识产权的内容进行使用、出租、出借、复制、修改、链接、转载、汇编、发表、出版、建立镜像站点等;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.4 对本软件或者本软件运行过程中释放到任何终端内存中的数据、软件运行过程中客户端与服务器端的交互数据,以及本软件运行所必需的系统数据,进行复制、修改、增加、删除、挂载运行或创建任何衍生作品,形式包括但不限于使用插件、外挂或非我们经授权的第三方工具/服务接入本软件和相关系统;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.5 通过修改或伪造软件运行中的指令、数据,增加、删除、改变软件的功能或运行效果,或者将用于上述目的的软件、方法进行运营或向公众传播,无论这些行为是否为商业目的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.6 通过非我们开发、授权、许可的第三方软件、插件、外挂、系统,登录或使用我们的软件及服务,或制作、发布、传播上述工具,或对本软件的正常运行进行干扰、破坏、修改或施加其他影响;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.7 自行或者授权他人、第三方软件对本软件及其组件、模块、数据进行干扰;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.8 以任何方式(包括但不限于盗链、冗余盗取、非法抓取、模拟下载、深度链接、假冒注册等)直接或间接盗取本软件的视频、图文、用户信息等信息内容;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.9 利用或针对本软件进行任何危害计算机网络安全的行为,包括但不限于:非法侵入网络、干扰网络正常功能、窃取网络数据等危害网络安全的活动,或为上述活动提供程序、工具等支持与帮助;企图干涉、破坏本软件系统或网站的正常运行,故意传播恶意程序或病毒以及其他破坏干扰正常网络信息服务的行为等;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.1.10 其他以任何不合法的方式、为任何不合法的目的、或与我们为此制定的其他规范和标准不一致的方式使用本软件及未经我们明确授权的行为。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.2 您理解并同意,基于用户体验、笔墨讯使或相关服务平台运营安全、平台规则要求及健康发展等综合因素,我们有权选择提供服务的对象,有权决定功能设置,有权决定功能开放、数据接口和相关数据披露的对象和范围。针对以下情形,有权视具体情况中止或终止提供本服务,包括但不限于:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.2.1 违反法律法规或本协议规定的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.2.2 影响服务体验的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.2.3 存在安全隐患的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.2.4 与笔墨讯使或其服务平台已有主要功能或功能组件相似、相同,或可实现上述功能或功能组件的主要效用的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.2.5 界面、风格、功能、描述或使用者体验与笔墨讯使或其服务平台相似,可能造成笔墨讯使用户认为其所使用的功能或服务来源于我们或经我们授权的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.2.2.6 违反笔墨讯使或其服务平台运营原则,或不符合我们其他管理要求的。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.3 服务运营规范</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.3.1 除非您与笔墨讯使另有约定,您同意本服务仅为您个人非商业性质的使用。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.3.2 您应当通过笔墨讯使提供或认可的方式使用本服务。您依本协议条款所获得的权利不可转让。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.3.3 您不得使用未经笔墨讯使授权的插件、外挂或第三方工具对本协议项下的服务进行干扰、破坏、修改或施加其他影响。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.3.4 除非法律允许或我们书面许可,您使用本服务过程中不得从事下列行为:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">1) 提交、发布虚假信息,或冒充、利用他人名义的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2) 诱导其他用户点击链接页面或分享信息的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">3) 虚构事实、隐瞒真相以误导、欺骗他人的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">4) 侵犯他人名誉权、肖像权、知识产权、商业秘密等合法权利的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">5) 未经我们书面许可利用笔墨讯使账号和任何功能,以及第三方运营平台进行推广或相互推广的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6) 利用笔墨讯使账号或本软件及服务从事任何违法犯罪活动的;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">8) 其他违反法律法规规定、侵犯其他用户合法权益、干扰产品正常运营或我们未明确授权的行为。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.3.5 您在使用本服务过程中应当遵守当地相关的法律法规,并尊重当地的道德和风俗习惯。如果您的行为违反了当地法律法规或道德风俗,您应当为此单独承担责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.3.6 您应避免因使用本服务而使笔墨讯使卷入政治和公共事件,否则笔墨讯使有权暂停或终止对您的服务。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.4 对自己行为负责</span></p>
|
||||||
|
<p class="p1"><span class="s1">您充分了解并同意,您必须为自己注册账号下的一切行为负责,包括您所发表的任何内容以及由此产生的任何后果。您应对本服务中的内容自行加以判断,并承担因使用内容而引起的所有风险,包括因对内容的正确性、完整性或实用性的依赖而产生的风险。我们无法且不会对因前述风险而导致的任何损失或损害承担责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5 违约处理</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.1 如果我们发现或收到他人举报或投诉用户违反本协议约定的,我们有权不经通知随时对相关内容进行删除、屏蔽,并视行为情节对违规账号处以包括但不限于警告、限制或禁止使用部分或全部功能、账号封禁直至注销的处罚,并公告处理结果。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.2 您理解并同意,我们有权依据合理判断对违反有关法律法规或本协议规定的行为进行处罚,对违法违规的任何用户采取适当的法律行动,并依据法律法规保存有关信息向有关部门报告等,用户应单独承担由此而产生的一切法律责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.3 您理解并同意,因您违反本协议或相关服务条款的规定,导致或产生第三方主张的任何索赔、要求或损失,您应当独立承担责任;我们因此遭受损失的,您也应当一并赔偿。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.4如您违反本协议约定,我们有权作出独立判断,立即暂停或终止向您提供部分或全部本软件服务,包括禁言、屏蔽信息、删除发布内容、封禁账号、注销账号等措施。您应自行承担自身损失(包括但不限于虚拟财产清空、无法正常使用账号及相关本软件服务、无法正常获取您账号内资产或其他权益等),以及相应法律责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.5您承担法律责任的形式包括但不限于:对受到侵害者赔偿损失、赔礼道歉、消除影响、返还财产等。如您的行为给我们造成损失的,您应承担全部赔偿责任,包括行政处罚或损害赔偿款等直接损失以及商誉损失、和解款、律师费、诉讼费等间接损失。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.6您充分了解,任何向我公司的雇员或顾问等提供实物、现金、现金等价物、劳务、旅游等价值明显超出正常商务洽谈范畴的利益,均视为商业贿赂行为。发生前述情形的,我公司可立即终止与您的所有合作并追究您的法律责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.7您因违约导致我们终止本协议时,出于维护软件秩序的目的,我们可根据与您在其他协议项下达成的约定终止与您在其他协议项下的合作。如您违反我们与您在其他合作项下订立的协议,我们亦有权终止本协议。除前述协议终止外,我们亦可关联追究您的违约责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">6.5.8我们可将对您上述违约行为的处置信息,以及其他经国家行政或司法机关生效法律文书确认的违法信息,在本软件上予以公示。对涉嫌违反法律法规的行为,我们有义务保存有关记录,向国家有关机关报告并配合调查。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">七、知识产权声明</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">7.1 笔墨讯使在本服务中提供的内容(包括但不限于网页、文字、图片、音频、视频、图表、文字表述及其组合、界面设计、版面框架、图标、商标等)的知识产权归笔墨讯使所有,受中华人民共和国著作权法、商标法、专利法、反不正当竞争法及国际条约等法律法规的保护。未经我们书面允许,用户不得为任何目的擅自使用、复制、再造这些内容、或创造与内容有关的派生产品。用户在使用本服务中所产生的内容的知识产权归用户或相关权利人所有。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">7.2 除另有特别声明外,笔墨讯使提供本服务时所依据软件的著作权、专利权及其他知识产权均归笔墨讯使所有。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">7.3 笔墨讯使在本服务中所使用的“笔墨讯使”等形象等商业标识,其著作权或商标权归笔墨讯使所有。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">7.4 上述及其他任何本服务包含的内容的知识产权均受到法律保护,未经笔墨讯使、用户或相关权利人书面许可,任何人不得以任何形式进行使用或创作相关衍生作品。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">八、终端安全责任</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">8.1 您理解并同意,本软件同大多数互联网软件一样,可能会受多种因素影响,包括但不限于用户原因、网络服务质量、社会环境等;也可能会受各种安全问题的侵扰,包括但不限于他人非法利用用户资料,进行现实中的骚扰;用户下载安装的其他软件或访问的其他网站中可能含有病毒、木马程序或其他恶意程序,威胁您的终端设备信息和数据安全,继而影响本软件的正常使用等。因此,您应加强信息安全及个人信息的保护意识,注意密码保护,以免遭受损失。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">8.2 您不得制作、发布、使用、传播用于窃取笔墨讯使账号及他人个人信息、财产的恶意程序。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">8.3 维护软件安全与正常使用是我们和您的共同责任,我们将按照行业标准合理审慎地采取必要技术措施保护您的终端设备信息和数据安全,但是您承认和同意我们并不能就此提供完全保证。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">8.4 在任何情况下,您不应轻信借款、索要密码或其他涉及财产的网络信息。涉及财产操作的,请一定先核实对方身份,并请经常留意我们有关防范诈骗犯罪的提示。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>九、第三方软件或技术</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">9.1 本软件可能会使用第三方软件或技术(包括本软件可能使用的开放源代码和公共领域代码等,下同),这种使用已经获得合法授权。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">9.2 本软件如果使用了第三方的软件或技术,我们将按照相关法规或约定,对相关的协议或其他文件,可能通过本协议附件、在本软件安装包特定文件夹中打包、或通过开源软件页面等形式进行展示,它们可能会以“软件使用许可协议”、“授权协议”、“开放源代码许可证”或其他形式来表达。前述通过各种形式展示的相关协议、其他文件及网页,均是本协议不可分割的组成部分,与本协议具有同等的法律效力,您应当遵守这些要求。如果您没有遵守这些要求,该第三方或者国家机关可能会对您提起诉讼、罚款或采取其他制裁措施,并要求我们给予配合,您应当自行承担法律责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">9.3 如因本软件使用的第三方软件或技术引发的任何纠纷,应由该第三方负责解决,我们不承担任何责任。我们不对第三方软件或技术提供客服支持,若您需要获取支持,请与第三方联系。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">APP涉及内嵌第三方代码、插件传输个人信息的情形逐项列举如下:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**Bugly SDK**</span></p>
|
||||||
|
<p class="p1"><span class="s1">主体:深圳市腾讯计算机系统有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">用途:应用崩溃问题捕获</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集的个人信息类型:硬件型号、设备MAC地址、唯一设备识别码(如IMEI/MEID/ ANDROID ID /SN/OPENUDID/GUID、SIM卡IMSI信息在内的描述个人常用设备基本情况的信息)、设备型号、设备制造商、操作系统及其版本;</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:</span></p>
|
||||||
|
<p class="p1"><span class="s1">https://privacy.qq.com/document/preview/fc748b3d96224fdb825ea79e132c1a56</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**OPPO PUSH SDK**</span></p>
|
||||||
|
<p class="p1"><span class="s1">涉及个人信息:设备标识符(如IMEI、OAID、硬件序列号/Serial、IMSI、Android ID、GAID/AAID)、应用信息、网络信息、IP地址、设备信息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用场景:在OPPO手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1">第三方主体:广东欧珀移动通信有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:https://open.oppomobile.com/wiki/doc#id=10194</span></p>
|
||||||
|
<p class="p1"><span class="s1">隐私政策:https://open.oppomobile.com/wiki/doc#id=10288</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**VIVO PUSH SDK**</span></p>
|
||||||
|
<p class="p1"><span class="s1">涉及个人信息:设备信息、IMEI、OAID、GAID/AAID、Android ID、网络信息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用场景:在VIVO手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1">第三方主体:维沃移动通信有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:https://dev.vivo.com.cn/documentCenter/doc/366</span></p>
|
||||||
|
<p class="p1"><span class="s1">隐私政策:https://dev.vivo.com.cn/documentCenter/doc/652</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**华为 PUSH SDK**</span></p>
|
||||||
|
<p class="p1"><span class="s1">涉及个人信息:应用基本信息、应用内设备标识符、设备的硬件信息、软件列表、系统基本信息和系统设置信息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用场景:在华为手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1">第三方主体:华为软件技术有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:https://developer.huawei.com/consumer/cn/doc/app/20213</span></p>
|
||||||
|
<p class="p1"><span class="s1">隐私政策:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**hmscore-base-sdk**</span></p>
|
||||||
|
<p class="p1"><span class="s1">涉及个人信息:应用基本信息、应用内设备标识符、设备的硬件信息、软件列表、系统基本信息和系统设置信息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用场景:在华为手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1">第三方主体:华为软件技术有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:https://developer.huawei.com/consumer/cn/doc/app/20213</span></p>
|
||||||
|
<p class="p1"><span class="s1">隐私政策:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**小米 PUSH SDK**</span></p>
|
||||||
|
<p class="p1"><span class="s1">涉及个人信息:设备标识符(如Android ID、OAID)、应用信息、设备信息、网络信息(本地处理)、SSID</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用场景:在小米手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1">第三方主体:北京小米移动软件有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:https://dev.mi.com/console/appservice/push.html</span></p>
|
||||||
|
<p class="p1"><span class="s1">隐私政策:https://dev.mi.com/console/doc/detail?pId=1822</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**魅族 PUSH SDK**</span></p>
|
||||||
|
<p class="p1"><span class="s1">涉及个人信息:设备标识符(如IMEI、MEID、硬件序列号/Serial)、设备MAC地址、位置信息(如GPS)、WLAN接入点(如SSID、BSSID)、设备信息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用场景:在魅族手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1">第三方主体:珠海市魅族通讯设备有限公司及其关联方(简称魅族)、与魅族建立合作的合作方公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:https://open.flyme.cn/</span></p>
|
||||||
|
<p class="p1"><span class="s1">隐私政策:https://open.flyme.cn/docs?id=202</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">**高德 PUSH SDK**</span></p>
|
||||||
|
<p class="p1"><span class="s1">涉及个人信息:设备标识符(GAID/AAID),应用Token、推送消息内容</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用目的:推送消息</span></p>
|
||||||
|
<p class="p1"><span class="s1">使用场景:在高德手机终端推送消息时使用</span></p>
|
||||||
|
<p class="p1"><span class="s1">第三方主体:高德终端有限公司</span></p>
|
||||||
|
<p class="p1"><span class="s1">收集方式: SDK自行采集</span></p>
|
||||||
|
<p class="p1"><span class="s1">官网链接:https://lbs.amap.com/</span></p>
|
||||||
|
<p class="p1"><span class="s1">隐私政策:https://lbs.amap.com/pages/privacy/</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>十、不可抗力及其他免责事由</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">10.1 您理解并同意,在使用本服务的过程中,可能会遇到不可抗力等风险因素,使本服务发生中断。不可抗力是指不能预见、不能克服并不能避免且对一方或双方造成重大影响的客观事件,包括但不限于自然灾害如水灾、地震、瘟疫流行和风暴等以及社会事件如战争、动乱、政府行为等。出现上述情况时,笔墨讯使将努力在第一时间与相关单位配合,及时进行修复,但由此给您造成的损失笔墨讯使在法律允许的范围内免责。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">10.2 在法律允许的范围内,笔墨讯使对以下情形导致的服务中断或受阻不承担责任:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(1)受到计算机病毒、木马或其他恶意程序、黑客攻击的破坏;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(2)用户或笔墨讯使的电脑软件、系统、硬件和通信线路出现故障;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(3)用户操作不当;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(4)用户通过非笔墨讯使授权的方式使用本服务;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(5)其他笔墨讯使无法控制或合理预见的情形。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">10.3 您理解并同意,在使用本服务的过程中,可能会遇到网络信息或其他用户行为带来的风险,笔墨讯使不对任何信息的真实性、适用性、合法性承担责任,也不对因侵权行为给您造成的损害负责。这些风险包括但不限于:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(1)来自他人匿名或冒名的含有威胁、诽谤、令人反感或非法内容的信息;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(2)因使用本协议项下的服务,遭受他人误导、欺诈或其他导致或可能导致的任何心理、生理上的伤害以及经济上的损失;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(3)其他因网络信息或用户行为引起的风险。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">10.4 您理解并同意,本服务并非为某些特定目的而设计,包括但不限于核设施、军事用途、医疗设施、交通通信等重要领域。如果因为软件或服务的原因导致上述操作失败而带来的人员伤亡、财产损失和环境污染等,笔墨讯使不承担法律责任。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">10.5 笔墨讯使根据本协议约定获得处理违法违规内容的权利,该权利不构成笔墨讯使的义务或承诺,笔墨讯使不能保证及时发现违法行为或进行相应处理。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">10.6 在任何情况下,您不应轻信借款、索要密码或其他涉及财产的网络信息。涉及财产操作的,请一定先核实对方身份,并请经常留意笔墨讯使有关防范诈骗犯罪的提示。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>十一、服务的变更、中断、终止</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">11.1 笔墨讯使可能会对服务内容进行变更,也可能会中断、中止或终止服务。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">11.2 您理解并同意,笔墨讯使有权自主决定经营策略。在笔墨讯使发生合并、分立、收购、资产转让时,笔墨讯使可向第三方转让本服务下相关资产;笔墨讯使也可在单方通知您后,将本协议下部分或全部服务转交由第三方经营或履行。具体受让主体以笔墨讯使通知的为准。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">11.3 如发生下列任何一种情形,笔墨讯使有权不经通知而中断或终止向您提供的服务:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(1)根据法律规定您应提交真实信息,而您提供的个人资料不真实、或与注册时信息不一致又未能提供合理证明;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(2)您违反相关法律法规或本协议的约定;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(3)按照法律规定或主管部门的要求;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(4)出于安全的原因或其他必要的情形。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">11.4 笔墨讯使有权对部分服务进行收费。若您未按时足额付费,笔墨讯使有权中断、中止或终止提供服务。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">11.5 我们始终在不断变更和改进本软件服务,我们会尽最大努力向您提供服务,确保服务的连贯性和安全性。基于此,我们可能会对本软件进行更新,您应将软件更新到最新版本,否则我们不保证您可正常使用本软件。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">11.6 您理解并同意,我公司根据自身商业决策、政府行为、不可抗力等原因可能会选择中止、中断及终止本软件的部分或全部服务。如有此等情形发生,我们会采取合理的方式并以合理的期限提前通知您,除法律法规另有规定外,我们不承担由此对您造成的损失。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">11.7 您有责任自行备份存储在本服务中的数据。如果您的服务被终止,笔墨讯使可以从服务器上永久地删除您的数据,但法律法规另有规定的除外。服务终止后,笔墨讯使没有义务向您返还数据。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">十二、未成年人使用条款</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">12.1 若用户未满18周岁,则为未成年人,应在监护人监护、指导下阅读本协议和使用本服务。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">12.2 未成年人用户涉世未深,容易被网络虚拟迷惑,且好奇心强,遇事缺乏随机应变的处理能力,很容易被别有用心的人利用而又缺乏自我保护能力。因此,未成年人用户在使用本服务时应注意以下事项,提高安全意识,加强自我保护:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(1)认清网络世界与现实世界的区别,避免沉迷于网络,影响日常的学习生活;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(2)填写个人资料时,加强个人保护意识,以免不良分子对个人生活造成骚扰;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(3)在监护人或老师的指导下,学习正确使用网络;</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">(4)避免与陌生网友随意见面或参加联谊活动,以免不法分子有机可乘,危及自身安全。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">12.3 监护人、学校均应对未成年人使用本服务时多做引导。特别是家长应关心子女的成长,注意与子女的沟通,指导子女上网应该注意的安全问题,防患于未然。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">十三、协议变更与终止</span></p>
|
||||||
|
<p class="p1"><span class="s1">13.1协议变更通知</span></p>
|
||||||
|
<p class="p1"><span class="s1">我们有权在必要时修改本协议内容,并将通过合理的方式(包括但不限于本软件公告、系统消息、站内信、手机短信、电子邮件等)及合理的期限提前通知您,该等通知于发送之日视为已送达您。您可以通过软件相关页面查阅最新版本的协议内容。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">13.2变更协议生效</span></p>
|
||||||
|
<p class="p1"><span class="s1">本协议变更生效后,如您继续使用本软件,即视为您已接受修改后的协议。如您不接受修改后的协议,应当停止使用本软件,我们将根据公平原则与您终止协议。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">13.3协议终止</span></p>
|
||||||
|
<p class="p1"><span class="s1">您注销您的账号或我们通知您终止为您提供本软件服务(包括但不限于封禁账号、注销账号等)时,本协议将同时终止,我们将不再另行通知您终止本协议。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">十四、通知</span></p>
|
||||||
|
<p class="p1"><span class="s1">14.1联系方式</span></p>
|
||||||
|
<p class="p1"><span class="s1">14.1.1您在注册成为本软件用户,并接受本软件服务时,您应该向本软件提供真实有效的联系方式(包括您的电子邮件地址、联系电话、联系地址等),对于联系方式发生变更的,您有义务及时更新有关信息,并保持可被联系的状态。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">14.1.2您在注册本软件用户时生成的用于登陆本软件接收站内信、系统消息的账号,也作为您的有效联系方式。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">14.1.3本软件将向您的上述联系方式的其中之一或其中若干向您送达各类通知,而此类通知的内容可能对您的权利义务产生重大的有利或不利影响,请您务必及时关注。</span></p>
|
||||||
|
<p class="p1"><span class="s1">您有权通过您注册时填写的手机号码或者电子邮箱获取您感兴趣的商品广告信息、促销优惠等商业性信息;您如果不愿意接收此类信息,您有权通过本软件提供的相应的退订功能进行退订。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">14.2通知送达</span></p>
|
||||||
|
<p class="p1"><span class="s1">14.2.1本软件通过上述联系方式向您发出通知,其中以电子的方式发出的书面通知,包括但不限于在本软件公告,向您提供的联系电话发送手机短信,向您提供的电子邮件地址发送电子邮件,向您的账号发送信息、系统消息以及站内信信息,在发送成功后即视为送达;以纸质载体发出的书面通知,按照提供联系地址交邮后的第【7】个自然日即视为送达。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">14.2.2对于在本软件上因交易活动引起的任何纠纷,您同意司法机关(包括但不限于人民法院)可以通过手机短信、电子邮件等现代通讯方式或邮寄方式向您送达法律文书(包括但不限于诉讼文书)。您指定接收法律文书的手机号码、电子邮箱或软件账号等联系方式为您在本软件注册、更新时提供的手机号码、电子邮箱联系方式以及在注册本软件用户时生成的账号,司法机关向上述联系方式发出法律文书即视为送达。您指定的邮寄地址为您的法定联系地址或您提供的有效联系地址。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">14.2.3您同意司法机关可采取以上一种或多种送达方式向您送达法律文书,司法机关采取多种方式向您送达法律文书,送达时间以上述送达方式中最先送达的为准。</span></p>
|
||||||
|
<p class="p1"><span class="s1">您同意上述送达方式适用于各个司法程序阶段。如进入诉讼程序的,包括但不限于一审、二审、再审、执行以及督促程序等。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">14.2.4你应当保证所提供的联系方式是准确、有效的,并进行实时更新。如果因提供的联系方式不确切,或不及时告知变更后的联系方式,使法律文书无法送达或未及时送达,由您自行承担由此可能产生的法律后果。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">十五、其他</span></p>
|
||||||
|
<p class="p1"><span class="s1">15.1 您使用本软件即视为您已阅读并同意受本协议的约束。我们有权在必要时修改本协议条款。您可以在本软件的最新版本中查阅相关协议条款。本协议条款变更后,如果您继续使用本软件,即视为您已接受修改后的协议。如果您不接受修改后的协议,应当停止使用本软件。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">15.2 本协议的成立、生效、履行、解释及争议解决,适用中华人民共和国大陆地区法律法规;如法律无相关规定的,参照商业惯例及/或行业惯例。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">15.3 若您和我们之间发生任何纠纷或争议,首先应友好协商解决;协商不成的,您同意将纠纷或争议提交我公司所在地人民法院管辖。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">15.4 本协议所有条款的标题仅为阅读方便,本身并无实际含义,不能作为本协议含义解释的依据。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">15.5 本协议可能存在包括中文、英文在内的多种语言的版本,若存在中文版本与其他语言的版本相冲突的地方,以中文版本为准。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">15.6 本协议条款无论因何种原因部分无效或不可执行,其余条款仍有效,对双方具有约束力。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">15.7 如您对本协议有任何意见或建议,您可通过本平台联系我们,联系方式为【fengqunwangluo2025@163.com】,我们会给予您必要的帮助。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>自启动或关联启动说明</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">推送相关:为确保本应用处于后台或后台运行状态下可正常接收到客户端推送的广播信息,本应用须使用(自启动)能力,将存在一定频率通过系统发送广播唤醒本应用自启动或关联启动行为,是因实现功能及服务所必要的;当您打开内容类推送消息,在征得您的明确同意后,会跳转打开相关内容。在未征得您同意的情况下,则不会有关联启动。</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1"><span class="Apple-converted-space"> </span>读取剪贴板信息:</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">1、用于复制(手机号、id)方便用用户搜索添加好友</span></p>
|
||||||
|
<p class="p2"><span class="s1"></span><br></p>
|
||||||
|
<p class="p1"><span class="s1">2、用于复制(平台联系方式)方便用户提交意见反馈、举报等</span></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
|
"embed"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const legalPageStyle = `
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<style>
|
||||||
|
:root { color-scheme: light; }
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: #f5f6f8;
|
||||||
|
color: #24262b;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
|
||||||
|
"Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
width: min(100%, 800px);
|
||||||
|
min-height: 100vh;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 40px 48px 64px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin: 0 0 32px;
|
||||||
|
color: #17191d;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 1.35;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.legal-content p.p1, .legal-content p.p2 {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.85;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
-webkit-text-stroke: 0;
|
||||||
|
}
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
main { padding: 28px 20px 48px; }
|
||||||
|
h1 { margin-bottom: 24px; font-size: 22px; }
|
||||||
|
.legal-content p.p1, .legal-content p.p2 { font-size: 15px; line-height: 1.8; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
`
|
||||||
|
|
||||||
|
//go:embed legal/*.html
|
||||||
|
var legalDocumentFiles embed.FS
|
||||||
|
|
||||||
|
type legalDocument struct {
|
||||||
|
body []byte
|
||||||
|
etag string
|
||||||
|
}
|
||||||
|
|
||||||
|
var legalDocuments = map[string]legalDocument{
|
||||||
|
"/legal/user-terms": loadLegalDocument("legal/user-terms.html", "笔墨讯使软件服务协议"),
|
||||||
|
"/legal/privacy-policy": loadLegalDocument("legal/privacy-policy.html", "笔墨讯使隐私政策"),
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadLegalDocument(name, title string) legalDocument {
|
||||||
|
body, err := legalDocumentFiles.ReadFile(name)
|
||||||
|
if err != nil {
|
||||||
|
panic("load legal document: " + err.Error())
|
||||||
|
}
|
||||||
|
body = bytes.Replace(body,
|
||||||
|
[]byte("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">"),
|
||||||
|
[]byte("<!doctype html>"), 1)
|
||||||
|
body = bytes.Replace(body, []byte("<title></title>"), []byte("<title>"+title+"</title>"), 1)
|
||||||
|
body = bytes.Replace(body, []byte("</head>"), []byte(legalPageStyle+"</head>"), 1)
|
||||||
|
body = bytes.Replace(body, []byte("<body>"),
|
||||||
|
[]byte("<body><main><h1>"+title+"</h1><div class=\"legal-content\">"), 1)
|
||||||
|
body = bytes.Replace(body, []byte("</body>"), []byte("</div></main></body>"), 1)
|
||||||
|
digest := sha256.Sum256(body)
|
||||||
|
return legalDocument{body: body, etag: fmt.Sprintf("\"%x\"", digest[:16])}
|
||||||
|
}
|
||||||
|
|
||||||
|
func serveLegalDocument(wrt http.ResponseWriter, req *http.Request) {
|
||||||
|
if req.Method != http.MethodGet && req.Method != http.MethodHead {
|
||||||
|
wrt.Header().Set("Allow", "GET, HEAD")
|
||||||
|
http.Error(wrt, "method not allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
document, ok := legalDocuments[req.URL.Path]
|
||||||
|
if !ok {
|
||||||
|
http.NotFound(wrt, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wrt.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
wrt.Header().Set("Cache-Control", "public, max-age=300, must-revalidate")
|
||||||
|
wrt.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; img-src data:; base-uri 'none'; form-action 'none'")
|
||||||
|
wrt.Header().Set("Referrer-Policy", "no-referrer")
|
||||||
|
wrt.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
|
wrt.Header().Set("ETag", document.etag)
|
||||||
|
if req.Header.Get("If-None-Match") == document.etag {
|
||||||
|
wrt.WriteHeader(http.StatusNotModified)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.Method == http.MethodHead {
|
||||||
|
wrt.Header().Set("Content-Length", fmt.Sprintf("%d", len(document.body)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, _ = wrt.Write(document.body)
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServeLegalDocument(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
path string
|
||||||
|
title string
|
||||||
|
}{
|
||||||
|
{path: "/legal/user-terms", title: "笔墨讯使软件服务协议"},
|
||||||
|
{path: "/legal/privacy-policy", title: "笔墨讯使隐私政策"},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
t.Run(tc.path, func(t *testing.T) {
|
||||||
|
req := httptest.NewRequest(http.MethodGet, tc.path, nil)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
serveLegalDocument(rec, req)
|
||||||
|
if rec.Code != http.StatusOK {
|
||||||
|
t.Fatalf("status: got %d body=%s", rec.Code, rec.Body.String())
|
||||||
|
}
|
||||||
|
if got := rec.Header().Get("Content-Type"); got != "text/html; charset=utf-8" {
|
||||||
|
t.Fatalf("content type: got %q", got)
|
||||||
|
}
|
||||||
|
if rec.Header().Get("ETag") == "" {
|
||||||
|
t.Fatal("missing ETag")
|
||||||
|
}
|
||||||
|
if !strings.Contains(rec.Body.String(), "<title>"+tc.title+"</title>") ||
|
||||||
|
!strings.Contains(rec.Body.String(), "<meta name=\"viewport\"") {
|
||||||
|
t.Fatal("legal page is missing title or mobile viewport")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServeLegalDocumentConditionalHead(t *testing.T) {
|
||||||
|
getReq := httptest.NewRequest(http.MethodGet, "/legal/user-terms", nil)
|
||||||
|
getRec := httptest.NewRecorder()
|
||||||
|
serveLegalDocument(getRec, getReq)
|
||||||
|
|
||||||
|
headReq := httptest.NewRequest(http.MethodHead, "/legal/user-terms", nil)
|
||||||
|
headReq.Header.Set("If-None-Match", getRec.Header().Get("ETag"))
|
||||||
|
headRec := httptest.NewRecorder()
|
||||||
|
serveLegalDocument(headRec, headReq)
|
||||||
|
if headRec.Code != http.StatusNotModified || headRec.Body.Len() != 0 {
|
||||||
|
t.Fatalf("conditional HEAD: status=%d body=%q", headRec.Code, headRec.Body.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLegalDocumentDoesNotRequireAPIKey(t *testing.T) {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/legal/user-terms", serveLegalDocument)
|
||||||
|
handler := withIMHTTPProtocol("/v1/im/", mux)
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/legal/user-terms", nil)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
handler.ServeHTTP(rec, req)
|
||||||
|
if rec.Code != http.StatusOK {
|
||||||
|
t.Fatalf("public legal page was blocked: status=%d body=%s", rec.Code, rec.Body.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-1
@@ -71,7 +71,7 @@ const (
|
|||||||
minSupportedVersion = "0.20"
|
minSupportedVersion = "0.20"
|
||||||
|
|
||||||
// idleSessionTimeout defines duration of being idle before terminating a session.
|
// idleSessionTimeout defines duration of being idle before terminating a session.
|
||||||
idleSessionTimeout = time.Second * 55
|
idleSessionTimeout = time.Second * 45
|
||||||
// idleMasterTopicTimeout defines now long to keep master topic alive after the last session detached.
|
// idleMasterTopicTimeout defines now long to keep master topic alive after the last session detached.
|
||||||
idleMasterTopicTimeout = time.Second * 4
|
idleMasterTopicTimeout = time.Second * 4
|
||||||
// Same as above but shut down the proxy topic sooner. Otherwise master topic would be kept alive for too long.
|
// Same as above but shut down the proxy topic sooner. Otherwise master topic would be kept alive for too long.
|
||||||
@@ -850,6 +850,10 @@ func main() {
|
|||||||
mux.HandleFunc("/healthz", serveHealthz)
|
mux.HandleFunc("/healthz", serveHealthz)
|
||||||
mux.HandleFunc("/metrics", serveMetrics)
|
mux.HandleFunc("/metrics", serveMetrics)
|
||||||
|
|
||||||
|
// Public legal pages are opened directly by clients before login.
|
||||||
|
mux.HandleFunc("/legal/user-terms", serveLegalDocument)
|
||||||
|
mux.HandleFunc("/legal/privacy-policy", serveLegalDocument)
|
||||||
|
|
||||||
// Handle websocket clients.
|
// Handle websocket clients.
|
||||||
mux.HandleFunc(config.ApiPath+"v0/channels", serveWebSocket)
|
mux.HandleFunc(config.ApiPath+"v0/channels", serveWebSocket)
|
||||||
// Product HTTP API.
|
// Product HTTP API.
|
||||||
@@ -861,6 +865,7 @@ func main() {
|
|||||||
mux.HandleFunc(config.ApiPath+"v1/im/auth/verification-codes/", serveIMVerificationCodeVerify)
|
mux.HandleFunc(config.ApiPath+"v1/im/auth/verification-codes/", serveIMVerificationCodeVerify)
|
||||||
mux.HandleFunc(config.ApiPath+"v1/im/auth/password-reset/challenges/", serveIMPasswordResetVerify)
|
mux.HandleFunc(config.ApiPath+"v1/im/auth/password-reset/challenges/", serveIMPasswordResetVerify)
|
||||||
mux.HandleFunc(config.ApiPath+"v1/im/auth/password-reset/confirm", serveIMPasswordResetConfirm)
|
mux.HandleFunc(config.ApiPath+"v1/im/auth/password-reset/confirm", serveIMPasswordResetConfirm)
|
||||||
|
mux.HandleFunc(config.ApiPath+"v1/im/auth/logout", serveIMAuthLogout)
|
||||||
mux.HandleFunc(config.ApiPath+"v1/im/security/urls/check", serveIMSecurityURLCheck)
|
mux.HandleFunc(config.ApiPath+"v1/im/security/urls/check", serveIMSecurityURLCheck)
|
||||||
mux.HandleFunc(config.ApiPath+"v1/im/security/risk-challenges/", serveIMRiskChallengeConfirm)
|
mux.HandleFunc(config.ApiPath+"v1/im/security/risk-challenges/", serveIMRiskChallengeConfirm)
|
||||||
mux.HandleFunc(config.ApiPath+"v1/im/security/challenges", serveIMSecurityChallenges)
|
mux.HandleFunc(config.ApiPath+"v1/im/security/challenges", serveIMSecurityChallenges)
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ func (oh *ossHandler) Headers(tenantID types.TenantID, method string, url *url.U
|
|||||||
"ETag": {`"` + fdef.ETag + `"`},
|
"ETag": {`"` + fdef.ETag + `"`},
|
||||||
"Content-Type": {"application/json; charset=utf-8"},
|
"Content-Type": {"application/json; charset=utf-8"},
|
||||||
"Cache-Control": {oh.conf.CacheControl},
|
"Cache-Control": {oh.conf.CacheControl},
|
||||||
}, http.StatusPermanentRedirect, nil
|
}, http.StatusFound, nil
|
||||||
}
|
}
|
||||||
return nil, 0, nil
|
return nil, 0, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,16 +248,14 @@ func (ah *awshandler) Headers(tenantID types.TenantID, method string, url *url.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
if redirURL != "" {
|
if redirURL != "" {
|
||||||
// Return presigned URL with 308 Permanent redirect. Let the client cache the response.
|
// Return a temporary redirect to a short-lived presigned URL.
|
||||||
// The original URL will stop working after a short period of time to prevent use of Tinode
|
|
||||||
// as a free file server.
|
|
||||||
return http.Header{
|
return http.Header{
|
||||||
"Location": {redirURL},
|
"Location": {redirURL},
|
||||||
"ETag": {`"` + fdef.ETag + `"`},
|
"ETag": {`"` + fdef.ETag + `"`},
|
||||||
"Content-Type": {"application/json; charset=utf-8"},
|
"Content-Type": {"application/json; charset=utf-8"},
|
||||||
"Cache-Control": {ah.conf.CacheControl},
|
"Cache-Control": {ah.conf.CacheControl},
|
||||||
},
|
},
|
||||||
http.StatusPermanentRedirect, nil
|
http.StatusFound, nil
|
||||||
}
|
}
|
||||||
return nil, 0, nil
|
return nil, 0, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-15
@@ -50,15 +50,8 @@ func (t *Topic) addToPerSubs(topic string, online, enabled bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: maybe skip loading channel subscriptions. They can's send or receive these notifications anyway.
|
// TODO: maybe skip loading channel subscriptions. They can's send or receive these notifications anyway.
|
||||||
|
// Keep the canonical P2P topic as the key. usr... is accepted only as a
|
||||||
if uid1, uid2, err := types.ParseP2P(topic); err == nil {
|
// client input alias, while downlink frames should consistently use p2p....
|
||||||
// If this is a P2P topic, index it by second user's ID
|
|
||||||
if uid1.UserId() == t.name {
|
|
||||||
topic = uid2.UserId()
|
|
||||||
} else {
|
|
||||||
topic = uid1.UserId()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.perSubs[topic] = perSubsData{online: online, enabled: enabled}
|
t.perSubs[topic] = perSubsData{online: online, enabled: enabled}
|
||||||
}
|
}
|
||||||
@@ -544,7 +537,6 @@ func (t *Topic) infoCallSubsOffline(from string, target types.Uid, event string,
|
|||||||
func presSubsOfflineOffline(tenantID types.TenantID, topic string, cat types.TopicCat, subs []types.Subscription, what string,
|
func presSubsOfflineOffline(tenantID types.TenantID, topic string, cat types.TopicCat, subs []types.Subscription, what string,
|
||||||
params *presParams, skipSid string) {
|
params *presParams, skipSid string) {
|
||||||
|
|
||||||
count := 0
|
|
||||||
original := topic
|
original := topic
|
||||||
for i := range subs {
|
for i := range subs {
|
||||||
sub := &subs[i]
|
sub := &subs[i]
|
||||||
@@ -554,11 +546,6 @@ func presSubsOfflineOffline(tenantID types.TenantID, topic string, cat types.Top
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if cat == types.TopicCatP2P {
|
|
||||||
original = types.ParseUid(subs[(count+1)%2].User).UserId()
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
|
|
||||||
user := types.ParseUid(sub.User).UserId()
|
user := types.ParseUid(sub.User).UserId()
|
||||||
actor := params.actor
|
actor := params.actor
|
||||||
target := params.target
|
target := params.target
|
||||||
|
|||||||
+6
-6
@@ -87,11 +87,11 @@ func (t *Topic) pushForData(fromUid types.Uid, data *MsgServerData, msgMarkedAsR
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Topic) preparePushForSubReceipt(fromUid types.Uid, now time.Time) *push.Receipt {
|
func (t *Topic) preparePushForSubReceipt(fromUid types.Uid, now time.Time) *push.Receipt {
|
||||||
// The `Topic` in the push receipt is `t.xoriginal` for group topics, `fromUid` for p2p topics,
|
// P2P push payloads use the canonical p2p... topic. usr... is accepted only
|
||||||
// not the t.original(fromUid) because it's the topic name as seen by the recipient, not by the sender.
|
// as an input alias.
|
||||||
topic := t.xoriginal
|
topic := t.xoriginal
|
||||||
if t.cat == types.TopicCatP2P {
|
if t.cat == types.TopicCatP2P {
|
||||||
topic = fromUid.UserId()
|
topic = t.name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the push receipt.
|
// Initialize the push receipt.
|
||||||
@@ -165,11 +165,11 @@ func pushForChanDelete(tenantID types.TenantID, topicName string, now time.Time)
|
|||||||
|
|
||||||
// Prepares payload to be delivered to a mobile device as a push notification in response to receiving "read" notification.
|
// Prepares payload to be delivered to a mobile device as a push notification in response to receiving "read" notification.
|
||||||
func (t *Topic) pushForReadRcpt(uid types.Uid, seq int64, now time.Time) *push.Receipt {
|
func (t *Topic) pushForReadRcpt(uid types.Uid, seq int64, now time.Time) *push.Receipt {
|
||||||
// The `Topic` in the push receipt is `t.xoriginal` for group topics, `fromUid` for p2p topics,
|
// P2P push payloads use the canonical p2p... topic. usr... is accepted only
|
||||||
// not the t.original(fromUid) because it's the topic name as seen by the recipient, not by the sender.
|
// as an input alias.
|
||||||
topic := t.xoriginal
|
topic := t.xoriginal
|
||||||
if t.cat == types.TopicCatP2P {
|
if t.cat == types.TopicCatP2P {
|
||||||
topic = uid.UserId()
|
topic = t.name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the push receipt.
|
// Initialize the push receipt.
|
||||||
|
|||||||
@@ -143,19 +143,11 @@ func PrepareV1Notifications(rcpt *push.Receipt, config *configType) ([]*fcmv1.Me
|
|||||||
for uid, devList := range devices {
|
for uid, devList := range devices {
|
||||||
topic := rcpt.Payload.Topic
|
topic := rcpt.Payload.Topic
|
||||||
userData := data
|
userData := data
|
||||||
tcat := t.GetTopicCat(topic)
|
|
||||||
if rcpt.To[uid].Delivered > 0 || tcat == t.TopicCatP2P {
|
|
||||||
userData = clonePayload(data)
|
|
||||||
// Fix topic name for P2P pushes.
|
|
||||||
if tcat == t.TopicCatP2P {
|
|
||||||
topic, _ = t.P2PNameForUser(uid, topic)
|
|
||||||
userData["topic"] = topic
|
|
||||||
}
|
|
||||||
// Silence the push for user who have received the data interactively.
|
|
||||||
if rcpt.To[uid].Delivered > 0 {
|
if rcpt.To[uid].Delivered > 0 {
|
||||||
|
userData = clonePayload(data)
|
||||||
|
// Silence the push for user who have received the data interactively.
|
||||||
userData["silent"] = "true"
|
userData["silent"] = "true"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for i := range devList {
|
for i := range devList {
|
||||||
d := &devList[i]
|
d := &devList[i]
|
||||||
|
|||||||
@@ -352,15 +352,9 @@ func preparePayloads(rcpt *push.Receipt, config *configType) ([]*jpushPayload, [
|
|||||||
}
|
}
|
||||||
userData := cloneData(data)
|
userData := cloneData(data)
|
||||||
topic := rcpt.Payload.Topic
|
topic := rcpt.Payload.Topic
|
||||||
if t.GetTopicCat(topic) == t.TopicCatP2P {
|
|
||||||
if alias, err := t.P2PNameForUser(uid, topic); err == nil {
|
|
||||||
topic = alias
|
|
||||||
userData["topic"] = alias
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var audience map[string][]string
|
var audience map[string][]string
|
||||||
if useAlias {
|
if useAlias {
|
||||||
audience = map[string][]string{"alias": {uid.UserId()}}
|
audience = map[string][]string{"alias": {aliasForUid(uid)}}
|
||||||
} else {
|
} else {
|
||||||
var registrationIDs []string
|
var registrationIDs []string
|
||||||
for _, device := range devices[uid] {
|
for _, device := range devices[uid] {
|
||||||
@@ -457,7 +451,6 @@ func buildPayload(audience map[string][]string, topic string, data map[string]st
|
|||||||
APNsProduction: config.APNsProduction,
|
APNsProduction: config.APNsProduction,
|
||||||
Classification: config.Classification,
|
Classification: config.Classification,
|
||||||
},
|
},
|
||||||
CID: cidFor(topic, data),
|
|
||||||
}
|
}
|
||||||
if data["silent"] == "true" || data["type"] == "read" {
|
if data["silent"] == "true" || data["type"] == "read" {
|
||||||
payload.Message = &jpushMessage{MsgContent: alert, Title: title, Extras: data}
|
payload.Message = &jpushMessage{MsgContent: alert, Title: title, Extras: data}
|
||||||
@@ -584,6 +577,12 @@ func containsString(values []string, target string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func aliasForUid(uid t.Uid) string {
|
||||||
|
// JPush alias does not accept '-' or '_'. Tinode user IDs are base64url-like,
|
||||||
|
// so map them to legal characters which never appear in the original alphabet.
|
||||||
|
return strings.NewReplacer("-", ".", "_", "|").Replace(uid.UserId())
|
||||||
|
}
|
||||||
|
|
||||||
func providerDevicesForUsers(tenantID t.TenantID, provider string, uids ...t.Uid) (map[t.Uid][]t.DeviceDef, int, error) {
|
func providerDevicesForUsers(tenantID t.TenantID, provider string, uids ...t.Uid) (map[t.Uid][]t.DeviceDef, int, error) {
|
||||||
if tokens, ok := store.DevicePushTokens.(store.DevicePushTokenProviderQueryInterface); ok {
|
if tokens, ok := store.DevicePushTokens.(store.DevicePushTokenProviderQueryInterface); ok {
|
||||||
return tokens.GetAllByProvider(tenantID, provider, uids...)
|
return tokens.GetAllByProvider(tenantID, provider, uids...)
|
||||||
|
|||||||
@@ -97,18 +97,27 @@ func TestPreparePayloadsUsesAliasAndNormalizesP2PTopic(t *testing.T) {
|
|||||||
t.Fatalf("unexpected payload count: %d %#v", len(payloads), uids)
|
t.Fatalf("unexpected payload count: %d %#v", len(payloads), uids)
|
||||||
}
|
}
|
||||||
payload := payloads[0]
|
payload := payloads[0]
|
||||||
if got := payload.Audience["alias"][0]; got != callee.UserId() {
|
if got := payload.Audience["alias"][0]; got != aliasForUid(callee) {
|
||||||
t.Fatalf("unexpected alias: %s", got)
|
t.Fatalf("unexpected alias: %s", got)
|
||||||
}
|
}
|
||||||
userTopic, _ := types.P2PNameForUser(callee, topic)
|
if got := payload.Notification.Android.Extras["topic"]; got != topic {
|
||||||
if got := payload.Notification.Android.Extras["topic"]; got != userTopic {
|
t.Fatalf("topic was not kept canonical for callee: got %s want %s", got, topic)
|
||||||
t.Fatalf("topic was not normalized for callee: got %s want %s", got, userTopic)
|
|
||||||
}
|
}
|
||||||
if payload.Notification.IOS.Badge != "3" {
|
if payload.Notification.IOS.Badge != "3" {
|
||||||
t.Fatalf("unexpected badge: %s", payload.Notification.IOS.Badge)
|
t.Fatalf("unexpected badge: %s", payload.Notification.IOS.Badge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAliasForUidUsesJPushSafeCharacters(t *testing.T) {
|
||||||
|
uid := types.ParseUserId("usrd6Ag5opa-ww")
|
||||||
|
if uid.IsZero() {
|
||||||
|
t.Fatal("test user id did not parse")
|
||||||
|
}
|
||||||
|
if got, want := aliasForUid(uid), "usrd6Ag5opa.ww"; got != want {
|
||||||
|
t.Fatalf("unexpected alias: got %s want %s", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPreparePayloadsCanUseRegistrationID(t *testing.T) {
|
func TestPreparePayloadsCanUseRegistrationID(t *testing.T) {
|
||||||
oldTokens := store.DevicePushTokens
|
oldTokens := store.DevicePushTokens
|
||||||
uid := types.Uid(42)
|
uid := types.Uid(42)
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ var (
|
|||||||
tenantByIDCache = newConfigCache[*types.Tenant]()
|
tenantByIDCache = newConfigCache[*types.Tenant]()
|
||||||
registrationSMSCache = newConfigCache[bool]()
|
registrationSMSCache = newConfigCache[bool]()
|
||||||
thirdPartyConfigCache = newConfigCache[map[string]string]()
|
thirdPartyConfigCache = newConfigCache[map[string]string]()
|
||||||
|
appReleaseConfigCache = newConfigCache[*types.AppRelease]()
|
||||||
thirdPartyConfigAllKeys = "*"
|
thirdPartyConfigAllKeys = "*"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -71,6 +72,11 @@ func cloneTenant(t *types.Tenant) *types.Tenant {
|
|||||||
return &cp
|
return &cp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvalidateAppReleaseConfigCache clears global client release policies.
|
||||||
|
func InvalidateAppReleaseConfigCache() {
|
||||||
|
appReleaseConfigCache.clear()
|
||||||
|
}
|
||||||
|
|
||||||
func cloneStringMap(src map[string]string) map[string]string {
|
func cloneStringMap(src map[string]string) map[string]string {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package store
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -53,6 +55,7 @@ type groupMessageRuntime interface {
|
|||||||
Close() error
|
Close() error
|
||||||
Claim(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) (*groupMessageUniqueRecord, bool, error)
|
Claim(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) (*groupMessageUniqueRecord, bool, error)
|
||||||
NextSeq(tenantID types.TenantID, topic string, baseline int64) (int64, error)
|
NextSeq(tenantID types.TenantID, topic string, baseline int64) (int64, error)
|
||||||
|
MarkPending(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string, seq int64) error
|
||||||
MarkDone(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string, seq int64, msgID string) error
|
MarkDone(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string, seq int64, msgID string) error
|
||||||
MarkFailed(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) error
|
MarkFailed(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) error
|
||||||
CacheHotMessage(tenantID types.TenantID, msg *types.Message) error
|
CacheHotMessage(tenantID types.TenantID, msg *types.Message) error
|
||||||
@@ -78,6 +81,7 @@ type groupMessageRuntime interface {
|
|||||||
AllowRate(tenantID types.TenantID, scope string, limit int, window time.Duration) (bool, int, time.Duration, error)
|
AllowRate(tenantID types.TenantID, scope string, limit int, window time.Duration) (bool, int, time.Duration, error)
|
||||||
ClaimShortState(namespace, id string, ttl time.Duration) (bool, error)
|
ClaimShortState(namespace, id string, ttl time.Duration) (bool, error)
|
||||||
ClaimShortStateValue(namespace, id, value string, ttl time.Duration) (bool, bool, error)
|
ClaimShortStateValue(namespace, id, value string, ttl time.Duration) (bool, bool, error)
|
||||||
|
ShortStateExists(namespace, id string) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var groupMsgRuntime groupMessageRuntime
|
var groupMsgRuntime groupMessageRuntime
|
||||||
@@ -108,6 +112,13 @@ func MarkMessageUniqueDone(tenantID types.TenantID, topic string, from types.Uid
|
|||||||
return groupMsgRuntime.MarkDone(tenantID, topic, from, clientMsgID, seq, msgID)
|
return groupMsgRuntime.MarkDone(tenantID, topic, from, clientMsgID, seq, msgID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MarkMessageUniquePending(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string, seq int64) error {
|
||||||
|
if groupMsgRuntime == nil || !tenantID.IsValid() || topic == "" || from.IsZero() || clientMsgID == "" || seq <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return groupMsgRuntime.MarkPending(tenantID, topic, from, clientMsgID, seq)
|
||||||
|
}
|
||||||
|
|
||||||
func MarkMessageUniqueFailed(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) error {
|
func MarkMessageUniqueFailed(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) error {
|
||||||
if groupMsgRuntime == nil || !tenantID.IsValid() || topic == "" || from.IsZero() || clientMsgID == "" {
|
if groupMsgRuntime == nil || !tenantID.IsValid() || topic == "" || from.IsZero() || clientMsgID == "" {
|
||||||
return nil
|
return nil
|
||||||
@@ -146,6 +157,26 @@ func ClaimShortStateValue(namespace, id, value string, ttl time.Duration) (bool,
|
|||||||
return claimed, sameValue, true, err
|
return claimed, sameValue, true, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RevokeLoginToken(tenantID types.TenantID, token []byte, ttl time.Duration) (bool, error) {
|
||||||
|
if groupMsgRuntime == nil || !tenantID.IsValid() || len(token) == 0 || ttl <= 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
digest := sha256.Sum256(token)
|
||||||
|
id := strconv.FormatInt(int64(tenantID), 10) + ":" + hex.EncodeToString(digest[:])
|
||||||
|
_, err := groupMsgRuntime.ClaimShortState("revoked_login_token", id, ttl)
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsLoginTokenRevoked(tenantID types.TenantID, token []byte) (bool, bool, error) {
|
||||||
|
if groupMsgRuntime == nil || !tenantID.IsValid() || len(token) == 0 {
|
||||||
|
return false, false, nil
|
||||||
|
}
|
||||||
|
digest := sha256.Sum256(token)
|
||||||
|
id := strconv.FormatInt(int64(tenantID), 10) + ":" + hex.EncodeToString(digest[:])
|
||||||
|
revoked, err := groupMsgRuntime.ShortStateExists("revoked_login_token", id)
|
||||||
|
return revoked, true, err
|
||||||
|
}
|
||||||
|
|
||||||
func RefreshUserPresence(tenantID types.TenantID, uid types.Uid, sid, nodeID string) error {
|
func RefreshUserPresence(tenantID types.TenantID, uid types.Uid, sid, nodeID string) error {
|
||||||
if groupMsgRuntime == nil || !tenantID.IsValid() || uid.IsZero() || sid == "" {
|
if groupMsgRuntime == nil || !tenantID.IsValid() || uid.IsZero() || sid == "" {
|
||||||
return nil
|
return nil
|
||||||
@@ -441,6 +472,15 @@ func (r *redisGroupMessageRuntime) MarkDone(tenantID types.TenantID, topic strin
|
|||||||
return r.client.Set(context.Background(), r.uniqueKey(tenantID, topic, from, clientMsgID), raw, time.Duration(r.cfg.DoneTTL)*time.Second).Err()
|
return r.client.Set(context.Background(), r.uniqueKey(tenantID, topic, from, clientMsgID), raw, time.Duration(r.cfg.DoneTTL)*time.Second).Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *redisGroupMessageRuntime) MarkPending(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string, seq int64) error {
|
||||||
|
if clientMsgID == "" || seq <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
rec := &groupMessageUniqueRecord{Status: "pending", Seq: seq, CreatedAt: time.Now().UTC()}
|
||||||
|
raw, _ := json.Marshal(rec)
|
||||||
|
return r.client.Set(context.Background(), r.uniqueKey(tenantID, topic, from, clientMsgID), raw, time.Duration(r.cfg.PendingTTL)*time.Second).Err()
|
||||||
|
}
|
||||||
|
|
||||||
func (r *redisGroupMessageRuntime) MarkFailed(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) error {
|
func (r *redisGroupMessageRuntime) MarkFailed(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) error {
|
||||||
if clientMsgID == "" {
|
if clientMsgID == "" {
|
||||||
return nil
|
return nil
|
||||||
@@ -881,6 +921,11 @@ func (r *redisGroupMessageRuntime) ClaimShortStateValue(namespace, id, value str
|
|||||||
return false, existing == value, nil
|
return false, existing == value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *redisGroupMessageRuntime) ShortStateExists(namespace, id string) (bool, error) {
|
||||||
|
count, err := r.client.Exists(context.Background(), r.shortStateKey(namespace, id)).Result()
|
||||||
|
return count > 0, err
|
||||||
|
}
|
||||||
|
|
||||||
func (r *redisGroupMessageRuntime) hotSeqIDs(tenantID types.TenantID, topic string, opts *types.QueryOpt, limit int) ([]int64, bool, error) {
|
func (r *redisGroupMessageRuntime) hotSeqIDs(tenantID types.TenantID, topic string, opts *types.QueryOpt, limit int) ([]int64, bool, error) {
|
||||||
if opts != nil && len(opts.IdRanges) > 0 {
|
if opts != nil && len(opts.IdRanges) > 0 {
|
||||||
seqs := expandRanges(opts.IdRanges, limit)
|
seqs := expandRanges(opts.IdRanges, limit)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
type testGroupMessageRuntime struct {
|
type testGroupMessageRuntime struct {
|
||||||
claims map[string]*groupMessageUniqueRecord
|
claims map[string]*groupMessageUniqueRecord
|
||||||
seqs map[string]int64
|
seqs map[string]int64
|
||||||
|
shortStates map[string]bool
|
||||||
deletedPrefixes []string
|
deletedPrefixes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ func newTestGroupMessageRuntime() *testGroupMessageRuntime {
|
|||||||
return &testGroupMessageRuntime{
|
return &testGroupMessageRuntime{
|
||||||
claims: make(map[string]*groupMessageUniqueRecord),
|
claims: make(map[string]*groupMessageUniqueRecord),
|
||||||
seqs: make(map[string]int64),
|
seqs: make(map[string]int64),
|
||||||
|
shortStates: make(map[string]bool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +49,12 @@ func (r *testGroupMessageRuntime) MarkDone(_ types.TenantID, topic string, from
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *testGroupMessageRuntime) MarkPending(_ types.TenantID, topic string, from types.Uid, clientMsgID string, seq int64) error {
|
||||||
|
key := topic + ":" + from.UserId() + ":" + clientMsgID
|
||||||
|
r.claims[key] = &groupMessageUniqueRecord{Status: "pending", Seq: seq, CreatedAt: time.Now().UTC()}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *testGroupMessageRuntime) MarkFailed(_ types.TenantID, topic string, from types.Uid, clientMsgID string) error {
|
func (r *testGroupMessageRuntime) MarkFailed(_ types.TenantID, topic string, from types.Uid, clientMsgID string) error {
|
||||||
key := topic + ":" + from.UserId() + ":" + clientMsgID
|
key := topic + ":" + from.UserId() + ":" + clientMsgID
|
||||||
r.claims[key] = &groupMessageUniqueRecord{Status: "failed", CreatedAt: time.Now().UTC()}
|
r.claims[key] = &groupMessageUniqueRecord{Status: "failed", CreatedAt: time.Now().UTC()}
|
||||||
@@ -138,7 +146,12 @@ func (r *testGroupMessageRuntime) AllowRate(types.TenantID, string, int, time.Du
|
|||||||
return true, 0, 0, nil
|
return true, 0, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *testGroupMessageRuntime) ClaimShortState(string, string, time.Duration) (bool, error) {
|
func (r *testGroupMessageRuntime) ClaimShortState(namespace, id string, _ time.Duration) (bool, error) {
|
||||||
|
key := namespace + ":" + id
|
||||||
|
if r.shortStates[key] {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
r.shortStates[key] = true
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +159,30 @@ func (r *testGroupMessageRuntime) ClaimShortStateValue(string, string, string, t
|
|||||||
return true, true, nil
|
return true, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *testGroupMessageRuntime) ShortStateExists(namespace, id string) (bool, error) {
|
||||||
|
return r.shortStates[namespace+":"+id], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoginTokenRevocation(t *testing.T) {
|
||||||
|
oldRuntime := groupMsgRuntime
|
||||||
|
groupMsgRuntime = newTestGroupMessageRuntime()
|
||||||
|
t.Cleanup(func() { groupMsgRuntime = oldRuntime })
|
||||||
|
|
||||||
|
token := []byte("current-device-token")
|
||||||
|
if revoked, enabled, err := IsLoginTokenRevoked(7, token); err != nil || !enabled || revoked {
|
||||||
|
t.Fatalf("unexpected initial state: revoked=%v enabled=%v err=%v", revoked, enabled, err)
|
||||||
|
}
|
||||||
|
if enabled, err := RevokeLoginToken(7, token, time.Hour); err != nil || !enabled {
|
||||||
|
t.Fatalf("revoke token: enabled=%v err=%v", enabled, err)
|
||||||
|
}
|
||||||
|
if revoked, enabled, err := IsLoginTokenRevoked(7, token); err != nil || !enabled || !revoked {
|
||||||
|
t.Fatalf("revoked token was accepted: revoked=%v enabled=%v err=%v", revoked, enabled, err)
|
||||||
|
}
|
||||||
|
if revoked, _, err := IsLoginTokenRevoked(7, []byte("other-device-token")); err != nil || revoked {
|
||||||
|
t.Fatalf("other device token was revoked: revoked=%v err=%v", revoked, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMessageRuntimeSeqAndClientMidIdempotency(t *testing.T) {
|
func TestMessageRuntimeSeqAndClientMidIdempotency(t *testing.T) {
|
||||||
oldRuntime := groupMsgRuntime
|
oldRuntime := groupMsgRuntime
|
||||||
runtime := newTestGroupMessageRuntime()
|
runtime := newTestGroupMessageRuntime()
|
||||||
|
|||||||
+40
-5
@@ -169,6 +169,7 @@ type AdminInternalConfigProvider interface {
|
|||||||
ListActiveTenants(limit int) ([]types.Tenant, error)
|
ListActiveTenants(limit int) ([]types.Tenant, error)
|
||||||
RegistrationSMSEnabled() (bool, error)
|
RegistrationSMSEnabled() (bool, error)
|
||||||
ThirdPartyConfig(group string, keys ...string) (map[string]string, error)
|
ThirdPartyConfig(group string, keys ...string) (map[string]string, error)
|
||||||
|
LatestAppRelease(platform, channel string) (*types.AppRelease, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var adminInternalConfigProvider AdminInternalConfigProvider
|
var adminInternalConfigProvider AdminInternalConfigProvider
|
||||||
@@ -1629,6 +1630,7 @@ type GroupBusinessPersistenceInterface interface {
|
|||||||
ListJoinRequests(types.TenantID, string, string, string, int) ([]types.GroupJoinRequest, string, error)
|
ListJoinRequests(types.TenantID, string, string, string, int) ([]types.GroupJoinRequest, string, error)
|
||||||
ResolveJoinRequest(types.TenantID, string, string, types.Uid, string, string, int, any, time.Time) (*types.GroupJoinRequest, error)
|
ResolveJoinRequest(types.TenantID, string, string, types.Uid, string, string, int, any, time.Time) (*types.GroupJoinRequest, error)
|
||||||
LatestAnnouncement(types.TenantID, string) (*types.GroupAnnouncement, error)
|
LatestAnnouncement(types.TenantID, string) (*types.GroupAnnouncement, error)
|
||||||
|
GetAnnouncement(types.TenantID, string, string) (*types.GroupAnnouncement, error)
|
||||||
PutAnnouncement(types.TenantID, *types.GroupAnnouncement, int) (*types.GroupAnnouncement, error)
|
PutAnnouncement(types.TenantID, *types.GroupAnnouncement, int) (*types.GroupAnnouncement, error)
|
||||||
ReadAnnouncement(types.TenantID, string, string, types.Uid, time.Time) error
|
ReadAnnouncement(types.TenantID, string, string, types.Uid, time.Time) error
|
||||||
ListMutes(types.TenantID, string, string, int) ([]types.GroupMute, string, error)
|
ListMutes(types.TenantID, string, string, int) ([]types.GroupMute, string, error)
|
||||||
@@ -1902,6 +1904,17 @@ func (groupBusinessMapper) LatestAnnouncement(tenantID types.TenantID, topic str
|
|||||||
return tenantAdp.TenantGroupAnnouncementLatest(tenantID, strings.TrimSpace(topic))
|
return tenantAdp.TenantGroupAnnouncementLatest(tenantID, strings.TrimSpace(topic))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (groupBusinessMapper) GetAnnouncement(tenantID types.TenantID, topic, announcementID string) (*types.GroupAnnouncement, error) {
|
||||||
|
if strings.TrimSpace(topic) == "" || strings.TrimSpace(announcementID) == "" {
|
||||||
|
return nil, types.ErrMalformed
|
||||||
|
}
|
||||||
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tenantAdp.TenantGroupAnnouncementGet(tenantID, strings.TrimSpace(topic), strings.TrimSpace(announcementID))
|
||||||
|
}
|
||||||
|
|
||||||
func (groupBusinessMapper) PutAnnouncement(tenantID types.TenantID, ann *types.GroupAnnouncement, expectedVersion int) (*types.GroupAnnouncement, error) {
|
func (groupBusinessMapper) PutAnnouncement(tenantID types.TenantID, ann *types.GroupAnnouncement, expectedVersion int) (*types.GroupAnnouncement, error) {
|
||||||
if ann == nil || ann.Topic == "" || ann.AuthorUserID.IsZero() || ann.Content == "" {
|
if ann == nil || ann.Topic == "" || ann.AuthorUserID.IsZero() || ann.Content == "" {
|
||||||
return nil, types.ErrMalformed
|
return nil, types.ErrMalformed
|
||||||
@@ -2716,24 +2729,37 @@ type profileMapper struct{}
|
|||||||
var Profiles ProfilePersistenceInterface
|
var Profiles ProfilePersistenceInterface
|
||||||
|
|
||||||
type AppReleasePersistenceInterface interface {
|
type AppReleasePersistenceInterface interface {
|
||||||
Latest(tenantID types.TenantID, platform, channel string) (*types.AppRelease, error)
|
Latest(platform, channel string) (*types.AppRelease, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type appReleaseMapper struct{}
|
type appReleaseMapper struct{}
|
||||||
|
|
||||||
var AppReleases AppReleasePersistenceInterface
|
var AppReleases AppReleasePersistenceInterface
|
||||||
|
|
||||||
func (appReleaseMapper) Latest(tenantID types.TenantID, platform, channel string) (*types.AppRelease, error) {
|
func (appReleaseMapper) Latest(platform, channel string) (*types.AppRelease, error) {
|
||||||
platform = strings.ToLower(strings.TrimSpace(platform))
|
platform = strings.ToLower(strings.TrimSpace(platform))
|
||||||
channel = strings.ToLower(strings.TrimSpace(channel))
|
channel = strings.ToLower(strings.TrimSpace(channel))
|
||||||
if platform == "" || channel == "" {
|
if platform == "" || channel == "" {
|
||||||
return nil, types.ErrMalformed
|
return nil, types.ErrMalformed
|
||||||
}
|
}
|
||||||
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
cacheKey := platform + ":" + channel
|
||||||
|
if cached, ok := appReleaseConfigCache.get(cacheKey); ok {
|
||||||
|
copy := *cached
|
||||||
|
return ©, nil
|
||||||
|
}
|
||||||
|
if adminInternalConfigProvider == nil {
|
||||||
|
return nil, types.ErrUnsupported
|
||||||
|
}
|
||||||
|
release, err := adminInternalConfigProvider.LatestAppRelease(platform, channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return tenantAdp.TenantAppReleaseLatest(tenantID, platform, channel)
|
if release == nil {
|
||||||
|
return nil, types.ErrNotFound
|
||||||
|
}
|
||||||
|
copy := *release
|
||||||
|
appReleaseConfigCache.set(cacheKey, ©)
|
||||||
|
return release, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DevicePushTokenPersistenceInterface interface {
|
type DevicePushTokenPersistenceInterface interface {
|
||||||
@@ -3008,7 +3034,7 @@ func (profileMapper) UpdatePrivacy(tenantID types.TenantID, uid types.Uid, patch
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validUserPrivacyPatch(patch types.UserPrivacyPatch) bool {
|
func validUserPrivacyPatch(patch types.UserPrivacyPatch) bool {
|
||||||
if patch.AddMeMethods == nil && patch.ProfileVisibility == nil && patch.LastSeenVisibility == nil && patch.ReadReceipts == nil {
|
if patch.AddMeMethods == nil && patch.ProfileVisibility == nil && patch.LastSeenVisibility == nil && patch.ReadReceipts == nil && patch.GroupInviteVerification == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for method := range patch.AddMeMethods {
|
for method := range patch.AddMeMethods {
|
||||||
@@ -3411,6 +3437,14 @@ func relationshipContext(tenantAdp adapter.TenantBusinessAdapter, tenantID types
|
|||||||
if cachedFriend, err := cachedFriendContains(tenantID, userID, peerID); err != nil {
|
if cachedFriend, err := cachedFriendContains(tenantID, userID, peerID); err != nil {
|
||||||
logs.Warn.Printf("cache friend[%s:%s]: read failed: %v", userID.UserId(), peerID.UserId(), err)
|
logs.Warn.Printf("cache friend[%s:%s]: read failed: %v", userID.UserId(), peerID.UserId(), err)
|
||||||
} else if cachedFriend {
|
} else if cachedFriend {
|
||||||
|
if friendship, err := tenantAdp.TenantFriendshipGet(tenantID, userID, peerID); err != nil {
|
||||||
|
logs.Warn.Printf("friendship[%s:%s]: read failed after cache hit: %v", userID.UserId(), peerID.UserId(), err)
|
||||||
|
} else if friendship != nil && friendship.Status == types.RelationshipFriend {
|
||||||
|
ctx.Remark = friendship.Remark
|
||||||
|
if friendship.Topic != "" {
|
||||||
|
ctx.Topic = friendship.Topic
|
||||||
|
}
|
||||||
|
}
|
||||||
ctx.Relationship = types.RelationshipFriend
|
ctx.Relationship = types.RelationshipFriend
|
||||||
ctx.CanSend = true
|
ctx.CanSend = true
|
||||||
if ctx.Topic == "" {
|
if ctx.Topic == "" {
|
||||||
@@ -3424,6 +3458,7 @@ func relationshipContext(tenantAdp adapter.TenantBusinessAdapter, tenantID types
|
|||||||
cacheFriendOneWay(tenantID, userID, peerID)
|
cacheFriendOneWay(tenantID, userID, peerID)
|
||||||
ctx.Relationship = types.RelationshipFriend
|
ctx.Relationship = types.RelationshipFriend
|
||||||
ctx.CanSend = true
|
ctx.CanSend = true
|
||||||
|
ctx.Remark = friendship.Remark
|
||||||
if ctx.Topic == "" {
|
if ctx.Topic == "" {
|
||||||
ctx.Topic = friendship.Topic
|
ctx.Topic = friendship.Topic
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const (
|
|||||||
GroupMemberStatusLeft = "left"
|
GroupMemberStatusLeft = "left"
|
||||||
|
|
||||||
GroupInvitationStatusPending = "pending"
|
GroupInvitationStatusPending = "pending"
|
||||||
|
GroupInvitationStatusPendingApproval = "pending_approval"
|
||||||
GroupInvitationStatusJoined = "joined"
|
GroupInvitationStatusJoined = "joined"
|
||||||
|
|
||||||
GroupJoinRequestStatusPending = "pending"
|
GroupJoinRequestStatusPending = "pending"
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ type UserPrivacySettings struct {
|
|||||||
ProfileVisibility string
|
ProfileVisibility string
|
||||||
LastSeenVisibility string
|
LastSeenVisibility string
|
||||||
ReadReceipts bool
|
ReadReceipts bool
|
||||||
|
GroupInviteVerification bool
|
||||||
Version int
|
Version int
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
@@ -44,6 +45,7 @@ type UserPrivacyPatch struct {
|
|||||||
ProfileVisibility *string
|
ProfileVisibility *string
|
||||||
LastSeenVisibility *string
|
LastSeenVisibility *string
|
||||||
ReadReceipts *bool
|
ReadReceipts *bool
|
||||||
|
GroupInviteVerification *bool
|
||||||
Version int
|
Version int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ type RegistrationInviteCode struct {
|
|||||||
Code string `db:"code" json:"code"`
|
Code string `db:"code" json:"code"`
|
||||||
Status RegistrationInviteStatus `db:"status" json:"status"`
|
Status RegistrationInviteStatus `db:"status" json:"status"`
|
||||||
ExpiresAt time.Time `db:"expires_at" json:"expires_at"`
|
ExpiresAt time.Time `db:"expires_at" json:"expires_at"`
|
||||||
|
MaxUses int `db:"max_uses" json:"max_uses"`
|
||||||
UsageCount int `db:"usage_count" json:"usage_count"`
|
UsageCount int `db:"usage_count" json:"usage_count"`
|
||||||
|
BoundUserID *int64 `db:"bound_user_id" json:"bound_user_id,omitempty"`
|
||||||
LastUsedAt *time.Time `db:"last_used_at" json:"last_used_at,omitempty"`
|
LastUsedAt *time.Time `db:"last_used_at" json:"last_used_at,omitempty"`
|
||||||
CreatedBy int64 `db:"created_by" json:"created_by"`
|
CreatedBy int64 `db:"created_by" json:"created_by"`
|
||||||
Remark string `db:"remark" json:"remark,omitempty"`
|
Remark string `db:"remark" json:"remark,omitempty"`
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ type RelationshipContext struct {
|
|||||||
Topic string `json:"topic"`
|
Topic string `json:"topic"`
|
||||||
Relationship string `json:"relationship"`
|
Relationship string `json:"relationship"`
|
||||||
CanSend bool `json:"can_send"`
|
CanSend bool `json:"can_send"`
|
||||||
|
Remark string `json:"remark,omitempty"`
|
||||||
RequestID string `json:"request_id,omitempty"`
|
RequestID string `json:"request_id,omitempty"`
|
||||||
PendingStatus string `json:"pending_status,omitempty"`
|
PendingStatus string `json:"pending_status,omitempty"`
|
||||||
Peer *User `json:"peer,omitempty"`
|
Peer *User `json:"peer,omitempty"`
|
||||||
|
|||||||
@@ -1269,6 +1269,7 @@ type MessageSaveResult struct {
|
|||||||
SeqId int64
|
SeqId int64
|
||||||
MarkedReadBySender bool
|
MarkedReadBySender bool
|
||||||
Duplicate bool
|
Duplicate bool
|
||||||
|
Pending bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Range is a range of message SeqIDs. Low end is inclusive (closed), high end is exclusive (open): [Low, Hi).
|
// Range is a range of message SeqIDs. Low end is inclusive (closed), high end is exclusive (open): [Low, Hi).
|
||||||
|
|||||||
+10
-11
@@ -262,8 +262,8 @@ func (t *Topic) prepareBroadcastableMessage(msg *ServerComMessage, uid types.Uid
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (t.cat == types.TopicCatP2P && !uid.IsZero()) || (t.cat == types.TopicCatGrp && t.isChan) {
|
if (t.cat == types.TopicCatP2P && !uid.IsZero()) || (t.cat == types.TopicCatGrp && t.isChan) {
|
||||||
// For p2p topics topic name is dependent on receiver.
|
// P2P topics are exposed by their canonical p2p... name. Channel topics
|
||||||
// Channel topics may be presented as grpXXX or chnXXX.
|
// may be presented as grpXXX or chnXXX.
|
||||||
var topicName string
|
var topicName string
|
||||||
if isChanSub {
|
if isChanSub {
|
||||||
topicName = types.GrpToChn(t.xoriginal)
|
topicName = types.GrpToChn(t.xoriginal)
|
||||||
@@ -2867,14 +2867,15 @@ func (t *Topic) replyGetSub(sess *Session, asUid types.Uid, authLevel auth.Level
|
|||||||
banned = true
|
banned = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reporting user's subscriptions to other topics. P2P topic name is the
|
// Reporting user's subscriptions to other topics. P2P topic names are
|
||||||
// UID of the other user.
|
// reported by their canonical p2p... names; usr... remains accepted as
|
||||||
|
// an input alias only.
|
||||||
with := sub.GetWith()
|
with := sub.GetWith()
|
||||||
canViewLastSeen := true
|
canViewLastSeen := true
|
||||||
if with != "" {
|
if with != "" {
|
||||||
mts.Topic = with
|
mts.Topic = sub.Topic
|
||||||
canViewLastSeen = imCanViewLastSeen(t.tenantID, asUid, types.ParseUserId(with))
|
canViewLastSeen = imCanViewLastSeen(t.tenantID, asUid, types.ParseUserId(with))
|
||||||
mts.Online = t.perSubs[with].online && !deleted && presencer
|
mts.Online = t.perSubs[sub.Topic].online && !deleted && presencer
|
||||||
if !deleted && presencer {
|
if !deleted && presencer {
|
||||||
mts.Online = redisUserOnline(t.tenantID, types.ParseUserId(with), mts.Online)
|
mts.Online = redisUserOnline(t.tenantID, types.ParseUserId(with), mts.Online)
|
||||||
}
|
}
|
||||||
@@ -4130,8 +4131,8 @@ func (t *Topic) isDeleted() bool {
|
|||||||
// Get topic name suitable for the given client
|
// Get topic name suitable for the given client
|
||||||
func (t *Topic) original(uid types.Uid) string {
|
func (t *Topic) original(uid types.Uid) string {
|
||||||
if t.cat == types.TopicCatP2P {
|
if t.cat == types.TopicCatP2P {
|
||||||
if pud, ok := t.perUser[uid]; ok {
|
if _, ok := t.perUser[uid]; ok {
|
||||||
return pud.topicName
|
return t.name
|
||||||
}
|
}
|
||||||
panic("Invalid P2P topic")
|
panic("Invalid P2P topic")
|
||||||
}
|
}
|
||||||
@@ -4350,7 +4351,6 @@ func genTopicName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert expanded (routable) topic name into name suitable for sending to the user.
|
// Convert expanded (routable) topic name into name suitable for sending to the user.
|
||||||
// For example p2pAbCDef123 -> usrAbCDef
|
|
||||||
func topicNameForUser(name string, uid types.Uid, isChan bool) string {
|
func topicNameForUser(name string, uid types.Uid, isChan bool) string {
|
||||||
switch topicCat(name) {
|
switch topicCat(name) {
|
||||||
case types.TopicCatMe:
|
case types.TopicCatMe:
|
||||||
@@ -4358,8 +4358,7 @@ func topicNameForUser(name string, uid types.Uid, isChan bool) string {
|
|||||||
case types.TopicCatFnd:
|
case types.TopicCatFnd:
|
||||||
return "fnd"
|
return "fnd"
|
||||||
case types.TopicCatP2P:
|
case types.TopicCatP2P:
|
||||||
topic, _ := types.P2PNameForUser(uid, name)
|
return name
|
||||||
return topic
|
|
||||||
case types.TopicCatGrp:
|
case types.TopicCatGrp:
|
||||||
if isChan {
|
if isChan {
|
||||||
return types.GrpToChn(name)
|
return types.GrpToChn(name)
|
||||||
|
|||||||
+12
-13
@@ -259,8 +259,8 @@ func TestHandleBroadcastDataP2P(t *testing.T) {
|
|||||||
if r.Data == nil {
|
if r.Data == nil {
|
||||||
t.Fatalf("Response[0] must have a ctrl message")
|
t.Fatalf("Response[0] must have a ctrl message")
|
||||||
}
|
}
|
||||||
if r.Data.Topic != from {
|
if r.Data.Topic != "p2p-test" {
|
||||||
t.Errorf("Response[0] topic: expected '%s', got '%s'", from, r.Data.Topic)
|
t.Errorf("Response[0] topic: expected '%s', got '%s'", "p2p-test", r.Data.Topic)
|
||||||
}
|
}
|
||||||
if r.Data.Content.(string) != "test" {
|
if r.Data.Content.(string) != "test" {
|
||||||
t.Errorf("Response[0] content: expected 'test', got '%s'", r.Data.Content.(string))
|
t.Errorf("Response[0] content: expected 'test', got '%s'", r.Data.Content.(string))
|
||||||
@@ -274,7 +274,7 @@ func TestHandleBroadcastDataP2P(t *testing.T) {
|
|||||||
if len(helper.hubMessages) != 2 {
|
if len(helper.hubMessages) != 2 {
|
||||||
t.Fatal("Huhelper.route expected exactly two recipients routed via huhelper.")
|
t.Fatal("Huhelper.route expected exactly two recipients routed via huhelper.")
|
||||||
}
|
}
|
||||||
for i, uid := range helper.uids {
|
for _, uid := range helper.uids {
|
||||||
if mm, ok := helper.hubMessages[uid.UserId()]; ok {
|
if mm, ok := helper.hubMessages[uid.UserId()]; ok {
|
||||||
if len(mm) == 1 {
|
if len(mm) == 1 {
|
||||||
s := mm[0]
|
s := mm[0]
|
||||||
@@ -286,7 +286,7 @@ func TestHandleBroadcastDataP2P(t *testing.T) {
|
|||||||
if p.SkipTopic != "p2p-test" {
|
if p.SkipTopic != "p2p-test" {
|
||||||
t.Errorf("Uid %s: pres skip topic is expected to be 'p2p-test', got %s", uid.UserId(), p.SkipTopic)
|
t.Errorf("Uid %s: pres skip topic is expected to be 'p2p-test', got %s", uid.UserId(), p.SkipTopic)
|
||||||
}
|
}
|
||||||
expectedSrc := helper.uids[i^1].UserId()
|
expectedSrc := "p2p-test"
|
||||||
if p.Src != expectedSrc {
|
if p.Src != expectedSrc {
|
||||||
t.Errorf("Uid %s: pres.src expected: %s, found: %s", uid.UserId(), expectedSrc, p.Src)
|
t.Errorf("Uid %s: pres.src expected: %s, found: %s", uid.UserId(), expectedSrc, p.Src)
|
||||||
}
|
}
|
||||||
@@ -425,8 +425,8 @@ func TestHandleBroadcastCall(t *testing.T) {
|
|||||||
if r.Data == nil {
|
if r.Data == nil {
|
||||||
t.Fatalf("Response[0] must have a ctrl message")
|
t.Fatalf("Response[0] must have a ctrl message")
|
||||||
}
|
}
|
||||||
if r.Data.Topic != from {
|
if r.Data.Topic != "p2p-test" {
|
||||||
t.Errorf("Response[0] topic: expected '%s', got '%s'", from, r.Data.Topic)
|
t.Errorf("Response[0] topic: expected '%s', got '%s'", "p2p-test", r.Data.Topic)
|
||||||
}
|
}
|
||||||
content := r.Data.Content.(map[string]any)
|
content := r.Data.Content.(map[string]any)
|
||||||
if content["callId"] != "call-1" || content["callType"] != "audio" || content["video"] != false {
|
if content["callId"] != "call-1" || content["callType"] != "audio" || content["video"] != false {
|
||||||
@@ -447,7 +447,7 @@ func TestHandleBroadcastCall(t *testing.T) {
|
|||||||
if len(helper.hubMessages) != 2 {
|
if len(helper.hubMessages) != 2 {
|
||||||
t.Fatal("Huhelper.route expected exactly two recipients routed via huhelper.")
|
t.Fatal("Huhelper.route expected exactly two recipients routed via huhelper.")
|
||||||
}
|
}
|
||||||
for i, uid := range helper.uids {
|
for _, uid := range helper.uids {
|
||||||
if mm, ok := helper.hubMessages[uid.UserId()]; ok {
|
if mm, ok := helper.hubMessages[uid.UserId()]; ok {
|
||||||
if len(mm) == 1 {
|
if len(mm) == 1 {
|
||||||
s := mm[0]
|
s := mm[0]
|
||||||
@@ -459,7 +459,7 @@ func TestHandleBroadcastCall(t *testing.T) {
|
|||||||
if p.SkipTopic != "p2p-test" {
|
if p.SkipTopic != "p2p-test" {
|
||||||
t.Errorf("Uid %s: pres skip topic is expected to be 'p2p-test', got %s", uid.UserId(), p.SkipTopic)
|
t.Errorf("Uid %s: pres skip topic is expected to be 'p2p-test', got %s", uid.UserId(), p.SkipTopic)
|
||||||
}
|
}
|
||||||
expectedSrc := helper.uids[i^1].UserId()
|
expectedSrc := "p2p-test"
|
||||||
if p.Src != expectedSrc {
|
if p.Src != expectedSrc {
|
||||||
t.Errorf("Uid %s: pres.src expected: %s, found: %s", uid.UserId(), expectedSrc, p.Src)
|
t.Errorf("Uid %s: pres.src expected: %s, found: %s", uid.UserId(), expectedSrc, p.Src)
|
||||||
}
|
}
|
||||||
@@ -1321,9 +1321,8 @@ func TestHandleBroadcastInfoP2P(t *testing.T) {
|
|||||||
res := helper.results[1].messages[0].(*ServerComMessage)
|
res := helper.results[1].messages[0].(*ServerComMessage)
|
||||||
if res.Info != nil {
|
if res.Info != nil {
|
||||||
info := res.Info
|
info := res.Info
|
||||||
// Topic name will be fixed (to -> from).
|
if info.Topic != topicName {
|
||||||
if info.Topic != from.UserId() {
|
t.Errorf("Info.Topic: expected '%s', found '%s'", topicName, info.Topic)
|
||||||
t.Errorf("Info.Topic: expected '%s', found '%s'", to.UserId(), info.Topic)
|
|
||||||
}
|
}
|
||||||
if info.From != from.UserId() {
|
if info.From != from.UserId() {
|
||||||
t.Errorf("Info.From: expected '%s', found '%s'", from.UserId(), info.From)
|
t.Errorf("Info.From: expected '%s', found '%s'", from.UserId(), info.From)
|
||||||
@@ -1341,9 +1340,9 @@ func TestHandleBroadcastInfoP2P(t *testing.T) {
|
|||||||
if len(helper.hubMessages) != 2 {
|
if len(helper.hubMessages) != 2 {
|
||||||
t.Fatalf("Hubhelper.route expected exactly two recipients routed via hubhelper. Found %d", len(helper.hubMessages))
|
t.Fatalf("Hubhelper.route expected exactly two recipients routed via hubhelper. Found %d", len(helper.hubMessages))
|
||||||
}
|
}
|
||||||
for i, uid := range helper.uids {
|
for _, uid := range helper.uids {
|
||||||
if routedMsgs, ok := helper.hubMessages[uid.UserId()]; ok {
|
if routedMsgs, ok := helper.hubMessages[uid.UserId()]; ok {
|
||||||
expectedSrc := helper.uids[i^1].UserId()
|
expectedSrc := topicName
|
||||||
for _, s := range routedMsgs {
|
for _, s := range routedMsgs {
|
||||||
if s.Info != nil {
|
if s.Info != nil {
|
||||||
// Info messages for offline sessions.
|
// Info messages for offline sessions.
|
||||||
|
|||||||
@@ -452,6 +452,9 @@ func validateRegistrationInvite(tenantID types.TenantID, code string, now time.T
|
|||||||
if !now.Before(invite.ExpiresAt) {
|
if !now.Before(invite.ExpiresAt) {
|
||||||
return types.ErrInviteExpired
|
return types.ErrInviteExpired
|
||||||
}
|
}
|
||||||
|
if invite.MaxUses > 0 && invite.UsageCount >= invite.MaxUses {
|
||||||
|
return types.ErrInviteInvalid
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return types.ErrInviteInvalid
|
return types.ErrInviteInvalid
|
||||||
|
|||||||
Reference in New Issue
Block a user