feat(credits): exchange balance for points

Replace the legacy points-to-balance and external points purchase flows
with direct integer balance-to-points exchange. Enforce exchange and
points-transfer limits and capability checks across the UI and REST API.
This commit is contained in:
2026-08-13 15:20:06 +08:00
parent f9bce15c9a
commit 1247f9bf4e
18 changed files with 234 additions and 648 deletions
@@ -20,9 +20,11 @@ export const rechargeSchema = {
pay_balance_pass_charge_s: false,
pay_balance_pass_charge_desc: '',
pay_balance_pass_charge_only_password: false,
pay_balance_exchange_s: false,
pay_balance_exchange_rate: 100,
pay_balance_exchange_desc: '',
pay_balance_points_exchange_s: false,
pay_balance_points_exchange_rate: 100,
pay_balance_points_exchange_min_points: 100,
pay_balance_points_exchange_daily_max_points: 100000,
pay_balance_points_exchange_desc: '',
pay_balance_withdraw_s: false,
},
groups: [
@@ -79,12 +81,14 @@ export const rechargeSchema = {
},
{
key: 'exchange',
title: '积分兑换',
title: '余额兑换积分',
icon: 'fas fa-coins',
fields: [
{ key: 'pay_balance_exchange_s', label: '启用积分兑换', type: 'switch', default: false },
{ key: 'pay_balance_exchange_rate', label: '兑换比例', type: 'number', default: 100, min: 1, max: 10000, help: 'N 积分 = 1 元', dependsOn: { key: 'pay_balance_exchange_s', value: true } },
{ key: 'pay_balance_exchange_desc', label: '兑换说明', type: 'textarea', default: '', dependsOn: { key: 'pay_balance_exchange_s', value: true } },
{ key: 'pay_balance_points_exchange_s', label: '启用余额兑换积分', type: 'switch', default: false, dependsOn: { key: 'pay_balance_s', value: true } },
{ key: 'pay_balance_points_exchange_rate', label: '兑换比例', type: 'number', default: 100, min: 1, max: 10000, help: '1 余额 = N 积分', dependsOn: { key: 'pay_balance_points_exchange_s', value: true } },
{ key: 'pay_balance_points_exchange_min_points', label: '单笔最低购买积分', type: 'number', default: 100, min: 1, max: 10000000, dependsOn: { key: 'pay_balance_points_exchange_s', value: true } },
{ key: 'pay_balance_points_exchange_daily_max_points', label: '每日最高购买积分', type: 'number', default: 100000, min: 1, max: 10000000, dependsOn: { key: 'pay_balance_points_exchange_s', value: true } },
{ key: 'pay_balance_points_exchange_desc', label: '兑换说明', type: 'textarea', default: '', dependsOn: { key: 'pay_balance_points_exchange_s', value: true } },
],
},
{
@@ -5,8 +5,6 @@ export const creditsSchema = {
description: '积分规则、积分日志、用户积分管理。',
defaults: {
points_s: true,
points_pay_s: false,
points_rate: 100,
points_name: '积分',
points_decimal: 2,
points_earn_daily_limit: 50,
@@ -43,12 +41,6 @@ export const creditsSchema = {
icon: 'fas fa-coins',
fields: [
{ key: 'points_s', label: '启用积分系统', type: 'switch', default: true },
{ key: 'points_pay_s', label: '启用购买积分', type: 'switch', default: false, help: '对齐 zibll points_pay_s:允许用户用现金/余额购买积分。' },
{ key: 'points_rate', label: '积分汇率(1元=N积分)', type: 'number', default: 100, min: 1, max: 10000, dependsOn: { key: 'points_pay_s', value: true } },
{ key: 'pay_points_desc', label: '购买积分说明', type: 'textarea', default: '', dependsOn: { key: 'points_pay_s', value: true } },
{ key: 'pay_points_product', label: '积分套餐', type: 'textarea', default: '', help: '每行:支付金额|积分数量|标题。留空则仅自定义数量。', dependsOn: { key: 'points_pay_s', value: true } },
{ key: 'pay_points_product_custom_s', label: '允许自定义积分数量', type: 'switch', default: true, dependsOn: { key: 'points_pay_s', value: true } },
{ key: 'pay_points_product_custom_limit', label: '自定义积分上限', type: 'number', default: 99999, min: 1, max: 999999, dependsOn: { key: 'points_pay_s', value: true } },
{ key: 'points_name', label: '积分名称', type: 'input', default: '积分' },
{ key: 'points_decimal', label: '积分小数位数', type: 'number', default: 2, min: 0, max: 4 },
],