From 45b8c70cb9c8a7141555e62bd390d646a7ddf30b Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Wed, 8 Apr 2026 11:48:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=90=8E=E5=8F=B0=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 功能模块: - 仪表盘: 统计数据概览、快速操作入口 - 资料池管理: 查看、搜索、删除资料 - 文章历史: 查看历史文章列表和主题标签 - 工作流控制: 新建工作流、配置参数、启动流程 - 系统设置: LLM配置、文章类型、数据管理 技术栈: - Flask Web框架 - Tailwind CSS - RESTful API - 实时LLM连接测试 --- admin/app.py | 276 +++++++++++++++++++++++++++++++++ admin/templates/articles.html | 126 +++++++++++++++ admin/templates/index.html | 226 +++++++++++++++++++++++++++ admin/templates/resources.html | 236 ++++++++++++++++++++++++++++ admin/templates/settings.html | 234 ++++++++++++++++++++++++++++ admin/templates/workflow.html | 219 ++++++++++++++++++++++++++ requirements.txt | 4 +- 7 files changed, 1320 insertions(+), 1 deletion(-) create mode 100644 admin/app.py create mode 100644 admin/templates/articles.html create mode 100644 admin/templates/index.html create mode 100644 admin/templates/resources.html create mode 100644 admin/templates/settings.html create mode 100644 admin/templates/workflow.html diff --git a/admin/app.py b/admin/app.py new file mode 100644 index 0000000..38a22aa --- /dev/null +++ b/admin/app.py @@ -0,0 +1,276 @@ +""" +文章撰写工作流系统 - 后台管理API +""" + +from flask import Flask, render_template, jsonify, request, send_file +from flask_cors import CORS +import json +import os +import sys +from pathlib import Path +from datetime import datetime + +# 添加父目录到路径 +sys.path.insert(0, str(Path(__file__).parent.parent)) + +from config.settings import LLM_CONFIG, ARTICLE_TYPES, RESOURCE_POOL_CONFIG +from src.resource_pool import ResourcePool +from src.llm_client import LLMClient + +app = Flask(__name__) +CORS(app) + +# 初始化资料池 +pool = ResourcePool(RESOURCE_POOL_CONFIG) + + +# ============ 页面路由 ============ + +@app.route('/') +def index(): + """首页 - 仪表盘""" + return render_template('index.html') + + +@app.route('/resources') +def resources_page(): + """资料池页面""" + return render_template('resources.html') + + +@app.route('/articles') +def articles_page(): + """文章历史页面""" + return render_template('articles.html') + + +@app.route('/workflow') +def workflow_page(): + """工作流控制页面""" + return render_template('workflow.html') + + +@app.route('/settings') +def settings_page(): + """系统设置页面""" + return render_template('settings.html') + + +# ============ API路由 ============ + +@app.route('/api/stats') +def api_stats(): + """获取统计数据""" + stats = pool.get_stats() + + # 添加更多统计 + articles = pool.get_article_history(limit=100) + + # 按日期统计文章 + date_stats = {} + for article in articles: + date = article.get('date', '')[:10] + date_stats[date] = date_stats.get(date, 0) + 1 + + stats['articles_by_date'] = date_stats + stats['recent_articles'] = articles[:5] + + return jsonify(stats) + + +@app.route('/api/resources') +def api_resources(): + """获取资料列表""" + analyzed_only = request.args.get('analyzed') == 'true' + keyword = request.args.get('keyword', '') + + resources = pool.list_resources(analyzed_only=analyzed_only) + + # 关键词过滤 + if keyword: + resources = [r for r in resources if + keyword.lower() in r.get('title', '').lower() or + keyword.lower() in r.get('url', '').lower()] + + return jsonify(resources) + + +@app.route('/api/resources/') +def api_resource_detail(resource_id): + """获取资料详情""" + resource = pool.get_resource(resource_id) + + if not resource: + return jsonify({'error': 'Resource not found'}), 404 + + # 获取分析摘要 + summary = pool.get_summary(resource_id) + if summary: + resource['summary'] = summary + + return jsonify(resource) + + +@app.route('/api/resources/', methods=['DELETE']) +def api_delete_resource(resource_id): + """删除资料""" + # TODO: 实现删除逻辑 + return jsonify({'success': True}) + + +@app.route('/api/summaries') +def api_summaries(): + """获取所有摘要""" + summaries = pool.get_all_summaries() + return jsonify(summaries) + + +@app.route('/api/articles') +def api_articles(): + """获取文章历史""" + limit = request.args.get('limit', 20, type=int) + articles = pool.get_article_history(limit=limit) + return jsonify(articles) + + +@app.route('/api/topics') +def api_topics(): + """获取历史主题""" + topics = pool.get_past_topics() + return jsonify(topics) + + +@app.route('/api/article-types') +def api_article_types(): + """获取文章类型""" + return jsonify(ARTICLE_TYPES) + + +@app.route('/api/keywords') +def api_keywords(): + """获取关键词索引""" + keywords = pool.index.get('keywords_index', {}) + return jsonify(keywords) + + +@app.route('/api/config') +def api_config(): + """获取当前配置""" + # 隐藏敏感信息 + safe_config = { + 'base_url': LLM_CONFIG.get('base_url', ''), + 'model': LLM_CONFIG.get('model', ''), + 'max_tokens': LLM_CONFIG.get('max_tokens', 4096), + 'temperature': LLM_CONFIG.get('temperature', 0.7), + } + return jsonify(safe_config) + + +@app.route('/api/config', methods=['POST']) +def api_update_config(): + """更新配置""" + data = request.json + + # 这里只更新内存中的配置,实际应该保存到文件 + # TODO: 实现配置持久化 + + return jsonify({'success': True, 'message': '配置已更新'}) + + +@app.route('/api/workflow/start', methods=['POST']) +def api_start_workflow(): + """启动工作流""" + data = request.json + topic = data.get('topic') + article_type = data.get('type', '技术解析') + mode = data.get('mode', 'full') + + if not topic: + return jsonify({'error': '请提供文章主题'}), 400 + + # TODO: 实际启动工作流(可以用线程或队列) + # 这里返回模拟响应 + result = { + 'status': 'started', + 'topic': topic, + 'type': article_type, + 'mode': mode, + 'message': '工作流已启动,请稍后查看结果' + } + + return jsonify(result) + + +@app.route('/api/workflow/status') +def api_workflow_status(): + """获取工作流状态""" + # TODO: 实现实际的工作流状态追踪 + return jsonify({ + 'running': False, + 'current_step': None, + 'progress': 0 + }) + + +@app.route('/api/test-llm', methods=['POST']) +def api_test_llm(): + """测试LLM连接""" + try: + client = LLMClient(LLM_CONFIG) + result = client.generate("你好,请回复'连接成功'") + + if result: + return jsonify({'success': True, 'response': result}) + else: + return jsonify({'success': False, 'error': '模型无响应'}), 500 + + except Exception as e: + return jsonify({'success': False, 'error': str(e)}), 500 + + +@app.route('/api/articles/') +def api_article_file(filename): + """获取文章文件内容""" + output_dir = Path(__file__).parent.parent / 'output' / 'articles' + filepath = output_dir / filename + + if filepath.exists(): + return send_file(filepath) + else: + return jsonify({'error': 'File not found'}), 404 + + +@app.route('/api/export/resources') +def api_export_resources(): + """导出资料数据""" + resources = pool.list_resources() + + export_data = { + 'exported_at': datetime.now().isoformat(), + 'count': len(resources), + 'resources': resources + } + + return jsonify(export_data) + + +# ============ 错误处理 ============ + +@app.errorhandler(404) +def not_found(error): + return jsonify({'error': 'Not found'}), 404 + + +@app.errorhandler(500) +def server_error(error): + return jsonify({'error': 'Internal server error'}), 500 + + +if __name__ == '__main__': + print("=" * 50) + print("文章撰写工作流系统 - 后台管理") + print("=" * 50) + print(f"访问地址: http://localhost:5001") + print("=" * 50) + + app.run(host='0.0.0.0', port=5001, debug=True) \ No newline at end of file diff --git a/admin/templates/articles.html b/admin/templates/articles.html new file mode 100644 index 0000000..490fdd7 --- /dev/null +++ b/admin/templates/articles.html @@ -0,0 +1,126 @@ + + + + + + 文章历史 - 文章工作流 + + + + +
+ + +
+

