feat: 固定个人与企业认证流程
This commit is contained in:
1 parent
b4364e63ec
commit
ec63b446e8
8 files changed
+139
-111
No files matched your search
@@ -6,14 +6,19 @@ export const verifySchema = {
|
|||||||
defaults: {
|
defaults: {
|
||||||
user_verify_enabled: true,
|
user_verify_enabled: true,
|
||||||
user_verify_public_display: true,
|
user_verify_public_display: true,
|
||||||
user_verify_badge_text: '已认证',
|
user_verify_personal_badge_text: '个人认证',
|
||||||
|
user_verify_personal_fee: 0,
|
||||||
|
user_verify_personal_free_applications: 0,
|
||||||
|
user_verify_personal_require_real_name: false,
|
||||||
|
user_verify_enterprise_badge_text: '企业认证',
|
||||||
|
user_verify_enterprise_fee: 0,
|
||||||
|
user_verify_enterprise_free_applications: 0,
|
||||||
|
user_verify_enterprise_require_real_name: false,
|
||||||
user_verify_allow_apply: true,
|
user_verify_allow_apply: true,
|
||||||
user_verify_disable_desc:
|
user_verify_disable_desc:
|
||||||
'由于系统正在维护,暂时无法申请身份认证\n详情请联系管理员',
|
'由于系统正在维护,暂时无法申请身份认证\n详情请联系管理员',
|
||||||
user_verify_limit_level: 2,
|
|
||||||
user_verify_desc:
|
user_verify_desc:
|
||||||
'认证用户会在昵称后显示认证徽章,同时享受多种优先待遇。申请请确保信息属实。',
|
'认证用户会在昵称后显示认证徽章,同时享受多种优先待遇。申请请确保信息属实。',
|
||||||
user_verify_apply_option: 'real_name|实名认证\norganization|企业认证',
|
|
||||||
},
|
},
|
||||||
groups: [
|
groups: [
|
||||||
{
|
{
|
||||||
@@ -30,28 +35,18 @@ export const verifySchema = {
|
|||||||
dependsOn: { key: 'user_verify_enabled', value: true },
|
dependsOn: { key: 'user_verify_enabled', value: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'user_verify_badge_text',
|
key: 'user_verify_personal_badge_text', label: '个人认证徽标文案', type: 'input', default: '个人认证',
|
||||||
label: '认证徽标文案',
|
dependsOn: { key: 'user_verify_public_display', value: true },
|
||||||
type: 'input',
|
},
|
||||||
default: '已认证',
|
{
|
||||||
|
key: 'user_verify_enterprise_badge_text', label: '企业认证徽标文案', type: 'input', default: '企业认证',
|
||||||
dependsOn: { key: 'user_verify_public_display', value: true },
|
dependsOn: { key: 'user_verify_public_display', value: true },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'workflow',
|
key: 'workflow', title: '认证方式', icon: 'fas fa-tasks',
|
||||||
title: '审核流程',
|
fields: [{ type: 'alert', content: '认证方式固定为个人认证和企业认证,申请人不可自行新增或修改类型。' }],
|
||||||
icon: 'fas fa-tasks',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
key: 'user_verify_apply_option',
|
|
||||||
label: '申请类型选项',
|
|
||||||
type: 'textarea',
|
|
||||||
default: 'real_name|实名认证\norganization|企业认证',
|
|
||||||
help: '每行:slug|显示名称',
|
|
||||||
dependsOn: { key: 'user_verify_enabled', value: true },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'apply',
|
key: 'apply',
|
||||||
@@ -72,16 +67,12 @@ export const verifySchema = {
|
|||||||
default: '由于系统正在维护,暂时无法申请身份认证\n详情请联系管理员',
|
default: '由于系统正在维护,暂时无法申请身份认证\n详情请联系管理员',
|
||||||
dependsOn: { key: 'user_verify_allow_apply', value: false },
|
dependsOn: { key: 'user_verify_allow_apply', value: false },
|
||||||
},
|
},
|
||||||
{
|
{ key: 'user_verify_personal_fee', label: '个人认证每次扣余额(元)', type: 'number', default: 0, min: 0, step: 0.01, dependsOn: { key: 'user_verify_allow_apply', value: true } },
|
||||||
key: 'user_verify_limit_level',
|
{ key: 'user_verify_personal_free_applications', label: '个人认证赠送初始次数', type: 'number', default: 0, min: 0, max: 9999, help: '每位用户前 N 次个人认证申请免费,之后按单次费用扣余额。', dependsOn: { key: 'user_verify_allow_apply', value: true } },
|
||||||
label: '申请要求等级',
|
{ key: 'user_verify_personal_require_real_name', label: '个人认证强制填写真实姓名', type: 'switch', default: false, dependsOn: { key: 'user_verify_allow_apply', value: true } },
|
||||||
type: 'number',
|
{ key: 'user_verify_enterprise_fee', label: '企业认证每次扣余额(元)', type: 'number', default: 0, min: 0, step: 0.01, dependsOn: { key: 'user_verify_allow_apply', value: true } },
|
||||||
default: 2,
|
{ key: 'user_verify_enterprise_free_applications', label: '企业认证赠送初始次数', type: 'number', default: 0, min: 0, max: 9999, help: '每位用户前 N 次企业认证申请免费,之后按单次费用扣余额。', dependsOn: { key: 'user_verify_allow_apply', value: true } },
|
||||||
min: 0,
|
{ key: 'user_verify_enterprise_require_real_name', label: '企业认证强制填写真实姓名', type: 'switch', default: false, dependsOn: { key: 'user_verify_allow_apply', value: true } },
|
||||||
max: 99,
|
|
||||||
help: '0 表示不限制;依赖用户等级功能',
|
|
||||||
dependsOn: { key: 'user_verify_allow_apply', value: true },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'user_verify_desc',
|
key: 'user_verify_desc',
|
||||||
label: '申请介绍',
|
label: '申请介绍',
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.6" ><path fill="rgb(248,253,251)" stroke="rgb(248,253,251)" stroke-width="1" opacity="1" d="M 128.5 67 Q 136.8 65.7 139 70.5 L 140 76.5 L 97.5 132 L 88.5 133 L 79 124.5 L 60 101.5 L 60 95.5 Q 61.5 89.5 70.5 91 L 75 94.5 L 91.5 114 L 128.5 67 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 96.5 36 Q 104.8 34.7 108.5 38 L 127.5 57 L 155.5 57 L 162 61.5 L 164 65.5 L 164 93.5 L 180 109.5 L 180 111.5 L 170.5 121 L 164 114.5 L 163 84.5 L 158.5 79 L 154.5 77 L 140.5 77 L 139 77.5 L 140 72.5 L 136.5 68 L 128.5 67 L 121.5 75 L 122 73.5 L 107.5 58 Q 103.8 54.7 95.5 56 L 73.5 77 L 45.5 77 Q 39.7 78.3 37.5 83 L 37 65.5 L 40 60 L 45.5 57 L 73.5 57 L 96.5 36 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 119.5 77 L 117.5 80 L 119.5 77 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 115.5 82 L 114.5 84 L 115.5 82 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 135.5 83 L 134.5 85 L 135.5 83 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 36.5 84 L 37 86.5 L 36 86.5 L 36.5 84 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 132.5 87 L 131.5 89 L 132.5 87 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 66.5 90 L 70 90.5 L 66.5 91 L 66.5 90 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 63.5 91 L 60.5 95 L 63.5 91 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 129.5 91 L 128.5 93 L 129.5 91 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 73.5 92 L 74.5 94 L 73.5 92 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 75.5 95 L 76.5 97 L 75.5 95 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 35.5 96 L 36 114.5 L 29.5 120 L 21 110.5 L 35.5 96 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 80.5 101 L 82.5 104 L 80.5 101 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 60.5 102 L 61.5 104 L 60.5 102 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 64.5 107 L 66.5 110 L 64.5 107 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 86.5 108 L 88.5 111 L 86.5 108 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 70.5 114 L 72.5 117 L 70.5 114 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 76.5 121 L 78.5 124 L 76.5 121 Z " /><path fill="rgb(77,228,160)" stroke="rgb(77,228,160)" stroke-width="1" opacity="0.9764705882352941" d="M 82.5 128 L 84.5 131 L 82.5 128 Z " /><path fill="rgb(79,232,157)" stroke="rgb(79,232,157)" stroke-width="1" opacity="0.9607843137254902" d="M 99.5 15 L 105.5 16 L 108.5 18 L 127.5 37 L 155.5 37 L 163 42.5 L 165 48.5 L 165 74.5 L 184 93.5 Q 186.7 96.8 186 103.5 L 180.5 111 L 164 93.5 L 164 65.5 L 159.5 59 L 155.5 57 L 127.5 57 L 108.5 38 Q 104.8 34.7 96.5 36 L 73.5 57 L 45.5 57 L 40 60 L 37 65.5 L 36 95.5 L 21 111.5 L 35.5 127 L 17 108.5 Q 14 105.5 15 98.5 L 17 93.5 L 36 74.5 L 36 48.5 Q 36.9 41.9 41.5 39 L 45.5 37 L 73.5 37 L 93.5 17 L 99.5 15 Z " /><path fill="rgb(79,232,157)" stroke="rgb(79,232,157)" stroke-width="1" opacity="0.9607843137254902" d="M 164.5 127 L 165 152.5 L 164 152.5 L 164.5 127 Z " /><path fill="rgb(69,220,162)" stroke="rgb(69,220,162)" stroke-width="1" opacity="0.9882352941176471" d="M 95.5 56 Q 103.8 54.7 107.5 58 L 122 72.5 L 113.5 84 L 104.5 76 L 96.5 76 L 91.5 79 L 75.5 95 L 73.5 92 L 66.5 90 L 60 94.5 L 59.5 100 L 59 97 L 45.5 97 L 39 101.5 L 37 105.5 L 37 124.5 L 35.5 126 L 30 120.5 L 36 114.5 L 36 87.5 L 37 83.5 L 42.5 78 L 45.5 77 L 73.5 77 L 95.5 56 Z " /><path fill="rgb(69,220,162)" stroke="rgb(69,220,162)" stroke-width="1" opacity="0.9882352941176471" d="M 140.5 77 L 154.5 77 L 162 82.5 L 163 84.5 L 163 102.5 L 162 102.5 L 160.5 100 L 155.5 97 L 125 96.5 L 140.5 77 Z " /><path fill="rgb(69,220,162)" stroke="rgb(69,220,162)" stroke-width="1" opacity="0.9882352941176471" d="M 112.5 86 L 111.5 88 L 112.5 86 Z " /><path fill="rgb(69,220,162)" stroke="rgb(69,220,162)" stroke-width="1" opacity="0.9882352941176471" d="M 109.5 90 L 108.5 92 L 109.5 90 Z " />Line truncated
|
||||||
|
After Width: | Height: | Size: 8.7 KiB |
@@ -163,7 +163,13 @@ if (!function_exists('aksrt_get_user_name')) {
|
|||||||
$icon_url = esc_url((string) ($signal['icon_url'] ?? ''));
|
$icon_url = esc_url((string) ($signal['icon_url'] ?? ''));
|
||||||
$title = (string) ($signal['title'] ?? $label);
|
$title = (string) ($signal['title'] ?? $label);
|
||||||
if ($type === 'verify' && !empty($args['auth']) && $auth_html === '') {
|
if ($type === 'verify' && !empty($args['auth']) && $auth_html === '') {
|
||||||
$auth_html = '<span class="badg badg-sm ml3 aksrt-identity-chip aksrt-identity-chip--success" title="' . esc_attr($title) . '"><i class="fa fa-check-circle" aria-hidden="true"></i> ' . esc_html($label) . '</span>';
|
|
||||||
|
$auth_html = $icon_url !== ''
|
||||||
|
|
||||||
|
? '<img class="aksrt-identity-certification-icon img-icon ml3" src="' . $icon_url . '" alt="' . esc_attr($label) . '" title="' . esc_attr($title) . '" loading="lazy" decoding="async" />'
|
||||||
|
|
||||||
|
: '<span class="badg badg-sm ml3 aksrt-identity-chip aksrt-identity-chip--success" title="' . esc_attr($title) . '"><i class="fa fa-check-circle" aria-hidden="true"></i> ' . esc_html($label) . '</span>';
|
||||||
|
|
||||||
} elseif ($type === 'level' && !empty($args['level']) && $level_html === '') {
|
} elseif ($type === 'level' && !empty($args['level']) && $level_html === '') {
|
||||||
if ($icon_url !== '') {
|
if ($icon_url !== '') {
|
||||||
$level_html = '<img class="aksrt-user-level-icon img-icon ml3" src="' . $icon_url . '" alt="' . esc_attr($label) . '" title="' . esc_attr($title) . '" loading="lazy" decoding="async" />';
|
$level_html = '<img class="aksrt-user-level-icon img-icon ml3" src="' . $icon_url . '" alt="' . esc_attr($label) . '" title="' . esc_attr($title) . '" loading="lazy" decoding="async" />';
|
||||||
|
|||||||
@@ -24,10 +24,7 @@ foreach ((array) ($settings['types'] ?? []) as $type) {
|
|||||||
$type_labels[(string) ($type['slug'] ?? '')] = (string) ($type['label'] ?? '');
|
$type_labels[(string) ($type['slug'] ?? '')] = (string) ($type['label'] ?? '');
|
||||||
}
|
}
|
||||||
$apply_type = sanitize_key((string) ($apply['type'] ?? ''));
|
$apply_type = sanitize_key((string) ($apply['type'] ?? ''));
|
||||||
$limit = (int) ($settings['limit_level'] ?? 0);
|
$can_apply = !empty($settings['enabled']) && !empty($settings['allow_apply']) && $status !== 'verified';
|
||||||
$current_level = class_exists('\AKSRT\User\Level') ? (int) \AKSRT\User\Level::get_level($user_id) : 0;
|
|
||||||
$blocked_level = $limit > 0 && $current_level < $limit;
|
|
||||||
$can_apply = !empty($settings['enabled']) && !empty($settings['allow_apply']) && !$blocked_level && $status !== 'verified';
|
|
||||||
?>
|
?>
|
||||||
<div class="aksrt-user-auth-panel uc-auth-panel">
|
<div class="aksrt-user-auth-panel uc-auth-panel">
|
||||||
<?php if ($status === 'verified') :
|
<?php if ($status === 'verified') :
|
||||||
@@ -100,6 +97,7 @@ $can_apply = !empty($settings['enabled']) && !empty($settings['allow_apply']) &&
|
|||||||
<form class="aksrt-user-auth-form uc-auth-form" enctype="multipart/form-data">
|
<form class="aksrt-user-auth-form uc-auth-form" enctype="multipart/form-data">
|
||||||
<label><span><?php esc_html_e('认证类型', 'aksrt'); ?></span><select class="form-control" name="type" required><?php foreach ((array) ($settings['types'] ?? []) as $type) : ?><option value="<?php echo esc_attr((string) $type['slug']); ?>"><?php echo esc_html((string) $type['label']); ?></option><?php endforeach; ?></select></label>
|
<label><span><?php esc_html_e('认证类型', 'aksrt'); ?></span><select class="form-control" name="type" required><?php foreach ((array) ($settings['types'] ?? []) as $type) : ?><option value="<?php echo esc_attr((string) $type['slug']); ?>"><?php echo esc_html((string) $type['label']); ?></option><?php endforeach; ?></select></label>
|
||||||
<label><span><?php esc_html_e('认证身份', 'aksrt'); ?></span><input type="text" class="form-control" name="name" required minlength="4" maxlength="16" placeholder="<?php esc_attr_e('请输入 4-16 个字符', 'aksrt'); ?>"></label>
|
<label><span><?php esc_html_e('认证身份', 'aksrt'); ?></span><input type="text" class="form-control" name="name" required minlength="4" maxlength="16" placeholder="<?php esc_attr_e('请输入 4-16 个字符', 'aksrt'); ?>"></label>
|
||||||
|
<label><span>真实姓名</span><input type="text" class="form-control" name="real_name" maxlength="50" placeholder="认证方式要求时必须填写"></label>
|
||||||
<label><span><?php esc_html_e('身份简介', 'aksrt'); ?></span><textarea class="form-control" name="desc" rows="3" maxlength="300" placeholder="<?php esc_attr_e('认证通过后公开展示的身份说明', 'aksrt'); ?>"></textarea></label>
|
<label><span><?php esc_html_e('身份简介', 'aksrt'); ?></span><textarea class="form-control" name="desc" rows="3" maxlength="300" placeholder="<?php esc_attr_e('认证通过后公开展示的身份说明', 'aksrt'); ?>"></textarea></label>
|
||||||
<label><span><?php esc_html_e('申请说明', 'aksrt'); ?></span><textarea class="form-control" name="msg" rows="3" maxlength="500" placeholder="<?php esc_attr_e('说明申请缘由,便于管理员审核', 'aksrt'); ?>"></textarea></label>
|
<label><span><?php esc_html_e('申请说明', 'aksrt'); ?></span><textarea class="form-control" name="msg" rows="3" maxlength="500" placeholder="<?php esc_attr_e('说明申请缘由,便于管理员审核', 'aksrt'); ?>"></textarea></label>
|
||||||
<label class="uc-auth-upload"><span><?php esc_html_e('证明材料', 'aksrt'); ?></span><input type="file" name="image[]" accept="image/jpeg,image/png,image/gif,image/webp" multiple data-auth-files><small><?php esc_html_e('最多上传 3 张图片,单张不超过 2MB(可选)。', 'aksrt'); ?></small><div class="uc-auth-upload__previews" data-auth-previews></div></label>
|
<label class="uc-auth-upload"><span><?php esc_html_e('证明材料', 'aksrt'); ?></span><input type="file" name="image[]" accept="image/jpeg,image/png,image/gif,image/webp" multiple data-auth-files><small><?php esc_html_e('最多上传 3 张图片,单张不超过 2MB(可选)。', 'aksrt'); ?></small><div class="uc-auth-upload__previews" data-auth-previews></div></label>
|
||||||
|
|||||||
@@ -615,15 +615,21 @@ class SchemaUsers {
|
|||||||
['key' => 'display', 'title' => '公开展示', 'fields' => [
|
['key' => 'display', 'title' => '公开展示', 'fields' => [
|
||||||
['key' => 'user_verify_enabled', 'label' => '启用身份认证', 'type' => 'switch', 'default' => true],
|
['key' => 'user_verify_enabled', 'label' => '启用身份认证', 'type' => 'switch', 'default' => true],
|
||||||
['key' => 'user_verify_public_display', 'label' => '公开页显示认证徽标', 'type' => 'switch', 'default' => true],
|
['key' => 'user_verify_public_display', 'label' => '公开页显示认证徽标', 'type' => 'switch', 'default' => true],
|
||||||
['key' => 'user_verify_badge_text', 'label' => '认证徽标文案', 'type' => 'input', 'default' => '已认证'],
|
['key' => 'user_verify_personal_badge_text', 'label' => '个人认证徽标文案', 'type' => 'input', 'default' => '个人认证'],
|
||||||
|
['key' => 'user_verify_enterprise_badge_text', 'label' => '企业认证徽标文案', 'type' => 'input', 'default' => '企业认证'],
|
||||||
]],
|
]],
|
||||||
['key' => 'workflow', 'title' => '申请类型', 'fields' => [
|
['key' => 'workflow', 'title' => '认证方式', 'fields' => [
|
||||||
['key' => 'user_verify_apply_option', 'label' => '申请类型选项', 'type' => 'textarea', 'default' => "real_name|实名认证\norganization|企业认证", 'desc' => '每行:slug|显示名称'],
|
['type' => 'alert', 'content' => '认证方式固定为个人认证和企业认证,申请人不可自行新增或修改类型。'],
|
||||||
]],
|
]],
|
||||||
['key' => 'apply', 'title' => '申请设置', 'fields' => [
|
['key' => 'apply', 'title' => '申请设置', 'fields' => [
|
||||||
['key' => 'user_verify_allow_apply', 'label' => '允许用户前台申请', 'type' => 'switch', 'default' => true],
|
['key' => 'user_verify_allow_apply', 'label' => '允许用户前台申请', 'type' => 'switch', 'default' => true],
|
||||||
['key' => 'user_verify_disable_desc', 'label' => '停用申请说明', 'type' => 'textarea', 'default' => "由于系统正在维护,暂时无法申请身份认证\n详情请联系管理员"],
|
['key' => 'user_verify_disable_desc', 'label' => '停用申请说明', 'type' => 'textarea', 'default' => "由于系统正在维护,暂时无法申请身份认证\n详情请联系管理员"],
|
||||||
['key' => 'user_verify_limit_level', 'label' => '申请要求等级', 'type' => 'number', 'default' => 2, 'min' => 0, 'max' => 99, 'desc' => '0 表示不限制;依赖用户等级'],
|
['key' => 'user_verify_personal_fee', 'label' => '个人认证每次扣余额(元)', 'type' => 'number', 'default' => 0, 'min' => 0, 'step' => 0.01],
|
||||||
|
['key' => 'user_verify_personal_free_applications', 'label' => '个人认证赠送初始次数', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999, 'desc' => '每位用户前 N 次个人认证申请免费,之后按单次费用扣余额。'],
|
||||||
|
['key' => 'user_verify_personal_require_real_name', 'label' => '个人认证强制填写真实姓名', 'type' => 'switch', 'default' => false],
|
||||||
|
['key' => 'user_verify_enterprise_fee', 'label' => '企业认证每次扣余额(元)', 'type' => 'number', 'default' => 0, 'min' => 0, 'step' => 0.01],
|
||||||
|
['key' => 'user_verify_enterprise_free_applications', 'label' => '企业认证赠送初始次数', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999, 'desc' => '每位用户前 N 次企业认证申请免费,之后按单次费用扣余额。'],
|
||||||
|
['key' => 'user_verify_enterprise_require_real_name', 'label' => '企业认证强制填写真实姓名', 'type' => 'switch', 'default' => false],
|
||||||
['key' => 'user_verify_desc', 'label' => '申请介绍', 'type' => 'textarea', 'default' => '认证用户会在昵称后显示认证徽章,同时享受多种优先待遇。申请请确保信息属实。'],
|
['key' => 'user_verify_desc', 'label' => '申请介绍', 'type' => 'textarea', 'default' => '认证用户会在昵称后显示认证徽章,同时享受多种优先待遇。申请请确保信息属实。'],
|
||||||
]],
|
]],
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class UserRuntime {
|
|||||||
* User identity, level, medal, and report governance settings.
|
* User identity, level, medal, and report governance settings.
|
||||||
*
|
*
|
||||||
* @return array{
|
* @return array{
|
||||||
* verify:array{enabled:bool,public_display:bool,badge_text:string,accept_email_verified:bool,allow_apply:bool,disable_desc:string,limit_level:int,desc:string,apply_option:string},
|
* verify:array{enabled:bool,public_display:bool,allow_apply:bool,disable_desc:string,desc:string,types:array<string,array{slug:string,label:string,badge_text:string,fee:float,free_applications:int,require_real_name:bool}>},
|
||||||
* level:array{enabled:bool,public_display:bool,source:string,label_prefix:string,thresholds:array<int,int>},
|
* level:array{enabled:bool,public_display:bool,source:string,label_prefix:string,thresholds:array<int,int>},
|
||||||
* medal:array{enabled:bool,public_display:bool,limit:int,categories:array<int,array{cat_name:string,items:array<int,array{slug:string,name:string,desc:string,icon:string,get_type:string,get_val:int}>}>,items_by_slug:array<string,array{slug:string,name:string,desc:string,icon:string,get_type:string,get_val:int,cat_name:string}>},
|
* medal:array{enabled:bool,public_display:bool,limit:int,categories:array<int,array{cat_name:string,items:array<int,array{slug:string,name:string,desc:string,icon:string,get_type:string,get_val:int}>}>,items_by_slug:array<string,array{slug:string,name:string,desc:string,icon:string,get_type:string,get_val:int,cat_name:string}>},
|
||||||
* badge:array{enabled:bool,public_display:bool,limit:int,dictionary:array<int,array{slug:string,label:string,tone:string,icon_url?:string}>},
|
* badge:array{enabled:bool,public_display:bool,limit:int,dictionary:array<int,array{slug:string,label:string,tone:string,icon_url?:string}>},
|
||||||
@@ -151,21 +151,35 @@ class UserRuntime {
|
|||||||
*/
|
*/
|
||||||
public static function get_user_identity_settings(): array {
|
public static function get_user_identity_settings(): array {
|
||||||
$settings = Settings::get_all();
|
$settings = Settings::get_all();
|
||||||
$verify_badge_text = trim((string) ($settings['user_verify_badge_text'] ?? ''));
|
|
||||||
$ban_notice_text = trim((string) ($settings['user_report_ban_notice_text'] ?? ''));
|
$ban_notice_text = trim((string) ($settings['user_report_ban_notice_text'] ?? ''));
|
||||||
|
$verify_types = [
|
||||||
|
'personal' => [
|
||||||
|
'slug' => 'personal',
|
||||||
|
'label' => __('个人认证', 'aksrt'),
|
||||||
|
'badge_text' => trim((string) ($settings['user_verify_personal_badge_text'] ?? '')) ?: __('个人认证', 'aksrt'),
|
||||||
|
'fee' => max(0, round((float) ($settings['user_verify_personal_fee'] ?? 0), 2)),
|
||||||
|
'free_applications' => max(0, (int) ($settings['user_verify_personal_free_applications'] ?? 0)),
|
||||||
|
'require_real_name' => !empty($settings['user_verify_personal_require_real_name']),
|
||||||
|
],
|
||||||
|
'enterprise' => [
|
||||||
|
'slug' => 'enterprise',
|
||||||
|
'label' => __('企业认证', 'aksrt'),
|
||||||
|
'badge_text' => trim((string) ($settings['user_verify_enterprise_badge_text'] ?? '')) ?: __('企业认证', 'aksrt'),
|
||||||
|
'fee' => max(0, round((float) ($settings['user_verify_enterprise_fee'] ?? 0), 2)),
|
||||||
|
'free_applications' => max(0, (int) ($settings['user_verify_enterprise_free_applications'] ?? 0)),
|
||||||
|
'require_real_name' => !empty($settings['user_verify_enterprise_require_real_name']),
|
||||||
|
],
|
||||||
|
];
|
||||||
$medal = self::parse_medal_catalog($settings);
|
$medal = self::parse_medal_catalog($settings);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'verify' => [
|
'verify' => [
|
||||||
'enabled' => !isset($settings['user_verify_enabled']) || !empty($settings['user_verify_enabled']),
|
'enabled' => !isset($settings['user_verify_enabled']) || !empty($settings['user_verify_enabled']),
|
||||||
'public_display' => !isset($settings['user_verify_public_display']) || !empty($settings['user_verify_public_display']),
|
'public_display' => !isset($settings['user_verify_public_display']) || !empty($settings['user_verify_public_display']),
|
||||||
'badge_text' => $verify_badge_text !== '' ? $verify_badge_text : __('已认证', 'aksrt'),
|
'allow_apply' => !isset($settings['user_verify_allow_apply']) || !empty($settings['user_verify_allow_apply']),
|
||||||
'accept_email_verified' => false,
|
'disable_desc' => (string) ($settings['user_verify_disable_desc'] ?? ''),
|
||||||
'allow_apply' => !isset($settings['user_verify_allow_apply']) || !empty($settings['user_verify_allow_apply']),
|
'desc' => (string) ($settings['user_verify_desc'] ?? ''),
|
||||||
'disable_desc' => (string) ($settings['user_verify_disable_desc'] ?? ''),
|
'types' => $verify_types,
|
||||||
'limit_level' => max(0, (int) ($settings['user_verify_limit_level'] ?? 0)),
|
|
||||||
'desc' => (string) ($settings['user_verify_desc'] ?? ''),
|
|
||||||
'apply_option' => (string) ($settings['user_verify_apply_option'] ?? ''),
|
|
||||||
],
|
],
|
||||||
'level' => [
|
'level' => [
|
||||||
'enabled' => !isset($settings['user_level_s']) || !empty($settings['user_level_s']),
|
'enabled' => !isset($settings['user_level_s']) || !empty($settings['user_level_s']),
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class AuthApply {
|
|||||||
public const REVIEWED_AT_META = 'aksrt_user_verify_reviewed_at';
|
public const REVIEWED_AT_META = 'aksrt_user_verify_reviewed_at';
|
||||||
public const REVIEWER_META = 'aksrt_user_verify_reviewer';
|
public const REVIEWER_META = 'aksrt_user_verify_reviewer';
|
||||||
public const HISTORY_META = 'aksrt_user_verify_history';
|
public const HISTORY_META = 'aksrt_user_verify_history';
|
||||||
|
public const APPLICATION_COUNTS_META = 'aksrt_user_verify_application_counts';
|
||||||
|
|
||||||
private static $instance = null;
|
private static $instance = null;
|
||||||
|
|
||||||
@@ -40,49 +41,30 @@ class AuthApply {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @return array{enabled:bool,allow_apply:bool,public_display:bool,limit_level:int,desc:string,disable_desc:string,types:array<string,array{slug:string,label:string,badge_text:string,fee:float,free_applications:int,require_real_name:bool}>} */
|
||||||
* @return array{
|
|
||||||
* enabled:bool,allow_apply:bool,public_display:bool,badge_text:string,
|
|
||||||
* limit_level:int,desc:string,disable_desc:string,
|
|
||||||
* types:array<int,array{slug:string,label:string}>
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
public static function settings(): array {
|
public static function settings(): array {
|
||||||
$all = class_exists('\AKSRT\Settings\Settings')
|
$identity = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_user_identity_settings() : [];
|
||||||
? (array) \AKSRT\Settings\Settings::get_all()
|
return is_array($identity['verify'] ?? null) ? $identity['verify'] : [];
|
||||||
: [];
|
}
|
||||||
$enabled = !isset($all['user_verify_enabled']) || !empty($all['user_verify_enabled']);
|
|
||||||
$types_raw = (string) ($all['user_verify_apply_option'] ?? "real_name|实名认证\norganization|企业认证");
|
/** @return array<string,mixed> */
|
||||||
$types = [];
|
public static function type_settings(string $type): array {
|
||||||
foreach (preg_split('/\r\n|\r|\n/', $types_raw) as $line) {
|
$types = self::settings()['types'] ?? [];
|
||||||
$line = trim($line);
|
return is_array($types[sanitize_key($type)] ?? null) ? $types[sanitize_key($type)] : [];
|
||||||
if ($line === '') {
|
}
|
||||||
continue;
|
|
||||||
}
|
public static function application_count(int $user_id, string $type): int {
|
||||||
$parts = array_map('trim', explode('|', $line, 2));
|
$counts = get_user_meta($user_id, self::APPLICATION_COUNTS_META, true);
|
||||||
$slug = sanitize_key($parts[0] ?? '');
|
$counts = is_array($counts) ? $counts : [];
|
||||||
$label = $parts[1] ?? $parts[0];
|
return max(0, (int) ($counts[sanitize_key($type)] ?? 0));
|
||||||
if ($slug === '') {
|
}
|
||||||
continue;
|
|
||||||
}
|
private static function increment_application_count(int $user_id, string $type): void {
|
||||||
$types[] = ['slug' => $slug, 'label' => (string) $label];
|
$counts = get_user_meta($user_id, self::APPLICATION_COUNTS_META, true);
|
||||||
}
|
$counts = is_array($counts) ? $counts : [];
|
||||||
if ($types === []) {
|
$type = sanitize_key($type);
|
||||||
$types = [
|
$counts[$type] = max(0, (int) ($counts[$type] ?? 0)) + 1;
|
||||||
['slug' => 'real_name', 'label' => __('实名认证', 'aksrt')],
|
update_user_meta($user_id, self::APPLICATION_COUNTS_META, $counts);
|
||||||
['slug' => 'organization', 'label' => __('企业认证', 'aksrt')],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
'enabled' => $enabled,
|
|
||||||
'allow_apply' => !isset($all['user_verify_allow_apply']) || !empty($all['user_verify_allow_apply']),
|
|
||||||
'public_display' => !isset($all['user_verify_public_display']) || !empty($all['user_verify_public_display']),
|
|
||||||
'badge_text' => (string) ($all['user_verify_badge_text'] ?? __('已认证', 'aksrt')),
|
|
||||||
'limit_level' => max(0, (int) ($all['user_verify_limit_level'] ?? 0)),
|
|
||||||
'desc' => (string) ($all['user_verify_desc'] ?? ''),
|
|
||||||
'disable_desc' => (string) ($all['user_verify_disable_desc'] ?? ''),
|
|
||||||
'types' => $types,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get_status(int $user_id): string {
|
public static function get_status(int $user_id): string {
|
||||||
@@ -257,6 +239,7 @@ class AuthApply {
|
|||||||
public static function application_view(array $application, int $owner_id = 0, bool $admin_context = false): array {
|
public static function application_view(array $application, int $owner_id = 0, bool $admin_context = false): array {
|
||||||
return [
|
return [
|
||||||
'name' => (string) ($application['name'] ?? ''),
|
'name' => (string) ($application['name'] ?? ''),
|
||||||
|
'real_name' => (string) ($application['real_name'] ?? ''),
|
||||||
'desc' => (string) ($application['desc'] ?? ''),
|
'desc' => (string) ($application['desc'] ?? ''),
|
||||||
'msg' => (string) ($application['msg'] ?? ''),
|
'msg' => (string) ($application['msg'] ?? ''),
|
||||||
'type' => sanitize_key((string) ($application['type'] ?? '')),
|
'type' => sanitize_key((string) ($application['type'] ?? '')),
|
||||||
@@ -409,33 +392,27 @@ class AuthApply {
|
|||||||
if (self::get_status($user_id) === 'pending') {
|
if (self::get_status($user_id) === 'pending') {
|
||||||
wp_send_json_error(['message' => __('您的申请正在审核中', 'aksrt')], 409);
|
wp_send_json_error(['message' => __('您的申请正在审核中', 'aksrt')], 409);
|
||||||
}
|
}
|
||||||
if ($s['limit_level'] > 0 && class_exists('\AKSRT\User\Level')) {
|
|
||||||
$lv = (int) Level::get_level($user_id);
|
|
||||||
if ($lv < $s['limit_level']) {
|
|
||||||
wp_send_json_error([
|
|
||||||
'message' => sprintf(
|
|
||||||
/* translators: %d: required level */
|
|
||||||
__('等级不足,需达到 LV.%d 后申请', 'aksrt'),
|
|
||||||
$s['limit_level']
|
|
||||||
),
|
|
||||||
], 403);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = isset($_POST['name']) ? sanitize_text_field(wp_unslash((string) $_POST['name'])) : '';
|
$name = isset($_POST['name']) ? sanitize_text_field(wp_unslash((string) $_POST['name'])) : '';
|
||||||
|
$real_name = isset($_POST['real_name']) ? sanitize_text_field(wp_unslash((string) $_POST['real_name'])) : '';
|
||||||
$desc = isset($_POST['desc']) ? sanitize_textarea_field(wp_unslash((string) $_POST['desc'])) : '';
|
$desc = isset($_POST['desc']) ? sanitize_textarea_field(wp_unslash((string) $_POST['desc'])) : '';
|
||||||
$msg = isset($_POST['msg']) ? sanitize_textarea_field(wp_unslash((string) $_POST['msg'])) : '';
|
$msg = isset($_POST['msg']) ? sanitize_textarea_field(wp_unslash((string) $_POST['msg'])) : '';
|
||||||
$type = isset($_POST['type']) ? sanitize_key((string) wp_unslash($_POST['type'])) : '';
|
$type = isset($_POST['type']) ? sanitize_key((string) wp_unslash($_POST['type'])) : '';
|
||||||
$allowed_types = array_column((array) $s['types'], 'slug');
|
$type_settings = self::type_settings($type);
|
||||||
if ($this->text_length($name) < 4 || $this->text_length($name) > 16) {
|
if ($this->text_length($name) < 4 || $this->text_length($name) > 16) {
|
||||||
wp_send_json_error(['message' => __('认证身份长度需在 4-16 个字符之间', 'aksrt')], 422);
|
wp_send_json_error(['message' => __('认证身份长度需在 4-16 个字符之间', 'aksrt')], 422);
|
||||||
}
|
}
|
||||||
if ($this->text_length($desc) > 300 || $this->text_length($msg) > 500) {
|
if ($this->text_length($desc) > 300 || $this->text_length($msg) > 500) {
|
||||||
wp_send_json_error(['message' => __('认证说明内容过长', 'aksrt')], 422);
|
wp_send_json_error(['message' => __('认证说明内容过长', 'aksrt')], 422);
|
||||||
}
|
}
|
||||||
if ($type === '' || !in_array($type, $allowed_types, true)) {
|
if ($type_settings === []) {
|
||||||
wp_send_json_error(['message' => __('请选择有效的认证类型', 'aksrt')], 422);
|
wp_send_json_error(['message' => __('请选择有效的认证类型', 'aksrt')], 422);
|
||||||
}
|
}
|
||||||
|
if (!empty($type_settings['require_real_name']) && $real_name === '') {
|
||||||
|
wp_send_json_error(['message' => __('请填写真实姓名', 'aksrt')], 422);
|
||||||
|
}
|
||||||
|
if ($this->text_length($real_name) > 50) {
|
||||||
|
wp_send_json_error(['message' => __('真实姓名不能超过 50 个字符', 'aksrt')], 422);
|
||||||
|
}
|
||||||
|
|
||||||
$lock_key = 'aksrt_auth_apply_lock_' . $user_id;
|
$lock_key = 'aksrt_auth_apply_lock_' . $user_id;
|
||||||
$lock_token = wp_generate_uuid4();
|
$lock_token = wp_generate_uuid4();
|
||||||
@@ -472,26 +449,52 @@ class AuthApply {
|
|||||||
}
|
}
|
||||||
$this->renew_submission_lock($lock_key, $lock_token);
|
$this->renew_submission_lock($lock_key, $lock_token);
|
||||||
|
|
||||||
|
$free_applications = max(0, (int) ($type_settings['free_applications'] ?? 0));
|
||||||
|
$application_count = self::application_count($user_id, $type);
|
||||||
|
$fee = $application_count < $free_applications ? 0.0 : max(0, (float) ($type_settings['fee'] ?? 0));
|
||||||
|
if ($fee > 0) {
|
||||||
|
$deducted = \AKSRT\Credits\Balance::deduct(
|
||||||
|
$user_id,
|
||||||
|
$fee,
|
||||||
|
'verify_application',
|
||||||
|
['type' => 'verify', 'id' => $user_id],
|
||||||
|
sprintf(__('提交%s申请', 'aksrt'), (string) $type_settings['label'])
|
||||||
|
);
|
||||||
|
if (is_wp_error($deducted)) {
|
||||||
|
$this->delete_attachments($uploaded);
|
||||||
|
$this->release_submission_lock($lock_key, $lock_token);
|
||||||
|
wp_send_json_error(['message' => $deducted->get_error_message()], 422);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$previous_payload = self::get_apply_payload($user_id);
|
$previous_payload = self::get_apply_payload($user_id);
|
||||||
$requested_at = current_time('Y-m-d H:i');
|
$requested_at = current_time('Y-m-d H:i');
|
||||||
$payload = [
|
$payload = [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
|
'real_name' => $real_name,
|
||||||
'desc' => $desc,
|
'desc' => $desc,
|
||||||
'msg' => $msg,
|
'msg' => $msg,
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'evidence_attachment_ids' => $uploaded,
|
'evidence_attachment_ids' => $uploaded,
|
||||||
'time' => $requested_at,
|
'time' => $requested_at,
|
||||||
|
'fee' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$payload_saved = update_user_meta($user_id, self::APPLY_META, $payload);
|
$payload_saved = update_user_meta($user_id, self::APPLY_META, $payload);
|
||||||
if ($payload_saved === false && get_user_meta($user_id, self::APPLY_META, true) !== $payload) {
|
if ($payload_saved === false && get_user_meta($user_id, self::APPLY_META, true) !== $payload) {
|
||||||
$this->delete_attachments($uploaded);
|
$this->delete_attachments($uploaded);
|
||||||
|
if ($fee > 0) {
|
||||||
|
\AKSRT\Credits\Balance::add($user_id, $fee, 'verify_application_refund', ['type' => 'verify', 'id' => $user_id], __('认证申请保存失败退款', 'aksrt'));
|
||||||
|
}
|
||||||
$this->release_submission_lock($lock_key, $lock_token);
|
$this->release_submission_lock($lock_key, $lock_token);
|
||||||
wp_send_json_error(['message' => __('认证申请保存失败,请重试', 'aksrt')], 500);
|
wp_send_json_error(['message' => __('认证申请保存失败,请重试', 'aksrt')], 500);
|
||||||
}
|
}
|
||||||
$status_saved = update_user_meta($user_id, self::STATUS_META, 'pending');
|
$status_saved = update_user_meta($user_id, self::STATUS_META, 'pending');
|
||||||
if ($status_saved === false && self::get_status($user_id) !== 'pending') {
|
if ($status_saved === false && self::get_status($user_id) !== 'pending') {
|
||||||
$this->delete_attachments($uploaded);
|
$this->delete_attachments($uploaded);
|
||||||
|
if ($fee > 0) {
|
||||||
|
\AKSRT\Credits\Balance::add($user_id, $fee, 'verify_application_refund', ['type' => 'verify', 'id' => $user_id], __('认证申请保存失败退款', 'aksrt'));
|
||||||
|
}
|
||||||
$previous_payload === []
|
$previous_payload === []
|
||||||
? delete_user_meta($user_id, self::APPLY_META)
|
? delete_user_meta($user_id, self::APPLY_META)
|
||||||
: update_user_meta($user_id, self::APPLY_META, $previous_payload);
|
: update_user_meta($user_id, self::APPLY_META, $previous_payload);
|
||||||
@@ -502,6 +505,7 @@ class AuthApply {
|
|||||||
delete_user_meta($user_id, self::REVIEWED_AT_META);
|
delete_user_meta($user_id, self::REVIEWED_AT_META);
|
||||||
delete_user_meta($user_id, self::REVIEWER_META);
|
delete_user_meta($user_id, self::REVIEWER_META);
|
||||||
delete_user_meta($user_id, self::REASON_META);
|
delete_user_meta($user_id, self::REASON_META);
|
||||||
|
self::increment_application_count($user_id, $type);
|
||||||
|
|
||||||
if (!$this->owns_submission_lock($lock_key, $lock_token)) {
|
if (!$this->owns_submission_lock($lock_key, $lock_token)) {
|
||||||
$this->release_submission_lock($lock_key, $lock_token);
|
$this->release_submission_lock($lock_key, $lock_token);
|
||||||
|
|||||||
+14
-6
@@ -139,12 +139,20 @@ class Home {
|
|||||||
$signals = [];
|
$signals = [];
|
||||||
|
|
||||||
if (!empty($settings['verify']['enabled']) && !empty($settings['verify']['public_display']) && $this->is_user_verified($user_id, $settings['verify'])) {
|
if (!empty($settings['verify']['enabled']) && !empty($settings['verify']['public_display']) && $this->is_user_verified($user_id, $settings['verify'])) {
|
||||||
$signals[] = [
|
$info = class_exists('AKSRT\\User\\AuthApply') ? AuthApply::get_auth_info($user_id) : [];
|
||||||
'type' => 'verify',
|
$type = sanitize_key((string) ($info['type'] ?? ''));
|
||||||
'label' => (string) $settings['verify']['badge_text'],
|
$type_settings = is_array($settings['verify']['types'][$type] ?? null) ? $settings['verify']['types'][$type] : [];
|
||||||
'icon' => 'check-circle',
|
if ($type_settings !== []) {
|
||||||
'tone' => 'success',
|
$label = (string) $type_settings['badge_text'];
|
||||||
];
|
$signals[] = [
|
||||||
|
'type' => 'verify',
|
||||||
|
'label' => $label,
|
||||||
|
'title' => $label,
|
||||||
|
'icon' => 'check-circle',
|
||||||
|
'icon_url' => get_theme_file_uri('/assets/img/user/user-certification.svg'),
|
||||||
|
'tone' => 'success',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($settings['level']['enabled']) && !empty($settings['level']['public_display'])) {
|
if (!empty($settings['level']['enabled']) && !empty($settings['level']['public_display'])) {
|
||||||
|
|||||||
Reference in new issue
Block a user