this is 4.22 update
This commit is contained in:
parent
8837d8bc54
commit
4ebe4839fb
|
@ -1,6 +1,8 @@
|
|||
package com.cultural.heritage.controller.clothes;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
|
@ -17,24 +19,31 @@ import com.cultural.heritage.model.dto.CommonRequest;
|
|||
import com.cultural.heritage.model.dto.clothes.ClothesAddRequest;
|
||||
import com.cultural.heritage.model.dto.clothes.ClothesQueryRequest;
|
||||
import com.cultural.heritage.model.dto.clothes.ClothesUpdateRequest;
|
||||
import com.cultural.heritage.model.dto.facelift.ClothesUrlObj;
|
||||
import com.cultural.heritage.model.dto.facelift.GarmentObj;
|
||||
import com.cultural.heritage.model.dto.facelift.LogoUrlObj;
|
||||
import com.cultural.heritage.model.dto.facelift.ModelObj;
|
||||
import com.cultural.heritage.model.entity.Clothes;
|
||||
import com.cultural.heritage.model.vo.clothes.ClothesLabelVO;
|
||||
import com.cultural.heritage.model.vo.clothes.ClothesVO;
|
||||
import com.cultural.heritage.service.clothes.ClothesService;
|
||||
import com.cultural.heritage.service.common.CommonService;
|
||||
import com.cultural.heritage.utils.DecoderUtils;
|
||||
import com.cultural.heritage.utils.Sign;
|
||||
import com.google.gson.Gson;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
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.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RestController
|
||||
|
@ -292,6 +301,47 @@ public class ClothesController {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* 小程序端用户调用换装api
|
||||
* @param modelURL 模特Url
|
||||
* @param clothesURL 服装URL
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/facelift")
|
||||
@Operation(summary = "小程序端用户调用换装api", description = "参数:服装id,权限:管理员(admin, boss),方法名:updateClothesShelvesStatus")
|
||||
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||
public BaseResponse<String> invokeChangeClothesApi(@RequestParam String modelURL, @RequestParam String clothesURL) {
|
||||
if (StringUtils.isBlank(modelURL) || StringUtils.isBlank(clothesURL)) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数不能为空");
|
||||
}
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("req_key", "dressing_diffusion");
|
||||
ModelObj modelObj = ModelObj.builder().id("1").url(modelURL).build();
|
||||
param.put("model", modelObj);
|
||||
ClothesUrlObj clothesUrlObj = ClothesUrlObj.builder().url(clothesURL).build();
|
||||
List<ClothesUrlObj> clothesUrlObjList = new ArrayList<>();
|
||||
clothesUrlObjList.add(clothesUrlObj);
|
||||
GarmentObj garmentObj = GarmentObj.builder().id("1").data(clothesUrlObjList).build();
|
||||
param.put("garment", garmentObj);
|
||||
param.put("return_url", true);
|
||||
LogoUrlObj logoUrlObj = LogoUrlObj.builder().add_logo(false).position(0).language(0).logo_text_content("这里是明水印内容").build();
|
||||
param.put("logo_url", logoUrlObj);
|
||||
// 使用 Gson 将 Map 转换为 byte[]
|
||||
Gson gson = new Gson();
|
||||
byte[] body = gson.toJson(param).getBytes(StandardCharsets.UTF_8);
|
||||
String responseBody = null;
|
||||
try {
|
||||
responseBody = Sign.invokeChangeClothesApi(body);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 使用 fastjson 将 responseBody 字符串解析为 JSONObject
|
||||
JSONObject jsonObject = JSONObject.parseObject(responseBody);
|
||||
|
||||
// 从 JSON 中获取 "data" 对象,然后获取 "image_urls" 数组
|
||||
JSONArray imageUrls = jsonObject.getJSONObject("data").getJSONArray("image_urls");
|
||||
return ResultUtils.success(imageUrls.getString(0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.cultural.heritage.model.dto.facelift;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class ClothesUrlObj implements Serializable {
|
||||
|
||||
/**
|
||||
* 服装url
|
||||
*/
|
||||
private String url;
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.cultural.heritage.model.dto.facelift;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class GarmentObj implements Serializable {
|
||||
|
||||
/**
|
||||
* 模特配置
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 服装URL列表
|
||||
*/
|
||||
private List<ClothesUrlObj> data;
|
||||
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.cultural.heritage.model.dto.facelift;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class LogoUrlObj implements Serializable {
|
||||
|
||||
/**
|
||||
* 是否添加水印
|
||||
*/
|
||||
private Boolean add_logo;
|
||||
|
||||
/**
|
||||
* 水印位置
|
||||
*/
|
||||
private Integer position;
|
||||
|
||||
/**
|
||||
* 水印的语言
|
||||
*/
|
||||
private Integer language;
|
||||
|
||||
/**
|
||||
* 水印的内容
|
||||
*/
|
||||
private String logo_text_content;
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.cultural.heritage.model.dto.facelift;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class ModelObj implements Serializable {
|
||||
|
||||
/**
|
||||
* 模特配置
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 模特URL
|
||||
*/
|
||||
private String url;
|
||||
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 4460640673274461809L;
|
||||
|
||||
}
|
258
src/main/java/com/cultural/heritage/utils/Sign.java
Normal file
258
src/main/java/com/cultural/heritage/utils/Sign.java
Normal file
|
@ -0,0 +1,258 @@
|
|||
package com.cultural.heritage.utils;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Copyright (year) Beijing Volcano Engine Technology Ltd.
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
public class Sign {
|
||||
|
||||
private static final BitSet URLENCODER = new BitSet(256);
|
||||
|
||||
private static final String CONST_ENCODE = "0123456789ABCDEF";
|
||||
public static final Charset UTF_8 = StandardCharsets.UTF_8;
|
||||
|
||||
private final String region;
|
||||
private final String service;
|
||||
private final String schema;
|
||||
private final String host;
|
||||
private final String path;
|
||||
private final String ak;
|
||||
private final String sk;
|
||||
|
||||
static {
|
||||
int i;
|
||||
for (i = 97; i <= 122; ++i) {
|
||||
URLENCODER.set(i);
|
||||
}
|
||||
|
||||
for (i = 65; i <= 90; ++i) {
|
||||
URLENCODER.set(i);
|
||||
}
|
||||
|
||||
for (i = 48; i <= 57; ++i) {
|
||||
URLENCODER.set(i);
|
||||
}
|
||||
URLENCODER.set('-');
|
||||
URLENCODER.set('_');
|
||||
URLENCODER.set('.');
|
||||
URLENCODER.set('~');
|
||||
}
|
||||
|
||||
public Sign(String region, String service, String schema, String host, String path, String ak, String sk) {
|
||||
this.region = region;
|
||||
this.service = service;
|
||||
this.host = host;
|
||||
this.schema = schema;
|
||||
this.path = path;
|
||||
this.ak = ak;
|
||||
this.sk = sk;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) throws Exception {
|
||||
// String SecretAccessKey = "T0dJeU1HVTRaamsxWldSaE5HTTNOemswWVdRMk1qUmxaVEprWXpFNFpUYw==";
|
||||
// String AccessKeyID = "AKLTNzZjODdkZGQ5YjkwNDhlZmFlNDFkNWQ1ODM4YmI4NmU";
|
||||
// // 请求地址
|
||||
// String endpoint = "visual.volcengineapi.com";
|
||||
// String path = "/"; // 路径,不包含 Query// 请求接口信息
|
||||
// String service = "cv";
|
||||
// String region = "cn-north-1";
|
||||
// String schema = "https";
|
||||
// Sign sign = new Sign(region, service, schema, endpoint, path, AccessKeyID, SecretAccessKey);
|
||||
//
|
||||
// String action = "CVProcess";
|
||||
// String version = "2022-08-31";
|
||||
//
|
||||
// Date date = new Date();
|
||||
// HashMap<String, String> queryMap = new HashMap<>() {{
|
||||
// put("Limit", "1");
|
||||
// }};
|
||||
//
|
||||
// sign.doRequest("POST", queryMap, null, date, action, version);
|
||||
// }
|
||||
|
||||
|
||||
public static String invokeChangeClothesApi(byte[] body) throws Exception {
|
||||
String SecretAccessKey = "T0dJeU1HVTRaamsxWldSaE5HTTNOemswWVdRMk1qUmxaVEprWXpFNFpUYw==";
|
||||
String AccessKeyID = "AKLTNzZjODdkZGQ5YjkwNDhlZmFlNDFkNWQ1ODM4YmI4NmU";
|
||||
// 请求地址
|
||||
String endpoint = "visual.volcengineapi.com";
|
||||
String path = "/"; // 路径,不包含 Query// 请求接口信息
|
||||
String service = "cv";
|
||||
String region = "cn-north-1";
|
||||
String schema = "https";
|
||||
Sign sign = new Sign(region, service, schema, endpoint, path, AccessKeyID, SecretAccessKey);
|
||||
|
||||
String action = "CVProcess";
|
||||
String version = "2022-08-31";
|
||||
|
||||
Date date = new Date();
|
||||
HashMap<String, String> queryMap = new HashMap<>() {{
|
||||
put("Limit", "1");
|
||||
}};
|
||||
|
||||
return sign.doRequest("POST", queryMap, body, date, action, version);
|
||||
}
|
||||
|
||||
|
||||
public String doRequest(String method, Map<String, String> queryList, byte[] body,
|
||||
Date date, String action, String version) throws Exception {
|
||||
if (body == null) {
|
||||
body = new byte[0];
|
||||
}
|
||||
String xContentSha256 = hashSHA256(body);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
String xDate = sdf.format(date);
|
||||
String shortXDate = xDate.substring(0, 8);
|
||||
String contentType = "application/json";
|
||||
|
||||
String signHeader = "host;x-date;x-content-sha256;content-type";
|
||||
|
||||
|
||||
SortedMap<String, String> realQueryList = new TreeMap<>(queryList);
|
||||
realQueryList.put("Action", action);
|
||||
realQueryList.put("Version", version);
|
||||
StringBuilder querySB = new StringBuilder();
|
||||
for (String key : realQueryList.keySet()) {
|
||||
querySB.append(signStringEncoder(key)).append("=").append(signStringEncoder(realQueryList.get(key))).append("&");
|
||||
}
|
||||
querySB.deleteCharAt(querySB.length() - 1);
|
||||
|
||||
String canonicalStringBuilder = method + "\n" + path + "\n" + querySB + "\n" +
|
||||
"host:" + host + "\n" +
|
||||
"x-date:" + xDate + "\n" +
|
||||
"x-content-sha256:" + xContentSha256 + "\n" +
|
||||
"content-type:" + contentType + "\n" +
|
||||
"\n" +
|
||||
signHeader + "\n" +
|
||||
xContentSha256;
|
||||
|
||||
System.out.println(canonicalStringBuilder);
|
||||
|
||||
String hashcanonicalString = hashSHA256(canonicalStringBuilder.getBytes());
|
||||
String credentialScope = shortXDate + "/" + region + "/" + service + "/request";
|
||||
String signString = "HMAC-SHA256" + "\n" + xDate + "\n" + credentialScope + "\n" + hashcanonicalString;
|
||||
|
||||
byte[] signKey = genSigningSecretKeyV4(sk, shortXDate, region, service);
|
||||
String signature = HexFormat.of().formatHex(hmacSHA256(signKey, signString));
|
||||
|
||||
|
||||
URL url = new URL(schema + "://" + host + path + "?" + querySB);
|
||||
|
||||
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod(method);
|
||||
conn.setRequestProperty("Host", host);
|
||||
conn.setRequestProperty("X-Date", xDate);
|
||||
conn.setRequestProperty("X-Content-Sha256", xContentSha256);
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
conn.setRequestProperty("Authorization", "HMAC-SHA256" +
|
||||
" Credential=" + ak + "/" + credentialScope +
|
||||
", SignedHeaders=" + signHeader +
|
||||
", Signature=" + signature);
|
||||
if (!Objects.equals(conn.getRequestMethod(), "GET")) {
|
||||
conn.setDoOutput(true);
|
||||
OutputStream os = conn.getOutputStream();
|
||||
os.write(body);
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
conn.connect();
|
||||
|
||||
int responseCode = conn.getResponseCode();
|
||||
|
||||
InputStream is;
|
||||
if (responseCode == 200) {
|
||||
is = conn.getInputStream();
|
||||
} else {
|
||||
is = conn.getErrorStream();
|
||||
}
|
||||
String responseBody = new String(is.readAllBytes());
|
||||
is.close();
|
||||
|
||||
System.out.println(responseCode);
|
||||
System.out.println(responseBody);
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
private String signStringEncoder(String source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder buf = new StringBuilder(source.length());
|
||||
ByteBuffer bb = UTF_8.encode(source);
|
||||
while (bb.hasRemaining()) {
|
||||
int b = bb.get() & 255;
|
||||
if (URLENCODER.get(b)) {
|
||||
buf.append((char) b);
|
||||
} else if (b == 32) {
|
||||
buf.append("%20");
|
||||
} else {
|
||||
buf.append("%");
|
||||
char hex1 = CONST_ENCODE.charAt(b >> 4);
|
||||
char hex2 = CONST_ENCODE.charAt(b & 15);
|
||||
buf.append(hex1);
|
||||
buf.append(hex2);
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String hashSHA256(byte[] content) throws Exception {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
return HexFormat.of().formatHex(md.digest(content));
|
||||
} catch (Exception e) {
|
||||
throw new Exception(
|
||||
"Unable to compute hash while signing request: "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] hmacSHA256(byte[] key, String content) throws Exception {
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(new SecretKeySpec(key, "HmacSHA256"));
|
||||
return mac.doFinal(content.getBytes());
|
||||
} catch (Exception e) {
|
||||
throw new Exception(
|
||||
"Unable to calculate a request signature: "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] genSigningSecretKeyV4(String secretKey, String date, String region, String service) throws Exception {
|
||||
byte[] kDate = hmacSHA256((secretKey).getBytes(), date);
|
||||
byte[] kRegion = hmacSHA256(kDate, region);
|
||||
byte[] kService = hmacSHA256(kRegion, service);
|
||||
return hmacSHA256(kService, "request");
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ server:
|
|||
session:
|
||||
cookie:
|
||||
max-age: 2592000
|
||||
timeout: 720h
|
||||
timeout: 2592000
|
||||
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath:mapper/*.xml
|
||||
|
|
|
@ -52,7 +52,7 @@ server:
|
|||
session:
|
||||
cookie:
|
||||
max-age: 2592000
|
||||
timeout: 720h
|
||||
timeout: 2592000
|
||||
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath:mapper/*.xml
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
spring:
|
||||
profiles:
|
||||
active: prod
|
||||
active: dev
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user