完成以下第三方接口对接:
1.地图功能-地理/逆地理编码 2.发送短信验证码 3.COS云对象存储对接 其他: 完成文件上传/预览公共接口
This commit is contained in:
parent
0edffa145b
commit
39953cca84
11 changed files with 622 additions and 1 deletions
34
pom.xml
34
pom.xml
|
|
@ -17,7 +17,25 @@
|
|||
<properties>
|
||||
<java.version>25</java.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>2025.0.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
|
|
@ -76,6 +94,22 @@
|
|||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.18.0</version>
|
||||
</dependency>
|
||||
<!--腾讯云SDK-->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<version>3.1.1396</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qcloud</groupId>
|
||||
<artifactId>cos_api</artifactId>
|
||||
<version>5.6.246</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-core</artifactId>
|
||||
<version>3.2.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
package com.xjhs.findmemerchant.common.openapi;
|
||||
|
||||
import com.qcloud.cos.COSClient;
|
||||
import com.qcloud.cos.exception.CosClientException;
|
||||
import com.qcloud.cos.model.GetObjectRequest;
|
||||
import com.qcloud.cos.model.PutObjectRequest;
|
||||
import com.xjhs.findmemerchant.common.openapi.dto.CosPutObjectResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TencentCOSService {
|
||||
@Value("${appconfig.tencentCos.bucketName}")
|
||||
private String bucketName;
|
||||
private final COSClient tencentCosClient;
|
||||
|
||||
/**
|
||||
* 文件上传到Cos存储桶
|
||||
*
|
||||
* @param file 文件
|
||||
* @return 存储对象信息
|
||||
*/
|
||||
public CosPutObjectResult putObject(File file) throws Exception {
|
||||
try {
|
||||
var key = UUID.randomUUID().toString();
|
||||
var req = new PutObjectRequest(this.bucketName, key, file);
|
||||
var result = tencentCosClient.putObject(req);
|
||||
return new CosPutObjectResult(key, result.getETag());
|
||||
} catch (CosClientException e) {
|
||||
log.error("文件上传到对象存储失败", e);
|
||||
throw new Exception("文件上传到对象存储失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件输入流(下载文件)
|
||||
* @param key 对象key
|
||||
* @return 输入流
|
||||
* @throws Exception 下载失败
|
||||
*/
|
||||
public InputStream getObject(String key) throws Exception{
|
||||
try {
|
||||
var req = new GetObjectRequest(this.bucketName, key);
|
||||
var cosObject = this.tencentCosClient.getObject(req);
|
||||
return cosObject.getObjectContent();
|
||||
} catch (CosClientException e) {
|
||||
log.error("从对象存储下载文件失败",e);
|
||||
throw new Exception("从对象存储下载文件失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除存储对象
|
||||
*
|
||||
* @param key 对象key
|
||||
* @throws Exception 删除失败
|
||||
*/
|
||||
public void deleteObject(String key) throws Exception {
|
||||
try {
|
||||
this.tencentCosClient.deleteObject(this.bucketName, key);
|
||||
} catch (CosClientException e) {
|
||||
log.error("文件上传到对象存储失败", e);
|
||||
throw new Exception("文件上传到对象存储失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.xjhs.findmemerchant.common.openapi;
|
||||
|
||||
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
|
||||
import com.tencentcloudapi.sms.v20190711.SmsClient;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor()
|
||||
public class TencentCloudSMSService {
|
||||
@Value("${appconfig.tencentSms.sdkAppId}")
|
||||
private String sdkAppid;
|
||||
@Value("${appconfig.tencentSms.templateId}")
|
||||
private String templateId;
|
||||
@Value("${appconfig.tencentSms.signName}")
|
||||
private String signName;
|
||||
private final SmsClient tencentSmsClient;
|
||||
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
*
|
||||
* @param phone 11位国内手机号码
|
||||
* @param code 验证码
|
||||
* @return 验证码值
|
||||
* @throws Exception 发送失败
|
||||
*/
|
||||
public String sendVerifyCode(String phone, String code) throws Exception {
|
||||
try {
|
||||
if (!phone.startsWith("+86")) {
|
||||
phone = "+86" + phone;
|
||||
}
|
||||
var req = new SendSmsRequest();
|
||||
req.setSmsSdkAppid(this.sdkAppid);
|
||||
req.setTemplateID(this.templateId);
|
||||
req.setSign(this.signName);
|
||||
req.setPhoneNumberSet(new String[]{phone});
|
||||
req.setTemplateParamSet(new String[]{code});
|
||||
var resp = this.tencentSmsClient.SendSms(req);
|
||||
if (resp.getSendStatusSet().length == 0){
|
||||
throw new Exception("取回短信发送结果失败");
|
||||
}
|
||||
if (!"ok".equalsIgnoreCase(resp.getSendStatusSet()[0].getCode())){
|
||||
throw new Exception(resp.getSendStatusSet()[0].getMessage());
|
||||
}
|
||||
return code;
|
||||
} catch (TencentCloudSDKException e) {
|
||||
log.error("验证码发送失败", e);
|
||||
throw new Exception("系统错误,验证码发送失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.xjhs.findmemerchant.common.openapi.amap;
|
||||
|
||||
|
||||
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapGeocodeResponse;
|
||||
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapReGeocodeResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* 高德地图服务接口
|
||||
*/
|
||||
@FeignClient(name = "amapFeignClient", url = "https://restapi.amap.com")
|
||||
public interface AmapFeignClient {
|
||||
|
||||
/**
|
||||
* 地理编码 API 服务
|
||||
* @param key 高德Key
|
||||
* @param address 结构化地址信息,规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。
|
||||
* @return 响应信息
|
||||
*/
|
||||
@GetMapping("/v3/geocode/geo")
|
||||
AmapGeocodeResponse getGeo(@RequestParam(name = "key") String key,
|
||||
@RequestParam(name = "address") String address);
|
||||
|
||||
|
||||
/**
|
||||
* 逆地理编码 API 服务地址
|
||||
* @param key 高德Key
|
||||
* @param location 经纬度坐标 传入内容规则:经度在前,纬度在后,经纬度间以“,”分割,经纬度小数点后不要超过 6 位。
|
||||
*/
|
||||
@GetMapping("/v3/geocode/regeo")
|
||||
AmapReGeocodeResponse getReGeo(@RequestParam(name = "key") String key,
|
||||
@RequestParam(name = "location") String location);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.xjhs.findmemerchant.common.openapi.amap;
|
||||
|
||||
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapGeocodeResponse;
|
||||
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapReGeocodeResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AmapService {
|
||||
|
||||
@Value("${appconfig.amapKey}")
|
||||
private String amapKey = "c618de6e686c43095a8593db836c7de2";
|
||||
private final AmapFeignClient amapFeignClient;
|
||||
|
||||
/**
|
||||
* 地址转经纬度
|
||||
*
|
||||
* @param address 地址信息
|
||||
* @return 经纬度信息结果
|
||||
*/
|
||||
public AmapGeocodeResponse getGeo(String address) {
|
||||
return this.amapFeignClient.getGeo(this.amapKey, address);
|
||||
}
|
||||
|
||||
/**
|
||||
* 经纬度转地理位置信息
|
||||
*
|
||||
* @param lng 经度
|
||||
* @param lat 纬度
|
||||
* @return 位置信息
|
||||
*/
|
||||
public AmapReGeocodeResponse getRegeo(double lng, double lat) {
|
||||
return this.amapFeignClient.getReGeo(this.amapKey, lng + "," + lat);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package com.xjhs.findmemerchant.common.openapi.amap.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 地理编码 API 服务响应内容
|
||||
*/
|
||||
@Data
|
||||
public class AmapGeocodeResponse {
|
||||
/**
|
||||
* 请求状态值,0 表示请求失败,1 表示请求成功
|
||||
*/
|
||||
private int status;
|
||||
|
||||
/**
|
||||
* 返回结果的数量
|
||||
*/
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* 返回结果的详细说明,当 status 为 0 时,info 会包含错误原因;否则返回 "OK"
|
||||
*/
|
||||
private String info;
|
||||
|
||||
/**
|
||||
* 地理编码信息列表,包含多个地址组件
|
||||
*/
|
||||
private List<GeocodeDetails> geocodes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 地理编码信息的详细字段
|
||||
*/
|
||||
@Data
|
||||
public static class GeocodeDetails {
|
||||
|
||||
@JsonProperty("formatted_address")
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 国家,默认返回中国
|
||||
*/
|
||||
private String country;
|
||||
|
||||
/**
|
||||
* 省份名称,例如:北京市
|
||||
*/
|
||||
private String province;
|
||||
|
||||
/**
|
||||
* 城市名称,例如:北京市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 城市编码,例如:010
|
||||
*/
|
||||
private String citycode;
|
||||
|
||||
/**
|
||||
* 区域名称,例如:朝阳区
|
||||
*/
|
||||
private String district;
|
||||
|
||||
/**
|
||||
* 街道名称,例如:单通东大街
|
||||
*/
|
||||
private String street;
|
||||
|
||||
/**
|
||||
* 门牌号,例如:6号
|
||||
*/
|
||||
private String number;
|
||||
|
||||
/**
|
||||
* 区域编码,例如:110101
|
||||
*/
|
||||
private String adcode;
|
||||
|
||||
/**
|
||||
* 经纬度坐标,逗号分隔
|
||||
*/
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* 匹配级别,用于地理匹配的精确度
|
||||
*/
|
||||
private String level;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
package com.xjhs.findmemerchant.common.openapi.amap.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 逆地理位置服务响应内容
|
||||
*/
|
||||
@Data
|
||||
public class AmapReGeocodeResponse {
|
||||
|
||||
/**
|
||||
* 请求状态,1 表示请求成功
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 地址组件信息
|
||||
*/
|
||||
private Regeocode regeocode;
|
||||
|
||||
/**
|
||||
* 返回的状态信息
|
||||
*/
|
||||
private String info;
|
||||
|
||||
/**
|
||||
* 状态码,10000 表示成功
|
||||
*/
|
||||
private String infocode;
|
||||
|
||||
/**
|
||||
* 地址组件类,包含具体的地理信息
|
||||
*/
|
||||
@Data
|
||||
public static class Regeocode {
|
||||
|
||||
/**
|
||||
* 地址组件,包含城市、区、街道等信息
|
||||
*/
|
||||
private AddressComponent addressComponent;
|
||||
|
||||
/**
|
||||
* 格式化后的地址,整合了详细信息
|
||||
*/
|
||||
@JsonProperty("formatted_address")
|
||||
private String address;
|
||||
}
|
||||
|
||||
/**
|
||||
* 地址组件,包含详细的地理信息
|
||||
*/
|
||||
@Data
|
||||
public static class AddressComponent {
|
||||
|
||||
/**
|
||||
* 城市名称,可能为空
|
||||
*/
|
||||
private List<String> city = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 省份名称
|
||||
*/
|
||||
private String province;
|
||||
|
||||
/**
|
||||
* 区域编码
|
||||
*/
|
||||
private String adcode;
|
||||
|
||||
/**
|
||||
* 区域名称
|
||||
*/
|
||||
private String district;
|
||||
|
||||
/**
|
||||
* 城镇编码
|
||||
*/
|
||||
private String towncode;
|
||||
|
||||
/**
|
||||
* 街道信息
|
||||
*/
|
||||
private StreetNumber streetNumber;
|
||||
|
||||
/**
|
||||
* 国家名称
|
||||
*/
|
||||
private String country;
|
||||
|
||||
/**
|
||||
* 街道所属乡镇名称
|
||||
*/
|
||||
private String township;
|
||||
|
||||
/**
|
||||
* 商圈信息,包含多个商圈
|
||||
*/
|
||||
private List<BusinessArea> businessAreas;
|
||||
|
||||
/**
|
||||
* 建筑信息
|
||||
*/
|
||||
private Building building;
|
||||
|
||||
/**
|
||||
* 邻里信息
|
||||
*/
|
||||
private Neighborhood neighborhood;
|
||||
|
||||
/**
|
||||
* 城市编码
|
||||
*/
|
||||
private String citycode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 街道信息,包括街道名称、位置、方向等
|
||||
*/
|
||||
@Data
|
||||
public static class StreetNumber {
|
||||
|
||||
/**
|
||||
* 门牌号
|
||||
*/
|
||||
private String number;
|
||||
|
||||
/**
|
||||
* 经纬度位置
|
||||
*/
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* 方向
|
||||
*/
|
||||
private String direction;
|
||||
|
||||
/**
|
||||
* 距离
|
||||
*/
|
||||
private String distance;
|
||||
|
||||
/**
|
||||
* 街道名称
|
||||
*/
|
||||
private String street;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商圈信息
|
||||
*/
|
||||
@Data
|
||||
public static class BusinessArea {
|
||||
|
||||
/**
|
||||
* 商圈位置(经纬度)
|
||||
*/
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* 商圈名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 商圈ID
|
||||
*/
|
||||
private String id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 建筑信息,包括建筑名称和类型
|
||||
*/
|
||||
@Data
|
||||
public static class Building {
|
||||
|
||||
/**
|
||||
* 建筑名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 建筑类型
|
||||
*/
|
||||
private String type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 邻里信息
|
||||
*/
|
||||
@Data
|
||||
public static class Neighborhood {
|
||||
|
||||
/**
|
||||
* 邻里名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 邻里类型
|
||||
*/
|
||||
private String type;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.xjhs.findmemerchant.common.openapi.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class CosPutObjectResult {
|
||||
private String key;
|
||||
private String eTag;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.xjhs.findmemerchant.config;
|
||||
|
||||
import com.xjhs.findmemerchant.common.openapi.amap.AmapFeignClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableFeignClients(basePackageClasses = {
|
||||
AmapFeignClient.class,
|
||||
})
|
||||
public class FeignConfig {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.xjhs.findmemerchant.config;
|
||||
|
||||
import com.qcloud.cos.COSClient;
|
||||
import com.qcloud.cos.ClientConfig;
|
||||
import com.qcloud.cos.auth.BasicCOSCredentials;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.common.profile.Region;
|
||||
import com.tencentcloudapi.sms.v20190711.SmsClient;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class ThirdOpenApiConfig {
|
||||
|
||||
@Bean
|
||||
public SmsClient tencentSmsClient(@Value("${appconfig.tencentSms.secretId}") String secretId,
|
||||
@Value("${appconfig.tencentSms.secretKey}") String secretKey) {
|
||||
var cred = new Credential(secretId, secretKey);
|
||||
var httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("sms.tencentcloudapi.com");
|
||||
var clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
return new SmsClient(cred, "ap-guangzhou", clientProfile);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public COSClient tencentCosClient(@Value("${appconfig.tencentCos.secretId}") String secretId,
|
||||
@Value("${appconfig.tencentCos.secretKey}") String secretKey){
|
||||
var cred = new BasicCOSCredentials(secretId,secretKey);
|
||||
ClientConfig clientConfig = new ClientConfig(new com.qcloud.cos.region.Region("ap-guangzhou"));
|
||||
return new COSClient(cred, clientConfig);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,3 +31,20 @@ spring:
|
|||
password: ${REDIS_PASS:123456}
|
||||
database: 0
|
||||
timeout: 3s
|
||||
|
||||
appconfig:
|
||||
saveFileRoot: ${SAVE_FILE_ROOT:./file-data}
|
||||
amapKey: ${AMAP_KEY:c618de6e686c43095a8593db836c7de2}
|
||||
tencentSms:
|
||||
sdkAppId: ${SMS_SDKAPP_ID:1401031336}
|
||||
templateId: ${SMS_TEMPLATE_ID:2512787}
|
||||
signName: ${SMS_SIGN_NAME:新疆火烁智能科技}
|
||||
secretId: ${SMS_SECRET_ID:AKIDWyGMFwQinhPFzXt54rTuAD5kEYheOyOd}
|
||||
secretKey: ${SMS_SECRET_KEY:62mLjvwmQs9GAsQ5f6LQ7umgWCgy31sX}
|
||||
tencentCos:
|
||||
secretId: ${COS_SECRET_ID:AKIDWyGMFwQinhPFzXt54rTuAD5kEYheOyOd}
|
||||
secretKey: ${COS_SECRET_KEY:62mLjvwmQs9GAsQ5f6LQ7umgWCgy31sX}
|
||||
appId: ${COS_APP_ID:1375214531}
|
||||
bucketName: ${COS_APP_BUCKET:merchant-1375214531}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue