import React, { useState, useEffect } from 'react'; import { adminAPI } from '@/api'; import { mockCoupons } from '@/mock/data'; import type { MarketApp, Coupon } from '@/types'; const SVGIcon: React.FC<{ children: React.ReactNode; size?: number }> = ({ children, size = 16 }) => ( {children} ); // Phase 4.1: 安检状态徽章 function SecurityBadge({ scan }: { scan?: any }) { if (!scan || !scan.status) return 未扫描; const map: Record = { pass: { label: '安检通过', bg: '#16a34a1A', fg: '#16a34a' }, warn: { label: '安检注意', bg: '#d977061A', fg: '#d97706' }, fail: { label: '安检风险', bg: '#dc26261A', fg: '#dc2626' }, }; const m = map[scan.status] || map.warn; return ( {m.label} ); } const mapApp = (a: any): MarketApp => ({ id: a.id, name: a.name, type: a.type, source: a.source, publisherId: a.publisher_id, publisherName: a.publisher_name || '未知', description: a.description || '', icon: a.icon || '?', price: a.price || 0, isMemberFree: a.is_member_free || false, joinPromotion: a.join_promotion || false, status: a.status || 'published', ratingAvg: a.rating_avg || 0, reviewCount: a.review_count || 0, installCount: a.install_count || 0, createdAt: a.created_at || '', version: a.version || '1.0.0', verified: a.verified || false, securityScan: a.security_scan || null, dependencies: a.dependencies || null, }); const Market: React.FC = () => { const [reviewApps, setReviewApps] = useState([]); const [officialApps, setOfficialApps] = useState([]); const [loading, setLoading] = useState(false); const [activeTab, setActiveTab] = useState<'review' | 'coupon' | 'official'>('review'); const [showCouponModal, setShowCouponModal] = useState(false); const [coupons] = useState(mockCoupons); const [couponForm, setCouponForm] = useState({ code: '', type: 'fixed' as 'fixed' | 'percent', value: 0, minAmount: 0, validFrom: '', validTo: '', }); // Phase 4.1: 版本历史弹窗 const [versionsApp, setVersionsApp] = useState(null); const [versions, setVersions] = useState([]); const [loadingVersions, setLoadingVersions] = useState(false); const loadReview = () => { setLoading(true); adminAPI.getPendingApps().then((res: any) => { if (res && Array.isArray(res)) setReviewApps(res.map(mapApp)); else if (res?.code === 0 && Array.isArray(res.data)) setReviewApps(res.data.map(mapApp)); }).catch(() => {}).finally(() => setLoading(false)); }; const loadOfficial = () => { setLoading(true); adminAPI.getAdminMarketApps('status=published').then((res: any) => { const items = (res?.data?.items || res?.items || []).map(mapApp).filter((a: MarketApp) => a.source === 'official'); setOfficialApps(items); }).catch(() => {}).finally(() => setLoading(false)); }; useEffect(() => { if (activeTab === 'review') loadReview(); else if (activeTab === 'official') loadOfficial(); }, [activeTab]); const handleApprove = (id: string) => { adminAPI.approveApp(id).then(() => loadReview()).catch(() => alert('审核失败')); }; const handleReject = (id: string) => { adminAPI.rejectApp(id).then(() => loadReview()).catch(() => alert('拒绝失败')); }; const handleRemoveOfficial = (id: string) => { if (!confirm('确认下架该官方应用?')) return; adminAPI.rejectApp(id).then(() => loadOfficial()).catch(() => alert('下架失败')); }; const handleRescan = (id: string) => { adminAPI.rescanApp(id).then((res: any) => { alert('重新安检完成:' + (res?.status || 'unknown')); loadOfficial(); }).catch(() => alert('安检失败')); }; const openVersions = (app: MarketApp) => { setVersionsApp(app); setLoadingVersions(true); setVersions([]); adminAPI.getAppVersions(app.id).then((res: any) => { setVersions(res?.items || []); }).catch(() => {}).finally(() => setLoadingVersions(false)); }; const handleRollback = (appId: string, versionId: string) => { if (!confirm('确认回滚到该版本?当前配置将被覆盖。')) return; adminAPI.rollbackApp(appId, versionId).then(() => { alert('已回滚'); openVersions({ ...versionsApp!, id: appId } as MarketApp); loadOfficial(); }).catch(() => alert('回滚失败')); }; const formatDate = (d: string) => { if (!d) return '-'; const dt = new Date(d); return dt.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); }; const tabs = [ { key: 'review' as const, label: '待审核应用', count: reviewApps.length }, { key: 'coupon' as const, label: '优惠券管理', count: coupons.length }, { key: 'official' as const, label: '官方应用管理', count: officialApps.length }, ]; return (

AI技能审核管理

{/* Tabs */}
{tabs.map(tab => ( ))}
{/* Pending Review Tab */} {activeTab === 'review' && (

待审核应用

{reviewApps.map(app => ( ))} {reviewApps.length === 0 && !loading && ( )} {loading && ( )}
应用名 类型 发布者 价格 安检 发布时间 操作
{app.name} {app.type.toUpperCase()} {app.publisherName} {app.price} 元 {formatDate(app.createdAt)}
暂无待审核应用
加载中...
)} {/* Coupon Management Tab */} {activeTab === 'coupon' && (

优惠券列表

{coupons.map(c => ( ))}
兑换码 类型 面值 最低消费 有效期 状态 操作
{c.code} {c.type === 'fixed' ? '固定金额' : '百分比'} {c.type === 'fixed' ? `${c.value} 元` : `${c.value}%`} {c.minAmount > 0 ? `${c.minAmount} 元` : '无门槛'} {c.validFrom} 至 {c.validTo} {c.status === 'active' ? '有效' : '已过期'} 只读
)} {/* Official App Management Tab */} {activeTab === 'official' && (

官方应用列表

{officialApps.map(app => ( ))} {officialApps.length === 0 && !loading && ( )} {loading && ( )}
应用名 类型 版本 绿标 安检 安装量 操作
{app.name} {app.type.toUpperCase()} v{app.version} {app.verified ? ✓ 已认证 : 未认证} {app.installCount.toLocaleString()}
暂无官方应用
加载中...
)} {/* Version History Modal */} {versionsApp && (
setVersionsApp(null)}>
e.stopPropagation()}>

版本历史 · {versionsApp.name}

当前版本:v{versionsApp.version}

{loadingVersions ? (

加载中...

) : versions.length === 0 ? (

暂无历史版本

) : ( {versions.map((v: any) => ( ))}
版本安检创建时间操作
v{v.version} {formatDate(v.created_at)}
)}
)}
); }; export default Market;