zhensolid 8 месяцев назад
Родитель
Сommit
47da0e695e
1 измененных файлов с 236 добавлено и 29 удалено
  1. 236 29
      日报工具/autowrite_day.py

+ 236 - 29
日报工具/autowrite_day.py

@@ -26,50 +26,238 @@ import os
 import psutil
 import time
 import tkinter as tk
-from tkinter import scrolledtext
+from tkinter import scrolledtext, messagebox, ttk
 from playwright.async_api import async_playwright
+import requests
+import logging
+import threading
+import re
+
+# 配置日志
+logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
+
+# 全局变量,用于控制生成状态
+is_generating = False
+
+def count_chinese_chars(text):
+    """统计中文字符数量"""
+    return len(re.findall(r'[\u4e00-\u9fff]', text))
+
+def count_words(text):
+    """统计总字数(中文字符+其他字符)"""
+    return count_chinese_chars(text) + len(re.sub(r'[\u4e00-\u9fff]', '', text))
+
+def generate_daily_report(prompt, ollama_url, model_name):
+    """使用Ollama生成日报内容"""
+    try:
+        logging.info(f"开始生成日报,使用模型: {model_name}")
+        # 生成今日工作总结
+        summary_response = requests.post(
+            f"{ollama_url}/api/generate",
+            json={
+                "model": model_name,
+                "prompt": f"你是一个专业的日报生成助手,请根据以下工作内容生成专业的今日工作总结:{prompt}",
+                "stream": False
+            }
+        )
+        logging.info(f"今日工作总结生成状态码: {summary_response.status_code}")
+        
+        # 生成明日工作计划
+        plan_response = requests.post(
+            f"{ollama_url}/api/generate",
+            json={
+                "model": model_name,
+                "prompt": f"你是一个专业的日报生成助手,请根据以下工作内容生成合理的明日工作计划:{prompt}",
+                "stream": False
+            }
+        )
+        logging.info(f"明日工作计划生成状态码: {plan_response.status_code}")
+        
+        if summary_response.status_code == 200 and plan_response.status_code == 200:
+            return summary_response.json()["response"], plan_response.json()["response"]
+        else:
+            error_msg = f"API调用失败: 总结状态码={summary_response.status_code}, 计划状态码={plan_response.status_code}"
+            if summary_response.status_code != 200:
+                error_msg += f"\n总结生成失败原因: {summary_response.text}"
+            if plan_response.status_code != 200:
+                error_msg += f"\n计划生成失败原因: {plan_response.text}"
+            logging.error(error_msg)
+            return None, error_msg
+    except Exception as e:
+        error_msg = f"生成日报时发生错误: {str(e)}"
+        logging.error(error_msg)
+        return None, error_msg
 
 def get_user_input():
     """通过GUI窗口获取用户输入的日报内容"""
     root = tk.Tk()
     root.title("日报填写助手")
-    root.geometry("900x700")
+    root.geometry("1000x800")  # 设置更大的初始窗口大小
     
     # 设置窗口样式
     root.configure(bg='#f0f0f0')
-    root.option_add('*Font', '微软雅黑 10')
+    # 修改字体设置方式
+    default_font = ('微软雅黑', 10)
+    root.option_add('*Font', default_font)
     
     # 设置窗口图标(如果有的话)
     try:
-        root.iconbitmap('icon.ico')  # 如果有图标文件的话
+        root.iconbitmap('icon.ico')
     except:
         pass
     
     # 创建主框架
-    main_frame = tk.Frame(root, bg='#f0f0f0', padx=20, pady=20)
-    main_frame.pack(fill=tk.BOTH, expand=True)
+    main_frame = tk.Frame(root, bg='#f0f0f0')
+    main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
     
     # 创建标题
     title_label = tk.Label(main_frame, 
                          text="日报填写", 
-                         font=("微软雅黑", 16, "bold"),
+                         font=('微软雅黑', 16, 'bold'),
                          bg='#f0f0f0',
-                         pady=10)
+                         pady=5)
     title_label.pack()
     
