会员中心
会员中心提供前台 C 端会员体系与后台运营管理体系。前台会员存储在 members 表,后台管理员存储在 users 表,两套账号、认证中间件、Token 语义、Redis 会话前缀与前端入口均相互隔离。
双用户体系与认证隔离
| 维度 | 后台管理员 | 前台会员 |
|---|---|---|
| 用户表 | users | members |
| 认证接口 | /api/auth/* | /api/member/auth/* |
| 中间件 | authMiddleware | memberAuthMiddleware |
| 请求上下文 | currentUser() | currentMember() / currentMemberId() |
| 前端入口 | index.html | member.html |
| Token 存储 | zenith_token | zenith_member_token / zenith_member_refresh_token |
会员 Access Token 的 payload 固定包含 type: 'member'、memberId、identifier、tenantId、jti。memberAuthMiddleware 强制校验 type: 'member',管理员 authMiddleware 会反向拒绝带 type: 'member' 的 Token,避免会员 Token 访问后台管理接口。
会员会话使用独立 Redis key:
| 用途 | Redis key |
|---|---|
| 在线会话 | {REDIS_KEY_PREFIX}member-session:{jti} |
| 强制下线黑名单 | {REDIS_KEY_PREFIX}member-blacklist:{jti} |
会员会话 TTL 为 8 小时,请求经过 memberAuthMiddleware 时会刷新活跃时间;黑名单 TTL 为 2 小时,与会员 Access Token 有效期一致。
会员认证
会员认证路由挂载在 /api/member/auth。
| 接口 | 说明 | 保护 |
|---|---|---|
POST /sms-code | 发送短信验证码,场景为 register / login / reset | sensitiveRateLimit |
POST /register | 会员注册;手机号 + 验证码可无密码,用户名 / 邮箱 / 手机号也可配合密码注册 | sensitiveRateLimit |
POST /login | 会员登录 | authRateLimit |
POST /refresh | 使用 Refresh Token 刷新 Access Token | 公开 |
POST /reset-password | 手机号 + 验证码重置密码 | sensitiveRateLimit |
POST /logout | 退出登录并删除会员会话 | memberAuthMiddleware |
GET /me | 获取当前会员资料 | memberAuthMiddleware |
PUT /profile | 修改昵称、头像、性别、生日、邮箱 | memberAuthMiddleware |
PUT /password | 修改登录密码 | memberAuthMiddleware |
登录支持 4 种凭证组合:
- 手机号 + 短信验证码:
loginType = 'sms' - 手机号 + 密码:
loginType = 'password',account填手机号 - 邮箱 + 密码:
loginType = 'password',account填邮箱 - 用户名 + 密码:
loginType = 'password',account填用户名
密码使用 bcryptjs,hash 强度为 10。会员注册与后台创建会员都会在事务内初始化 member_point_accounts 与 member_wallets。
注册与登录在业务校验前接入规则中心名单判定:member-auth.service.ts 通过统一求值门面 decide({ kind: 'list', key: 'risk_blacklist' }, ..., { caller: 'member.auth' }) 检查手机号(注册 / 短信登录)与客户端 IP。名单命中时写入失败登录日志并返回 403;名单不存在、禁用或求值异常按可选接入语义放行。规则资产配置与执行留痕见规则中心 · 在线求值。
短信验证码存储在 Redis:
| 用途 | Redis key | TTL |
|---|---|---|
| 验证码 | {REDIS_KEY_PREFIX}member:smscode:{scene}:{phone} | 5 分钟 |
| 发送间隔 | {REDIS_KEY_PREFIX}member:smscode-interval:{phone} | 60 秒 |
验证码校验成功后立即删除,防止重放。非生产环境接口会返回 devCode 便于联调,生产环境不返回验证码明文。
会员等级
会员等级配置存储在 member_levels 表,用于维护等级序号、成长值门槛、折扣与权益展示。
| 字段 | 说明 |
|---|---|
level | 等级序号,数字越大等级越高,全局唯一 |
growth_threshold | 升至该等级所需成长值 |
discount | 等级折扣,百分比整数,100 表示原价,95 表示 95 折 |
benefits | 权益描述数组 |
status | enabled / disabled |
前台通过 GET /api/member/levels 查看启用等级权益;后台通过 /api/member-levels 管理等级。
会员标签(运营分群)
标签存储在 member_tags 表,绑定关系在 member_tag_bindings(member_id + tag_id 唯一,均级联删除)。
- 标签管理:
/api/member-tags(列表带各标签会员数;增删改权限码member:member:update,带审计)。前端入口在会员管理页「标签管理」弹窗。 - 会员打标:
PUT /api/members/{id}/tags(覆盖式)、PUT /api/members/batch-tags(批量追加,onConflictDoNothing跳过已有绑定)。 - 会员列表 / 详情 / 概览通过 RQB
tagBindings.tag附带tags数组;列表与导出支持tagId筛选。
系统种子等级包括普通会员、银卡会员、金卡会员、钻石会员,成长值门槛分别为 0、1000、5000、20000,折扣分别为 100、98、95、90。
成长值与自动定级
成长值(members.growth_value)驱动等级:任何成长值变动都会在同一事务内按 growth_threshold 匹配「最高满足档」自动升降级,低于所有阈值时等级置空,成长值下限钳制为 0。
- 签到 / 补签:规则中的
experience奖励在累加members.experience的同时,等额累加成长值并自动重定级(applyGrowthDeltaInTx(),与签到同事务)。 - 后台调整:
POST /api/members/{id}/growth(权限码member:member:update,带审计与idempotencyGuard),delta可正可负,调整原因记入操作审计。 - 手动指定等级:后台编辑会员或批量调整等级时,系统会把成长值抬升至目标等级门槛(
GREATEST(growth_value, threshold)),避免后续成长值变动时被自动定级回退。
积分体系
积分账户表为 member_point_accounts,一名会员对应一个账户;流水表为 member_point_transactions。
| 表 | 关键字段 |
|---|---|
member_point_accounts | member_id、balance、frozen、total_earned、total_spent、version |
member_point_transactions | member_id、type、amount、balance_after、biz_type、biz_id、operator_id |
积分为整数。流水类型为 earn / redeem / expire / adjust / refund。
changePoints() 是统一记账入口:在数据库事务中读取账户,计算余额,使用 version 乐观锁更新账户,并原子写入流水。余额不足时返回业务错误,乐观锁冲突通过 withOptimisticRetry() 重试。
后台管理员可通过 POST /api/member-points/adjust 手动调整积分,权限码为 member:point:adjust,流水 bizType 为 admin_adjust,并记录操作人 operatorId。该接口带 idempotencyGuard({ ttlSeconds: 10 }) 防止双击/网络重试导致重复入账。
钱包体系
钱包账户表为 member_wallets,流水表为 member_wallet_transactions。金额单位统一为分(整数)。
| 表 | 关键字段 |
|---|---|
member_wallets | member_id、balance、frozen、total_recharge、total_consume、version |
member_wallet_transactions | member_id、type、amount、balance_after、biz_type、biz_id、payment_order_id、operator_id |
钱包流水类型为 recharge / consume / refund / adjust。
changeWallet() 是统一记账入口:在事务中计算余额,使用 version 乐观锁更新账户,并写入永久流水。余额不足时拒绝扣减。
会员前台通过 POST /api/member/wallet/recharge 发起充值,该接口带 idempotencyGuard({ ttlSeconds: 10 })。充值会调用支付中心创建支付单:
bizType = 'member_recharge'bizId = String(memberId)subject = '会员钱包充值'- 过期时间为 30 分钟
- 可选
memberCouponId用于充值满减;支付成功后钱包按支付单originalAmount入账,平台补贴优惠差额
支付成功后,paymentEventBus 触发 payment.succeeded 事件,payment-subscribers.ts 监听 bizType = 'member_recharge' 并调用 creditWalletOnRecharge() 入账。入账按支付单号做幂等校验:若 member_wallet_transactions 中已存在 biz_type = 'member_recharge' 且 biz_id = orderNo 的流水,则不重复入账。
后台支持手动调整余额与退款入账(两个接口均带 idempotencyGuard({ ttlSeconds: 10 }) 防重复提交):
POST /api/member-wallets/adjust:权限码member:wallet:adjust,流水bizType = 'admin_adjust'POST /api/member-wallets/refund:权限码member:wallet:refund,流水bizType = 'admin_refund'
后台「充值记录」页(/member/recharges,权限码 member:recharge:list)通过 GET /api/member-recharges 查询支付中心的会员充值支付单,支持按关键词、状态(pending / paying / success / closed / refunding / refunded / failed)、渠道(wechat / alipay / unionpay)与日期区间筛选,并支持导出。
付费会员(VIP)与自动续费
会员 VIP 状态由 members.vip_expire_at 表达,续费记录存储在 member_vip_renewals 表(order_no 唯一约束作为幂等键)。自动续费复用支付中心的签约代扣能力:
- 签约:
POST /api/member/renewal/sign(带idempotencyGuard),bizType = 'member_renewal'、bizId = 会员 ID;sandbox 渠道签约即时生效并执行首期扣款。 - 续费计划:
GET /api/member/renewal/plans返回支付中心启用中的代扣计划公开视图。 - 状态查询:
GET /api/member/renewal返回 VIP 到期时间、当前代扣协议与续费记录。 - 手动补扣:
POST /api/member/renewal/deduct对当前协议手动扣一期(到期前手动续费)。 - 解约:
POST /api/member/renewal/terminate终止本人协议。
扣款成功后由 payment.succeeded 事件订阅者调用 extendVipOnRenewal() 延长 VIP:按订单号幂等(member_vip_renewals.order_no 唯一约束 + 事务级咨询锁串行化并发重投);未过期时从原到期时间顺延,已过期从当前时间起算,顺延周期取协议绑定的计划周期。前台 SPA 提供自动续费页管理签约状态。
会员软删除
后台删除会员(DELETE /api/members/{id})为软删除:仅设置 members.deleted_at 并强制下线全部会话,积分/钱包账户与流水、券码、签到与登录日志全部保留,用于审计与财务对账。
phone/email/username的唯一约束为部分唯一索引(WHERE deleted_at IS NULL),删除后同一标识符可再次注册。- 已删除会员对列表、详情、下拉、导出、看板统计全部不可见;无法登录、无法刷新 Token;资金调整、发券、补签等操作会返回 404。
例行维护任务与数据导出
系统周期任务 member-housekeeping(每天 02:10,调度中心可手动执行)依次处理:
- 优惠券过期:
member_coupons中已过expire_at的未使用券批量置为expired,保证统计与展示口径准确。 - 积分不活跃过期:由 system_config
member_point_expire_days控制(默认0不启用);账户超过 N 天无任何积分变动时,余额通过changePoints(type='expire')清零并写bizType = 'points_inactive_expire'流水,可审计可对账。 - 生日礼发放:见「生日礼自动发放」章节。
- 券到期提醒:见「券到期提醒」章节。
会员登录日志的生命周期由全局「数据保留」框架中的 member_login_logs 策略管理(默认 180 天,0 表示永久保留),每日 data-retention 任务分批删除超期记录。
会员域已注册 7 个导出中心实体(execution 为 auto,大数据量自动转异步任务):
| 实体 | 页面 | 权限码 |
|---|---|---|
member.members | 会员管理 | member:member:list |
member.point-transactions | 积分管理 | member:point:list |
member.wallet-transactions | 钱包管理 | member:wallet:list |
member.coupon-records | 领券记录 | member:coupon:list |
member.checkins | 签到记录 | member:checkin:log:list |
member.recharges | 充值记录 | member:recharge:list |
member.login-logs | 登录日志 | member:loginlog:list |
优惠券
优惠券模板存储在 coupons 表,会员领券记录存储在 member_coupons 表。
| 表 | 关键字段 |
|---|---|
coupons | type、face_value、threshold、max_discount、total_quantity、issued_quantity、per_limit、valid_type、valid_start、valid_end、valid_days、exchange_points、status |
member_coupons | coupon_id、member_id、code、status、received_at、used_at、expire_at、biz_type、biz_id |
券模板类型:
amount:满减券,face_value为减免金额(分)percent:折扣券,face_value为折扣百分比,90表示 9 折,max_discount为最高减免金额(分)
有效期类型为 fixed / relative,模板状态为 draft / active / paused / expired。会员券状态为 unused / used / expired / frozen。
发券使用事务内原子库存扣减:issued_quantity + 1 与库存条件在同一条 UPDATE 中完成,total_quantity = 0 表示不限量;同时校验 per_limit 每人限领数量。券码以 CP 开头并全局唯一。后台向指定会员发券时接入规则中心决策表 coupon_eligibility:issueCoupon() 调用 decide({ kind: 'table', key: 'coupon_eligibility' }, { member, coupon }, { caller: 'member.coupon' }),当输出 eligible = false 时拒绝发券;规则资产缺失或异常按可选接入语义放行,配置方式见规则中心 · 在线求值。
前台会员可查看可领取优惠券、领取优惠券、查看自己的卡券列表;后台可管理模板、发券给指定会员、查看领券记录、作废未使用券码。服务层提供 redeemCoupon(code) 核销入口,会将可用券更新为 used 并写入 used_at、biz_type、biz_id。
积分兑换优惠券
模板配置 exchange_points > 0 后即可被积分兑换(积分出口最小闭环):
GET /api/member/coupons/exchangeable:可兑换券列表(active + 有库存 + 未过期)。POST /api/member/coupons/exchange:兑换(带idempotencyGuard)。事务内先条件 UPDATE 扣积分(balance >= cost,防超扣),写bizType = 'coupon_exchange'积分流水,再走grantCoupon()(库存/限领校验),券记录标记bizType = 'points_exchange';任一步失败整体回滚。- 前台 SPA「我的卡券 → 积分兑换」Tab 展示余额与兑换入口;后台券表单可配置「兑换积分」。
生日礼自动发放
每日例行维护任务在生日当天(birthday 的 MM-DD 匹配)为启用会员发放礼包,按年幂等(每年最多一次):
member_birthday_points(system_config,默认0不发):积分礼,流水bizType = 'birthday'、bizId = 年份,以流水查重防重发。member_birthday_coupon_id(system_config,默认0不发):券礼,member_coupons以同样标记查重;库存不足等业务异常跳过该会员不阻断整体。
券到期提醒
前台「我的卡券」对 7 天内到期的可用券展示「即将过期」红色标记(基于 expireAt 前端计算);每日例行维护任务同时扫描 7 天内到期券并发送站内通知(以券记录 ID 防重,每张券仅提醒一次)。
券码核销工具
后台「领券记录」页提供核销入口(权限码 member:coupon:update,带审计与幂等):
GET /api/coupons/code/{code}:核销前预览券详情(券信息 / 持有会员 / 状态 / 有效期)。POST /api/coupons/redeem:核销(redeemCoupon()原子条件更新防双花),核销来源标记bizType = 'manual_redeem'。
站内通知 / 邀请裂变 / 账户注销
会员站内通知
通知存储在 member_notifications 表((member_id, created_at) 索引 + (type, biz_id) 防重索引)。
- 发送入口:
createMemberNotification()(带bizId时按(memberId, type, bizId)幂等)。已接入:生日礼、券到期提醒、管理员积分/余额调整、邀请奖励。 - 前台自助:
GET /api/member/notifications(分页/unreadOnly)、GET /notifications/unread-count、PUT /notifications/{id}/read、PUT /notifications/read-all;消息中心页/messages,侧边栏与移动端 TabBar 均带未读红点(60s 轮询)。
邀请裂变
members.invite_code(部分唯一索引,首次访问邀请页懒生成)+invited_by(邀请关系)。- 注册接口支持
inviteCode(选填):注册成功后绑定邀请关系,按 system_configmember_invite_reward_points(默认0关闭)给邀请人发积分(流水bizType='invite'、bizId=新会员ID,天然幂等)并发站内通知;处理为 best-effort,不阻断注册。 - 前台:邀请页
/invite(邀请码/邀请链接复制、已邀人数、累计奖励、最近邀请列表);注册弹窗支持邀请码输入并可从链接#/?invite=CODE预填。
账户自助注销
POST /api/member/auth/deactivate(限流保护):已设密码的验证密码,否则验证手机短信验证码;通过后软删除 + 强制下线全部会话。数据按软删除策略保留,标识符立即可重新注册。前台入口在「个人设置」危险区。
移动端适配
前台会员中心在 ≤768px 视口下隐藏侧边导航,改用底部固定 TabBar(首页/卡券/签到/消息/我的),消息项带未读徽标。
等级折扣消费侧接入
services/member/member-benefits.service.ts 提供订单/支付链路的统一接入点:
getMemberDiscount(memberId):返回会员当前折扣百分比(无等级/等级停用 = 100)。applyDiscount(amountFen, discount):按折扣计算应付金额(分)。- 前台
GET /api/member/benefits返回当前折扣、权益列表与下一等级升级差距;等级权益页展示升级进度条。
签到
签到规则存储在 checkin_rules 表,签到记录存储在 member_checkins 表。
| 表 | 关键字段 |
|---|---|
checkin_rules | day_number、points、experience、remark |
member_checkins | member_id、checkin_date、consecutive_days、points_awarded、experience_awarded |
checkin_rules.day_number 唯一。会员每天只能签到一次,member_checkins 对 member_id + checkin_date 建立唯一约束。
签到奖励按连续天数匹配规则:
- 精确命中
day_number时使用该规则 - 超过最大
day_number时使用最后一条规则 - 未精确命中时使用不大于连续天数的最近规则
执行签到时,系统在事务内写入签到记录;若奖励积分大于 0,会原子累加积分账户 balance、total_earned 与 version,并写入 bizType = 'checkin' 的积分流水。经验奖励累加到 members.experience,并等额累加成长值触发自动定级(见「成长值与自动定级」)。
前台签到接口 POST /api/member/checkin 带 idempotencyGuard({ ttlSeconds: 5 })。
签到设置与自助补签
签到设置为 checkin_settings 单行配置(get-or-create),包含补签开关(makeup_enabled)、补签消耗积分(makeup_cost_points)与补签可回溯天数(makeup_max_days)。查询走 GET /api/checkin-settings(权限码 member:checkin:rule:list),更新走 PUT /api/checkin-settings(权限码 member:checkin:setting:update,带审计),入口在「签到配置」页的「签到设置」按钮。
- 会员自助补签:
POST /api/member/checkin/makeup(带幂等),开关开启时可对可回溯天数内的漏签日期补签,消耗设置中的积分,无需原因。 - 管理端补签:
POST /api/members/{id}/checkin/makeup(权限码member:checkin:makeup)必须提供reason(2-256 字符),原因记入member_checkins.remark与操作审计。
签到里程碑
里程碑配置存储在 checkin_milestones 表:累计签到天数达标后发放奖励,reward_type = points 发积分、reward_type = coupon 发指定优惠券模板,支持启停。发放记录写入 member_checkin_milestone_awards 防止重复发放。
- 管理端:
/api/checkin-milestonesCRUD(权限码member:checkin:milestone:list/create/update/delete),页面为「里程碑配置」(/member/checkin-milestones)。 - 前台:
GET /api/member/checkin/milestones返回里程碑达成进度,签到页展示奖励进度。
会员数据看板
后台「会员看板」页(/member/dashboard,权限码 member:dashboard:view)提供只读聚合统计:
GET /api/member-stats/overview:会员总数、今日 / 本月新增、30 日活跃、积分总余额、钱包总余额、今日签到数与签到率等概览卡片GET /api/member-stats/charts:10 张图表数据,包括近 30 日注册趋势、累计会员增长、等级分布、近 30 日积分收支、近 7 日签到人数、活跃分层、充值能力分层、近 30 日钱包收支、注册来源分布与卡券状态分布
内容互动(CMS 自助接口)
/api/member/cms/* 为会员提供 CMS 内容互动自助能力:内容浏览上报与浏览历史、点赞 / 收藏、评论、投稿(创建 / 编辑 / 删除 / 查询)、栏目订阅与订阅状态、互动活动提交。全部接口走 memberAuthMiddleware 并按 currentMemberId() 过滤。内容管理侧能力见 CMS 内容管理。
接口一览
前台会员接口
| 前缀 | 接口 | 说明 |
|---|---|---|
/api/member/auth | POST /sms-code | 发送短信验证码 |
/api/member/auth | POST /register | 注册并登录 |
/api/member/auth | POST /login | 登录 |
/api/member/auth | POST /refresh | 刷新 Access Token |
/api/member/auth | POST /reset-password | 重置密码 |
/api/member/auth | POST /logout | 退出登录 |
/api/member/auth | GET /me | 当前会员资料 |
/api/member/auth | PUT /profile | 修改资料 |
/api/member/auth | PUT /password | 修改密码 |
/api/member | GET /points/account | 我的积分账户 |
/api/member | GET /points/transactions | 我的积分流水 |
/api/member | GET /wallet | 我的钱包 |
/api/member | GET /wallet/transactions | 我的钱包流水 |
/api/member | POST /wallet/recharge | 发起钱包充值 |
/api/member | GET /levels | 等级权益 |
/api/member | GET /benefits | 当前折扣、权益与升级差距 |
/api/member | GET /renewal、GET /renewal/plans | 自动续费状态与可选计划 |
/api/member | POST /renewal/sign、POST /renewal/deduct、POST /renewal/terminate | 签约 / 手动扣款 / 解约自动续费 |
/api/member | GET /coupons/available | 可领取优惠券 |
/api/member | GET /coupons/exchangeable | 可积分兑换优惠券 |
/api/member | GET /coupons | 我的优惠券 |
/api/member | POST /coupons/receive | 领取优惠券 |
/api/member | POST /coupons/exchange | 积分兑换优惠券 |
/api/member | GET /checkin/status | 今日签到状态 |
/api/member | POST /checkin | 执行签到 |
/api/member | POST /checkin/makeup | 自助补签(消耗积分) |
/api/member | GET /checkin/history | 我的签到历史 |
/api/member | GET /checkin/milestones | 里程碑达成进度 |
/api/member | GET /notifications、GET /notifications/unread-count | 我的站内通知与未读数 |
/api/member | PUT /notifications/{id}/read、PUT /notifications/read-all | 标记通知已读 |
/api/member | GET /invite/summary | 邀请码、邀请人数与奖励汇总 |
/api/member | GET /login-logs | 我的登录历史 |
/api/member/auth | POST /deactivate | 账户自助注销(软删除) |
/api/member/cms | GET/POST/PUT/DELETE /* | 内容互动自助接口(浏览历史 / 点赞收藏 / 评论 / 投稿 / 订阅 / 互动活动) |
后台管理接口与权限码
| 路由 | 接口 | 权限码 |
|---|---|---|
/api/members | GET /、GET /{id}、GET /{id}/overview | member:member:list |
/api/members | POST / | member:member:create |
/api/members | PUT /{id}、PUT /{id}/status、POST /{id}/reset-password、POST /{id}/growth、PUT /{id}/tags、PUT /batch-status、PUT /batch-level、PUT /batch-tags | member:member:update |
/api/members | DELETE /{id}(软删除) | member:member:delete |
/api/members | GET /options(会员搜索下拉) | member:member:list |
/api/members | GET /login-logs(会员登录日志) | member:loginlog:list |
/api/members | POST /{id}/checkin/makeup(管理端补签) | member:checkin:makeup |
/api/member-stats | GET /overview、GET /charts | member:dashboard:view |
/api/member-recharges | GET / | member:recharge:list |
/api/member-tags | GET / | member:member:list |
/api/member-tags | POST /、PUT /{id}、DELETE /{id} | member:member:update |
/api/member-levels | GET /、GET /{id} | member:level:list |
/api/member-levels | POST / | member:level:create |
/api/member-levels | PUT /{id} | member:level:update |
/api/member-levels | DELETE /{id} | member:level:delete |
/api/member-points | GET /transactions、GET /account/{id} | member:point:list |
/api/member-points | POST /adjust | member:point:adjust |
/api/member-wallets | GET /transactions、GET /account/{id} | member:wallet:list |
/api/member-wallets | POST /adjust | member:wallet:adjust |
/api/member-wallets | POST /refund | member:wallet:refund |
/api/coupons | GET /、GET /{id}、GET /records、GET /code/{code} | member:coupon:list |
/api/coupons | POST / | member:coupon:create |
/api/coupons | PUT /{id}、POST /redeem | member:coupon:update |
/api/coupons | DELETE /{id} | member:coupon:delete |
/api/coupons | POST /{id}/issue | member:coupon:issue |
/api/coupons | POST /records/{id}/revoke | member:coupon:revoke |
/api/checkin-rules | GET / | member:checkin:rule:list |
/api/checkin-rules | POST / | member:checkin:rule:create |
/api/checkin-rules | PUT /{id} | member:checkin:rule:update |
/api/checkin-rules | DELETE /{id} | member:checkin:rule:delete |
/api/checkin-settings | GET / | member:checkin:rule:list |
/api/checkin-settings | PUT / | member:checkin:setting:update |
/api/checkin-milestones | GET / | member:checkin:milestone:list |
/api/checkin-milestones | POST / | member:checkin:milestone:create |
/api/checkin-milestones | PUT /{id} | member:checkin:milestone:update |
/api/checkin-milestones | DELETE /{id} | member:checkin:milestone:delete |
/api/member-checkins | GET / | member:checkin:log:list |
/api/member-checkins | GET /calendar?month=YYYY-MM | member:checkin:log:list |
会员中心后台菜单种子位于 SEED_MENUS 的 9000 段,包括会员看板、会员管理、会员等级、积分管理、钱包管理、优惠券、领券记录、会员签到(签到配置 / 签到记录 / 里程碑配置)、登录日志与充值记录。
前端
前台会员端是独立 SPA:
- HTML 入口:
packages/web/member.html - 代码目录:
packages/web/src/member/(入口、认证 Provider、独立请求客户端、布局) - 路由:
HashRouter
member-request.ts 自动携带 zenith_member_token,遇到 401 会调用 /api/member/auth/refresh 刷新 Access Token;刷新失败时清理会员 Token 并跳转到 member.html#/login。
前台页面覆盖会员概览、我的积分、我的钱包、我的卡券、每日签到(含里程碑进度与自助补签)、等级权益、自动续费、消息中心、邀请有礼、内容互动(浏览历史 / 收藏 / 评论 / 投稿 / 订阅)、个人设置、编辑资料、修改密码与登录历史。钱包充值页将用户输入的元转换为分后提交。
后台管理页面位于 packages/web/src/pages/member/,覆盖会员看板、会员管理、会员等级、积分管理、钱包管理、优惠券、领券记录、签到配置、签到记录、里程碑配置、登录日志与充值记录,并按对应 member:* 权限码控制按钮展示。