Chore: remove promotional copy and home-training wording
这个提交包含在:
@@ -1,6 +1,6 @@
|
|||||||
# Tennis Training Hub
|
# Tennis Training Hub
|
||||||
|
|
||||||
AI 网球训练助手,提供训练计划、姿势分析、实时摄像头分析、在线视频录制与视频库管理。当前版本新增独立 Go 媒体服务,用于处理在线录制、分段上传、实时推流信令和归档回放。
|
网球训练管理与分析应用,提供训练计划、姿势分析、实时摄像头分析、在线视频录制与视频库管理。当前版本新增独立 Go 媒体服务,用于处理在线录制、分段上传、实时推流信令和归档回放。
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default function Dashboard() {
|
|||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Button data-testid="dashboard-training-button" onClick={() => setLocation("/training")} className="gap-2">
|
<Button data-testid="dashboard-training-button" onClick={() => setLocation("/training")} className="gap-2">
|
||||||
<Target className="h-4 w-4" />
|
<Target className="h-4 w-4" />
|
||||||
开始训练
|
训练计划
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" onClick={() => setLocation("/analysis")} className="gap-2">
|
<Button variant="outline" onClick={() => setLocation("/analysis")} className="gap-2">
|
||||||
<Video className="h-4 w-4" />
|
<Video className="h-4 w-4" />
|
||||||
@@ -220,7 +220,7 @@ export default function Dashboard() {
|
|||||||
<div className="h-[200px] flex items-center justify-center text-muted-foreground text-sm">
|
<div className="h-[200px] flex items-center justify-center text-muted-foreground text-sm">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<Video className="h-8 w-8 mx-auto mb-2 opacity-30" />
|
<Video className="h-8 w-8 mx-auto mb-2 opacity-30" />
|
||||||
<p>上传训练视频开始AI分析</p>
|
<p>上传训练视频后可查看分析结果</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -231,7 +231,7 @@ export default function Dashboard() {
|
|||||||
{/* Quick actions */}
|
{/* Quick actions */}
|
||||||
<Card className="border-0 shadow-sm">
|
<Card className="border-0 shadow-sm">
|
||||||
<CardHeader className="pb-2">
|
<CardHeader className="pb-2">
|
||||||
<CardTitle className="text-base font-semibold">快速开始</CardTitle>
|
<CardTitle className="text-base font-semibold">常用入口</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
||||||
@@ -244,7 +244,7 @@ export default function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium text-sm">生成训练计划</p>
|
<p className="font-medium text-sm">生成训练计划</p>
|
||||||
<p className="text-xs text-muted-foreground">AI定制个人训练方案</p>
|
<p className="text-xs text-muted-foreground">按当前设置生成训练安排</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -256,7 +256,7 @@ export default function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium text-sm">上传视频分析</p>
|
<p className="font-medium text-sm">上传视频分析</p>
|
||||||
<p className="text-xs text-muted-foreground">MediaPipe AI姿势识别</p>
|
<p className="text-xs text-muted-foreground">导入视频并查看姿势分析</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -268,7 +268,7 @@ export default function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium text-sm">查看NTRP评分</p>
|
<p className="font-medium text-sm">查看NTRP评分</p>
|
||||||
<p className="text-xs text-muted-foreground">多维度能力评估</p>
|
<p className="text-xs text-muted-foreground">查看评分记录和维度结果</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,18 +30,18 @@ export default function Home() {
|
|||||||
<div className="max-w-3xl mx-auto text-center">
|
<div className="max-w-3xl mx-auto text-center">
|
||||||
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-primary/10 text-primary text-sm font-medium mb-6">
|
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-primary/10 text-primary text-sm font-medium mb-6">
|
||||||
<Zap className="h-3.5 w-3.5" />
|
<Zap className="h-3.5 w-3.5" />
|
||||||
AI网球训练助手
|
网球训练系统
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight leading-tight">
|
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight leading-tight">
|
||||||
精准分析
|
训练记录
|
||||||
<span className="text-primary block mt-1">高效提升</span>
|
<span className="text-primary block mt-1">分析与录制</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-lg text-muted-foreground mt-6 max-w-xl mx-auto leading-relaxed">
|
<p className="text-lg text-muted-foreground mt-6 max-w-xl mx-auto leading-relaxed">
|
||||||
AI姿势识别 · 智能训练计划 · 实时动作分析 · 自动评分反馈
|
训练计划 · 姿势分析 · 实时录制 · 评分记录
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center justify-center gap-3 mt-8">
|
<div className="flex items-center justify-center gap-3 mt-8">
|
||||||
<Button onClick={() => setLocation("/login")} size="lg" className="gap-2 h-12 px-6">
|
<Button onClick={() => setLocation("/login")} size="lg" className="gap-2 h-12 px-6">
|
||||||
开始训练
|
进入系统
|
||||||
<ChevronRight className="h-4 w-4" />
|
<ChevronRight className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,43 +50,43 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* Features */}
|
{/* Features */}
|
||||||
<section className="container py-16">
|
<section className="container py-16">
|
||||||
<h2 className="text-2xl font-bold text-center mb-12">核心功能</h2>
|
<h2 className="text-2xl font-bold text-center mb-12">功能</h2>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 max-w-5xl mx-auto">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 max-w-5xl mx-auto">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
icon: Video,
|
icon: Video,
|
||||||
title: "AI姿势识别",
|
title: "姿势识别",
|
||||||
desc: "MediaPipe实时分析33个关键点,精准评估挥拍动作",
|
desc: "使用 MediaPipe 分析 33 个关键点并记录挥拍数据",
|
||||||
color: "bg-blue-50 text-blue-600",
|
color: "bg-blue-50 text-blue-600",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: Target,
|
icon: Target,
|
||||||
title: "智能训练计划",
|
title: "训练计划",
|
||||||
desc: "根据水平和分析结果,AI自动生成和调整训练方案",
|
desc: "根据水平和分析结果生成训练安排",
|
||||||
color: "bg-green-50 text-green-600",
|
color: "bg-green-50 text-green-600",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: Award,
|
icon: Award,
|
||||||
title: "NTRP自动评分",
|
title: "NTRP自动评分",
|
||||||
desc: "USTA标准五维度评估,每次分析自动更新评分",
|
desc: "按 USTA 维度记录评分结果",
|
||||||
color: "bg-purple-50 text-purple-600",
|
color: "bg-purple-50 text-purple-600",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: Zap,
|
icon: Zap,
|
||||||
title: "击球统计",
|
title: "击球统计",
|
||||||
desc: "击球次数、挥拍速度、一致性,量化训练效果",
|
desc: "记录击球次数、挥拍速度和一致性",
|
||||||
color: "bg-orange-50 text-orange-600",
|
color: "bg-orange-50 text-orange-600",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: Footprints,
|
icon: Footprints,
|
||||||
title: "运动轨迹",
|
title: "运动轨迹",
|
||||||
desc: "重心移动轨迹分析,优化脚步移动模式",
|
desc: "记录重心移动轨迹和脚步变化",
|
||||||
color: "bg-teal-50 text-teal-600",
|
color: "bg-teal-50 text-teal-600",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: TrendingUp,
|
icon: TrendingUp,
|
||||||
title: "进度追踪",
|
title: "进度追踪",
|
||||||
desc: "训练历史、能力趋势、评分变化一目了然",
|
desc: "查看训练历史、趋势和评分变化",
|
||||||
color: "bg-indigo-50 text-indigo-600",
|
color: "bg-indigo-50 text-indigo-600",
|
||||||
},
|
},
|
||||||
].map((feature) => (
|
].map((feature) => (
|
||||||
@@ -103,11 +103,11 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* How it works */}
|
{/* How it works */}
|
||||||
<section className="container py-16">
|
<section className="container py-16">
|
||||||
<h2 className="text-2xl font-bold text-center mb-12">使用流程</h2>
|
<h2 className="text-2xl font-bold text-center mb-12">使用步骤</h2>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 max-w-4xl mx-auto">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 max-w-4xl mx-auto">
|
||||||
{[
|
{[
|
||||||
{ step: "1", title: "输入用户名", desc: "用户名登录即可" },
|
{ step: "1", title: "输入用户名", desc: "用户名登录即可" },
|
||||||
{ step: "2", title: "生成计划", desc: "AI个性化训练方案" },
|
{ step: "2", title: "生成计划", desc: "生成训练安排" },
|
||||||
{ step: "3", title: "上传视频", desc: "录制挥拍并分析" },
|
{ step: "3", title: "上传视频", desc: "录制挥拍并分析" },
|
||||||
{ step: "4", title: "获取反馈", desc: "评分与矫正建议" },
|
{ step: "4", title: "获取反馈", desc: "评分与矫正建议" },
|
||||||
].map((item) => (
|
].map((item) => (
|
||||||
@@ -125,10 +125,10 @@ export default function Home() {
|
|||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className="container py-16">
|
<section className="container py-16">
|
||||||
<div className="max-w-2xl mx-auto text-center p-8 rounded-2xl bg-primary/5">
|
<div className="max-w-2xl mx-auto text-center p-8 rounded-2xl bg-primary/5">
|
||||||
<h2 className="text-2xl font-bold mb-3">提升技术,从这里开始</h2>
|
<h2 className="text-2xl font-bold mb-3">登录入口</h2>
|
||||||
<p className="text-muted-foreground mb-6">输入用户名即可使用全部功能</p>
|
<p className="text-muted-foreground mb-6">输入用户名后进入系统</p>
|
||||||
<Button onClick={() => setLocation("/login")} size="lg" className="gap-2">
|
<Button onClick={() => setLocation("/login")} size="lg" className="gap-2">
|
||||||
立即开始
|
前往登录
|
||||||
<ChevronRight className="h-4 w-4" />
|
<ChevronRight className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -141,7 +141,7 @@ export default function Home() {
|
|||||||
<Target className="h-4 w-4" />
|
<Target className="h-4 w-4" />
|
||||||
<span>Tennis Hub</span>
|
<span>Tennis Hub</span>
|
||||||
</div>
|
</div>
|
||||||
<span>AI网球训练助手</span>
|
<span>训练与分析</span>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ export default function LiveCamera() {
|
|||||||
摄像头位置设置
|
摄像头位置设置
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
为获得最佳分析效果,请按以下步骤调整设备位置
|
请按以下步骤调整设备位置
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4 py-2">
|
<div className="space-y-4 py-2">
|
||||||
@@ -313,7 +313,7 @@ export default function LiveCamera() {
|
|||||||
<Button onClick={() => setSetupStep(s => s + 1)}>下一步</Button>
|
<Button onClick={() => setSetupStep(s => s + 1)}>下一步</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button onClick={handleSetupComplete} className="gap-2">
|
<Button onClick={handleSetupComplete} className="gap-2">
|
||||||
<Camera className="h-4 w-4" />开始使用摄像头
|
<Camera className="h-4 w-4" />启用摄像头
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ export default function Login() {
|
|||||||
<Target className="w-8 h-8 text-primary" />
|
<Target className="w-8 h-8 text-primary" />
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-3xl font-bold tracking-tight">Tennis Hub</h1>
|
<h1 className="text-3xl font-bold tracking-tight">Tennis Hub</h1>
|
||||||
<p className="text-muted-foreground mt-2">AI网球训练助手</p>
|
<p className="text-muted-foreground mt-2">训练与分析入口</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card className="border-0 shadow-xl">
|
<Card className="border-0 shadow-xl">
|
||||||
<CardHeader className="text-center pb-2">
|
<CardHeader className="text-center pb-2">
|
||||||
<CardTitle className="text-xl" data-testid="login-title">开始训练</CardTitle>
|
<CardTitle className="text-xl" data-testid="login-title">登录</CardTitle>
|
||||||
<CardDescription>输入用户名即可开始使用</CardDescription>
|
<CardDescription>输入用户名后进入系统</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<form onSubmit={handleLogin} className="space-y-4">
|
<form onSubmit={handleLogin} className="space-y-4">
|
||||||
@@ -96,7 +96,7 @@ export default function Login() {
|
|||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<p className="text-center text-xs text-muted-foreground mt-6">
|
<p className="text-center text-xs text-muted-foreground mt-6">
|
||||||
输入用户名即可使用全部功能
|
输入用户名后进入系统
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ export default function Training() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold tracking-tight" data-testid="training-title">训练计划</h1>
|
<h1 className="text-2xl font-bold tracking-tight" data-testid="training-title">训练计划</h1>
|
||||||
<p className="text-muted-foreground text-sm mt-1">AI个性化训练方案</p>
|
<p className="text-muted-foreground text-sm mt-1">按水平和周期生成训练安排</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ export default function Training() {
|
|||||||
生成训练计划
|
生成训练计划
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
根据水平和目标,AI生成个性化训练方案
|
根据水平和目标生成训练安排
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4">
|
||||||
@@ -149,7 +149,7 @@ export default function Training() {
|
|||||||
className="w-full sm:w-auto gap-2"
|
className="w-full sm:w-auto gap-2"
|
||||||
>
|
>
|
||||||
{generateMutation.isPending ? (
|
{generateMutation.isPending ? (
|
||||||
<><Loader2 className="h-4 w-4 animate-spin" />AI生成中...</>
|
<><Loader2 className="h-4 w-4 animate-spin" />生成中...</>
|
||||||
) : (
|
) : (
|
||||||
<><Sparkles className="h-4 w-4" />生成训练计划</>
|
<><Sparkles className="h-4 w-4" />生成训练计划</>
|
||||||
)}
|
)}
|
||||||
@@ -186,7 +186,7 @@ export default function Training() {
|
|||||||
) : (
|
) : (
|
||||||
<RefreshCw className="h-3 w-3" />
|
<RefreshCw className="h-3 w-3" />
|
||||||
)}
|
)}
|
||||||
智能调整
|
重新调整
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{activePlan.adjustmentNotes && (
|
{activePlan.adjustmentNotes && (
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export default function Tutorials() {
|
|||||||
<BookOpen className="w-6 h-6 text-primary" />
|
<BookOpen className="w-6 h-6 text-primary" />
|
||||||
教程库
|
教程库
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-muted-foreground mt-1">专业动作分解与要领,对照标准动作提升技术</p>
|
<p className="text-muted-foreground mt-1">查看动作分解、要点说明和常见错误</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Progress Overview */}
|
{/* Progress Overview */}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
- **训练提醒通知**:支持训练/打卡/分析多类型提醒,自定义时间和重复日期
|
- **训练提醒通知**:支持训练/打卡/分析多类型提醒,自定义时间和重复日期
|
||||||
- **浏览器通知推送**:Notification API集成,权限管理和状态提示
|
- **浏览器通知推送**:Notification API集成,权限管理和状态提示
|
||||||
- **通知记录管理**:未读计数、全部标记已读、历史记录浏览
|
- **通知记录管理**:未读计数、全部标记已读、历史记录浏览
|
||||||
- **文案优化**:去除“在家”等冗余描述,简化为直接信息反馈
|
- **文案调整**:去除冗余描述,简化为直接信息反馈
|
||||||
|
|
||||||
### 数据库变更
|
### 数据库变更
|
||||||
|
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
- **每日打卡系统**:日历视图展示打卡记录,自动计算连续打卡天数
|
- **每日打卡系统**:日历视图展示打卡记录,自动计算连续打卡天数
|
||||||
- **成就徽章系统**:24种成就徽章,涵盖里程碑、训练、连续打卡、视频、分析、评分6个类别
|
- **成就徽章系统**:24种成就徽章,涵盖里程碑、训练、连续打卡、视频、分析、评分6个类别
|
||||||
- **实时摄像头分析**:支持手机/电脑摄像头实时捕捉和MediaPipe姿势分析
|
- **实时摄像头分析**:支持手机/电脑摄像头实时捕捉和MediaPipe姿势分析
|
||||||
- **摄像头位置确认提示**:引导用户调整摄像头到最佳位置
|
- **摄像头位置确认提示**:引导用户调整摄像头位置
|
||||||
- **在线录制系统**:稳定压缩流录制,自适应码率1-2.5Mbps
|
- **在线录制系统**:稳定压缩流录制,自适应码率1-2.5Mbps
|
||||||
- **断线自动重连**:摄像头意外断开时自动检测并重新连接
|
- **断线自动重连**:摄像头意外断开时自动检测并重新连接
|
||||||
- **自动剪辑功能**:基于运动检测自动标记关键时刻
|
- **自动剪辑功能**:基于运动检测自动标记关键时刻
|
||||||
- **移动端全面适配**:安全区域、触摸优化、横屏支持
|
- **移动端适配**:安全区域、触摸优化、横屏支持
|
||||||
- **手机摄像头优化**:前后摄像头切换、自适应分辨率
|
- **手机摄像头优化**:前后摄像头切换、自适应分辨率
|
||||||
|
|
||||||
### 数据库变更
|
### 数据库变更
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
### 文档
|
### 文档
|
||||||
|
|
||||||
- 新增完整README.md
|
- 新增 README.md
|
||||||
- 新增API接口文档
|
- 新增API接口文档
|
||||||
- 新增数据库设计文档
|
- 新增数据库设计文档
|
||||||
- 新增功能列表清单
|
- 新增功能列表清单
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
### 用户与训练
|
### 用户与训练
|
||||||
|
|
||||||
- 用户名登录:无需注册,输入用户名即可进入训练工作台
|
- 用户名登录:无需注册,输入用户名即可进入训练工作台
|
||||||
- AI 训练计划:按技能等级和训练周期生成个性化训练计划
|
- 训练计划:按技能等级和训练周期生成训练计划
|
||||||
- 训练进度:展示训练次数、时长、评分趋势、最近分析结果
|
- 训练进度:展示训练次数、时长、评分趋势、最近分析结果
|
||||||
- 每日打卡与提醒:支持训练打卡、提醒、通知记录
|
- 每日打卡与提醒:支持训练打卡、提醒、通知记录
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
- 归档回放:worker 合并片段并生成 WebM,FFmpeg 可用时额外生成 MP4
|
- 归档回放:worker 合并片段并生成 WebM,FFmpeg 可用时额外生成 MP4
|
||||||
- 视频库登记:归档完成后自动写回现有视频库
|
- 视频库登记:归档完成后自动写回现有视频库
|
||||||
|
|
||||||
## 前端体验能力
|
## 前端能力
|
||||||
|
|
||||||
### 移动端
|
### 移动端
|
||||||
|
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ export const appRouter = router({
|
|||||||
footworkScore: a.footworkScore,
|
footworkScore: a.footworkScore,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const prompt = `你是一位专业网球教练。请为一位${
|
const prompt = `你是一位网球教练。请为一位${
|
||||||
input.skillLevel === "beginner" ? "初级" : input.skillLevel === "intermediate" ? "中级" : "高级"
|
input.skillLevel === "beginner" ? "初级" : input.skillLevel === "intermediate" ? "中级" : "高级"
|
||||||
}水平的网球学员生成一个${input.durationDays}天的在家训练计划。
|
}水平的网球学员生成一个${input.durationDays}天的训练计划。
|
||||||
|
|
||||||
要求:
|
要求:
|
||||||
- 只需要球拍,不需要球场和球网
|
- 只需要球拍,不需要球场和球网
|
||||||
@@ -87,7 +87,7 @@ ${recentScores.length > 0 ? `- 用户最近的分析数据: ${JSON.stringify(rec
|
|||||||
|
|
||||||
const response = await invokeLLM({
|
const response = await invokeLLM({
|
||||||
messages: [
|
messages: [
|
||||||
{ role: "system", content: "你是专业网球教练AI助手。返回严格的JSON格式。" },
|
{ role: "system", content: "你是网球训练计划生成器。返回严格的JSON格式。" },
|
||||||
{ role: "user", content: prompt },
|
{ role: "user", content: prompt },
|
||||||
],
|
],
|
||||||
response_format: {
|
response_format: {
|
||||||
@@ -175,7 +175,7 @@ ${recentScores.length > 0 ? `- 用户最近的分析数据: ${JSON.stringify(rec
|
|||||||
|
|
||||||
const response = await invokeLLM({
|
const response = await invokeLLM({
|
||||||
messages: [
|
messages: [
|
||||||
{ role: "system", content: "你是专业网球教练AI助手。返回严格的JSON格式。" },
|
{ role: "system", content: "你是网球评分生成器。返回严格的JSON格式。" },
|
||||||
{ role: "user", content: prompt },
|
{ role: "user", content: prompt },
|
||||||
],
|
],
|
||||||
response_format: {
|
response_format: {
|
||||||
@@ -361,7 +361,7 @@ ${recentScores.length > 0 ? `- 用户最近的分析数据: ${JSON.stringify(rec
|
|||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: "system",
|
role: "system",
|
||||||
content: "你是一位专业网球教练。根据MediaPipe姿势分析数据,给出具体的姿势矫正建议。用中文回答。",
|
content: "你是一位网球动作分析员。根据MediaPipe姿势分析数据,给出具体的姿势矫正建议。用中文回答。",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: "user",
|
role: "user",
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户