+    # 创建配置区域框架
+    config_frame = tk.Frame(main_frame, bg='#f0f0f0')
+    config_frame.pack(fill=tk.X, pady=5)
+    
+    # 创建Ollama配置区域
+    ollama_frame = tk.LabelFrame(config_frame, 
+                               text="Ollama配置", 
+                               font=('微软雅黑', 12),
+                               bg='#f0f0f0',
+                               padx=10,
+                               pady=5)
+    ollama_frame.pack(fill=tk.X, pady=2)
+    
+    # Ollama地址输入
+    url_frame = tk.Frame(ollama_frame, bg='#f0f0f0')
+    url_frame.pack(fill=tk.X, pady=2)
+    tk.Label(url_frame, 
+            text="Ollama地址:", 
+            font=('微软雅黑', 11),
+            bg='#f0f0f0').pack(side=tk.LEFT)
+    ollama_url = tk.Entry(url_frame, 
+                         font=('微软雅黑', 11))
+    ollama_url.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
+    ollama_url.insert(0, "http://localhost:11434")
+    
+    # 模型名称输入
+    model_frame = tk.Frame(ollama_frame, bg='#f0f0f0')
+    model_frame.pack(fill=tk.X, pady=2)
+    tk.Label(model_frame, 
+            text="模型名称:", 
+            font=('微软雅黑', 11),
+            bg='#f0f0f0').pack(side=tk.LEFT)
+    model_name = tk.Entry(model_frame, 
+                         font=('微软雅黑', 11))
+    model_name.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
+    model_name.insert(0, "llama2")
+    
+    # 创建提示词输入区域
+    prompt_frame = tk.LabelFrame(config_frame, 
+                               text="工作内容提示词", 
+                               font=('微软雅黑', 12),
+                               bg='#f0f0f0',
+                               padx=10,
+                               pady=5)
+    prompt_frame.pack(fill=tk.X, pady=2)
+    
+    prompt_text = scrolledtext.ScrolledText(prompt_frame, 
+                                          height=3, 
+                                          font=('微软雅黑', 11),
+                                          wrap=tk.WORD,
+                                          padx=10,
+                                          pady=10)
+    prompt_text.pack(fill=tk.X, expand=True)
+    
+    # 创建进度条
+    progress_var = tk.DoubleVar()
+    progress_bar = ttk.Progressbar(prompt_frame, 
+                                 variable=progress_var,
+                                 maximum=100,
+                                 mode='indeterminate')
+    
+    # 创建自动生成按钮
+    def auto_generate():
+        global is_generating
+        if is_generating:
+            return
+            
+        prompt = prompt_text.get("1.0", tk.END).strip()
+        if not prompt:
+            messagebox.showwarning("提示", "请输入工作内容提示词")
+            return
+            
+        try:
+            is_generating = True
+            auto_generate_button.config(state=tk.DISABLED)
+            progress_bar.pack(fill=tk.X, pady=5)
+            progress_bar.start()
+            
+            def generate_thread():
+                try:
+                    summary, plan = generate_daily_report(
+                        prompt,
+                        ollama_url.get().strip(),
+                        model_name.get().strip()
+                    )
+                    if summary and plan:
+                        root.after(0, lambda: update_texts(summary, plan))
+                    else:
+                        root.after(0, lambda: messagebox.showerror("错误", f"生成日报失败:{plan}"))
+                except Exception as e:
+                    root.after(0, lambda: messagebox.showerror("错误", f"生成日报时发生错误:{str(e)}"))
+                finally:
+                    root.after(0, finish_generation)
+            
+            threading.Thread(target=generate_thread, daemon=True).start()
+            
+        except Exception as e:
+            messagebox.showerror("错误", f"生成日报时发生错误:{str(e)}")
+            finish_generation()
+    
+    def update_texts(summary, plan):
+        summary_text.delete("1.0", tk.END)
+        plan_text.delete("1.0", tk.END)
+        summary_text.insert("1.0", summary)
+        plan_text.insert("1.0", plan)
+        update_counts()
+    
+    def finish_generation():
+        global is_generating
+        is_generating = False
+        auto_generate_button.config(state=tk.NORMAL)
+        progress_bar.stop()
+        progress_bar.pack_forget()
+    
+    auto_generate_button = tk.Button(prompt_frame,
+                                   text="自动生成日报",
+                                   command=auto_generate,
+                                   font=('微软雅黑', 11),
+                                   bg='#2196F3',
+                                   fg='white',
+                                   relief=tk.FLAT,
+                                   cursor='hand2')
+    auto_generate_button.pack(pady=5)
+    
+    # 创建内容区域框架
+    content_frame = tk.Frame(main_frame, bg='#f0f0f0')
+    content_frame.pack(fill=tk.BOTH, expand=True, pady=5)
+    
     # 创建今日工作总结输入区域
