修复所有bug并添加新功能

- 修复添加账号按钮无反应问题
- 添加账号备注字段(可选)
- 添加账号设置按钮(修改密码/备注)
- 修复用户反馈���能
- 添加定时任务执行日志
- 修复容器重启后账号加载问题
- 修复所有JavaScript语法错误
- 优化账号加载机制(4层保障)

🤖 Generated with Claude Code
This commit is contained in:
Yu Yon
2025-12-10 11:19:16 +08:00
parent 0fd7137cea
commit b5344cd55e
67 changed files with 38235 additions and 3271 deletions

166
fix_screenshot.py Normal file
View File

@@ -0,0 +1,166 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
NEW_FUNC = '''def take_screenshot_for_account(user_id, account_id, browse_type="应读", source="manual", task_start_time=None, browse_result=None):
"""为账号任务完成后截图(使用独立进程避免eventlet冲突)"""
import subprocess
import json
import uuid
if user_id not in user_accounts or account_id not in user_accounts[user_id]:
return
account = user_accounts[user_id][account_id]
# 使用截图信号量控制并发
semaphore, max_concurrent = get_screenshot_semaphore()
screenshot_acquired = semaphore.acquire(blocking=True, timeout=300)
if not screenshot_acquired:
log_to_client(f"截图资源获取超时,跳过截图", user_id, account_id)
if account_id in task_status:
del task_status[account_id]
return
max_retries = 2
screenshot_success = False
for attempt in range(1, max_retries + 1):
try:
if account_id in task_status:
task_status[account_id]["detail_status"] = f"正在截图{f' (第{attempt}次)' if attempt > 1 else ''}"
if attempt > 1:
log_to_client(f"🔄 第 {attempt} 次截图尝试...", user_id, account_id)
beijing_tz = pytz.timezone('Asia/Shanghai')
now_beijing = datetime.now(beijing_tz)
timestamp = now_beijing.strftime('%Y%m%d_%H%M%S')
user_info = database.get_user_by_id(user_id)
username_prefix = user_info['username'] if user_info else f"user{user_id}"
login_account = account.username
actual_browse_type = account.last_browse_type or browse_type
screenshot_filename = f"{username_prefix}_{login_account}_{actual_browse_type}_{timestamp}.jpg"
screenshot_path = os.path.join(SCREENSHOTS_DIR, screenshot_filename)
config = {
'username': account.username,
'password': account.password,
'remember': account.remember if hasattr(account, 'remember') else '',
'browse_type': actual_browse_type,
'screenshot_path': screenshot_path,
'proxy_config': account.proxy_config if hasattr(account, 'proxy_config') else None
}
config_file = f"/tmp/screenshot_config_{uuid.uuid4().hex}.json"
with open(config_file, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False)
log_to_client(f"启动截图进程...", user_id, account_id)
try:
result = subprocess.run(
['python3', '/www/wwwroot/zsglpt/screenshot_worker.py', config_file],
capture_output=True,
text=True,
timeout=120
)
output = result.stdout
if "===RESULT===" in output:
result_json = output.split("===RESULT===")[1].strip()
result_data = json.loads(result_json)
if result_data.get('success'):
log_to_client(f"✓ 截图成功: {screenshot_filename}", user_id, account_id)
screenshot_success = True
break
else:
log_to_client(f"截图失败: {result_data.get('message', '未知错误')}", user_id, account_id)
else:
err_msg = result.stderr[:200] if result.stderr else '无输出'
log_to_client(f"截图进程异常: {err_msg}", user_id, account_id)
except subprocess.TimeoutExpired:
log_to_client(f"截图超时", user_id, account_id)
except Exception as e:
log_to_client(f"截图进程错误: {str(e)}", user_id, account_id)
try:
if os.path.exists(config_file):
os.remove(config_file)
except:
pass
if attempt < max_retries:
log_to_client(f"将重试...", user_id, account_id)
time.sleep(2)
except Exception as e:
log_to_client(f"截图出错: {str(e)}", user_id, account_id)
if attempt < max_retries:
log_to_client(f"将重试...", user_id, account_id)
time.sleep(2)
if not screenshot_success:
log_to_client(f"❌ 截图失败: 已重试{max_retries}", user_id, account_id)
account.status = "未开始"
socketio.emit('account_update', account.to_dict(), room=f'user_{user_id}')
semaphore.release()
if account_id in task_status:
del task_status[account_id]
if task_start_time and browse_result:
import time as time_module
total_duration = int(time_module.time() - task_start_time)
database.create_task_log(
user_id=user_id,
account_id=account_id,
username=account.username if account else "",
browse_type=actual_browse_type,
status='success',
total_items=browse_result.get('total_items', 0),
total_attachments=browse_result.get('total_attachments', 0),
error_message='' if screenshot_success else '截图失败',
duration=total_duration,
source=source
)
log_to_client(f"任务完成!总耗时 {total_duration}", user_id, account_id)
'''
def main():
with open('/www/wwwroot/zsglpt/app.py', 'r', encoding='utf-8') as f:
content = f.read()
lines = content.split('\n')
start_idx = None
end_idx = None
for i, line in enumerate(lines):
if line.startswith('def take_screenshot_for_account('):
start_idx = i
elif start_idx is not None and line.startswith('def ') and i > start_idx:
end_idx = i
break
if start_idx is None:
print("未找到函数")
return
if end_idx is None:
end_idx = len(lines)
new_lines = lines[:start_idx] + NEW_FUNC.split('\n') + [''] + lines[end_idx:]
with open('/www/wwwroot/zsglpt/app.py', 'w', encoding='utf-8') as f:
f.write('\n'.join(new_lines))
print(f"已替换函数 (行 {start_idx+1}{end_idx})")
if __name__ == '__main__':
main()