文档目录
用户等级表

简介

本文件面向DouPHP会员系统的开发者与运营人员,聚焦“用户等级体系”的数据模型与业务实现,围绕 dou_user_level(用户等级表)与 dou_user_level_log(等级升级日志表)展开,说明等级名称、升级条件、等级折扣等配置项,解释自动升级规则、日志记录、以及等级与权限/特权(如商品折扣)的关联方式。文档同时给出升级流程、数据一致性与性能建议,便于在二次开发与运维中参考。

项目结构与范围

  • 数据库定义与演进脚本位于模块更新与开发手册中,包含等级表、日志表的创建与时间字段统一迁移。
  • 后台管理入口通过控制器与服务层完成等级列表、新增、编辑、删除与日志查看。
  • 运行时升级逻辑由核心服务负责,结合用户消费/推广累计值进行自动升级并写日志。
  • 前端展示通过查询当前等级与下一档目标计算成长进度。
graph TB
A["后台界面<br/>等级管理"] --> B["LevelController<br/>路由与视图"]
B --> C["LevelService / LevelFormRequest<br/>校验与组装"]
C --> D["UserLevel Model<br/>白名单与基础查询"]
D --> E["数据库: dou_user_level"]
B --> F["UserLevelService<br/>checkLevelUpgrade()"]
F --> G["数据库: dou_user_level_log"]
H["订单/统计服务"] --> F
I["UserProfileQuery<br/>currentLevel()/levelName()"] --> J["页面展示<br/>等级名称/折扣"]

核心数据模型

  • 用户等级表(dou_user_level)
    • 主键:id(或 level_id,随版本迁移差异存在)
    • 名称:name
    • 升级类型:upgrade_type(noauto/shopping/promote)
    • 升级条件:upgrade_condition(数值阈值)
    • 等级特权:good_discount(商品折扣)
    • 图标:icon
    • 时间:created_at(经迁移后统一为datetime)
  • 等级升级日志表(dou_user_level_log)
    • 自增ID:id
    • 用户ID:user_id
    • 旧等级ID:old_level_id
    • 新等级ID:new_level_id
    • 升级类型:upgrade_type
    • 触发条件值:condition_value
    • 触发订单号:order_sn
    • 时间:created_at(经迁移后统一为datetime,并建索引)

说明

  • 历史SQL中存在 level_id 作为主键的定义;后续备份与迁移脚本将主键改为 id,并将时间字段从 create_time/add_time 统一为 created_at。
  • 升级类型支持:
    • noauto:不自动升级,需人工调整
    • shopping:按累计消费金额达到阈值升级
    • promote:按累计推广金额达到阈值升级

架构总览

用户等级体系由“配置表 + 日志表 + 服务层 + 展示层”构成:

  • 配置表:dou_user_level 定义等级、升级条件与特权
  • 日志表:dou_user_level_log 记录每次升级事件
  • 服务层:UserLevelService 负责读取用户累计值、判断是否满足升级条件、原子更新用户等级并写日志
  • 展示层:UserProfileQuery 提供当前等级名称与折扣,用于前台展示与权限判定
sequenceDiagram
participant 订单流 as "订单/统计"
participant 服务 as "UserLevelService"
participant 用户 as "用户(user)"
participant 等级 as "等级(user_level)"
participant 日志 as "日志(user_level_log)"
订单流->>服务 : checkLevelUpgrade(userId, orderSn)
服务->>用户 : 加锁读取当前level_id
服务->>等级 : 读取全部等级(升序)
服务->>服务 : 计算累计消费/推广
alt 满足下一档条件
服务->>用户 : 更新level_id为新等级
服务->>日志 : 写入升级记录
服务-->>订单流 : 返回升级成功
else 未满足
服务-->>订单流 : 返回无升级
end

详细组件分析

用户等级表(dou_user_level)字段与含义

  • id/level_id:等级标识(不同版本主键名可能不同,但语义一致)
  • name:等级名称,用于展示与识别
  • upgrade_type:升级策略
    • noauto:手动控制
    • shopping:按消费累计值升级
    • promote:按推广累计值升级
  • upgrade_condition:升级阈值(数值型)
  • good_discount:等级折扣(用于商品折扣特权)
  • icon:等级图标
  • created_at:创建时间(统一后的datetime)

使用要点

  • 等级顺序以 id 升序排列,升级时从当前等级之后开始匹配第一档满足条件的等级。
  • 若 upgrade_type=noauto,则跳过自动升级,仅允许后台人工调整。

等级升级日志表(dou_user_level_log)字段与用途

  • id:自增主键
  • user_id:发生升级的用户
  • old_level_id/new_level_id:升级前后等级
  • upgrade_type:升级类型(shopping/promote/noauto)
  • condition_value:触发升级的条件阈值
  • order_sn:触发升级的订单号(可选)
  • created_at:升级时间(统一后的datetime,带索引)

