mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 10:27:46 +08:00
feat(referrals): 添加邀请返利和注册确认功能
This commit is contained in:
@@ -262,6 +262,203 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-4 border-t pt-5">
|
||||
<div class="flex items-center h-full">
|
||||
<div class="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="referral-enabled"
|
||||
:checked="referralEnabled"
|
||||
@update:checked="$emit('update:referralEnabled', $event)"
|
||||
/>
|
||||
<div>
|
||||
<Label
|
||||
for="referral-enabled"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
邀请返利
|
||||
</Label>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
开启后可按充值比例、人头或两者同时发放赠款返利
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label
|
||||
for="referral-reward-mode"
|
||||
class="block text-sm font-medium mb-2"
|
||||
>
|
||||
返利方式
|
||||
</Label>
|
||||
<Select
|
||||
:model-value="referralRewardMode"
|
||||
@update:model-value="$emit('update:referralRewardMode', $event)"
|
||||
>
|
||||
<SelectTrigger id="referral-reward-mode">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="percent">
|
||||
按充值比例
|
||||
</SelectItem>
|
||||
<SelectItem value="headcount">
|
||||
按邀请人头
|
||||
</SelectItem>
|
||||
<SelectItem value="both">
|
||||
两者同时启用
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label
|
||||
for="referral-recharge-percent"
|
||||
class="block text-sm font-medium"
|
||||
>
|
||||
充值返利比例 (%)
|
||||
</Label>
|
||||
<Input
|
||||
id="referral-recharge-percent"
|
||||
:model-value="referralRechargePercent"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.01"
|
||||
class="mt-1"
|
||||
@update:model-value="$emit('update:referralRechargePercent', Number($event))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label
|
||||
for="referral-headcount-amount"
|
||||
class="block text-sm font-medium"
|
||||
>
|
||||
人头返利金额 (美元)
|
||||
</Label>
|
||||
<Input
|
||||
id="referral-headcount-amount"
|
||||
:model-value="referralHeadcountAmountUsd"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.01"
|
||||
class="mt-1"
|
||||
@update:model-value="$emit('update:referralHeadcountAmountUsd', Number($event))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label
|
||||
for="referral-headcount-trigger"
|
||||
class="block text-sm font-medium mb-2"
|
||||
>
|
||||
人头返利触发时机
|
||||
</Label>
|
||||
<Select
|
||||
:model-value="referralHeadcountTrigger"
|
||||
@update:model-value="$emit('update:referralHeadcountTrigger', $event)"
|
||||
>
|
||||
<SelectTrigger id="referral-headcount-trigger">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="registration">
|
||||
注册成功
|
||||
</SelectItem>
|
||||
<SelectItem value="email_verified">
|
||||
邮箱验证完成
|
||||
</SelectItem>
|
||||
<SelectItem value="first_paid_order">
|
||||
首笔真实支付完成
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-4 border-t pt-5">
|
||||
<div class="flex items-center h-full">
|
||||
<div class="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="privacy-policy-enabled"
|
||||
:checked="registrationPrivacyPolicyEnabled"
|
||||
@update:checked="$emit('update:registrationPrivacyPolicyEnabled', $event)"
|
||||
/>
|
||||
<div>
|
||||
<Label
|
||||
for="privacy-policy-enabled"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
注册隐私政策确认
|
||||
</Label>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
开启后注册时必须确认当前版本
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label
|
||||
for="privacy-policy-version"
|
||||
class="block text-sm font-medium"
|
||||
>
|
||||
隐私政策版本
|
||||
</Label>
|
||||
<Input
|
||||
id="privacy-policy-version"
|
||||
:model-value="registrationPrivacyPolicyVersion"
|
||||
type="text"
|
||||
placeholder="2026-05-16"
|
||||
class="mt-1"
|
||||
@update:model-value="$emit('update:registrationPrivacyPolicyVersion', String($event || '').trim())"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label
|
||||
for="privacy-policy-format"
|
||||
class="block text-sm font-medium mb-2"
|
||||
>
|
||||
隐私政策格式
|
||||
</Label>
|
||||
<Select
|
||||
:model-value="registrationPrivacyPolicyFormat"
|
||||
@update:model-value="$emit('update:registrationPrivacyPolicyFormat', $event)"
|
||||
>
|
||||
<SelectTrigger id="privacy-policy-format">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="markdown">
|
||||
Markdown
|
||||
</SelectItem>
|
||||
<SelectItem value="html">
|
||||
HTML
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div class="md:col-span-2">
|
||||
<Label
|
||||
for="privacy-policy-content"
|
||||
class="block text-sm font-medium"
|
||||
>
|
||||
隐私政策内容
|
||||
</Label>
|
||||
<Textarea
|
||||
id="privacy-policy-content"
|
||||
:model-value="registrationPrivacyPolicyContent"
|
||||
rows="8"
|
||||
class="mt-1"
|
||||
placeholder="填写 Markdown 或 HTML 内容"
|
||||
@update:model-value="$emit('update:registrationPrivacyPolicyContent', $event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardSection>
|
||||
</template>
|
||||
@@ -270,6 +467,7 @@
|
||||
import Button from '@/components/ui/button.vue'
|
||||
import Input from '@/components/ui/input.vue'
|
||||
import Label from '@/components/ui/label.vue'
|
||||
import Textarea from '@/components/ui/textarea.vue'
|
||||
import Checkbox from '@/components/ui/checkbox.vue'
|
||||
import Select from '@/components/ui/select.vue'
|
||||
import SelectTrigger from '@/components/ui/select-trigger.vue'
|
||||
@@ -288,6 +486,15 @@ defineProps<{
|
||||
turnstileSecretKey: string
|
||||
turnstileSecretConfigured: boolean
|
||||
turnstileAllowedHostnamesStr: string
|
||||
referralEnabled: boolean
|
||||
referralRewardMode: string
|
||||
referralRechargePercent: number
|
||||
referralHeadcountAmountUsd: number
|
||||
referralHeadcountTrigger: string
|
||||
registrationPrivacyPolicyEnabled: boolean
|
||||
registrationPrivacyPolicyFormat: string
|
||||
registrationPrivacyPolicyContent: string
|
||||
registrationPrivacyPolicyVersion: string
|
||||
autoDeleteExpiredKeys: boolean
|
||||
enableFormatConversion: boolean
|
||||
enableOpenaiImageSyncHeartbeat: boolean
|
||||
@@ -306,6 +513,15 @@ defineEmits<{
|
||||
'update:turnstileSecretKey': [value: string]
|
||||
'update:turnstileAllowedHostnamesStr': [value: string]
|
||||
clearTurnstileSecret: []
|
||||
'update:referralEnabled': [value: boolean]
|
||||
'update:referralRewardMode': [value: string]
|
||||
'update:referralRechargePercent': [value: number]
|
||||
'update:referralHeadcountAmountUsd': [value: number]
|
||||
'update:referralHeadcountTrigger': [value: string]
|
||||
'update:registrationPrivacyPolicyEnabled': [value: boolean]
|
||||
'update:registrationPrivacyPolicyFormat': [value: string]
|
||||
'update:registrationPrivacyPolicyContent': [value: string]
|
||||
'update:registrationPrivacyPolicyVersion': [value: string]
|
||||
'update:autoDeleteExpiredKeys': [value: boolean]
|
||||
'update:enableFormatConversion': [value: boolean]
|
||||
'update:enableOpenaiImageSyncHeartbeat': [value: boolean]
|
||||
|
||||
@@ -20,6 +20,15 @@ export interface SystemConfig {
|
||||
turnstile_secret_key: string
|
||||
turnstile_secret_key_is_set: boolean
|
||||
turnstile_allowed_hostnames: string[]
|
||||
referral_enabled: boolean
|
||||
referral_reward_mode: string
|
||||
referral_recharge_percent: number
|
||||
referral_headcount_amount_usd: number
|
||||
referral_headcount_trigger: string
|
||||
registration_privacy_policy_enabled: boolean
|
||||
registration_privacy_policy_format: string
|
||||
registration_privacy_policy_content: string
|
||||
registration_privacy_policy_version: string
|
||||
// 独立余额 Key 过期管理
|
||||
auto_delete_expired_keys: boolean
|
||||
// 格式转换
|
||||
@@ -65,6 +74,15 @@ const CONFIG_KEYS = [
|
||||
'turnstile_site_key',
|
||||
'turnstile_secret_key',
|
||||
'turnstile_allowed_hostnames',
|
||||
'referral_enabled',
|
||||
'referral_reward_mode',
|
||||
'referral_recharge_percent',
|
||||
'referral_headcount_amount_usd',
|
||||
'referral_headcount_trigger',
|
||||
'registration_privacy_policy_enabled',
|
||||
'registration_privacy_policy_format',
|
||||
'registration_privacy_policy_content',
|
||||
'registration_privacy_policy_version',
|
||||
// 独立余额 Key 过期管理
|
||||
'auto_delete_expired_keys',
|
||||
// 格式转换
|
||||
@@ -112,6 +130,15 @@ function createDefaultConfig(): SystemConfig {
|
||||
turnstile_secret_key: '',
|
||||
turnstile_secret_key_is_set: false,
|
||||
turnstile_allowed_hostnames: [],
|
||||
referral_enabled: false,
|
||||
referral_reward_mode: 'percent',
|
||||
referral_recharge_percent: 5,
|
||||
referral_headcount_amount_usd: 0,
|
||||
referral_headcount_trigger: 'registration',
|
||||
registration_privacy_policy_enabled: false,
|
||||
registration_privacy_policy_format: 'markdown',
|
||||
registration_privacy_policy_content: '',
|
||||
registration_privacy_policy_version: '1',
|
||||
// 独立余额 Key 过期管理
|
||||
auto_delete_expired_keys: false,
|
||||
// 格式转换
|
||||
@@ -184,6 +211,19 @@ export function useSystemConfig() {
|
||||
systemConfig.value.turnstile_secret_key.trim() !== '' ||
|
||||
JSON.stringify(systemConfig.value.turnstile_allowed_hostnames) !==
|
||||
JSON.stringify(originalConfig.value.turnstile_allowed_hostnames) ||
|
||||
systemConfig.value.referral_enabled !== originalConfig.value.referral_enabled ||
|
||||
systemConfig.value.referral_reward_mode !== originalConfig.value.referral_reward_mode ||
|
||||
systemConfig.value.referral_recharge_percent !== originalConfig.value.referral_recharge_percent ||
|
||||
systemConfig.value.referral_headcount_amount_usd !== originalConfig.value.referral_headcount_amount_usd ||
|
||||
systemConfig.value.referral_headcount_trigger !== originalConfig.value.referral_headcount_trigger ||
|
||||
systemConfig.value.registration_privacy_policy_enabled !==
|
||||
originalConfig.value.registration_privacy_policy_enabled ||
|
||||
systemConfig.value.registration_privacy_policy_format !==
|
||||
originalConfig.value.registration_privacy_policy_format ||
|
||||
systemConfig.value.registration_privacy_policy_content !==
|
||||
originalConfig.value.registration_privacy_policy_content ||
|
||||
systemConfig.value.registration_privacy_policy_version !==
|
||||
originalConfig.value.registration_privacy_policy_version ||
|
||||
systemConfig.value.auto_delete_expired_keys !== originalConfig.value.auto_delete_expired_keys ||
|
||||
systemConfig.value.enable_format_conversion !== originalConfig.value.enable_format_conversion ||
|
||||
systemConfig.value.enable_openai_image_sync_heartbeat !== originalConfig.value.enable_openai_image_sync_heartbeat
|
||||
@@ -386,6 +426,51 @@ export function useSystemConfig() {
|
||||
value: systemConfig.value.turnstile_allowed_hostnames,
|
||||
description: 'Cloudflare Turnstile 允许的 hostname 列表',
|
||||
},
|
||||
{
|
||||
key: 'referral_enabled',
|
||||
value: systemConfig.value.referral_enabled,
|
||||
description: '邀请返利开关',
|
||||
},
|
||||
{
|
||||
key: 'referral_reward_mode',
|
||||
value: systemConfig.value.referral_reward_mode,
|
||||
description: '邀请返利方式',
|
||||
},
|
||||
{
|
||||
key: 'referral_recharge_percent',
|
||||
value: systemConfig.value.referral_recharge_percent,
|
||||
description: '邀请充值比例返利百分比',
|
||||
},
|
||||
{
|
||||
key: 'referral_headcount_amount_usd',
|
||||
value: systemConfig.value.referral_headcount_amount_usd,
|
||||
description: '邀请人头返利金额(美元)',
|
||||
},
|
||||
{
|
||||
key: 'referral_headcount_trigger',
|
||||
value: systemConfig.value.referral_headcount_trigger,
|
||||
description: '邀请人头返利触发时机',
|
||||
},
|
||||
{
|
||||
key: 'registration_privacy_policy_enabled',
|
||||
value: systemConfig.value.registration_privacy_policy_enabled,
|
||||
description: '注册隐私政策确认开关',
|
||||
},
|
||||
{
|
||||
key: 'registration_privacy_policy_format',
|
||||
value: systemConfig.value.registration_privacy_policy_format,
|
||||
description: '注册隐私政策内容格式',
|
||||
},
|
||||
{
|
||||
key: 'registration_privacy_policy_content',
|
||||
value: systemConfig.value.registration_privacy_policy_content,
|
||||
description: '注册隐私政策内容',
|
||||
},
|
||||
{
|
||||
key: 'registration_privacy_policy_version',
|
||||
value: systemConfig.value.registration_privacy_policy_version,
|
||||
description: '注册隐私政策版本',
|
||||
},
|
||||
{
|
||||
key: 'auto_delete_expired_keys',
|
||||
value: systemConfig.value.auto_delete_expired_keys,
|
||||
@@ -426,6 +511,21 @@ export function useSystemConfig() {
|
||||
originalConfig.value.turnstile_allowed_hostnames = [
|
||||
...systemConfig.value.turnstile_allowed_hostnames,
|
||||
]
|
||||
originalConfig.value.referral_enabled = systemConfig.value.referral_enabled
|
||||
originalConfig.value.referral_reward_mode = systemConfig.value.referral_reward_mode
|
||||
originalConfig.value.referral_recharge_percent = systemConfig.value.referral_recharge_percent
|
||||
originalConfig.value.referral_headcount_amount_usd =
|
||||
systemConfig.value.referral_headcount_amount_usd
|
||||
originalConfig.value.referral_headcount_trigger =
|
||||
systemConfig.value.referral_headcount_trigger
|
||||
originalConfig.value.registration_privacy_policy_enabled =
|
||||
systemConfig.value.registration_privacy_policy_enabled
|
||||
originalConfig.value.registration_privacy_policy_format =
|
||||
systemConfig.value.registration_privacy_policy_format
|
||||
originalConfig.value.registration_privacy_policy_content =
|
||||
systemConfig.value.registration_privacy_policy_content
|
||||
originalConfig.value.registration_privacy_policy_version =
|
||||
systemConfig.value.registration_privacy_policy_version
|
||||
if (turnstileSecret) {
|
||||
systemConfig.value.turnstile_secret_key = ''
|
||||
systemConfig.value.turnstile_secret_key_is_set = true
|
||||
|
||||
Reference in New Issue
Block a user