// @ts-nocheck /** * 推广系统管理页面 — 使用 admin 设计系统 */ import React, { useState, useEffect, useCallback } from 'react'; import { adminAPI } from '@/api'; const SVGIcon: React.FC<{ children: React.ReactNode; size?: number }> = ({ children, size = 16 }) => ( {children} ); interface Promotion { id: number; title: string; description: string; reward_type: string; reward_value: number; min_payout: number; start_date: string; end_date: string; status: string; max_referrals: number; created_at: string; updated_at: string; link_count: number; total_rewards: number; } interface ReferralLink { id: number; code: string; user_id: number; username: string; promotion_id: number; promotion_title: string; target_url: string; channel: string; total_clicks: number; total_registrations: number; total_conversions: number; status: string; created_at: string; } interface ReferralReward { id: number; referral_code: string; referrer_name: string; referee_name: string; order_id: string; reward_type: string; reward_amount: number; reward_points: number; status: string; payout_method: string; paid_at: string; created_at: string; } const Promotion: React.FC = () => { const [activeTab, setActiveTab] = useState<'overview' | 'promotions' | 'links' | 'rewards' | 'leaderboard'>('overview'); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [stats, setStats] = useState(null); const [promotions, setPromotions] = useState([]); const [referralLinks, setReferralLinks] = useState([]); const [rewards, setRewards] = useState([]); const [leaderboard, setLeaderboard] = useState([]); const [promoPage, setPromoPage] = useState(1); const [totalPromos, setTotalPromos] = useState(0); const [showPromoModal, setShowPromoModal] = useState(false); const [showLinkModal, setShowLinkModal] = useState(false); const [editingPromo, setEditingPromo] = useState(null); const loadStats = useCallback(async () => { try { const res = await adminAPI.getPromotionStats(); const data = (res as any)?.data || res || {}; setStats(data); } catch (err) { console.error('Stats load failed:', err); } }, []); const loadPromotions = useCallback(async () => { setLoading(true); try { const res = await adminAPI.getPromotions({ page: promoPage, page_size: 20 }); const data = (res as any)?.data || res || {}; setPromotions(data.items || []); setTotalPromos(data.total || 0); } catch (err) { setError('加载失败'); } finally { setLoading(false); } }, [promoPage]); const loadLinks = useCallback(async () => { setLoading(true); try { const res = await adminAPI.getReferralLinks({ page: 1, page_size: 50 }); const data = (res as any)?.data || res || {}; setReferralLinks(data.items || []); } catch (err) { setError('加载失败'); } finally { setLoading(false); } }, []); const loadRewards = useCallback(async () => { setLoading(true); try { const res = await adminAPI.getReferralRewards({ page: 1, page_size: 50 }); const data = (res as any)?.data || res || {}; setRewards(data.items || []); } catch (err) { setError('加载失败'); } finally { setLoading(false); } }, []); const loadLeaderboard = useCallback(async () => { try { const res = await adminAPI.getPromotionLeaderboard({ limit: 50 }); const data = (res as any)?.data || res || {}; setLeaderboard(data.items || data.leaderboard || []); } catch (err) { console.error('Leaderboard load failed:', err); } }, []); useEffect(() => { setError(''); if (activeTab === 'overview') loadStats(); else if (activeTab === 'promotions') loadPromotions(); else if (activeTab === 'links') loadLinks(); else if (activeTab === 'rewards') loadRewards(); else if (activeTab === 'leaderboard') loadLeaderboard(); }, [activeTab, loadStats, loadPromotions, loadLinks, loadRewards, loadLeaderboard]); const handleSavePromo = async (formData: any) => { setLoading(true); try { if (editingPromo) await adminAPI.updatePromotion(editingPromo.id, formData); else await adminAPI.createPromotion(formData); setShowPromoModal(false); setEditingPromo(null); loadPromotions(); loadStats(); } catch (err) { setError('保存失败'); } finally { setLoading(false); } }; const handleTogglePromo = async (id: number) => { try { await adminAPI.togglePromotion(id); loadPromotions(); } catch (err) { setError('操作失败'); } }; const handleDeletePromo = async (id: number) => { if (!window.confirm('确定删除此推广活动?')) return; try { await adminAPI.deletePromotion(id); loadPromotions(); loadStats(); } catch (err) { setError('删除失败'); } }; const handleGenerateLink = async (formData: any) => { setLoading(true); try { await adminAPI.generateReferralLink(formData); setShowLinkModal(false); loadLinks(); loadStats(); } catch (err) { setError('生成失败'); } finally { setLoading(false); } }; const handleApproveReward = async (id: number) => { try { await adminAPI.approveReward(id); loadRewards(); } catch (err) { setError('操作失败'); } }; const handleMarkPaid = async (id: number) => { const payout_method = prompt('请输入提现方式(wechat/alipay/bank/balance):'); if (!payout_method) return; try { await adminAPI.markRewardPaid(id, { payout_method, payout_transaction_id: `TXN${Date.now()}` }); loadRewards(); } catch (err) { setError('操作失败'); } }; const inputStyle: React.CSSProperties = { background: 'var(--color-bg-secondary)', border: '1px solid var(--color-border)', borderRadius: 'var(--radius-md)', padding: '8px 12px', color: 'var(--color-text)', fontSize: 'var(--text-sm)', width: '100%', outline: 'none', }; const labelStyle: React.CSSProperties = { fontSize: 'var(--text-xs)', color: 'var(--color-text-tertiary)', fontWeight: 600, marginBottom: 4, display: 'block', }; const tabs = [ { key: 'overview', label: '概览', icon: <> }, { key: 'promotions', label: '推广活动', icon: <> }, { key: 'links', label: '分销链接', icon: <> }, { key: 'rewards', label: '返佣记录', icon: <> }, { key: 'leaderboard', label: '排行榜', icon: <> }, ]; return (

