You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
410 lines
16 KiB
410 lines
16 KiB
import tkinter as tk
|
|
import customtkinter as ctk
|
|
from config.config import config_manager
|
|
|
|
class SettingsComponent:
|
|
"""设置界面组件"""
|
|
def __init__(self, parent_frame, app, api):
|
|
self.parent_frame = parent_frame
|
|
self.app = app
|
|
self.api = api
|
|
self.settings_frame = None
|
|
self.scrollable_frame = None
|
|
|
|
def _create_settings_interface(self):
|
|
"""创建设置界面"""
|
|
if self.settings_frame is None:
|
|
self.settings_frame = ctk.CTkFrame(self.parent_frame, fg_color="#1e1e1e")
|
|
|
|
# 创建滑动条
|
|
self.scrollable_frame = ctk.CTkScrollableFrame(self.settings_frame, fg_color="#1e1e1e")
|
|
self.scrollable_frame.pack(fill="both", expand=True, padx=20, pady=20)
|
|
|
|
# 设置标题
|
|
settings_title = ctk.CTkLabel(
|
|
self.scrollable_frame,
|
|
text="系统设置",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=24, weight="bold"),
|
|
text_color="#ffffff"
|
|
)
|
|
settings_title.pack(pady=20)
|
|
|
|
# 账户信息部分
|
|
account_frame = ctk.CTkFrame(self.scrollable_frame, fg_color="#252525", corner_radius=10)
|
|
account_frame.pack(fill="x", padx=20, pady=10)
|
|
|
|
account_title = ctk.CTkLabel(
|
|
account_frame,
|
|
text="账户信息",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=18, weight="bold"),
|
|
text_color="#ffffff"
|
|
)
|
|
account_title.pack(pady=10, padx=20, anchor="w")
|
|
|
|
# 用户名
|
|
username_label = ctk.CTkLabel(
|
|
account_frame,
|
|
text="用户名:",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#cccccc"
|
|
)
|
|
username_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
username_value = ctk.CTkLabel(
|
|
account_frame,
|
|
text=self.app.current_username if self.app.current_username else "未登录",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#ffffff"
|
|
)
|
|
username_value.pack(pady=(0, 10), padx=20, anchor="w")
|
|
|
|
# 会话ID
|
|
session_id_label = ctk.CTkLabel(
|
|
account_frame,
|
|
text="会话ID:",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
session_id_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
session_id_value = ctk.CTkLabel(
|
|
account_frame,
|
|
text=self.app.current_session_id if self.app.current_session_id else "无",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#ffffff"
|
|
)
|
|
session_id_value.pack(pady=(0, 10), padx=20, anchor="w")
|
|
|
|
# 模型设置部分
|
|
model_frame = ctk.CTkFrame(self.scrollable_frame, fg_color="#252525", corner_radius=10)
|
|
model_frame.pack(fill="x", padx=20, pady=10)
|
|
|
|
model_title = ctk.CTkLabel(
|
|
model_frame,
|
|
text="模型设置",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=18, weight="bold"),
|
|
text_color="#ffffff"
|
|
)
|
|
model_title.pack(pady=10, padx=20, anchor="w")
|
|
|
|
# 模型选择
|
|
model_label = ctk.CTkLabel(
|
|
model_frame,
|
|
text="当前模型:",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
model_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
self.model_var = tk.StringVar(value=self.api.model)
|
|
self.model_combo = ctk.CTkComboBox(
|
|
model_frame,
|
|
variable=self.model_var,
|
|
values=["deepseek-chat", "deepseek-coder"],
|
|
width=200,
|
|
corner_radius=8,
|
|
fg_color="#333333",
|
|
button_color="#444444",
|
|
button_hover_color="#555555"
|
|
)
|
|
self.model_combo.pack(pady=(0, 10), padx=20, anchor="w")
|
|
|
|
# 回复随机性 (Temperature)
|
|
temperature_label = ctk.CTkLabel(
|
|
model_frame,
|
|
text=f"回复随机性: {config_manager.get_temperature():.2f}",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
temperature_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
self.temperature_slider = ctk.CTkSlider(
|
|
model_frame,
|
|
from_=0.0,
|
|
to=1.0,
|
|
number_of_steps=100,
|
|
command=lambda value: temperature_label.configure(text=f"回复随机性: {value:.2f}"),
|
|
width=200,
|
|
fg_color="#333333",
|
|
progress_color="#0078d4"
|
|
)
|
|
self.temperature_slider.set(config_manager.get_temperature())
|
|
self.temperature_slider.pack(pady=(0, 15), padx=20, anchor="w")
|
|
|
|
# 最大回复长度 (Max Tokens)
|
|
max_tokens_label = ctk.CTkLabel(
|
|
model_frame,
|
|
text=f"最大回复长度: {config_manager.get_max_tokens()}",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
max_tokens_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
self.max_tokens_slider = ctk.CTkSlider(
|
|
model_frame,
|
|
from_=128,
|
|
to=2048,
|
|
number_of_steps=7,
|
|
command=lambda value: max_tokens_label.configure(text=f"最大回复长度: {int(value)}"),
|
|
width=200,
|
|
fg_color="#333333",
|
|
progress_color="#0078d4"
|
|
)
|
|
self.max_tokens_slider.set(config_manager.get_max_tokens())
|
|
self.max_tokens_slider.pack(pady=(0, 15), padx=20, anchor="w")
|
|
|
|
# API设置部分
|
|
api_frame = ctk.CTkFrame(self.scrollable_frame, fg_color="#252525", corner_radius=10)
|
|
api_frame.pack(fill="x", padx=20, pady=10)
|
|
|
|
api_title = ctk.CTkLabel(
|
|
api_frame,
|
|
text="API设置",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=18, weight="bold"),
|
|
text_color="#ffffff"
|
|
)
|
|
api_title.pack(pady=10, padx=20, anchor="w")
|
|
|
|
# API类型选择
|
|
api_type_frame = ctk.CTkFrame(api_frame, fg_color="transparent")
|
|
api_type_frame.pack(pady=(0, 15), padx=20, anchor="w")
|
|
|
|
self.api_type_var = tk.StringVar(value="default")
|
|
|
|
default_api_radio = ctk.CTkRadioButton(
|
|
api_type_frame,
|
|
text="默认API",
|
|
variable=self.api_type_var,
|
|
value="default",
|
|
command=self._toggle_api_type,
|
|
text_color="#ffffff",
|
|
fg_color="#0078d4"
|
|
)
|
|
default_api_radio.pack(side="left", padx=10)
|
|
|
|
custom_api_radio = ctk.CTkRadioButton(
|
|
api_type_frame,
|
|
text="自定义API",
|
|
variable=self.api_type_var,
|
|
value="custom",
|
|
command=self._toggle_api_type,
|
|
text_color="#ffffff",
|
|
fg_color="#0078d4"
|
|
)
|
|
custom_api_radio.pack(side="left", padx=10)
|
|
|
|
# API URL
|
|
self.api_url_label = ctk.CTkLabel(
|
|
api_frame,
|
|
text="API URL:",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
self.api_url_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
self.api_url_entry = ctk.CTkEntry(
|
|
api_frame,
|
|
placeholder_text="请输入API URL",
|
|
width=300,
|
|
height=40,
|
|
corner_radius=8,
|
|
fg_color="#333333",
|
|
text_color="#ffffff",
|
|
placeholder_text_color="#aaaaaa",
|
|
state="disabled"
|
|
)
|
|
self.api_url_entry.pack(pady=(0, 10), padx=20, anchor="w")
|
|
|
|
# API密钥
|
|
self.api_key_label = ctk.CTkLabel(
|
|
api_frame,
|
|
text="API密钥:",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
self.api_key_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
self.api_key_entry = ctk.CTkEntry(
|
|
api_frame,
|
|
placeholder_text="请输入API密钥",
|
|
width=300,
|
|
height=40,
|
|
corner_radius=8,
|
|
fg_color="#333333",
|
|
text_color="#ffffff",
|
|
placeholder_text_color="#aaaaaa",
|
|
state="disabled"
|
|
)
|
|
self.api_key_entry.pack(pady=(0, 15), padx=20, anchor="w")
|
|
|
|
# AI提示设置部分
|
|
ai_prompt_frame = ctk.CTkFrame(self.scrollable_frame, fg_color="#252525", corner_radius=10)
|
|
ai_prompt_frame.pack(fill="x", padx=20, pady=10)
|
|
|
|
ai_prompt_title = ctk.CTkLabel(
|
|
ai_prompt_frame,
|
|
text="AI提示设置",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=18, weight="bold"),
|
|
text_color="#ffffff"
|
|
)
|
|
ai_prompt_title.pack(pady=10, padx=20, anchor="w")
|
|
|
|
# 日程助手提示
|
|
schedule_prompt_label = ctk.CTkLabel(
|
|
ai_prompt_frame,
|
|
text="日程助手系统提示:",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
schedule_prompt_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
self.schedule_prompt_textbox = ctk.CTkTextbox(
|
|
ai_prompt_frame,
|
|
height=100,
|
|
width=500,
|
|
corner_radius=8,
|
|
fg_color="#333333",
|
|
text_color="#ffffff"
|
|
)
|
|
self.schedule_prompt_textbox.pack(pady=(0, 15), padx=20, anchor="w")
|
|
self.schedule_prompt_textbox.insert("1.0", config_manager.get_schedule_assistant_prompt())
|
|
|
|
# 待办助手提示
|
|
todo_prompt_label = ctk.CTkLabel(
|
|
ai_prompt_frame,
|
|
text="待办助手系统提示:",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#aaaaaa"
|
|
)
|
|
todo_prompt_label.pack(pady=(0, 5), padx=20, anchor="w")
|
|
|
|
self.todo_prompt_textbox = ctk.CTkTextbox(
|
|
ai_prompt_frame,
|
|
height=100,
|
|
width=500,
|
|
corner_radius=8,
|
|
fg_color="#333333",
|
|
text_color="#ffffff"
|
|
)
|
|
self.todo_prompt_textbox.pack(pady=(0, 15), padx=20, anchor="w")
|
|
self.todo_prompt_textbox.insert("1.0", config_manager.get_todo_assistant_prompt())
|
|
|
|
# 日志设置部分
|
|
logs_frame = ctk.CTkFrame(self.scrollable_frame, fg_color="#252525", corner_radius=10)
|
|
logs_frame.pack(fill="x", padx=20, pady=10)
|
|
|
|
logs_title = ctk.CTkLabel(
|
|
logs_frame,
|
|
text="系统日志",
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=18, weight="bold"),
|
|
text_color="#ffffff"
|
|
)
|
|
logs_title.pack(pady=10, padx=20, anchor="w")
|
|
|
|
# 查看日志按钮
|
|
view_logs_btn = ctk.CTkButton(
|
|
logs_frame,
|
|
text="查看日志",
|
|
command=self.app._show_logs,
|
|
width=150,
|
|
height=40,
|
|
corner_radius=8,
|
|
fg_color="#005a9e",
|
|
hover_color="#004a80"
|
|
)
|
|
view_logs_btn.pack(pady=10, padx=20, anchor="w")
|
|
|
|
# 保存设置按钮(移到最底部)
|
|
save_btn = ctk.CTkButton(
|
|
self.scrollable_frame,
|
|
text="保存设置",
|
|
command=self._save_settings,
|
|
width=200,
|
|
height=40,
|
|
corner_radius=8,
|
|
fg_color="#005a9e",
|
|
hover_color="#004a80"
|
|
)
|
|
save_btn.pack(pady=30, padx=20, anchor="center")
|
|
|
|
def _toggle_api_type(self):
|
|
"""切换API类型"""
|
|
api_type = self.api_type_var.get()
|
|
if api_type == "default":
|
|
self.api_url_entry.configure(state="disabled")
|
|
self.api_key_entry.configure(state="disabled")
|
|
else:
|
|
self.api_url_entry.configure(state="normal")
|
|
self.api_key_entry.configure(state="normal")
|
|
|
|
def _save_settings(self):
|
|
"""保存设置"""
|
|
# 获取当前设置
|
|
selected_model = self.model_var.get()
|
|
api_type = self.api_type_var.get()
|
|
api_url = self.api_url_entry.get() if api_type == "custom" else ""
|
|
api_key = self.api_key_entry.get() if api_type == "custom" else ""
|
|
temperature = self.temperature_slider.get()
|
|
max_tokens = int(self.max_tokens_slider.get())
|
|
|
|
# 获取AI提示设置
|
|
schedule_prompt = self.schedule_prompt_textbox.get("1.0", "end-1c")
|
|
todo_prompt = self.todo_prompt_textbox.get("1.0", "end-1c")
|
|
|
|
# 更新API模型
|
|
self.api.model = selected_model
|
|
config_manager.set_default_model(selected_model)
|
|
|
|
# 更新温度和最大回复长度
|
|
config_manager.set_temperature(temperature)
|
|
config_manager.set_max_tokens(max_tokens)
|
|
|
|
# 更新AI提示设置
|
|
config_manager.set_schedule_assistant_prompt(schedule_prompt)
|
|
config_manager.set_todo_assistant_prompt(todo_prompt)
|
|
|
|
# 更新API设置
|
|
if api_type == "custom":
|
|
if api_url and api_key:
|
|
# 这里可以添加实际的API设置更新逻辑
|
|
self.api.api_url = api_url
|
|
self.api.api_key = api_key
|
|
config_manager.set_api_url(api_url)
|
|
config_manager.set_api_key(api_key)
|
|
print(f"更新API设置: URL={api_url}, Key={api_key}")
|
|
success_msg = "所有设置已保存"
|
|
else:
|
|
success_msg = "自定义API需要填写完整的URL和密钥"
|
|
else:
|
|
# 恢复默认API设置
|
|
self.api.api_url = ""
|
|
self.api.api_key = ""
|
|
config_manager.set_api_url("https://api.deepseek.com/v1/chat/completions")
|
|
success_msg = "所有设置已保存"
|
|
|
|
# 显示保存成功提示
|
|
self.save_success_label = ctk.CTkLabel(
|
|
self.scrollable_frame,
|
|
text=success_msg,
|
|
font=ctk.CTkFont(family="Microsoft YaHei UI", size=14),
|
|
text_color="#34a853"
|
|
)
|
|
self.save_success_label.pack(pady=(0, 10))
|
|
|
|
# 3秒后自动移除提示
|
|
self.settings_frame.after(3000, self.save_success_label.destroy)
|
|
|
|
def get_settings_frame(self):
|
|
"""获取设置帧"""
|
|
return self.settings_frame
|
|
|
|
def show(self):
|
|
"""显示设置界面"""
|
|
self._create_settings_interface()
|
|
self.settings_frame.pack(side="right", fill="both", expand=True, padx=(0, 5))
|
|
|
|
def hide(self):
|
|
"""隐藏设置界面"""
|
|
if self.settings_frame:
|
|
self.settings_frame.pack_forget()
|