feat(users): normalize center routes and withdrawal limits
This commit is contained in:
@@ -245,6 +245,7 @@ class SchemaPageDisplay {
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
['key' => 'layout', 'title' => '主页布局', 'fields' => [
|
||||
['key' => 'user_home_route_identifier', 'label' => '主页 URL 标识', 'type' => 'select', 'default' => 'nicename', 'options' => [['label' => '用户名 URL slug', 'value' => 'nicename'], ['label' => '数字用户 ID', 'value' => 'uid']]],
|
||||
['key' => 'user_home_cover', 'label' => '封面区域', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_home_sidebar', 'label' => '侧边栏(已弃用)', 'type' => 'switch', 'default' => false, 'help' => '公开主页对齐 Zibll 作者页为通栏布局;交易/快捷入口仅在用户中心展示。此开关保留兼容,运行时强制关闭。'],
|
||||
['key' => 'user_home_follow', 'label' => '关注按钮', 'type' => 'switch', 'default' => true],
|
||||
|
||||
@@ -97,7 +97,6 @@ class SchemaPayment {
|
||||
]],
|
||||
['key' => 'withdraw', 'title' => '余额提现', 'fields' => [
|
||||
['key' => 'pay_balance_withdraw_s', 'label' => '启用余额提现', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'pay_balance_s', 'value' => true]],
|
||||
['key' => 'pay_balance_withdraw_lowest_money', 'label' => '最低提现金额', 'type' => 'number', 'default' => 50, 'min' => 1, 'max' => 99999, 'dependsOn' => ['key' => 'pay_balance_withdraw_s', 'value' => true]],
|
||||
]],
|
||||
],
|
||||
],
|
||||
@@ -373,11 +372,11 @@ class SchemaPayment {
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
['key' => 'basic', 'title' => '提现设置', 'fields' => [
|
||||
['key' => 'pay_rebate_withdraw_lowest_money', 'label' => '最低提现金额', 'type' => 'number', 'default' => 50, 'min' => 1, 'max' => 99999],
|
||||
['key' => 'withdraw_service_charge', 'label' => '提现手续费(%)', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 50],
|
||||
['key' => 'pay_rebate_withdraw_text_details', 'label' => '提现说明', 'type' => 'textarea', 'default' => '<div>可提现金额达到50元后即可发起提现</div>
|
||||
<div>申请提现需后台人工处理,一般2-3小时,请耐心等待</div>
|
||||
<div>如有其它疑问,请与客服联系</div>'],
|
||||
['key' => 'pay_rebate_withdraw_lowest_money', 'label' => '最低提现金额', 'type' => 'number', 'default' => 50, 'min' => 0, 'max' => 99999],
|
||||
['key' => 'withdraw_service_charge', 'label' => '提现手续费(%)', 'type' => 'number', 'default' => 5, 'min' => 0, 'max' => 50],
|
||||
['key' => 'withdraw_daily_count', 'label' => '每日可提现次数', 'type' => 'number', 'default' => 3, 'min' => 0, 'max' => 99999, 'sanitize_type' => 'int'],
|
||||
['key' => 'withdraw_daily_limit', 'label' => '每日提现上限', 'type' => 'number', 'default' => 50, 'min' => 0, 'max' => 999999],
|
||||
['key' => 'withdraw_reset_time', 'label' => '重置时间', 'type' => 'input', 'default' => '00:00', 'help' => '按站点 WordPress 时区重置,格式 HH:MM。'],
|
||||
]],
|
||||
],
|
||||
],
|
||||
|
||||
@@ -207,6 +207,24 @@ class SchemaProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if ($domain === 'payment' && $section === 'withdrawal') {
|
||||
$stored = get_option('aksrt_settings', []);
|
||||
$merged = is_array($stored) ? array_merge($stored, $data) : $data;
|
||||
$count = $merged['withdraw_daily_count'] ?? 3;
|
||||
$min = (float) ($merged['pay_rebate_withdraw_lowest_money'] ?? 50);
|
||||
$limit = (float) ($merged['withdraw_daily_limit'] ?? 50);
|
||||
$time = (string) ($merged['withdraw_reset_time'] ?? '00:00');
|
||||
if (filter_var($count, FILTER_VALIDATE_INT) === false || (int) $count < 0) {
|
||||
$errors[] = __('每日可提现次数必须是非负整数', 'aksrt');
|
||||
}
|
||||
if ($limit < $min) {
|
||||
$errors[] = __('每日提现上限不得低于最低提现金额', 'aksrt');
|
||||
}
|
||||
if (preg_match('/^(?:[01]\\d|2[0-3]):[0-5]\\d$/', $time) !== 1) {
|
||||
$errors[] = __('重置时间必须为 HH:MM', 'aksrt');
|
||||
}
|
||||
}
|
||||
|
||||
return ['valid' => empty($errors), 'errors' => $errors];
|
||||
}
|
||||
|
||||
@@ -318,6 +336,10 @@ class SchemaProvider {
|
||||
$stored[$key] = $value;
|
||||
}
|
||||
|
||||
if (($schema['key'] ?? '') === 'withdrawal') {
|
||||
unset($stored['pay_rebate_withdraw_text_details'], $stored['pay_balance_withdraw_lowest_money']);
|
||||
}
|
||||
|
||||
// Captcha: keep enabled_scenarios / disabled_scenarios mirrors in sync.
|
||||
if ($option_key === 'aksrt_captcha_config' && function_exists('aksrt_captcha_scenes')) {
|
||||
$all = array_keys(aksrt_captcha_scenes());
|
||||
|
||||
@@ -165,7 +165,7 @@ trait OAuthPart2 {
|
||||
}
|
||||
$user = wp_get_current_user();
|
||||
if ($user->ID) {
|
||||
return home_url('/user/' . $user->user_nicename . '/');
|
||||
return function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($user) : home_url('/');
|
||||
}
|
||||
return home_url('/');
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class DBMigrator {
|
||||
use DBMigratorVip;
|
||||
|
||||
/** Current schema version; changing it re-runs dbDelta. */
|
||||
const SCHEMA_VERSION = '1.21.0';
|
||||
const SCHEMA_VERSION = '1.22.0';
|
||||
|
||||
const OPT_KEY = 'aksrt_db_schema_version';
|
||||
|
||||
|
||||
@@ -224,6 +224,7 @@ trait DBMigratorPart2 {
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
amount DECIMAL(10,2) NOT NULL DEFAULT 0,
|
||||
gross_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
|
||||
method VARCHAR(32) NOT NULL DEFAULT '',
|
||||
account_info TEXT DEFAULT NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
@@ -232,6 +233,7 @@ trait DBMigratorPart2 {
|
||||
note TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_user (user_id),
|
||||
KEY idx_user_created (user_id, created_at),
|
||||
KEY idx_status (status),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
|
||||
@@ -292,7 +292,7 @@ $hmb_js = get_template_directory() . '/assets/js/header-newadd.js';
|
||||
$is_resource_archive = function_exists('aksrt_is_resource_archive') && aksrt_is_resource_archive();
|
||||
// /user/{nicename}/ 自定义重写路由(class-aksrt-user.php 注册)
|
||||
// 此路径下 is_page() / is_page_template() 均为 false,需手动识别以正确入队 CSS
|
||||
$is_profile_route = (bool) get_query_var('user_nicename');
|
||||
$is_profile_route = (bool) get_query_var('aksrt_author_identifier');
|
||||
$is_user_center_route = (bool) get_query_var('aksrt_user_center');
|
||||
$is_static_page = is_page() || is_singular('page') || $is_profile_route || $is_user_center_route;
|
||||
$is_auth_route = (bool) get_query_var('aksrt_sign');
|
||||
|
||||
@@ -111,7 +111,7 @@ trait ScriptsPart2 {
|
||||
}
|
||||
if ((function_exists('aksrt_is_user_center_page') && aksrt_is_user_center_page())
|
||||
|| (function_exists('aksrt_is_user_home_page') && aksrt_is_user_home_page())
|
||||
|| get_query_var('user_nicename')) {
|
||||
|| get_query_var('aksrt_author_identifier')) {
|
||||
$classes[] = 'aksrt-profile';
|
||||
}
|
||||
// 区分本人中心与公开主页的 body class
|
||||
|
||||
@@ -398,50 +398,37 @@ trait BalanceServiceRest {
|
||||
if (class_exists('\AKSRT\Settings\Capabilities') && !\AKSRT\Settings\Capabilities::user_can('balance_withdraw', $user_id)) {
|
||||
return new \WP_Error('aksrt_withdraw_forbidden', __('当前账号无权提现', 'aksrt'), ['status' => 403]);
|
||||
}
|
||||
$amount = round((float) ($params['amount'] ?? 0), 2);
|
||||
$raw_amount = $params['amount'] ?? 0;
|
||||
if (filter_var($raw_amount, FILTER_VALIDATE_INT) === false || (int) $raw_amount <= 0) {
|
||||
return new \WP_Error('aksrt_withdraw_amount', __('提现金额必须为正整数', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$amount = (int) $raw_amount;
|
||||
$method = sanitize_key((string) ($params['method'] ?? 'alipay'));
|
||||
$account = sanitize_textarea_field((string) ($params['account_info'] ?? $params['account'] ?? ''));
|
||||
$lowest = max(1, (float) ($settings['pay_balance_withdraw_lowest_money'] ?? $settings['pay_rebate_withdraw_lowest_money'] ?? 50));
|
||||
$withdraw_settings = class_exists('\\AKSRT\\Settings\\Settings')
|
||||
? \AKSRT\Settings\Settings::get_withdrawal_settings()
|
||||
: ['min_amount' => 50, 'service_charge_rate' => 5, 'daily_count' => 3, 'daily_limit' => 50, 'reset_time' => '00:00'];
|
||||
$lowest = (float) $withdraw_settings['min_amount'];
|
||||
if ($amount < $lowest) {
|
||||
return new \WP_Error('aksrt_withdraw_min', sprintf(__('最低提现 %s 元', 'aksrt'), (string) $lowest), ['status' => 400]);
|
||||
return new \WP_Error('withdraw_min_amount', sprintf(__('提现金额低于最低提现门槛(%s 元)', 'aksrt'), (string) $lowest), ['status' => 400]);
|
||||
}
|
||||
if ($account === '') {
|
||||
return new \WP_Error('aksrt_withdraw_account', __('请填写收款账号信息', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
// One open balance withdrawal at a time (Zibll parity).
|
||||
if (\AKSRT\Payment\Withdrawal::get_instance()->has_open_withdrawal($user_id)) {
|
||||
return new \WP_Error('aksrt_withdraw_pending', __('您有处理中的提现申请,请等待完成后再申请', 'aksrt'), ['status' => 409]);
|
||||
}
|
||||
$wallet = Balance::balance($user_id);
|
||||
if ($wallet < $amount) {
|
||||
return new \WP_Error('aksrt_balance_insufficient', __('余额不足', 'aksrt'), ['status' => 402]);
|
||||
}
|
||||
$deduct = Balance::deduct($user_id, $amount, 'withdraw_hold', ['type' => 'withdraw'], __('余额提现申请冻结', 'aksrt'));
|
||||
if (is_wp_error($deduct)) {
|
||||
return $deduct;
|
||||
}
|
||||
$fee_rate = max(0, min(50, (int) ($settings['withdraw_service_charge'] ?? 0)));
|
||||
$net = $fee_rate > 0 ? round($amount * (100 - $fee_rate) / 100, 2) : $amount;
|
||||
$account_payload = wp_json_encode([
|
||||
'account' => $account,
|
||||
'gross_amount' => $amount,
|
||||
'fee_rate' => $fee_rate,
|
||||
'source' => 'balance',
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?: $account;
|
||||
$wid = \AKSRT\Payment\Withdrawal::get_instance()->create($user_id, $net, $method !== '' ? $method : 'alipay', $account_payload);
|
||||
if ($wid <= 0) {
|
||||
Balance::add($user_id, $amount, 'withdraw_refund', [], __('提现申请失败退回', 'aksrt'));
|
||||
return new \WP_Error('aksrt_withdraw_failed', __('提现申请失败', 'aksrt'), ['status' => 500]);
|
||||
$result = \AKSRT\Payment\Withdrawal::get_instance()->create_balance_request($user_id, $amount, $method !== '' ? $method : 'alipay', $account, $withdraw_settings);
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
return rest_ensure_response([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'message' => __('提现申请已提交,请等待处理', 'aksrt'),
|
||||
'withdrawal_id' => $wid,
|
||||
'withdrawal_id' => $result['withdrawal_id'],
|
||||
'amount' => $amount,
|
||||
'net_amount' => $net,
|
||||
'wallet_balance' => Balance::balance($user_id),
|
||||
'reload' => true,
|
||||
'net_amount' => $result['net_amount'],
|
||||
'wallet_balance' => $result['wallet_balance'],
|
||||
'remaining_count' => $result['usage']['remaining_count'],
|
||||
'remaining_amount' => $result['usage']['remaining_amount'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
+112
-2
@@ -30,7 +30,7 @@ class Withdrawal {
|
||||
/**
|
||||
* 创建提现申请
|
||||
*/
|
||||
public function create(int $user_id, float $amount, string $method = '', string $account_info = ''): int {
|
||||
public function create(int $user_id, float $amount, string $method = '', string $account_info = '', ?float $gross_amount = null): int {
|
||||
global $wpdb;
|
||||
|
||||
if ($user_id <= 0 || $amount <= 0) {
|
||||
@@ -40,15 +40,122 @@ class Withdrawal {
|
||||
$wpdb->insert($this->table(), [
|
||||
'user_id' => $user_id,
|
||||
'amount' => $amount,
|
||||
'gross_amount' => $gross_amount === null ? $amount : $gross_amount,
|
||||
'method' => sanitize_key($method),
|
||||
'account_info' => sanitize_textarea_field($account_info),
|
||||
'status' => self::STATUS_PENDING,
|
||||
'created_at' => current_time('mysql'),
|
||||
], ['%d', '%f', '%s', '%s', '%s', '%s']);
|
||||
], ['%d', '%f', '%f', '%s', '%s', '%s', '%s']);
|
||||
|
||||
return (int) $wpdb->insert_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Daily withdrawal window in the configured WordPress timezone.
|
||||
* @return array{start:string,end:string}
|
||||
*/
|
||||
public function daily_window(string $reset_time = '00:00', ?\DateTimeInterface $now = null): array {
|
||||
if (preg_match('/^(?:[01]\\d|2[0-3]):[0-5]\\d$/', $reset_time) !== 1) {
|
||||
$reset_time = '00:00';
|
||||
}
|
||||
$tz = wp_timezone();
|
||||
$local_now = $now ? \DateTimeImmutable::createFromInterface($now)->setTimezone($tz) : new \DateTimeImmutable('now', $tz);
|
||||
$today_reset = new \DateTimeImmutable($local_now->format('Y-m-d') . ' ' . $reset_time . ':00', $tz);
|
||||
$start = $local_now < $today_reset ? $today_reset->modify('-1 day') : $today_reset;
|
||||
return ['start' => $start->format('Y-m-d H:i:s'), 'end' => $start->modify('+1 day')->format('Y-m-d H:i:s')];
|
||||
}
|
||||
|
||||
/** @return array{count:int,total:float,remaining_count:int,remaining_amount:float,window:array{start:string,end:string}} */
|
||||
public function daily_usage(int $user_id, array $settings): array {
|
||||
$window = $this->daily_window((string) ($settings['reset_time'] ?? '00:00'));
|
||||
return $this->daily_usage_in_window($user_id, $settings, $window);
|
||||
}
|
||||
|
||||
/** @return array{count:int,total:float,remaining_count:int,remaining_amount:float,window:array{start:string,end:string}} */
|
||||
private function daily_usage_in_window(int $user_id, array $settings, array $window): array {
|
||||
global $wpdb;
|
||||
$row = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT COUNT(*) AS count, COALESCE(SUM(CASE WHEN gross_amount > 0 THEN gross_amount ELSE amount END), 0) AS total FROM {$this->table()} WHERE user_id = %d AND created_at >= %s AND created_at < %s",
|
||||
$user_id, $window['start'], $window['end']
|
||||
), ARRAY_A);
|
||||
$count = (int) ($row['count'] ?? 0);
|
||||
$total = round((float) ($row['total'] ?? 0), 2);
|
||||
$max_count = max(0, (int) ($settings['daily_count'] ?? 3));
|
||||
$max_amount = max(0, (float) ($settings['daily_limit'] ?? 50));
|
||||
return [
|
||||
'count' => $count,
|
||||
'total' => $total,
|
||||
'remaining_count' => max(0, $max_count - $count),
|
||||
'remaining_amount' => max(0, round($max_amount - $total, 2)),
|
||||
'window' => $window,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically validates quotas, freezes wallet funds, writes the ledger and creates an order.
|
||||
* @return array{withdrawal_id:int,net_amount:float,wallet_balance:float,usage:array}|\WP_Error
|
||||
*/
|
||||
public function create_balance_request(int $user_id, int $gross_amount, string $method, string $account, array $settings) {
|
||||
global $wpdb;
|
||||
if ($user_id <= 0 || $gross_amount <= 0) {
|
||||
return new \WP_Error('aksrt_withdraw_amount', __('提现金额必须为正整数', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
if (!class_exists('\AKSRT\\Credits\\Balance')) {
|
||||
return new \WP_Error('aksrt_withdraw_unavailable', __('提现服务不可用', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
$meta_table = $wpdb->usermeta;
|
||||
$meta_key = \AKSRT\Credits\Balance::META_KEY;
|
||||
if (!metadata_exists('user', $user_id, $meta_key)) {
|
||||
add_user_meta($user_id, $meta_key, '0', true);
|
||||
}
|
||||
$wpdb->query('START TRANSACTION');
|
||||
try {
|
||||
$meta_id = $wpdb->get_var($wpdb->prepare("SELECT umeta_id FROM {$meta_table} WHERE user_id = %d AND meta_key = %s LIMIT 1 FOR UPDATE", $user_id, $meta_key));
|
||||
if (!$meta_id) {
|
||||
throw new \RuntimeException('wallet row unavailable');
|
||||
}
|
||||
$window = $this->daily_window((string) ($settings['reset_time'] ?? '00:00'));
|
||||
$usage = $this->daily_usage_in_window($user_id, $settings, $window);
|
||||
if ($usage['remaining_count'] <= 0) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
return new \WP_Error('withdraw_count_limit', __('当日提现次数已用尽', 'aksrt'), ['status' => 409]);
|
||||
}
|
||||
if ($gross_amount > $usage['remaining_amount']) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
return new \WP_Error('withdraw_amount_limit', __('本次提现后将超出单日提现总额上限', 'aksrt'), ['status' => 409]);
|
||||
}
|
||||
$before = (float) $wpdb->get_var($wpdb->prepare("SELECT meta_value FROM {$meta_table} WHERE umeta_id = %d", $meta_id));
|
||||
if ($before < $gross_amount) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
return new \WP_Error('aksrt_balance_insufficient', __('余额不足', 'aksrt'), ['status' => 402]);
|
||||
}
|
||||
$after = round($before - $gross_amount, 2);
|
||||
if ($wpdb->update($meta_table, ['meta_value' => (string) $after], ['umeta_id' => $meta_id], ['%s'], ['%d']) !== 1) {
|
||||
throw new \RuntimeException('wallet update failed');
|
||||
}
|
||||
$fee_rate = max(0, min(50, (int) ($settings['service_charge_rate'] ?? 5)));
|
||||
$net = round($gross_amount * (100 - $fee_rate) / 100, 2);
|
||||
$payload = wp_json_encode(['account' => $account, 'gross_amount' => $gross_amount, 'fee_rate' => $fee_rate, 'source' => 'balance'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?: $account;
|
||||
$ok = $wpdb->insert($this->table(), [
|
||||
'user_id' => $user_id, 'amount' => $net, 'gross_amount' => $gross_amount, 'method' => sanitize_key($method),
|
||||
'account_info' => $payload, 'status' => self::STATUS_PENDING, 'created_at' => current_time('mysql'),
|
||||
], ['%d', '%f', '%f', '%s', '%s', '%s', '%s']);
|
||||
if (!$ok) { throw new \RuntimeException('withdrawal insert failed'); }
|
||||
$withdrawal_id = (int) $wpdb->insert_id;
|
||||
\AKSRT\Credits\Balance::log($user_id, -$gross_amount, $after, 'withdraw_hold', ['type' => 'withdraw', 'id' => $withdrawal_id], __('余额提现申请冻结', 'aksrt'));
|
||||
$wpdb->query('COMMIT');
|
||||
wp_cache_delete($user_id, 'user_meta');
|
||||
$usage['count']++;
|
||||
$usage['total'] = round($usage['total'] + $gross_amount, 2);
|
||||
$usage['remaining_count']--;
|
||||
$usage['remaining_amount'] = max(0, round($usage['remaining_amount'] - $gross_amount, 2));
|
||||
return ['withdrawal_id' => $withdrawal_id, 'net_amount' => $net, 'wallet_balance' => $after, 'usage' => $usage];
|
||||
} catch (\Throwable $e) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
return new \WP_Error('aksrt_withdraw_failed', __('提现申请失败', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single row.
|
||||
*
|
||||
@@ -394,6 +501,9 @@ class Withdrawal {
|
||||
* @param array<string,mixed> $meta
|
||||
*/
|
||||
private function resolve_gross_amount(array $row, array $meta): float {
|
||||
if ((float) ($row['gross_amount'] ?? 0) > 0) {
|
||||
return max(0, round((float) $row['gross_amount'], 2));
|
||||
}
|
||||
if (isset($meta['gross_amount'])) {
|
||||
return max(0, round((float) $meta['gross_amount'], 2));
|
||||
}
|
||||
|
||||
@@ -438,16 +438,18 @@ class PaymentRuntime {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{min_amount:int,service_charge_rate:int,text:string}
|
||||
*/
|
||||
/** @return array{min_amount:float,service_charge_rate:int,daily_count:int,daily_limit:float,reset_time:string} */
|
||||
public static function get_withdrawal_settings(): array {
|
||||
$s = Settings::get_all();
|
||||
|
||||
return [
|
||||
'min_amount' => max(1, min(99999, (int) ($s['pay_rebate_withdraw_lowest_money'] ?? 50))),
|
||||
'service_charge_rate' => max(0, min(50, (int) ($s['withdraw_service_charge'] ?? 0))),
|
||||
'text' => sanitize_textarea_field((string) ($s['pay_rebate_withdraw_text_details'] ?? '')),
|
||||
'min_amount' => max(0, min(99999, (float) ($s['pay_rebate_withdraw_lowest_money'] ?? 50))),
|
||||
'service_charge_rate' => max(0, min(50, (int) ($s['withdraw_service_charge'] ?? 5))),
|
||||
'daily_count' => max(0, min(99999, (int) ($s['withdraw_daily_count'] ?? 3))),
|
||||
'daily_limit' => max(0, min(999999, (float) ($s['withdraw_daily_limit'] ?? 50))),
|
||||
'reset_time' => preg_match('/^(?:[01]\\d|2[0-3]):[0-5]\\d$/', (string) ($s['withdraw_reset_time'] ?? '00:00'))
|
||||
? (string) $s['withdraw_reset_time']
|
||||
: '00:00',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ class UserRuntime {
|
||||
$mobile_hide = $parse_csv('user_home_tabs_mobile_hide', '');
|
||||
|
||||
return [
|
||||
'route_identifier' => (($settings['user_home_route_identifier'] ?? 'nicename') === 'uid') ? 'uid' : 'nicename',
|
||||
'tabs' => $normalized_tabs,
|
||||
'tabs_order' => $ordered,
|
||||
'tabs_pc_hide' => $pc_hide,
|
||||
|
||||
Reference in New Issue
Block a user