fix:优化配置存储
This commit is contained in:
@@ -1,189 +1,98 @@
|
||||
from nicegui import ui
|
||||
import os
|
||||
from utils.template_utils import get_template_files
|
||||
|
||||
# 修改点 1:统一导入,避免与变量名 config 冲突
|
||||
from config.config import load_config, save_config
|
||||
from nicegui import ui, app
|
||||
|
||||
from ui.views.templates.back_home import backHome
|
||||
from utils.template_utils import get_template_files
|
||||
|
||||
|
||||
def create_config_page():
|
||||
# 修改点 2:将加载逻辑放入页面生成函数内,确保每次刷新页面获取最新值
|
||||
conf_data = load_config("config.toml")
|
||||
template_options = get_template_files()
|
||||
current_filename = os.path.basename(conf_data.get("source_file", ""))
|
||||
# 获取当前持久化存储中的数据
|
||||
cfg = app.storage.general
|
||||
|
||||
template_options = get_template_files()
|
||||
current_filename = os.path.basename(cfg.get("source_file", ""))
|
||||
if current_filename and current_filename not in template_options:
|
||||
template_options.append(current_filename)
|
||||
|
||||
ui.add_head_html('<link href="/assets/style.css" rel="stylesheet" />')
|
||||
|
||||
# 样式修正:添加全屏且不滚动条的 CSS
|
||||
ui.add_head_html(
|
||||
"""
|
||||
ui.add_head_html("""
|
||||
<style>
|
||||
body { overflow: hidden; }
|
||||
.main-card { height: calc(100vh - 100px); display: flex; flex-direction: column; }
|
||||
.q-tab-panels { flex-grow: 1; overflow-y: auto !important; }
|
||||
</style>
|
||||
"""
|
||||
)
|
||||
""")
|
||||
|
||||
with ui.header().classes("app-header items-center justify-between shadow-md"):
|
||||
# 左侧:图标和标题
|
||||
with ui.row().classes("items-center gap-2"):
|
||||
ui.image("/assets/icon.ico").classes("w-8 h-8").props("fit=contain")
|
||||
ui.label("尚城幼儿园成长报告助手").classes("text-xl font-bold")
|
||||
# 右侧:署名 + 配置按钮
|
||||
with ui.row().classes("items-center gap-4"):
|
||||
ui.label("By 寒寒 | 这里的每一份评语都充满爱意").classes(
|
||||
"text-xs opacity-90"
|
||||
)
|
||||
ui.button(icon="home", on_click=lambda: ui.navigate.to("/")).props(
|
||||
"flat round color=white"
|
||||
)
|
||||
backHome()
|
||||
|
||||
# 修改点 3:使用 flex 布局撑满
|
||||
with ui.card().classes("w-full max-w-5xl mx-auto shadow-lg main-card p-0"):
|
||||
with ui.tabs().classes("w-full") as tabs:
|
||||
tab_path = ui.tab("路径设置", icon="folder")
|
||||
tab_class = ui.tab("班级与教师", icon="school")
|
||||
tab_ai = ui.tab("AI 接口配置", icon="psychology")
|
||||
|
||||
with ui.tab_panels(tabs, value=tab_path).classes(
|
||||
"w-full flex-grow bg-transparent"
|
||||
):
|
||||
# --- 路径设置 ---
|
||||
with ui.tab_panel(tab_path).classes("w-full p-0"):
|
||||
with ui.column().classes("w-full p-4 gap-4"):
|
||||
source_file = (
|
||||
ui.select(
|
||||
options=template_options,
|
||||
label="PPT 模板",
|
||||
value=current_filename,
|
||||
)
|
||||
.props("outlined fill-input")
|
||||
.classes("w-full")
|
||||
)
|
||||
excel_file = (
|
||||
ui.input(
|
||||
"Excel 文件",
|
||||
value=os.path.basename(conf_data.get("excel_file", "")),
|
||||
)
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
image_folder = (
|
||||
ui.input(
|
||||
"图片目录",
|
||||
value=os.path.basename(conf_data.get("image_folder", "")),
|
||||
)
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
output_folder = (
|
||||
ui.input(
|
||||
"输出目录",
|
||||
value=os.path.basename(
|
||||
conf_data.get("output_folder", "output")
|
||||
),
|
||||
)
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
with ui.tab_panels(tabs, value=tab_path).classes("w-full flex-grow bg-transparent"):
|
||||
# --- 1. 路径设置 ---
|
||||
with ui.tab_panel(tab_path).classes("w-full p-4 gap-4"):
|
||||
# 注意:这里改用普通的 value= 参数,不使用 bind_value
|
||||
source_file = ui.select(options=template_options, label="PPT 模板", value=cfg.get('source_file')).props(
|
||||
"outlined").classes("w-full")
|
||||
excel_file = ui.input("Excel 文件名", value=cfg.get('excel_file')).props("outlined").classes("w-full")
|
||||
image_folder = ui.input("图片目录名", value=cfg.get('image_folder')).props("outlined").classes("w-full")
|
||||
output_folder = ui.input("输出目录名", value=cfg.get('output_folder', 'output')).props(
|
||||
"outlined").classes("w-full")
|
||||
|
||||
# --- 班级信息 ---
|
||||
with ui.tab_panel(tab_class).classes("w-full p-0"):
|
||||
with ui.column().classes("w-full p-4 gap-4"):
|
||||
class_name = (
|
||||
ui.input("班级名称", value=conf_data.get("class_name", ""))
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
age_group = (
|
||||
ui.select(
|
||||
options=[
|
||||
"小班上学期",
|
||||
"小班下学期",
|
||||
"中班上学期",
|
||||
"中班下学期",
|
||||
"大班上学期",
|
||||
"大班下学期",
|
||||
],
|
||||
label="年龄段",
|
||||
value=conf_data.get("age_group", "中班上学期"),
|
||||
)
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
teachers_text = (
|
||||
ui.textarea(
|
||||
"教师名单", value="\n".join(conf_data.get("teachers", []))
|
||||
)
|
||||
.props("outlined")
|
||||
.classes("w-full h-40")
|
||||
)
|
||||
class_type = (
|
||||
ui.select(
|
||||
options={0: "便宜班", 1: "昂贵班", 2: "昂贵的双木桥班"},
|
||||
label="班级类型",
|
||||
value=conf_data.get("class_type", 0),
|
||||
)
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
# --- 2. 班级信息 ---
|
||||
with ui.tab_panel(tab_class).classes("w-full p-4 gap-4"):
|
||||
class_name = ui.input("班级名称", value=cfg.get('class_name')).props("outlined").classes("w-full")
|
||||
age_group = ui.select(
|
||||
options=["小班上学期", "小班下学期", "中班上学期", "中班下学期", "大班上学期", "大班下学期"],
|
||||
label="年龄段",
|
||||
value=cfg.get('age_group')
|
||||
).props("outlined").classes("w-full")
|
||||
|
||||
# --- AI 配置 ---
|
||||
with ui.tab_panel(tab_ai).classes("w-full p-0"):
|
||||
with ui.column().classes("w-full p-4 gap-4"):
|
||||
ai_key = (
|
||||
ui.input("API Key", value=conf_data["ai"].get("api_key", ""))
|
||||
.props("outlined password")
|
||||
.classes("w-full")
|
||||
)
|
||||
ai_url = (
|
||||
ui.input("API URL", value=conf_data["ai"].get("api_url", ""))
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
ai_model = (
|
||||
ui.input("Model Name", value=conf_data["ai"].get("model", ""))
|
||||
.props("outlined")
|
||||
.classes("w-full")
|
||||
)
|
||||
ai_prompt = (
|
||||
ui.textarea(
|
||||
"System Prompt", value=conf_data["ai"].get("prompt", "")
|
||||
)
|
||||
.props("outlined")
|
||||
.classes("w-full h-full")
|
||||
)
|
||||
# 底部固定按钮
|
||||
teachers_text = ui.textarea("教师名单(每行一个)", value="\n".join(cfg.get("teachers", []))).props(
|
||||
"outlined").classes("w-full h-40")
|
||||
|
||||
class_type = ui.select(
|
||||
options={0: "便宜班", 1: "昂贵班", 2: "昂贵的双木桥班"},
|
||||
label="班级类型",
|
||||
value=cfg.get('class_type', 0)
|
||||
).props("outlined").classes("w-full")
|
||||
|
||||
# --- 3. AI 配置 ---
|
||||
with ui.tab_panel(tab_ai).classes("w-full p-4 gap-4"):
|
||||
ai_data = cfg.get('ai', {}) # 获取子字典
|
||||
ai_key = ui.input("API Key", value=ai_data.get("api_key")).props("outlined password").classes("w-full")
|
||||
ai_url = ui.input("API URL", value=ai_data.get("api_url")).props("outlined").classes("w-full")
|
||||
ai_model = ui.input("Model Name", value=ai_data.get("model")).props("outlined").classes("w-full")
|
||||
ai_prompt = ui.textarea("System Prompt", value=ai_data.get("prompt")).props("outlined").classes(
|
||||
"w-full h-64")
|
||||
|
||||
# --- 底部按钮:点击后统一更新到 Storage ---
|
||||
with ui.row().classes("w-full p-4"):
|
||||
|
||||
async def handle_save():
|
||||
new_data = {
|
||||
def handle_manual_save():
|
||||
# 统一更新到 app.storage.general
|
||||
# NiceGUI 会在此时感知到字典变化并触发自动保存到 JSON 文件
|
||||
cfg.update({
|
||||
"source_file": source_file.value,
|
||||
"excel_file": excel_file.value,
|
||||
"image_folder": image_folder.value,
|
||||
"output_folder": output_folder.value,
|
||||
"class_name": class_name.value,
|
||||
"age_group": age_group.value,
|
||||
"signature_image": conf_data.get("signature_image", ""),
|
||||
"teachers": [
|
||||
t.strip() for t in teachers_text.value.split("\n") if t.strip()
|
||||
],
|
||||
"teachers": [t.strip() for t in teachers_text.value.split('\n') if t.strip()],
|
||||
"class_type": class_type.value,
|
||||
"ai": {
|
||||
"api_key": ai_key.value,
|
||||
"api_url": ai_url.value,
|
||||
"model": ai_model.value,
|
||||
"prompt": ai_prompt.value,
|
||||
},
|
||||
}
|
||||
# 修改点 4:直接调用导入的 save_config 函数名
|
||||
success, message = save_config(new_data)
|
||||
ui.notify("配置已保存重启生效", type="positive")
|
||||
}
|
||||
})
|
||||
ui.notify("配置已成功更新至系统存储", type="positive", icon="save")
|
||||
|
||||
ui.button("保存配置", on_click=handle_save).classes("w-full py-4").props(
|
||||
"outline color=primary"
|
||||
)
|
||||
ui.button("保存配置", icon="save", on_click=handle_manual_save).classes("w-full py-4 shadow-md").props(
|
||||
"color=primary")
|
||||
|
||||
@@ -5,6 +5,7 @@ import pythoncom
|
||||
from loguru import logger
|
||||
from nicegui import ui
|
||||
|
||||
from ui.views.templates.back_home import backHome
|
||||
from utils.file_utils import open_folder
|
||||
|
||||
progress_bar = None
|
||||
@@ -85,18 +86,7 @@ def create_convert_pdf_page(folder: str = ""):
|
||||
)
|
||||
|
||||
with ui.header().classes("app-header items-center justify-between shadow-md"):
|
||||
# 左侧:图标和标题
|
||||
with ui.row().classes("items-center gap-2"):
|
||||
ui.image("/assets/icon.ico").classes("w-8 h-8").props("fit=contain")
|
||||
ui.label("尚城幼儿园成长报告助手").classes("text-xl font-bold")
|
||||
# 右侧:署名 + 配置按钮
|
||||
with ui.row().classes("items-center gap-4"):
|
||||
ui.label("By 寒寒 | 这里的每一份评语都充满爱意").classes(
|
||||
"text-xs opacity-90"
|
||||
)
|
||||
ui.button(icon="home", on_click=lambda: ui.navigate.to("/")).props(
|
||||
"flat round color=white"
|
||||
)
|
||||
backHome()
|
||||
|
||||
with ui.card().classes("w-full"):
|
||||
with ui.row().classes("w-full justify-between"):
|
||||
|
||||
@@ -1,28 +1,17 @@
|
||||
import pandas as pd
|
||||
from nicegui import ui
|
||||
from config.config import load_config
|
||||
import os
|
||||
|
||||
import pandas as pd
|
||||
from nicegui import ui
|
||||
|
||||
def create_header():
|
||||
with ui.header().classes("app-header items-center justify-between shadow-md"):
|
||||
with ui.row().classes("items-center gap-2"):
|
||||
ui.image("/assets/icon.ico").classes("w-8 h-8").props("fit=contain")
|
||||
ui.label("尚城幼儿园成长报告助手").classes("text-xl font-bold")
|
||||
|
||||
with ui.row().classes("items-center gap-4"):
|
||||
ui.label("By 寒寒 | 这里的每一份评语都充满爱意").classes(
|
||||
"text-xs opacity-90"
|
||||
)
|
||||
ui.button(icon="home", on_click=lambda: ui.navigate.to("/")).props(
|
||||
"flat round color=white"
|
||||
).tooltip("回到首页")
|
||||
from config.config import load_config
|
||||
from ui.views.templates.back_home import backHome
|
||||
|
||||
|
||||
def create_data_page():
|
||||
ui.add_head_html('<link href="/assets/style.css" rel="stylesheet" />')
|
||||
|
||||
create_header()
|
||||
with ui.header().classes("app-header items-center justify-between shadow-md"):
|
||||
backHome()
|
||||
|
||||
with ui.column().classes("w-full max-w-6xl mx-auto p-4 gap-4 thin-scrollbar"):
|
||||
with ui.card().classes("func-card"):
|
||||
@@ -37,7 +26,7 @@ def create_data_page():
|
||||
|
||||
|
||||
def load_data():
|
||||
conf_data = load_config("config.toml")
|
||||
conf_data = load_config()
|
||||
excel_path = conf_data.get("excel_file")
|
||||
|
||||
with (
|
||||
@@ -47,7 +36,7 @@ def load_data():
|
||||
),
|
||||
):
|
||||
with ui.row().classes(
|
||||
"w-full bg-gradient-to-r from-blue-50 to-indigo-50 items-center justify-between"
|
||||
"w-full bg-gradient-to-r from-blue-50 to-indigo-50 items-center justify-between"
|
||||
):
|
||||
with ui.column().classes("gap-0"):
|
||||
ui.label("幼儿成长档案").classes(
|
||||
@@ -61,7 +50,7 @@ def load_data():
|
||||
content_container = ui.column().classes("w-full")
|
||||
|
||||
with ui.row().classes(
|
||||
"w-full p-5 bg-slate-50/80 backdrop-blur-md border-t justify-end gap-3"
|
||||
"w-full p-5 bg-slate-50/80 backdrop-blur-md border-t justify-end gap-3"
|
||||
):
|
||||
ui.button("确认", on_click=detail_dialog.close).props(
|
||||
"unelevated color=blue-6"
|
||||
@@ -75,7 +64,7 @@ def load_data():
|
||||
|
||||
with content_container:
|
||||
with ui.row().classes(
|
||||
"w-full items-center p-4 bg-blue-600 rounded-2xl shadow-md shadow-blue-100"
|
||||
"w-full items-center p-4 bg-blue-600 rounded-2xl shadow-md shadow-blue-100"
|
||||
):
|
||||
ui.avatar("person", color="white", text_color="blue-6").props(
|
||||
"size=48px"
|
||||
@@ -105,7 +94,7 @@ def load_data():
|
||||
df = df.fillna("-")
|
||||
|
||||
with ui.row().classes(
|
||||
"bg-blue-50 w-full p-3 px-6 items-center rounded-t-xl border-b border-blue-100"
|
||||
"bg-blue-50 w-full p-3 px-6 items-center rounded-t-xl border-b border-blue-100"
|
||||
):
|
||||
ui.icon("fact_check", color="primary", size="20px")
|
||||
ui.label(f"班级:{conf_data.get('class_name', '未设定')}").classes(
|
||||
|
||||
@@ -12,7 +12,7 @@ from utils.generate_utils import (
|
||||
generate_zodiac,
|
||||
)
|
||||
|
||||
config = load_config("config.toml")
|
||||
config = load_config()
|
||||
|
||||
|
||||
def create_header():
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from nicegui import ui
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from loguru import logger
|
||||
from nicegui import ui
|
||||
from pptx import Presentation
|
||||
|
||||
from config.config import load_config
|
||||
from utils.file_utils import open_folder
|
||||
from loguru import logger
|
||||
import traceback
|
||||
from pptx import Presentation
|
||||
|
||||
|
||||
def create_signature_page(folder: str = ""):
|
||||
@@ -142,7 +144,7 @@ def sign_file(folder, file_name: str):
|
||||
"""
|
||||
try:
|
||||
# 1. 加载配置文件
|
||||
config = load_config("config.toml")
|
||||
config = load_config()
|
||||
except Exception as e:
|
||||
logger.error(f"配置文件获取失败: {str(e)}")
|
||||
# 打印详细报错位置,方便调试
|
||||
|
||||
16
ui/views/templates/back_home.py
Normal file
16
ui/views/templates/back_home.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from nicegui import ui
|
||||
|
||||
|
||||
def backHome():
|
||||
"""返回首页"""
|
||||
with ui.row().classes("items-center gap-2"):
|
||||
ui.image("/assets/icon.ico").classes("w-8 h-8").props("fit=contain")
|
||||
ui.label("尚城幼儿园成长报告助手").classes("text-xl font-bold")
|
||||
|
||||
with ui.row().classes("items-center gap-4"):
|
||||
ui.label("By 寒寒 | 这里的每一份评语都充满爱意").classes(
|
||||
"text-xs opacity-90"
|
||||
)
|
||||
ui.button(icon="home", on_click=lambda: ui.navigate.to("/")).props(
|
||||
"flat round color=white"
|
||||
).tooltip("回到首页")
|
||||
Reference in New Issue
Block a user