-    summary_frame = tk.LabelFrame(main_frame, 
+    summary_frame = tk.LabelFrame(content_frame, 
                                 text="今日工作总结", 
-                                font=("微软雅黑", 12),
+                                font=('微软雅黑', 12),
                                 bg='#f0f0f0',
                                 padx=10,
                                 pady=5)
-    summary_frame.pack(fill=tk.BOTH, expand=True, pady=10)
+    summary_frame.pack(fill=tk.BOTH, expand=True, pady=2)
     
     summary_text = scrolledtext.ScrolledText(summary_frame, 
-                                           width=80, 
-                                           height=8, 
-                                           font=("微软雅黑", 11),
+                                           height=8,
+                                           font=('微软雅黑', 11),
                                            wrap=tk.WORD,
                                            padx=10,
                                            pady=10)
@@ -78,24 +266,23 @@ def get_user_input():
     # 添加字数统计
     summary_count = tk.Label(summary_frame, 
                            text="字数:0", 
-                           font=("微软雅黑", 10),
+                           font=('微软雅黑', 10),
                            bg='#f0f0f0',
                            anchor='e')
     summary_count.pack(fill=tk.X, padx=10)
     
     # 创建明日工作计划输入区域
-    plan_frame = tk.LabelFrame(main_frame, 
+    plan_frame = tk.LabelFrame(content_frame, 
                              text="明日工作计划", 
-                             font=("微软雅黑", 12),
+                             font=('微软雅黑', 12),
                              bg='#f0f0f0',
                              padx=10,
                              pady=5)
-    plan_frame.pack(fill=tk.BOTH, expand=True, pady=10)
+    plan_frame.pack(fill=tk.BOTH, expand=True, pady=2)
     
     plan_text = scrolledtext.ScrolledText(plan_frame, 
-                                        width=80, 
-                                        height=8, 
-                                        font=("微软雅黑", 11),
+                                        height=8,
+                                        font=('微软雅黑', 11),
                                         wrap=tk.WORD,
                                         padx=10,
                                         pady=10)
@@ -104,27 +291,31 @@ def get_user_input():
     # 添加字数统计
     plan_count = tk.Label(plan_frame, 
                         text="字数:0", 
-                        font=("微软雅黑", 10),
+                        font=('微软雅黑', 10),
                         bg='#f0f0f0',
                         anchor='e')
     plan_count.pack(fill=tk.X, padx=10)
     
     # 创建底部控制区域
-    bottom_frame = tk.Frame(main_frame, bg='#f0f0f0', pady=10)
-    bottom_frame.pack(fill=tk.X)
+    bottom_frame = tk.Frame(main_frame, bg='#f0f0f0')
+    bottom_frame.pack(fill=tk.X, pady=5)
     
     # 创建复选框
     keep_original = tk.BooleanVar(value=False)
     check_button = tk.Checkbutton(bottom_frame, 
                                 text="保留原有内容", 
                                 variable=keep_original, 
-                                font=("微软雅黑", 11),
+                                font=('微软雅黑', 11),
                                 bg='#f0f0f0')
     check_button.pack(side=tk.LEFT, padx=10)
     
     # 创建提交按钮
     result = {"summary": "", "plan": "", "is_submitted": False, "keep_original": False}
     def submit():
+        if not summary_text.get("1.0", tk.END).strip() or not plan_text.get("1.0", tk.END).strip():
+            messagebox.showwarning("提示", "请填写完整的工作总结和计划")
+            return
+            
         result["summary"] = summary_text.get("1.0", tk.END).strip()
         result["plan"] = plan_text.get("1.0", tk.END).strip()
         result["keep_original"] = keep_original.get()
@@ -135,18 +326,21 @@ def get_user_input():
     submit_button = tk.Button(bottom_frame, 
                             text="提交", 
                             command=submit, 
-                            font=("微软雅黑", 12, "bold"),
+                            font=('微软雅黑', 12, 'bold'),
                             bg='#4CAF50',
                             fg='white',
                             width=15,
                             height=2,
-                            relief=tk.FLAT)
+                            relief=tk.FLAT,
+                            cursor='hand2')
     submit_button.pack(side=tk.RIGHT, padx=10)
     
     # 添加字数统计更新函数
     def update_counts(event=None):
-        summary_count.config(text=f"字数:{len(summary_text.get('1.0', tk.END).strip())}")
-        plan_count.config(text=f"字数:{len(plan_text.get('1.0', tk.END).strip())}")
+        summary_text_content = summary_text.get("1.0", tk.END).strip()
+        plan_text_content = plan_text.get("1.0", tk.END).strip()
+        summary_count.config(text=f"字数:{count_words(summary_text_content)}(中文字符:{count_chinese_chars(summary_text_content)})")
+        plan_count.config(text=f"字数:{count_words(plan_text_content)}(中文字符:{count_chinese_chars(plan_text_content)})")
     
     # 绑定字数统计更新
     summary_text.bind('<KeyRelease>', update_counts)
@@ -163,6 +357,19 @@ def get_user_input():
     y = (root.winfo_screenheight() // 2) - (height // 2)
     root.geometry(f'{width}x{height}+{x}+{y}')
 
+    # 设置窗口最小尺寸
+    root.minsize(900, 700)
+    
+    # 设置窗口关闭确认
+    def on_closing():
+        if messagebox.askokcancel("确认", "确定要关闭窗口吗?"):
+            root.destroy()
+    
+    root.protocol("WM_DELETE_WINDOW", on_closing)
+    
+    # 设置默认焦点
+    prompt_text.focus_set()
+
     root.mainloop()
     return result["summary"], result["plan"], result["is_submitted"], result["keep_original"]