# 夜市摊位功能需求

## 用户类型

| 类型值 | 角色 | 说明 |
|--------|------|------|
| 3 | 夜市用户 | 可创建多个摊位，可为摊位创建摊位主 |
| 4 | 摊位主 | 由夜市用户创建，管理对应摊位 |

## 数据模型变更

### PosStore 表（摊位即店铺）

- 新增字段 `isStall`（tinyint）：0=店铺，1=摊位
- `userId` 字段：存夜市用户（type=3）的 ID，标识摊位归属

### InfoUser 表

- 新增字段 `storeId`（bigint）：仅摊位主（type=4）使用，指向 PosStore 的摊位 ID，标识该摊位主属于哪个摊位

## 关系说明

```
夜市用户(type=3) --1:N--> PosStore(isStall=1) 摊位
摊位 PosStore --1:N--> 摊位主 InfoUser(type=4, storeId=摊位ID)
```

- PosStore.userId = 夜市用户ID（摊位属于哪个夜市用户）
- InfoUser.storeId = 摊位ID（摊位主属于哪个摊位）

## 相关路径

- 商家前端页面：`E:\QtwCode\foodie\foodie-store`

## 权限设计

### 摊位主（userType=4）— 受限权限

可做日常经营操作：
- 上下架商品
- 接单/处理订单
- 查看自己摊位的订单和营收

不可做结构性操作：
- 删除/修改摊位基本信息
- 创建其他摊位主
- 管理摊位级别的设置

### 夜市用户（userType=3）— 只读 + 管理权

- 可查看所有摊位的数据（订单、营收）
- 可管理摊位主账号（创建、启用、禁用、删除）
- 不直接操作摊位内容（不加商品、不接单）
- 职责划分：夜市用户管"人"，摊位主管"事"

## 商家前端功能

### 新增菜单：摊位管理

夜市用户登录商家端后，在侧边栏新增「摊位管理」菜单目录，包含以下功能：

1. **摊位列表**：展示当前夜市用户创建的所有摊位（PosStore where isStall=1）
2. **创建摊位**：新建摊位（复用现有店铺创建流程，isStall 自动设为 1）
3. **分配账号**：创建摊位后，可为该摊位创建/分配摊位主账号（userType=4，storeId=摊位ID）
4. **摊位主管理**：查看和管理每个摊位下的摊位主账号

### 操作流程

```
夜市用户登录商家端 → 摊位管理 → 创建摊位 → 为摊位分配摊位主账号
```

## 后端接口

已实现（StallController）：
- GET /stall/list — 获取当前夜市用户的摊位列表
- POST /stall/add — 创建摊位（复用 PosStore，isStall=1）
- POST /stall/addOwner — 为摊位创建摊位主账号
- GET /stall/owners — 获取摊位下的摊位主列表
- PUT /stall/disableOwner — 禁用摊位主
- PUT /stall/enableOwner — 启用摊位主
- DELETE /stall/deleteOwner — 删除摊位主

复用现有商家接口（addmendian 等）用于摊位内容管理。

## 摊位钱包设计

### 背景

现有 `user_wallet` 表通过 `user_id` 关联用户，存放骑手/商家余额。摊位主可多人管理同一摊位，摊位收入进入一个共同的池子，因此钱包应关联到摊位而非个人。

### 数据模型变更

#### UserWallet 表

- 新增字段 `storeId`（bigint, default null）：关联摊位 ID，非摊位钱包为 NULL

| 场景 | user_id | store_id | 说明 |
|------|---------|----------|------|
| 普通用户/骑手钱包 | 用户 ID | NULL | 不变 |
| 摊位钱包 | NULL | 摊位 ID | 摊位共用一个钱包 |

### 关系说明

```
摊位 PosStore --1:1--> UserWallet(storeId=摊位ID) 摊位钱包
摊位 PosStore --1:N--> 摊位主 InfoUser(type=4)
摊位主 InfoUser --通过权限--> 可操作对应摊位的钱包
```

- 一个摊位只有一个钱包，收入统一进入该钱包
- 多个摊位主共享同一个摊位钱包，通过 `info_user` 表判断权限（`store_id = 摊位ID AND user_type = '4' AND status = '正常'`）
- 摊位主变更（新增/删除/禁用）不影响钱包余额

### 查询逻辑

- 查用户钱包：`WHERE user_id = ? AND store_id IS NULL`
- 查摊位钱包：`WHERE store_id = ?`
- 判断摊位主是否有权限操作：查 `info_user` 表（`store_id = ? AND user_type = '4' AND status = '0'`）

### 钱包创建时机

创建摊位时自动创建对应的摊位钱包（`store_id = 摊位ID`）。

## PosStore 软删除

### 背景

现有 pos_store 删除为物理删除（`DELETE FROM pos_store`），会导致关联数据（摊位主、钱包、商品等）变成孤儿数据。改为软删除，删除时标记而非物理移除。

### 数据模型变更

#### PosStore 表

- 新增字段 `del_flag`（char(1), default '0'）：0=存在，1=删除

### 删除逻辑

- 所有店铺和摊位的删除操作改为 `UPDATE pos_store SET del_flag = '1' WHERE id = ?`
- 所有查询 pos_store 的 SQL 加上 `del_flag = '0'` 条件，过滤已删除记录
- 删除摊位时需级联处理：标记摊位为删除状态，关联的摊位主、钱包保留（数据不丢失）

### 变更影响范围

- PosStore.java：新增 delFlag 字段
- PosStoreMapper.xml：resultMap、select、insert、update、delete 改造
- PosStoreServiceImpl.java：delete 方法改为 update del_flag
- PosStoreController.java：删除接口逻辑调整
- 所有通过 selectPosStoreList 查询的地方自动受影响

## 普通商家新增门店审核门禁（2026-08-24）

### 业务规则

- `POST /chanting/store/addmendian` 创建新门店时，后端必须根据请求头 `token` 识别当前登录商家。
- 只有 `InfoUser.auditStatus = "1"`（已审核）的商家可以新增门店；未审核、用户资料不存在时沿用现有国际化业务错误。
- 新门店的 `PosStore.userId` 必须由后端写为当前登录用户 ID，不信任请求体中的 `userId`。
- 请求体携带门店 `id` 时视为编辑已有门店，本次变更不增加商家审核状态门禁，保持现有编辑行为。
- 本次仅调整普通商家门店入口，不扩展到平台后台建店或夜市摊位入口。

### 验收场景

1. 未审核商家提交新增门店请求时，接口返回 `no.user.state.no.audit` 对应语言的业务错误，且不保存门店。
2. 已审核商家提交新增门店请求时，门店可以保存，保存的 `userId` 等于 token 中的用户 ID，即使请求体传入其他用户 ID 也不能改变归属。
3. 编辑已有门店时不调用新增门店审核校验，保持现有流程。
