Files
suixinkan_uikit/docs/账号注销后端接口需求.md

432 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 账号注销后端接口需求
> **2026-08-28 已被新范围替代:** 本次迭代改为使用旧 `account-deregister` 接口,仅注销当前 `store_user` 身份,不实施本文的主账号注销、新接口或恢复专用 Token 方案。当前接入情况见 [门店身份注销接入说明](门店身份注销接入说明.md)。下文保留为历史讨论记录。
更新日期:2026-08-27
适用端:随心瞰商家版 iOS;后端账号状态应同时约束 Android、旧版本客户端及其他登录入口。
文档性质:**接口需求建议稿,以下新增路径和字段尚未与后端确认,不代表线上已有接口。**
## 1. 需要后端提供什么
需要 **5 个注销接口、现有登录与鉴权流程改造,以及服务端到期处理任务**。
| 类型 | 建议接口 / 能力 | 用途 |
| --- | --- | --- |
| 新增 | `GET /api/app/account-deletion/precheck` | 返回真实资产、注销影响说明及阻断原因 |
| 新增 | `POST /api/app/account-deletion/send-sms-code` | 向主账号绑定手机号发送注销专用验证码 |
| 新增 | `POST /api/app/account-deletion/submit` | 校验验证码和用户确认,提交注销申请 |
| 新增 | `GET /api/app/account-deletion/status` | 查询当前账号的服务端注销状态及截止时间 |
| 新增 | `POST /api/app/account-deletion/cancel` | 冷静期内由用户明确确认后取消注销 |
| 修改 | `POST /api/app/v9/login` | 身份验证通过后区分正常登录、待注销恢复和不可恢复状态 |
| 修改 | `POST /api/app/v9/set-user` 与统一鉴权 | 禁止待注销或已注销账号取得、使用业务 Token |
| 服务端任务 | 到期注销、失败重试、会话失效 | 不依赖客户端在线或再次打开 App |
如果已有等价能力,可以复用后端现有路径,但需覆盖本文的数据和行为要求,不必重复建设。
### 当前客户端状态
- 已有设置入口、资产核验页、短信验证页、成功页、密码登录时的恢复确认和冷启动检查。
- 当前为 `AccountDeletionMockService`:资产是固定示例,验证码固定为 `123456`,注销记录保存在本机 `UserDefaults`。
- **目前不会发送真实短信,也不会注销后端账号或删除后端数据。**
- 接入真实接口后,服务端状态为唯一依据;本机时间、手机号输入值及本地记录不能作为注销结果或操作权限的依据。
## 2. 账号范围与统一约定
### 2.1 注销对象
当前功能意图是注销**手机号登录对应的主账号及其关联业务身份**,不是仅退出当前登录,也不是只停用当前选中的景区或门店身份。
- 后端根据 Token 解析稳定的主账号 ID,并据此聚合所有关联景区、门店身份的数据。
- 请求不接受客户端指定待注销的 `user_id`、`username`、`phone`、`scenic_id` 或 `store_id`;短信收件人也由后端确定。
- 当前业务身份资料里的手机号可能与主账号绑定手机号不同,不能直接用业务身份手机号发送注销短信。
- “解除景区、门店账号”指解除该用户的关联身份;**不应删除景区、门店实体,也不能误删其他用户、门店或客户共同拥有的数据**。
- 若存在管理员、负责人或共享资产,需明确移交、保留或阻断策略,不能因为客户端勾选“放弃资产”就直接删除。
### 2.2 请求和响应
沿用当前 App 网络层约定:
```http
Content-Type: application/json
Accept: application/json
token: <当前请求所需的凭证>
X-APP-VERSION: <客户端版本>
X-OS-TYPE: <客户端现有平台标识>
```
当前工程使用 `token` 请求头,**不是** `Authorization: Bearer ...`。恢复专用凭证也建议放在同一请求头,由服务端识别凭证类型和权限。
```json
{
"code": 100000,
"msg": "success",
"data": {}
}
```
- 成功业务码沿用 `100000`;新增失败码由后端统一分配,见第 6 节。
- JSON 字段使用 `snake_case`;布尔值使用 `true/false`,空列表使用 `[]`。
- ID 建议统一返回字符串,客户端不依赖数据库自增 ID 或 UUID 的内部格式。
- 时间统一使用带时区的 ISO 8601 字符串,例如 `2026-08-27T08:00:00Z`;客户端负责本地化显示。
- 时间相关响应返回 `server_time`;冷静期截止、验证码到期和取消资格全部由服务端判断。
### 2.3 状态及七天冷静期
建议在真实服务中区分“不可再取消”和“数据已处理完成”,避免定时任务尚未完成就展示为永久删除成功。
| `state` | 含义 | 允许恢复 | 允许进入业务 |
| --- | --- | --- | --- |
| `none` | 没有注销申请 | 不适用 | 是 |
| `pending` | 在冷静期内,待用户取消或到期 | 是,且服务端当前时间必须早于截止时间 | 否 |
| `canceled` | 最近一次申请已取消 | 不适用;可以重新申请 | 是,需重新取得有效业务 Token |
| `processing` | 已到截止时间,正在执行最终处理 | 否 | 否 |
| `completed` | 服务端已完成约定的注销处理 | 否 | 否 |
流转:`none/canceled → pending → processing → completed`;仅 `pending` 且未到期时允许转为 `canceled`。
- 建议默认冷静期为提交成功后 `7 × 24` 小时,后端返回准确的 `scheduled_deletion_at`,客户端不自行推算。
- 恰好到达截止时刻即不可取消;即使定时任务尚未运行,接口也必须立即按不可恢复处理。
- 任务失败保持不可恢复状态,记录原因并重试,不能重新开放登录或重置冷静期。
- 当前 Mock 没有 `processing` 状态;接入真实后端时客户端需同步扩展。
## 3. 五个接口的详细需求
### 3.1 注销前置核验
```http
GET /api/app/account-deletion/precheck
```
使用有效业务 Token,无查询参数。返回整个主账号范围内的资产快照、当前绑定手机号的脱敏值、注销后果,以及是否允许提交。
成功响应示例(资产数值仅为示例):
```json
{
"code": 100000,
"msg": "success",
"data": {
"precheck_id": "precheck_example_001",
"expires_at": "2026-08-27T08:10:00Z",
"server_time": "2026-08-27T08:00:00Z",
"masked_phone": "138****0000",
"can_submit": true,
"blocking_reasons": [],
"assets": [
{"kind": "wallet", "title": "钱包余额", "value": "0.00", "unit": "CNY", "value_text": "¥0.00"},
{"kind": "works", "title": "作品与相册", "value": "36", "unit": "item", "value_text": "36个"},
{"kind": "projects", "title": "项目", "value": "4", "unit": "item", "value_text": "4个"},
{"kind": "cloud_files", "title": "云盘文件", "value": "8589934592", "unit": "byte", "value_text": "8 GB"}
],
"consequences": [
"本人关联的景区与门店身份将解除",
"个人作品和云盘文件将按已确认的规则处理",
"提交后7天内再次登录并确认恢复,可取消注销"
],
"acknowledgement_version": "account-deletion-v1"
}
}
```
| 字段 | 要求 |
| --- | --- |
| `precheck_id` / `expires_at` | 后端生成的核验快照标识及有效期,绑定当前主账号,用于确认用户看到的资产和后果 |
| `masked_phone` | 主账号实际绑定手机号的脱敏值;不返回短信验证码 |
| `can_submit` | 是否满足注销条件;客户端据此禁止或允许继续 |
| `blocking_reasons` | 不可提交时返回 `[{"reason_code":"WALLET_NOT_SETTLED","message":"请先处理钱包余额或结算中的款项"}]`,可有多项 |
| `assets` | 当前页面需要 `wallet`、`works`、`projects`、`cloud_files` 四类;零资产也返回对应项 |
| `value` / `unit` / `value_text` | 原始值统一为字符串;金额为元且保留两位小数,计数、字节为整数字符串;`value_text` 供页面直接展示 |
| `consequences` | 由后端按最终业务规则返回,不能宣称会删除实际需要保留的数据 |
| `acknowledgement_version` | 本次注销说明版本,随提交保存确认记录 |
要求:
- 核验不得触发删除、资金扣除、身份解绑或短信发送。
- 作品、相册、项目及云盘文件的统计口径和去重方式由后端明确,不能把共享资产全部算成该用户可删除的资产。
- 余额、冻结款、提现中、未完成订单、未补缴收款等是否阻断,由产品和后端确认。**在规则确认前,建议未结清资金类问题阻断注销,不直接照搬 Mock 的“放弃余额”。**
- 提交时必须再次校验条件。资产或影响范围发生需要重新确认的变化时,返回“请重新核验”,不得默默沿用旧快照。
### 3.2 发送注销短信验证码
```http
POST /api/app/account-deletion/send-sms-code
```
使用有效业务 Token,请求体为 `{}`。只发送给当前主账号绑定手机号,不接受任意手机号参数。
```json
{
"code": 100000,
"msg": "success",
"data": {
"verification_id": "verification_example_001",
"masked_phone": "138****0000",
"expires_in": 300,
"retry_after": 60,
"server_time": "2026-08-27T08:01:00Z"
}
}
```
- `verification_id` 是验证码会话标识,绑定主账号、当时的绑定手机号及“账号注销”用途,提交时一并携带。
- `expires_in`、`retry_after` 单位为秒;示例为 5 分钟有效、60 秒后可重发,实际值由后端配置并返回。
- 使用 6 位数字验证码;不在响应、日志或埋点中返回明文验证码。
- 设置账号、手机号、IP 等维度的频率限制及错误次数限制;重发后旧验证码失效。
- 与登录、提现、实名认证等验证码用途隔离。可复用短信基础设施,不可混用验证码。
- 主账号换绑手机号后,旧手机号对应的验证码会话及核验快照失效,要求重新开始。
- 缺少绑定手机号、发送失败或触发限流时返回明确错误;前端不能在失败时显示“已发送”。
### 3.3 提交注销申请
```http
POST /api/app/account-deletion/submit
```
使用有效业务 Token。请求示例:
```json
{
"client_request_id": "709277cb-2085-49c1-b80f-042476c7c36b",
"precheck_id": "precheck_example_001",
"verification_id": "verification_example_001",
"sms_code": "482951",
"acknowledged_asset_kinds": ["wallet", "works", "projects", "cloud_files"],
"acknowledgement_version": "account-deletion-v1"
}
```
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `client_request_id` | 是 | 客户端为本次提交生成的 UUID 字符串;网络重试沿用同一个值 |
| `precheck_id` | 是 | 当前主账号的有效核验快照,不接受其他账号的快照 |
| `verification_id` / `sms_code` | 是 | 验证码会话及用户输入的真实短信码;示例不是固定验证码 |
| `acknowledged_asset_kinds` | 是 | 用户已确认的资产类别,须与快照中要求确认的集合一致 |
| `acknowledgement_version` | 是 | 用户确认的注销说明版本 |
成功响应示例:
```json
{
"code": 100000,
"msg": "success",
"data": {
"state": "pending",
"can_cancel": true,
"server_time": "2026-08-27T08:02:00Z",
"request": {
"id": "deletion_example_001",
"client_request_id": "709277cb-2085-49c1-b80f-042476c7c36b",
"status": "pending",
"submitted_at": "2026-08-27T08:02:00Z",
"scheduled_deletion_at": "2026-09-03T08:02:00Z",
"canceled_at": null,
"completed_at": null,
"acknowledged_asset_kinds": ["wallet", "works", "projects", "cloud_files"],
"acknowledgement_version": "account-deletion-v1"
}
}
}
```
处理要求:
1. 服务端重新校验身份、验证码、快照、确认版本以及资金和未完成业务条件。
2. 原子保存申请及用户确认记录、消耗验证码,并使该主账号所有设备上的业务 Token、旧登录临时 Token 和刷新凭证失去业务访问权限。
3. 冷静期内保留可恢复的身份及数据,不提前执行不可逆删除;状态必须限制新建订单、上传、提现等业务操作。
4. 同一主账号同一时刻最多有一条有效申请。已成功的同一 `client_request_id` 重试应返回原申请,不因验证码已消费而重复报错;同一幂等键不能承载不同请求内容。
5. 账号已有待处理申请时,不创建第二条,也不延长原截止时间;返回原状态或可识别的“已有申请”错误,客户端转查询状态。
6. 成功页使用服务端返回的截止时间。客户端收到成功响应后应立即清理业务登录态;即使用户尚未点击成功页“退出”,后端也已禁止业务访问。
**响应丢失的处理:** 提交可能已成功且原 Token 已失效。此时客户端重新完成身份验证,通过登录接口取得恢复专用凭证,再查 `status`;不得把网络超时直接当成提交失败,也不得为了查询结果自动取消注销。
### 3.4 查询注销状态
```http
GET /api/app/account-deletion/status
```
- 无查询参数,以凭证定位主账号。
- 接受有效业务 Token、正常登录临时 Token,或第 4 节定义的恢复专用 Token;不能提供匿名按手机号查询。
- 原业务 Token 已被注销操作撤销时,不重新赋予其查询权限,应先重新验证身份取得恢复专用 Token。
- 用于启动检查、回到前台、多设备状态校准,以及提交/取消请求超时后的结果确认。
响应 `data` 与提交接口一致,包含 `state`、`can_cancel`、`server_time`、`request`。无申请时:
```json
{
"code": 100000,
"msg": "success",
"data": {
"state": "none",
"can_cancel": false,
"server_time": "2026-08-27T08:00:00Z",
"request": null
}
}
```
- `canceled` 返回最近取消的申请和 `canceled_at`;`completed` 返回实际完成时间 `completed_at`。
- `can_cancel` 由后端计算,只能在状态为 `pending` 且未到截止时刻时为 `true`。
- 查询不得取消注销或延长冷静期。到期任务尚未完成时返回 `processing`,不能仅凭时间到了就返回 `completed`。
- 状态查询失败时,不应默认账号正常;客户端提示重试或重新登录,业务接口仍由后端鉴权保护。
### 3.5 取消注销申请
```http
POST /api/app/account-deletion/cancel
token: <恢复专用 Token>
```
只有重新验证身份且用户点击“恢复账号并登录”后调用:
```json
{
"request_id": "deletion_example_001"
}
```
成功响应示例:
```json
{
"code": 100000,
"msg": "success",
"data": {
"request_id": "deletion_example_001",
"state": "canceled",
"canceled_at": "2026-08-28T01:00:00Z",
"server_time": "2026-08-28T01:00:00Z",
"login": {
"token": "new-account-selection-token",
"scenic_users": [],
"store_users": []
}
}
}
```
- `login` 结构复用现有 v9 登录响应;示例数组省略业务内容,实际需返回恢复后当前可选的景区、门店身份。
- 返回的 `login.token` 为新生成的正常账号选择临时 Token;客户端继续走原有单账号自动选择、多账号选择及 `/v9/set-user` 流程,不复用注销前的旧凭证。
- `request_id` 必须与凭证绑定的主账号和注销申请一致,不能取消别人的申请或该账号下一次新申请。
- 与到期任务通过事务或等效并发控制互斥;按服务端时间决定取消是否成功,不能出现既恢复又删除的结果。
- 对同一已取消申请的重试,不重复改变状态或产生副作用。若凭证仍有效,可返回原取消结果和有效登录上下文;若凭证已撤销或过期,重新登录确认状态,不要求用户再次取消。
- 到期、`processing`、`completed` 均拒绝恢复,返回可识别错误;不得重新启用旧 Token。
## 4. 登录、会话与多端配合
### 4.1 调整现有 `/api/app/v9/login`
保留现有手机号密码登录参数。必须先完成密码/验证码等身份验证,再返回该主账号的注销状态,避免泄露任意手机号是否注册或注销。
| 状态 | 登录接口行为 |
| --- | --- |
| `none` / `canceled` | 沿用当前 `token`、`scenic_users`、`store_users`;可附带最新注销状态 |
| 未到期的 `pending` | 不签发正常账号选择或业务 Token;返回申请信息和恢复专用 Token,等待用户决定 |
| `processing` / `completed` | 返回明确的不可登录、不可恢复业务错误,不签发可登录凭证 |
待注销登录建议使用成功 Envelope 承载“验证身份成功但尚未登录”的结果:
```json
{
"code": 100000,
"msg": "success",
"data": {
"token": "",
"scenic_users": [],
"store_users": [],
"account_deletion": {
"state": "pending",
"request_id": "deletion_example_001",
"submitted_at": "2026-08-27T08:02:00Z",
"scheduled_deletion_at": "2026-09-03T08:02:00Z",
"server_time": "2026-08-28T01:00:00Z",
"can_cancel": true
},
"recovery_token": "opaque-recovery-token",
"recovery_token_expires_at": "2026-08-28T01:10:00Z"
}
}
```
恢复专用 Token 要求:
- 短时有效,并绑定主账号、当前注销申请和允许的操作;示例有效期为 10 分钟,实际由后端配置。
- **仅可查询注销状态和取消该申请**,不能调用 `/v9/set-user`、订单、钱包、文件下载等业务接口,也不能兑换或刷新成业务 Token。
- 不能通过改请求参数变成其他用户的凭证;不记录到普通日志、埋点或 URL。
- 用户选择“暂不登录”只结束本次登录,不调用取消接口;重新登录或查询本身不得自动恢复账号。
- 取消完成后撤销该申请的恢复操作权限;新登录凭证按取消接口约定返回。
### 4.2 修改 `/api/app/v9/set-user` 和统一鉴权
- 无论客户端是否接入新功能,待注销及不可恢复账号都不能通过旧临时 Token、刷新 Token、账号切换或其他登录入口继续使用业务。
- 校验“凭证属于谁、凭证可做什么、账号当前是什么状态”,不能只检查签名或过期时间。
- 提交注销需要覆盖同一主账号的全部设备和全部关联业务身份,不仅让提交申请的 iPhone 退出。
- Android 当前有 `/v9/login` 的密码和短信两种登录方式;所有方式执行相同的状态检查。iOS 短信登录入口目前仍待接入,不能因此遗漏后端约束。
- 冷静期取消后签发新凭证,不恢复旧凭证的有效性;业务身份列表以取消时的最新数据为准。
### 4.3 与客户端接入的关系
当前本地 `loginState`、`cancelDeletion` 是同步方法,接入网络后需改为异步;不能只替换 Mock 类名。
客户端还需扩展登录返回模型、恢复专用 Token 上下文、`processing` 状态、短信倒计时、阻断原因和核验快照处理。当前 Mock 使用登录输入框中的手机号取消注销,真实接口必须改用受验证的主账号/申请上下文,不能继续依赖可编辑输入值。
当前 Mock 申请 ID 使用 Swift `UUID`,资产枚举原始值包含 `cloudFiles`;本文建议接口使用字符串 ID 和 `cloud_files`。客户端需通过网络 DTO 显式映射,不能把本地 Mock 模型直接序列化后当作请求契约。
## 5. 服务端必须负责的后台处理
- 提交成功后持久保存申请,App 卸载、退出或长期离线都不影响到期处理。
- 冷静期内不执行不可逆清理;到期后先禁止恢复,再按最终确认的规则解除身份、处理个人资产和第三方关联。
- 共享资产、资金账务、交易记录、客户已购买内容等分别制定处理方案;需要保留的记录与可删除的个人数据应区分,保留范围及周期由相关负责人确认。
- 处理任务可重复执行且有重试机制;只有约定的必需处理步骤完成后才标记 `completed`,部分失败不能假报成功。
- 保留可审计的申请、确认说明版本、时间、取消记录、处理进度及失败原因;审计中不保留明文验证码或 Token。
- 到期删除与取消操作必须有统一的并发保护;业务鉴权和后台任务读取一致的主账号状态。
- 需要测试环境的可控时间或缩短冷静期能力,以便验证到期边界及失败重试;不得在生产开放客户端任意修改截止时间的接口。
## 6. 错误返回要求
沿用整数 `code` 和可直接展示的中文 `msg`。以下名称是**待后端分配业务码的语义清单**,不是现有错误码。
| 错误语义 | 典型场景 | 客户端处理 |
| --- | --- | --- |
| `ACCOUNT_IDENTITY_REQUIRED` | 主账号没有可用于验证的绑定手机号 | 提示先处理账号信息 |
| `DELETION_BLOCKED` | 资金未结清、订单未完成、负责人未移交等 | 展示阻断原因,禁止提交 |
| `PRECHECK_EXPIRED` / `PRECHECK_CHANGED` | 快照过期、资产或说明版本发生变化 | 重新核验并要求再次确认 |
| `ACKNOWLEDGEMENT_REQUIRED` | 缺少必需资产确认或确认版本不匹配 | 返回资产核验页 |
| `SMS_SEND_FAILED` / `SMS_RATE_LIMITED` | 短信发送失败或限流 | 提示重试;限流返回重试秒数 |
| `SMS_CODE_INVALID` / `SMS_CODE_EXPIRED` / `SMS_ATTEMPTS_EXCEEDED` | 验证码错误、过期、尝试超限 | 提示重输或重新发送 |
| `DELETION_ALREADY_PENDING` | 已有有效申请 | 查询原申请,不重复创建 |
| `NO_PENDING_DELETION` | 申请不存在或并非当前可取消申请 | 查询最新状态 |
| `DELETION_NOT_CANCELABLE` | 已到截止时间或正在最终处理 | 不再提供恢复入口 |
| `ACCOUNT_DELETION_COMPLETED` | 已完成注销 | 禁止登录和恢复 |
| `RECOVERY_TOKEN_INVALID` / `RECOVERY_TOKEN_EXPIRED` | 恢复凭证失效 | 重新验证身份,不自动取消 |
| `IDEMPOTENCY_CONFLICT` | 同一幂等键用于不同请求内容 | 停止自动重试,提示重新操作 |
错误响应继续采用现有 Envelope。后端如需在 `data` 中返回 `blocking_reasons`、`retry_after` 等结构化详情,需同时给出字段契约;当前 iOS `APIClient` 对失败响应只暴露 `code/msg`,接入时需要补充详情解析。
**与现有全局登录失效处理区分:** 当前 iOS 会将 HTTP `401/403` 及业务码 `180024`、`100091`、`100090`、`100060` 视为登录失效。资产阻断、验证码错误、快照过期等业务问题不要复用这些码,避免误触发全局退出。真实凭证失效仍沿用项目鉴权规则。
## 7. 联调验收清单
1. 主账号关联多个景区、门店时,核验范围完整;切换业务身份不会变成另一个注销对象;不能查询、提交或取消其他主账号的申请。
2. 无手机号、无资产、存在余额/冻结款/未完成业务时,分别返回约定的正常或阻断结果。
3. 正确验证码可提交;错误、过期、重发前旧码、其他用途码、其他账号验证码都不可提交。
4. 资产确认不完整、核验过期、资产发生变化、说明版本不一致时,后端拒绝并要求重新确认。
5. 成功申请返回准确截止时间;重复请求不产生新申请、不重置冷静期;请求超时后可重新验证身份并查到真实结果。
6. 提交成功后所有设备及旧版本业务访问受限;旧 Token、账号选择、短信登录等不能绕过注销状态。
7. 冷静期登录只显示恢复确认;点“暂不登录”保持待注销,点“恢复账号并登录”后取消并取得新的账号选择凭证。
8. 恢复专用 Token 只能查询状态和取消绑定申请;不能访问业务或取消其他申请。
9. 截止前可取消、恰好截止不可取消;取消与到期任务并发时只产生一个一致结果。
10. 未运行 App 也会按期处理;任务部分失败会重试,处理期间保持不可恢复,未完成时不返回 `completed`。
11. 已取消账号可再次发起新申请;旧申请和旧恢复凭证不能影响新申请。
12. 完成注销后不能登录或恢复;共享数据、客户内容和需保留记录按确认的方案处理,没有越权删除。
## 8. 请后端与产品确认并回传
- **账号及数据边界:** 主账号映射、关联身份范围;作品与相册/项目的统计口径;共享资产和已售内容的处理方式。
- **准入规则:** 余额是否允许放弃;冻结资金、提现中、未完成订单、线下未补缴款及负责人身份是否阻断,如何解除阻断。
- **时限和最终处理:** 七天是否按 168 小时计算;到期处理内容、记录保留范围与周期;注销后同手机号能否重新注册,且不得恢复旧账号数据。
- **接口契约:** 最终路径、字段类型、完整正常/异常响应、业务码、短信频控、恢复凭证权限及有效期。
- **联调交付:** 测试环境地址、测试账号及各状态样例、到期和失败重试验证方式、预计可联调时间。
上述规则确认前,客户端中的“永久删除”“放弃资产”等 Mock 文案不能直接作为最终业务承诺,应随实际后端处理规则调整。