feat: 用户徽章与等级体系,积分经济管理重构
- 新增徽章系统:badge 服务与 handler、管理端配置页、BadgeChip/LevelBadge 展示组件 - 新增等级模型:model/level 及前端 levels 元数据 - 管理端经济模块拆分为 points/badges/levels 独立页面,EconomySettings 迁入设置 - 积分、签到、评论等服务适配等级与徽章逻辑
This commit is contained in:
@@ -32,6 +32,14 @@
|
||||
--ok: #137333;
|
||||
--ok-soft: rgba(19, 115, 51, 0.1);
|
||||
|
||||
/* 等级徽章与自定义徽章扩展色板 */
|
||||
--info: #1c6ea8;
|
||||
--info-soft: rgba(28, 110, 168, 0.1);
|
||||
--purple: #6d3fc0;
|
||||
--purple-soft: rgba(109, 63, 192, 0.1);
|
||||
--teal: #0f7a6e;
|
||||
--teal-soft: rgba(15, 122, 110, 0.1);
|
||||
|
||||
/* 积分看板最近流水:金额与类型标签 */
|
||||
--ledger-in: #16a34a;
|
||||
--ledger-out: #dc2626;
|
||||
@@ -103,6 +111,18 @@
|
||||
--rail-top: calc(var(--header-h) + var(--main-pad-y));
|
||||
--rail-max-h: calc(100vh - var(--rail-top) - 1rem);
|
||||
|
||||
/* 等级徽章默认色兜底(layout.tsx 会按后台配置注入 --lv-N-* 覆盖此处;
|
||||
与 lib/levels.ts 色板保持同步:灰/蓝/青/绿/红牌/黑金/鎏金,
|
||||
特效档为含高光段的流动渐变,流光由高光段随 position 流动呈现) */
|
||||
--lv-1-fg: #9aa3b2; --lv-1-bg: rgba(148,158,176,0.16); --lv-1-ring: transparent;
|
||||
--lv-2-fg: #4d8dff; --lv-2-bg: rgba(59,118,240,0.15); --lv-2-ring: transparent;
|
||||
--lv-3-fg: #12a89b; --lv-3-bg: rgba(14,148,136,0.15); --lv-3-ring: transparent;
|
||||
--lv-4-fg: #27a94f; --lv-4-bg: rgba(31,156,71,0.15); --lv-4-ring: transparent;
|
||||
--lv-5-fg: #ffffff; --lv-5-bg: linear-gradient(90deg, #b91c1c, #ef4444 25%, #fecaca 38%, #dc2626 52%, #991b1b 78%, #b91c1c) 0% 0% / 200% 100%; --lv-5-ring: transparent;
|
||||
--lv-6-fg: #e9c46a; --lv-6-bg: linear-gradient(90deg, #16171c, #23252c 22%, #4a3d1c 36%, #23252c 52%, #16171c 78%) 0% 0% / 200% 100%; --lv-6-ring: rgba(233, 196, 106, 0.5);
|
||||
--lv-7-fg: transparent; --lv-7-bg: linear-gradient(180deg, #221b0f, #100d07); --lv-7-ring: rgba(240, 200, 120, 0.45);
|
||||
--lv-7-text-image: linear-gradient(90deg, #c9973f, #ffe9a8 30%, #fff6d8 46%, #f0c964 66%, #c9973f); --lv-7-text-position: 0% 0%; --lv-7-text-size: 200% 100%;
|
||||
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
@@ -133,6 +153,14 @@
|
||||
--ok: #58d18a;
|
||||
--ok-soft: rgba(88, 209, 138, 0.15);
|
||||
|
||||
/* 等级徽章与自定义徽章扩展色板 */
|
||||
--info: #5db8f0;
|
||||
--info-soft: rgba(93, 184, 240, 0.16);
|
||||
--purple: #c39bf5;
|
||||
--purple-soft: rgba(195, 155, 245, 0.16);
|
||||
--teal: #4fd8c4;
|
||||
--teal-soft: rgba(79, 216, 196, 0.16);
|
||||
|
||||
--ledger-in: #4ade80;
|
||||
--ledger-out: #f87171;
|
||||
--ledger-checkin-bg: rgba(22, 163, 74, 0.22);
|
||||
@@ -279,6 +307,51 @@ html.j13-has-admin-bg[data-j13-chrome="admin"] body::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 等级徽章特效(LevelBadge / .lv-badge):底色/前景由 SSR 注入的 --lv-N-* 变量驱动。
|
||||
特效档背景为水平多段渐变(首尾同色)+ background-size 200%,
|
||||
lv-flow 位移 0→200% 恰好一个图块周期(百分比 position 非线性:偏移=(100%-size)×p,
|
||||
size=200% 时 p=200% 的偏移=-200% 即一个图块宽),循环首尾严格重合、无接缝。
|
||||
.lv-text 为文字渐变层(--lv-N-text 存在时经 background-clip:text 呈现鎏金字,
|
||||
同样走 lv-flow 流动;无渐变档 background 为 none,文字按 --lv-N-fg 正常着色) */
|
||||
@keyframes lv-flow {
|
||||
to {
|
||||
background-position: 200% 0%;
|
||||
}
|
||||
}
|
||||
.lv-badge {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
animation: lv-flow 6s linear infinite;
|
||||
}
|
||||
.lv-text {
|
||||
animation: lv-flow 6s linear infinite;
|
||||
}
|
||||
/* 站点特效总开关(levels_fx 设置,layout SSR 注入 html[data-lv-fx]):
|
||||
关闭时停用流光动画,徽章退化为静态配色 */
|
||||
html[data-lv-fx="off"] .lv-badge,
|
||||
html[data-lv-fx="off"] .lv-text {
|
||||
animation: none;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.lv-badge,
|
||||
.lv-text {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 徽章类统一禁止鼠标选择:拖选/双击正文时避免把小胶囊文字带进选区 */
|
||||
.lv-badge,
|
||||
.cmt-badge,
|
||||
.badge-pending,
|
||||
.badge-type,
|
||||
.badge-access,
|
||||
.badge-status,
|
||||
.badge-accepted,
|
||||
.j13-board-tag {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
/* 全站悬停即显提示气泡(配合 TipHost + data-tip,替代原生 title 延迟) */
|
||||
.j13-tip-bubble {
|
||||
position: fixed;
|
||||
@@ -3079,6 +3152,9 @@ body:has([data-admin-viewport]) {
|
||||
height: 100%;
|
||||
box-shadow: var(--shadow-lg);
|
||||
animation: admin-drawer-in 0.18s ease-out;
|
||||
/* 覆盖 .admin-rail 的上下内边距并叠加刘海/手势区避让 */
|
||||
padding-top: calc(1rem + env(safe-area-inset-top, 0px));
|
||||
padding-bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
.admin-rail-brand {
|
||||
@@ -3265,6 +3341,7 @@ body:has([data-admin-viewport]) {
|
||||
inset: 0;
|
||||
z-index: 60;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.admin-drawer-backdrop {
|
||||
@@ -3273,7 +3350,8 @@ body:has([data-admin-viewport]) {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: color-mix(in srgb, var(--ink) 28%, transparent);
|
||||
background: color-mix(in srgb, var(--ink) 32%, transparent);
|
||||
animation: admin-fade-in 0.18s ease-out;
|
||||
}
|
||||
|
||||
@keyframes admin-drawer-in {
|
||||
@@ -3287,8 +3365,49 @@ body:has([data-admin-viewport]) {
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes admin-drawer-out {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes admin-fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes admin-fade-out {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 退场:面板滑出 + 背板淡出,结束后由组件卸载 */
|
||||
.admin-drawer.is-closing .admin-drawer-backdrop {
|
||||
animation: admin-fade-out 0.18s ease-in forwards;
|
||||
}
|
||||
|
||||
.admin-drawer.is-closing .admin-drawer-panel {
|
||||
animation: admin-drawer-out 0.18s ease-in forwards;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.admin-drawer-panel {
|
||||
.admin-drawer-panel,
|
||||
.admin-drawer-backdrop,
|
||||
.admin-drawer.is-closing .admin-drawer-panel,
|
||||
.admin-drawer.is-closing .admin-drawer-backdrop {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user