feat(invite-code): one-time invite codes with rewards, usage log, import/export

- 一次性邀请码:批量生成(次数/有效期/备注/四类奖励)、原子消费防超发、
  开启注册验证时奖励延迟发放(账本幂等键)
- Zibll 兼容文本导入(points/balance/vip/vip_time/level_integral,分隔符可自定义,
  第三段标识存为备注)、CSV 全字段导出与可回流文本导出
- 使用记录表 aksrt_invite_code_usage + 后台使用者列;注册表单 400ms 防抖实时校验
- 注册门控三模式(close/open/must)设置链路(PHP schema + admin SPA schema)
- 契约测试覆盖建表/消费竞态/导入导出/备注全链路
This commit is contained in:
2026-09-21 20:53:36 +08:00
parent 20387fdb06
commit 3dd3f71c97
16 changed files with 1285 additions and 1 deletions
+21
View File
@@ -96,12 +96,33 @@ trait ServicePart1b {
return ['success' => false, 'error' => __('推广码无效,请检查后重试', 'aksrt')];
}
$invite_service = class_exists('\AKSRT\Payment\InviteCode')
? \AKSRT\Payment\InviteCode::get_instance()
: null;
if ($invite_service) {
$invite_service->clear_registration_context();
$invite_mode = $invite_service->field_mode();
$submitted_invite = sanitize_key((string) ($post['invite_code'] ?? ''));
if ($invite_mode === 'required' && $submitted_invite === '') {
return ['success' => false, 'error' => __('请填写邀请码', 'aksrt')];
}
if ($submitted_invite !== '') {
if (!$invite_service->is_valid($submitted_invite)) {
return ['success' => false, 'error' => __('邀请码无效或已用完,请检查后重试', 'aksrt')];
}
$invite_service->set_registration_context($submitted_invite);
}
}
// 创建用户
$user_id = wp_create_user($username, $pass, '');
if (is_wp_error($user_id)) {
if ($ref_service) {
$ref_service->clear_registration_context();
}
if ($invite_service) {
$invite_service->clear_registration_context();
}
return ['success' => false, 'error' => $user_id->get_error_message()];
}