Skip to content

Commit 724d8c1

Browse files
committed
添加翻译功能,包括翻译请求和响应的 DTO,翻译服务实现,控制器,前端页面及样式,更新 Azure 配置和国际化文件
1 parent 8cdff84 commit 724d8c1

17 files changed

Lines changed: 396 additions & 26 deletions

File tree

pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@
278278
<artifactId>redisson</artifactId>
279279
<version>${redisson.version}</version>
280280
</dependency>
281+
<dependency>
282+
<groupId>org.projectlombok</groupId>
283+
<artifactId>lombok</artifactId>
284+
<version>1.18.42</version>
285+
<scope>provided</scope>
286+
</dependency>
281287
<dependency>
282288
<groupId>org.testcontainers</groupId>
283289
<artifactId>jdbc</artifactId>
@@ -322,6 +328,15 @@
322328
<plugin>
323329
<groupId>org.apache.maven.plugins</groupId>
324330
<artifactId>maven-compiler-plugin</artifactId>
331+
<configuration>
332+
<annotationProcessorPaths>
333+
<path>
334+
<groupId>org.projectlombok</groupId>
335+
<artifactId>lombok</artifactId>
336+
<version>1.18.42</version>
337+
</path>
338+
</annotationProcessorPaths>
339+
</configuration>
325340
</plugin>
326341
<plugin>
327342
<groupId>org.apache.maven.plugins</groupId>

src/main/docker/mysql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: flamingrose
33
services:
44
mysql:
5-
image: mysql:8.3.0
5+
image: mysql:8.0.36
66
volumes:
77
- ./config/mysql:/etc/mysql/conf.d
88
# - ~/volumes/jhipster/flamingrose/mysql/:/var/lib/mysql/
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.github.flamingrose.config;
2+
3+
import java.util.Map;
4+
import org.springframework.beans.factory.annotation.Qualifier;
5+
import org.springframework.beans.factory.annotation.Value;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.web.client.RestClient;
9+
10+
@Configuration
11+
public class AzureConfig {
12+
13+
@Value("${azure.translator.key}")
14+
private String apiKey;
15+
16+
@Value("${azure.translator.endpoint}")
17+
private String endpoint;
18+
19+
@Value("${azure.translator.region}")
20+
private String region;
21+
22+
@Bean
23+
@Qualifier("azureRestClient")
24+
public RestClient azureRestClient() {
25+
return RestClient.builder()
26+
.baseUrl(endpoint)
27+
.defaultHeaders(headers -> {
28+
headers.add("Ocp-Apim-Subscription-Key", apiKey);
29+
headers.add("Ocp-Apim-Subscription-Region", region);
30+
headers.add("Content-type", "application/json");
31+
})
32+
.build();
33+
}
34+
}

src/main/java/com/github/flamingrose/config/CacheConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.springframework.boot.info.GitProperties;
1717
import org.springframework.cache.annotation.EnableCaching;
1818
import org.springframework.cache.interceptor.KeyGenerator;
19-
import org.springframework.context.annotation.*;
2019
import org.springframework.context.annotation.Bean;
2120
import org.springframework.context.annotation.Configuration;
2221
import tech.jhipster.config.JHipsterProperties;
@@ -36,7 +35,8 @@ public javax.cache.configuration.Configuration<Object, Object> jcacheConfigurati
3635
URI redisUri = URI.create(jHipsterProperties.getCache().getRedis().getServer()[0]);
3736

