diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index ac3bac1..feb4403 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,14 +4,7 @@
-
-
-
-
-
-
-
-
+
@@ -101,7 +94,7 @@
-
+
@@ -127,7 +120,15 @@
1766152994686
-
+
+
+ 1766330259490
+
+
+
+ 1766330259490
+
+
diff --git a/config.toml b/config.toml
index 1460574..94d2fd2 100644
--- a/config.toml
+++ b/config.toml
@@ -1,25 +1,26 @@
[paths]
-source_file = "(横板)中班 幼儿学期发展报告.pptx"
+source_file = "大二班 幼儿学期发展报告.pptx"
output_folder = "output"
excel_file = "names.xlsx"
image_folder = "images"
fonts_dir = "fonts"
-signature_image = "D:\\working\\tools\\growth_report\\data\\"
+signature_image = "signature.png"
[class_info]
-class_name = "K3A"
+class_name = "K4B"
teachers = [
- "丁文敏",
- "麦芷晴",
- "徐焕奎",
+ "李垚",
+ "廖琴琴",
+ "余鸿仙",
]
+class_type = 1
[defaults]
default_comment = ""
-age_group = "中班上学期"
+age_group = "大班上学期"
[ai]
api_key = "sk-8b0c9522df8843b4d0e7e91ecb628957"
api_url = "https://apis.iflow.cn/v1/chat/completions"
model = "deepseek-v3.2"
-prompt = "# Role\n你是一位拥有20年经验的资深幼儿园主班老师。你的文笔温暖、细腻、充满爱意,擅长发现每个孩子身上独特的闪光点。你的评语风格是“治愈系”的,能让家长读完后感到欣慰并对未来充满希望。\n\n# Goal\n请根据用户提供的【幼儿姓名】、【年龄段/班级】以及【日常表现关键词/评分数据】,撰写一份高质量的学期末成长评语。\n\n# Constraints & Rules\n1. **严格的格式排版 (Strict Formatting)**:\n - **换行**:正文中间不要随意换行,保持为一段完整的段落。\n\n2. **称呼处理**:\n - 自动识别用户输入的姓名,去掉姓氏。\n - 例如:“王小明” -> 第一行输出“小明宝贝:”。\n\n3. **分龄侧重 (根据 Age_Group 调整侧重点)**:\n - **小班 (3-4岁)**:侧重于适应集体生活、情绪稳定性、基本生活自理能力、愿意与老师互动。\n - **中班 (4-5岁)**:侧重于社交互动、分享与合作、动手能力、好奇心、规则意识。\n - **大班 (5-6岁)**:侧重于学习习惯、逻辑思维、领导力、任务意识、幼小衔接准备。\n\n4. **写作结构 (固定内容)**:\n - **开头**:固定文本必须包含:“本学期开展了柏克莱主题课程(语言、社会、科学、艺术、健康);英语及特色课程(体能、舞蹈、美工、魔力猴、足球、国学)。”\n - **正文**:结合【表现关键词】和【性别】,具体描述进步和优点。\n - **结尾**:委婉地提出期望(“如果你能...老师会更为你骄傲”),并送上祝福。\n\n5. **语气风格**:\n - 积极正面,多用肯定句。\n - 字数控制在 150-250 字之间。\n\n# Input Format\n- Name {{name}}\n- Age_Group {{class_name}}\n- Traits {{traits}}\n- Sex {{sex}}\n\n# Output Example\n(假设输入:Name=张图图, Age_Group=小班, Traits=适应能力强, 爱笑, 挑食,Sex=女)\n图图宝贝:你好,本学期开展了柏克莱主题课程(语言、社会、科学、艺术、健康);英语及特色课程(体能、舞蹈、美工、魔力猴、足球、国学)。你是一个爱笑的小天使,每天早上都能看到你甜甜的笑脸。从一开始的哭鼻子到现在能开心地参与游戏,你的适应能力让老师感到惊喜。不过,老师发现你在吃饭时偶尔会把不喜欢的青菜挑出来哦。如果你能和青菜宝宝做好朋友,把身体练得棒棒的,那就更完美啦!祝可爱的图图宝贝新年快乐,健康成长!\n"
+prompt = "# Role \n你是一位拥有20年经验的资深幼儿园主班老师。你的文笔温暖、细腻、充满爱意,擅长发现每个孩子身上独特的闪光点。你的评语风格是“治愈系”的,能让家长读完后感到欣慰并对未来充满希望。\n\n# Goal\n请根据用户提供的【幼儿姓名】、【年龄段/班级】以及【日常表现关键词/评分数据】,撰写一份高质量的学期末成长评语。\n# Constraints & Rules\n1. **严格的格式排版 (Strict Formatting)**:\n- **换行**:正文中间不要随意换行,保持为一段完整的段落。\n2. **称呼处理**:\n- 自动识别用户输入的姓名,去掉姓氏。\n- 例如:“王小明” -> 第一行输出“小明宝贝:”。\n3. **分龄侧重 (根据 Age_Group 调整侧重点)**:\n- **小班 (3-4岁)**:侧重于适应集体生活、情绪稳定性、基本生活自理能力、愿意与老师互动。\n- **中班 (4-5岁)**:侧重于社交互动、分享与合作、动手能力、好奇心、规则意识。\n- **大班 (5-6岁)**:侧重于学习习惯、逻辑思维、领导力、任务意识、幼小衔接准备。\n4. **写作结构 (固定内容)**:\n- **开头**:固定文本必须包含:“{class_type}”\n- **正文**:结合【表现关键词】和【性别】,具体描述进步和优点。\n- **结尾**:委婉地提出期望(“如果你能...老师会更为你骄傲”),并送上祝福。\n5. **语气风格**:\n- 积极正面,多用肯定句。\n- 字数控制在 150-250 字之间。\n# Input Format\n- Name {{name}}\n- Age_Group {{class_name}}\n- Traits {{traits}}\n- Sex {{sex}}\n# Output Example\n(假设输入:Name=张图图, Age_Group=小班, Traits=适应能力强, 爱笑, 挑食,Sex=女)\n亲爱的图图宝贝:{class_type}\n你是一个爱笑的小天使,每天早上都能看到你甜甜的笑脸。从一开始的哭鼻子到现在能开心地参与游戏,你的适应能力让老师感到惊喜。不过,老师发现你在吃饭时偶尔会把不喜欢的青菜挑出来哦。如果你能和青菜宝宝做好朋友,把身体练得棒棒的,那就更完美啦!祝可爱的图图宝贝新年快乐,健康成长!\n"
diff --git a/config/config.py b/config/config.py
index 4fc645e..c2cd97f 100644
--- a/config/config.py
+++ b/config/config.py
@@ -69,9 +69,10 @@ def load_config(config_filename="config.toml"):
"class_name": class_info.get("class_name", "未命名班级"),
"teachers": class_info.get("teachers", []),
+ "class_type": class_info.get("class_type", 0),
"default_comment": defaults.get("default_comment", "暂无评语"),
"age_group": defaults.get("age_group", "大班上学期"),
- "ai": data.get("ai", {"api_key": "", "api_url": "", "model": ""}),
+ "ai": data.get("ai", {"api_key": "", "api_url": "", "model":"","prompt":""}),
}
return config
@@ -103,6 +104,7 @@ def save_config(config_data, config_filename="config.toml"):
"class_info": {
"class_name": config_data.get("class_name", ""),
"teachers": config_data.get("teachers", []),
+ "class_type": config_data.get("class_type", 0),
},
"defaults": {
"default_comment": config_data.get("default_comment", ""),
diff --git a/data/names.xlsx b/data/names.xlsx
index eb0364a..27239c5 100644
Binary files a/data/names.xlsx and b/data/names.xlsx differ
diff --git a/templates/大二班 幼儿学期发展报告.pptx b/templates/大二班 幼儿学期发展报告.pptx
new file mode 100644
index 0000000..07f0146
Binary files /dev/null and b/templates/大二班 幼儿学期发展报告.pptx differ
diff --git a/ui/views/config_page.py b/ui/views/config_page.py
index 7646a44..2636378 100644
--- a/ui/views/config_page.py
+++ b/ui/views/config_page.py
@@ -59,6 +59,10 @@ def create_config_page():
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: '昂贵班'},
+ label='班级类型', value=conf_data.get('class_type', 0)
+ ).props('outlined').classes('w-full')
# --- AI 配置 ---
with ui.tab_panel(tab_ai).classes('w-full p-0'):
@@ -78,6 +82,7 @@ def create_config_page():
"class_name": class_name.value,
"age_group": age_group.value,
"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,
@@ -87,6 +92,6 @@ def create_config_page():
}
# 修改点 4:直接调用导入的 save_config 函数名
success, message = save_config(new_data)
- ui.notify(message, type='positive' if success else 'negative')
+ ui.notify("配置已保存重启生效", type='positive')
ui.button('保存配置', on_click=handle_save).classes('w-full py-4').props('outline color=primary')
diff --git a/utils/agent_utils.py b/utils/agent_utils.py
index 0bc08ff..2bb4bb1 100644
--- a/utils/agent_utils.py
+++ b/utils/agent_utils.py
@@ -4,11 +4,13 @@ from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from loguru import logger
-
+import traceback
from config.config import load_config
-config = load_config("config.toml")
-
+class_type_config =[
+ "本期开展了小袋鼠整合主题课程:(语言、社会、科学、健康、艺术)、生活数学;特色课程(英语、体能、美工、篮球)",
+ "本学期开展了柏克莱主题课程(语言、社会、科学、艺术、健康);英语及特色课程(体能、舞蹈、美工、魔力猴、足球、国学)"
+]
def generate_comment(name, age_group, traits,sex):
"""
@@ -19,7 +21,14 @@ def generate_comment(name, age_group, traits,sex):
:param sex: 性别
:return: 评语
"""
-
+ # 1. 加载配置文件
+ try:
+ config = load_config("config.toml")
+ except Exception as e:
+ logger.error(f"配置文件获取失败: {str(e)}")
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
+ return "配置文件加载失败,请检查文件路径和内容。"
ai_config = config["ai"]
llm = ChatOpenAI(
base_url=ai_config["api_url"],
@@ -42,7 +51,8 @@ def generate_comment(name, age_group, traits,sex):
"name": name,
"age_group": age_group,
"traits": traits,
- "sex": sex
+ "sex": sex,
+ "class_type": class_type_config[(config.get("class_type", 0))],
})
cleaned_text = re.sub(r'\s+', '', comment)
logger.success(f"学生:{name} =>生成评语成功: {cleaned_text}")
diff --git a/utils/generate_utils.py b/utils/generate_utils.py
index a0be9c1..5c3bff0 100644
--- a/utils/generate_utils.py
+++ b/utils/generate_utils.py
@@ -24,15 +24,6 @@ from utils.growt_utils import (
)
from utils.pptx_utils import replace_picture
-# 如果你之前没有全局定义 console,这里定义一个
-console = Console()
-
-# ==========================================
-# 1. 配置区域 (Configuration)
-# ==========================================
-config = load_config("config.toml")
-
-
# ==========================================
# 1. 生成模板(根据names.xlsx文件生成名字图片文件夹)
# ==========================================
@@ -42,6 +33,13 @@ def generate_template(stop_event: threading.Event = None, progress_callback=None
:params stop_event 任务是否停止事件(监听UI的事件监听)
:params progress_callback 进度回调函数
"""
+ # 1. 加载配置文件
+ try:
+ config = load_config("config.toml")
+ except Exception as e:
+ logger.error(f"配置文件获取失败: {str(e)}")
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
try:
# 1. 读取数据
df = pd.read_excel(config["excel_file"], sheet_name="Sheet1")
@@ -89,6 +87,13 @@ def generate_comment_all(stop_event: threading.Event = None, progress_callback=N
:params stop_event 任务是否停止事件(监听UI的事件监听)
:params progress_callback 进度回调函数
"""
+ # 1. 加载配置文件
+ try:
+ config = load_config("config.toml")
+ except Exception as e:
+ logger.error(f"配置文件获取失败: {str(e)}")
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
try:
# 1. 读取数据
excel_path = config["excel_file"]
@@ -109,9 +114,6 @@ def generate_comment_all(stop_event: threading.Event = None, progress_callback=N
if stop_event and stop_event.is_set():
logger.warning("任务正在停止中,正在中断中.....")
return # 停止任务
- # 添加进度条
- if progress_callback:
- progress_callback(i + 1, total_count, "生成学生评语")
# 获取学生姓名
name = df.at[i, "姓名"]
@@ -135,7 +137,9 @@ def generate_comment_all(stop_event: threading.Event = None, progress_callback=N
if not pd.isna(current_comment) and str(current_comment).strip() != "":
logger.info(f"[{i + 1}/{total_count}] {name} 已有评语,跳过。")
continue
-
+ # 添加进度条
+ if progress_callback:
+ progress_callback(i + 1, total_count, f"[{i + 1}/{total_count}] 正在生成评价: {name}")
logger.info(f"[{i + 1}/{total_count}] 正在生成评价: {name}")
try:
@@ -176,7 +180,13 @@ def generate_report(stop_event: threading.Event = None, progress_callback=None):
根据学生姓名生成成长报告
:params stop_event 任务是否停止事件(监听UI的事件监听)
:params progress_callback 进度回调函数
- """
+ """ # 1. 加载配置文件
+ try:
+ config = load_config("config.toml")
+ except Exception as e:
+ logger.error(f"配置文件获取失败: {str(e)}")
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
# 1. 检查模版文件是否存在
if not os.path.exists(config["source_file"]):
logger.info(f"错误: 找不到模版文件 {config["source_file"]}")
@@ -212,9 +222,6 @@ def generate_report(stop_event: threading.Event = None, progress_callback=None):
if stop_event and stop_event.is_set():
logger.warning("任务正在停止中,正在中断中.....")
return
- # 更新进度条
- if progress_callback:
- progress_callback(i + 1, total_count, "生成报告")
# 解包数据
(
name,
@@ -228,7 +235,9 @@ def generate_report(stop_event: threading.Event = None, progress_callback=None):
food,
comments,
) = row_data
-
+ # 更新进度条
+ if progress_callback:
+ progress_callback(i + 1, total_count, f"[{i + 1}/{len(datas)}] 正在生成: 【{name}】 成长报告")
logger.info(f"[{i + 1}/{len(datas)}] 正在生成: {name}")
# 每次循环重新加载模版
@@ -341,6 +350,13 @@ def batch_convert_folder(folder_path, stop_event: threading.Event = None, progre
:params stop_event 任务是否停止事件(监听UI的事件监听)
:params progress_callback 进度回调函数
"""
+ # 1. 加载配置文件
+ try:
+ config = load_config("config.toml")
+ except Exception as e:
+ logger.error(f"配置文件获取失败: {str(e)}")
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
# 子线程初始化 COM 组件
pythoncom.CoInitialize()
try:
@@ -424,6 +440,13 @@ def generate_zodiac(stop_event: threading.Event = None, progress_callback=None):
:params stop_event 任务是否停止事件(监听UI的事件监听)
:params progress_callback 进度回调函数
"""
+ # 1. 加载配置文件
+ try:
+ config = load_config("config.toml")
+ except Exception as e:
+ logger.error(f"配置文件获取失败: {str(e)}")
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
try:
# 1. 读取数据
excel_path = config["excel_file"]
@@ -505,6 +528,13 @@ def generate_signature(progress_callback=None) -> str:
"""
生成园长签名
"""
+ # 1. 加载配置文件
+ try:
+ config = load_config("config.toml")
+ except Exception as e:
+ logger.error(f"配置文件获取失败: {str(e)}")
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
try:
# 获取所有的PPT (此时返回的是文件名或路径的列表)
pptx_files = get_output_pptx_files(config["output_folder"])
@@ -542,4 +572,6 @@ def generate_signature(progress_callback=None) -> str:
progress_callback(len(pptx_files), len(pptx_files), "签名生成完成")
except Exception as e:
logger.error(f"generate_signature 发生未知错误: {e}")
- return str(e)
\ No newline at end of file
+ # 打印详细报错位置,方便调试
+ logger.error(traceback.format_exc())
+ return str(e)