Files
wordpress-theme-aksrt/assets/admin/src/pages/CmsCredits.vue
T
kate522 6bad39a7ba chore(admin): clarify download points purchase mode copy
Rename residual 积分扣费/按次扣费 labels to 积分购买模式 and note cashier unlock; keep download_credit key for storage.
2026-07-14 21:18:26 +08:00

166 lines
6.3 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="aksrt-page-container">
<h2 class=”aksrt-page-title”>积分配置</h2>
<p class=”aksrt-page-desc”>
配置积分规则与发放策略。可自定义货币名称(如”金币”、”魔石”等)。用户余额与手工调整已迁移到 WordPress 原生”用户”菜单中管理。
</p>
<n-card class="aksrt-section-card">
<div class="aksrt-section-header"><h3>主开关 + 基础设置</h3></div>
<n-form :model="cfg" label-placement="left" label-width="200" class="aksrt-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="aksrt-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="aksrt-section-card">
<div class="aksrt-section-header"><h3>每日签到</h3></div>
<n-form :model="cfg.daily_signin" label-placement="left" label-width="200" class="aksrt-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="aksrt-hint-text">连续 N 天时额外发放的积分。</span>
</template>
</n-form-item>
</n-form>
</n-card>
<n-card class="aksrt-section-card">
<div class="aksrt-section-header"><h3>评论奖励</h3></div>
<n-form :model="cfg.comment_reward" label-placement="left" label-width="200" class="aksrt-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="aksrt-section-card">
<div class="aksrt-section-header"><h3>邀请奖励</h3></div>
<n-form :model="cfg.invite_reward" label-placement="left" label-width="200" class="aksrt-form">
<n-form-item label="启用">
<n-switch v-model:value="cfg.invite_reward.enabled" />
</n-form-item>
<n-form-item label="邀请人奖励">
<n-input-number v-model:value="cfg.invite_reward.inviter_amount" :min="0" :max="10000" />
</n-form-item>
<n-form-item label="被邀请人奖励">
<n-input-number v-model:value="cfg.invite_reward.invitee_amount" :min="0" :max="10000" />
</n-form-item>
<n-form-item label="需邮箱验证后发放">
<n-switch v-model:value="cfg.invite_reward.require_verify" />
</n-form-item>
<n-form-item label="同 IP 当日上限">
<n-input-number v-model:value="cfg.invite_reward.ip_daily_cap" :min="0" :max="100" />
</n-form-item>
</n-form>
</n-card>
<n-card class="aksrt-section-card">
<div class="aksrt-section-header"><h3>下载消费(参考)</h3></div>
<n-form :model="cfg" label-placement="left" label-width="200" class="aksrt-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="aksrt-hint-text">兼容字段。实际价格以文章「付费内容设置」的积分价/现金价为准;下载解锁走收银台订单,不按次扣费。</span>
</template>
</n-form-item>
</n-form>
</n-card>
<div class="aksrt-form-footer">
<n-button type="primary" :loading="saving" @click="saveCfg">保存配置</n-button>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { useMessage } from 'naive-ui'
import api from '@/api'
const message = useMessage()
// ---------- 配置 ----------
const cfg = reactive({
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 },
invite_reward: {
enabled: true,
inviter_amount: 5,
invitee_amount: 2,
require_verify: true,
ip_daily_cap: 3,
register_field: 'optional',
reject_invalid: true,
},
download_default_cost: 0,
})
const streakJson = ref('{}')
const saving = ref(false)
async function loadCfg() {
try {
const data = await api.getCreditSettings()
Object.assign(cfg, data)
streakJson.value = JSON.stringify(cfg.daily_signin?.streak || {}, null, 0)
} catch (e) {
message.error(e.message || '加载失败')
}
}
async function saveCfg() {
saving.value = true
try {
let streak = {}
try { streak = JSON.parse(streakJson.value || '{}') } catch (_) { /* ignore */ }
cfg.daily_signin.streak = streak
await api.saveCreditSettings(cfg)
message.success('已保存')
} catch (e) {
message.error(e.message || '保存失败')
} finally {
saving.value = false
}
}
onMounted(() => {
loadCfg()
})
</script>