Skip to content

v0.0.3 用户管理与手机号脱敏 ​

版本信息 ​

项目内容
版本v0.0.3
定位新增核心用户管理模块,统一手机号脱敏能力,修复富文本全屏展示问题
发布日期2026-09-25

本版本在不改变既有接口行为的前提下,新增管理端「用户管理」核心模块(会员用户)、统一的手机号脱敏工具,并修复管理端富文本编辑器全屏后的层级错乱问题。

升级涉及一张新表和三条菜单,增量脚本可重复执行。

主要变更 ​

用户端(会员认证体系) ​

  • 会员认证接口全部切换到 sys_member 表(原 /api 接口错误地操作 sys_user,已移除重写):

    方法路由说明
    POST/api/sms/code发送短信验证码(1登录 2注册 3换绑手机号),独立于认证接口的通用能力
    POST/api/auth/register手机号+验证码注册,默认昵称/头像取用户端平台配置,注册后直接登录
    POST/api/auth/login_password账号密码登录,账号不存在时提示「账号不存在」
    POST/api/auth/login_sms手机号+验证码登录
    POST/api/auth/logout退出登录
    GET/api/auth/profile当前会员资料(手机号脱敏)
    POST/api/auth/profile/update修改昵称、姓名、头像
    POST/api/auth/account/update修改登录账号(4-32位字母数字下划线,全表唯一)
    POST/api/auth/password/update修改登录密码(至少6位且含字母和数字,已设密码时校验原密码,改后强制重新登录)
    POST/api/auth/mobile/update修改手机号(新手机号验证码校验,全表唯一)
  • 短信验证码限流(基于 Redis 计数实现):同一手机号同一场景每分钟最多 2 条;5 分钟内累计超过 5 条则禁止发送 30 分钟,并提示用户端「账号已被限制30分钟」;验证码 5 分钟有效、错误超过 5 次作废、校验成功一次性消费。所有发送行为(成功、渠道失败、被限流拦截)均写入短信发送记录,拦截请求的错误信息记录具体拦截原因,供管理端审计。

  • 用户编号(sn)由 pkg/sn 统一生成:固定小写前缀 cf + 8 位小写字母和数字(如 cfk3m9x2a),唯一索引兜底,冲突自动重试。

  • 用户端每个接口必须携带请求头:X-Platform-Source(平台来源 1-4,缺失或非法返回 400,注册时写入注册来源)、X-App-Version(客户端版本号,仅透传不做一致性校验)。

  • 登录令牌为单会话:JWT 携带会员ID、昵称、sn、头像与会话ID(login_id);重新登录后旧令牌失效;管理端禁用会员后令牌立即失效。

  • 新增 pkg/sms 短信发送封装(阿里云/腾讯云,标准库实现无新增依赖),验证码按短信配置(sys_sms_config/签名/验证码模板)发送,发送结果写入短信发送记录;新增 pkg/sn 业务编号生成封装。

  • 鉴权中间件支持客户端类型限定:管理端接口仅接受 admin 令牌,用户端接口仅接受 api 令牌,两类令牌不能互调。

后端 ​

  • 新增会员用户模型 internal/common/model/sys_member.go,表 sys_member 管理C端注册用户。

  • 新增枚举 internal/common/enums/member.go:

    • 性别 gender:1 男、2 女、3 未知;
    • 注册来源 register_source:1 微信小程序、2 微信公众号、3 iOS、4 Android。
  • 新增管理端接口(Auth → Permission → OperationLog 完整链路):

    方法路由用途
    GET/admin/member/list系统用户分页列表,支持关键字、账号状态、注册来源筛选
    POST/admin/member/set_status启用/禁用会员账号,同状态重复提交幂等返回成功
  • CheckTables 核心必需表清单加入 sys_member,缺表时服务拒绝启动并提示执行升级脚本。

  • 管理端禁用会员时同步删除其会话缓存,会员令牌立即失效;管理端系统用户列表增加「编号」(sn)展示并纳入关键字搜索。

  • 新增 pkg/mask 统一脱敏工具:

    • mask.Mobile:手机号保留前 3 位与后 4 位(138****8001);空串或纯空白返回空串;非 11 位原样返回;
    • mask.MobilePtr:可空指针版本,nil 返回空串;
    • 已接入:会员用户列表、短信发送记录、用户端个人资料三处展示;
    • 人员管理列表与个人设置保持原文返回:两处的编辑表单使用列表数据回填后提交,脱敏会把掩码串写回数据库,待修改接口支持「掩码值不更新」语义后再接入。
  • 系统版本号改为在 config.yaml 顶层 version 配置,作为版本号唯一来源,启动时校验必填(未配置时服务拒绝启动并给出明确提示):

    • 启动日志输出当前生效版本(如 管理端 API v0.0.3 启动: ...);
    • go run . version -c config.yaml 输出配置中的生效版本;
    • /admin/platform/public 与 /admin/platform/admin/detail 响应新增 version 字段,登录页底部与「系统配置 → 平台配置 → 管理端配置」展示该版本号。
  • 接口文档 docs/admin_openapi.yaml 同步新增「系统用户」标签、两个接口与 MemberItem / MemberListRes / MemberSetStatusReq 结构,并补充性别、注册来源通用枚举说明。

  • 配置模板 config.example.yaml 与 README 配置表同步新增 version 配置项。

数据库 ​

