diff --git a/data/html/wechat.html b/data/html/wechat.html index 46ce0c2..399c468 100644 --- a/data/html/wechat.html +++ b/data/html/wechat.html @@ -1,2 +1,22 @@ -微信公众号文章

项目描述

视频演示

本系统包含管理员和用户两个角色。

管理员角色:

  1. 轮播图管理:管理轮播图的配置参数,包括新增、查看、修改和删除轮播图。

  2. 用户管理:管理系统中所有用户的信息,包括新增、查看、修改和删除用户。

  3. 资源分类管理:管理资源的分类信息,包括新增、查看、修改和删除资源分类。

  4. 资源分享区管理:管理资源分享区的帖子,包括新增、查看、修改和删除帖子。

  5. 资源信息管理:管理资源信息,包括查看、修改、删除和查看评论。

  6. 系统公告管理:管理系统公告,包括新增、查看、修改和删除公告。

用户角色:

  1. 我的收藏管理:管理用户的收藏信息,包括查看和删除收藏。

  2. 资源信息管理:管理用户发布的资源信息,包括新增、查看、修改、删除和查看评论。

  3. 资源分享区管理:管理用户在资源分享区发布的帖子,包括新增、查看、修改和删除帖子。

  4. 个人信息管理:管理用户的个人信息,包括账号、姓名、性别、手机、邮箱等。

技术选型

系统截图

1.后台登录

 

2.后台首页

 

3.轮播图管理

 

4.用户管理

 

5.资源分类管理

 

6.资源分享区管理

 

7.资源信息管理

 

8.系统公告管理

 

9.首页

 

10.资源信息

 

11.系统公告

 

12.资源分享区

运行步骤

准备环境

安装JDK 1.8、Maven、Node.js 14 和 MySQL 5.7以上

创建数据库

使用Navicat工具创建数据库并导入SQL脚本

配置后端

修改application.yml中的数据库连接信息(用户名/密码/库名)

启动后端服务

进入后端项目(/server_code) 执行:
mvn clean install - mvn spring-boot:run

前端依赖安装

进入前端目录(/manage_code或者/client_code),执行安装命令:
npm install

启动前端服务

执行启动命令:
npm run serve

访问系统

常见问题

端口冲突

前端安装依赖失败

推荐阅读

其他说明

源码获取


长按小程序码,打开小程序搜索 "A177" 即可获取资源
+微信公众号文章

项目描述

视频演示

本系统包含管理员、学生、维修员三个角色。
+管理员角色:
+1. 用户管理:管理系统中所有用户的信息,包括添加、删除和修改用户。
+2. 配置管理:管理系统配置参数,如上传图片的路径等。
+3. 权限管理:分配和管理不同角色的权限。
+4. 宿舍管理:管理宿舍信息,包括宿舍房号、类型、床位数量等。
+5. 报修管理:管理报修信息、报修处理、结果反馈、维修报修、报修分配等。
+6. 公告管理:管理公告信息,包括标题、简介、图片、内容等。
+7. 论坛管理:管理论坛交流信息,包括帖子标题、内容、用户名等。
+8. 轮播图管理:管理轮播图信息,包括配置参数名称、值等。
+学生角色:
+1. 报修信息申报:学生可以申报报修信息,填写宿舍房号、报修编号、报修物品等信息,并上传相关附件。
+2. 论坛交流:学生可以发布和查看论坛帖子,包括帖子标题、内容、用户名等。
+3. 个人信息管理:学生可以管理自己的个人信息,包括学号、姓名、性别、宿舍号、联系方式等。
+维修员角色:
+1. 报修信息处理:维修员可以查看和处理报修信息,包括报修物品、报修时间等。
+2. 报修处理:维修员可以处理报修信息,填写处理时间等。
+3. 结果反馈:维修员可以反馈报修处理结果,包括图片、结果反馈等。
+4. 维修报修:维修员可以查看和统计维修报修信息,包括报修物品、报修时间等。
+5. 报修分配:维修员可以查看和处理报修分配信息,包括宿舍房号、报修编号、报修物品等。
+6. 个人信息管理:维修员可以管理自己的个人信息,包括维修员账号、姓名、性别、联系方式等。

技术选型

系统截图

1.首页

 

2.论坛交流

 

3.公告信息

 

4.后台登录

 

5.管理员管理

 

6.学生管理

 

7.维修员管理

 

8.宿舍信息管理

 

9.结果反馈管理

 

10.公告信息管理

 

11.论坛交流管理

 

