Bladeren bron

添加第三方api子项目

lighter 8 maanden geleden
bovenliggende
commit
64eb5c8c89

+ 2 - 0
pom.xml

@@ -23,6 +23,7 @@
         <thyy-haikang>0.0.4</thyy-haikang>
         <thyy-beinhospital>0.0.1</thyy-beinhospital>
         <thyy-emr-query>1.5.0</thyy-emr-query>
+        <thyy-thirdpart-api>0.0.1</thyy-thirdpart-api>
     </properties>
     <modules>
         <module>thyy-archive</module>
@@ -31,6 +32,7 @@
         <module>thyy-haikang</module>
         <module>thyy-beinhospital</module>
         <module>thyy-emr-query</module>
+        <module>thyy-thirdpart-api</module>
     </modules>
     <dependencies>
         <dependency>

+ 60 - 0
thyy-thirdpart-api/pom.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.thyy.business</groupId>
+        <artifactId>thyy-business</artifactId>
+        <version>0.0.1</version>
+    </parent>
+    <groupId>org.thyy</groupId>
+    <artifactId>thyy-thirdpart-api</artifactId>
+    <version>${thyy-thirdpart-api}</version>
+    <name>thyy-thirdpart-api</name>
+    <description>thyy-thirdpart-api</description>
+
+    <properties>
+        <java.version>21</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>cn.xfyun</groupId>
+            <artifactId>websdk-java-speech</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.thyy.business</groupId>
+            <artifactId>thyy-utils</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 15 - 0
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/ThyyThirdpartApiApplication.java

@@ -0,0 +1,15 @@
+package org.thyy.thirdpartapi;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan("org.thyy.*")
+public class ThyyThirdpartApiApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ThyyThirdpartApiApplication.class, args);
+    }
+
+}

+ 16 - 0
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/xfyun/XfConfig.java

@@ -0,0 +1,16 @@
+package org.thyy.thirdpartapi.xfyun;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "thyy.xfyun")
+public class XfConfig {
+    private String appId;
+    private String apiKey;
+    private String apiSecret;
+    private String directory;
+    private String speechUrl;
+}

+ 111 - 0
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/xfyun/XfTtsApi.java

