feat(ux): forum pay-hide depth, clogin OAuth, ban appeals admin, posts-navs widget

- Forum compose/save/draft: VIP prices, partial hide, coupons + shortcode tools
- Rainbow clogin aggregate login (rewrite + schema + CLoginClient)
- Native ban appeals tab: approve/reject + lift ban + notify
- WidgetPostsNavs + register missing forum widgets
- Submit editor shortcodes: login/reply/vip/payshow
This commit is contained in:
2026-07-18 23:31:57 +08:00
parent 25aabb71a3
commit 24330653f0
15 changed files with 834 additions and 35 deletions
@@ -24,6 +24,11 @@ export const oauthSchema = {
oauth_weibo_s: false,
oauth_baidu_s: false,
oauth_alipay_s: false,
clogin_s: false,
clogin_url: '',
clogin_id: '',
clogin_key: '',
clogin_oauth_s: ['qq', 'weixin', 'weibo', 'alipay'],
github_appid: '',
github_appkey: '',
gitee_appid: '',
@@ -92,6 +97,7 @@ export const oauthSchema = {
{ key: 'oauth_weibo_s', label: '微博登录', type: 'switch', default: false },
{ key: 'oauth_baidu_s', label: '百度登录', type: 'switch', default: false },
{ key: 'oauth_alipay_s', label: '支付宝登录', type: 'switch', default: false },
{ key: 'clogin_s', label: '彩虹聚合登录', type: 'switch', default: false, help: '通过第三方聚合登录平台统一接入 QQ/微信/微博/支付宝等' },
],
},
{
@@ -174,6 +180,23 @@ export const oauthSchema = {
{ key: 'baidu_appkey', label: 'Secret Key', type: 'input', default: '' },
],
},
{
key: 'clogin',
title: '彩虹聚合登录',
icon: 'fas fa-cloud',
fields: [
{ key: 'clogin_url', label: '接口地址', type: 'input', default: '', help: '如 https://xxx.com 不要带 connect.php', dependsOn: { key: 'clogin_s', value: true } },
{ key: 'clogin_id', label: 'AppID', type: 'input', default: '', dependsOn: { key: 'clogin_s', value: true } },
{ key: 'clogin_key', label: 'AppKey', type: 'input', default: '', dependsOn: { key: 'clogin_s', value: true } },
{ key: 'clogin_oauth_s', label: '启用平台', type: 'checkbox', default: ['qq', 'weixin', 'weibo', 'alipay'], options: [
{ label: 'QQ', value: 'qq' },
{ label: '微信', value: 'weixin' },
{ label: '微博', value: 'weibo' },
{ label: '支付宝', value: 'alipay' },
{ label: '百度', value: 'baidu' },
], dependsOn: { key: 'clogin_s', value: true } },
],
},
{
key: 'alipay',
title: '支付宝配置',
+38
View File
@@ -621,6 +621,44 @@
});
}
function insertForumEditorContent(html) {
if (window.tinymce) {
var ed = window.tinymce.get('compose-content') || window.tinymce.get('post_content');
if (ed && !ed.isHidden()) {
ed.focus();
ed.execCommand('mceInsertContent', false, html);
return;
}
}
var ta = document.getElementById('compose-content') || document.getElementById('post_content');
if (!ta) return;
var start = ta.selectionStart || 0;
var end = ta.selectionEnd || 0;
var val = ta.value || '';
ta.value = val.slice(0, start) + html + val.slice(end);
ta.focus();
}
function bindComposeShortcodeTools(root) {
root = root || document;
root.addEventListener('click', function (e) {
var btn = e.target.closest('[data-insert-shortcode]');
if (!btn) return;
e.preventDefault();
var type = btn.getAttribute('data-insert-shortcode');
if (type === 'hide') {
insertForumEditorContent('[hidecontent type="login"]隐藏内容[/hidecontent]');
} else if (type === 'reply') {
insertForumEditorContent('[hidecontent type="reply"]回复后可见[/hidecontent]');
} else if (type === 'payshow') {
insertForumEditorContent('[hidecontent type="payshow"]付费可见内容[/hidecontent]');
} else if (type === 'vip') {
insertForumEditorContent('[vip]VIP 可见内容[/vip]');
}
});
}
function bindComposeVisibilityToggle(form) {
var visSelect = form.querySelector('#compose-visibility');
var creditsField = form.querySelector('#compose-credits-cost-field');
+6 -2
View File
@@ -543,9 +543,13 @@
e.preventDefault();
var type = btn.getAttribute('data-insert-shortcode');
if (type === 'hide') {
insertEditorContent('[hidecontent type="logged"]hidden[/hidecontent]');
insertEditorContent('[hidecontent type="login"]' + (i18n.hidePlaceholder || '隐藏内容') + '[/hidecontent]');
} else if (type === 'payshow') {
insertEditorContent('[hidecontent type="payshow"]paid content[/hidecontent]');
insertEditorContent('[hidecontent type="payshow"]' + (i18n.payPlaceholder || '付费可见内容') + '[/hidecontent]');
} else if (type === 'reply') {
insertEditorContent('[hidecontent type="reply"]' + (i18n.replyPlaceholder || '回复后可见') + '[/hidecontent]');
} else if (type === 'vip') {
insertEditorContent('[vip]' + (i18n.vipPlaceholder || 'VIP 可见内容') + '[/vip]');
}
});
},