- New ARCHITECTURE.md (3-layer model + data flow + lifecycle matrix) - New PERMISSIONS.md (grant calculation rules + enforcement) - New ADMIN_GUIDE.md (華文极简:Customer/CustomerProduct 授权 + Product/Resource 管理) - Rewrite N8N_WORKFLOWS.md from WF1-6 (obsolete) to actual W1/W2/W3 - Update DATABASE_SCHEMA.md: fix status enum (drop 'disabled'), add 5-status semantics - Update README.md doc index
94 lines
3.7 KiB
Markdown
94 lines
3.7 KiB
Markdown
# 管理员操作指南(ADMIN_GUIDE)
|
||
|
||
> 极简版。只讲你在 NocoDB 里怎么点,不讲技术细节。
|
||
|
||
---
|
||
|
||
## 第一部分:给顾客授权(Customers + CustomerProducts)
|
||
|
||
### 目标
|
||
让一个顾客能登录 AList,看到他买的产品对应的文件夹,并在他到期时自动失效。
|
||
|
||
### 步骤
|
||
|
||
**第 1 步 — 建顾客(Customers 表)**
|
||
|
||
1. 打开 NocoDB 的 `AlistAccess` → `Customers` 表,点「+新记录」。
|
||
2. 填这两个字段(其余先留空):
|
||
- `username`:顾客登录 AList 的账号(唯一,别重复)
|
||
- `password`:顾客的密码
|
||
3. `status` 先选 **`active`**。
|
||
|
||
> **期待值**:保存后几秒,n8n 会自动在 AList 建好这个顾客的账号 + 专属角色,
|
||
> 并回填 `alist_user_id`、`alist_role_id`,`sync_status` 变成 `synced`。
|
||
> 此时顾客还看不到任何文件夹(还没买产品,权限为空)。
|
||
|
||
**第 2 步 — 给顾客挂产品(CustomerProducts 表)**
|
||
|
||
1. 打开 `CustomerProducts` 表,点「+新记录」。
|
||
2. 填:
|
||
- `customer`:选刚才那个顾客
|
||
- `product`:选一个产品(比如「Test Product」)
|
||
- `start_at`:开始日期
|
||
- `expires_at`:到期日期(**到期当天就失效**,要含当天请往后多填一天)
|
||
- `status`:选 **`active`**
|
||
|
||
> **期待值**:保存后,n8n 会算出这个产品包含的文件夹路径,写进该顾客的 AList 权限。
|
||
> 顾客登录后就能看到对应文件夹。`expires_at` 一过,权限自动移除。
|
||
|
||
**第 3 步 — 验证**
|
||
|
||
- 用顾客的 `username` / `password` 登录 AList 前端,确认只看到该产品对应的文件夹。
|
||
- 想看整体权限是否同步正确:该顾客记录的 `sync_status` 应为 `synced`。
|
||
|
||
---
|
||
|
||
## 第二部分:管理产品(Products + Resources)
|
||
|
||
### 目标
|
||
定义「产品」是什么,每个产品对应哪些文件夹,好让第一部分能直接选用。
|
||
|
||
### 概念对应
|
||
|
||
| NocoDB 表 | 是什么 | 例子 |
|
||
|---|---|---|
|
||
| `Resources` | 一个真实文件夹路径 | `alist_path = /Class/Forex` |
|
||
| `Products` | 一个可售产品 = 打包若干 Resources | 「Python 全套」含 `/Class/Python/01`、`/Class/Python/02` |
|
||
|
||
### 步骤
|
||
|
||
**第 1 步 — 加资源(Resources 表)**
|
||
|
||
1. 打开 `Resources` 表,点「+新记录」。
|
||
2. 填:
|
||
- `name`:给人看的名字(如「Forex 课程」)
|
||
- `alist_path`:AList 里的**绝对路径**(如 `/Class/Forex`,必须以 `/` 开头)
|
||
|
||
> **期待值**:这个资源能被产品引用。路径必须真实存在于 AList 的挂载里,否则顾客会 403。
|
||
|
||
**第 2 步 — 建产品(Products 表)**
|
||
|
||
1. 打开 `Products` 表,点「+新记录」。
|
||
2. 填:
|
||
- `name`:产品名(如「Python Basic」)
|
||
- `status`:选 **`active`**
|
||
3. 在 `Resources` 这一列(关联列)里,勾选这个产品**包含**的资源(一个产品可勾多个)。
|
||
|
||
> **期待值**:第一部分给顾客挂这个产品时,n8n 会把产品里勾选的所有资源的路径
|
||
> 一次性算给顾客。
|
||
|
||
---
|
||
|
||
## 附:Customers.status 怎么配
|
||
|
||
| status | 含义 | 顾客能看到文件吗 | 何时用 |
|
||
|---|---|---|---|
|
||
| `pending` | 未正式开通 | ❌(且还没建账号)| 刚建顾客、还没决定卖什么时 |
|
||
| `active` | 正常 | ✅(按已买产品)| 客户正在使用中 |
|
||
| `suspended` | 管理员封禁 | ❌ | 暂时停权(欠费/风控)|
|
||
| `expired` | 整户期满 | ❌ | 客户整体服务结束 |
|
||
| `deleted` | 软删除 | ❌(账号保留)| 停用但保留历史记录 |
|
||
|
||
- 只要是非 `active`,顾客就登不进去、也看不到文件。
|
||
- 改回 `active`,会自动按**当前还有效**的产品重新算权限(已过期的不会回来)。
|