Files
article-workflow/admin/templates/workflow.html
hubian 45b8c70cb9 新增后台管理系统
功能模块:
- 仪表盘: 统计数据概览、快速操作入口
- 资料池管理: 查看、搜索、删除资料
- 文章历史: 查看历史文章列表和主题标签
- 工作流控制: 新建工作流、配置参数、启动流程
- 系统设置: LLM配置、文章类型、数据管理

技术栈:
- Flask Web框架
- Tailwind CSS
- RESTful API
- 实时LLM连接测试
2026-04-08 11:48:39 +08:00

219 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>工作流控制 - 文章工作流</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css" rel="stylesheet">
</head>
<body class="bg-gray-50 min-h-screen">
<div class="flex">
<aside class="w-64 bg-slate-800 min-h-screen fixed left-0 top-0">
<div class="p-6">
<h1 class="text-white text-xl font-bold flex items-center gap-2">
<i class="ri-article-line text-2xl text-blue-400"></i>
文章工作流
</h1>
</div>
<nav class="mt-6">
<a href="/" class="flex items-center gap-3 px-6 py-3 text-slate-300 hover:bg-slate-700 hover:text-white">
<i class="ri-dashboard-line"></i><span>仪表盘</span>
</a>
<a href="/resources" class="flex items-center gap-3 px-6 py-3 text-slate-300 hover:bg-slate-700 hover:text-white">
<i class="ri-database-2-line"></i><span>资料池</span>
</a>
<a href="/articles" class="flex items-center gap-3 px-6 py-3 text-slate-300 hover:bg-slate-700 hover:text-white">
<i class="ri-file-list-3-line"></i><span>文章历史</span>
</a>
<a href="/workflow" class="flex items-center gap-3 px-6 py-3 bg-slate-700 text-white">
<i class="ri-flow-chart"></i><span>工作流</span>
</a>
<a href="/settings" class="flex items-center gap-3 px-6 py-3 text-slate-300 hover:bg-slate-700 hover:text-white">
<i class="ri-settings-3-line"></i><span>系统设置</span>
</a>
</nav>
</aside>
<main class="ml-64 flex-1 p-8">
<h1 class="text-2xl font-bold text-gray-800 mb-6">工作流控制</h1>
<!-- 新建工作流 -->
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4 flex items-center gap-2">
<i class="ri-add-circle-line text-blue-500"></i>
新建工作流
</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">文章主题</label>
<input type="text" id="topicInput"
placeholder="输入文章主题Flash Attention原理解析"
class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">文章类型</label>
<select id="typeSelect" class="w-full px-4 py-3 border border-gray-200 rounded-lg">
<option value="技术解析">技术解析</option>
<option value="技术文档翻译">技术文档翻译</option>
<option value="项目介绍分析">项目介绍分析</option>
<option value="综述文章">综述文章</option>
<option value="实践教程">实践教程</option>
<option value="问题分析">问题分析</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">运行模式</label>
<div class="flex gap-4">
<label class="flex items-center gap-2">
<input type="radio" name="mode" value="full" checked class="text-blue-500">
<span>完整流程</span>
</label>
<label class="flex items-center gap-2">
<input type="radio" name="mode" value="collect" class="text-blue-500">
<span>仅收集资料</span>
</label>
<label class="flex items-center gap-2">
<input type="radio" name="mode" value="write" class="text-blue-500">
<span>仅写作文章</span>
</label>
</div>
</div>
<div class="flex gap-3 pt-4">
<button onclick="startWorkflow()"
class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 flex items-center gap-2">
<i class="ri-play-line"></i> 启动工作流
</button>
<button onclick="suggestTopic()"
class="px-6 py-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 flex items-center gap-2">
<i class="ri-lightbulb-line"></i> 推荐主题
</button>
</div>
</div>
</div>
<!-- 工作流状态 -->
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4 flex items-center gap-2">
<i class="ri-loader-4-line text-orange-500"></i>
工作流状态
</h2>
<div id="workflowStatus" class="text-gray-500">
当前没有运行中的工作流
</div>
</div>
<!-- 工作流说明 -->
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4 flex items-center gap-2">
<i class="ri-information-line text-green-500"></i>
工作流说明
</h2>
<div class="grid grid-cols-1 md:grid-cols-5 gap-4">
<div class="text-center p-4 bg-blue-50 rounded-lg">
<div class="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center mx-auto mb-2">
<span class="text-white font-bold">1</span>
</div>
<p class="font-medium text-gray-800">确定主题</p>
<p class="text-sm text-gray-500 mt-1">选择主题和类型</p>
</div>
<div class="text-center p-4 bg-green-50 rounded-lg">
<div class="w-10 h-10 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-2">
<span class="text-white font-bold">2</span>
</div>
<p class="font-medium text-gray-800">收集资料</p>
<p class="text-sm text-gray-500 mt-1">搜索相关资料</p>
</div>
<div class="text-center p-4 bg-yellow-50 rounded-lg">
<div class="w-10 h-10 bg-yellow-500 rounded-full flex items-center justify-center mx-auto mb-2">
<span class="text-white font-bold">3</span>
</div>
<p class="font-medium text-gray-800">分析资料</p>
<p class="text-sm text-gray-500 mt-1">深度分析内容</p>
</div>
<div class="text-center p-4 bg-purple-50 rounded-lg">
<div class="w-10 h-10 bg-purple-500 rounded-full flex items-center justify-center mx-auto mb-2">
<span class="text-white font-bold">4</span>
</div>
<p class="font-medium text-gray-800">生成大纲</p>
<p class="text-sm text-gray-500 mt-1">规划文章结构</p>
</div>
<div class="text-center p-4 bg-pink-50 rounded-lg">
<div class="w-10 h-10 bg-pink-500 rounded-full flex items-center justify-center mx-auto mb-2">
<span class="text-white font-bold">5</span>
</div>
<p class="font-medium text-gray-800">撰写文章</p>
<p class="text-sm text-gray-500 mt-1">输出最终文章</p>
</div>
</div>
</div>
</main>
</div>
<script>
async function startWorkflow() {
const topic = document.getElementById('topicInput').value.trim();
const type = document.getElementById('typeSelect').value;
const mode = document.querySelector('input[name="mode"]:checked').value;
if (!topic) {
alert('请输入文章主题');
return;
}
const statusEl = document.getElementById('workflowStatus');
statusEl.innerHTML = `
<div class="flex items-center gap-3">
<div class="w-5 h-5 border-2 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
<span>正在启动工作流...</span>
</div>
`;
try {
const response = await fetch('/api/workflow/start', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ topic, type, mode })
});
const data = await response.json();
if (data.status === 'started') {
statusEl.innerHTML = `
<div class="p-4 bg-green-50 rounded-lg">
<p class="text-green-700 font-medium"><i class="ri-check-line"></i> 工作流已启动</p>
<p class="text-sm text-green-600 mt-1">主题: ${data.topic}</p>
<p class="text-sm text-green-600">类型: ${data.type}</p>
<p class="text-sm text-gray-500 mt-2">${data.message}</p>
</div>
`;
} else {
statusEl.innerHTML = `<p class="text-red-500">启动失败: ${data.error}</p>`;
}
} catch (e) {
statusEl.innerHTML = `<p class="text-red-500">请求失败: ${e.message}</p>`;
}
}
async function suggestTopic() {
const topics = [
"Flash Attention原理解析",
"RAG技术实践指南",
"大模型推理优化综述",
"MoE架构深度分析",
"向量数据库选型对比",
"LLM应用开发实战"
];
const randomTopic = topics[Math.floor(Math.random() * topics.length)];
document.getElementById('topicInput').value = randomTopic;
}
</script>
</body>
</html>