新增表 sys_member(会员用户表),基础字段与 sys_user 一致(id、created_at、updated_at、deleted_at),业务字段:

字段类型说明
snvarchar(32)用户编号,全局唯一(M+时间戳+随机数)
accountvarchar(32)登录账号,可空唯一索引,未设置为 NULL
login_idvarchar(64)当前登录会话ID,重新登录后旧会话失效,配合 Redis 实现禁用即失效
nicknamevarchar(32)昵称
real_namevarchar(32)姓名
accountvarchar(32)登录账号(普通索引)
mobilevarchar(16)手机号(唯一索引,业务必填)
passwordvarchar(128)登录密码 bcrypt 密文
avatarvarchar(512)头像相对路径
gendertinyint性别:1男,2女,3未知
agetinyint unsigned年龄
birthdaydate出生日期
register_ip / login_ipvarchar(64)注册IP / 最近登录IP
registered_at / logged_atdatetime(3)注册时间 / 最近登录时间
balancedecimal(12,2)账户余额(Go 侧字符串承载,禁用浮点)
register_sourcetinyint注册来源:1微信小程序,2微信公众号,3iOS,4Android
statustinyint账号状态:1启用,2禁用

新增菜单(脚本按 path / api_path 业务键判断,可重复执行,不指定自增ID):

text
用户管理(目录 /user,sort 5)
└── 系统用户(页面 /user/system,GET:/admin/member/list)
    └── 用户禁用(按钮,POST:/admin/member/set_status)

管理端 ​

  • 新增 src/api/member.ts、src/types/member.ts、src/enums/member.ts 与页面 src/views/user/system/index.vue(菜单路径 /user/system 对应动态路由)。
  • 系统用户列表展示:用户(头像+昵称+账号)、姓名、手机号(脱敏)、性别(男/女/未知三种 tag 颜色区分)、年龄、出生日期、账户余额、注册来源、账号状态、注册时间与注册IP两行展示、最近登录时间与登录IP两行展示。
  • 操作列提供启用/禁用按钮(v-perm 控制权限,二次确认后提交)。
  • 修复 RichTextEditor 全屏问题:wangeditor 官方全屏样式只设置 position:fixed 不带 z-index,会被顶栏(z-index:5)和 DOM 靠后的定位元素遮挡;现统一为 z-index:1000,高于布局层、低于 Element Plus 弹窗(2000+)与水印(9999),并去除全屏态的圆角边框。

升级前准备 ​

  1. 备份 MySQL 数据库。
  2. 备份当前后端二进制与管理端构建产物。
  3. 在 config.yaml 顶层增加 version: v0.0.3(本版本起版本号为必填配置,未配置时服务拒绝启动)。
  4. 确认已执行历史版本全部脚本(sql/v0.0.1/cf_backend_frame.sql、sql/v0.0.2/ 与 sql/v0.0.3/ 下增量脚本)。

数据库升级 ​

bash
mysql -uroot -p 数据库名 < sql/v0.0.3/member.sql

脚本包含建表与菜单写入,均可重复执行;重复执行不会产生重复菜单。执行后检查:

sql
SHOW CREATE TABLE sys_member;
SELECT id, name, type, path, api_path FROM sys_menu WHERE path LIKE '/user%' OR api_path LIKE '%member%';

推荐部署顺序 ​

  1. 停止旧版管理端 API。
  2. 备份数据库并执行 sql/v0.0.3/member.sql。
  3. 在生产 config.yaml 中增加 version: v0.0.3。
  4. 发布并启动新版管理端 API(用户端 API 如未变更可不发布,本版本用户端仅个人资料手机号脱敏一处变化)。
  5. 发布新版 admin_client 静态资源。
  6. 在「角色管理」为普通角色分配「用户管理」菜单及「用户禁用」按钮权限(超级管理员默认可见)。
  7. 冒烟验证系统用户列表、筛选、启用/禁用。

验证命令 ​

后端:

bash
gofmt -l .
go vet ./...
go build ./...
go test ./...

管理端:

bash
pnpm exec vue-tsc --noEmit
pnpm build

部署后至少检查:

  1. go run . version -c config.yaml 输出 server_api v0.0.3,服务启动日志带版本号;
  2. 用户端服务(service api)正常启动,注册登录流程可用(需先在短信配置中维护真实渠道、签名与验证码模板);
  3. 登录页底部展示版本号,「平台配置 → 管理端配置」可看到只读的系统版本;
  4. 服务启动不再提示缺少 sys_member 表;
  5. 「用户管理 → 系统用户」页面可以打开,列表含编号、手机号为脱敏格式;
  6. 禁用/启用操作生效,无权限角色看不到操作按钮且接口返回 403;
  7. 短信发送记录与用户端个人资料的手机号为脱敏格式;
  8. 文章编辑页富文本全屏后工具栏完整可见、表单不再穿透,退出全屏恢复正常。

版本边界 ​

  • 用户端注册仅支持手机号+验证码,注册后未设置登录账号与密码时需先通过短信验证码登录,再通过账号/密码修改接口设置。
  • 短信验证码依赖短信配置中的真实渠道凭证,测试环境可使用本地 mock 服务地址验证全流程。
  • 手机号脱敏仅覆盖展示型响应;人员管理与个人设置因编辑回填流程暂不脱敏。
  • 会员账户余额仅作展示,充值、消费等资金操作未在本版本范围内。