文章历史

+ + +
+
+
+

已生成的文章

+ 0 篇文章 +
+
+ +
+
加载中...
+
+
+ + +
+

历史主题标签

+
+ 加载中... +
+
+
+
+ + + + \ No newline at end of file diff --git a/admin/templates/index.html b/admin/templates/index.html new file mode 100644 index 0000000..6ef9781 --- /dev/null +++ b/admin/templates/index.html @@ -0,0 +1,226 @@ + + + + + + 文章撰写工作流系统 - 后台管理 + + + + + +
+ + + + +
+ +
+
+
+
+

资料总数

+

-

+
+
+ +
+
+
+ +
+
+
+

已分析

+

-

+
+
+ +
+
+
+ +
+
+
+

文章总数

+

-

+
+
+ +
+
+
+ +
+
+
+

关键词数

+

-

+
+
+ +
+
+
+
+ + + + + +
+

+ + 系统状态 +

+
+
+

LLM模型

+

-

+
+
+

API地址

+

-

+
+
+

连接状态

+

+ 检测中... +

+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/admin/templates/resources.html b/admin/templates/resources.html new file mode 100644 index 0000000..e95087c --- /dev/null +++ b/admin/templates/resources.html @@ -0,0 +1,236 @@ + + + + + + 资料池管理 - 文章工作流 + + + + +
+ + + + +
+
+

