diff --git a/config.env.toml b/config.env.toml new file mode 100644 index 0000000..1e755d7 --- /dev/null +++ b/config.env.toml @@ -0,0 +1,97 @@ +[paths] +# PPT模版路径 +source_file = "templates/大班幼儿学期发展报告.pptx" +# 输出文件夹 +output_folder = "output" +# Excel数据文件路径 +excel_file = "data/names.xlsx" +# 图片资源文件夹 +image_folder = "data/images" +# 字体文件夹 +fonts_dir = "fonts" + +[class_info] +# 班级名称 +class_name = "K4D" +# TODO 老师名单 (数组格式) +teachers = [""] + +[defaults] +# 当Excel中没有评语时的默认内容 +default_comment = "暂无评语" +age_group = "大班上学期" + + +# ======================== +# Excel 配置 (Data) +# ======================== +[excel] +sheet_name = "Sheet1" +# 对应Excel表头名称,顺序必须与代码中的解包顺序一致! +# 顺序:姓名, 英文名, 性别, 生日, 属相, 好朋友, 爱好, 游戏, 食物, 评语 +columns = [ + "姓名", + "英文名", + "性别", + "生日", + "属相", + "我的好朋友", + "我的爱好", + "喜欢的游戏", + "喜欢吃的食物", + "评价" +] + +# TODO API 配置 +[ai] +api_key = "" +api_url = "" +model = "" +prompt = """ +# Role +你是一位拥有20年经验的资深幼儿园主班老师。你的文笔温暖、细腻、充满爱意,擅长发现每个孩子身上独特的闪光点。你的评语风格是“治愈系”的,能让家长读完后感到欣慰并对未来充满希望。 + +# Goal +请根据用户提供的【幼儿姓名】、【年龄段/班级】以及【日常表现关键词/评分数据】,撰写一份高质量的学期末成长评语。 + +# Constraints & Rules +1. **称呼处理**: + - 自动识别用户输入的姓名。 + - **必须去掉姓氏**,只使用名。 + - 统一格式为:“[名]宝贝,你好!”或“[名]宝贝:”。 + - 例如:“王小明” -> “小明宝贝”;“李在这个” -> “在这个宝贝”。 + +2. **分龄侧重 (根据 Age_Group 调整侧重点)**: + - **小班 (3-4岁)**:侧重于适应集体生活、情绪稳定性、基本生活自理能力(吃饭、午睡、如厕)、愿意与老师互动。 + - **中班 (4-5岁)**:侧重于社交互动、分享与合作、动手能力、好奇心、规则意识的建立、自信心的增强。 + - **大班 (5-6岁)**:侧重于学习习惯、逻辑思维、领导力/榜样作用、任务意识、为幼小衔接做的准备、抗挫折能力。 + +3. **写作结构 (三段式)**: + - **开头**:亲切的问候 + 总体印象(用美好的形容词,如文静、活泼、机灵等)。 + - **正文**:结合提供的【表现关键词】,具体描述孩子的进步和优点(必须具体,拒绝空洞)。 + - **结尾**:委婉地提出一点小小的期望(用“如果你能...老师会更为你骄傲”的句式),并送上新学期的祝福。 + +4. **语气风格**: + - 积极正面,多用肯定句。 + - 避免生硬的批评,将缺点转化为“待提升的潜力”或“期望”。 + - 字数控制在 150-250 字之间(适合PPT展示)。 + +# Workflow +1. 分析用户输入的年龄段,确定评价基调。 +2. 处理姓名,提取昵称。 +3. 将输入的关键词串联成通顺、优美的句子。 +4. 按照三段式结构输出最终评语。 + +# Input Format +用户将提供 JSON 格式或特定格式的数据,包含: +- Name {{name}} +- Age_Group {{class_name}} +- Traits (表现关键词/特征,如:吃饭香、爱画画、有些胆小、数学好) + +# Output Example +(假设输入:Name=张图图, Age_Group=小班, Traits=适应能力强, 爱笑, 挑食) +图图宝贝,你好! +你是一个爱笑的小天使,每天早上都能看到你甜甜的笑脸,老师的心都要被你融化了。这个学期你进步真大呀,从一开始的哭鼻子到现在能开心地参与游戏,你的适应能力让老师感到惊喜。在集体活动中,你总是那么投入。 +不过,老师发现你在吃饭时偶尔会把不喜欢的青菜挑出来哦。如果你能和青菜宝宝做好朋友,把身体练得棒棒的,那就更完美啦! +祝可爱的图图宝贝新年快乐,健康成长! +""" \ No newline at end of file diff --git a/data/names.env.xlsx b/data/names.env.xlsx new file mode 100644 index 0000000..1f139e7 Binary files /dev/null and b/data/names.env.xlsx differ diff --git a/main.py b/main.py index f60672b..2369856 100644 --- a/main.py +++ b/main.py @@ -16,6 +16,7 @@ from rich.table import Table from config.config import load_config from utils.agent_utils import generate_comment from utils.font_utils import install_fonts_from_directory +from utils.image_utils import find_image_path from utils.pef_utils import batch_convert_folder from utils.pptx_utils import replace_text_in_slide, replace_picture @@ -112,31 +113,39 @@ def generate_report(): # --- 页面 3 --- student_image_folder = os.path.join(config["image_folder"], name) if os.path.exists(student_image_folder): - me_image = os.path.join(student_image_folder, "me_image.jpg") + me_image_path = find_image_path(student_image_folder, "me_image") # 构造信息字典供 helper 使用 info_dict = { "name": name, "english_name": english_name, "sex": sex, "birthday": birthday, "zodiac": zodiac, "friend": friend, "hobby": hobby, "game": game, "food": food } - replace_three_page(prs, info_dict, me_image) + replace_three_page(prs, info_dict, me_image_path) else: logger.warning(f"错误: 学生图片文件夹不存在 {student_image_folder}") # --- 页面 4 --- - class_image_path = os.path.join(config["image_folder"], config["class_name"] + ".jpg") + class_image_path = find_image_path(config["image_folder"], config["class_name"]) if os.path.exists(class_image_path): replace_four_page(prs, class_image_path) else: logger.warning(f"错误: 班级图片文件不存在 {class_image_path}") - # 原逻辑中如果班级图片不存在会 continue 跳过保存,这里保持一致 - continue - # --- 页面 5 --- + # --- 页面 5 --- if os.path.exists(student_image_folder): - image1 = os.path.join(student_image_folder, "1.jpg") - image2 = os.path.join(student_image_folder, "2.jpg") # 注意:原代码逻辑也是两张一样的图 - replace_five_page(prs, image1, image2) + img1_path = find_image_path(student_image_folder, "1") + img2_path = find_image_path(student_image_folder, "2") + # 逻辑优化: + # 情况A: 两张都找到了 -> 正常插入 + if img1_path and img2_path: + replace_five_page(prs, img1_path, img2_path) + + # 情况B: 只找到了 1 -> 两张图都用 1 (避免报错) + elif img1_path and not img2_path: + replace_five_page(prs, img1_path, img1_path) + # 情况C: 一张都没找到 + else: + logger.warning(f"⚠️ 警告: {name} 缺少生活照片 (1.jpg/png 或 2.jpg/png)[/]") else: logger.warning(f"错误: 学生图片文件夹不存在 {student_image_folder}") diff --git a/utils/image_utils.py b/utils/image_utils.py new file mode 100644 index 0000000..67dff08 --- /dev/null +++ b/utils/image_utils.py @@ -0,0 +1,28 @@ +import os + + +def find_image_path(folder, base_filename): + """ + 在指定文件夹中查找图片,支持 jpg/jpeg/png 等多种后缀。 + :param folder: 文件夹路径 + :param base_filename: 基础文件名(不带后缀,例如 "1" 或 "me_image") + :return: 找到的完整文件路径,如果没找到则返回 None + """ + if not os.path.exists(folder): + return None + + # 支持的后缀列表 (包含大小写) + extensions = [ + ".jpg", ".JPG", + ".jpeg", ".JPEG", + ".png", ".PNG", + ".bmp", ".BMP" + ] + + for ext in extensions: + # 拼凑完整路径,例如 data/images/张三/1.png + full_path = os.path.join(folder, base_filename + ext) + if os.path.exists(full_path): + return full_path + + return None