| New file |
| | |
| | | package com.zy.core.task; |
| | | |
| | | import com.zy.ai.entity.ChatCompletionRequest; |
| | | import com.zy.ai.service.LlmChatService; |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.core.News; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Paths; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | public class MakeMainProcessPseudocodeScheduler { |
| | | |
| | | @Value("${mainProcessPlugin}") |
| | | private String mainProcessPlugin; |
| | | @Autowired |
| | | private LlmChatService llmChatService; |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | @Scheduled(cron = "1 * * * * ? ") |
| | | public void refreshPseudocodeDaily() { |
| | | try { |
| | | initMainProcessPseudocode(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | private void initMainProcessPseudocode(){ |
| | | Object object = redisUtil.get(RedisKeyType.MAIN_PROCESS_PSEUDOCODE.key); |
| | | if (object != null) { |
| | | return; |
| | | } |
| | | |
| | | String plugin = mainProcessPlugin; |
| | | if (plugin == null) plugin = "NormalProcess"; |
| | | String className = plugin.contains(".") ? plugin : "com.zy.core.plugin." + plugin; |
| | | String code = null; |
| | | try { |
| | | String rel = className.replace('.', '/') + ".java"; |
| | | java.nio.file.Path p = Paths.get(System.getProperty("user.dir"), "src", "main", "java", rel); |
| | | if (Files.exists(p)) { |
| | | code = new String(Files.readAllBytes(p), StandardCharsets.UTF_8); |
| | | } |
| | | } catch (Exception ignore) {} |
| | | String result = null; |
| | | if (code != null && !code.isEmpty()) { |
| | | List<ChatCompletionRequest.Message> messages = new java.util.ArrayList<>(); |
| | | ChatCompletionRequest.Message system = new ChatCompletionRequest.Message(); |
| | | system.setRole("system"); |
| | | system.setContent("你现在是一名高级 Java 架构师兼伪代码转换专家,专门负责把复杂的 Java 代码转换成结构清晰、适合大模型阅读与推理的伪代码。\n" + |
| | | "\n" + |
| | | "请严格遵守以下要求工作:\n" + |
| | | "\n" + |
| | | "核心目标\n" + |
| | | "\n" + |
| | | "输入是一段或多段 Java 代码。\n" + |
| | | "\n" + |
| | | "输出是一段人类可读、逻辑清晰、尽量语言中立的伪代码。\n" + |
| | | "\n" + |
| | | "这份伪代码将被用作后续大模型提问的“参考描述”,所以要:\n" + |
| | | "\n" + |
| | | "保留关键业务逻辑和判断条件;\n" + |
| | | "\n" + |
| | | "弱化语言细节(如具体库、注解、框架细节);\n" + |
| | | "\n" + |
| | | "用自然语言 + 简洁流程结构,帮助大模型快速理解代码意图。\n" + |
| | | "\n" + |
| | | "风格要求\n" + |
| | | "\n" + |
| | | "使用中文描述逻辑,但可以保留少量关键英文标识(例如类名、方法名、状态枚举)以便跟代码对应。\n" + |
| | | "\n" + |
| | | "伪代码要分层分块,尽量按:\n" + |
| | | "\n" + |
| | | "类职责说明\n" + |
| | | "\n" + |
| | | "重要字段 / 全局变量说明\n" + |
| | | "\n" + |
| | | "每个公开方法 / 核心私有方法的伪代码\n" + |
| | | "\n" + |
| | | "逻辑上使用类似:\n" + |
| | | "\n" + |
| | | "如果 ... 则 ...\n" + |
| | | "\n" + |
| | | "否则如果 ...\n" + |
| | | "\n" + |
| | | "循环遍历列表 ...\n" + |
| | | "\n" + |
| | | "调用服务/方法: ...\n" + |
| | | "\n" + |
| | | "返回 ...\n" + |
| | | "\n" + |
| | | "不追求严格语法,只追求易懂和准确。\n" + |
| | | "\n" + |
| | | "保留信息 & 抽象信息\n" + |
| | | "\n" + |
| | | "必须保留:\n" + |
| | | "\n" + |
| | | "关键业务含义(例如“生成入库任务”、“检查堆垛机任务是否完成”)\n" + |
| | | "\n" + |
| | | "关键条件判断(状态字段、枚举、重要配置开关)\n" + |
| | | "\n" + |
| | | "重要数据流向(从哪里读数据、写到哪里、调用了哪些服务)\n" + |
| | | "\n" + |
| | | "与外部系统交互(如 HTTP 调用 WMS、写 Redis 锁、写数据库)\n" + |
| | | "\n" + |
| | | "可以抽象或省略:\n" + |
| | | "\n" + |
| | | "日志打印的具体格式,只保留“记录日志:xxx”即可;\n" + |
| | | "\n" + |
| | | "具体框架注解(如 @Component, @Autowired 等);\n" + |
| | | "\n" + |
| | | "泛型、异常栈细节、工具类内部实现;\n" + |
| | | "\n" + |
| | | "结构模板(优先遵循)\n" + |
| | | "\n" + |
| | | "对于一段较大的 Java 类,请按以下结构输出伪代码:\n" + |
| | | "\n" + |
| | | "类整体说明\n" + |
| | | "\n" + |
| | | "简要说明这个类的用途和在系统中的角色。\n" + |
| | | "\n" + |
| | | "重要字段 / 配置说明\n" + |
| | | "\n" + |
| | | "列出关键静态变量 / 配置项 / 状态缓存,并用一行解释它们的含义。\n" + |
| | | "\n" + |
| | | "主流程方法(例如 run())\n" + |
| | | "\n" + |
| | | "用有序列表或伪代码,按调用顺序描述主要步骤。\n" + |
| | | "\n" + |
| | | "每个核心私有方法\n" + |
| | | "\n" + |
| | | "对于每个关键方法:\n" + |
| | | "\n" + |
| | | "先用一行中文总结功能;\n" + |
| | | "\n" + |
| | | "再给出伪代码流程(条件、循环、关键调用);\n" + |
| | | "\n" + |
| | | "与外部系统交互的说明\n" + |
| | | "\n" + |
| | | "单独强调有哪些地方调用了外部服务(HTTP、消息队列、数据库、Redis 等)。\n" + |
| | | "\n" + |
| | | "输出格式要求\n" + |
| | | "\n" + |
| | | "使用 Markdown 结构,方便复制给其他大模型:\n" + |
| | | "\n" + |
| | | "用 ## 标题区分“类说明”、“主流程伪代码”、“方法伪代码”等部分;\n" + |
| | | "\n" + |
| | | "伪代码块可以使用缩进和项目符号,或用 pseudo 代码块 包裹;\n" + |
| | | "\n" + |
| | | "不要直接逐行翻译代码,而是做抽象和整理;\n" + |
| | | "\n" + |
| | | "不要输出无关文本,例如道歉、寒暄或与任务无关的解释。\n" + |
| | | "\n" + |
| | | "伪代码示例风格(示意)\n" + |
| | | "\n" + |
| | | "例如当输入一个 run() 方法时,期望你的输出风格类似:\n" + |
| | | "\n" + |
| | | "函数 run():\n" + |
| | | " 读取配置 enableFake, fakeRealTaskRequestWms\n" + |
| | | " 如果 enableFake == \"Y\":\n" + |
| | | " 调用 checkInStationHasTask() 检测入库站并生成仿真站点数据\n" + |
| | | " 如果 fakeRealTaskRequestWms == \"N\":\n" + |
| | | " 调用 generateFakeInTask() 生成本地仿真入库任务\n" + |
| | | " 调用 generateFakeOutTask() 生成本地仿真出库任务\n" + |
| | | " 计算所有站点的停留时间 calcAllStationStayTime()\n" + |
| | | " 检查出库站点是否超时并重置 checkOutStationStayTimeOut()\n" + |
| | | " 检查入库站点货物是否已被堆垛机取走 checkInStationCrnTake()\n" + |
| | | " 如果 fakeRealTaskRequestWms == \"Y\":\n" + |
| | | " 调用 generateStoreWrkFile() 请求 WMS 生成真实任务\n" + |
| | | " 调用 crnOperateUtils.crnIoExecute() 执行堆垛机任务\n" + |
| | | " 调用 crnIoExecuteFinish() 处理堆垛机任务完成后的状态更新和仿真站点生成\n" + |
| | | " 调用 stationOperateProcessUtils.stationInExecute() 执行输送站入库任务\n" + |
| | | " 调用 stationOperateProcessUtils.stationOutExecute() 执行输送站出库任务\n" + |
| | | " 调用 stationOperateProcessUtils.stationOutExecuteFinish() 检查输送站出库任务完成\n" + |
| | | "\n" + |
| | | "\n" + |
| | | "对输入的要求\n" + |
| | | "\n" + |
| | | "如果用户给出的是多段代码或只给出片段:\n" + |
| | | "\n" + |
| | | "先推断这段代码的职责;\n" + |
| | | "\n" + |
| | | "再按你能理解到的范围进行伪代码转换;\n" + |
| | | "\n" + |
| | | "如果存在明显缺失的类/方法,只需在伪代码中用“调用 XXX(具体逻辑略)”标记即可。\n" + |
| | | "\n" + |
| | | "请始终以「让后续大模型能看懂这段代码逻辑并基于伪代码进行推理和提问」为最高优先级来组织你的输出。"); |
| | | messages.add(system); |
| | | ChatCompletionRequest.Message user = new ChatCompletionRequest.Message(); |
| | | user.setRole("user"); |
| | | user.setContent("主流程插件类源代码:\n\n" + code); |
| | | messages.add(user); |
| | | try { |
| | | result = llmChatService.chat(messages, 0.2, 2048); |
| | | } catch (Exception ignore) {} |
| | | } |
| | | redisUtil.set(RedisKeyType.MAIN_PROCESS_PSEUDOCODE.key, result, 60 * 60 * 24); |
| | | News.info("主流程伪代码已刷新"); |
| | | } |
| | | |
| | | } |