add
This commit is contained in:
Sanjin
2025-05-09 21:24:09 +08:00
parent 5450f95d12
commit 6cbaa3d7b8
12 changed files with 267 additions and 7 deletions
+2
View File
@@ -1,6 +1,8 @@
<script setup lang="ts">
import Toaster from '@/components/ui/toast/Toaster.vue'
</script>
<template>
<Toaster />
<router-view />
</template>
+9
View File
@@ -8,3 +8,12 @@ export function getHelloWorld() {
export function getWriterSeque() {
return request.get<{ writer_seque: string[] }>("/writer_seque");
}
export function openFolderAPI(task_id: string) {
return request.get<{ message: string }>("/open_folder", {
params: {
task_id,
},
});
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

@@ -0,0 +1,85 @@
<script setup lang="ts">
import { ref } from 'vue'
import { Button } from '@/components/ui/button'
import { useRouter } from 'vue-router'
// 定义样例类型
interface ModelingExample {
id: number
title: string
source: string
description: string
tags: string[]
problemText: string
}
const router = useRouter()
const examples = ref<ModelingExample[]>([
{
id: 1,
title: "基于改进随机森林算法的农作物产量预测",
source: "2023年高教社杯全国大学生数学建模竞赛",
description: "通过历史气象和产量数据,建立农作物产量预测模型。",
tags: ["随机森林", "数据分析", "气象预测"],
problemText: "给定历年中国主要粮食作物产量数据及气象数据,建立一个预测模型,预测未来五年的粮食产量,并分析气候变化对粮食产量的影响。"
},
{
id: 2,
title: "共享单车潮汐调度优化研究",
source: "2022年美国大学生数学建模竞赛",
description: "针对城市高峰期共享单车分布不均问题,构建调度优化模型。",
tags: ["图论", "线性规划", "智能调度"],
problemText: "针对共享单车系统在早晚高峰期出现的车辆分布不均问题,构建一个优化调度模型,最小化调度成本同时满足用户需求。"
},
{
id: 3,
title: "新冠疫情传播模型与干预策略评估",
source: "2021年高教社杯全国大学生数学建模竞赛",
description: "基于SEIR模型改进的传染病传播预测与防控策略分析。",
tags: ["微分方程", "蒙特卡洛", "策略评估"],
problemText: "基于已有的疫情数据,构建传染病传播模型,模拟不同干预措施对疫情发展的影响,为防控决策提供科学依据。"
}
])
// 选择样例并跳转到任务创建步骤
const selectExample = (example: ModelingExample) => {
// 这里可以存储选中的样例数据到 localStorage 或 pinia store
localStorage.setItem('selectedExample', JSON.stringify(example))
// 跳转到任务创建流程
router.push('/task/create')
}
</script>
<template>
<div class="mt-8 mb-12">
<h2 class="text-xl font-medium mb-4">样例解析</h2>
<p class="text-sm text-muted-foreground mb-6">浏览历年数模竞赛优秀案例快速开始你的建模任务</p>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div v-for="example in examples" :key="example.id"
class="border rounded-lg overflow-hidden hover:shadow-md transition-shadow">
<div class="p-4 border-b bg-muted/30">
<h3 class="font-medium line-clamp-2">{{ example.title }}</h3>
<p class="text-xs text-muted-foreground mt-1">{{ example.source }}</p>
</div>
<div class="p-4">
<p class="text-sm text-muted-foreground mb-3">{{ example.description }}</p>
<div class="flex flex-wrap gap-2 mt-2 mb-3">
<span v-for="tag in example.tags" :key="tag"
class="px-2 py-0.5 bg-primary/10 text-primary rounded-full text-xs">
{{ tag }}
</span>
</div>
<div class="flex gap-2 mt-4">
<Button variant="default" size="sm" class="flex-1" @click="selectExample(example)">
基于此开始
</Button>
</div>
</div>
</div>
</div>
</div>
</template>
+3
View File
@@ -3,6 +3,7 @@
import AppSidebar from '@/components/AppSidebar.vue'
import UserStepper from '@/components/UserStepper.vue'
import ModelingExamples from '@/components/ModelingExamples.vue'
import { ref, onMounted } from 'vue'
import {
SidebarInset,
@@ -37,6 +38,8 @@ onMounted(() => {
<UserStepper>
</UserStepper>
<ModelingExamples />
</div>
</div>
</SidebarInset>
+117
View File
@@ -0,0 +1,117 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Button } from '@/components/ui/button'
interface ModelingExample {
id: number
title: string
source: string
description: string
tags: string[]
problemText: string
}
const route = useRoute()
const router = useRouter()
const exampleId = route.params.id as string
const example = ref<ModelingExample | null>(null)
const loading = ref(true)
onMounted(() => {
// 从localStorage获取样例数据
const storedExample = localStorage.getItem('viewingExample')
if (storedExample) {
example.value = JSON.parse(storedExample)
loading.value = false
} else {
// 如果没有找到缓存的数据可以模拟一个API请求
// 实际项目中应该从API获取
setTimeout(() => {
example.value = {
id: parseInt(exampleId),
title: "数学建模样例案例",
source: "全国大学生数学建模竞赛",
description: "这是一个示例数模案例。",
tags: ["数据分析", "算法优化"],
problemText: "这里是完整的竞赛题目描述文本。"
}
loading.value = false
}, 800)
}
})
// 基于当前样例开始新任务
const startModelingTask = () => {
if (example.value) {
localStorage.setItem('selectedExample', JSON.stringify(example.value))
router.push('/task/create')
}
}
// 返回样例列表
const goBack = () => {
router.push('/chat')
}
</script>
<template>
<div class="container mx-auto py-8 px-4 max-w-4xl">
<Button variant="ghost" class="mb-6" @click="goBack">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2">
<path d="m15 18-6-6 6-6" />
</svg>
返回首页
</Button>
<div v-if="loading" class="flex justify-center py-12">
<div class="animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full"></div>
</div>
<div v-else-if="example" class="space-y-8">
<div class="space-y-4">
<h1 class="text-2xl font-semibold">{{ example.title }}</h1>
<p class="text-muted-foreground">{{ example.source }}</p>
<div class="flex flex-wrap gap-2 mt-4">
<span v-for="tag in example.tags" :key="tag"
class="px-3 py-1 bg-primary/10 text-primary rounded-full text-sm">
{{ tag }}
</span>
</div>
</div>
<div class="space-y-4">
<h2 class="text-xl font-medium">题目描述</h2>
<div class="p-6 border rounded-lg bg-muted/20">
<p class="whitespace-pre-line">{{ example.problemText }}</p>
</div>
</div>
<div class="space-y-4">
<h2 class="text-xl font-medium">解题思路</h2>
<div class="p-6 border rounded-lg">
<ol class="list-decimal list-inside space-y-3">
<li>分析问题背景和关键变量</li>
<li>收集和预处理相关数据</li>
<li>构建数学模型并确定算法</li>
<li>实现代码并训练模型</li>
<li>验证模型并分析结果</li>
<li>撰写论文并呈现结论</li>
</ol>
</div>
</div>
<div class="flex justify-center pt-6">
<Button size="lg" @click="startModelingTask">
基于此案例开始建模
</Button>
</div>
</div>
<div v-else class="text-center py-12">
<p>未找到相关样例</p>
<Button variant="outline" class="mt-4" @click="goBack">返回首页</Button>
</div>
</div>
</template>
+24 -4
View File
@@ -19,9 +19,13 @@ import WriterEditor from '@/components/WriterEditor.vue'
import ChatArea from '@/components/ChatArea.vue'
import { onMounted, onBeforeUnmount, ref } from 'vue'
import { useTaskStore } from '@/stores/task'
import { ScrollArea } from '@/components/ui/scroll-area'
import { getWriterSeque } from '@/apis/commonApi';
import { Button } from '@/components/ui/button';
import { openFolderAPI } from '@/apis/commonApi';
import { useToast } from '@/components/ui/toast/use-toast'
const { toast } = useToast()
const props = defineProps<{ task_id: string }>()
const taskStore = useTaskStore()
@@ -36,6 +40,15 @@ onMounted(async () => {
writerSequence.value = Array.isArray(res.data) ? res.data : [];
})
const openFolder = async () => {
const res = await openFolderAPI(props.task_id);
console.log(res);
toast({
title: '打开工作目录成功',
description: res.data.message,
})
}
onBeforeUnmount(() => {
taskStore.closeWebSocket()
@@ -63,9 +76,16 @@ onBeforeUnmount(() => {
</TabsTrigger>
</TabsList>
<!-- TODO: 其他选项 -->
<Button @click="taskStore.downloadMessages" class="flex justify-end">
下载消息
</Button>
<div class="flex justify-end gap-2">
<Button @click="taskStore.downloadMessages" class="flex justify-end">
下载消息
</Button>
<Button @click="openFolder" class="flex">
打开工作目录
</Button>
</div>
</div>
<TabsContent value="coder" class="h-full p-1 flex-1 overflow-auto">
+5
View File
@@ -20,6 +20,11 @@ const routes = [
path: "/task/:task_id",
component: () => import("@/pages/task/index.vue"),
props: true,
},
{
path: "/example/:id",
component: () => import("@/pages/example/[id].vue"),
props: true,
},
{
path: "/test",