Files
aitsc/优化历史功能设计方案.md

1054 lines
37 KiB
Markdown
Raw Permalink Normal View History

2025-10-10 23:39:54 +08:00
# 📚 优化历史功能设计方案
## 🎯 功能概述
基于现有的生成专业提示词系统,开发一个完整的优化历史功能,让用户可以:
- 查看自己生成的所有提示词历史
- 搜索和筛选历史记录
- 重新使用历史提示词
- 收藏重要的提示词
- 导出历史数据
## 🏗️ 系统架构设计
### 1. 数据模型设计
#### 1.1 历史记录表 (prompt_history)
```sql
CREATE TABLE prompt_history (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
wx_user_id INT,
original_input TEXT NOT NULL COMMENT '原始输入',
generated_prompt TEXT NOT NULL COMMENT '生成的提示词',
template_id INT COMMENT '使用的模板ID',
template_name VARCHAR(100) COMMENT '模板名称',
generation_time INT COMMENT '生成耗时(毫秒)',
satisfaction_rating TINYINT COMMENT '满意度评分(1-5)',
tags JSON COMMENT '标签列表',
is_favorite BOOLEAN DEFAULT FALSE COMMENT '是否收藏',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_wx_user_id (wx_user_id),
INDEX idx_created_at (created_at),
INDEX idx_template_id (template_id),
INDEX idx_is_favorite (is_favorite)
);
```
#### 1.2 历史标签表 (history_tags)
```sql
CREATE TABLE history_tags (
id INT PRIMARY KEY AUTO_INCREMENT,
history_id INT NOT NULL,
tag_name VARCHAR(50) NOT NULL,
tag_type VARCHAR(20) DEFAULT 'custom',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (history_id) REFERENCES prompt_history(id) ON DELETE CASCADE,
INDEX idx_history_id (history_id),
INDEX idx_tag_name (tag_name)
);
```
#### 1.3 用户统计表 (user_statistics)
```sql
CREATE TABLE user_statistics (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
total_generations INT DEFAULT 0,
favorite_count INT DEFAULT 0,
avg_rating DECIMAL(3,2) DEFAULT 0.00,
last_generation_at TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_user_id (user_id)
);
```
### 2. API接口设计
#### 2.1 获取历史记录列表
```http
GET /api/history
参数:
- page: 页码 (默认1)
- per_page: 每页数量 (默认20)
- search: 搜索关键词
- template_id: 模板筛选
- date_from: 开始日期
- date_to: 结束日期
- is_favorite: 是否只显示收藏
- sort: 排序方式 (created_at, rating, generation_time)
```
#### 2.2 获取单个历史记录
```http
GET /api/history/{id}
```
#### 2.3 更新历史记录
```http
PUT /api/history/{id}
数据:
- satisfaction_rating: 满意度评分
- tags: 标签列表
- is_favorite: 是否收藏
```
#### 2.4 删除历史记录
```http
DELETE /api/history/{id}
```
#### 2.5 批量操作
```http
POST /api/history/batch
操作:
- delete: 批量删除
- favorite: 批量收藏
- unfavorite: 批量取消收藏
```
#### 2.6 导出历史记录
```http
GET /api/history/export
参数:
- format: 导出格式 (json, csv, txt)
- date_from: 开始日期
- date_to: 结束日期
```
### 3. 前端页面设计
#### 3.1 历史记录列表页面
- **搜索栏**: 支持关键词搜索
- **筛选器**: 按模板、日期、评分筛选
- **排序选项**: 按时间、评分、生成时间排序
- **列表展示**: 卡片式展示历史记录
- **分页导航**: 支持分页浏览
#### 3.2 历史记录详情页面
- **完整展示**: 原始输入和生成结果
- **操作按钮**: 复制、收藏、评分、删除
- **相关信息**: 生成时间、使用模板、耗时等
#### 3.3 统计面板
- **总生成数**: 历史生成总数
- **收藏数量**: 收藏的提示词数量
- **平均评分**: 用户满意度统计
- **使用趋势**: 生成时间趋势图
## 🔧 技术实现方案
### 1. 后端实现
#### 1.1 数据模型 (models.py)
```python
class PromptHistory(db.Model):
__tablename__ = 'prompt_history'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, nullable=False)
wx_user_id = db.Column(db.Integer)
original_input = db.Column(db.Text, nullable=False)
generated_prompt = db.Column(db.Text, nullable=False)
template_id = db.Column(db.Integer)
template_name = db.Column(db.String(100))
generation_time = db.Column(db.Integer)
satisfaction_rating = db.Column(db.SmallInteger)
tags = db.Column(db.JSON)
is_favorite = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# 关联关系
template = db.relationship('PromptTemplate', backref='histories')
history_tags = db.relationship('HistoryTag', backref='history', lazy='dynamic', cascade='all, delete-orphan')
def to_dict(self):
return {
'id': self.id,
'original_input': self.original_input,
'generated_prompt': self.generated_prompt,
'template_id': self.template_id,
'template_name': self.template_name,
'generation_time': self.generation_time,
'satisfaction_rating': self.satisfaction_rating,
'tags': self.tags or [],
'is_favorite': self.is_favorite,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None
}
class HistoryTag(db.Model):
__tablename__ = 'history_tags'
id = db.Column(db.Integer, primary_key=True)
history_id = db.Column(db.Integer, db.ForeignKey('prompt_history.id'), nullable=False)
tag_name = db.Column(db.String(50), nullable=False)
tag_type = db.Column(db.String(20), default='custom')
created_at = db.Column(db.DateTime, default=datetime.utcnow)
class UserStatistics(db.Model):
__tablename__ = 'user_statistics'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, unique=True, nullable=False)
total_generations = db.Column(db.Integer, default=0)
favorite_count = db.Column(db.Integer, default=0)
avg_rating = db.Column(db.Numeric(3, 2), default=0.00)
last_generation_at = db.Column(db.DateTime)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
```
#### 1.2 API路由 (history_routes.py)
```python
from flask import Blueprint, request, jsonify, current_app
from sqlalchemy import desc, asc, and_, or_
from datetime import datetime, timedelta
import json
history_bp = Blueprint('history', __name__)
@history_bp.route('/api/history', methods=['GET'])
def get_history_list():
"""获取历史记录列表"""
try:
# 获取参数
page = request.args.get('page', 1, type=int)
per_page = min(request.args.get('per_page', 20, type=int), 100)
search = request.args.get('search', '').strip()
template_id = request.args.get('template_id', type=int)
date_from = request.args.get('date_from')
date_to = request.args.get('date_to')
is_favorite = request.args.get('is_favorite', type=bool)
sort = request.args.get('sort', 'created_at')
# 获取用户ID
user_id = get_current_user_id()
# 构建查询
query = PromptHistory.query.filter(
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id)
)
# 搜索条件
if search:
query = query.filter(
or_(
PromptHistory.original_input.contains(search),
PromptHistory.generated_prompt.contains(search)
)
)
# 模板筛选
if template_id:
query = query.filter(PromptHistory.template_id == template_id)
# 日期筛选
if date_from:
query = query.filter(PromptHistory.created_at >= datetime.fromisoformat(date_from))
if date_to:
query = query.filter(PromptHistory.created_at <= datetime.fromisoformat(date_to))
# 收藏筛选
if is_favorite is not None:
query = query.filter(PromptHistory.is_favorite == is_favorite)
# 排序
if sort == 'rating':
query = query.order_by(desc(PromptHistory.satisfaction_rating))
elif sort == 'generation_time':
query = query.order_by(asc(PromptHistory.generation_time))
else:
query = query.order_by(desc(PromptHistory.created_at))
# 分页
pagination = query.paginate(page=page, per_page=per_page, error_out=False)
# 格式化结果
history_list = [history.to_dict() for history in pagination.items]
return jsonify({
'success': True,
'data': {
'history': history_list,
'pagination': {
'page': pagination.page,
'per_page': pagination.per_page,
'total': pagination.total,
'pages': pagination.pages,
'has_next': pagination.has_next,
'has_prev': pagination.has_prev
}
}
})
except Exception as e:
current_app.logger.error(f"获取历史记录失败: {str(e)}")
return jsonify({
'success': False,
'message': '获取历史记录失败'
}), 500
@history_bp.route('/api/history/<int:history_id>', methods=['GET'])
def get_history_detail(history_id):
"""获取单个历史记录详情"""
try:
user_id = get_current_user_id()
history = PromptHistory.query.filter(
PromptHistory.id == history_id,
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id)
).first()
if not history:
return jsonify({
'success': False,
'message': '历史记录不存在'
}), 404
return jsonify({
'success': True,
'data': history.to_dict()
})
except Exception as e:
current_app.logger.error(f"获取历史记录详情失败: {str(e)}")
return jsonify({
'success': False,
'message': '获取历史记录详情失败'
}), 500
@history_bp.route('/api/history/<int:history_id>', methods=['PUT'])
def update_history(history_id):
"""更新历史记录"""
try:
user_id = get_current_user_id()
history = PromptHistory.query.filter(
PromptHistory.id == history_id,
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id)
).first()
if not history:
return jsonify({
'success': False,
'message': '历史记录不存在'
}), 404
data = request.get_json()
# 更新字段
if 'satisfaction_rating' in data:
history.satisfaction_rating = data['satisfaction_rating']
if 'tags' in data:
history.tags = data['tags']
if 'is_favorite' in data:
history.is_favorite = data['is_favorite']
history.updated_at = datetime.utcnow()
db.session.commit()
# 更新用户统计
update_user_statistics(user_id)
return jsonify({
'success': True,
'data': history.to_dict(),
'message': '更新成功'
})
except Exception as e:
current_app.logger.error(f"更新历史记录失败: {str(e)}")
return jsonify({
'success': False,
'message': '更新历史记录失败'
}), 500
@history_bp.route('/api/history/<int:history_id>', methods=['DELETE'])
def delete_history(history_id):
"""删除历史记录"""
try:
user_id = get_current_user_id()
history = PromptHistory.query.filter(
PromptHistory.id == history_id,
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id)
).first()
if not history:
return jsonify({
'success': False,
'message': '历史记录不存在'
}), 404
db.session.delete(history)
db.session.commit()
# 更新用户统计
update_user_statistics(user_id)
return jsonify({
'success': True,
'message': '删除成功'
})
except Exception as e:
current_app.logger.error(f"删除历史记录失败: {str(e)}")
return jsonify({
'success': False,
'message': '删除历史记录失败'
}), 500
@history_bp.route('/api/history/export', methods=['GET'])
def export_history():
"""导出历史记录"""
try:
user_id = get_current_user_id()
format_type = request.args.get('format', 'json')
date_from = request.args.get('date_from')
date_to = request.args.get('date_to')
# 构建查询
query = PromptHistory.query.filter(
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id)
)
if date_from:
query = query.filter(PromptHistory.created_at >= datetime.fromisoformat(date_from))
if date_to:
query = query.filter(PromptHistory.created_at <= datetime.fromisoformat(date_to))
histories = query.order_by(desc(PromptHistory.created_at)).all()
if format_type == 'json':
data = [history.to_dict() for history in histories]
return jsonify({
'success': True,
'data': data,
'count': len(data)
})
elif format_type == 'csv':
# 实现CSV导出
pass
else:
return jsonify({
'success': False,
'message': '不支持的导出格式'
}), 400
except Exception as e:
current_app.logger.error(f"导出历史记录失败: {str(e)}")
return jsonify({
'success': False,
'message': '导出历史记录失败'
}), 500
def get_current_user_id():
"""获取当前用户ID"""
# 实现用户ID获取逻辑
return 1 # 临时返回默认用户ID
def update_user_statistics(user_id):
"""更新用户统计信息"""
try:
# 获取用户历史统计
total_generations = PromptHistory.query.filter(
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id)
).count()
favorite_count = PromptHistory.query.filter(
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id),
PromptHistory.is_favorite == True
).count()
# 计算平均评分
avg_rating_result = db.session.query(db.func.avg(PromptHistory.satisfaction_rating)).filter(
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id),
PromptHistory.satisfaction_rating.isnot(None)
).scalar()
avg_rating = float(avg_rating_result) if avg_rating_result else 0.0
# 获取最后生成时间
last_generation = PromptHistory.query.filter(
or_(PromptHistory.user_id == user_id, PromptHistory.wx_user_id == user_id)
).order_by(desc(PromptHistory.created_at)).first()
last_generation_at = last_generation.created_at if last_generation else None
# 更新或创建统计记录
stats = UserStatistics.query.filter_by(user_id=user_id).first()
if not stats:
stats = UserStatistics(user_id=user_id)
db.session.add(stats)
stats.total_generations = total_generations
stats.favorite_count = favorite_count
stats.avg_rating = avg_rating
stats.last_generation_at = last_generation_at
stats.updated_at = datetime.utcnow()
db.session.commit()
except Exception as e:
current_app.logger.error(f"更新用户统计失败: {str(e)}")
db.session.rollback()
```
### 2. 前端实现
#### 2.1 历史记录页面 (history.html)
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>优化历史 - AI提示词生成器</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.history-card {
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
transition: all 0.3s ease;
}
.history-card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.history-card.favorite {
border-color: #ff6b6b;
background-color: #fff5f5;
}
.search-section {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin-bottom: 30px;
}
.stats-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.tag {
display: inline-block;
background: #e3f2fd;
color: #1976d2;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
margin: 2px;
}
.rating-stars {
color: #ffc107;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<!-- 侧边栏 -->
<div class="col-md-3">
<div class="search-section">
<h5><i class="fas fa-search"></i> 搜索和筛选</h5>
<div class="mb-3">
<input type="text" class="form-control" id="searchInput" placeholder="搜索历史记录...">
</div>
<div class="mb-3">
<select class="form-select" id="templateFilter">
<option value="">所有模板</option>
</select>
</div>
<div class="mb-3">
<select class="form-select" id="dateFilter">
<option value="">所有时间</option>
<option value="today">今天</option>
<option value="week">本周</option>
<option value="month">本月</option>
</select>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="favoriteFilter">
<label class="form-check-label" for="favoriteFilter">
只显示收藏
</label>
</div>
</div>
<div class="mb-3">
<select class="form-select" id="sortSelect">
<option value="created_at">按时间排序</option>
<option value="rating">按评分排序</option>
<option value="generation_time">按生成时间排序</option>
</select>
</div>
<button class="btn btn-primary w-100" onclick="searchHistory()">
<i class="fas fa-search"></i> 搜索
</button>
</div>
<!-- 统计信息 -->
<div class="stats-card">
<h6><i class="fas fa-chart-bar"></i> 统计信息</h6>
<div class="row text-center">
<div class="col-6">
<div class="h4" id="totalGenerations">0</div>
<small>总生成数</small>
</div>
<div class="col-6">
<div class="h4" id="favoriteCount">0</div>
<small>收藏数</small>
</div>
</div>
<div class="mt-3">
<small>平均评分: <span id="avgRating">0.0</span></small>
</div>
</div>
</div>
<!-- 主内容区 -->
<div class="col-md-9">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2><i class="fas fa-history"></i> 优化历史</h2>
<div>
<button class="btn btn-outline-primary" onclick="exportHistory()">
<i class="fas fa-download"></i> 导出
</button>
<button class="btn btn-primary" onclick="refreshHistory()">
<i class="fas fa-refresh"></i> 刷新
</button>
</div>
</div>
<!-- 历史记录列表 -->
<div id="historyList">
<!-- 动态加载内容 -->
</div>
<!-- 分页 -->
<nav aria-label="历史记录分页">
<ul class="pagination justify-content-center" id="pagination">
<!-- 动态生成分页 -->
</ul>
</nav>
</div>
</div>
</div>
<!-- 历史记录详情模态框 -->
<div class="modal fade" id="historyModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">历史记录详情</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">原始输入:</label>
<div class="border p-3 rounded" id="modalOriginalInput"></div>
</div>
<div class="mb-3">
<label class="form-label">生成的提示词:</label>
<div class="border p-3 rounded" id="modalGeneratedPrompt"></div>
</div>
<div class="row">
<div class="col-md-6">
<label class="form-label">模板:</label>
<span id="modalTemplateName"></span>
</div>
<div class="col-md-6">
<label class="form-label">生成时间:</label>
<span id="modalCreatedAt"></span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" onclick="copyPrompt()">
<i class="fas fa-copy"></i> 复制
</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
let currentPage = 1;
let currentFilters = {};
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
loadHistory();
loadTemplates();
loadStatistics();
});
// 加载历史记录
function loadHistory(page = 1) {
const params = new URLSearchParams({
page: page,
per_page: 20,
...currentFilters
});
fetch(`/api/history?${params}`)
.then(response => response.json())
.then(data => {
if (data.success) {
displayHistory(data.data.history);
displayPagination(data.data.pagination);
currentPage = page;
} else {
alert('加载历史记录失败: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('加载历史记录失败');
});
}
// 显示历史记录
function displayHistory(historyList) {
const container = document.getElementById('historyList');
if (historyList.length === 0) {
container.innerHTML = `
<div class="text-center py-5">
<i class="fas fa-history fa-3x text-muted mb-3"></i>
<h5 class="text-muted">暂无历史记录</h5>
<p class="text-muted">开始生成您的第一个提示词吧!</p>
</div>
`;
return;
}
container.innerHTML = historyList.map(history => `
<div class="history-card ${history.is_favorite ? 'favorite' : ''}" data-id="${history.id}">
<div class="row">
<div class="col-md-8">
<h6 class="mb-2">
${history.template_name || '默认模板'}
${history.is_favorite ? '<i class="fas fa-heart text-danger ms-2"></i>' : ''}
</h6>
<p class="text-muted mb-2">${history.original_input.substring(0, 100)}${history.original_input.length > 100 ? '...' : ''}</p>
<div class="mb-2">
${history.tags ? history.tags.map(tag => `<span class="tag">${tag}</span>`).join('') : ''}
</div>
<small class="text-muted">
<i class="fas fa-clock"></i> ${formatDate(history.created_at)}
${history.generation_time ? ` | <i class="fas fa-stopwatch"></i> ${history.generation_time}ms` : ''}
</small>
</div>
<div class="col-md-4 text-end">
<div class="mb-2">
${history.satisfaction_rating ? generateStars(history.satisfaction_rating) : ''}
</div>
<div class="btn-group">
<button class="btn btn-sm btn-outline-primary" onclick="viewHistory(${history.id})">
<i class="fas fa-eye"></i>
</button>
<button class="btn btn-sm btn-outline-success" onclick="copyPrompt('${history.generated_prompt.replace(/'/g, "\\'")}')">
<i class="fas fa-copy"></i>
</button>
<button class="btn btn-sm ${history.is_favorite ? 'btn-warning' : 'btn-outline-warning'}" onclick="toggleFavorite(${history.id})">
<i class="fas fa-heart"></i>
</button>
<button class="btn btn-sm btn-outline-danger" onclick="deleteHistory(${history.id})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
</div>
`).join('');
}
// 搜索历史记录
function searchHistory() {
currentFilters = {
search: document.getElementById('searchInput').value,
template_id: document.getElementById('templateFilter').value,
date_filter: document.getElementById('dateFilter').value,
is_favorite: document.getElementById('favoriteFilter').checked,
sort: document.getElementById('sortSelect').value
};
loadHistory(1);
}
// 查看历史记录详情
function viewHistory(historyId) {
fetch(`/api/history/${historyId}`)
.then(response => response.json())
.then(data => {
if (data.success) {
const history = data.data;
document.getElementById('modalOriginalInput').textContent = history.original_input;
document.getElementById('modalGeneratedPrompt').textContent = history.generated_prompt;
document.getElementById('modalTemplateName').textContent = history.template_name || '默认模板';
document.getElementById('modalCreatedAt').textContent = formatDate(history.created_at);
const modal = new bootstrap.Modal(document.getElementById('historyModal'));
modal.show();
} else {
alert('获取历史记录详情失败: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('获取历史记录详情失败');
});
}
// 复制提示词
function copyPrompt(text) {
if (text) {
navigator.clipboard.writeText(text).then(() => {
alert('提示词已复制到剪贴板');
});
}
}
// 切换收藏状态
function toggleFavorite(historyId) {
fetch(`/api/history/${historyId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
is_favorite: !document.querySelector(`[data-id="${historyId}"]`).classList.contains('favorite')
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
loadHistory(currentPage);
loadStatistics();
} else {
alert('操作失败: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('操作失败');
});
}
// 删除历史记录
function deleteHistory(historyId) {
if (confirm('确定要删除这条历史记录吗?')) {
fetch(`/api/history/${historyId}`, {
method: 'DELETE'
})
.then(response => response.json())
.then(data => {
if (data.success) {
loadHistory(currentPage);
loadStatistics();
} else {
alert('删除失败: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('删除失败');
});
}
}
// 导出历史记录
function exportHistory() {
const params = new URLSearchParams({
format: 'json',
...currentFilters
});
window.open(`/api/history/export?${params}`, '_blank');
}
// 刷新历史记录
function refreshHistory() {
loadHistory(currentPage);
loadStatistics();
}
// 加载模板列表
function loadTemplates() {
fetch('/api/templates')
.then(response => response.json())
.then(data => {
if (data.success) {
const select = document.getElementById('templateFilter');
select.innerHTML = '<option value="">所有模板</option>' +
data.data.templates.map(template =>
`<option value="${template.id}">${template.name}</option>`
).join('');
}
});
}
// 加载统计信息
function loadStatistics() {
fetch('/api/history/statistics')
.then(response => response.json())
.then(data => {
if (data.success) {
document.getElementById('totalGenerations').textContent = data.data.total_generations;
document.getElementById('favoriteCount').textContent = data.data.favorite_count;
document.getElementById('avgRating').textContent = data.data.avg_rating.toFixed(1);
}
});
}
// 工具函数
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleString('zh-CN');
}
function generateStars(rating) {
return '★'.repeat(rating) + '☆'.repeat(5 - rating);
}
</script>
</body>
</html>
```
### 3. 集成到现有系统
#### 3.1 修改生成逻辑
在现有的生成提示词逻辑中添加历史记录保存:
```python
def save_to_history(user_input, generated_text, template_id=None, generation_time=None):
"""保存到历史记录"""
try:
user_id = get_current_user_id()
template = PromptTemplate.query.get(template_id) if template_id else None
history = PromptHistory(
user_id=user_id,
original_input=user_input,
generated_prompt=generated_text,
template_id=template_id,
template_name=template.name if template else None,
generation_time=generation_time
)
db.session.add(history)
db.session.commit()
# 更新用户统计
update_user_statistics(user_id)
return history.id
except Exception as e:
current_app.logger.error(f"保存历史记录失败: {str(e)}")
db.session.rollback()
return None
```
#### 3.2 修改路由注册
在应用初始化时注册历史记录蓝图:
```python
from src.flask_prompt_master.routes.history_routes import history_bp
def create_app():
app = Flask(__name__)
# 注册蓝图
app.register_blueprint(main_bp)
app.register_blueprint(history_bp) # 新增历史记录蓝图
return app
```
## 🎯 功能特性
### 1. 核心功能
-**历史记录管理**: 完整的CRUD操作
-**搜索和筛选**: 多维度搜索和筛选
-**收藏功能**: 重要提示词收藏管理
-**评分系统**: 用户满意度评分
-**标签系统**: 自定义标签管理
-**数据导出**: 支持多种格式导出
### 2. 用户体验
-**响应式设计**: 移动端适配
-**实时搜索**: 防抖搜索优化
-**分页浏览**: 大数据量分页处理
-**统计面板**: 使用统计和趋势分析
-**批量操作**: 批量删除和收藏
### 3. 性能优化
-**数据库索引**: 关键字段索引优化
-**分页查询**: 减少数据传输量
-**缓存策略**: 模板和统计数据缓存
-**异步加载**: 前端异步数据加载
## 📊 数据统计
### 1. 用户统计
- 总生成数量
- 收藏数量
- 平均满意度评分
- 最后生成时间
### 2. 使用趋势
- 每日生成数量
- 模板使用频率
- 用户活跃度分析
## 🚀 部署说明
### 1. 数据库迁移
```sql
-- 执行SQL脚本创建表结构
-- 运行数据库迁移脚本
```
### 2. 配置更新
```python
# 在配置文件中添加历史记录相关配置
HISTORY_PAGE_SIZE = 20
HISTORY_MAX_EXPORT = 1000
```
### 3. 前端资源
- 将历史记录页面添加到路由
- 更新导航菜单
- 添加相关静态资源
## 🎉 总结
这个优化历史功能设计完整,具有以下特点:
1. **功能完整**: 涵盖历史记录的完整生命周期管理
2. **用户体验**: 现代化的界面设计和交互体验
3. **性能优化**: 多层次的性能优化策略
4. **扩展性强**: 支持功能扩展和定制
5. **集成简单**: 与现有系统无缝集成
通过这个功能,用户可以更好地管理和回顾自己的提示词生成历史,提升使用体验和工作效率。
---
*设计完成时间2025年1月*
*功能版本v1.0*
*维护人员:系统管理员*