commit b263d0430d58bd1324655469ec824bcf452178cc Author: jiulinxiri Date: Mon Aug 21 21:35:29 2023 +0800 QAI项目的初始化 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e24cd10 --- /dev/null +++ b/.gitignore @@ -0,0 +1,143 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +.idea +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..be1d01d --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.14 + + + + org.example + QAI + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + 3.1.2 + + + org.springframework.boot + spring-boot-starter-aop + 3.1.2 + + + io.github.gemingjia + gear-wenxinworkshop-starter + 0.0.7 + + + com.github.xiaoymin + knife4j-spring-boot-starter + 3.0.3 + + + org.projectlombok + lombok + 1.18.28 + + + org.springframework.boot + spring-boot-starter-test + 2.7.14 + test + + + + junit + junit + 4.13.2 + test + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + 17 + 17 + UTF-8 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + \ No newline at end of file diff --git a/src/main/java/cn/honour/QAIApplication.java b/src/main/java/cn/honour/QAIApplication.java new file mode 100644 index 0000000..6ccad2d --- /dev/null +++ b/src/main/java/cn/honour/QAIApplication.java @@ -0,0 +1,14 @@ +package cn.honour; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author qiaoxiaoxu + */ +@SpringBootApplication +public class QAIApplication { + public static void main(String[] args) { + SpringApplication.run(QAIApplication.class, args); + } +} diff --git a/src/main/java/cn/honour/common/BaseResponse.java b/src/main/java/cn/honour/common/BaseResponse.java new file mode 100644 index 0000000..cd4e296 --- /dev/null +++ b/src/main/java/cn/honour/common/BaseResponse.java @@ -0,0 +1,27 @@ +package cn.honour.common; + +import com.gearwenxin.common.ErrorCode; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class BaseResponse implements Serializable { + private int code; + private T data; + private String message; + + public BaseResponse(int code, T data, String message) { + this.code = code; + this.data = data; + this.message = message; + } + + public BaseResponse(int code, T data) { + this(code, data, ""); + } + + public BaseResponse(ErrorCode errorCode) { + this(errorCode.getCode(), null, errorCode.getMessage()); + } +} diff --git a/src/main/java/cn/honour/common/LogInterceptor.java b/src/main/java/cn/honour/common/LogInterceptor.java new file mode 100644 index 0000000..d1739a0 --- /dev/null +++ b/src/main/java/cn/honour/common/LogInterceptor.java @@ -0,0 +1,103 @@ +package cn.honour.common; + +import cn.honour.exception.ResultUtils; +import com.gearwenxin.common.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * 请求响应日志 + */ +@Aspect +@Component +@Slf4j +public class LogInterceptor { + private final Map> ipRequestRecords = new ConcurrentHashMap<>(); + private final Map ipHourlyRequestCounts = new ConcurrentHashMap<>(); + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + public LogInterceptor() { + // 设置定时任务,每小时清理一次请求记录 + scheduler.scheduleAtFixedRate(this::clearExpiredRecords, 1, 1, TimeUnit.HOURS); + } + + private Map ipListMap = new ConcurrentHashMap<>(); + + @Around("execution(* cn.honour.controller.*.*(..))") + public Object doInterceptor(ProceedingJoinPoint point) throws Throwable { + HttpServletRequest httpServletRequest = getHttpServletRequest(); + String ip = httpServletRequest.getRemoteAddr(); + // 获取亲求路径 + RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); + HttpServletRequest httpServletRequest1 = ((ServletRequestAttributes) requestAttributes).getRequest(); + String requestId = UUID.randomUUID().toString(); + String uri = httpServletRequest1.getRequestURI(); + + Object[] args = point.getArgs(); + String reqParam = "[" + StringUtils.join(args, ", ") + "]"; + ipListMap.put("120.216.179.82", "blacklist"); + // 输出请求日志 + log.info("request start,id: {}, path: {}, ip: {}, params: {}", requestId, uri, + httpServletRequest1.getRemoteHost(), reqParam); + // 检查名单 + String listType = ipListMap.get(ip); + if ("blacklist".equals(listType)) { + log.warn("IP {} is in the blacklist.", ip); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "IP已被加入黑名单!"); + } else if ("whitelist".equals(listType)) { + // 在白名单中处理方式,这里示意直接放行 + return point.proceed(); + } + + // 检测每小时内请求的次数 + Integer hourlyRequestCounts = ipHourlyRequestCounts.getOrDefault(ip, 0); + if (hourlyRequestCounts >= 30) { + log.warn("IP {} has been blacklist due to excessive requests.", ip); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "次数过多"); + } + + // 记录请求时间 + long currentTimeMillis = System.currentTimeMillis(); + List requests = ipRequestRecords.computeIfAbsent(ip, k -> new ArrayList<>()); + requests.add(currentTimeMillis); + + // 清理1分钟内请求次数 + requests.removeIf(timestap -> timestap < currentTimeMillis - 60000); + + // 检测1分钟内的请求次数 + if(requests.size() > 8) { + log.warn("IP {} has made too many request in the last minute.", ip); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "次数过快!"); + } + + // 执行原方法 + return point.proceed(); + } + + private void clearExpiredRecords() { + long currentTimeMillis = System.currentTimeMillis(); + ipRequestRecords.forEach((ip, requests) -> { + requests.removeIf(timestamp -> timestamp < currentTimeMillis - 3600000); + ipHourlyRequestCounts.put(ip, requests.size()); + }); + } + + private HttpServletRequest getHttpServletRequest() { + RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); + return ((ServletRequestAttributes)requestAttributes).getRequest(); + } +} diff --git a/src/main/java/cn/honour/config/CorsConfig.java b/src/main/java/cn/honour/config/CorsConfig.java new file mode 100644 index 0000000..dc6b3dc --- /dev/null +++ b/src/main/java/cn/honour/config/CorsConfig.java @@ -0,0 +1,23 @@ +package cn.honour.config; + +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * 全局跨域配置 + */ +@Configurable +public class CorsConfig implements WebMvcConfigurer { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + // 允许发送 Cookie + .allowCredentials(true) + // 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突) + .allowedOriginPatterns("*") + .allowedMethods("GET", "POST", "DELETE", "OPTIONS") + .allowedHeaders("*") + .exposedHeaders("*"); + } +} diff --git a/src/main/java/cn/honour/config/Knife4jConfig.java b/src/main/java/cn/honour/config/Knife4jConfig.java new file mode 100644 index 0000000..8b3a88e --- /dev/null +++ b/src/main/java/cn/honour/config/Knife4jConfig.java @@ -0,0 +1,30 @@ +package cn.honour.config; + +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.context.annotation.Profile; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configurable +@EnableSwagger2 +@Profile("dev") +public class Knife4jConfig { + public Docket defaultApi2() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(new ApiInfoBuilder() + .title("wenxin") + .description("wenxin") + .version("1.0") + .build()) + .select() + // 指定 Controller 扫描包路径 + .apis(RequestHandlerSelectors.basePackage("cn.honour.controller")) + .paths(PathSelectors.any()) + .build(); + } +} diff --git a/src/main/java/cn/honour/controller/BloomZ7BController.java b/src/main/java/cn/honour/controller/BloomZ7BController.java new file mode 100644 index 0000000..ef7f185 --- /dev/null +++ b/src/main/java/cn/honour/controller/BloomZ7BController.java @@ -0,0 +1,75 @@ +package cn.honour.controller; + +import cn.honour.common.BaseResponse; +import cn.honour.exception.ResultUtils; +import com.gearwenxin.client.BloomZ7BClient; +import com.gearwenxin.entity.chatmodel.ChatBaseRequest; +import com.gearwenxin.entity.response.ChatResponse; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +import javax.annotation.Resource; + +@RestController +@RequestMapping("/bloomz7b") +public class BloomZ7BController { + @Resource + private BloomZ7BClient bloomz7BClient; + + // 单轮对话 + @PostMapping("/chat") + public BaseResponse chatSingle(String msg) { + ChatResponse response = bloomz7BClient.chatSingle(msg).block(); + return ResultUtils.success(response); + } + + // 连续对话 + @PostMapping("/chats") + public BaseResponse chatCont(String msg, String msgUid) { + ChatResponse response = bloomz7BClient.chatCont(msg, msgUid).block(); + return ResultUtils.success(response); + } + + // 流式返回,单次对话 + @PostMapping(value = "/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux chatSingleStream(String msg) { + return bloomz7BClient.chatSingleOfStream(msg); + } + + // 流式返回,连续对话 + @PostMapping(value = "/stream/chats", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux chatContStream(String msg, String msgUid) { + return bloomz7BClient.chatContOfStream(msg, msgUid); + } + + // 模板对话 + @PostMapping("/param/chat") + public BaseResponse pChatSingle(@RequestBody ChatBaseRequest chatBaseRequest) { + ChatResponse chatResponse = bloomz7BClient.chatSingle(chatBaseRequest).block(); + return ResultUtils.success(chatResponse); + } + + // 连续对话 + @PostMapping("/param/chats") + public BaseResponse pChatCont(@RequestBody ChatBaseRequest chatBaseRequest) { + ChatResponse response = bloomz7BClient.chatCont(chatBaseRequest, chatBaseRequest.getUserId()).block(); + return ResultUtils.success(response); + } + + // 流式返回,单次对话 + @PostMapping(value = "/param/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux pChatSingleStream(@RequestBody ChatBaseRequest chatBaseRequest) { + return bloomz7BClient.chatSingleOfStream(chatBaseRequest); + } + + // 流式返回,连续对话 + @PostMapping(value = "/param/stream/chats", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux pChatContStream(@RequestBody ChatBaseRequest chatBaseRequest, String msgUid) { + return bloomz7BClient.chatContOfStream(chatBaseRequest, msgUid); + } + +} diff --git a/src/main/java/cn/honour/controller/ErnieBotController.java b/src/main/java/cn/honour/controller/ErnieBotController.java new file mode 100644 index 0000000..4f833f0 --- /dev/null +++ b/src/main/java/cn/honour/controller/ErnieBotController.java @@ -0,0 +1,77 @@ +package cn.honour.controller; + +import cn.honour.common.BaseResponse; +import cn.honour.exception.ResultUtils; +import com.gearwenxin.client.ernie.ErnieBotClient; +import com.gearwenxin.entity.chatmodel.ChatErnieRequest; +import com.gearwenxin.entity.response.ChatResponse; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +import javax.annotation.Resource; + +/** + * 文心一言的相关接口 + * @author qiaoxiaoxu + */ +@RestController +@RequestMapping("/ernie") +public class ErnieBotController { + @Resource + private ErnieBotClient ernieBotClient; + + // 单轮对话 + @PostMapping("/chat") + public BaseResponse chatSingle(String msg) { + ChatResponse chatResponse = ernieBotClient.chatSingle(msg).block(); + return ResultUtils.success(chatResponse); + } + // 连续对话 + @PostMapping("/chats") + public BaseResponse chatCont(String msg, String msgUid) { + ChatResponse chatResponseMono = ernieBotClient.chatCont(msg, msgUid).block(); + return ResultUtils.success(chatResponseMono); + } + + // 流式返回,单次对话 + @PostMapping(value = "/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux chatSingleStream(String msg) { + return ernieBotClient.chatSingleOfStream(msg); + } + + // 流式返回,连续对话 + @PostMapping(value = "/stream/chats", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux chatContStream(String msg, String msgUid) { + return ernieBotClient.chatContOfStream(msg, msgUid); + } + + // 模板对话 + @PostMapping("/param/chat") + public BaseResponse pChatSingle(@RequestBody ChatErnieRequest chatErnieRequest) { + ChatResponse chatResponse = ernieBotClient.chatSingle(chatErnieRequest).block(); + return ResultUtils.success(chatResponse); + } + + // 连续对话 + @PostMapping("/param/chats") + public BaseResponse pChatCont(@RequestBody ChatErnieRequest chatErnieRequest) { + ChatResponse response = ernieBotClient.chatCont(chatErnieRequest, chatErnieRequest.getUserId()).block(); + return ResultUtils.success(response); + } + + // 流式返回,单次对话 + @PostMapping(value = "/param/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux pChatSingleStream(@RequestBody ChatErnieRequest chatErnieRequest) { + return ernieBotClient.chatSingleOfStream(chatErnieRequest); + } + + // 流式返回,连续对话 + @PostMapping(value = "/param/stream/chats", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux pChatContStream(@RequestBody ChatErnieRequest chatErnieRequest, String msgUid) { + return ernieBotClient.chatContOfStream(chatErnieRequest, msgUid); + } +} diff --git a/src/main/java/cn/honour/controller/ErnieBotTurboController.java b/src/main/java/cn/honour/controller/ErnieBotTurboController.java new file mode 100644 index 0000000..581decb --- /dev/null +++ b/src/main/java/cn/honour/controller/ErnieBotTurboController.java @@ -0,0 +1,77 @@ +package cn.honour.controller; + +import cn.honour.common.BaseResponse; +import cn.honour.exception.ResultUtils; +import com.gearwenxin.client.ernie.ErnieBotTurboClient; +import com.gearwenxin.entity.chatmodel.ChatBaseRequest; +import com.gearwenxin.entity.response.ChatResponse; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +import javax.annotation.Resource; + +/** + * @author qiaoxiaoxu + */ +@RestController +@RequestMapping("/turbo") +public class ErnieBotTurboController { + @Resource + private ErnieBotTurboClient ernieBotTurboClient; + + // 单轮对话 + @PostMapping("/chat") + public BaseResponse chatSingle(String msg) { + ChatResponse chatResponse = ernieBotTurboClient.chatSingle(msg).block(); + return ResultUtils.success(chatResponse); + } + + // 连续对话 + @PostMapping("/chats") + public BaseResponse chatCont(String msg, String msgUid) { + ChatResponse response = ernieBotTurboClient.chatCont(msg, msgUid).block(); + return ResultUtils.success(response); + } + + // 流式返回,单次对话 + @PostMapping(value = "/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux chatSingleStream(String msg) { + return ernieBotTurboClient.chatSingleOfStream(msg); + } + + // 流式返回,连续对话 + @PostMapping(value = "/stream/chats", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux chatContStream(String msg, String msgUid) { + return ernieBotTurboClient.chatContOfStream(msg, msgUid); + } + + // 模板对话 + @PostMapping("/param/chat") + public BaseResponse pChatSingle(@RequestBody ChatBaseRequest chatBaseRequest) { + ChatResponse chatResponse = ernieBotTurboClient.chatSingle(chatBaseRequest).block(); + return ResultUtils.success(chatResponse); + } + + // 连续对话 + @PostMapping("/param/chats") + public BaseResponse pChatCont(@RequestBody ChatBaseRequest chatBaseRequest) { + ChatResponse response = ernieBotTurboClient.chatCont(chatBaseRequest, chatBaseRequest.getUserId()).block(); + return ResultUtils.success(response); + } + + // 流式返回,单次对话 + @PostMapping(value = "/param/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux pChatSingleStream(@RequestBody ChatBaseRequest chatBaseRequest) { + return ernieBotTurboClient.chatSingleOfStream(chatBaseRequest); + } + + // 流式返回,连续对话 + @PostMapping(value = "/param/stream/chats", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux pChatContStream(@RequestBody ChatBaseRequest chatBaseRequest, String msgUid) { + return ernieBotTurboClient.chatContOfStream(chatBaseRequest, msgUid); + } +} diff --git a/src/main/java/cn/honour/controller/PromptController.java b/src/main/java/cn/honour/controller/PromptController.java new file mode 100644 index 0000000..e84d17d --- /dev/null +++ b/src/main/java/cn/honour/controller/PromptController.java @@ -0,0 +1,39 @@ +package cn.honour.controller; + +import cn.honour.common.BaseResponse; +import cn.honour.exception.ResultUtils; +import com.gearwenxin.client.PromptBotClient; +import com.gearwenxin.entity.chatmodel.ChatPromptRequest; +import com.gearwenxin.entity.response.PromptResponse; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/propt") +public class PromptController { + @Resource + private PromptBotClient promptClient; + + // 模板对话 + @PostMapping + public BaseResponse chatSingle(int id) { + + Map map = new HashMap<>(); + map.put("article", "人们都说:“桂林山水甲天下。”我们乘着木船,荡漾在漓江上,来观赏桂林的山水。\n" + + "我看见过波澜壮阔的大海,玩赏过水平如镜的西湖,却从没看见过漓江这样的水。漓江的水真静啊,静得让你感觉不到它在流动;漓江的水真清啊,清得可以看见江底的沙石;漓江的水真绿啊,绿得仿佛那是一块无瑕的翡翠。船桨激起的微波扩散出一道道水纹,才让你感觉到船在前进,岸在后移。\n" + + "我攀登过峰峦雄伟的泰山,游览过红叶似火的香山,却从没看见过桂林这一带的.山,桂林的山真奇啊,一座座拔地而起,各不相连,像老人,像巨象,像骆驼,奇峰罗列,形态万千;桂林的山真秀啊,像翠绿的屏障,像新生的竹笋,色彩明丽,倒映水中;桂林的山真险啊,危峰兀立,怪石嶙峋,好像一不小心就会栽倒下来。\n" + + "这样的山围绕着这样的水,这样的水倒映着这样的山,再加上空中云雾迷蒙,山间绿树红花,江上竹筏小舟,让你感到像是走进了连绵不断的画卷,真是“舟行碧波上,人在画中游”。"); + map.put("number", "20"); + ChatPromptRequest promptRequest = new ChatPromptRequest(); + promptRequest.setId(id); + promptRequest.setParamMap(map); + PromptResponse promptResponse = promptClient.chatPrompt(promptRequest).block(); + + return ResultUtils.success(promptResponse); + } +} diff --git a/src/main/java/cn/honour/exception/BusinessException.java b/src/main/java/cn/honour/exception/BusinessException.java new file mode 100644 index 0000000..335ae27 --- /dev/null +++ b/src/main/java/cn/honour/exception/BusinessException.java @@ -0,0 +1,30 @@ +package cn.honour.exception; + +import com.gearwenxin.common.ErrorCode; + +/** + * 自定义异常类 + * @author qiaoxiaoxu + */ +public class BusinessException extends RuntimeException { + private final int code; + + public BusinessException(int code, String message) { + super(message); + this.code = code; + } + + public BusinessException(ErrorCode errorCode){ + super(errorCode.getMessage()); + this.code = errorCode.getCode(); + } + + public BusinessException(ErrorCode errorCode, String message){ + super(message); + this.code = errorCode.getCode(); + } + + public int getCode() { + return code; + } +} diff --git a/src/main/java/cn/honour/exception/GlobalExceptionHandler.java b/src/main/java/cn/honour/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..b1386a4 --- /dev/null +++ b/src/main/java/cn/honour/exception/GlobalExceptionHandler.java @@ -0,0 +1,29 @@ +package cn.honour.exception; + +import cn.honour.common.BaseResponse; +import com.gearwenxin.common.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 全局异常处理器 + * @author qiaoxiaoxu + */ + +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + @ExceptionHandler(BusinessException.class) + public BaseResponse businessExceptionHandler(BusinessException e) { + log.error("BusinessException", e); + return ResultUtils.error(e.getCode(), e.getMessage()); + } + + @ExceptionHandler(RuntimeException.class) + public BaseResponse runtimeExceptionHandler(RuntimeException e) { + log.error("RuntimeException", e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误"); + } +} diff --git a/src/main/java/cn/honour/exception/ResultUtils.java b/src/main/java/cn/honour/exception/ResultUtils.java new file mode 100644 index 0000000..50562c9 --- /dev/null +++ b/src/main/java/cn/honour/exception/ResultUtils.java @@ -0,0 +1,45 @@ +package cn.honour.exception; + +import cn.honour.common.BaseResponse; +import com.gearwenxin.common.ErrorCode; + +public class ResultUtils { + /** + * 成功 + * @param data + * @return + * @param + */ + public static BaseResponse success(T data) { + return new BaseResponse<>(0, data, "ok"); + } + + /** + * 失败 + * @param errorCode + * @return + */ + public static BaseResponse error(ErrorCode errorCode) { + return new BaseResponse<>(errorCode); + } + + /** + * 失败 + * @param code + * @param message + * @return + */ + public static BaseResponse error(int code, String message) { + return new BaseResponse<>(code, null, message); + } + + /** + * 失败 + * @param errorCode + * @param message + * @return + */ + public static BaseResponse error(ErrorCode errorCode, String message) { + return new BaseResponse<>(errorCode.getCode(), null, message); + } +} diff --git a/src/main/java/cn/honour/exception/ThrowUtils.java b/src/main/java/cn/honour/exception/ThrowUtils.java new file mode 100644 index 0000000..de72a4d --- /dev/null +++ b/src/main/java/cn/honour/exception/ThrowUtils.java @@ -0,0 +1,39 @@ +package cn.honour.exception; + +import com.gearwenxin.common.ErrorCode; + +/** + * 抛弃异常工具类 + * @author qiaoxiaoxu + */ +public class ThrowUtils { + /** + * 条件成立则抛弃异常 + * @param condition + * @param runtimeException + */ + public static void throwIf(boolean condition, RuntimeException runtimeException) { + if (condition) { + throw runtimeException; + } + } + + /** + * 条件成立则抛异常 + * @param condition + * @param errorCode + */ + public static void throwIf(boolean condition, ErrorCode errorCode) { + throwIf(condition, new BusinessException(errorCode)); + } + + /** + * 条件成立则抛异常 + * @param condition + * @param errorCode + * @param message + */ + public static void throwIf(boolean condition, ErrorCode errorCode, String message) { + throwIf(condition, new BusinessException(errorCode, message)); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..794944e --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,17 @@ +spring: + application: + name: qai + mvc: + pathmatch: + matching-strategy: ANT_PATH_MATCHER +server: + port: 7529 + servlet: + context-path: /api + +gear: + wenxin: + api-key: kQnoazc1Ph9ApVsiKLO4N3Hi + secret-key: 6XIDixfpvffvsDkm9ZGv4Bip008QXgBP + chat-glm2-6b-url: http://asdhkjashdkjas + star-coder-url: http://asdhkjashdkjas \ No newline at end of file