refactor(referral): prune dead code and formalize ops list header
- remove unused AuthReader::invitation_mode and ReferralAttribution helpers (get_or_create_code / validate_ref); contract test now asserts the canonical invit_code_s reader in CreditsRuntime - drop legacy aksrt_invite table from uninstall cleanup list - track referral code creation time (aksrt_referral_code_created) and surface it in the referral ops REST list - formalize ops list headers (归属用户/推广码/启用状态/推广用户数/ 有效付费用户数/创建时间) and right-align count columns
This commit is contained in:
@@ -31,7 +31,7 @@ trait UsersMenusReferral {
|
||||
<option value="disabled"><?php esc_html_e('已禁用', 'aksrt'); ?></option>
|
||||
<option value="missing"><?php esc_html_e('未生成', 'aksrt'); ?></option>
|
||||
</select>
|
||||
<input type="search" id="aksrt-ref-search" placeholder="<?php esc_attr_e('搜索用户或 Ref 码', 'aksrt'); ?>">
|
||||
<input type="search" id="aksrt-ref-search" placeholder="<?php esc_attr_e('搜索归属用户或推广码', 'aksrt'); ?>">
|
||||
<button type="button" class="button" id="aksrt-ref-filter"><?php esc_html_e('筛选', 'aksrt'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,14 +39,15 @@ trait UsersMenusReferral {
|
||||
<div id="aksrt-ref-notice" role="status" aria-live="polite"></div>
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead><tr>
|
||||
<th><?php esc_html_e('用户', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('Ref 推广码', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('状态', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('绑定用户', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('有效付费用户', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('归属用户', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('推广码', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('启用状态', 'aksrt'); ?></th>
|
||||
<th style="text-align:right;"><?php esc_html_e('推广用户数', 'aksrt'); ?></th>
|
||||
<th style="text-align:right;"><?php esc_html_e('有效付费用户数', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('创建时间', 'aksrt'); ?></th>
|
||||
<th><?php esc_html_e('操作', 'aksrt'); ?></th>
|
||||
</tr></thead>
|
||||
<tbody id="aksrt-ref-rows"><tr><td colspan="6"><?php esc_html_e('正在加载…', 'aksrt'); ?></td></tr></tbody>
|
||||
<tbody id="aksrt-ref-rows"><tr><td colspan="7"><?php esc_html_e('正在加载…', 'aksrt'); ?></td></tr></tbody>
|
||||
</table>
|
||||
<div class="tablenav bottom"><div class="tablenav-pages" id="aksrt-ref-pages"></div></div>
|
||||
</div>
|
||||
@@ -102,7 +103,7 @@ trait UsersMenusReferral {
|
||||
const load = async (page = 1) => {
|
||||
currentPage = page;
|
||||
setNotice('');
|
||||
rows.innerHTML = '<tr><td colspan="6"><?php echo esc_js(__('正在加载…', 'aksrt')); ?></td></tr>';
|
||||
rows.innerHTML = '<tr><td colspan="7"><?php echo esc_js(__('正在加载…', 'aksrt')); ?></td></tr>';
|
||||
const url = new URL(endpoint);
|
||||
url.searchParams.set('page', String(page));
|
||||
url.searchParams.set('per_page', '20');
|
||||
@@ -115,10 +116,11 @@ trait UsersMenusReferral {
|
||||
<td><strong>${escapeHtml(item.user.name)}</strong><br><small>${escapeHtml(item.user.login)} · #${Number(item.user.id)}</small></td>
|
||||
<td>${item.ref ? `<code>${escapeHtml(item.ref)}</code>` : '—'}</td>
|
||||
<td>${escapeHtml({active:'<?php echo esc_js(__('已启用', 'aksrt')); ?>',disabled:'<?php echo esc_js(__('已禁用', 'aksrt')); ?>',missing:'<?php echo esc_js(__('未生成', 'aksrt')); ?>'}[item.status] || item.status)}</td>
|
||||
<td>${Number(item.bound_count || 0)}</td>
|
||||
<td>${Number(item.effective_payers || 0)}</td>
|
||||
<td style="text-align:right;">${Number(item.bound_count || 0)}</td>
|
||||
<td style="text-align:right;">${Number(item.effective_payers || 0)}</td>
|
||||
<td>${item.created_at ? escapeHtml(item.created_at) : '—'}</td>
|
||||
<td>${actionButton(item)}</td>
|
||||
</tr>`).join('') : '<tr><td colspan="6"><?php echo esc_js(__('没有符合条件的用户', 'aksrt')); ?></td></tr>';
|
||||
</tr>`).join('') : '<tr><td colspan="7"><?php echo esc_js(__('没有符合条件的用户', 'aksrt')); ?></td></tr>';
|
||||
pages.innerHTML = Array.from({length: Number(data.max_pages || 1)}, (_, index) => {
|
||||
const number = index + 1;
|
||||
return `<button type="button" class="button ${number === Number(data.page) ? 'button-primary' : ''}" data-ref-page="${number}">${number}</button>`;
|
||||
|
||||
@@ -14,6 +14,8 @@ final class ReferralAttribution {
|
||||
private const COOKIE = 'aksrt_referral';
|
||||
private const META_CODE = 'aksrt_referral_code';
|
||||
private const META_STATUS = 'aksrt_referral_code_status';
|
||||
/** 推广码生成时间(新生成的码才有;历史码为空,后台列表显示 —)。 */
|
||||
private const META_CREATED = 'aksrt_referral_code_created';
|
||||
private const STATUS_ACTIVE = 'active';
|
||||
private const STATUS_DISABLED = 'disabled';
|
||||
|
||||
@@ -258,14 +260,6 @@ final class ReferralAttribution {
|
||||
];
|
||||
}
|
||||
|
||||
public function get_or_create_code(int $user_id): string {
|
||||
return (string) ($this->create_link($user_id)['ref'] ?? '');
|
||||
}
|
||||
|
||||
public function validate_ref(string $ref): bool {
|
||||
return $this->resolve_promoter($ref) > 0;
|
||||
}
|
||||
|
||||
public function resolve(int $user_id = 0): int {
|
||||
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
@@ -482,9 +476,10 @@ final class ReferralAttribution {
|
||||
|
||||
$where_sql = implode(' AND ', $where);
|
||||
$joins = $wpdb->prepare(
|
||||
"LEFT JOIN {$wpdb->usermeta} code ON code.user_id=u.ID AND code.meta_key=%s LEFT JOIN {$wpdb->usermeta} state ON state.user_id=u.ID AND state.meta_key=%s",
|
||||
"LEFT JOIN {$wpdb->usermeta} code ON code.user_id=u.ID AND code.meta_key=%s LEFT JOIN {$wpdb->usermeta} state ON state.user_id=u.ID AND state.meta_key=%s LEFT JOIN {$wpdb->usermeta} created ON created.user_id=u.ID AND created.meta_key=%s",
|
||||
self::META_CODE,
|
||||
self::META_STATUS
|
||||
self::META_STATUS,
|
||||
self::META_CREATED
|
||||
);
|
||||
$count_sql = "SELECT COUNT(DISTINCT u.ID) FROM {$wpdb->users} u {$joins} WHERE {$where_sql}";
|
||||
$total = (int) ($params
|
||||
@@ -495,7 +490,7 @@ final class ReferralAttribution {
|
||||
$ledger_table = \AKSRT\Core\DBMigrator::table('commission_ledger');
|
||||
$stats_joins = "LEFT JOIN (SELECT promoter_id, COUNT(*) AS bound_count FROM {$relation_table} WHERE status='bound' GROUP BY promoter_id) relation_stats ON relation_stats.promoter_id=u.ID "
|
||||
. "LEFT JOIN (SELECT promoter_id, COUNT(DISTINCT source_user_id) AS effective_payers FROM {$ledger_table} WHERE original_amount > 0 GROUP BY promoter_id) payer_stats ON payer_stats.promoter_id=u.ID";
|
||||
$list_sql = "SELECT DISTINCT u.ID, u.user_login, u.display_name, u.user_email, code.meta_value AS ref, state.meta_value AS ref_status, "
|
||||
$list_sql = "SELECT DISTINCT u.ID, u.user_login, u.display_name, u.user_email, code.meta_value AS ref, state.meta_value AS ref_status, created.meta_value AS created_at, "
|
||||
. "COALESCE(relation_stats.bound_count, 0) AS bound_count, COALESCE(payer_stats.effective_payers, 0) AS effective_payers "
|
||||
. "FROM {$wpdb->users} u {$joins} {$stats_joins} WHERE {$where_sql} ORDER BY u.ID DESC LIMIT %d OFFSET %d";
|
||||
$list_params = array_merge($params, [$per_page, ($page - 1) * $per_page]);
|
||||
@@ -514,6 +509,7 @@ final class ReferralAttribution {
|
||||
],
|
||||
'ref' => $ref,
|
||||
'status' => $ref === '' ? 'missing' : ((string) ($row['ref_status'] ?? '') === self::STATUS_DISABLED ? self::STATUS_DISABLED : self::STATUS_ACTIVE),
|
||||
'created_at' => (string) ($row['created_at'] ?? ''),
|
||||
'bound_count' => (int) ($row['bound_count'] ?? 0),
|
||||
'effective_payers' => (int) ($row['effective_payers'] ?? 0),
|
||||
];
|
||||
@@ -553,6 +549,7 @@ final class ReferralAttribution {
|
||||
if (empty($owners)) {
|
||||
update_user_meta($user_id, self::META_CODE, $code);
|
||||
update_user_meta($user_id, self::META_STATUS, self::STATUS_ACTIVE);
|
||||
update_user_meta($user_id, self::META_CREATED, current_time('mysql'));
|
||||
$updated = $this->code_record($user_id);
|
||||
if ($updated['code'] === $code && $updated['status'] === self::STATUS_ACTIVE) {
|
||||
return $code;
|
||||
|
||||
@@ -184,12 +184,6 @@ trait AuthReader {
|
||||
return (bool) self::get_value('user_signup_no_repas', true);
|
||||
}
|
||||
|
||||
/** 推广码在注册表单中的唯一显示模式。 */
|
||||
public static function invitation_mode(): string {
|
||||
$mode = (string) self::get_value('invit_code_s', 'close');
|
||||
return in_array($mode, ['close', 'open', 'must'], true) ? $mode : 'close';
|
||||
}
|
||||
|
||||
/** 自动弹窗配置。 */
|
||||
public static function sign_modal_auto(): array {
|
||||
return [
|
||||
|
||||
Reference in New Issue
Block a user