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

@@ -17,6 +17,8 @@ import PasswordForm from "./PasswordForm";
import LoginDevices from "./LoginDevices";
import ProfileHeroAvatar from "./ProfileHeroAvatar";
import RoleBadge from "@/components/RoleBadge";
import LevelBadge from "@/components/LevelBadge";
import BadgeChip from "@/components/BadgeChip";
import { roleMeta } from "@/lib/roles";
import StartDMButton from "./StartDMButton";
import StaffUserMenu from "@/components/StaffUserMenu";
@@ -253,6 +255,7 @@ export default async function UserPage({ params, searchParams }: UserPageProps)
>
{u.nickname || u.username}
</h1>
<LevelBadge level={u.level} />
{u.role !== "user" && (
<RoleBadge role={u.role} boardIds={u.board_ids} />
)}
@@ -265,6 +268,18 @@ export default async function UserPage({ params, searchParams }: UserPageProps)
</span>
)}
</div>
{/* 徽章墙:管理员颁布的全部徽章,悬浮显示授予时间 */}
{(u.badges ?? []).length > 0 && (
<div className="mt-1.5 flex items-center gap-1.5 flex-wrap">
{(u.badges ?? []).map((ub) => (
<BadgeChip
key={ub.id}
badge={ub.badge}
tip={`${ub.badge.name} · ${new Date(ub.awarded_at).toLocaleDateString("zh-CN")} 颁布`}
/>
))}
</div>
)}
<p className="mt-1.5 text-[14px] leading-snug flex flex-wrap items-center" style={{ color: "var(--ink-2)" }}>
<span>
<span className="tabular-nums font-semibold" style={{ color: "var(--ink)" }}>{data.stats.post_count}</span>