@@ -0,0 +1,111 @@
+package org.thyy.thirdpartapi.xfyun;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.xfyun.api.TtsClient;
+import cn.xfyun.model.response.TtsResponse;
+import cn.xfyun.service.tts.AbstractTtsWebSocketListener;
+import jakarta.annotation.PostConstruct;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.Response;
+import okhttp3.WebSocket;
+import org.springframework.beans.factory.annotation.Autowired;
+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 org.thyy.thirdpartapi.xfyun.request.TtsRequest;
+import org.thyy.utils.exception.ExceptionEnum;
+import org.thyy.utils.result.R;
+import org.thyy.utils.result.ResultVo;
+
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@RestController
+@RequestMapping("/xfTtsApi")
+public class XfTtsApi {
+    private TtsClient ttsClient;
+    private final XfConfig cfg;
+
+    @Autowired
+    public XfTtsApi(XfConfig cfg) {
+        this.cfg = cfg;
+    }
+
+    @PostConstruct
+    public void initTtsClient() {
+        try {
+            if (StrUtil.isBlank(cfg.getDirectory())) {
+                cfg.setDirectory(System.getProperty("user.dir"));
+            }
+            ttsClient = new TtsClient.Builder()
+                    .signature(cfg.getAppId(), cfg.getApiKey(), cfg.getApiSecret())
+                    .vcn("aisjinger").volume(100).build();
+            log.info("讯飞SDK初始化成功。");
+        } catch (Exception e) {
+            log.error("讯飞SDK初始化失败:", e);
+        }
+    }
+
+    @PostMapping("/textToSpeech")
+    public ResultVo<String> textToSpeech(@RequestBody TtsRequest request) {
+        String filePath = cfg.getDirectory() + File.separator + request.getId() + ".mp3";
+        FileUtil.del(filePath);
+
+        final Boolean[] progress = { false, null };
+        final String[] message = {""};
+        try  {
+            File file = new File(filePath);
+            ttsClient.send(request.getText(), new AbstractTtsWebSocketListener(file) {
+                @Override
+                public void onSuccess(byte[] bytes) {
+                    progress[0] = true;
+                }
+                @Override
+                public void onFail(WebSocket webSocket, Throwable throwable, Response response) {
+                    log.error("[onFail]生成语音文件失败:{}", throwable.getMessage());
+                    message[0] = throwable.getMessage();
+                }
+
+                @Override
+                public void onBusinessFail(WebSocket webSocket, TtsResponse ttsResponse) {
+                    log.error("[onBusinessFail]生成语音文件失败:{}", ttsResponse.toString());
+                    message[0] = ttsResponse.toString();
+                }
+
+                @Override
+                public void onClosing(WebSocket webSocket, int code, String reason) {
+                    super.onClosing(webSocket, code, reason);
+                }
+
+                @Override
+                public void onClosed(WebSocket webSocket, int code, String reason) {
+                    super.onClosed(webSocket, code, reason);
+                    progress[1] = true;
+                }
+            });
+        } catch (Exception e) {
+            log.error("生成语音文件失败", e);
+            log.error("错误码查询链接:https://www.xfyun.cn/document/error-code");
+            message[0] = e.getMessage();
+            progress[1] = true;
+        }
+
+        while (null == progress[1]) {
+            try {
+                TimeUnit.MILLISECONDS.sleep(1000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        if (StrUtil.isNotBlank(message[0])) {
+            return R.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, message[0]);
+        }
+
+        String voiceUrl = cfg.getSpeechUrl() + "/" + request.getId() + ".mp3";
+        return R.ok(voiceUrl);
+    }
+
+}

+ 9 - 0
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/xfyun/request/TtsRequest.java

@@ -0,0 +1,9 @@
+package org.thyy.thirdpartapi.xfyun.request;
+
+import lombok.Data;
+
+@Data
+public class TtsRequest {
+    private String id;
+    private String text;
+}

+ 13 - 0
thyy-thirdpart-api/src/main/resources/application.yml

@@ -0,0 +1,13 @@
+spring:
+  application:
+    name: thyy-thirdpart-api
+server:
+  port: 21701
+
+thyy:
+  xfyun:
+    app-id: fdde4cef
+    api-key: 95a78dd3cfcc4863e3c003352ca8ec65
+    api-secret: OWZjZGE4NjI3MDdkYzg4ZjllY2VjNGQ0
+    directory: D:\a.snapshot\resource\voice
+    speechUrl: http://172.16.32.160:8080/resource/voice

+ 124 - 0
thyy-thirdpart-api/src/main/resources/logback-spring.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+    <springProperty name="application_name" scope="context" source="spring.application.name"/>
+    <springProperty scope="context" name="LOG_HOME" source="logging.path"
+                    defaultValue="${user.dir}/logs/${application_name}"/>
+
+    <!-- 日志级别 -->
+    <springProperty scope="context" name="LOG_ROOT_LEVEL" source="logging.level.root" defaultValue="INFO"/>
+
+    <!--  标识这个"STDOUT" 将会添加到这个logger -->
+    <springProperty scope="context" name="STDOUT" source="log.stdout" defaultValue="STDOUT"/>
+
+    <!-- 日志文件名称-->
+    <property name="LOG_PREFIX" value="spring-boot-logback"/>
+
+    <!-- 日志文件编码-->
+    <property name="LOG_CHARSET" value="UTF-8"/>
+
+    <!-- 日志文件路径+日期-->
+    <property name="LOG_DIR" value="${LOG_HOME}/%d{yyyy-MM-dd}"/>
+
+    <!--对日志进行格式化-->
+    <property name="LOG_MSG" value="- [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%level] [%thread] [%logger{16}] --> %msg%n "/>
+
+    <!--文件大小,默认10MB-->
+    <property name="MAX_FILE_SIZE" value="30MB"/>
+
+    <!-- 配置日志的滚动时间 ,value表示保留日志的天数,0表示永久保存 -->
+    <property name="MAX_HISTORY" value="0"/>
+
+
+    <!-- 彩色日志 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
+    <conversionRule conversionWord="wex"
+                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+    <conversionRule conversionWord="wEx"
+                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN"
+              value="-[%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){blue}] [%clr(%level)] [%clr(%thread)] [%clr(%logger{16}){cyan}] %clr(-->){red} %clr(%msg%n){yellow}"/>
+
+    <!--输出到控制台-->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <!-- 输出的日志内容格式化-->
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+        </layout>
+    </appender>
+
+    <!--输出到文件-->
+    <appender name="0" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    </appender>
+
+    <!-- 定义 ALL 日志的输出方式:-->
+    <appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!--日志文件路径,日志文件名称-->
+        <File>${LOG_HOME}/all_${LOG_PREFIX}.log</File>
+
+        <!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
+            <!--日志文件路径,新的 ALL 日志文件名称,“ i ” 是个变量 -->
+            <FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}.log</FileNamePattern>
+
+            <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
+            <MaxHistory>${MAX_HISTORY}</MaxHistory>
+            <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+        </rollingPolicy>
+
+        <!-- 输出的日志内容格式化-->
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>${LOG_MSG}</pattern>
+        </layout>
+    </appender>
+
+    <!-- 定义 ERROR 日志的输出方式:-->
+    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 下面为配置只输出error级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <OnMismatch>DENY</OnMismatch>
+            <OnMatch>ACCEPT</OnMatch>
+        </filter>
+        <!--日志文件路径,日志文件名称-->
+        <File>${LOG_HOME}/err_${LOG_PREFIX}.log</File>
+
+        <!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
+            <!--日志文件路径,新的 ERR 日志文件名称,“ i ” 是个变量 -->
+            <FileNamePattern>${LOG_DIR}/err_${LOG_PREFIX}.log</FileNamePattern>
+
+            <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
+            <MaxHistory>${MAX_HISTORY}</MaxHistory>
+            <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+        </rollingPolicy>
+
+        <!-- 输出的日志内容格式化-->
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <Pattern>${LOG_MSG}</Pattern>
+        </layout>
+    </appender>
+
+    <!-- additivity 设为false,则logger内容不附加至root ,配置以配置包下的所有类的日志的打印,级别是 ERROR-->
+
+    <logger name="org.springframework" level="ERROR"/>
+    <logger name="org.apache.commons" level="ERROR"/>
+    <!--    <logger name="th.itcenter.apps.controller.logger.LoggingController" level="WARN"/>-->
+    <!-- ${LOG_ROOT_LEVEL} 日志级别 -->
+    <root level="${LOG_ROOT_LEVEL}">
+
+        <!-- 标识这个"${STDOUT}"将会添加到这个logger -->
+        <appender-ref ref="${STDOUT}"/>
+
+        <!-- FILE_ALL 日志输出添加到 logger -->
+        <appender-ref ref="FILE_ALL"/>
+
+        <!-- FILE_ERROR 日志输出添加到 logger -->
+        <appender-ref ref="FILE_ERROR"/>
+    </root>
+
+</configuration>

+ 13 - 0
thyy-thirdpart-api/src/test/java/org/thyy/thirdpartapi/ThyyThirdpartApiApplicationTests.java

@@ -0,0 +1,13 @@
+package org.thyy.thirdpartapi;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class ThyyThirdpartApiApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}