|
|
import tkinter as tk
|
|
|
import customtkinter as ctk
|
|
|
|
|
|
class UserAuthUI:
|
|
|
def __init__(self, app):
|
|
|
self.app = app
|
|
|
self.root = app.root
|
|
|
self.auth = app.auth
|
|
|
self.login_window = None
|
|
|
self.username_entry = None
|
|
|
self.password_entry = None
|
|
|
self.login_error_label = None
|
|
|
|
|
|
def show_login_window(self):
|
|
|
"""显示登录窗口"""
|
|
|
# 隐藏主窗口
|
|
|
self.root.withdraw()
|
|
|
|
|
|
# 创建登录窗口
|
|
|
self.login_window = ctk.CTkToplevel(self.root)
|
|
|
self.login_window.title("登录 - DeepSeek AI Assistant")
|
|
|
self.login_window.geometry("400x350")
|
|
|
self.login_window.resizable(False, False)
|
|
|
self.login_window.protocol("WM_DELETE_WINDOW", self.root.destroy)
|
|
|
|
|
|
|
|
|
# 设置窗口居中
|
|
|
self.login_window.update_idletasks()
|
|
|
width = self.login_window.winfo_width()
|
|
|
height = self.login_window.winfo_height()
|
|
|
x = (self.login_window.winfo_screenwidth() // 2) - (width // 2)
|
|
|
y = (self.login_window.winfo_screenheight() // 2) - (height // 2)
|
|
|
self.login_window.geometry(f"{width}x{height}+{x}+{y}")
|
|
|
|
|
|
# 标题
|
|
|
title_label = ctk.CTkLabel(
|
|
|
self.login_window,
|
|
|
text="DeepSeek AI Assistant",
|
|
|
font=ctk.CTkFont(size=24, weight="bold")
|
|
|
)
|
|
|
title_label.pack(pady=30)
|
|
|
|
|
|
# 登录表单框架
|
|
|
form_frame = ctk.CTkFrame(self.login_window, fg_color="transparent")
|
|
|
form_frame.pack(pady=10, padx=20, fill="both", expand=True)
|
|
|
|
|
|
# 用户名
|
|
|
self.username_entry = ctk.CTkEntry(
|
|
|
form_frame,
|
|
|
placeholder_text="用户名",
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8
|
|
|
)
|
|
|
self.username_entry.pack(pady=(10, 5))
|
|
|
|
|
|
# 密码
|
|
|
self.password_entry = ctk.CTkEntry(
|
|
|
form_frame,
|
|
|
placeholder_text="密码",
|
|
|
show="*",
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8
|
|
|
)
|
|
|
self.password_entry.pack(pady=(5, 10))
|
|
|
|
|
|
# 错误提示
|
|
|
self.login_error_label = ctk.CTkLabel(
|
|
|
form_frame,
|
|
|
text="",
|
|
|
text_color="red",
|
|
|
font=ctk.CTkFont(size=12)
|
|
|
)
|
|
|
self.login_error_label.pack(pady=(5, 10))
|
|
|
|
|
|
# 登录按钮
|
|
|
login_btn = ctk.CTkButton(
|
|
|
form_frame,
|
|
|
text="登录",
|
|
|
command=self._handle_login,
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8,
|
|
|
fg_color="#0078d4",
|
|
|
hover_color="#106ebe"
|
|
|
)
|
|
|
login_btn.pack(pady=(5, 5))
|
|
|
|
|
|
# 注册按钮
|
|
|
register_btn = ctk.CTkButton(
|
|
|
form_frame,
|
|
|
text="注册新用户",
|
|
|
command=self._show_register_window,
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8,
|
|
|
fg_color="#333333",
|
|
|
hover_color="#444444"
|
|
|
)
|
|
|
register_btn.pack(pady=(5, 10))
|
|
|
|
|
|
# 绑定回车事件
|
|
|
self.username_entry.bind("<Return>", lambda e: self.password_entry.focus())
|
|
|
self.password_entry.bind("<Return>", lambda e: self._handle_login())
|
|
|
|
|
|
def _show_register_window(self):
|
|
|
"""显示注册窗口"""
|
|
|
# 隐藏登录窗口
|
|
|
self.login_window.withdraw()
|
|
|
|
|
|
# 创建注册窗口
|
|
|
register_window = ctk.CTkToplevel(self.root)
|
|
|
register_window.title("注册 - DeepSeek AI Assistant")
|
|
|
register_window.geometry("400x400")
|
|
|
register_window.resizable(False, False)
|
|
|
register_window.protocol("WM_DELETE_WINDOW", self.root.destroy)
|
|
|
|
|
|
# 设置窗口居中
|
|
|
register_window.update_idletasks()
|
|
|
width = register_window.winfo_width()
|
|
|
height = register_window.winfo_height()
|
|
|
x = (register_window.winfo_screenwidth() // 2) - (width // 2)
|
|
|
y = (register_window.winfo_screenheight() // 2) - (height // 2)
|
|
|
register_window.geometry(f"{width}x{height}+{x}+{y}")
|
|
|
|
|
|
# 标题
|
|
|
title_label = ctk.CTkLabel(
|
|
|
register_window,
|
|
|
text="创建新账户",
|
|
|
font=ctk.CTkFont(size=20, weight="bold")
|
|
|
)
|
|
|
title_label.pack(pady=20)
|
|
|
|
|
|
# 注册表单框架
|
|
|
form_frame = ctk.CTkFrame(register_window, fg_color="transparent")
|
|
|
form_frame.pack(pady=10, padx=20, fill="both", expand=True)
|
|
|
|
|
|
# 用户名
|
|
|
username_entry = ctk.CTkEntry(
|
|
|
form_frame,
|
|
|
placeholder_text="用户名",
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8
|
|
|
)
|
|
|
username_entry.pack(pady=(10, 5))
|
|
|
|
|
|
# 密码
|
|
|
password_entry = ctk.CTkEntry(
|
|
|
form_frame,
|
|
|
placeholder_text="密码(至少6位)",
|
|
|
show="*",
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8
|
|
|
)
|
|
|
password_entry.pack(pady=(5, 5))
|
|
|
|
|
|
# 确认密码
|
|
|
confirm_entry = ctk.CTkEntry(
|
|
|
form_frame,
|
|
|
placeholder_text="确认密码",
|
|
|
show="*",
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8
|
|
|
)
|
|
|
confirm_entry.pack(pady=(5, 5))
|
|
|
|
|
|
# 邮箱(可选)
|
|
|
email_entry = ctk.CTkEntry(
|
|
|
form_frame,
|
|
|
placeholder_text="邮箱(可选)",
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8
|
|
|
)
|
|
|
email_entry.pack(pady=(5, 10))
|
|
|
|
|
|
# 错误提示
|
|
|
error_label = ctk.CTkLabel(
|
|
|
form_frame,
|
|
|
text="",
|
|
|
text_color="red",
|
|
|
font=ctk.CTkFont(size=12)
|
|
|
)
|
|
|
error_label.pack(pady=(5, 10))
|
|
|
|
|
|
def _handle_register():
|
|
|
"""处理注册"""
|
|
|
username = username_entry.get().strip()
|
|
|
password = password_entry.get().strip()
|
|
|
confirm = confirm_entry.get().strip()
|
|
|
email = email_entry.get().strip()
|
|
|
|
|
|
# 验证输入
|
|
|
if not username:
|
|
|
error_label.configure(text="请输入用户名")
|
|
|
return
|
|
|
if not password:
|
|
|
error_label.configure(text="请输入密码")
|
|
|
return
|
|
|
if password != confirm:
|
|
|
error_label.configure(text="两次输入的密码不一致")
|
|
|
return
|
|
|
|
|
|
# 调用注册方法
|
|
|
success, message = self.auth.register(username, password, email)
|
|
|
if success:
|
|
|
error_label.configure(text=message, text_color="green")
|
|
|
# 3秒后关闭注册窗口,返回登录窗口
|
|
|
register_window.after(1500, lambda: [register_window.destroy(), self.login_window.deiconify()])
|
|
|
else:
|
|
|
error_label.configure(text=message)
|
|
|
|
|
|
# 注册按钮
|
|
|
register_btn = ctk.CTkButton(
|
|
|
form_frame,
|
|
|
text="注册",
|
|
|
command=_handle_register,
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8,
|
|
|
fg_color="#0078d4",
|
|
|
hover_color="#106ebe"
|
|
|
)
|
|
|
register_btn.pack(pady=(5, 5))
|
|
|
|
|
|
# 返回登录按钮
|
|
|
back_btn = ctk.CTkButton(
|
|
|
form_frame,
|
|
|
text="返回登录",
|
|
|
command=lambda: [register_window.destroy(), self.login_window.deiconify()],
|
|
|
width=300,
|
|
|
height=40,
|
|
|
corner_radius=8,
|
|
|
fg_color="#333333",
|
|
|
hover_color="#444444"
|
|
|
)
|
|
|
back_btn.pack(pady=(5, 10))
|
|
|
|
|
|
# 绑定回车事件
|
|
|
username_entry.bind("<Return>", lambda e: password_entry.focus())
|
|
|
password_entry.bind("<Return>", lambda e: confirm_entry.focus())
|
|
|
confirm_entry.bind("<Return>", lambda e: email_entry.focus())
|
|
|
email_entry.bind("<Return>", lambda e: _handle_register())
|
|
|
|
|
|
def _handle_login(self):
|
|
|
"""处理登录"""
|
|
|
username = self.username_entry.get().strip()
|
|
|
password = self.password_entry.get().strip()
|
|
|
|
|
|
# 验证输入
|
|
|
if not username:
|
|
|
self.login_error_label.configure(text="请输入用户名")
|
|
|
return
|
|
|
if not password:
|
|
|
self.login_error_label.configure(text="请输入密码")
|
|
|
return
|
|
|
|
|
|
# 调用登录方法
|
|
|
success, result = self.auth.login(username, password)
|
|
|
if success:
|
|
|
# 登录成功
|
|
|
session_id = result
|
|
|
|
|
|
# 关闭登录窗口
|
|
|
self.login_window.destroy()
|
|
|
|
|
|
# 设置用户名和session_id
|
|
|
self.app.current_username = username
|
|
|
self.app.current_session_id = session_id
|
|
|
|
|
|
# 显示主窗口并初始化UI
|
|
|
self.root.deiconify()
|
|
|
self.app.init_ui()
|
|
|
else:
|
|
|
# 登录失败
|
|
|
self.login_error_label.configure(text=result)
|