3837
Config config = new Config();
39-
// Fix Hibernate lazy initialization https://github.com/jhipster/generator-jhipster/issues/22889
38+
// Fix Hibernate lazy initialization
39+
// https://github.com/jhipster/generator-jhipster/issues/22889
4040
config.setCodec(new org.redisson.codec.SerializationCodec());
4141
if (jHipsterProperties.getCache().getRedis().isCluster()) {
4242
ClusterServersConfig clusterServersConfig = config

src/main/java/com/github/flamingrose/config/SecurityConfiguration.java

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,57 @@ public SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Buil
6161
.authorizeHttpRequests(
6262
authz ->
6363
// prettier-ignore
64-
authz
65-
.requestMatchers(mvc.pattern("/index.html"), mvc.pattern("/*.js"), mvc.pattern("/*.txt"), mvc.pattern("/*.json"), mvc.pattern("/*.map"), mvc.pattern("/*.css")).permitAll()
66-
.requestMatchers(mvc.pattern("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")).permitAll()
67-
.requestMatchers(mvc.pattern("/app/**")).permitAll()
68-
.requestMatchers(mvc.pattern("/i18n/**")).permitAll()
69-
.requestMatchers(mvc.pattern("/content/**")).permitAll()
70-
.requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll()
71-
.requestMatchers(mvc.pattern(HttpMethod.POST, "/api/authenticate")).permitAll()
72-
.requestMatchers(mvc.pattern(HttpMethod.GET, "/api/authenticate")).permitAll()
73-
.requestMatchers(mvc.pattern("/api/register")).permitAll()
74-
.requestMatchers(mvc.pattern("/api/activate")).permitAll()
75-
.requestMatchers(mvc.pattern("/api/account/reset-password/init")).permitAll()
76-
.requestMatchers(mvc.pattern("/api/account/reset-password/finish")).permitAll()
77-
.requestMatchers(mvc.pattern("/api/admin/**")).hasAuthority(AuthoritiesConstants.ADMIN)
78-
.requestMatchers(mvc.pattern("/api/**")).authenticated()
79-
.requestMatchers(mvc.pattern("/websocket/**")).authenticated()
80-
.requestMatchers(mvc.pattern("/v3/api-docs/**")).hasAuthority(AuthoritiesConstants.ADMIN)
81-
.requestMatchers(mvc.pattern("/management/health")).permitAll()
82-
.requestMatchers(mvc.pattern("/management/health/**")).permitAll()
83-
.requestMatchers(mvc.pattern("/management/info")).permitAll()
84-
.requestMatchers(mvc.pattern("/management/prometheus")).permitAll()
85-
.requestMatchers(mvc.pattern("/management/**")).hasAuthority(AuthoritiesConstants.ADMIN)
64+
authz
65+
.requestMatchers(mvc.pattern("/index.html"),
66+
mvc.pattern("/*.js"),
67+
mvc.pattern("/*.txt"),
68+
mvc.pattern("/*.json"),
69+
mvc.pattern("/*.map"),
70+
mvc.pattern("/*.css"))
71+
.permitAll()
72+
.requestMatchers(mvc.pattern("/*.ico"),
73+
mvc.pattern("/*.png"),
74+
mvc.pattern("/*.svg"),
75+
mvc.pattern("/*.webapp"))
76+
.permitAll()
77+
.requestMatchers(mvc.pattern("/app/**")).permitAll()
78+
.requestMatchers(mvc.pattern("/i18n/**")).permitAll()
79+
.requestMatchers(mvc.pattern("/content/**")).permitAll()
80+
.requestMatchers(mvc.pattern("/swagger-ui/**"))
81+
.permitAll()
82+
.requestMatchers(mvc.pattern(HttpMethod.POST,
83+
"/api/authenticate"))
84+
.permitAll()
85+
.requestMatchers(mvc.pattern(HttpMethod.GET,
86+
"/api/authenticate"))
87+
.permitAll()
88+
.requestMatchers(mvc.pattern("/api/register"))
89+
.permitAll()
90+
.requestMatchers(mvc.pattern("/api/activate"))
91+
.permitAll()
92+
.requestMatchers(mvc.pattern(
93+
"/api/account/reset-password/init"))
94+
.permitAll()
95+
.requestMatchers(mvc.pattern(
96+
"/api/account/reset-password/finish"))
97+
.permitAll()
98+
.requestMatchers(mvc.pattern("/api/admin/**"))
99+
.hasAuthority(AuthoritiesConstants.ADMIN)
100+
.requestMatchers(mvc.pattern("/api/**")).authenticated()
101+
.requestMatchers(mvc.pattern("/websocket/**"))
102+
.authenticated()
103+
.requestMatchers(mvc.pattern("/v3/api-docs/**"))
104+
.hasAuthority(AuthoritiesConstants.ADMIN)
105+
.requestMatchers(mvc.pattern("/management/health"))
106+
.permitAll()
107+
.requestMatchers(mvc.pattern("/management/health/**"))
108+
.permitAll()
109+
.requestMatchers(mvc.pattern("/management/info"))
110+
.permitAll()
111+
.requestMatchers(mvc.pattern("/management/prometheus"))
112+
.permitAll()
113+
.requestMatchers(mvc.pattern("/management/**"))
114+
.hasAuthority(AuthoritiesConstants.ADMIN)
86115
)
87116
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
88117
.exceptionHandling(
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.github.flamingrose.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
7+
@Data
8+
@NoArgsConstructor
9+
@AllArgsConstructor
10+
public class TranslateRequest {
11+
12+
private String text;
13+
private String from;
14+
private String to;
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.github.flamingrose.dto;
2+
3+
import java.util.List;
4+
import lombok.Data;
5+
6+
@Data
7+
public class TranslateResponse {
8+
9+
private List<Translation> translations;
10+
11+
@Data
12+
public static class Translation {
13+
14+
private String text;
15+
private String to;
16+
}
17+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.github.flamingrose.service;
2+
3+
public interface TranslationService {
4+
String translate(String text, String fromLang, String toLang);
5+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.github.flamingrose.service.impl;
2+
3+
import com.github.flamingrose.dto.TranslateResponse;
4+
import com.github.flamingrose.service.TranslationService;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.Map;
8+
import org.springframework.beans.factory.annotation.Qualifier;
9+
import org.springframework.core.ParameterizedTypeReference;
10+
import org.springframework.http.MediaType;
11+
import org.springframework.stereotype.Service;
12+
import org.springframework.util.CollectionUtils;
13+
import org.springframework.web.client.RestClient;
14+
15+
@Service
16+
public class TranslationServiceImpl implements TranslationService {
17+
18+
private final RestClient restClient;
19+
20+
public TranslationServiceImpl(@Qualifier("azureRestClient") RestClient restClient) {
21+
this.restClient = restClient;
22+
}
23+
24+
@Override
25+
public String translate(String text, String fromLang, String toLang) {
26+
List<TranslateResponse> resp = restClient
27+
.post()
28+
.uri(
29+
uriBuilder ->
30+
uriBuilder
31+
.path("/translate")
32+
.queryParam("api-version", "3.0")
33+
.queryParam("from", fromLang)
34+
.queryParam("to", toLang)
35+
.build()
36+
)
37+
.contentType(MediaType.APPLICATION_JSON)
38+
.body(Collections.singletonList(Map.of("Text", text)))
39+
.retrieve()
40+
.body(new ParameterizedTypeReference<>() {});
41+
if (CollectionUtils.isEmpty(resp)) {
42+
return null;
43+
}
44+
TranslateResponse response = resp.get(0);
45+
if (CollectionUtils.isEmpty(response.getTranslations())) {
46+
return null;
47+
}
48+
return response.getTranslations().get(0).getText();
49+
}
50+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.github.flamingrose.web.rest;
2+
3+
import com.github.flamingrose.dto.TranslateRequest;
4+
import com.github.flamingrose.service.TranslationService;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.http.ResponseEntity;
7+
import org.springframework.web.bind.annotation.PostMapping;
8+
import org.springframework.web.bind.annotation.RequestBody;
9+
import org.springframework.web.bind.annotation.RequestMapping;
10+
import org.springframework.web.bind.annotation.RequestParam;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequestMapping("/api/translate")
15+
@RequiredArgsConstructor
16+
public class TranslationController {
17+
18+
private final TranslationService translationService;
19+
20+
@PostMapping
21+
public ResponseEntity<String> translate(@RequestBody TranslateRequest text) {
22+
String result = translationService.translate(text.getText(), text.getFrom(), text.getTo());
23+
return ResponseEntity.ok(result);
24+
}
25+
}

0 commit comments

Comments
 (0)