♻️ refactor: 重构余额系统 - 基于 usePricing 逻辑优化
主要改进: - 🔄 完全重构 balance.ts,参考 usePricing.md 的最佳实践 - ✅ 集成余额检查、扣费、错误处理到单一 API - 🎯 使用 authClient.subscription.meterEvent 替代自定义 API - 💡 添加 checkTokenBalance 和 redirectToPricePage 辅助方法 - 🧹 简化 form.tsx 中的扣费流程,减少60%代码量 技术细节: - 从 metered 订阅类型获取 creditBalance - 使用 React Native Alert 替代 Web toast - 余额不足时自动引导用户充值 - 扣费成功后自动刷新余额显示 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ export const unstable_settings = {
|
||||
import { BackButton } from '@/components/ui/back-button';
|
||||
import { DynamicFormField } from '@/components/forms/dynamic-form-field';
|
||||
import { getTemplateById } from '@/lib/api/templates';
|
||||
import { getUserBalance, chargeUser } from '@/lib/api/balance';
|
||||
import { recordTokenUsage } from '@/lib/api/balance';
|
||||
import { runTemplate } from '@/lib/api/template-runs';
|
||||
import { Template, TemplateGraphNode } from '@/lib/types/template';
|
||||
|
||||
@@ -105,47 +105,23 @@ export default function TemplateFormScreen() {
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
// 1. 检查余额
|
||||
const balanceResponse = await getUserBalance();
|
||||
|
||||
if (!balanceResponse.success) {
|
||||
Alert.alert('错误', '无法获取账户余额');
|
||||
return;
|
||||
}
|
||||
|
||||
const balance = balanceResponse.data.balance;
|
||||
// 1. 扣费(已集成余额检查和错误处理)
|
||||
const requiredAmount = template.costPrice || 0;
|
||||
|
||||
if (balance < requiredAmount) {
|
||||
Alert.alert(
|
||||
'余额不足',
|
||||
`当前余额: ${balance}\n所需费用: ${requiredAmount}\n请先充值`,
|
||||
[
|
||||
{ text: '取消', style: 'cancel' },
|
||||
{ text: '去充值', onPress: () => router.push('/recharge') },
|
||||
]
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 扣费
|
||||
const chargeResponse = await chargeUser({
|
||||
amount: requiredAmount,
|
||||
description: `生成视频 - ${template.title}`,
|
||||
const usageResponse = await recordTokenUsage({
|
||||
price: requiredAmount,
|
||||
name: `生成视频 - ${template.title}`,
|
||||
metadata: {
|
||||
templateId: template.id,
|
||||
templateTitle: template.title,
|
||||
},
|
||||
});
|
||||
|
||||
if (!chargeResponse.success) {
|
||||
Alert.alert('错误', '扣费失败,请稍后重试');
|
||||
if (!usageResponse.success) {
|
||||
// recordTokenUsage 已经显示了错误提示,这里不需要重复
|
||||
return;
|
||||
}
|
||||
|
||||
const transactionId = chargeResponse.data.id;
|
||||
|
||||
// 3. 调用 template run
|
||||
// 2. 调用 template run
|
||||
const runResponse = await runTemplate(id, formData);
|
||||
|
||||
if (!runResponse.success) {
|
||||
@@ -155,7 +131,7 @@ export default function TemplateFormScreen() {
|
||||
|
||||
const generationId = runResponse.data;
|
||||
|
||||
// 4. 跳转到结果页面
|
||||
// 3. 跳转到结果页面
|
||||
Alert.alert('成功', '视频生成任务已创建', [
|
||||
{
|
||||
text: '查看结果',
|
||||
|
||||
Reference in New Issue
Block a user