# 配件查询系统 - 数据库设计文档(辅助配置表) **版本**: 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 | 是否VIP(1是 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_price(VIP价格) | 字段 | 类型 | 空值 | 默认值 | 说明 | |------|------|------|--------|------| | price | DECIMAL(10,2) | NO | | 单月价格(元) | **索引**:无 **说明**: - 全局配置表,仅一条记录 - 表示平台统一VIP单月价格 - 管理端可读取和修改 --- ### 1.3 vip_recharges(VIP充值记录) | 字段 | 类型 | 空值 | 默认值 | 说明 | |------|------|------|--------|------| | 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 | | 店铺ID(0=全局) | | 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默认值 - 新增表需评估是否属于核心业务表或辅助表,放入对应文档