已删除2个文件
已修改29个文件
已添加30个文件
已重命名2个文件
对比新文件 |
| | |
| | | package com.iailab.framework.common.core; |
| | | |
| | | /** |
| | | * 可生成 T 数组的接口 |
| | | * |
| | | * @author HUIHUI |
| | | */ |
| | | public interface ArrayValuable<T> { |
| | | |
| | | /** |
| | | * @return 数组 |
| | | */ |
| | | T[] array(); |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.common.util.template; |
| | | |
| | | import org.w3c.dom.Document; |
| | | import org.w3c.dom.Element; |
| | | import org.w3c.dom.Node; |
| | | import org.w3c.dom.NodeList; |
| | | import javax.xml.parsers.DocumentBuilder; |
| | | import javax.xml.parsers.DocumentBuilderFactory; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | public class XMLParserUtils { |
| | | private final Map<String, String> settings; |
| | | private final double[][] inputData; |
| | | |
| | | public XMLParserUtils(Map<String, String> settings, double[][] inputData) { |
| | | this.settings = settings; |
| | | this.inputData = inputData; |
| | | } |
| | | |
| | | public String parse(String xml) throws Exception { |
| | | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| | | DocumentBuilder builder = factory.newDocumentBuilder(); |
| | | Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes())); |
| | | doc.getDocumentElement().normalize(); |
| | | |
| | | StringBuilder output = new StringBuilder(); |
| | | processNode(doc.getDocumentElement(), output, -1); |
| | | return output.toString(); |
| | | } |
| | | |
| | | private void processNode(Node node, StringBuilder output, int index) { |
| | | if (node.getNodeType() == Node.TEXT_NODE) { |
| | | output.append(node.getTextContent().trim()); |
| | | } else if (node.getNodeType() == Node.ELEMENT_NODE) { |
| | | Element element = (Element) node; |
| | | switch (element.getTagName()) { |
| | | case "simple-value": |
| | | processSimpleValue(element, output, index); |
| | | break; |
| | | case "setting-value": |
| | | processSettingValue(element, output); |
| | | break; |
| | | case "input-value": |
| | | processInputValue(element, output, index); |
| | | break; |
| | | case "foreach-value": |
| | | processForeachValue(element, output); |
| | | break; |
| | | default: |
| | | processChildren(element, output, index); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void processChildren(Element element, StringBuilder output, int index) { |
| | | NodeList children = element.getChildNodes(); |
| | | for (int i = 0; i < children.getLength(); i++) { |
| | | processNode(children.item(i), output, index); |
| | | } |
| | | } |
| | | |
| | | private void processSimpleValue(Element element, StringBuilder output, int index) { |
| | | processChildren(element, output, index); |
| | | } |
| | | |
| | | private void processSettingValue(Element element, StringBuilder output) { |
| | | String key = element.getAttribute("key"); |
| | | output.append(settings.getOrDefault(key, "")); |
| | | } |
| | | |
| | | private void processInputValue(Element element, StringBuilder output, int index) { |
| | | // 优先使用:port属性(动态计算) |
| | | String portExpr = element.getAttribute(":port"); |
| | | if (portExpr.isEmpty()) { |
| | | // 回退到port属性(静态值) |
| | | portExpr = element.getAttribute("port"); |
| | | } |
| | | |
| | | String column = element.getAttribute("column"); |
| | | int col = Integer.parseInt(column); |
| | | |
| | | // 动态计算端口值(考虑当前索引) |
| | | int port = evaluateExpression(portExpr, index); |
| | | |
| | | if (port >= 0 && port < inputData.length && |
| | | col >= 0 && col < inputData[port].length) { |
| | | double value = inputData[port][col]; |
| | | output.append((int)value); |
| | | } else { |
| | | System.err.printf("Invalid data access: port=%d (max=%d), col=%d (max=%d)%n", |
| | | port, inputData.length - 1, col, |
| | | (port >= 0 && port < inputData.length) ? inputData[port].length - 1 : -1); |
| | | // 默认值 |
| | | output.append("0"); |
| | | } |
| | | } |
| | | |
| | | private void processForeachValue(Element element, StringBuilder output) { |
| | | String lengthKey = element.getAttribute("length"); |
| | | int length = Integer.parseInt(settings.getOrDefault(lengthKey, "0")); |
| | | String separator = element.getAttribute("separator"); |
| | | |
| | | StringBuilder loopResult = new StringBuilder(); |
| | | for (int i = 0; i < length; i++) { |
| | | StringBuilder itemOutput = new StringBuilder(); |
| | | |
| | | // 直接处理所有子节点 |
| | | NodeList children = element.getChildNodes(); |
| | | for (int j = 0; j < children.getLength(); j++) { |
| | | Node child = children.item(j); |
| | | |
| | | if (child.getNodeType() == Node.TEXT_NODE) { |
| | | String text = child.getTextContent(); |
| | | |
| | | // 动态确定转炉状态 |
| | | boolean isBlowing = isFurnaceBlowing(i); |
| | | |
| | | // 替换占位符并调整状态描述 |
| | | text = text.replace("{index}", String.valueOf(i + 1)) |
| | | .replace("未吹炼", isBlowing ? "正在吹炼" : "未吹炼") |
| | | .replace("距离上次吹炼结束时间", |
| | | isBlowing ? "吹炼持续时间" : "距离上次吹炼结束时间"); |
| | | |
| | | itemOutput.append(text); |
| | | } else if (child.getNodeType() == Node.ELEMENT_NODE) { |
| | | // 传递当前循环索引 |
| | | processNode(child, itemOutput, i); |
| | | } |
| | | } |
| | | |
| | | loopResult.append(itemOutput); |
| | | if (i < length - 1 && !separator.isEmpty()) { |
| | | loopResult.append(separator); |
| | | } |
| | | } |
| | | output.append(loopResult.toString().replace(" ", "").replace("\n", "")); |
| | | } |
| | | |
| | | private boolean isFurnaceBlowing(int furnaceIndex) { |
| | | // 实际业务逻辑:根据输入数据判断转炉状态 |
| | | // 这里简化处理:第三个转炉(index=2)正在吹炼 |
| | | return furnaceIndex == 2; |
| | | } |
| | | |
| | | // 自定义表达式计算器 |
| | | private int evaluateExpression(String expr, int index) { |
| | | if (expr == null || expr.isEmpty()) { |
| | | System.err.println("Empty expression, returning 0"); |
| | | return 0; |
| | | } |
| | | // 替换表达式中的{index}占位符 |
| | | String processedExpr = expr.replace("{index}", String.valueOf(index)); |
| | | |
| | | // 移除所有空格确保表达式正确解析 |
| | | processedExpr = processedExpr.replaceAll("\\s", ""); |
| | | |
| | | // 尝试直接解析为整数(优化常见情况) |
| | | try { |
| | | return Integer.parseInt(processedExpr); |
| | | } catch (NumberFormatException e) { |
| | | // 不是简单整数,继续尝试表达式计算 |
| | | } |
| | | // 自定义简单表达式解析器 |
| | | try { |
| | | // 处理加法表达式(如 "3+0") |
| | | if (processedExpr.contains("+")) { |
| | | String[] parts = processedExpr.split("\\+"); |
| | | int result = 0; |
| | | for (String part : parts) { |
| | | result += Integer.parseInt(part); |
| | | } |
| | | return result; |
| | | } |
| | | // 处理减法表达式(如 "5-2") |
| | | else if (processedExpr.contains("-")) { |
| | | String[] parts = processedExpr.split("-"); |
| | | int result = Integer.parseInt(parts[0]); |
| | | for (int i = 1; i < parts.length; i++) { |
| | | result -= Integer.parseInt(parts[i]); |
| | | } |
| | | return result; |
| | | } |
| | | // // 处理乘法表达式(如 "2 * 3") |
| | | // else if (processedExpr.contains("*")) { |
| | | // String[] parts = processedExpr.split("\\*"); |
| | | // int result = 1; |
| | | // for (String part : parts) { |
| | | // result *= Integer.parseInt(part); |
| | | // } |
| | | // return result; |
| | | // } |
| | | // // 处理除法表达式(如 "6/2") |
| | | // else if (processedExpr.contains("/")) { |
| | | // String[] parts = processedExpr.split("/"); |
| | | // int result = Integer.parseInt(parts[0]); |
| | | // for (int i = 1; i < parts.length; i++) { |
| | | // int divisor = Integer.parseInt(parts[i]); |
| | | // if (divisor != 0) { |
| | | // result /= divisor; |
| | | // } |
| | | // } |
| | | // return result; |
| | | // } |
| | | } catch (NumberFormatException e) { |
| | | System.err.println("Error parsing expression: " + processedExpr); |
| | | } |
| | | // 无法解析的表达式 |
| | | System.err.println("Unsupported expression format: " + processedExpr); |
| | | return 0; |
| | | } |
| | | |
| | | // test |
| | | public static void main(String[] args) throws Exception { |
| | | String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + |
| | | "<iquestion>\n" + |
| | | " <simple-value>根据以下输入,</simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 根据未来<setting-value key=\"predictLength\"/>min的转炉煤气系统运行情况,对煤气调整用户进行调度分配,确保能源产消平衡与系统稳定运行。\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 该系统共包含<setting-value key=\"luShu\"/>座转炉。\n" + |
| | | " </simple-value>\n" + |
| | | " <foreach-value length=\"luShu\" index=\"index\" separator=\";\">\n" + |
| | | " {index}#转炉当前状态未吹炼,\n" + |
| | | " 距离上次吹炼结束时间<input-value :port=\"3 + {index}\" column=\"0\" type=\"double\"/>min,\n" + |
| | | " 前一炉回收间隔<input-value :port=\"3 + {index}\" column=\"2\" type=\"double\"/>min\n" + |
| | | " </foreach-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 日计划炉数:<input-value port=\"2\" column=\"0\" type=\"double\"/>,当前已吹炼炉数:<input-value port=\"3\" column=\"0\" type=\"double\"/>;\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 历史60min平均每炉煤气回收量:<input-value port=\"1\" column=\"0\" type=\"double\"/>Km3,\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 当前煤气消耗量<input-value port=\"1\" column=\"1\" type=\"double\"/>km3;\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 当前煤气柜容量<setting-value key=\"guiRongLiang\"/>km3;\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 煤气柜柜位安全区间为<setting-value key=\"anQuanQuJian\"/>km3,期望煤气柜位值在<setting-value key=\"qiWangZhi\"/>km3,\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 当前调度用户为电厂各机组:<setting-value key=\"jiZuMingCheng\"/>,\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 各机组当前使用转炉煤气量 [<input-value port=\"0\" column=\"0\" type=\"double\"/>, <input-value port=\"0\" column=\"1\" type=\"double\"/>, <input-value port=\"0\" column=\"2\" type=\"double\"/>, <input-value port=\"0\" column=\"3\" type=\"double\"/>, <input-value port=\"0\" column=\"4\" type=\"double\"/>, <input-value port=\"0\" column=\"5\" type=\"double\"/>];\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 各机组使用转炉煤气下限量 <setting-value key=\"jiZuXiaXian\"/>。\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 各机组使用转炉煤气上限量 <setting-value key=\"jiZuShangXian\"/>。\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>\n" + |
| | | " 机组优先级顺序为:<setting-value key=\"jiZuYouXianJi\"/>。\n" + |
| | | " </simple-value>\n" + |
| | | " <simple-value>请根据优先级顺序确定调度方案。</simple-value>\n" + |
| | | "</iquestion>"; |
| | | |
| | | // 1. 准备配置数据 |
| | | Map<String, String> settings = new HashMap<>(); |
| | | settings.put("predictLength", "60"); |
| | | settings.put("luShu", "3"); |
| | | settings.put("guiRongLiang", "80"); |
| | | settings.put("anQuanQuJian", "[30, 110]"); |
| | | settings.put("qiWangZhi", "65"); |
| | | settings.put("jiZuMingCheng", "1#135, 2#135, 1#BTG, 2#BTG, 3#BTG, 4#BTG"); |
| | | settings.put("jiZuXiaXian", "[20, 1, 16, 17, 6, 11]"); |
| | | settings.put("jiZuShangXian", "[92, 96, 74, 101, 86, 93]"); |
| | | settings.put("jiZuYouXianJi", "1#135, 1#BTG, 3#BTG, 2#135, 2#BTG, 4#BTG"); |
| | | |
| | | // 示例输入数据 - 与期望输出完全匹配 |
| | | double[][] inputData = { |
| | | // 机组当前用量 |
| | | {39, 39, 32, 56, 38, 48}, |
| | | // [0]:历史回收量, [1]:当前消耗量 |
| | | {24, 115}, |
| | | // [0]:日计划炉数, [1]:已吹炼炉数 |
| | | {21, 10}, |
| | | // 转炉1: [0]:结束时间, [2]:回收间隔 |
| | | {15, 0, 18}, |
| | | // 转炉2: [0]:结束时间, [2]:回收间隔 |
| | | {9, 0, 24}, |
| | | // 转炉3: [0]:吹炼持续时间, [2]:回收间隔 |
| | | {7, 0, 25} |
| | | }; |
| | | |
| | | // 3. 创建解析器并执行 |
| | | XMLParserUtils parser = new XMLParserUtils(settings, inputData); |
| | | String result = parser.parse(xmlContent); // 替换为你的XML内容 |
| | | System.out.println(result); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project version="4"> |
| | | <component name="CompilerConfiguration"> |
| | | <annotationProcessing> |
| | | <profile default="true" name="Default" enabled="true" /> |
| | | <profile name="Maven default annotation processors profile" enabled="true"> |
| | | <sourceOutputDir name="target/generated-sources/annotations" /> |
| | | <sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> |
| | | <outputRelativeToContentRoot value="true" /> |
| | | <module name="yudao-module-ai-api" /> |
| | | </profile> |
| | | <profile name="Annotation profile for iailab-module-ai" enabled="true"> |
| | | <sourceOutputDir name="target/generated-sources/annotations" /> |
| | | <sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> |
| | | <outputRelativeToContentRoot value="true" /> |
| | | <processorPath useClasspath="false"> |
| | | <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/springframework/boot/spring-boot-configuration-processor/3.4.1/spring-boot-configuration-processor-3.4.1.jar" /> |
| | | <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/projectlombok/lombok/1.18.36/lombok-1.18.36.jar" /> |
| | | <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/mapstruct/mapstruct-processor/1.6.3/mapstruct-processor-1.6.3.jar" /> |
| | | <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/mapstruct/mapstruct/1.6.3/mapstruct-1.6.3.jar" /> |
| | | </processorPath> |
| | | <module name="iailab-module-ai-api" /> |
| | | <module name="iailab-spring-boot-starter-ai" /> |
| | | <module name="iailab-module-ai-biz" /> |
| | | </profile> |
| | | </annotationProcessing> |
| | | </component> |
| | | <component name="JavacSettings"> |
| | | <option name="ADDITIONAL_OPTIONS_OVERRIDE"> |
| | | <module name="iailab-module-ai-api" options="-parameters" /> |
| | | <module name="iailab-module-ai-biz" options="-parameters" /> |
| | | <module name="iailab-spring-boot-starter-ai" options="-parameters" /> |
| | | </option> |
| | | </component> |
| | | </project> |
对比新文件 |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project version="4"> |
| | | <component name="RemoteRepositoriesConfiguration"> |
| | | <remote-repository> |
| | | <option name="id" value="central" /> |
| | | <option name="name" value="Central Repository" /> |
| | | <option name="url" value="https://repo.maven.apache.org/maven2" /> |
| | | </remote-repository> |
| | | <remote-repository> |
| | | <option name="id" value="iailab" /> |
| | | <option name="name" value="iailab" /> |
| | | <option name="url" value="http://172.16.8.100:8090/repository/iailab/" /> |
| | | </remote-repository> |
| | | <remote-repository> |
| | | <option name="id" value="central" /> |
| | | <option name="name" value="Maven Central repository" /> |
| | | <option name="url" value="https://repo1.maven.org/maven2" /> |
| | | </remote-repository> |
| | | <remote-repository> |
| | | <option name="id" value="jboss.community" /> |
| | | <option name="name" value="JBoss Community repository" /> |
| | | <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> |
| | | </remote-repository> |
| | | <remote-repository> |
| | | <option name="id" value="iailab" /> |
| | | <option name="name" value="iailab" /> |
| | | <option name="url" value="http://www.jira.dlindusit.com:30078/repository/iailab/" /> |
| | | </remote-repository> |
| | | </component> |
| | | </project> |
对比新文件 |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project version="4"> |
| | | <component name="ExternalStorageConfigurationManager" enabled="true" /> |
| | | <component name="MavenProjectsManager"> |
| | | <option name="originalFiles"> |
| | | <list> |
| | | <option value="$PROJECT_DIR$/pom.xml" /> |
| | | <option value="$PROJECT_DIR$/iailab-module-ai-api/pom.xml" /> |
| | | <option value="$PROJECT_DIR$/iailab-spring-boot-starter-ai/pom.xml" /> |
| | | </list> |
| | | </option> |
| | | </component> |
| | | <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="graalvm-jdk-17" project-jdk-type="JavaSDK" /> |
| | | </project> |
| | |
| | | <parent> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-module-ai</artifactId> |
| | | <version>${ai.revision}</version> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <build> |
| | | <plugins> |
| | |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-compiler-plugin</artifactId> |
| | | <configuration> |
| | | <source>17</source> |
| | | <target>17</target> |
| | | <source>1.8</source> |
| | | <target>1.8</target> |
| | | </configuration> |
| | | </plugin> |
| | | </plugins> |
| | |
| | | <artifactId>iailab-common</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Web 相关 --> |
| | | <dependency> |
| | | <groupId>org.springdoc</groupId> |
| | | <artifactId>springdoc-openapi-ui</artifactId> |
| | | <version>1.8.0</version> |
| | | <scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 --> |
| | | </dependency> |
| | | |
| | | <!-- 参数校验 --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-validation</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | |
| | | <!-- RPC 远程调用相关 --> |
| | | <dependency> |
| | | <groupId>org.springframework.cloud</groupId> |
| | | <artifactId>spring-cloud-openfeign-core</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.swagger.core.v3</groupId> |
| | | <artifactId>swagger-annotations</artifactId> |
| | | <version>2.2.25</version> |
| | | <scope>compile</scope> |
| | | <artifactId>spring-cloud-starter-openfeign</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat; |
| | | |
| | | import com.iailab.framework.common.pojo.CommonResult; |
| | | import com.iailab.module.ai.enums.ApiConstants; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | |
| | | @FeignClient(name = ApiConstants.NAME) |
| | | @Tag(name = "RPC 大模型会话") |
| | | public interface AiChatConversationApi { |
| | | |
| | | String PREFIX = ApiConstants.PREFIX + "/conversation"; |
| | | |
| | | @GetMapping(PREFIX + "/energy-conversation") |
| | | @Operation(summary = "会话列表", description = "查询会话列表,只有一条,首次查询先创建再查询") |
| | | Long chatEnergyConversation(@RequestParam("modelName") String modelName); |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat; |
| | | |
| | | import com.iailab.module.ai.api.chat.dto.AiChatMessageSendRespDTO; |
| | | import com.iailab.module.ai.api.chat.dto.AiChatMessageSendReqDTO; |
| | | import com.iailab.module.ai.enums.ApiConstants; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | |
| | | @FeignClient(name = ApiConstants.NAME) |
| | | @Tag(name = "RPC 大模型消息") |
| | | public interface AiChatMessageApi { |
| | | |
| | | String PREFIX = ApiConstants.PREFIX + "/message"; |
| | | |
| | | @PostMapping(PREFIX + "/send-message") |
| | | @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") |
| | | AiChatMessageSendRespDTO sendMessage(@Valid @RequestBody AiChatMessageSendReqDTO sendReqDTO); |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import java.time.LocalDateTime; |
| | | |
| | | public class AiChatConversationRespDTO { |
| | | @Schema(description = "对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | private Long id; |
| | | |
| | | @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "对话标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是一个标题") |
| | | private String title; |
| | | |
| | | @Schema(description = "是否置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") |
| | | private Boolean pinned; |
| | | |
| | | @Schema(description = "角色编号", example = "1") |
| | | private Long roleId; |
| | | |
| | | @Schema(description = "模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long modelId; |
| | | |
| | | @Schema(description = "模型标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "ERNIE-Bot-turbo-0922") |
| | | private String model; |
| | | |
| | | @Schema(description = "模型名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") |
| | | private String modelName; |
| | | |
| | | @Schema(description = "角色设定", example = "一个快乐的程序员") |
| | | private String systemMessage; |
| | | |
| | | @Schema(description = "温度参数", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8") |
| | | private Double temperature; |
| | | |
| | | @Schema(description = "单条回复的最大 Token 数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096") |
| | | private Integer maxTokens; |
| | | |
| | | @Schema(description = "上下文的最大 Message 数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| | | private Integer maxContexts; |
| | | |
| | | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private LocalDateTime createTime; |
| | | |
| | | // ========== 关联 role 信息 ========== |
| | | |
| | | @Schema(description = "角色头像", example = "https://www.Iailab.cn/1.png") |
| | | private String roleAvatar; |
| | | |
| | | @Schema(description = "角色名字", example = "小黄") |
| | | private String roleName; |
| | | |
| | | // ========== 仅在【对话管理】时加载 ========== |
| | | |
| | | @Schema(description = "消息数量", example = "20") |
| | | private Integer messageCount; |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管理后台 - AI 聊天消息发送 Request VO") |
| | | @Data |
| | | public class AiChatMessageSendReqDTO { |
| | | |
| | | @Schema(description = "聊天对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | @NotNull(message = "聊天对话编号不能为空") |
| | | private Long conversationId; |
| | | |
| | | @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "帮我写个 Java 算法") |
| | | @NotEmpty(message = "聊天内容不能为空") |
| | | private String content; |
| | | |
| | | @Schema(description = "是否携带上下文", example = "true") |
| | | private Boolean useContext; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Data |
| | | public class AiChatMessageSendRespDTO { |
| | | |
| | | @Schema(description = "发送消息", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private Message send; |
| | | |
| | | @Schema(description = "接收消息", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private Message receive; |
| | | |
| | | @Schema(description = "消息") |
| | | @Data |
| | | public static class Message { |
| | | |
| | | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | private Long id; |
| | | |
| | | @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "role") |
| | | private String type; // 参见 MessageType 枚举类 |
| | | |
| | | @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,你好啊") |
| | | private String content; |
| | | |
| | | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat.dto; |
| | | |
| | | import com.iailab.framework.common.enums.CommonStatusEnum; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * AI 模型 DO |
| | | * |
| | | * 默认模型:{@link #status} 为开启,并且 {@link #sort} 排序第一 |
| | | * |
| | | * @author houzhongjian |
| | | * @since 2025/6/33 11:39 |
| | | */ |
| | | @Data |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AiModelDO { |
| | | |
| | | /** |
| | | * 编号 |
| | | */ |
| | | private Long id; |
| | | /** |
| | | * API 秘钥编号 |
| | | * |
| | | */ |
| | | private Long keyId; |
| | | /** |
| | | * 模型名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 模型标志 |
| | | */ |
| | | private String model; |
| | | /** |
| | | * 平台 |
| | | * |
| | | */ |
| | | private String platform; |
| | | /** |
| | | * 类型 |
| | | * |
| | | */ |
| | | private Integer type; |
| | | |
| | | /** |
| | | * 排序值 |
| | | */ |
| | | private Integer sort; |
| | | /** |
| | | * 状态 |
| | | * |
| | | * 枚举 {@link CommonStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | |
| | | // ========== 对话配置 ========== |
| | | |
| | | /** |
| | | * 温度参数 |
| | | * |
| | | * 用于调整生成回复的随机性和多样性程度:较低的温度值会使输出更收敛于高频词汇,较高的则增加多样性 |
| | | */ |
| | | private Double temperature; |
| | | /** |
| | | * 单条回复的最大 Token 数量 |
| | | */ |
| | | private Integer maxTokens; |
| | | /** |
| | | * 上下文的最大 Message 数量 |
| | | */ |
| | | private Integer maxContexts; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.questionTemplate; |
| | | |
| | | import com.iailab.framework.common.enums.RpcConstants; |
| | | import com.iailab.module.ai.api.questionTemplate.dto.AiModelDTO; |
| | | import com.iailab.module.ai.api.questionTemplate.dto.QuestionTemplateDTO; |
| | | import com.iailab.module.ai.enums.ApiConstants; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author DongYukun |
| | | * @Description |
| | | * @createTime 2025年06月04日 |
| | | */ |
| | | @FeignClient(name = ApiConstants.NAME) |
| | | @Tag(name = "问题模板") |
| | | public interface QuestionTemplateApi { |
| | | |
| | | String PREFIX = RpcConstants.RPC_API_PREFIX + "/ai/questiontemplate"; |
| | | |
| | | @GetMapping(PREFIX + "/modelList") |
| | | @Operation(summary = "Ai大模型级联问题模版") |
| | | List<AiModelDTO> queryModelList(); |
| | | |
| | | @PostMapping(PREFIX + "/queryTemplates") |
| | | @Operation(summary = "Ai大模型级联问题模版") |
| | | List<QuestionTemplateDTO> queryTemplates(@RequestBody QuestionTemplateDTO questionTemplateDTO); |
| | | } |
文件名从 iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/AiModelDto.java 修改 |
| | |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | public class AiModelDto implements Serializable { |
| | | public class AiModelDTO implements Serializable { |
| | | |
| | | @Schema(description = "编号", example = "2630") |
| | | private Long id; |
| | |
| | | @Schema(description = "上下文的最大 Message 数量", example = "8192") |
| | | private Integer maxContexts; |
| | | |
| | | private List<QuestionTemplateDto> children; |
| | | private List<QuestionTemplateDTO> children; |
| | | |
| | | } |
文件名从 iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/QuestionTemplateDto.java 修改 |
| | |
| | | * @author 超级管理员 |
| | | */ |
| | | @Data |
| | | public class QuestionTemplateDto implements Serializable { |
| | | public class QuestionTemplateDTO implements Serializable { |
| | | |
| | | /** |
| | | * id |
| | |
| | | @Getter |
| | | public enum AiChatRoleEnum { |
| | | |
| | | AI_WRITE_ROLE("写作助手", """ |
| | | 你是一位出色的写作助手,能够帮助用户生成创意和灵感,并在用户提供场景和提示词时生成对应的回复。你的任务包括: |
| | | 1. 撰写建议:根据用户提供的主题或问题,提供详细的写作建议、情节发展方向、角色设定以及背景描写,确保内容结构清晰、有逻辑。 |
| | | 2. 回复生成:根据用户提供的场景和提示词,生成合适的对话或文字回复,确保语气和风格符合场景需求。 |
| | | 除此之外不需要除了正文内容外的其他回复,如标题、开头、任何解释性语句或道歉。 |
| | | """), |
| | | AI_WRITE_ROLE("写作助手", "你是一位出色的写作助手,能够帮助用户生成创意和灵感,并在用户提供场景和提示词时生成对应的回复。你的任务包括:\n" + |
| | | " 1.\t撰写建议:根据用户提供的主题或问题,提供详细的写作建议、情节发展方向、角色设定以及背景描写,确保内容结构清晰、有逻辑。\n" + |
| | | " 2.\t回复生成:根据用户提供的场景和提示词,生成合适的对话或文字回复,确保语气和风格符合场景需求。\n" + |
| | | " 除此之外不需要除了正文内容外的其他回复,如标题、开头、任何解释性语句或道歉。"), |
| | | |
| | | AI_MIND_MAP_ROLE("导图助手", """ |
| | | 你是一位非常优秀的思维导图助手,你会把用户的所有提问都总结成思维导图,然后以 Markdown 格式输出。markdown 只需要输出一级标题,二级标题,三级标题,四级标题,最多输出四级,除此之外不要输出任何其他 markdown 标记。下面是一个合格的例子: |
| | | # Geek-AI 助手 |
| | | ## 完整的开源系统 |
| | | ### 前端开源 |
| | | ### 后端开源 |
| | | ## 支持各种大模型 |
| | | ### OpenAI |
| | | ### Azure |
| | | ### 文心一言 |
| | | ### 通义千问 |
| | | ## 集成多种收费方式 |
| | | ### 支付宝 |
| | | ### 微信 |
| | | 除此之外不要任何解释性语句。 |
| | | """), |
| | | AI_MIND_MAP_ROLE("导图助手", "你是一位非常优秀的思维导图助手,你会把用户的所有提问都总结成思维导图,然后以 Markdown 格式输出。markdown 只需要输出一级标题,二级标题,三级标题,四级标题,最多输出四级,除此之外不要输出任何其他 markdown 标记。下面是一个合格的例子:\n" + |
| | | " # Geek-AI 助手\n" + |
| | | " ## 完整的开源系统\n" + |
| | | " ### 前端开源\n" + |
| | | " ### 后端开源\n" + |
| | | " ## 支持各种大模型\n" + |
| | | " ### OpenAI\n" + |
| | | " ### Azure\n" + |
| | | " ### 文心一言\n" + |
| | | " ### 通义千问\n" + |
| | | " ## 集成多种收费方式\n" + |
| | | " ### 支付宝\n" + |
| | | " ### 微信\n" + |
| | | " 除此之外不要任何解释性语句。"), |
| | | ; |
| | | |
| | | /** |
对比新文件 |
| | |
| | | package com.iailab.module.ai.enums; |
| | | |
| | | import com.iailab.framework.common.enums.RpcConstants; |
| | | |
| | | /** |
| | | * API 相关的枚举 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class ApiConstants { |
| | | |
| | | /** |
| | | * 服务名 |
| | | * |
| | | * 注意,需要保证和 spring.application.name 保持一致 |
| | | */ |
| | | public static final String NAME = "ai-server"; |
| | | |
| | | public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/ai"; |
| | | |
| | | public static final String VERSION = "1.0.0"; |
| | | |
| | | } |
| | |
| | | <parent> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-module-ai</artifactId> |
| | | <version>${ai.revision}</version> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <artifactId>iailab-module-ai-biz</artifactId> |
| | |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-module-ai-api</artifactId> |
| | | <version>${ai.revision}</version> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- 业务组件 --> |
| | |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-compiler-plugin</artifactId> |
| | | <configuration> |
| | | <source>17</source> |
| | | <target>17</target> |
| | | <source>${java.version}</source> |
| | | <target>${java.version}</target> |
| | | </configuration> |
| | | </plugin> |
| | | </plugins> |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat; |
| | | |
| | | import com.iailab.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateEnergyReqVO; |
| | | import com.iailab.module.ai.dal.dataobject.chat.AiChatConversationDO; |
| | | import com.iailab.module.ai.service.chat.AiChatConversationService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | |
| | | @RestController // 提供 RESTful API 接口,给 Feign 调用 |
| | | @Validated |
| | | public class AiChatConversionApiImpl implements AiChatConversationApi { |
| | | |
| | | @Resource |
| | | private AiChatConversationService chatConversationService; |
| | | |
| | | @Override |
| | | public Long chatEnergyConversation(String modelName) { |
| | | Long conversationId; |
| | | List<AiChatConversationDO> list = chatConversationService.getChatConversationList(getLoginUserId(), modelName); |
| | | if(list.size() == 0) { |
| | | AiChatConversationCreateEnergyReqVO createReqVO = new AiChatConversationCreateEnergyReqVO(); |
| | | createReqVO.setModelName(modelName); |
| | | conversationId = chatConversationService.createChatConversationEnergy(createReqVO); |
| | | } else { |
| | | conversationId = list.get(0).getId(); |
| | | } |
| | | return conversationId; |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.chat; |
| | | |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.module.ai.api.chat.dto.AiChatMessageSendRespDTO; |
| | | import com.iailab.module.ai.api.chat.dto.AiChatMessageSendReqDTO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; |
| | | import com.iailab.module.ai.service.chat.AiChatMessageService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | |
| | | @RestController // 提供 RESTful API 接口,给 Feign 调用 |
| | | @Validated |
| | | public class AiChatMessageApiImpl implements AiChatMessageApi { |
| | | |
| | | @Resource |
| | | private AiChatMessageService chatMessageService; |
| | | |
| | | @Override |
| | | public AiChatMessageSendRespDTO sendMessage(AiChatMessageSendReqDTO sendReqDTO) { |
| | | AiChatMessageSendRespVO aiChatMessageSendRespVO = chatMessageService.sendMessage(BeanUtils.toBean(sendReqDTO, AiChatMessageSendReqVO.class), getLoginUserId()); |
| | | return BeanUtils.toBean(aiChatMessageSendRespVO, AiChatMessageSendRespDTO.class); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api; |
对比新文件 |
| | |
| | | package com.iailab.module.ai.api.template; |
| | | |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.module.ai.api.questionTemplate.QuestionTemplateApi; |
| | | import com.iailab.module.ai.api.questionTemplate.dto.AiModelDTO; |
| | | import com.iailab.module.ai.api.questionTemplate.dto.QuestionTemplateDTO; |
| | | import com.iailab.module.ai.controller.admin.questiontemplate.vo.QuestionTemplateReqVO; |
| | | import com.iailab.module.ai.service.model.AiModelService; |
| | | import com.iailab.module.ai.service.questiontemplate.QuestionTemplateService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @description: |
| | | * @author: dongyukun |
| | | * @date: 2025/6/4 14:50 |
| | | **/ |
| | | @RestController // 提供 RESTful API 接口,给 Feign 调用 |
| | | @Validated |
| | | public class QuestionTemplateApiImpl implements QuestionTemplateApi { |
| | | |
| | | @Resource |
| | | private QuestionTemplateService questionTemplateService; |
| | | |
| | | @Resource |
| | | private AiModelService aiModelService; |
| | | |
| | | @Override |
| | | public List<AiModelDTO> queryModelList() { |
| | | List<AiModelDTO> list = BeanUtils.toBean(aiModelService.getModelListByStatusAndType(0, 1, null), AiModelDTO.class); |
| | | list.forEach(item->{ |
| | | item.setChildren( |
| | | BeanUtils.toBean(questionTemplateService.getQuestionTemplateList(item.getId()), QuestionTemplateDTO.class)); |
| | | }); |
| | | return list; |
| | | } |
| | | |
| | | @Override |
| | | public List<QuestionTemplateDTO> queryTemplates(QuestionTemplateDTO reqDTO) { |
| | | QuestionTemplateReqVO ReqVO = BeanUtils.toBean(reqDTO, QuestionTemplateReqVO.class); |
| | | return BeanUtils.toBean(questionTemplateService.getQuestionTemplates(ReqVO), QuestionTemplateDTO.class); |
| | | } |
| | | } |
| | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.common.util.collection.MapUtils; |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.*; |
| | | import com.iailab.module.ai.dal.dataobject.chat.AiChatConversationDO; |
| | | import com.iailab.module.ai.dal.dataobject.chat.AiChatMessageDO; |
| | | import com.iailab.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | import reactor.core.publisher.Flux; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | return chatMessageService.sendChatMessageStream(sendReqVO, getLoginUserId()); |
| | | } |
| | | |
| | | @Operation(summary = "获得指定对话的消息列表(分页)") |
| | | @GetMapping("/page-list-by-conversation-id") |
| | | public CommonResult<PageResult<AiChatMessageRespVO>> getChatMessagePageListByConversationId(AiChatMessageReqVO queryReqVO) { |
| | | PageResult<AiChatMessageRespVO> pageResult = new PageResult<>(); |
| | | AiChatConversationDO conversation = chatConversationService.getChatConversation(queryReqVO.getConversationId()); |
| | | if (conversation == null || ObjUtil.notEqual(conversation.getUserId(), getLoginUserId())) { |
| | | return success(pageResult); |
| | | } |
| | | // 1. 获取消息列表 |
| | | PageResult<AiChatMessageDO> pageList = chatMessageService.getChatMessagePageByConversationId(queryReqVO); |
| | | List<AiChatMessageDO> messageList = pageList.getList(); |
| | | if (CollUtil.isEmpty(messageList)) { |
| | | pageResult.setList(new ArrayList<>()); |
| | | pageResult.setTotal(0L); |
| | | return success(pageResult); |
| | | } |
| | | List<AiChatMessageRespVO> messageVOList = BeanUtils.toBean(messageList, AiChatMessageRespVO.class); |
| | | dealKnowledge(messageList, messageVOList); |
| | | pageResult.setList(messageVOList); |
| | | pageResult.setTotal(pageList.getTotal()); |
| | | return success(pageResult); |
| | | } |
| | | |
| | | @Operation(summary = "获得指定对话的消息列表") |
| | | @GetMapping("/list-by-conversation-id") |
| | | @Parameter(name = "conversationId", required = true, description = "对话编号", example = "1024") |
| | |
| | | if (CollUtil.isEmpty(messageList)) { |
| | | return success(Collections.emptyList()); |
| | | } |
| | | |
| | | // 2. 拼接数据,主要是知识库段落信息 |
| | | Map<Long, AiKnowledgeSegmentDO> segmentMap = knowledgeSegmentService.getKnowledgeSegmentMap(convertListByFlatMap(messageList, |
| | | message -> CollUtil.isEmpty(message.getSegmentIds()) ? null : message.getSegmentIds().stream())); |
| | | Map<Long, AiKnowledgeDocumentDO> documentMap = knowledgeDocumentService.getKnowledgeDocumentMap( |
| | | convertList(segmentMap.values(), AiKnowledgeSegmentDO::getDocumentId)); |
| | | List<AiChatMessageRespVO> messageVOList = BeanUtils.toBean(messageList, AiChatMessageRespVO.class); |
| | | for (int i = 0; i < messageList.size(); i++) { |
| | | AiChatMessageDO message = messageList.get(i); |
| | | if (CollUtil.isEmpty(message.getSegmentIds())) { |
| | | continue; |
| | | } |
| | | // 设置知识库段落信息 |
| | | messageVOList.get(i).setSegments(convertList(message.getSegmentIds(), segmentId -> { |
| | | AiKnowledgeSegmentDO segment = segmentMap.get(segmentId); |
| | | if (segment == null) { |
| | | return null; |
| | | } |
| | | AiKnowledgeDocumentDO document = documentMap.get(segment.getDocumentId()); |
| | | if (document == null) { |
| | | return null; |
| | | } |
| | | return new AiChatMessageRespVO.KnowledgeSegment().setId(segment.getId()).setContent(segment.getContent()) |
| | | .setDocumentId(segment.getDocumentId()).setDocumentName(document.getName()); |
| | | })); |
| | | } |
| | | dealKnowledge(messageList, messageVOList); |
| | | return success(messageVOList); |
| | | } |
| | | |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | private void dealKnowledge(List<AiChatMessageDO> messageList, List<AiChatMessageRespVO> messageVOList) { |
| | | // 拼接数据,主要是知识库段落信息 |
| | | Map<Long, AiKnowledgeSegmentDO> segmentMap = knowledgeSegmentService.getKnowledgeSegmentMap(convertListByFlatMap(messageList, |
| | | message -> CollUtil.isEmpty(message.getSegmentIds()) ? null : message.getSegmentIds().stream())); |
| | | Map<Long, AiKnowledgeDocumentDO> documentMap = knowledgeDocumentService.getKnowledgeDocumentMap( |
| | | convertList(segmentMap.values(), AiKnowledgeSegmentDO::getDocumentId)); |
| | | for (int i = 0; i < messageList.size(); i++) { |
| | | AiChatMessageDO message = messageList.get(i); |
| | | if (CollUtil.isEmpty(message.getSegmentIds())) { |
| | | continue; |
| | | } |
| | | // 设置知识库段落信息 |
| | | messageVOList.get(i).setSegments(convertList(message.getSegmentIds(), segmentId -> { |
| | | AiKnowledgeSegmentDO segment = segmentMap.get(segmentId); |
| | | if (segment == null) { |
| | | return null; |
| | | } |
| | | AiKnowledgeDocumentDO document = documentMap.get(segment.getDocumentId()); |
| | | if (document == null) { |
| | | return null; |
| | | } |
| | | return new AiChatMessageRespVO.KnowledgeSegment().setId(segment.getId()).setContent(segment.getContent()) |
| | | .setDocumentId(segment.getDocumentId()).setDocumentName(document.getName()); |
| | | })); |
| | | } |
| | | } |
| | | } |
| | |
| | | @Schema(description = "模型名称", example = "zhuanlu") |
| | | private String modelName; |
| | | |
| | | @Schema(description = "会话名称", example = "2025-06-10 17:09:33") |
| | | private String title; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.controller.admin.chat.vo.message; |
| | | |
| | | import com.iailab.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管理后台 - AI 聊天消息查询 Request VO") |
| | | @Data |
| | | public class AiChatMessageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "对话编号", example = "2048") |
| | | private Long conversationId; |
| | | |
| | | @Schema(description = "用户编号", example = "1024") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "消息内容", example = "你好") |
| | | private String content; |
| | | |
| | | @Schema(description = "创建时间") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] createTime; |
| | | |
| | | } |
| | |
| | | package com.iailab.module.ai.controller.admin.questiontemplate; |
| | | |
| | | import com.iailab.module.ai.api.questionTemplate.dto.AiModelDto; |
| | | import com.iailab.module.ai.api.questionTemplate.dto.QuestionTemplateDto; |
| | | import com.iailab.module.ai.api.questionTemplate.dto.AiModelDTO; |
| | | import com.iailab.module.ai.api.questionTemplate.dto.QuestionTemplateDTO; |
| | | import com.iailab.module.ai.service.model.AiModelService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.web.bind.annotation.*; |
| | |
| | | |
| | | @GetMapping( "/modelList") |
| | | @Operation(summary = "Ai大模型级联问题模版") |
| | | List<AiModelDto> queryModelList(){ |
| | | List<AiModelDto> list = BeanUtils.toBean(aiModelService.getModelListByStatusAndType(0, 1, null), AiModelDto.class); |
| | | List<AiModelDTO> queryModelList(){ |
| | | List<AiModelDTO> list = BeanUtils.toBean(aiModelService.getModelListByStatusAndType(0, 1, null), AiModelDTO.class); |
| | | list.forEach(item->{ |
| | | item.setChildren( |
| | | BeanUtils.toBean(questionTemplateService.getQuestionTemplateList(item.getId()), QuestionTemplateDto.class)); |
| | | BeanUtils.toBean(questionTemplateService.getQuestionTemplateList(item.getId()), QuestionTemplateDTO.class)); |
| | | }); |
| | | return list; |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.ai.controller.admin.questiontemplate.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author houzh |
| | | */ |
| | | @Schema(description = "管理后台 - 大模型问题模板查询 Request VO") |
| | | @Data |
| | | public class QuestionTemplateReqVO { |
| | | |
| | | @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "31480") |
| | | private String id; |
| | | |
| | | @Schema(description = "模型id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11609") |
| | | private String modelId; |
| | | |
| | | @Schema(description = "问题编号", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private String questionCode; |
| | | |
| | | @Schema(description = "问题名称", example = "赵六") |
| | | private String questionName; |
| | | |
| | | @Schema(description = "模型名称") |
| | | private String modelName; |
| | | } |
| | |
| | | import com.iailab.framework.mybatis.core.mapper.BaseMapperX; |
| | | import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageReqVO; |
| | | import com.iailab.module.ai.dal.dataobject.chat.AiChatMessageDO; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | |
| | | @Mapper |
| | | public interface AiChatMessageMapper extends BaseMapperX<AiChatMessageDO> { |
| | | |
| | | default PageResult<AiChatMessageDO> selectPageByConversationId(AiChatMessageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<AiChatMessageDO>() |
| | | .eq(AiChatMessageDO::getConversationId, reqVO.getConversationId()) |
| | | .betweenIfPresent(AiChatMessageDO::getCreateTime, reqVO.getCreateTime()) |
| | | .orderByDesc(AiChatMessageDO::getId)); |
| | | } |
| | | |
| | | default List<AiChatMessageDO> selectListByConversationId(Long conversationId) { |
| | | return selectList(new LambdaQueryWrapperX<AiChatMessageDO>() |
| | | .eq(AiChatMessageDO::getConversationId, conversationId) |
| | |
| | | //package com.iailab.module.ai.job.image; |
| | | package com.iailab.module.ai.job.image;//package com.iailab.module.ai.job.image; |
| | | // |
| | | //import com.iailab.module.ai.service.image.AiImageService; |
| | | //import com.xxl.job.core.handler.annotation.XxlJob; |
| | |
| | | //package com.iailab.module.ai.job.music; |
| | | package com.iailab.module.ai.job.music;//package com.iailab.module.ai.job.music; |
| | | // |
| | | //import com.iailab.module.ai.service.music.AiMusicService; |
| | | //import com.xxl.job.core.handler.annotation.XxlJob; |
| | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.iailab.framework.ai.core.enums.AiModelTypeEnum; |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.common.util.date.DateUtils; |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateEnergyReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateMyReqVO; |
| | |
| | | import com.iailab.module.ai.service.model.AiChatRoleService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang.StringUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | import static com.iailab.module.ai.enums.ErrorCodeConstants.CHAT_CONVERSATION_MODEL_ERROR; |
| | | import static com.iailab.module.ai.enums.ErrorCodeConstants.CHAT_CONVERSATION_NOT_EXISTS; |
| | |
| | | AiChatConversationDO conversation = new AiChatConversationDO().setUserId(getLoginUserId()).setPinned(false) |
| | | .setModelId(model.getId()).setModel(model.getModel()) |
| | | .setTemperature(model.getTemperature()).setMaxTokens(model.getMaxTokens()).setMaxContexts(model.getMaxContexts()); |
| | | conversation.setTitle("新对话"); |
| | | if(StringUtils.isNotEmpty(createReqVO.getTitle())) { |
| | | conversation.setTitle(createReqVO.getTitle()); |
| | | } else { |
| | | String format = DateUtils.format(new Date(), FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND); |
| | | conversation.setTitle(format); |
| | | } |
| | | chatConversationMapper.insert(conversation); |
| | | return conversation.getId(); |
| | | } |
| | |
| | | throw exception(CHAT_CONVERSATION_MODEL_ERROR); |
| | | } |
| | | |
| | | @Override |
| | | public AiChatConversationDO validateChatConversationExists(Long id) { |
| | | AiChatConversationDO conversation = chatConversationMapper.selectById(id); |
| | | if (conversation == null) { |
| | |
| | | import com.iailab.framework.common.pojo.CommonResult; |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; |
| | | import com.iailab.module.ai.dal.dataobject.chat.AiChatMessageDO; |
| | |
| | | Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId); |
| | | |
| | | /** |
| | | * 获得指定对话的消息列表(分页) |
| | | * |
| | | * @param queryReqVO 消息请求 |
| | | * @return 消息列表 |
| | | */ |
| | | PageResult<AiChatMessageDO> getChatMessagePageByConversationId(AiChatMessageReqVO queryReqVO); |
| | | |
| | | /** |
| | | * 获得指定对话的消息列表 |
| | | * |
| | | * @param conversationId 对话编号 |
| | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.framework.tenant.core.util.TenantUtils; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; |
| | | import com.iailab.module.ai.controller.admin.chat.vo.message.*; |
| | | import com.iailab.module.ai.dal.dataobject.chat.AiChatConversationDO; |
| | | import com.iailab.module.ai.dal.dataobject.chat.AiChatMessageDO; |
| | | import com.iailab.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<AiChatMessageDO> getChatMessagePageByConversationId(AiChatMessageReqVO reqVO) { |
| | | return chatMessageMapper.selectPageByConversationId(reqVO); |
| | | } |
| | | |
| | | @Override |
| | | public List<AiChatMessageDO> getChatMessageListByConversationId(Long conversationId) { |
| | | return chatMessageMapper.selectListByConversationId(conversationId); |
| | | } |
| | |
| | | QuestionTemplateDO getQuestionTemplate(String id); |
| | | |
| | | /** |
| | | * 获得大模型问题模板 |
| | | * |
| | | * @param reqVO |
| | | * @return 大模型问题模板 |
| | | */ |
| | | List<QuestionTemplateDO> getQuestionTemplates(QuestionTemplateReqVO reqVO); |
| | | |
| | | /** |
| | | * 获得大模型问题模板分页 |
| | | * |
| | | * @param pageReqVO 分页查询 |
| | |
| | | package com.iailab.module.ai.service.questiontemplate; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import com.iailab.module.ai.controller.admin.questionparamsetting.vo.QuestionParamSettingRespVO; |
| | | import com.iailab.module.ai.dal.dataobject.model.AiModelDO; |
| | | import com.iailab.module.ai.dal.dataobject.questionparamsetting.QuestionParamSettingDO; |
| | | import com.iailab.module.ai.dal.mysql.questionparamsetting.QuestionParamSettingMapper; |
| | | import com.iailab.module.ai.service.model.AiModelService; |
| | | import jakarta.annotation.Resource; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | |
| | | |
| | | @Resource |
| | | private QuestionParamSettingMapper questionParamSettingMapper; |
| | | |
| | | @Resource |
| | | private AiModelService aiModelService; |
| | | |
| | | @Override |
| | | public String createQuestionTemplate(QuestionTemplateSaveReqVO createReqVO) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<QuestionTemplateDO> getQuestionTemplates(QuestionTemplateReqVO reqVO) { |
| | | String modelName = reqVO.getModelName(); |
| | | if(ObjectUtils.isNotEmpty(modelName)) { |
| | | AiModelDO model = aiModelService.getModelByName(modelName); |
| | | List<QuestionTemplateDO> questionTemplateDOS = questionTemplateMapper.selectList( |
| | | new LambdaQueryWrapperX<QuestionTemplateDO>() |
| | | .eqIfPresent(QuestionTemplateDO::getModelId, model.getId()) |
| | | .eqIfPresent(QuestionTemplateDO::getQuestionCode, reqVO.getQuestionCode())); |
| | | // 模板数量暂时很少,先循环遍历查询模板设置 |
| | | if (questionTemplateDOS != null && questionTemplateDOS.size() > 0) { |
| | | questionTemplateDOS.stream().forEach(questionTemplateDO -> { |
| | | questionTemplateDO.setSettingList( |
| | | BeanUtils.toBean(questionParamSettingMapper.selectList("template_id", questionTemplateDO.getId()), QuestionParamSettingRespVO.class)); |
| | | }); |
| | | } |
| | | return questionTemplateDOS; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<QuestionTemplateDO> getQuestionTemplatePage(QuestionTemplatePageReqVO pageReqVO) { |
| | | return questionTemplateMapper.selectPage(pageReqVO); |
| | | } |
| | |
| | | username: @nacos.username@ |
| | | password: @nacos.password@ |
| | | discovery: # 【配置中心】配置项 |
| | | ip: @deploy.server@ |
| | | namespace: @profiles.active@ |
| | | group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP |
| | | metadata: |
| | |
| | | |
| | | logging: |
| | | file: |
| | | name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径 |
| | | name: @log.path@/logs/${spring.application.name}.log # 日志文件名,全路径 |
| | | |
| | | --- #################### 接口文档配置 #################### |
| | | |
| | |
| | | job: |
| | | executor: |
| | | appname: ${spring.application.name} # 执行器 AppName |
| | | logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 |
| | | logpath: @log.path@/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 |
| | | accessToken: default_token # 执行器通讯TOKEN |
| | | |
| | | --- #################### AI 相关配置 #################### |
| | |
| | | <parent> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-module-ai</artifactId> |
| | | <version>${ai.revision}</version> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <build> |
| | | <plugins> |
| | |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-module-ai</artifactId> |
| | | <version>${ai.revision}</version> |
| | | <version>${revision}</version> |
| | | <packaging>pom</packaging> |
| | | |
| | | <modules> |
| | |
| | | <spring.cloud.version>2024.0.0</spring.cloud.version> |
| | | <spring.cloud.alibaba.version>2023.0.3.2</spring.cloud.alibaba.version> |
| | | <!-- Web 相关 --> |
| | | <springdoc.version>2.7.0</springdoc.version> |
| | | <springdoc.version>2.8.3</springdoc.version> |
| | | <knife4j.version>4.6.0</knife4j.version> |
| | | <!-- 工具类相关 --> |
| | | <bizlog-sdk.version>3.0.6</bizlog-sdk.version> |
| | |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-module-infra-api</artifactId> |
| | | <version>${revision}</version> |
| | | <version>${ai.revision}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | |
| | | @PostMapping(PREFIX + "/query-math-point/current-value") |
| | | @Operation(summary = "根据计算点编号查询测点集合") |
| | | PageResult<ApiPointDTO> queryMathPointCurrentValue(@RequestBody ApiPointPageReqVO reqVO); |
| | | } |
| | | |
| | | @PostMapping(PREFIX + "/query-point-bad-history/page") |
| | | @Operation(summary = "查询测点异常历史分页") |
| | | PageResult<ApiPointBadHistoryDTO> queryPointBadHistoryPage(@RequestBody ApiPointBadHistoryPageReqVO reqVO); |
| | | |
| | | @PostMapping(PREFIX + "/query-point/count") |
| | | @Operation(summary = "获取点位个数") |
| | | String getPointTotalCount(@RequestBody ApiPointCountReqVO reqVO); |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.api.point.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Data |
| | | @Tag(name = "测点异常历史表") |
| | | public class ApiPointBadHistoryDTO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Schema(description = "id") |
| | | private String id; |
| | | |
| | | @Schema(description = "测点ID") |
| | | private String pointId; |
| | | |
| | | @Schema(description = "测点编码") |
| | | private String pointNo; |
| | | |
| | | @Schema(description = "测点名称") |
| | | private String pointName; |
| | | |
| | | @Schema(description = "测点Tag") |
| | | private String tagNo; |
| | | |
| | | @Schema(description = "异常值") |
| | | private BigDecimal badValue; |
| | | |
| | | @Schema(description = "异常值类型") |
| | | private String badValueType; |
| | | |
| | | @Schema(description = "采集时间") |
| | | private Date collectTime; |
| | | |
| | | @Schema(description = "创建时间") |
| | | private Date createTime; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.api.point.dto; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.iailab.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Schema(description = "数据平台 - 测点异常分页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class ApiPointBadHistoryPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "测点编码") |
| | | private String pointNo; |
| | | |
| | | @Schema(description = "测点名称") |
| | | private String pointName; |
| | | |
| | | @Schema(description = "测点Tag") |
| | | private String tagNo; |
| | | |
| | | @Schema(description = "开始时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date startTime; |
| | | |
| | | @Schema(description = "结束时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date endTime; |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.api.point.dto; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Schema(description = "数据平台 - 测点数量查询 Request VO") |
| | | @Data |
| | | public class ApiPointCountReqVO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Schema(description = "测点类型") |
| | | private String pointType; |
| | | |
| | | @Schema(description = "数据类型") |
| | | private String dataType; |
| | | |
| | | @Schema(description = "是否启用") |
| | | private Integer isEnable; |
| | | |
| | | @Schema(description = "采集质量") |
| | | private String collectQuality; |
| | | |
| | | @Schema(description = "开始时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date startTime; |
| | | |
| | | @Schema(description = "结束时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date endTime; |
| | | |
| | | } |
| | |
| | | return success(indItemApi.queryIndItemValuePage(dto)); |
| | | } |
| | | |
| | | @PermitAll |
| | | @PostMapping("/query-point-bad-history/page") |
| | | @Operation(summary = "根据计算点编号查询测点集合") |
| | | public CommonResult<PageResult<ApiPointBadHistoryDTO>> queryPointBadHistoryPage(@RequestBody ApiPointBadHistoryPageReqVO reqVO) { |
| | | PageResult<ApiPointBadHistoryDTO> data = dataPointApi.queryPointBadHistoryPage(reqVO); |
| | | return success(data); |
| | | } |
| | | |
| | | @PermitAll |
| | | @PostMapping("/query-point/count") |
| | | @Operation(summary = "根据计算点编号查询测点集合") |
| | | public CommonResult<String> getPointTotalCount(@RequestBody ApiPointCountReqVO reqVO) { |
| | | String count = dataPointApi.getPointTotalCount(reqVO); |
| | | return success(count); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.iailab.module.data.point.dto.DaMathPointDTO; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import com.iailab.module.data.point.dto.DaPointWriteValueDTO; |
| | | import com.iailab.module.data.point.entity.DaPointBadHistoryEntity; |
| | | import com.iailab.module.data.point.service.DaMathPointService; |
| | | import com.iailab.module.data.point.service.DaPointBadHistoryService; |
| | | import com.iailab.module.data.point.service.DaPointService; |
| | | import com.iailab.module.data.point.vo.DaPointBadHistoryPageReqVO; |
| | | import com.iailab.module.data.point.vo.DaPointCountReqVO; |
| | | import com.iailab.module.data.point.vo.DaPointPageReqVO; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.util.CollectionUtils; |
| | |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.IntStream; |
| | | |
| | | /** |
| | | * @author PanZhibao |
| | |
| | | |
| | | @Autowired |
| | | private DaMathPointService daMathPointService; |
| | | |
| | | @Autowired |
| | | private DaPointBadHistoryService daPointBadHistoryService; |
| | | |
| | | @Override |
| | | public ApiPointDTO getInfoById(String pointId) { |
| | |
| | | }); |
| | | return new PageResult<>(dataList, pageResult.getTotal()); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<ApiPointBadHistoryDTO> queryPointBadHistoryPage(ApiPointBadHistoryPageReqVO reqVO) { |
| | | DaPointBadHistoryPageReqVO req = ConvertUtils.sourceToTarget(reqVO, DaPointBadHistoryPageReqVO.class); |
| | | PageResult<DaPointBadHistoryEntity> page = daPointBadHistoryService.queryPage(req); |
| | | List<ApiPointBadHistoryDTO> dataList = ConvertUtils.sourceToTarget(page.getList(), ApiPointBadHistoryDTO.class); |
| | | return new PageResult<>(dataList, page.getTotal()); |
| | | } |
| | | |
| | | @Override |
| | | public String getPointTotalCount(ApiPointCountReqVO reqVO) { |
| | | DaPointCountReqVO req = ConvertUtils.sourceToTarget(reqVO, DaPointCountReqVO.class); |
| | | return daPointService.getPointCount(req).toString(); |
| | | } |
| | | } |
| | |
| | | scheduleJobList.add("pointArchivingTaskNetShift"); |
| | | scheduleJobList.add("pointArchivingTaskNetYear"); |
| | | scheduleJobList.add("insertInfluxdbTask"); |
| | | scheduleJobList.add("pointBadHistoryGenerateTask"); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.job.task; |
| | | |
| | | import com.iailab.module.data.common.enums.CommonConstant; |
| | | import com.iailab.module.data.common.enums.DataQualityEnum; |
| | | import com.iailab.module.data.common.enums.IsEnableEnum; |
| | | import com.iailab.module.data.point.dto.DaPointBadHistoryDTO; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import com.iailab.module.data.point.service.DaPointBadHistoryService; |
| | | import com.iailab.module.data.point.service.DaPointService; |
| | | import com.iailab.module.data.point.vo.DaPointPageReqVO; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Calendar; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Point采集器1min |
| | | * 0 0/1 * * * ? |
| | | * |
| | | * @author Jay |
| | | * @Description 测点异常历史 |
| | | */ |
| | | @Component("pointBadHistoryGenerateTask") |
| | | public class PointBadHistoryGenerateTask implements ITask { |
| | | private final Logger logger = LoggerFactory.getLogger(getClass()); |
| | | |
| | | @Resource |
| | | private DaPointService daPointService; |
| | | |
| | | @Resource |
| | | private DaPointBadHistoryService daPointBadHistoryService; |
| | | |
| | | @Override |
| | | public void run(String params) { |
| | | // 0 0/1 * * * ? |
| | | logger.info("PointBadHistoryGenerateTask定时任务正在执行,参数为:{}", params); |
| | | try { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | calendar.set(Calendar.MILLISECOND, 0); |
| | | DaPointPageReqVO reqVO = new DaPointPageReqVO(); |
| | | reqVO.setIsEnable(IsEnableEnum.ENABLE.getCode()); |
| | | reqVO.setCollectQuality(DataQualityEnum.BAD.getCode()); |
| | | List<DaPointDTO> badPoints = daPointService.getList(reqVO); |
| | | badPoints.forEach(point -> { |
| | | DaPointBadHistoryDTO daPointBadHistoryDTO = new DaPointBadHistoryDTO(); |
| | | daPointBadHistoryDTO.setPointId(point.getId()); |
| | | daPointBadHistoryDTO.setPointNo(point.getPointNo()); |
| | | daPointBadHistoryDTO.setPointName(point.getPointName()); |
| | | daPointBadHistoryDTO.setTagNo(point.getTagNo()); |
| | | daPointBadHistoryDTO.setBadValue(CommonConstant.BAD_VALUE); |
| | | daPointBadHistoryDTO.setBadValueType("通讯异常"); |
| | | daPointBadHistoryDTO.setCollectTime(point.getCollectTime()); |
| | | daPointBadHistoryService.create(daPointBadHistoryDTO); |
| | | }); |
| | | logger.info("PointBadHistoryGenerateTask定时任务完成时间:" + LocalDateTime.now()); |
| | | } catch (Exception ex) { |
| | | ex.printStackTrace(); |
| | | logger.error("PointBadHistoryGenerateTask定时任务失败时间:" + LocalDateTime.now()); |
| | | } |
| | | |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.dao; |
| | | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.mybatis.core.mapper.BaseMapperX; |
| | | import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import com.iailab.framework.tenant.core.db.dynamic.TenantDS; |
| | | import com.iailab.module.data.point.entity.DaPointBadHistoryEntity; |
| | | import com.iailab.module.data.point.vo.DaPointBadHistoryPageReqVO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @TenantDS |
| | | @Mapper |
| | | public interface DaPointBadHistoryDao extends BaseMapperX<DaPointBadHistoryEntity> { |
| | | |
| | | default PageResult<DaPointBadHistoryEntity> selectPage(DaPointBadHistoryPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<DaPointBadHistoryEntity>() |
| | | .likeIfPresent(DaPointBadHistoryEntity::getPointNo, reqVO.getPointNo()) |
| | | .likeIfPresent(DaPointBadHistoryEntity::getPointName, reqVO.getPointName()) |
| | | .likeIfPresent(DaPointBadHistoryEntity::getTagNo, reqVO.getTagNo()) |
| | | .geIfPresent(DaPointBadHistoryEntity::getCollectTime, reqVO.getStartTime()) |
| | | .leIfPresent(DaPointBadHistoryEntity::getCollectTime, reqVO.getEndTime()) |
| | | .orderByDesc(DaPointBadHistoryEntity::getCreateTime)); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.iailab.framework.tenant.core.db.dynamic.TenantDS; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import com.iailab.module.data.point.entity.DaPointEntity; |
| | | import com.iailab.module.data.point.vo.DaPointCountReqVO; |
| | | import com.iailab.module.data.point.vo.DaPointPageReqVO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | |
| | | |
| | | List<DaPointDTO> getExtremalPoint(Map<String, Object> params); |
| | | |
| | | Long getPointCount(DaPointCountReqVO reqVO); |
| | | |
| | | default IPage<DaPointDTO> selectPageList(DaPointPageReqVO reqVO) { |
| | | return getPageList(getPage(reqVO), reqVO); |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Data |
| | | @Tag(name = "测点异常历史表") |
| | | public class DaPointBadHistoryDTO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Schema(description = "id") |
| | | private String id; |
| | | |
| | | @Schema(description = "测点ID") |
| | | private String pointId; |
| | | |
| | | @Schema(description = "测点编码") |
| | | private String pointNo; |
| | | |
| | | @Schema(description = "测点名称") |
| | | private String pointName; |
| | | |
| | | @Schema(description = "测点Tag") |
| | | private String tagNo; |
| | | |
| | | @Schema(description = "异常值") |
| | | private BigDecimal badValue; |
| | | |
| | | @Schema(description = "异常值类型") |
| | | private String badValueType; |
| | | |
| | | @Schema(description = "采集时间") |
| | | private Date collectTime; |
| | | |
| | | @Schema(description = "创建时间") |
| | | private Date createTime; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Data |
| | | @TableName("t_da_point_bad_history") |
| | | public class DaPointBadHistoryEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * id |
| | | */ |
| | | @TableId(type = IdType.ASSIGN_UUID) |
| | | private String id; |
| | | |
| | | /** |
| | | * 测点ID |
| | | */ |
| | | private String pointId; |
| | | |
| | | /** |
| | | * 测点编码 |
| | | */ |
| | | private String pointNo; |
| | | |
| | | /** |
| | | * 测点名称 |
| | | */ |
| | | private String pointName; |
| | | |
| | | /** |
| | | * 测点Tag |
| | | */ |
| | | private String tagNo; |
| | | |
| | | /** |
| | | * 异常值 |
| | | */ |
| | | private BigDecimal badValue; |
| | | |
| | | /** |
| | | * 异常值类型 |
| | | */ |
| | | private String badValueType; |
| | | |
| | | /** |
| | | * 采集时间 |
| | | */ |
| | | private Date collectTime; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | private Date createTime; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.service; |
| | | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.common.service.BaseService; |
| | | import com.iailab.module.data.point.dto.DaPointBadHistoryDTO; |
| | | import com.iailab.module.data.point.entity.DaPointBadHistoryEntity; |
| | | import com.iailab.module.data.point.vo.DaPointBadHistoryPageReqVO; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | public interface DaPointBadHistoryService extends BaseService<DaPointBadHistoryEntity> { |
| | | PageResult<DaPointBadHistoryEntity> queryPage(DaPointBadHistoryPageReqVO reqVO); |
| | | |
| | | void create(DaPointBadHistoryDTO daPointBadHistoryDTO); |
| | | |
| | | |
| | | } |
| | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.module.data.api.point.dto.ApiPointDTO; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import com.iailab.module.data.point.vo.*; |
| | | import com.iailab.module.data.point.vo.DaPointCountReqVO; |
| | | import com.iailab.module.data.point.vo.DaPointPageReqVO; |
| | | import com.iailab.module.data.point.vo.PointImportExcelVO; |
| | | import com.iailab.module.data.point.vo.PointImportRespVO; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | |
| | | List<DaPointDTO> getMeasurePoint(DaPointPageReqVO reqVO); |
| | | |
| | | List<DaPointDTO> getMathPoint(DaPointPageReqVO reqVO); |
| | | |
| | | Long getPointCount(DaPointCountReqVO reqVO); |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.service.impl; |
| | | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.common.service.impl.BaseServiceImpl; |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.module.data.point.dao.DaPointBadHistoryDao; |
| | | import com.iailab.module.data.point.dto.DaPointBadHistoryDTO; |
| | | import com.iailab.module.data.point.entity.DaPointBadHistoryEntity; |
| | | import com.iailab.module.data.point.service.DaPointBadHistoryService; |
| | | import com.iailab.module.data.point.vo.DaPointBadHistoryPageReqVO; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Date; |
| | | import java.util.UUID; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Service |
| | | public class DaPointBadHistoryServiceImpl extends BaseServiceImpl<DaPointBadHistoryDao, DaPointBadHistoryEntity> implements DaPointBadHistoryService { |
| | | |
| | | |
| | | @Override |
| | | public PageResult<DaPointBadHistoryEntity> queryPage(DaPointBadHistoryPageReqVO reqVO) { |
| | | return baseDao.selectPage(reqVO); |
| | | } |
| | | |
| | | @Override |
| | | public void create(DaPointBadHistoryDTO daPointBadHistoryDTO) { |
| | | DaPointBadHistoryEntity entity = BeanUtils.toBean(daPointBadHistoryDTO, DaPointBadHistoryEntity.class); |
| | | entity.setId(UUID.randomUUID().toString()); |
| | | entity.setCreateTime(new Date()); |
| | | baseDao.insert(entity); |
| | | } |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.dynamic.datasource.annotation.DSTransactional; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.iailab.framework.common.constant.Constant; |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.common.service.impl.BaseServiceImpl; |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | |
| | | import com.iailab.module.data.api.point.dto.ApiPointDTO; |
| | | import com.iailab.module.data.channel.common.service.ChannelSourceService; |
| | | import com.iailab.module.data.common.enums.CommonConstant; |
| | | import com.iailab.module.data.common.enums.IsEnableEnum; |
| | | import com.iailab.module.data.common.enums.IncreaseCodeEnum; |
| | | import com.iailab.module.data.common.enums.IsEnableEnum; |
| | | import com.iailab.module.data.point.common.PointTypeEnum; |
| | | import com.iailab.module.data.point.dao.DaPointDao; |
| | | import com.iailab.module.data.point.dto.DaCumulatePointDTO; |
| | |
| | | import com.iailab.module.data.point.entity.DaMeasurePointEntity; |
| | | import com.iailab.module.data.point.entity.DaPointEntity; |
| | | import com.iailab.module.data.point.service.*; |
| | | import com.iailab.module.data.point.vo.DaPointCountReqVO; |
| | | import com.iailab.module.data.point.vo.DaPointPageReqVO; |
| | | import com.iailab.module.data.point.vo.PointImportExcelVO; |
| | | import com.iailab.module.data.point.vo.PointImportRespVO; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Long getPointCount(DaPointCountReqVO reqVO ) { |
| | | if (StringUtils.isNotBlank(reqVO.getCollectQuality())){ |
| | | return daPointDao.getPointCount(reqVO); |
| | | } |
| | | QueryWrapper<DaPointEntity> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.eq(reqVO.getIsEnable() != null, "is_enable", reqVO.getIsEnable()); |
| | | return daPointDao.selectCount(queryWrapper); |
| | | } |
| | | |
| | | @Override |
| | | public List<DaPointDTO> getMathPoint(String freq) { |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("pointType", PointTypeEnum.CALCULATE_POINT.getCode()); |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.iailab.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Schema(description = "数据平台 - 测点异常分页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class DaPointBadHistoryPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "测点编码") |
| | | private String pointNo; |
| | | |
| | | @Schema(description = "测点名称") |
| | | private String pointName; |
| | | |
| | | @Schema(description = "测点Tag") |
| | | private String tagNo; |
| | | |
| | | @Schema(description = "开始时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date startTime; |
| | | |
| | | @Schema(description = "结束时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date endTime; |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @author Jay |
| | | */ |
| | | @Schema(description = "数据平台 - 测点数量查询 Request VO") |
| | | @Data |
| | | public class DaPointCountReqVO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Schema(description = "测点类型") |
| | | private String pointType; |
| | | |
| | | @Schema(description = "数据类型") |
| | | private String dataType; |
| | | |
| | | @Schema(description = "是否启用") |
| | | private Integer isEnable; |
| | | |
| | | @Schema(description = "采集质量") |
| | | private String collectQuality; |
| | | |
| | | @Schema(description = "开始时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date startTime; |
| | | |
| | | @Schema(description = "结束时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date endTime; |
| | | |
| | | } |
| | |
| | | - t_da_point_collect_status |
| | | - t_arc_data |
| | | - t_arc_setting |
| | | - t_da_point_bad_history |
| | | app: |
| | | app-key: data |
| | | app-secret: 85b0df7edc3df3611913df34ed695011 |
| | |
| | | </where> |
| | | </select> |
| | | |
| | | <select id="getPointCount" resultType="long"> |
| | | select count(*) |
| | | from t_da_point t1 |
| | | left join t_da_point_collect_status t2 on t2.point_no = t1.point_no |
| | | <where> |
| | | <if test="isEnable != null "> |
| | | and t1.is_enable = #{isEnable} |
| | | </if> |
| | | <if test="collectQuality != null and collectQuality != ''"> |
| | | and t2.collect_quality = #{collectQuality} |
| | | </if> |
| | | <if test="startTime != null"> |
| | | and t2.collect_time >= #{startTime} |
| | | </if> |
| | | <if test="endTime != null"> |
| | | and t2.collect_time <= #{endTime} |
| | | </if> |
| | | </where> |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | primary: master |
| | | datasource: |
| | | master: |
| | | url: jdbc:mysql://127.0.0.1:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 |
| | | url: jdbc:mysql://172.16.8.100:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 |
| | | # url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例 |
| | | # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例 |
| | | # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 |
| | |
| | | stScheduleSchemeService.updateTime(scheduleResult.getSchemeId(), scheduleResult.getScheduleTime(), scheduleResult.getResultCode()); |
| | | log.info("调度计算结束: " + System.currentTimeMillis()); |
| | | } catch (Exception ex) { |
| | | log.info("调度计算异常: " + System.currentTimeMillis()); |
| | | ex.printStackTrace(); |
| | | log.error("调度计算异常: " + System.currentTimeMillis(),ex); |
| | | return resp; |
| | | } |
| | | return resp; |
| | |
| | | |
| | | default List<MenuDO> selectList(MenuListReqVO reqVO) { |
| | | return selectList(new LambdaQueryWrapperX<MenuDO>() |
| | | .eqIfPresent(MenuDO::getStatus, reqVO.getStatus()) |
| | | .likeIfPresent(MenuDO::getName, reqVO.getName())); |
| | | } |
| | | |