Merge remote-tracking branch 'origin/main'
This commit is contained in:
102
navigate-8432/pom.xml
Normal file
102
navigate-8432/pom.xml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.ivmiku.tutorial</groupId>
|
||||||
|
<artifactId>first-tutorial</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>navigate-8432</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- fastjson2 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-redis-jackson</artifactId>
|
||||||
|
<version>1.38.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- dubbo -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.dubbo</groupId>
|
||||||
|
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-registry-nacos -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.dubbo</groupId>
|
||||||
|
<artifactId>dubbo-registry-nacos</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ivmiku.tutorial</groupId>
|
||||||
|
<artifactId>commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-http -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-http</artifactId>
|
||||||
|
<version>5.8.29</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
|
<artifactId>tencentcloud-sdk-java-ocr</artifactId>
|
||||||
|
<version>3.1.1076</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.ivmiku.tutorial;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@MapperScan("com.ivmiku.tutorial.mapper")
|
||||||
|
public class Main8432 {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Main8432.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.ivmiku.tutorial.entity.RouteStep;
|
||||||
|
import com.ivmiku.tutorial.response.Result;
|
||||||
|
import com.ivmiku.tutorial.service.NavigateService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/navigate")
|
||||||
|
@SaCheckLogin
|
||||||
|
public class NavigateController {
|
||||||
|
@Resource
|
||||||
|
private NavigateService navigateService;
|
||||||
|
|
||||||
|
private static final ConcurrentHashMap<String, List<RouteStep>> STEPS_MAP = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@GetMapping("/route")
|
||||||
|
public Object getRoute(@RequestParam(defaultValue = "") String origin,
|
||||||
|
@RequestParam(defaultValue = "") String destination,
|
||||||
|
@RequestParam(defaultValue = "-1") int step) {
|
||||||
|
String userId = (String) StpUtil.getLoginId();
|
||||||
|
if (!origin.isEmpty() && !destination.isEmpty()) {
|
||||||
|
Map<String, Object> route = navigateService.getRoute(origin, destination);
|
||||||
|
List<RouteStep> stepsList = (List<RouteStep>) route.get("steps");
|
||||||
|
STEPS_MAP.put(userId, stepsList);
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("total", stepsList.size());
|
||||||
|
map.put("distance", Integer.parseInt((String) route.get("distance")));
|
||||||
|
map.put("duration", Integer.parseInt((String) route.get("duration")));
|
||||||
|
map.put("step", stepsList.getFirst());
|
||||||
|
return JSON.toJSON(Result.ok(map));
|
||||||
|
} else if (step >0) {
|
||||||
|
if (!STEPS_MAP.containsKey(userId)) {
|
||||||
|
return JSON.toJSON(Result.error("请先获取路线!"));
|
||||||
|
}
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("step", STEPS_MAP.get(userId).get(step-1));
|
||||||
|
return JSON.toJSON(Result.ok(map));
|
||||||
|
}
|
||||||
|
return JSON.toJSON(Result.error("非法的请求参数"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/ticket")
|
||||||
|
public Object scanTicket(@RequestPart MultipartFile file) throws IOException {
|
||||||
|
BufferedImage image = ImageIO.read(file.getInputStream());
|
||||||
|
Map<String, Object> map = navigateService.scanTicket(image);
|
||||||
|
return JSON.toJSON(Result.ok(map));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.ivmiku.tutorial.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class RouteStep {
|
||||||
|
private String instruction;
|
||||||
|
private String orientation;
|
||||||
|
private String road;
|
||||||
|
private Integer distance;
|
||||||
|
private Integer duration;
|
||||||
|
private String polyline;
|
||||||
|
private String action;
|
||||||
|
private String assistant_action;
|
||||||
|
private Integer walk_type;
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.ivmiku.tutorial.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.img.ImgUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ivmiku.tutorial.entity.RouteStep;
|
||||||
|
import com.tencentcloudapi.common.Credential;
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||||
|
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||||
|
import com.tencentcloudapi.ocr.v20181119.OcrClient;
|
||||||
|
import com.tencentcloudapi.ocr.v20181119.models.*;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class NavigateService {
|
||||||
|
private final String key = "d3aa1b75aff468a5ca5384d2b4b6bfef";
|
||||||
|
private final String secretId = "AKID09INNYxYEFFJH3g9VhljVF3qbDiFdx50";
|
||||||
|
private final String secretKey = "KajjcNyNaaUCqQroqpzNoMtTHNj4Lbil";
|
||||||
|
|
||||||
|
public Map<String, Object> getRoute(String origin, String destination) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("key", key);
|
||||||
|
params.put("origin", origin);
|
||||||
|
params.put("destination", destination);
|
||||||
|
HttpResponse response = HttpRequest.get("https://restapi.amap.com/v3/direction/walking")
|
||||||
|
.form(params)
|
||||||
|
.execute();
|
||||||
|
String result = response.body();
|
||||||
|
response.close();
|
||||||
|
JSONObject route = JSONObject.parseObject(JSONObject.parseObject(result).getString("route"));
|
||||||
|
JSONArray paths = JSONArray.parseArray(route.getString("paths"));
|
||||||
|
JSONObject path = paths.getJSONObject(0);
|
||||||
|
String distance = path.getString("distance");
|
||||||
|
String duration = path.getString("duration");
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("distance", distance);
|
||||||
|
map.put("duration", duration);
|
||||||
|
map.put("steps", JSONArray.parseArray(path.getString("steps"), RouteStep.class));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> scanTicket(BufferedImage image) {
|
||||||
|
String base64Img = ImgUtil.toBase64(image, "jpg");
|
||||||
|
SmartStructuralOCRV2Response resp;
|
||||||
|
try {
|
||||||
|
Credential cred = new Credential(secretId, secretKey);
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("ocr.tencentcloudapi.com");
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
OcrClient client = new OcrClient(cred, "ap-shanghai", clientProfile);
|
||||||
|
SmartStructuralOCRV2Request req = new SmartStructuralOCRV2Request();
|
||||||
|
req.setImageBase64(base64Img);
|
||||||
|
String[] itemNames1 = {"登机口", "检票口"};
|
||||||
|
req.setItemNames(itemNames1);
|
||||||
|
resp = client.SmartStructuralOCRV2(req);
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
List<GroupInfo> groupInfoList = Arrays.stream(resp.getStructuralList()).toList();
|
||||||
|
for (GroupInfo groupInfo : groupInfoList) {
|
||||||
|
List<LineInfo> lineList = Arrays.stream(groupInfo.getGroups()).toList();
|
||||||
|
for (LineInfo lineInfo : lineList) {
|
||||||
|
List<ItemInfo> itemList = Arrays.stream(lineInfo.getLines()).toList();
|
||||||
|
for (ItemInfo info : itemList) {
|
||||||
|
if (info.getKey() != null && info.getValue() != null) {
|
||||||
|
result.put(String.valueOf(info.getKey().getAutoName()), info.getValue().getAutoContent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.ivmiku.tutorial.utils;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.SaTokenException;
|
||||||
|
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.ivmiku.tutorial.response.Result;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Aurora
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@ControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
@ExceptionHandler(value = SaTokenException.class)
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
@ResponseBody
|
||||||
|
public Object SaTokenExceptionHandler(SaTokenException e) {
|
||||||
|
log.error("SaTokenException:" + e.getLocalizedMessage());
|
||||||
|
return JSON.toJSON(Result.error("身份认证错误:" + e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = ParseException.class)
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
@ResponseBody
|
||||||
|
public Object parseExceptionHandler(ParseException e) {
|
||||||
|
|
||||||
|
log.error("ParseException:" + e.getLocalizedMessage());
|
||||||
|
return JSON.toJSON(Result.error("请检查日期是否合法"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = SQLException.class)
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
@ResponseBody
|
||||||
|
public Object SQLExceptionHandler(SQLException e) {
|
||||||
|
log.error("SQLException:" + e.getLocalizedMessage());
|
||||||
|
return JSON.toJSON(Result.error("数据库出错!(内部错误)\n" + e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = BlockException.class)
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
@ResponseBody
|
||||||
|
public Object sentinelHandler(BlockException e) {
|
||||||
|
return JSON.toJSON(Result.error("系统繁忙,请稍后再试"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = Exception.class)
|
||||||
|
@ResponseBody
|
||||||
|
public Object exceptionHandler(Exception e) {
|
||||||
|
log.error("Exception:" + e.getLocalizedMessage());
|
||||||
|
return JSON.toJSON(Result.error("服务器内部错误:" + e.getClass() + ":" + e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
19
navigate-8432/src/main/resources/application-dep.properties
Normal file
19
navigate-8432/src/main/resources/application-dep.properties
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
spring.data.redis.host=redis
|
||||||
|
spring.data.redis.port=6379
|
||||||
|
spring.data.redis.database=0
|
||||||
|
spring.data.redis.password=Shuodedaoli114514
|
||||||
|
|
||||||
|
spring.application.name=navigate
|
||||||
|
|
||||||
|
server.port=8432
|
||||||
|
|
||||||
|
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
|
spring.datasource.username=root
|
||||||
|
spring.datasource.password=Shuodedaoli114514
|
||||||
|
spring.datasource.url=jdbc:mysql://mysql:4514/tutorial?useUnicode=true&characterEncoding=utf8&useSSL=false&ServerTimezone=Asia/Shanghai
|
||||||
|
|
||||||
|
spring.cloud.nacos.discovery.server-addr=nacos:8848
|
||||||
|
spring.cloud.nacos.discovery.enabled=true
|
||||||
|
|
||||||
|
management.zipkin.tracing.endpoint=http://zipkin:9411/api/v2/spans
|
||||||
|
management.tracing.sampling.probability=1.0
|
||||||
14
navigate-8432/src/main/resources/application-dev.properties
Normal file
14
navigate-8432/src/main/resources/application-dev.properties
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
spring.data.redis.host=localhost
|
||||||
|
spring.data.redis.port=6379
|
||||||
|
spring.data.redis.database=0
|
||||||
|
|
||||||
|
spring.application.name=navigate
|
||||||
|
|
||||||
|
server.port=8432
|
||||||
|
|
||||||
|
dubbo.application.qos-enable=false
|
||||||
|
|
||||||
|
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
|
spring.datasource.username=root
|
||||||
|
spring.datasource.password=12345abcde
|
||||||
|
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tutorial?useUnicode=true&characterEncoding=utf8&useSSL=false&ServerTimezone=Asia/Shanghai
|
||||||
1
navigate-8432/src/main/resources/application.properties
Normal file
1
navigate-8432/src/main/resources/application.properties
Normal file
@@ -0,0 +1 @@
|
|||||||
|
spring.profiles.active=dev
|
||||||
Reference in New Issue
Block a user