12.轮播图管理

运行步骤

准备环境

安装JDK 1.8、Maven、Node.js 14 和 MySQL 5.7以上

创建数据库

使用Navicat工具创建数据库并导入SQL脚本

配置后端

修改application.yml中的数据库连接信息(用户名/密码/库名)

启动后端服务

进入后端项目(/server_code) 执行:
mvn clean install + mvn spring-boot:run

前端依赖安装

进入前端目录(/manage_code或者/client_code),执行安装命令:
npm install

启动前端服务

执行启动命令:
npm run serve

访问系统

常见问题

端口冲突

前端安装依赖失败

推荐阅读

其他说明

源码获取


长按小程序码,打开小程序搜索 "A167" 即可获取资源
diff --git a/gui.py b/gui.py index e8e8352..fabe446 100644 --- a/gui.py +++ b/gui.py @@ -5,6 +5,7 @@ from tkinter import ttk, messagebox, scrolledtext import threading import sys import os +import subprocess # 添加当前目录到路径 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) @@ -137,6 +138,14 @@ class YidaimaGUI: # 刷新按钮 ttk.Button(scheme_frame, text="刷新", command=self.refresh_css_schemes, width=8).grid(row=0, column=1, padx=(5, 0)) + # 调用API方式选项 + self.use_api_var = tk.BooleanVar(value=False) + ttk.Checkbutton( + config_frame, + text="调用API方式 (跳过浏览器自动化,直接调用API获取文章内容)", + variable=self.use_api_var + ).grid(row=2, column=0, columnspan=2, sticky=tk.W, pady=(10, 0)) + # === 操作按钮区域 === button_frame = ttk.Frame(self.tab_publish) button_frame.grid(row=1, column=0, pady=(10, 10)) @@ -414,25 +423,62 @@ class YidaimaGUI: self.root.after(0, lambda: self.log("=" * 50)) self.root.after(0, lambda: self.log("开始运行完整流程...")) self.root.after(0, lambda: self.log("=" * 50)) - + # 获取配置(从配置文件读取) chrome_path = self.config.get("chrome.path", "") username = self.config.get("step1.username", "") password = self.config.get("step1.password", "") project_name = self.project_name_var.get() - + use_api = self.use_api_var.get() + # Step 1 self.root.after(0, lambda: self.log("\n[Step 1] 开始执行...")) - - # 定义日志回调函数,将 step1 的日志输出到 GUI - def step1_log_callback(message: str): - self.root.after(0, lambda msg=message: self.log(msg)) - - step1 = Step1FeastCoding(chrome_path, username, password, log_callback=step1_log_callback) - step1.project_name = project_name # 设置项目名称 - step1.run() + + if use_api: + # API 方式获取内容 + self.root.after(0, lambda: self.log("[Step 1] 使用 API 方式获取文章内容...")) + import requests + import re + # 从项目名称中提取编号,如"【A167】" -> "A167" + match = re.search(r'【(.+?)】', project_name) + code_name = match.group(1) if match else project_name + api_url = "https://feast.yidaima.cn/prod-api/office/copyTemplate/open/generate" + params = { + "templateName": "FeastCoding", + "codeName": code_name + } + try: + response = requests.get(api_url, params=params, timeout=30) + response.raise_for_status() + json_data = response.json() + # 从 JSON 中提取 msg 字段内容 + content = json_data.get("msg", "") + # 将 \\n 替换为空行 + content = content.replace("\\n", "\n") + # 设置剪贴板内容 + subprocess.run( + ["powershell", "-command", f"Set-Clipboard -Value '{content.replace(chr(39), chr(39)+chr(39))}'"], + capture_output=True + ) + self.root.after(0, lambda: self.log(f"[Step 1] API 调用成功,已复制到剪贴板,内容长度: {len(content)} 字符")) + except Exception as e: + self.root.after(0, lambda: self.log(f"[Step 1] API 调用失败: {e}")) + raise + else: + # 浏览器方式 + self.root.after(0, lambda: self.log("[Step 1] 使用浏览器方式获取文章内容...")) + + # 定义日志回调函数,将 step1 的日志输出到 GUI + def step1_log_callback(message: str): + self.root.after(0, lambda msg=message: self.log(msg)) + + step1 = Step1FeastCoding(chrome_path, username, password, log_callback=step1_log_callback) + step1.project_name = project_name # 设置项目名称 + step1.run() + self.root.after(0, lambda: self.log("[Step 1] 浏览器方式执行完成!")) + self.root.after(0, lambda: self.log("[Step 1] 执行完成!")) - + # Step 2 self.root.after(0, lambda: self.log("\n[Step 2] 开始执行...")) @@ -444,15 +490,15 @@ class YidaimaGUI: scheme_name = self.css_scheme_var.get() css_scheme_id = self._get_scheme_id_by_name(scheme_name) - step2 = Step2Converter(log_callback=log_callback, css_scheme_id=css_scheme_id) + step2 = Step2Converter(log_callback=log_callback, css_scheme_id=css_scheme_id, project_name=project_name) step2.run() self.root.after(0, lambda: self.log("[Step 2] 执行完成!")) - + self.root.after(0, lambda: self.log("\n" + "=" * 50)) self.root.after(0, lambda: self.log("完整流程执行成功!")) self.root.after(0, lambda: self.log("=" * 50)) self.root.after(0, lambda: messagebox.showinfo("成功", "完整流程执行成功!")) - + except Exception as e: error_msg = str(e) self.root.after(0, lambda: self.log(f"\n[ERROR] {error_msg}")) diff --git a/step2.py b/step2.py index a0624b2..fae968a 100644 --- a/step2.py +++ b/step2.py @@ -37,16 +37,18 @@ class Step2Converter: 参考: docs/step2.md """ - def __init__(self, log_callback: Optional[Callable[[str], None]] = None, css_scheme_id: Optional[str] = None): + def __init__(self, log_callback: Optional[Callable[[str], None]] = None, css_scheme_id: Optional[str] = None, project_name: Optional[str] = None): """ 初始化 Step2Converter - + Args: log_callback: 日志回调函数,用于将日志输出到 GUI css_scheme_id: CSS 样式方案 ID,可选 + project_name: 项目名称,可选,用于生成文章标题 """ self.log_callback = log_callback self.css_scheme_id = css_scheme_id + self.project_name = project_name self.theme_manager = ThemeManager() def _log(self, message: str): @@ -84,12 +86,22 @@ class Step2Converter: # 创建编辑器实例,它会自动加载当前配置(包括已应用的 CSS 方案) editor = WechatMarkdownEditor() html_content = editor.render(md_content) - + # 提取标题(从 HTML 内容中提取 h1 标签) import re title_match = re.search(r']*>(.*?)', html_content) title = title_match.group(1) if title_match else "无标题" + # 如果提供了项目名称,使用项目名称去掉编号作为标题,并添加作者 + if self.project_name: + # 去掉编号,如"【A167】xxx" -> "xxx" + match = re.search(r'】(.+)', self.project_name) + if match: + title = match.group(1) + else: + title = self.project_name + # 添加作者 - 通过 publish_to_wechat 传入 + html_content = re.sub(r'\n\s*\n+', '\n', html_content) html_content = re.sub(r'>\s*\n\s*<', '><', html_content) @@ -134,7 +146,8 @@ class Step2Converter: content=html_content, appid=wechat_appid, appsecret=wechat_appsecret, - thumb_image_url=cover_image_url + thumb_image_url=cover_image_url, + author="南音" ) else: # 使用默认封面图片 @@ -145,7 +158,8 @@ class Step2Converter: content=html_content, appid=wechat_appid, appsecret=wechat_appsecret, - thumb_image_path=thumb_path + thumb_image_path=thumb_path, + author="南音" ) if success: self._log("[Step2] 公众号草稿推送成功!") diff --git a/wechat_publisher.py b/wechat_publisher.py index bc437dc..d9082e8 100644 --- a/wechat_publisher.py +++ b/wechat_publisher.py @@ -184,7 +184,8 @@ def publish_to_wechat( appid: str, appsecret: str, thumb_image_path: Optional[str] = None, - thumb_image_url: Optional[str] = None + thumb_image_url: Optional[str] = None, + author: str = "" ) -> bool: """ 便捷函数:发布文章到微信公众号草稿箱 @@ -196,6 +197,7 @@ def publish_to_wechat( appsecret: 微信公众号 AppSecret thumb_image_path: 封面图片本地路径(可选,与 thumb_image_url 二选一) thumb_image_url: 封面图片URL(可选,与 thumb_image_path 二选一) + author: 作者 Returns: 是否成功 @@ -219,7 +221,8 @@ def publish_to_wechat( result = publisher.add_draft( title=title, content=content, - thumb_media_id=thumb_media_id + thumb_media_id=thumb_media_id, + author=author ) print(f"[WeChat] 草稿添加成功,media_id: {result.get('media_id')}")