资料池管理

+
+ +
+
+ + +
+
+
+ +
+ +
+
+ + +
+ + + + + + + + + + + + + +
标题来源状态添加时间操作
加载中...
+
+ + + +
+
+ + + + \ No newline at end of file diff --git a/admin/templates/settings.html b/admin/templates/settings.html new file mode 100644 index 0000000..3cb7644 --- /dev/null +++ b/admin/templates/settings.html @@ -0,0 +1,234 @@ + + + + + + 系统设置 - 文章工作流 + + + + +
+ + +
+

系统设置

+ + +
+

+ + 大模型配置 +

+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+

+ + 文章类型 +

+ +
+

加载中...

+
+
+ + +
+

+ + 数据管理 +

+ +
+
+
+

导出资料池

+

导出所有资料数据为JSON格式

+
+ +
+
+
+

导出文章历史

+

导出所有文章记录

+
+ +
+
+
+

清空资料池

+

删除所有资料和分析数据(不可恢复)

+
+ +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/admin/templates/workflow.html b/admin/templates/workflow.html new file mode 100644 index 0000000..1431421 --- /dev/null +++ b/admin/templates/workflow.html @@ -0,0 +1,219 @@ + + + + + + 工作流控制 - 文章工作流 + + + + +
+ + +
+

工作流控制

+ + +
+

+ + 新建工作流 +

+ +
+
+ + +
+ +
+ + +
+ +
+ +
+ + + +
+
+ +
+ + +
+
+
+ + +
+

+ + 工作流状态 +

+ +
+ 当前没有运行中的工作流 +
+
+ + +
+

+ + 工作流说明 +

+ +
+
+
+ 1 +
+

确定主题

+

选择主题和类型

+
+
+
+ 2 +
+

收集资料

+

搜索相关资料

+
+
+
+ 3 +
+

分析资料

+

深度分析内容

+
+
+
+ 4 +
+

生成大纲

+

规划文章结构

+
+
+
+ 5 +
+

撰写文章

+

输出最终文章

+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 39aae79..1c31ad1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,3 @@ -requests>=2.28.0 \ No newline at end of file +requests>=2.28.0 +flask>=2.3.0 +flask-cors>=4.0.0 \ No newline at end of file