Files
dialect-chat/admin/app.py
hubian 3aab712ff0 新增后台管理系统
功能模块:
- 仪表盘: 用户统计、对话统计、方言使用分布
- 用户管理: 查看、搜索、删除用户
- 对话管理: 查看、删除对话、消息内容预览
- 数据导出: 导出用户数据

技术栈:
- Flask + Tailwind CSS
- RESTful API
- 数据可视化
2026-04-08 12:16:21 +08:00

250 lines
7.0 KiB
Python

"""
方言版AI对话助手 - 后台管理系统
"""
from flask import Flask, render_template, jsonify, request, send_file
from flask_cors import CORS
import json
from pathlib import Path
from datetime import datetime
app = Flask(__name__)
CORS(app)
# 数据目录
DATA_DIR = Path(__file__).parent.parent / 'data'
USERS_FILE = DATA_DIR / 'users.json'
CHATS_FILE = DATA_DIR / 'chats.json'
def load_users():
if USERS_FILE.exists():
return json.loads(USERS_FILE.read_text(encoding='utf-8'))
return {}
def load_chats():
if CHATS_FILE.exists():
return json.loads(CHATS_FILE.read_text(encoding='utf-8'))
return {}
# ============ 页面路由 ============
@app.route('/')
def index():
return render_template('index.html')
@app.route('/users')
def users_page():
return render_template('users.html')
@app.route('/chats')
def chats_page():
return render_template('chats.html')
# ============ API路由 ============
@app.route('/api/stats')
def api_stats():
users = load_users()
chats = load_chats()
# 统计消息数
total_messages = 0
for chat in chats.values():
total_messages += len(chat.get('messages', []))
# 今日新增用户
today = datetime.now().strftime('%Y-%m-%d')
today_users = sum(1 for u in users.values() if u.get('created_at', '').startswith(today))
# 今日活跃对话
today_chats = sum(1 for c in chats.values() if c.get('updated_at', '').startswith(today))
return jsonify({
'users_count': len(users),
'chats_count': len(chats),
'messages_count': total_messages,
'today_users': today_users,
'today_chats': today_chats,
})
@app.route('/api/users')
def api_users():
users = load_users()
user_list = []
for uid, user in users.items():
user_list.append({
'id': uid,
'username': user.get('username', ''),
'phone': user.get('phone', ''),
'email': user.get('email', ''),
'chats_count': len(user.get('chats', [])),
'created_at': user.get('created_at', ''),
})
# 按创建时间倒序
user_list.sort(key=lambda x: x['created_at'], reverse=True)
return jsonify(user_list)
@app.route('/api/users/<user_id>')
def api_user_detail(user_id):
users = load_users()
chats = load_chats()
user = users.get(user_id)
if not user:
return jsonify({'error': '用户不存在'}), 404
# 获取用户的对话列表
user_chats = []
for chat_id in user.get('chats', []):
if chat_id in chats:
chat = chats[chat_id]
user_chats.append({
'id': chat_id,
'title': chat.get('title', ''),
'dialect': chat.get('dialect', ''),
'messages_count': len(chat.get('messages', [])),
'created_at': chat.get('created_at', ''),
})
return jsonify({
'user': {
'id': user_id,
'username': user.get('username', ''),
'phone': user.get('phone', ''),
'email': user.get('email', ''),
'created_at': user.get('created_at', ''),
},
'chats': user_chats
})
@app.route('/api/users/<user_id>', methods=['DELETE'])
def api_delete_user(user_id):
users = load_users()
chats = load_chats()
if user_id not in users:
return jsonify({'error': '用户不存在'}), 404
# 删除用户的所有对话
for chat_id in users[user_id].get('chats', []):
if chat_id in chats:
del chats[chat_id]
# 删除用户
del users[user_id]
USERS_FILE.write_text(json.dumps(users, ensure_ascii=False, indent=2), encoding='utf-8')
CHATS_FILE.write_text(json.dumps(chats, ensure_ascii=False, indent=2), encoding='utf-8')
return jsonify({'success': True})
@app.route('/api/chats')
def api_chats():
chats = load_chats()
users = load_users()
chat_list = []
for cid, chat in chats.items():
user = users.get(chat.get('user_id', ''), {})
chat_list.append({
'id': cid,
'title': chat.get('title', ''),
'dialect': chat.get('dialect', ''),
'user_name': user.get('username', '未知'),
'messages_count': len(chat.get('messages', [])),
'created_at': chat.get('created_at', ''),
'updated_at': chat.get('updated_at', ''),
})
# 按更新时间倒序
chat_list.sort(key=lambda x: x['updated_at'], reverse=True)
return jsonify(chat_list)
@app.route('/api/chats/<chat_id>')
def api_chat_detail(chat_id):
chats = load_chats()
users = load_users()
chat = chats.get(chat_id)
if not chat:
return jsonify({'error': '对话不存在'}), 404
user = users.get(chat.get('user_id', ''), {})
return jsonify({
'id': chat_id,
'title': chat.get('title', ''),
'dialect': chat.get('dialect', ''),
'user': {
'id': chat.get('user_id', ''),
'username': user.get('username', '未知'),
},
'messages': chat.get('messages', []),
'created_at': chat.get('created_at', ''),
'updated_at': chat.get('updated_at', ''),
})
@app.route('/api/chats/<chat_id>', methods=['DELETE'])
def api_delete_chat(chat_id):
chats = load_chats()
users = load_users()
if chat_id not in chats:
return jsonify({'error': '对话不存在'}), 404
user_id = chats[chat_id].get('user_id')
# 删除对话
del chats[chat_id]
# 从用户列表中移除
if user_id and user_id in users:
if chat_id in users[user_id].get('chats', []):
users[user_id]['chats'].remove(chat_id)
CHATS_FILE.write_text(json.dumps(chats, ensure_ascii=False, indent=2), encoding='utf-8')
USERS_FILE.write_text(json.dumps(users, ensure_ascii=False, indent=2), encoding='utf-8')
return jsonify({'success': True})
@app.route('/api/dialect-stats')
def api_dialect_stats():
"""方言使用统计"""
chats = load_chats()
dialect_counts = {}
for chat in chats.values():
dialect = chat.get('dialect', 'mandarin')
dialect_counts[dialect] = dialect_counts.get(dialect, 0) + 1
return jsonify(dialect_counts)
@app.route('/api/export/users')
def api_export_users():
"""导出用户数据"""
users = load_users()
# 隐藏密码
export_data = []
for uid, user in users.items():
export_data.append({
'id': uid,
'username': user.get('username', ''),
'phone': user.get('phone', ''),
'email': user.get('email', ''),
'created_at': user.get('created_at', ''),
'chats_count': len(user.get('chats', [])),
})
return jsonify(export_data)
if __name__ == '__main__':
print("=" * 50)
print("方言AI助手 - 后台管理系统")
print("=" * 50)
print(f"访问地址: http://localhost:19003")
print("=" * 50)
app.run(host='0.0.0.0', port=19003, debug=True)