Files
wordpress-theme-aksrt/assets/admin/src/pages/CmsCredits.vue
T

188 lines
7.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="jio-page-container">
<h2 class="jio-page-title">积分配置</h2>
<p class="jio-page-desc">
配置积分规则与发放策略。可自定义货币名称(如”金币”、”魔石”等)。用户余额与手工调整在 WordPress 原生”用户”菜单中管理。
</p>
<n-card class="jio-section-card">
<div class="jio-section-header"><h3>主开关 + 基础设置</h3></div>
<n-form :model="cfg" label-placement="left" label-width="200" class="jio-form">
<n-form-item label="启用积分系统">
<n-switch v-model:value="cfg.enabled" />
</n-form-item>
<n-form-item label="自定义货币名称">
<n-input v-model:value="cfg.currency_name" placeholder="积分" maxlength="20" />
<template #feedback>
<span class="jio-hint-text">自定义货币显示名称,如"金币"、"魔石"等。留空则使用默认名称"积分"。</span>
</template>
</n-form-item>
<n-form-item label="注册赠送积分">
<n-input-number v-model:value="cfg.register_bonus" :min="0" :max="10000" />
</n-form-item>
</n-form>
</n-card>
<n-card class="jio-section-card">
<div class="jio-section-header"><h3>每日签到</h3></div>
<n-form :model="cfg.daily_signin" label-placement="left" label-width="200" class="jio-form">
<n-form-item label="启用">
<n-switch v-model:value="cfg.daily_signin.enabled" />
</n-form-item>
<n-form-item label="基础奖励">
<n-input-number v-model:value="cfg.daily_signin.base" :min="0" :max="10000" />
</n-form-item>
<n-form-item label="连续奖励(JSON)">
<n-input
type="textarea"
v-model:value="streakJson"
placeholder='{"3":2,"7":5,"30":20}'
:autosize="{ minRows: 2 }"
/>
<template #feedback>
<span class="jio-hint-text">连续 N 天时额外发放的积分。</span>
</template>
</n-form-item>
</n-form>
</n-card>
<n-card class="jio-section-card">
<div class="jio-section-header"><h3>评论奖励</h3></div>
<n-form :model="cfg.comment_reward" label-placement="left" label-width="200" class="jio-form">
<n-form-item label="启用">
<n-switch v-model:value="cfg.comment_reward.enabled" />
</n-form-item>
<n-form-item label="单次奖励">
<n-input-number v-model:value="cfg.comment_reward.amount" :min="0" :max="10000" />
</n-form-item>
<n-form-item label="每日上限">
<n-input-number v-model:value="cfg.comment_reward.daily_cap" :min="0" :max="100" />
</n-form-item>
<n-form-item label="最少字符数">
<n-input-number v-model:value="cfg.comment_reward.min_length" :min="0" :max="500" />
</n-form-item>
<n-form-item label="审核通过后发放">
<n-switch v-model:value="cfg.comment_reward.on_approved" />
</n-form-item>
</n-form>
</n-card>
<n-card class="jio-section-card">
<div class="jio-section-header"><h3>Ref 推广奖励</h3></div>
<n-form :model="cfg.referral_reward" label-placement="left" label-width="200" class="jio-form">
<n-form-item label="启用">
<n-switch v-model:value="cfg.referral_reward.enabled" />
</n-form-item>
<n-form-item label="推广人奖励">
<n-input-number v-model:value="cfg.referral_reward.promoter_amount" :min="0" :max="10000" />
</n-form-item>
<n-form-item label="新用户奖励">
<n-input-number v-model:value="cfg.referral_reward.referred_amount" :min="0" :max="10000" />
</n-form-item>
<n-form-item label="推广等级积分">
<n-input-number v-model:value="cfg.referral_reward.level_points" :min="0" :max="10000" />
</n-form-item>
<n-form-item label="需邮箱验证后发放">
<n-switch v-model:value="cfg.referral_reward.require_verify" />
</n-form-item>
<n-form-item label="同 IP 当日上限">
<n-input-number v-model:value="cfg.referral_reward.ip_daily_cap" :min="0" :max="100" />
</n-form-item>
</n-form>
</n-card>
<n-card class="jio-section-card">
<div class="jio-section-header"><h3>下载消费(参考)</h3></div>
<n-form :model="cfg" label-placement="left" label-width="200" class="jio-form">
<n-form-item :label="`默认积分价参考(${cfg.currency_name || '积分'})`">
<n-input-number v-model:value="cfg.download_default_cost" :min="0" :max="100000" />
<template #feedback>
<span class="jio-hint-text">实际价格以文章「付费内容设置」的积分价或现金价为准;下载解锁走收银台订单,不按次扣费。</span>
</template>
</n-form-item>
</n-form>
</n-card>
<JioSaveBar :dirty="dirty" :saving="saving" @save="saveCfg" @reload="loadCfg" />
</div>
</template>
<script setup>
import { computed, ref, reactive, onMounted } from 'vue'
import { useMessage } from 'naive-ui'
import api from '@/api'
import JioSaveBar from '@/components/form/JioSaveBar.vue'
const message = useMessage()
function defaultCfg() {
return {
enabled: true,
currency_name: '',
register_bonus: 10,
daily_signin: { enabled: true, base: 1, streak: { 3: 2, 7: 5, 30: 20 } },
comment_reward: { enabled: true, amount: 1, daily_cap: 5, min_length: 10, on_approved: true },
referral_reward: {
enabled: true,
promoter_amount: 5,
referred_amount: 2,
level_points: 0,
require_verify: true,
ip_daily_cap: 3,
},
download_default_cost: 0,
}
}
const cfg = reactive(defaultCfg())
const streakJson = ref('{}')
const loading = ref(true)
const saving = ref(false)
const initial = ref('')
const snapshot = computed(() => JSON.stringify({ cfg, streakJson: streakJson.value }))
const dirty = computed(() => !loading.value && initial.value !== '' && snapshot.value !== initial.value)
async function loadCfg() {
loading.value = true
try {
const response = await api.getCreditSettings()
const data = response?.data || response || {}
Object.assign(cfg, defaultCfg(), data)
streakJson.value = JSON.stringify(cfg.daily_signin?.streak || {}, null, 0)
initial.value = snapshot.value
} catch (e) {
message.error(e.message || '加载失败')
} finally {
loading.value = false
}
}
async function saveCfg() {
let streak
try {
streak = JSON.parse(streakJson.value || '{}')
} catch (error) {
message.error('连续奖励 JSON 格式错误')
return
}
if (!streak || typeof streak !== 'object' || Array.isArray(streak)) {
message.error('连续奖励必须是 JSON 对象')
return
}
saving.value = true
try {
await api.saveCreditSettings({ ...cfg, daily_signin: { ...cfg.daily_signin, streak } })
cfg.daily_signin.streak = streak
initial.value = snapshot.value
message.success('已保存')
} catch (e) {
message.error(e.message || '保存失败')
} finally {
saving.value = false
}
}
onMounted(() => {
loadCfg()
})
</script>