Files
Neo-ZQYY/docs/database/zqyy_app_admin_web_tables.md

145 lines
5.8 KiB
Markdown
Raw 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.
# zqyy_app — Web 管理后台表结构文档
## 变更说明
`zqyy_app` 数据库中新增 4 张表,支撑 Web 管理后台的用户认证、任务队列、执行日志和定时调度功能。
| 操作 | 表名 | 说明 |
|------|------|------|
| 新增 | admin_users | 管理后台操作员账户,绑定门店 site_id |
| 新增 | task_queue | ETL 任务执行队列,支持排序和状态流转 |
| 新增 | task_execution_log | 任务执行历史记录,含日志和摘要 |
| 新增 | scheduled_tasks | 定时调度任务,支持 5 种调度类型 |
### 新增字段概览
#### admin_users
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | SERIAL | PK | 自增主键 |
| username | VARCHAR(64) | UNIQUE NOT NULL | 登录用户名 |
| password_hash | VARCHAR(256) | NOT NULL | bcrypt 密码哈希 |
| display_name | VARCHAR(128) | | 显示名称 |
| site_id | BIGINT | NOT NULL | 绑定的门店 ID |
| is_active | BOOLEAN | DEFAULT TRUE | 是否启用 |
| created_at | TIMESTAMPTZ | DEFAULT NOW() | 创建时间 |
| updated_at | TIMESTAMPTZ | DEFAULT NOW() | 更新时间 |
#### task_queue
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | UUID | PK, DEFAULT gen_random_uuid() | 队列任务 ID |
| site_id | BIGINT | NOT NULL | 门店隔离 |
| config | JSONB | NOT NULL | 序列化的 TaskConfig |
| status | VARCHAR(20) | NOT NULL, DEFAULT 'pending' | pending/running/success/failed/cancelled |
| position | INTEGER | NOT NULL, DEFAULT 0 | 队列排序位置 |
| created_at | TIMESTAMPTZ | DEFAULT NOW() | 创建时间 |
| started_at | TIMESTAMPTZ | | 开始执行时间 |
| finished_at | TIMESTAMPTZ | | 执行完成时间 |
| exit_code | INTEGER | | 子进程退出码 |
| error_message | TEXT | | 错误信息 |
#### task_execution_log
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | UUID | PK, DEFAULT gen_random_uuid() | 日志 ID |
| queue_id | UUID | FK → task_queue(id) | 关联的队列任务(可空) |
| site_id | BIGINT | NOT NULL | 门店隔离 |
| task_codes | TEXT[] | NOT NULL | 执行的任务编码列表 |
| status | VARCHAR(20) | NOT NULL | 执行状态 |
| started_at | TIMESTAMPTZ | NOT NULL | 开始时间 |
| finished_at | TIMESTAMPTZ | | 结束时间 |
| exit_code | INTEGER | | 退出码 |
| duration_ms | INTEGER | | 执行时长(毫秒) |
| command | TEXT | | 实际执行的 CLI 命令 |
| output_log | TEXT | | stdout 完整日志 |
| error_log | TEXT | | stderr 日志 |
| summary | JSONB | | 执行摘要 |
| created_at | TIMESTAMPTZ | DEFAULT NOW() | 记录创建时间 |
#### scheduled_tasks
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | UUID | PK, DEFAULT gen_random_uuid() | 调度任务 ID |
| site_id | BIGINT | NOT NULL | 门店隔离 |
| name | VARCHAR(256) | NOT NULL | 调度任务名称 |
| task_codes | TEXT[] | NOT NULL | 任务编码列表 |
| task_config | JSONB | NOT NULL | 序列化的 TaskConfig |
| schedule_config | JSONB | NOT NULL | 序列化的 ScheduleConfig |
| enabled | BOOLEAN | DEFAULT TRUE | 是否启用 |
| last_run_at | TIMESTAMPTZ | | 上次执行时间 |
| next_run_at | TIMESTAMPTZ | | 下次执行时间 |
| run_count | INTEGER | DEFAULT 0 | 累计执行次数 |
| last_status | VARCHAR(20) | | 上次执行状态 |
| created_at | TIMESTAMPTZ | DEFAULT NOW() | 创建时间 |
| updated_at | TIMESTAMPTZ | DEFAULT NOW() | 更新时间 |
### 索引
| 索引名 | 表 | 列 | 类型 | 说明 |
|--------|------|------|------|------|
| idx_admin_users_site | admin_users | site_id | B-tree | 按门店查询用户 |
| idx_task_queue_status | task_queue | status | B-tree | 按状态查询队列 |
| idx_task_queue_site_position | task_queue | site_id, position | 部分索引 (WHERE status='pending') | 取出待执行任务 |
| idx_execution_log_site_started | task_execution_log | site_id, started_at DESC | B-tree | 执行历史列表 |
| idx_scheduled_tasks_site | scheduled_tasks | site_id | B-tree | 按门店查询调度 |
| idx_scheduled_tasks_next_run | scheduled_tasks | next_run_at | 部分索引 (WHERE enabled=TRUE) | 查询到期调度 |
### 种子数据
- 默认管理员:`admin` / `admin123`site_id=1
- 种子脚本:`db/zqyy_app/seeds/admin_web_seed.sql`
## 兼容性
- **ETL Connector**:无影响。新表位于 `zqyy_app`ETL 数据仍在 `etl_feiqiu`
- **后端 API**:新增的 FastAPI 路由将读写这 4 张表,需配置 `zqyy_app` 数据库连接
- **小程序**:无影响。小程序通过 FDW 访问 ETL 数据,不涉及管理后台表
- **现有 zqyy_app 表**:无影响。新表与现有 users/roles/tasks 等表无外键关联
## 回滚策略
```sql
-- 按依赖顺序删除task_execution_log 引用 task_queue
BEGIN;
DROP TABLE IF EXISTS task_execution_log CASCADE;
DROP TABLE IF EXISTS task_queue CASCADE;
DROP TABLE IF EXISTS scheduled_tasks CASCADE;
DROP TABLE IF EXISTS admin_users CASCADE;
COMMIT;
```
## 验证 SQL
```sql
-- 1. 验证 4 张表均已创建
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name IN ('admin_users', 'task_queue', 'task_execution_log', 'scheduled_tasks')
ORDER BY table_name;
-- 2. 验证索引已创建(应返回 6 条)
SELECT indexname, tablename
FROM pg_indexes
WHERE tablename IN ('admin_users', 'task_queue', 'task_execution_log', 'scheduled_tasks')
AND indexname LIKE 'idx_%'
ORDER BY tablename, indexname;
-- 3. 验证默认管理员已插入
SELECT id, username, display_name, site_id, is_active
FROM admin_users
WHERE username = 'admin';
-- 4. 验证 task_queue 的部分索引条件
SELECT indexname, indexdef
FROM pg_indexes
WHERE indexname = 'idx_task_queue_site_position';
-- 5. 验证 task_execution_log 的外键约束
SELECT conname, conrelid::regclass, confrelid::regclass
FROM pg_constraint
WHERE conrelid = 'task_execution_log'::regclass
AND contype = 'f';
```