准备上传

This commit is contained in:
2025-10-08 19:15:20 +08:00
parent 0aa7d55a23
commit 0e14a5fa1c
193 changed files with 14697 additions and 2461 deletions

View File

@@ -0,0 +1,584 @@
# 配件查询系统 - 数据库设计文档(辅助配置表)
**版本**: 1.0
**更新时间**: 2025-10-01
**数据库**: MySQL 8.0
**字符集**: utf8mb4 / utf8mb4_0900_ai_ci
---
## 一、VIP会员体系
### 1.1 vip_users会员用户
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | NO | | 店铺ID |
| user_id | BIGINT UNSIGNED | NO | | 用户ID |
| is_vip | TINYINT(1) | NO | 1 | 是否VIP1是 0否 |
| status | TINYINT UNSIGNED | NO | 0 | 启用状态1启用 0停用 |
| expire_at | DATETIME | YES | NULL | 到期时间 |
| remark | VARCHAR(255) | YES | NULL | 备注/审核说明 |
| reviewer_id | BIGINT UNSIGNED | YES | NULL | 审核人 |
| reviewed_at | DATETIME | YES | NULL | 审核时间 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_vu_shop_user` (`shop_id`, `user_id`)
- KEY: `idx_vu_shop_status` (`shop_id`, `status`)
**外键**
- `fk_vu_shop`: `shop_id``shops(id)`
- `fk_vu_user`: `user_id``users(id)`
- `fk_vu_reviewer`: `reviewer_id``users(id)`
**说明**
- VIP状态判定`status=1 AND is_vip=1 AND (expire_at IS NULL OR expire_at >= NOW())`
- 非VIP用户数据可见性最近60天可配置
- VIP用户查看全部历史数据
---
### 1.2 vip_priceVIP价格
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| price | DECIMAL(10,2) | NO | | 单月价格(元) |
**索引**:无
**说明**
- 全局配置表,仅一条记录
- 表示平台统一VIP单月价格
- 管理端可读取和修改
---
### 1.3 vip_rechargesVIP充值记录
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | NO | | 店铺ID |
| user_id | BIGINT UNSIGNED | NO | | 用户ID |
| price | DECIMAL(10,2) | NO | | 本次充值价格(元) |
| duration_days | INT | NO | | 本次续期天数 |
| expire_from | DATETIME | YES | NULL | 生效前到期时间 |
| expire_to | DATETIME | NO | | 生效后到期时间 |
| channel | VARCHAR(32) | NO | 'oneclick' | 渠道oneclick/... |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_vr_shop` (`shop_id`)
- KEY: `idx_vr_user` (`user_id`)
**外键**
- `fk_vr_shop`: `shop_id``shops(id)`
- `fk_vr_user`: `user_id``users(id)`
**说明**记录每次VIP开通/续费的历史,支持对账和查询。
---
## 二、普通管理员体系
### 2.1 normal_admin_audits普通管理员审计
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | NO | | 店铺ID |
| user_id | BIGINT UNSIGNED | NO | | 用户ID |
| action | ENUM('apply','approve','reject','revoke','expire') | NO | | 操作类型 |
| remark | VARCHAR(255) | YES | NULL | 备注 |
| operator_admin_id | BIGINT UNSIGNED | YES | NULL | 平台管理员ID |
| previous_role | VARCHAR(32) | YES | NULL | 变更前角色 |
| new_role | VARCHAR(32) | YES | NULL | 变更后角色 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_naudit_shop_time` (`shop_id`, `created_at`)
- KEY: `idx_naudit_user_time` (`user_id`, `created_at`)
**外键**
- `fk_naudit_shop`: `shop_id``shops(id)`
- `fk_naudit_user`: `user_id``users(id)`
- `fk_naudit_admin`: `operator_admin_id``admins(id)`
**说明**
- 普通管理员申请、审批、撤销的完整审计日志
- 当前状态 = 按user_id取最后一条记录的action
- VIP失效触发降级时写入expire审计
---
## 三、身份与认证
### 3.1 user_identities第三方身份映射
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | NO | | 店铺ID |
| user_id | BIGINT UNSIGNED | NO | | 用户ID |
| provider | ENUM('wechat_mp','wechat_app') | NO | | 身份提供方 |
| openid | VARCHAR(64) | NO | | 微信openid |
| unionid | VARCHAR(64) | YES | NULL | 微信unionid |
| nickname | VARCHAR(64) | YES | NULL | 昵称 |
| avatar_url | VARCHAR(512) | YES | NULL | 头像URL |
| last_login_at | DATETIME | YES | NULL | 最后登录时间 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_identity_user` (`user_id`)
- KEY: `idx_identity_shop` (`shop_id`)
- UNIQUE: `ux_identity_provider_openid` (`provider`, `openid`)
- UNIQUE: `ux_identity_unionid` (`unionid`)
**外键**
- `fk_identity_shop`: `shop_id``shops(id)`
- `fk_identity_user`: `user_id``users(id)`
**说明**
- 支持微信小程序和APP登录
- 短信登录使用users.phone作为全局唯一身份不创建identity记录
---
### 3.2 wechat_sessions微信会话
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| provider | ENUM('wechat_mp','wechat_app') | NO | | 提供方 |
| openid | VARCHAR(64) | NO | | 微信openid |
| session_key | VARCHAR(128) | NO | | 会话密钥 |
| expires_at | DATETIME | NO | | 过期时间 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_wechat_session_expires` (`expires_at`)
- UNIQUE: `ux_wechat_session` (`provider`, `openid`)
**说明**:临时存储微信会话密钥。
---
### 3.3 sms_codes短信验证码
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| phone | VARCHAR(32) | NO | | 手机号 |
| scene | VARCHAR(32) | NO | 'login' | 场景login/register/... |
| code_hash | CHAR(64) | NO | | 验证码哈希SHA-256 |
| salt | CHAR(32) | NO | | 加盐字符串 |
| expire_at | DATETIME | NO | | 过期时间 |
| status | TINYINT UNSIGNED | NO | 0 | 0=active 1=used 2=expired 3=blocked |
| fail_count | TINYINT UNSIGNED | NO | 0 | 错误次数 |
| ip | VARCHAR(45) | YES | NULL | 发送IP |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_phone_created_at` (`phone`, `created_at`)
- KEY: `idx_phone_scene_status` (`phone`, `scene`, `status`)
- KEY: `idx_expire_at` (`expire_at`)
- KEY: `idx_ip_created_at` (`ip`, `created_at`)
**说明**
- 验证码采用哈希+盐存储
- 支持多场景(登录、注册、重置密码等)
- 记录失败次数防止暴力破解
---
### 3.4 email_codes邮箱验证码
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| email | VARCHAR(128) | NO | | 邮箱 |
| scene | VARCHAR(32) | NO | | 场景login/register/reset |
| code_hash | VARCHAR(64) | NO | | 验证码哈希SHA-256 |
| salt | VARCHAR(64) | NO | | 加盐字符串 |
| expire_at | DATETIME | NO | | 过期时间 |
| status | TINYINT UNSIGNED | NO | 0 | 0=unused 1=used 2=expired |
| fail_count | INT | NO | 0 | 错误次数 |
| ip | VARCHAR(64) | YES | NULL | 发送IP |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_email_scene_created` (`email`, `scene`, `created_at`)
- KEY: `idx_email_expire` (`expire_at`)
**说明**与sms_codes类似用于邮箱验证场景。
---
## 四、咨询与公告
### 4.1 consults咨询
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | NO | | 所属店铺 |
| user_id | BIGINT UNSIGNED | NO | | 提问用户 |
| topic | VARCHAR(120) | NO | | 主题 |
| message | TEXT | NO | | 咨询内容 |
| status | ENUM('open','resolved','closed') | NO | 'open' | 状态 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_consult_shop_status` (`shop_id`, `status`)
- KEY: `fk_consult_user` (`user_id`)
**外键**
- `fk_consult_shop`: `shop_id``shops(id)`
- `fk_consult_user`: `user_id``users(id)`
**说明**
- open=未解决resolved=已解决closed=关闭
- 触发器有回复时自动标记为resolved
---
### 4.2 consult_replies咨询回复
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| consult_id | BIGINT UNSIGNED | NO | | 所属咨询 |
| user_id | BIGINT UNSIGNED | NO | | 回复人(管理员) |
| content | TEXT | NO | | 回复内容 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 回复时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_cr_consult` (`consult_id`)
- KEY: `fk_cr_user` (`user_id`)
**外键**
- `fk_cr_consult`: `consult_id``consults(id)`
- `fk_cr_user`: `user_id``users(id)`
**说明**:管理员对咨询的回复记录。
---
### 4.3 notices公告
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| title | VARCHAR(120) | NO | | 标题 |
| content | VARCHAR(500) | NO | | 内容(跑马灯) |
| tag | VARCHAR(32) | YES | NULL | 标签(如"活动" |
| is_pinned | TINYINT(1) | NO | 0 | 是否置顶 |
| starts_at | DATETIME | YES | NULL | 生效开始时间 |
| ends_at | DATETIME | YES | NULL | 生效结束时间 |
| status | ENUM('draft','published','offline') | NO | 'published' | 状态 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
| deleted_at | DATETIME | YES | NULL | 软删除标记 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_notices_time` (`starts_at`, `ends_at`)
**说明**
- 平台全局公告,与租户无关
- 前台仅显示status='published'且在有效期内的公告
- 排序is_pinned DESC, created_at DESC
---
## 五、系统配置
### 5.1 system_parameters系统参数
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | NO | | 店铺ID |
| user_id | BIGINT UNSIGNED | NO | | 创建/修改人 |
| key | VARCHAR(64) | NO | | 参数键 |
| value | JSON | NO | | 参数值JSON |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_sysparams_shop` (`shop_id`)
- UNIQUE: `ux_sysparams_shop_key` (`shop_id`, `key`)
**外键**
- `fk_sysparams_shop`: `shop_id``shops(id)`
- `fk_sysparams_user`: `user_id``users(id)`
**说明**
- 租户级配置支持JSON格式存储复杂配置
- 常用配置键:
- `vip.dataRetentionDaysForNonVip`: 非VIP数据保留天数默认60
- `normalAdmin.autoApprove`: 普通管理员自动审批默认false
- `normalAdmin.requiredVipActive`: 要求VIP有效默认true
---
### 5.2 finance_categories财务分类
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | NO | | 店铺ID0=全局) |
| type | ENUM('income','expense') | NO | | 收入/支出 |
| key | VARCHAR(64) | NO | | 分类key |
| label | VARCHAR(120) | NO | | 分类名称 |
| sort_order | INT | NO | 0 | 排序 |
| status | TINYINT UNSIGNED | NO | 1 | 1=启用 0=停用 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_fc_shop_type` (`shop_id`, `type`)
- UNIQUE: `ux_fc_shop_key` (`shop_id`, `key`)
**说明**
- 管理其他收入/支出的分类
- shop_id=0为平台默认分类
- 读取优先级finance_categories表 → system_parameters → application.properties
---
## 六、附件管理
### 6.1 attachments通用附件
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| shop_id | BIGINT UNSIGNED | YES | NULL | 店铺ID全局资源可空 |
| user_id | BIGINT UNSIGNED | YES | NULL | 上传人 |
| owner_type | VARCHAR(32) | NO | | 归属类型product/part_submission/... |
| owner_id | BIGINT UNSIGNED | NO | | 归属ID |
| url | VARCHAR(512) | NO | | 文件URL |
| hash | VARCHAR(64) | YES | NULL | 内容哈希SHA-256 |
| meta | JSON | YES | NULL | 元数据 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_attachments_owner` (`owner_type`, `owner_id`)
- UNIQUE: `ux_attachments_hash` (`hash`)
**外键**
- `fk_att_shop`: `shop_id``shops(id)`
- `fk_att_user`: `user_id``users(id)`
**说明**
- 通过hash实现文件去重
- 支持多种归属类型商品、配件提交、全局SKU等
- meta字段存储文件元信息大小、类型等
---
## 七、配件参数字典(扩展)
### 7.1 part_attribute_dictionary参数字典
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| attribute_name | VARCHAR(64) | NO | | 参数名称 |
| attribute_unit | VARCHAR(16) | YES | NULL | 单位 |
| attribute_type | ENUM('numeric','text','enum') | NO | 'text' | 类型 |
| enum_values | JSON | YES | NULL | 枚举值 |
| is_searchable | TINYINT(1) | NO | 1 | 是否可搜索 |
| sort_order | INT | NO | 0 | 排序 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- UNIQUE: `ux_pad_name` (`attribute_name`)
**说明**:全局参数字典,定义可用的配件参数。
---
### 7.2 part_categories配件分类
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| name | VARCHAR(64) | NO | | 分类名称 |
| parent_id | BIGINT UNSIGNED | YES | NULL | 父分类 |
| sort_order | INT | NO | 0 | 排序 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_pc_parent` (`parent_id`)
- UNIQUE: `ux_pc_name` (`name`)
**说明**:配件专用分类,支持层级结构。
---
### 7.3 part_category_attributes分类参数关联
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| category_id | BIGINT UNSIGNED | NO | | 分类ID |
| attribute_id | BIGINT UNSIGNED | NO | | 参数ID |
| is_required | TINYINT(1) | NO | 0 | 是否必填 |
| sort_order | INT | NO | 0 | 排序 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_pca_category` (`category_id`)
- UNIQUE: `ux_pca_cat_attr` (`category_id`, `attribute_id`)
**外键**
- `fk_pca_category`: `category_id``part_categories(id)` ON DELETE CASCADE
- `fk_pca_attribute`: `attribute_id``part_attribute_dictionary(id)` ON DELETE CASCADE
**说明**:定义每个配件分类应包含哪些参数。
---
### 7.4 part_attribute_templates参数模板
| 字段 | 类型 | 空值 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | BIGINT UNSIGNED | NO | AUTO_INCREMENT | 主键 |
| template_name | VARCHAR(64) | NO | | 模板名称 |
| category_id | BIGINT UNSIGNED | YES | NULL | 关联分类 |
| attributes | JSON | NO | | 参数定义JSON |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY: `id`
- KEY: `idx_pat_category` (`category_id`)
- UNIQUE: `ux_pat_name` (`template_name`)
**说明**:预定义的参数模板,快速应用到配件。
---
## 八、配置参数说明
### 8.1 VIP相关配置
| 配置键 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| vip.dataRetentionDaysForNonVip | number | 60 | 非VIP数据保留天数 |
| vip.price | number | 15 | VIP单月价格 |
| vip.durationDays | number | 30 | 开通时长(天) |
### 8.2 普通管理员配置
| 配置键 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| normalAdmin.autoApprove | boolean | false | 是否自动通过申请 |
| normalAdmin.requiredVipActive | boolean | true | 是否要求VIP有效 |
### 8.3 财务分类配置
**收入分类**income_categories
- operation_income: 经营所得
- interest_income: 利息收入
- other_income: 其它收入
- deposit_ar_income: 收订金/欠款
- investment_income: 投资收入
- sale_income: 销售收入
- account_operation: 账户操作
- fund_transfer_in: 资金转账转入
**支出分类**expense_categories
- operation_expense: 经营支出
- office_supplies: 办公用品
- rent: 房租
- interest_expense: 利息支出
- other_expense: 其它支出
- account_operation: 账户操作
- fund_transfer_out: 资金转账转出
---
## 九、数据安全与性能
### 9.1 敏感数据加密
- 密码SHA-256哈希存储password_hash
- 验证码SHA-256哈希+盐code_hash + salt
- 第三方token加密存储wechat_sessions.session_key
### 9.2 索引策略
- 高频查询字段shop_id, user_id, status, created_at
- 唯一性约束email, phone, openid, hash
- 复合索引:(shop_id, status), (user_id, created_at)
- 全文索引仅用于products.search_text
### 9.3 数据清理
**定期清理**
- sms_codes/email_codes清理7天前expired记录
- wechat_sessions清理过期会话
- inventory_movements归档6个月前数据可选
**软删除**
- 业务表采用deleted_at标记
- 查询默认过滤deleted_at IS NULL
- 定期归档软删除数据
---
## 十、扩展性设计
### 10.1 JSON字段应用
- products.attributes_json: 扩展商品属性
- part_submissions.attributes/images/tags: 灵活配件数据
- attachments.meta: 文件元信息
- system_parameters.value: 动态配置
### 10.2 ENUM类型管理
- 新增枚举值需要ALTER TABLE
- 重要状态采用ENUM确保数据一致性
- 次要分类采用VARCHAR + 配置表
### 10.3 多语言支持预留
- 公告内容可扩展为JSON{zh: "中文", en: "English"}
- 财务分类label可支持多语言
- 当前版本仅支持简体中文
---
**文档维护说明**
- 辅助表主要用于系统配置、认证、审计和扩展功能
- 任何结构变更必须同步更新本文档和`backend/db/db.sql`
- 配置参数变更需同时更新application.properties默认值
- 新增表需评估是否属于核心业务表或辅助表,放入对应文档