清理项目多余文件

删除以下文件:
- 8个修复脚本(fix_*.py)
- 5个app.py备份文件
- 7个templates备份文件
- 1个重复的admin.html文件

共删除21个临时文件和备份文件,保持项目整洁。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-10 15:57:39 +08:00
parent f9aa511806
commit 97d1406e11
21 changed files with 0 additions and 28781 deletions

View File

@@ -1,403 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""修复定时任务并添加执行日志功能"""
def add_schedule_logs_table(database_content):
"""在database.py中添加定时任务执行日志表"""
# 在init_database函数中添加表创建代码
insert_position = ''' print(" ✓ 创建 user_schedules 表 (用户定时任务)")'''
new_table_code = ''' print(" ✓ 创建 user_schedules 表 (用户定时任务)")
# 定时任务执行日志表
cursor.execute('''
CREATE TABLE IF NOT EXISTS schedule_execution_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
schedule_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
schedule_name TEXT,
execute_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_accounts INTEGER DEFAULT 0,
success_accounts INTEGER DEFAULT 0,
failed_accounts INTEGER DEFAULT 0,
total_items INTEGER DEFAULT 0,
total_attachments INTEGER DEFAULT 0,
total_screenshots INTEGER DEFAULT 0,
duration_seconds INTEGER DEFAULT 0,
status TEXT DEFAULT 'running',
error_message TEXT,
FOREIGN KEY (schedule_id) REFERENCES user_schedules (id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
)
''')
print(" ✓ 创建 schedule_execution_logs 表 (定时任务执行日志)")'''
if insert_position in database_content:
database_content = database_content.replace(insert_position, new_table_code)
print("✓ 已添加schedule_execution_logs表创建代码")
else:
print("❌ 未找到插入位置")
return database_content
# 添加数据库操作函数
functions_code = '''
# ==================== 定时任务执行日志 ====================
def create_schedule_execution_log(schedule_id, user_id, schedule_name):
"""创建定时任务执行日志"""
with db_pool.get_db() as conn:
cursor = conn.cursor()
cst_tz = pytz.timezone("Asia/Shanghai")
execute_time = datetime.now(cst_tz).strftime("%Y-%m-%d %H:%M:%S")
cursor.execute('''
INSERT INTO schedule_execution_logs (
schedule_id, user_id, schedule_name, execute_time, status
) VALUES (?, ?, ?, ?, 'running')
''', (schedule_id, user_id, schedule_name, execute_time))
conn.commit()
return cursor.lastrowid
def update_schedule_execution_log(log_id, **kwargs):
"""更新定时任务执行日志"""
with db_pool.get_db() as conn:
cursor = conn.cursor()
updates = []
params = []
allowed_fields = ['total_accounts', 'success_accounts', 'failed_accounts',
'total_items', 'total_attachments', 'total_screenshots',
'duration_seconds', 'status', 'error_message']
for field in allowed_fields:
if field in kwargs:
updates.append(f'{field} = ?')
params.append(kwargs[field])
if not updates:
return False
params.append(log_id)
sql = f"UPDATE schedule_execution_logs SET {', '.join(updates)} WHERE id = ?"
cursor.execute(sql, params)
conn.commit()
return cursor.rowcount > 0
def get_schedule_execution_logs(schedule_id, limit=10):
"""获取定时任务执行日志"""
with db_pool.get_db() as conn:
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM schedule_execution_logs
WHERE schedule_id = ?
ORDER BY execute_time DESC
LIMIT ?
''', (schedule_id, limit))
return [dict(row) for row in cursor.fetchall()]
def get_user_all_schedule_logs(user_id, limit=50):
"""获取用户所有定时任务的执行日志"""
with db_pool.get_db() as conn:
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM schedule_execution_logs
WHERE user_id = ?
ORDER BY execute_time DESC
LIMIT ?
''', (user_id, limit))
return [dict(row) for row in cursor.fetchall()]
'''
# 在文件末尾添加这些函数
database_content += functions_code
print("✓ 已添加定时任务日志操作函数")
return database_content
def add_schedule_log_tracking(app_content):
"""在app.py中添加定时任务执行日志记录"""
# 修改check_user_schedules函数添加日志记录
old_code = ''' print(f"[用户定时任务] 用户 {schedule_config.get('user_username', user_id)} 的任务 '{schedule_config.get('name', '')}' 开始执行")
started_count = 0
for account_id in account_ids:'''
new_code = ''' print(f"[用户定时任务] 用户 {schedule_config.get('user_username', user_id)} 的任务 '{schedule_config.get('name', '')}' 开始执行")
# 创建执行日志
import time as time_mod
execution_start_time = time_mod.time()
log_id = database.create_schedule_execution_log(
schedule_id=schedule_id,
user_id=user_id,
schedule_name=schedule_config.get('name', '未命名任务')
)
started_count = 0
for account_id in account_ids:'''
if old_code in app_content:
app_content = app_content.replace(old_code, new_code)
print("✓ 已添加执行日志创建代码")
else:
print("⚠ 未找到执行日志创建位置")
# 添加日志更新代码(在任务执行完成后)
old_code2 = ''' # 更新最后执行时间
database.update_schedule_last_run(schedule_id)
print(f"[用户定时任务] 已启动 {started_count} 个账号")'''
new_code2 = ''' # 更新最后执行时间
database.update_schedule_last_run(schedule_id)
# 更新执行日志
execution_duration = int(time_mod.time() - execution_start_time)
database.update_schedule_execution_log(
log_id,
total_accounts=len(account_ids),
success_accounts=started_count,
failed_accounts=len(account_ids) - started_count,
duration_seconds=execution_duration,
status='completed'
)
print(f"[用户定时任务] 已启动 {started_count} 个账号")'''
if old_code2 in app_content:
app_content = app_content.replace(old_code2, new_code2)
print("✓ 已添加执行日志更新代码")
else:
print("⚠ 未找到执行日志更新位置")
# 添加日志查询API
api_code = '''
# ==================== 定时任务执行日志API ====================
@app.route('/api/schedules/<int:schedule_id>/logs', methods=['GET'])
@login_required
def get_schedule_logs_api(schedule_id):
"""获取定时任务执行日志"""
schedule = database.get_schedule_by_id(schedule_id)
if not schedule:
return jsonify({"error": "定时任务不存在"}), 404
if schedule['user_id'] != current_user.id:
return jsonify({"error": "无权访问"}), 403
limit = request.args.get('limit', 10, type=int)
logs = database.get_schedule_execution_logs(schedule_id, limit)
return jsonify(logs)
'''
# 在批量操作API之前插入
insert_marker = '# ==================== 批量操作API ===================='
if insert_marker in app_content:
app_content = app_content.replace(insert_marker, api_code + insert_marker)
print("✓ 已添加日志查询API")
else:
print("⚠ 未找到API插入位置")
return app_content
def add_frontend_log_button(html_content):
"""在前端添加日志按钮"""
# 修改定时任务卡片,添加日志按钮
old_html = ''' '<button class="btn btn-text btn-small" onclick="editSchedule(' + s.id + ')">编辑</button>' +
'<button class="btn btn-text btn-small" style="color: var(--md-error);" onclick="deleteSchedule(' + s.id + ')">删除</button>' +'''
new_html = ''' '<button class="btn btn-text btn-small" onclick="editSchedule(' + s.id + ')">编辑</button>' +
'<button class="btn btn-text btn-small" onclick="viewScheduleLogs(' + s.id + ')">日志</button>' +
'<button class="btn btn-text btn-small" style="color: var(--md-error);" onclick="deleteSchedule(' + s.id + ')">删除</button>' +'''
if old_html in html_content:
html_content = html_content.replace(old_html, new_html)
print("✓ 已添加日志按钮HTML")
else:
print("⚠ 未找到日志按钮插入位置")
# 添加日志弹窗HTML
modal_html = ''' <!-- 定时任务执行日志弹窗 -->
<div class="modal-overlay" id="scheduleLogsModal">
<div class="modal" style="max-width: 800px;">
<div class="modal-header"><h3 class="modal-title" id="scheduleLogsTitle">执行日志</h3></div>
<div class="modal-body">
<div id="scheduleLogsList" style="max-height: 500px; overflow-y: auto;"></div>
<div id="emptyScheduleLogs" class="empty-state" style="display: none;">
<div class="empty-state-icon">📝</div>
<p>暂无执行记录</p>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-text" onclick="closeModal('scheduleLogsModal')">关闭</button>
</div>
</div>
</div>
<script>'''
insert_marker = ' <script>'
if insert_marker in html_content:
html_content = html_content.replace(insert_marker, modal_html, 1)
print("✓ 已添加日志弹窗HTML")
else:
print("⚠ 未找到弹窗插入位置")
# 添加JavaScript函数
js_code = '''
// ==================== 定时任务执行日志 ====================
function viewScheduleLogs(scheduleId) {
const schedule = schedules.find(s => s.id === scheduleId);
if (!schedule) {
showToast('定时任务不存在', 'error');
return;
}
document.getElementById('scheduleLogsTitle').textContent = schedule.name + ' - 执行日志';
loadScheduleLogs(scheduleId);
openModal('scheduleLogsModal');
}
function loadScheduleLogs(scheduleId) {
fetch('/api/schedules/' + scheduleId + '/logs?limit=20')
.then(r => r.json())
.then(logs => {
const container = document.getElementById('scheduleLogsList');
const empty = document.getElementById('emptyScheduleLogs');
if (!logs || logs.length === 0) {
container.innerHTML = '';
empty.style.display = 'block';
return;
}
empty.style.display = 'none';
let html = '<div style="display: grid; gap: 12px;">';
logs.forEach(log => {
const statusColor = log.status === 'completed' ? '#4CAF50' :
log.status === 'failed' ? '#F44336' : '#FF9800';
const statusText = log.status === 'completed' ? '已完成' :
log.status === 'failed' ? '失败' : '运行中';
html += '<div style="background: #f5f5f5; border-radius: 8px; padding: 16px; border-left: 4px solid ' + statusColor + ';">';
html += '<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">';
html += '<div style="font-weight: 500; font-size: 14px;">' + log.execute_time + '</div>';
html += '<div style="color: ' + statusColor + '; font-weight: 600; font-size: 13px;">' + statusText + '</div>';
html += '</div>';
html += '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; font-size: 13px;">';
html += '<div><span style="color: #666;">账号数:</span> <strong>' + (log.total_accounts || 0) + '</strong></div>';
html += '<div><span style="color: #666;">成功:</span> <strong style="color: #4CAF50;">' + (log.success_accounts || 0) + '</strong></div>';
html += '<div><span style="color: #666;">失败:</span> <strong style="color: #F44336;">' + (log.failed_accounts || 0) + '</strong></div>';
html += '<div><span style="color: #666;">浏览内容:</span> <strong>' + (log.total_items || 0) + '</strong></div>';
html += '<div><span style="color: #666;">查看附件:</span> <strong>' + (log.total_attachments || 0) + '</strong></div>';
html += '<div><span style="color: #666;">截图数:</span> <strong>' + (log.total_screenshots || 0) + '</strong></div>';
if (log.duration_seconds) {
const mins = Math.floor(log.duration_seconds / 60);
const secs = log.duration_seconds % 60;
html += '<div><span style="color: #666;">耗时:</span> <strong>' + mins + '' + secs + '秒</strong></div>';
}
html += '</div>';
if (log.error_message) {
html += '<div style="margin-top: 8px; padding: 8px; background: #FFEBEE; border-radius: 4px; color: #C62828; font-size: 12px;">';
html += '<strong>错误:</strong> ' + escapeHtml(log.error_message);
html += '</div>';
}
html += '</div>';
});
html += '</div>';
container.innerHTML = html;
})
.catch(err => {
showToast('加载日志失败', 'error');
console.error(err);
});
}
'''
# 在logout函数之前插入
insert_marker2 = ' function logout() {'
if insert_marker2 in html_content:
html_content = html_content.replace(insert_marker2, js_code + insert_marker2)
print("✓ 已添加日志查看JavaScript函数")
else:
print("⚠ 未找到JavaScript插入位置")
return html_content
def main():
import sys
print("=" * 60)
print("定时任务修复和日志功能添加脚本")
print("=" * 60)
print()
# 读取database.py
print("[1/3] 修改 database.py...")
with open('database.py', 'r', encoding='utf-8') as f:
database_content = f.read()
database_content = add_schedule_logs_table(database_content)
with open('database.py', 'w', encoding='utf-8') as f:
f.write(database_content)
print()
# 读取app.py
print("[2/3] 修改 app.py...")
with open('app.py', 'r', encoding='utf-8') as f:
app_content = f.read()
app_content = add_schedule_log_tracking(app_content)
with open('app.py', 'w', encoding='utf-8') as f:
f.write(app_content)
print()
# 读取templates/index.html
print("[3/3] 修改 templates/index.html...")
with open('templates/index.html', 'r', encoding='utf-8') as f:
html_content = f.read()
html_content = add_frontend_log_button(html_content)
with open('templates/index.html', 'w', encoding='utf-8') as f:
f.write(html_content)
print()
print("=" * 60)
print("✅ 所有修改完成!")
print("=" * 60)
print()
print("下一步操作:")
print("1. 重启Docker容器: docker-compose restart")
print("2. 检查定时任务是否启用: enabled = 1")
print("3. 测试定时任务执行")
print()
if __name__ == '__main__':
main()