一、项目背景
作为一名独立开发者,我一直想做一个能自动分析短视频内容并生成解说的工具。但传统方案面临两个难题:
1. 支付接入门槛高:支付宝/微信支付 SDK 需要企业资质,个人开发者无法直接接入
2. 原生能力限制:Expo RN 环境不支持原生模块,很多第三方 SDK 无法使用
经过探索,我设计了一套**"积分充值 + 手动审核"**的混合变现方案,既合规又实现了真实收益。
二、技术架构

┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Expo RN │────▶│ Supabase Cloud │────▶│ Edge Functions │
│ (前端) │◀────│ (数据库/存储) │◀────│ (AI 服务) │
└─────────────┘ └──────────────────┘ └─────────────────┘
▲ ▲
│ │
┌──────┴──────┐ ┌─────┴──────┐
│ 用户充值 │ │ ai-vision │
│ (上传凭证) │ │ ai-speech │
└─────────────┘ │ consume- │
│ points │
└────────────┘
核心技术栈:
• 前端:Expo SDK 56 + React Native 0.85 + TypeScript
• 后端:Supabase (PostgreSQL + Storage + Edge Functions)
• AI 能力:阿里云通义千问视觉模型 (ai-vision) + 语音合成 (ai-speech)
• 认证:短信验证码 + 密码登录(阿里云短信服务)
三、核心功能
1. 积分系统(替代传统支付)
充值流程:
1. 用户选择积分套餐(10/50/100 积分)
2. 扫描管理员提供的收款二维码完成支付
3. 上传支付截图提交审核
4. 管理员后台确认后,积分自动到账
消费流程:
1. 用户在发现页浏览视频
2. 点击"解锁 AI 分析"按钮
3. 系统通过 Edge Function 原子扣减 10 积分
4. 调用 ai-vision 分析视频内容,ai-speech 生成语音解说
关键代码(Edge Function 原子扣减):

// functions/consume-points/index.ts
const { data: pointsData } = await supabase
.from('user_points')
.select('balance')
.eq('user_id', userId)
.single();
if (pointsData.balance < points_required) {
throw new Error('积分不足');
}
// 原子扣减
await supabase.from('user_points')
.update({ balance: pointsData.balance - points_required })
.eq('user_id', userId);
// 记录购买
await supabase.from('purchased_analyses')
.insert({ user_id, video_id });
2. RLS 安全策略
-- 用户只能查看自己的积分
CREATE POLICY users_select_own_points ON public.user_points
FOR SELECT TO authenticated
USING (auth.uid() = user_id);
-- 管理员可以查看所有交易
CREATE POLICY admins_select_all_transactions ON public.point_transactions
FOR SELECT TO authenticated
USING (auth.uid() IN ('管理员UUID'));
-- 管理员可以更新交易状态
CREATE POLICY admins_update_transactions ON public.point_transactions
FOR UPDATE TO authenticated
USING (auth.uid() IN ('管理员UUID'));
3. 视频上传与 AI 分析

// 1. 读取本地视频文件(Expo RN 环境)
const response = await fetch(videoUri);
const arrayBuffer = await response.arrayBuffer();
// 2. 上传到 Supabase Storage
await supabase.storage.from('videos').upload(filePath, arrayBuffer);
// 3. 调用 ai-vision 分析
const visionResult = await fetch(`${supabaseUrl}/functions/v1/ai-vision`, {
method: 'POST',
headers: { 'OneDay-App-Id': projectUrlId },
body: JSON.stringify({ video_url: publicUrl }),
});
// 4. 调用 ai-speech 生成解说
const speechResult = await fetch(`${supabaseUrl}/functions/v1/ai-speech`, {
method: 'POST',
headers: { 'OneDay-App-Id': projectUrlId },
body: JSON.stringify({ text: analysisText }),
});
四、界面展示
发现页(类似抖音的视频流)

创作页(视频上传与 AI 分析)

个人中心(积分余额与流水)

管理后台(充值审核)

五、经验总结
踩过的坑:
1. Expo RN 不支持 Web API:FileReader、Blob等都无法使用,必须用 fetch(uri).arrayBuffer()读取本地文件
2. 共享云服务函数隔离:如果远端已有同名 AI 函数,当前项目不得覆盖部署,必须使用新名称创建独立函数
3. RLS 策略调试:初期忘记给管理员配置 UPDATE 权限,导致审核功能无法正常工作
最佳实践:
1. 匿名优先:默认免登录可用,新建表 user_id 可空,RLS 默认 USING (true)
2. Edge Function 原子操作:积分扣减必须在服务端完成,避免客户端并发导致超扣
3. 错误降级:AI 服务不可用时,提供友好的降级提示,而不是直接崩溃
六、开源地址
项目代码已托管在平台,欢迎交流讨论!