This commit is contained in:
theliu
2026-04-26 20:05:33 +08:00
commit 5ff0c575a1
21 changed files with 2507 additions and 0 deletions
+176
View File
@@ -0,0 +1,176 @@
from flask import Flask, render_template, request, jsonify, session, redirect, url_for, send_from_directory
import os
from flask_socketio import SocketIO
from flask_cors import CORS
import sys
from config import Config
from auth import infi_login, login_required
from database import UserManager, ChatManager
from websocket_handler import WebSocketHandler
from file_handler import FileHandler
app = Flask(__name__)
app.config.from_object(Config)
CORS(app)
# 初始化SocketIO
# 在 Windows 上避免使用 eventlet 的 monkey_patch,改用 threading
use_eventlet = False
if not sys.platform.startswith('win'):
try:
import eventlet
eventlet.monkey_patch()
use_eventlet = True
except Exception:
use_eventlet = False
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet' if use_eventlet else 'threading')
# 初始化管理器
user_manager = UserManager()
chat_manager = ChatManager()
# 初始化WebSocket处理器
ws_handler = WebSocketHandler(socketio, user_manager)
@app.route('/')
@login_required
def index():
"""主页面"""
user_account = session.get('user_account')
user_info = user_manager.get_user(user_account)['user_info']
return render_template('index.html', user_info=user_info)
@app.route('/login', methods=['GET', 'POST'])
def login():
"""登录页面"""
if request.method == 'GET':
return render_template('login.html')
# POST请求处理登录
data = request.json
account = data.get('account')
password = data.get('password')
# 检查本地是否已保存用户
if user_manager.verify_user(account, password):
session['user_account'] = account
user_manager.update_user_status(account, online=True)
return jsonify({'success': True, 'message': '登录成功'})
# 使用英飞API登录
result, error = infi_login(account, password)
if error:
return jsonify({'success': False, 'message': error})
# 保存用户信息到本地
user_manager.add_user(account, password, result['token'], result['user_info'])
# 设置session
session['user_account'] = account
user_manager.update_user_status(account, online=True)
return jsonify({'success': True, 'message': '登录成功'})
@app.route('/logout')
def logout():
"""登出"""
account = session.get('user_account')
if account:
user_manager.update_user_status(account, online=False)
session.clear()
return redirect(url_for('login'))
@app.route('/api/users')
@login_required
def get_users():
"""获取用户列表"""
current_user = session.get('user_account')
users = []
for account, data in user_manager.users.items():
if account != current_user:
users.append({
'account': account,
'name': data['user_info'].get('name', '未知用户'),
'online': data.get('online', False),
'org': data['user_info'].get('orgFullList', [{}])[0].get('name', '')
})
return jsonify(users)
@app.route('/api/upload', methods=['POST'])
@login_required
def upload_file():
"""文件上传"""
if 'file' not in request.files:
return jsonify({'success': False, 'message': '没有文件'})
# 检查是否可以上传新文件
if not chat_manager.can_upload_file():
return jsonify({'success': False, 'message': '同时最多只能有5个文件存在'})
file = request.files['file']
uploader = session.get('user_account')
# 检查文件大小
file.seek(0, 2) # 移动到文件末尾
file_size = file.tell()
file.seek(0) # 重置文件指针
if file_size > Config.MAX_CONTENT_LENGTH:
return jsonify({'success': False, 'message': '文件太大,最大100MB'})
# 保存文件
file_info = FileHandler.save_file(file, uploader)
if not file_info:
return jsonify({'success': False, 'message': '不支持的文件类型'})
# 添加到活跃文件列表
chat_manager.add_file(file_info)
return jsonify({
'success': True,
'filename': file_info.get('filename', file_info.get('original_name')),
'url': file_info['url']
})
@app.route('/api/files')
@login_required
def list_files():
"""获取文件列表"""
files = []
for file_info in chat_manager.active_files:
files.append({
'filename': file_info.get('filename', file_info.get('original_name')),
'uploader': file_info['uploader'],
'upload_time': file_info['upload_time'].isoformat(),
'size': file_info['size'],
'url': file_info['url']
})
return jsonify(files)
@app.route('/favicon.ico')
def favicon():
# 从 static/favicon.ico 返回 favicon
favicon_path = os.path.join(app.root_path, 'static', 'favicon.ico')
if os.path.exists(favicon_path):
return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico')
return ('', 404)
if __name__ == '__main__':
print("Starting Web WeChat server...")
print(f"Access at: http://localhost:5000")
socketio.run(app, debug=True, host='::', port=5000)
@app.route('/favicon.ico')
def favicon():
# 从 static/favicon.ico 返回 favicon
favicon_path = os.path.join(app.root_path, 'static', 'favicon.ico')
if os.path.exists(favicon_path):
return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico')
return ('', 404)