# API 契约：商家门店分管账号

所有商家端接口使用 `token` 请求头；平台接口使用现有若依后台认证和权限注解。业务错误沿用 `AjaxResult` 与国际化消息。

## 商家端分管账号接口

基础路径：`/merchant/subaccounts`

### `GET /merchant/subaccounts`

仅主账号可调用。返回所属分管账号及授权店铺。

```json
{
  "code": 200,
  "data": [
    {
      "userId": 501,
      "name": "张三",
      "phone": "+886900000001",
      "ownerEnabled": true,
      "platformEnabled": true,
      "online": true,
      "lastLoginAt": "2026-08-28T10:30:00",
      "stores": [
        { "storeId": 101, "storeName": "店铺 A" },
        { "storeId": 102, "storeName": "店铺 B" }
      ]
    }
  ]
}
```

### `POST /merchant/subaccounts`

仅主账号可调用。

```json
{
  "phone": "+886900000001",
  "name": "张三",
  "password": "前端RSA加密值",
  "storeIds": [101, 102]
}
```

规则：手机号和登录名使用规范化后的同一手机号；手机号全局唯一；`storeIds` 非空且全部属于当前主账号；账号创建和授权写入同一事务；不创建钱包。

### `PUT /merchant/subaccounts/{subaccountUserId}`

仅所属主账号可调用，用于修改姓名和授权店铺。

```json
{
  "name": "张三",
  "storeIds": [102, 103]
}
```

### `PUT /merchant/subaccounts/{subaccountUserId}/password`

仅所属主账号可调用。

```json
{ "password": "前端RSA加密值" }
```

成功后撤销该分管账号现有商家 App/PC 会话，要求重新登录。

### `PUT /merchant/subaccounts/{subaccountUserId}/status`

仅所属主账号可调用，只修改主账号控制状态。

```json
{ "enabled": false }
```

停用时立即撤销该账号商家 App/PC 会话；启用不能覆盖平台停用状态。

## 平台端分管账号接口

基础路径：`/infouser/merchant-subaccounts`

### `GET /infouser/merchant-subaccounts?merchantUserId={id}`

需要 `infouser:user:list`。`merchantUserId` 必须对应类型 1 主账号。响应结构与商家端列表一致，不返回密码、CID、Token 或商户敏感资料。

### `PUT /infouser/merchant-subaccounts/{subaccountUserId}/platform-status`

需要 `infouser:user:edit`。

```json
{ "enabled": false }
```

只修改平台控制状态。停用时撤销会话；恢复后如果主账号控制状态仍为停用，账号仍不可用。

平台不提供新增、密码重置或店铺授权修改接口。

## 登录与退出

### `POST /infouser/user/shanglodeing`

现有接口扩展：允许 `user_type=5`。签发 Token 前校验平台状态、主账号控制状态和所属主账号状态；成功后更新 CID 与 `lastLoginAt`。类型 5 不执行商家资料审核或钱包逻辑。

### `POST /infouser/user/merchantLogout`

请求头：`token`。删除当前 JWT 对应 Redis 会话。前端在清除本地 token 前调用；删除失败不返回 Token 内容。

## 店铺权限契约

以下有效商家端能力必须统一使用登录身份和实际门店归属校验：

| 能力 | 主账号 | 分管账号 |
|---|---|---|
| 店铺列表 | 全部自有店铺 | 全部授权店铺 |
| 店铺详情、基础资料、营业状态、营业时间 | 自有店铺 | 授权店铺 |
| 新增、删除店铺 | 允许 | 拒绝 |
| 商品、分类、规格查询与维护 | 自有店铺 | 授权店铺 |
| 订单列表、详情、商家状态操作、退款 | 自有店铺 | 授权店铺 |
| 分管账号管理 | 允许 | 拒绝 |
| 收款配置、提现、结算、跨店财务 | 允许 | 拒绝 |

所有写接口不得使用请求体中的 `userId`、`shId` 作为授权依据；订单、商品等先按 ID 查询实际 `mdId` 再校验。

## 通知路由契约

内部服务接口：

```java
void sendStoreNotification(
    Long storeId,
    Long ownerUserId,
    String titleKey,
    String contentKey,
    String body,
    String orderNo
);
```

返回值不影响原订单事务。每个选中账号先生成自己的 `push_message`，再尝试外部推送；单个账号失败只记录日志。店铺无法解析时只向 `ownerUserId` 兜底。
