feat: 用户徽章与等级体系,积分经济管理重构

- 新增徽章系统:badge 服务与 handler、管理端配置页、BadgeChip/LevelBadge 展示组件
- 新增等级模型:model/level 及前端 levels 元数据
- 管理端经济模块拆分为 points/badges/levels 独立页面,EconomySettings 迁入设置
- 积分、签到、评论等服务适配等级与徽章逻辑
This commit is contained in:
2026-09-25 16:38:29 +08:00
parent 7b327bc8cc
commit 4ae57d9392
57 changed files with 3939 additions and 147 deletions

View File

@@ -0,0 +1,45 @@
import { clampLevel, LEVEL_BADGE_CLASS } from "@/lib/levels";
/**
* 等级徽章:仅显示 Lv.n,颜色/特效由根布局 SSR 注入的 --lv-N-* 变量驱动
* (--lv-N-fg 前景 / --lv-N-bg 背景 / --lv-N-ring 内描边 / --lv-N-text 文字渐变层,
* text 存在时 fg 为 transparent,文字以流动金渐变呈现——鎏金字)。
* 等级数值由后端按累计获得积分计算,前端零计算;不弹悬浮提示。
* 流动动画见 globals.css 的 .lv-badge / .lv-text。
*/
export default function LevelBadge({
level,
className = "",
}: {
level?: number | null;
className?: string;
}) {
const n = clampLevel(level);
return (
<span
className={`${LEVEL_BADGE_CLASS} ${className}`}
style={{
background: `var(--lv-${n}-bg)`,
color: `var(--lv-${n}-fg)`,
boxShadow: `inset 0 0 0 1px var(--lv-${n}-ring, transparent)`,
}}
>
{/* 内层承载可选文字渐变。background 全长写(React 禁止简写与 backgroundClip
等长写混用);clip 同为长写,无渐变档 image=none 时 clip 无副作用 */}
<span
className="lv-text"
style={{
backgroundImage: `var(--lv-${n}-text-image, none)`,
backgroundPosition: `var(--lv-${n}-text-position, 0% 0%)`,
backgroundSize: `var(--lv-${n}-text-size, auto)`,
backgroundClip: "text",
WebkitBackgroundClip: "text",
color: `var(--lv-${n}-fg)`,
}}
>
Lv.{n}
</span>
</span>
);
}