feat(users): level integral XP schema + AKSRT_User_Level runtime
Rewrite /users/level to Zibll-like user_level_s/max/opt and user_integral_opt. Runtime grants XP with day_max, resolves level, hooks login/register/post/comment/like/favorite/follow. Profile signals read integral-backed levels. audit errors=0.
This commit is contained in:
1 parent
e80d8ea45d
commit
1b0eed6ef7
8 files changed
+658
-141
No files matched your search
@@ -1,33 +1,82 @@
|
||||
/**
|
||||
* User level + integral XP (Zibll user_level_s / user_level_opt / user_integral_opt).
|
||||
*/
|
||||
|
||||
export const INTEGRAL_CATALOG = [
|
||||
{ key: 'sign_up', label: '首次注册', default: 20, group: '用户' },
|
||||
{ key: 'sign_in', label: '每日登录', default: 5, group: '用户' },
|
||||
{ key: 'followed', label: '被关注', default: 5, group: '用户' },
|
||||
{ key: 'post_new', label: '发布文章', default: 5, group: '文章' },
|
||||
{ key: 'post_like', label: '文章获赞', default: 1, group: '文章' },
|
||||
{ key: 'post_favorite', label: '文章被收藏', default: 2, group: '文章' },
|
||||
{ key: 'comment_new', label: '发表评论', default: 2, group: '文章' },
|
||||
{ key: 'comment_like', label: '评论获赞', default: 1, group: '文章' },
|
||||
{ key: 'bbs_posts_new', label: '发布帖子', default: 3, group: '论坛' },
|
||||
{ key: 'bbs_score_extra', label: '帖子被加分', default: 1, group: '论坛' },
|
||||
{ key: 'bbs_essence', label: '帖子评为精华', default: 2, group: '论坛' },
|
||||
{ key: 'bbs_posts_hot', label: '帖子成为热门', default: 2, group: '论坛' },
|
||||
{ key: 'bbs_plate_new', label: '创建版块', default: 2, group: '论坛' },
|
||||
{ key: 'bbs_plate_hot', label: '版块成为热门', default: 2, group: '论坛' },
|
||||
{ key: 'bbs_adopt', label: '回答被采纳', default: 2, group: '论坛' },
|
||||
{ key: 'bbs_comment_hot', label: '评论成为神评', default: 2, group: '论坛' },
|
||||
]
|
||||
|
||||
export function defaultLevelOpt(max = 10) {
|
||||
const opt = {}
|
||||
for (let i = 1; i <= max; i++) {
|
||||
// Rough Zibll-like curve: LV1=0, then grows
|
||||
opt['upgrade_integral_' + i] = i === 1 ? 0 : Math.round(20 * Math.pow(i - 1, 1.6))
|
||||
opt['name_' + i] = 'Lv.' + i
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
||||
export function defaultIntegralOpt() {
|
||||
const opt = { day_max: 100 }
|
||||
for (const row of INTEGRAL_CATALOG) {
|
||||
opt[row.key] = row.default
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
||||
export const levelSchema = {
|
||||
key: 'users.level',
|
||||
title: '用户等级',
|
||||
icon: 'fas fa-level-up-alt',
|
||||
description: '配置等级展示前缀和等级阈值,当前可基于积分余额自动计算。',
|
||||
description: '等级与经验值:最高等级、升级阈值、经验获取矩阵(对齐 Zibll user_level / user_integral)。',
|
||||
defaults: {
|
||||
user_level_enabled: false,
|
||||
user_level_s: true,
|
||||
user_level_public_display: true,
|
||||
user_level_source: 'credits_balance',
|
||||
user_level_prefix: 'Lv.',
|
||||
user_level_thresholds: '1|0\n2|30\n3|100\n4|300',
|
||||
user_level_max: 10,
|
||||
user_level_opt: defaultLevelOpt(10),
|
||||
user_integral_opt: defaultIntegralOpt(),
|
||||
user_level_notify: true,
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
key: 'display',
|
||||
title: '等级显示',
|
||||
icon: 'fas fa-signal',
|
||||
fields: [
|
||||
{ key: 'user_level_enabled', label: '启用等级系统', type: 'switch', default: false },
|
||||
{ key: 'user_level_public_display', label: '公开页显示等级', type: 'switch', default: true, dependsOn: { key: 'user_level_enabled', value: true } },
|
||||
{ key: 'user_level_prefix', label: '等级前缀', type: 'input', default: 'Lv.', dependsOn: { key: 'user_level_enabled', value: true } },
|
||||
{ key: 'user_level_s', label: '启用用户等级', type: 'switch', default: true },
|
||||
{ key: 'user_level_public_display', label: '公开页显示等级', type: 'switch', default: true, dependsOn: { key: 'user_level_s', value: true } },
|
||||
{ key: 'user_level_prefix', label: '等级前缀', type: 'input', default: 'Lv.', dependsOn: { key: 'user_level_s', value: true } },
|
||||
{ key: 'user_level_max', label: '最高等级', type: 'number', default: 10, min: 3, max: 30, dependsOn: { key: 'user_level_s', value: true } },
|
||||
{ key: 'user_level_notify', label: '升级通知', type: 'switch', default: true, dependsOn: { key: 'user_level_s', value: true } },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'rules',
|
||||
title: '等级规则',
|
||||
icon: 'fas fa-list-ol',
|
||||
key: 'level_opt',
|
||||
title: '等级升级阈值',
|
||||
fields: [
|
||||
{ key: 'user_level_source', label: '等级来源', type: 'radio', default: 'credits_balance', options: [{ label: '积分余额', value: 'credits_balance' }, { label: '手动 Meta', value: 'manual_meta' }], dependsOn: { key: 'user_level_enabled', value: true } },
|
||||
{ key: 'user_level_thresholds', label: '等级阈值', type: 'textarea', default: '1|0\n2|30\n3|100\n4|300', help: '每行一个等级,格式:等级|所需积分,例如 3|100', dependsOn: { key: 'user_level_enabled', value: true } },
|
||||
{ key: 'user_level_opt', label: '升级经验配置', type: 'json', default: defaultLevelOpt(10), help: 'upgrade_integral_N 为升到 N 级所需累计经验' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'integral',
|
||||
title: '经验值得分',
|
||||
fields: [
|
||||
{ key: 'user_integral_opt', label: '经验值获取', type: 'json', default: defaultIntegralOpt(), help: 'day_max + 各行为得分;对应功能未开则将分值设 0' },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user