用途

  • 审计与追溯:记录每次自动升级的来源与依据
  • 运营看板:统计升级次数、来源、时间分布
  • 问题定位:核对升级是否符合预期阈值

升级规则与流程

  • 触发点:订单完成后调用 UserLevelService::checkLevelUpgrade
  • 关键步骤:
    • 锁定用户行,避免并发重复升级
    • 读取所有等级并按 id 升序
    • 计算用户累计消费/推广值
    • 从当前等级的下一档开始检查,遇到满足条件的等级即升级
    • 更新用户等级并写入日志
    • 事务提交或回滚保证一致性
flowchart TD
Start(["进入升级检查"]) --> Lock["锁定用户行"]
Lock --> ReadLevels["读取等级列表(升序)"]
ReadLevels --> Calc["计算累计消费/推广"]
Calc --> Loop{"遍历当前等级之后的档位"}
Loop --> |满足条件| Upgrade["更新用户等级并写日志"]
Loop --> |不满足| Next["继续下一档"]
Next --> Loop
Upgrade --> Commit["提交事务"]
Commit --> End(["结束"])

等级有效期与继承

  • 等级有效期:当前 dou_user_level 表未包含有效期字段;如需有效期能力,可在该表扩展 start_time/end_time 并在升级/过期流程中处理。
  • 等级继承:当前设计为“单等级”,用户仅有一个 level_id;不存在多等级叠加继承。若需要继承(如保留上一级部分权益),需在业务层增加额外字段与逻辑。

等级与权限/特权的关系

  • 商品折扣:通过等级 good_discount 字段体现,查询当前等级时一并返回,供定价与结算使用。
  • 等级名称:通过 UserProfileQuery 根据 level_id 获取名称,用于前端展示与权限提示。
  • 权限控制:当前代码中等级主要用于折扣与展示;若需更细粒度权限控制,可基于等级ID扩展权限矩阵或在业务层做判定。

后台管理与表单校验

  • 控制器:LevelController 负责列表、新增、编辑、删除与跳转
  • 表单请求:LevelFormRequest 对 name、upgrade_type、upgrade_condition、good_discount 进行校验
  • 模型:UserLevel 声明可批量写入字段白名单,并提供排序与名称查询方法

依赖关系分析

  • 控制器依赖服务层进行数据组装与持久化
  • 服务层依赖用户统计服务获取累计值,依赖数据库访问层执行事务操作
  • 展示层依赖 ProfileQuery 获取等级名称与折扣
  • 日志表与等级表共同支撑升级审计与回溯
graph LR
Ctl["LevelController"] --> Svc["UserLevelService"]
Svc --> DB1["dou_user_level"]
Svc --> DB2["dou_user_level_log"]
Svc --> Stats["用户统计服务"]
UI["前端/后台"] --> Prof["UserProfileQuery"]
Prof --> DB1

性能与一致性

  • 事务与锁:升级过程使用事务与行级锁,避免并发导致的重复升级或数据不一致
  • 索引优化:日志表对 user_id 与 created_at 建立索引,便于按用户与时间范围查询
  • 时间字段统一:通过迁移脚本将 create_time/add_time 统一为 created_at,提升可读性与查询一致性
  • 建议
    • 对高频升级场景,考虑缓存等级列表与用户累计值,减少频繁读库
    • 对日志表实施归档策略,避免大表影响查询性能
    • 对升级阈值与类型变更,配合灰度发布与监控告警

故障排查指南

  • 日志表缺失:若后台提示等级日志表不存在,请先执行数据库升级脚本
  • 升级未生效:检查 upgrade_type 是否为 noauto;确认累计消费/推广值是否达到阈值;查看日志表中是否有对应记录
  • 并发异常:确认升级流程是否被多次调用;检查事务是否正确提交/回滚
  • 时间显示异常:确认 created_at 是否已正确迁移;必要时重新执行时间字段统一脚本

结论

DouPHP 的用户等级体系以 dou_user_level 为核心配置表,配合 dou_user_level_log 实现可审计的自动升级机制。通过升级类型与阈值灵活配置,结合商品折扣等特权,形成完整的会员等级体系。建议在现有模型基础上按需扩展有效期与继承能力,并通过缓存与归档优化性能。

附录:字段与索引清单

  • dou_user_level
    • 字段:id/level_id、name、upgrade_type、upgrade_condition、good_discount、icon、created_at
    • 主键:id(或 level_id,视版本)
  • dou_user_level_log
    • 字段:id、user_id、old_level_id、new_level_id、upgrade_type、condition_value、order_sn、created_at
    • 索引:user_id、created_at
添加日期:2026-10-05