推广系统管理

管理推广活动、分销链接、返佣记录和推广统计

{activeTab === 'promotions' && ( )} {activeTab === 'links' && ( )}
{error &&
{error}
} {/* Tabs */}
{tabs.map(tab => ( ))}
{/* ===================== Overview Tab ===================== */} {activeTab === 'overview' && (
{!stats ? (
加载中...
) : ( <>
{[ { label: '推广活动总数', value: stats.total_promotions || 0, color: '#818cf8', icon: 'M3 11l18-5v12L3 14v-3z' }, { label: '进行中的活动', value: stats.active_promotions || 0, color: '#22c55e', icon: 'M9 12l2 2 4-4' }, { label: '分销链接总数', value: stats.total_referrals || stats.total_referral_links || 0, color: '#f59e0b', icon: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' }, { label: '已发返佣总额', value: `¥${(stats.total_rewards || stats.total_rewards_paid || 0).toFixed(2)}`, color: '#06b6d4', icon: 'M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6' }, ].map((s, i) => (
{s.value}
{s.label}
))}

待审核返佣

¥{(stats.pending_rewards || 0).toFixed(2)}
待审核返佣金额
)}
)} {/* ===================== Promotions Tab ===================== */} {activeTab === 'promotions' && (
{promotions.length === 0 ? ( ) : promotions.map(promo => ( ))}
ID活动标题返佣类型返佣值 状态链接数已发返佣创建时间操作
暂无数据
{promo.id}
{promo.title}
{promo.description &&
{promo.description}
}
{promo.reward_type === 'percentage' ? '百分比' : promo.reward_type === 'fixed' ? '固定金额' : '积分'} {promo.reward_type === 'percentage' ? `${promo.reward_value}%` : promo.reward_type === 'fixed' ? `¥${promo.reward_value?.toFixed(2)}` : `${promo.reward_value} 分`} {promo.status === 'active' ? '进行中' : promo.status === 'inactive' ? '已停用' : '已过期'} {promo.link_count || 0} ¥{(promo.total_rewards || 0).toFixed(2)} {promo.created_at ? new Date(promo.created_at).toLocaleDateString('zh-CN') : '-'}
{totalPromos > 20 && (
第 {promoPage} 页 / 共 {Math.ceil(totalPromos / 20)} 页
)}
)} {/* ===================== Links Tab ===================== */} {activeTab === 'links' && (
{referralLinks.length === 0 ? ( ) : referralLinks.map(link => ( ))}
ID推广短码推广人关联活动 点击数注册数转化数状态操作
暂无数据
{link.id} {link.code} {link.username} {link.promotion_title || '-'} {link.total_clicks || 0} {link.total_registrations || 0} {link.total_conversions || 0} {link.status === 'active' ? '活跃' : '停用'}
)} {/* ===================== Rewards Tab ===================== */} {activeTab === 'rewards' && (
{rewards.length === 0 ? ( ) : rewards.map(reward => ( ))}
ID推广码推广人被推荐人 返佣类型返佣金额状态打款时间操作
暂无数据
{reward.id} {reward.referral_code} {reward.referrer_name} {reward.referee_name} {reward.reward_type === 'registration' ? '注册奖励' : reward.reward_type === 'first_purchase' ? '首购返佣' : '续费返佣'} ¥{reward.reward_amount?.toFixed(2)} {reward.status === 'pending' ? '待审核' : reward.status === 'approved' ? '已通过' : reward.status === 'paid' ? '已打款' : '已取消'} {reward.paid_at ? new Date(reward.paid_at).toLocaleDateString('zh-CN') : '-'}
{reward.status === 'pending' && } {reward.status === 'approved' && }
)} {/* ===================== Leaderboard Tab ===================== */} {activeTab === 'leaderboard' && (
{leaderboard.length === 0 ? ( ) : leaderboard.map((entry, index) => ( ))}
排名用户点击数注册数转化数产生收入获得返佣
暂无数据
{index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : `#${index + 1}`} {entry.username} {entry.total_clicks || 0} {entry.total_registrations || 0} {entry.total_conversions || 0} ¥{(entry.total_revenue || 0).toFixed(2)} ¥{(entry.total_rewards || 0).toFixed(2)}
)} {/* ===================== Promotion Modal ===================== */} {showPromoModal && ( { setShowPromoModal(false); setEditingPromo(null); }} /> )} {/* ===================== Link Modal ===================== */} {showLinkModal && ( setShowLinkModal(false)} /> )}
); }; // ==================== 推广活动弹窗 ==================== const PromotionModal: React.FC<{ promotion: Promotion | null; onSave: (data: any) => void; onCancel: () => void }> = ({ promotion, onSave, onCancel }) => { const [formData, setFormData] = useState({ title: promotion?.title || '', description: promotion?.description || '', reward_type: promotion?.reward_type || 'percentage', reward_value: promotion?.reward_value || 5, min_payout: promotion?.min_payout || 10, start_date: promotion?.start_date ? promotion.start_date.slice(0, 16) : '', end_date: promotion?.end_date ? promotion.end_date.slice(0, 16) : '', max_referrals: promotion?.max_referrals || 0, status: promotion?.status || 'active', }); const inputStyle: React.CSSProperties = { background: 'var(--color-bg-secondary)', border: '1px solid var(--color-border)', borderRadius: 'var(--radius-md)', padding: '8px 12px', color: 'var(--color-text)', fontSize: 'var(--text-sm)', width: '100%', outline: 'none', }; const labelStyle: React.CSSProperties = { fontSize: 'var(--text-xs)', color: 'var(--color-text-tertiary)', fontWeight: 600, marginBottom: 4, display: 'block', }; return (
e.stopPropagation()}>

{promotion ? '编辑推广活动' : '创建推广活动'}

{ e.preventDefault(); onSave(formData); }}>
setFormData({ ...formData, title: e.target.value })} placeholder="例如:新用户推广计划" />