Merge branch 'dev/dev' into dev/dev-ltx
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -31,3 +31,4 @@ build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
/logs/
|
||||
|
||||
@@ -10,11 +10,12 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 日志切面
|
||||
*
|
||||
*
|
||||
* @author AI Assistant
|
||||
* @since 2024-01-01
|
||||
*/
|
||||
@@ -28,13 +29,15 @@ public class LoggingAspect {
|
||||
* 定义切点:所有Controller方法
|
||||
*/
|
||||
@Pointcut("execution(* com.aida.lanecarford.controller..*(..))")
|
||||
public void controllerMethods() {}
|
||||
public void controllerMethods() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义切点:所有Service方法
|
||||
*/
|
||||
@Pointcut("execution(* com.aida.lanecarford.service..*(..))")
|
||||
public void serviceMethods() {}
|
||||
public void serviceMethods() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller方法执行前记录日志
|
||||
@@ -44,12 +47,13 @@ public class LoggingAspect {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if (attributes != null) {
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
|
||||
logger.info("=== 请求开始 ===");
|
||||
logger.info("请求URL: {}", request.getRequestURL().toString());
|
||||
logger.info("请求方法: {}", request.getMethod());
|
||||
logger.info("请求IP: {}", getClientIpAddress(request));
|
||||
logger.info("调用方法: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
|
||||
// logger.info("调用方法: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
|
||||
logger.info("调用方法: {}.{}", joinPoint.getSignature().getDeclaringType().getSimpleName(), joinPoint.getSignature().getName());
|
||||
logger.info("请求参数: {}", Arrays.toString(joinPoint.getArgs()));
|
||||
}
|
||||
}
|
||||
@@ -59,7 +63,7 @@ public class LoggingAspect {
|
||||
*/
|
||||
@AfterReturning(pointcut = "controllerMethods()", returning = "result")
|
||||
public void logControllerAfterReturning(JoinPoint joinPoint, Object result) {
|
||||
logger.info("方法执行成功: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
|
||||
logger.info("方法执行成功: {}.{}", joinPoint.getSignature().getDeclaringType().getSimpleName(), joinPoint.getSignature().getName());
|
||||
logger.info("返回结果: {}", result);
|
||||
logger.info("=== 请求结束 ===");
|
||||
}
|
||||
@@ -69,7 +73,7 @@ public class LoggingAspect {
|
||||
*/
|
||||
@AfterThrowing(pointcut = "controllerMethods()", throwing = "exception")
|
||||
public void logControllerAfterThrowing(JoinPoint joinPoint, Throwable exception) {
|
||||
logger.error("方法执行异常: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
|
||||
logger.error("方法执行异常: {}.{}", joinPoint.getSignature().getDeclaringType().getSimpleName(), joinPoint.getSignature().getName());
|
||||
logger.error("异常信息: ", exception);
|
||||
logger.info("=== 请求异常结束 ===");
|
||||
}
|
||||
@@ -80,15 +84,15 @@ public class LoggingAspect {
|
||||
@Around("serviceMethods()")
|
||||
public Object logServiceAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
long startTime = System.currentTimeMillis();
|
||||
String methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
|
||||
|
||||
// String methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
|
||||
String methodName = joinPoint.getSignature().getDeclaringType().getSimpleName() + "." + joinPoint.getSignature().getName();
|
||||
try {
|
||||
logger.debug("Service方法开始执行: {}", methodName);
|
||||
Object result = joinPoint.proceed();
|
||||
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
logger.debug("Service方法执行成功: {}, 耗时: {}ms", methodName, (endTime - startTime));
|
||||
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
@@ -106,22 +110,22 @@ public class LoggingAspect {
|
||||
if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
|
||||
return xForwardedFor.split(",")[0];
|
||||
}
|
||||
|
||||
|
||||
String xRealIp = request.getHeader("X-Real-IP");
|
||||
if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
|
||||
return xRealIp;
|
||||
}
|
||||
|
||||
|
||||
String proxyClientIp = request.getHeader("Proxy-Client-IP");
|
||||
if (proxyClientIp != null && !proxyClientIp.isEmpty() && !"unknown".equalsIgnoreCase(proxyClientIp)) {
|
||||
return proxyClientIp;
|
||||
}
|
||||
|
||||
|
||||
String wlProxyClientIp = request.getHeader("WL-Proxy-Client-IP");
|
||||
if (wlProxyClientIp != null && !wlProxyClientIp.isEmpty() && !"unknown".equalsIgnoreCase(wlProxyClientIp)) {
|
||||
return wlProxyClientIp;
|
||||
}
|
||||
|
||||
|
||||
return request.getRemoteAddr();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 性能监控切面
|
||||
*
|
||||
*
|
||||
* @author AI Assistant
|
||||
* @since 2024-01-01
|
||||
*/
|
||||
@@ -22,7 +22,7 @@ public class PerformanceAspect {
|
||||
/**
|
||||
* 监控Controller方法性能
|
||||
*/
|
||||
@Around("execution(* com.aida.lanecarford.controller..*(..))")
|
||||
// @Around("execution(* com.aida.lanecarford.controller..*(..))")
|
||||
public Object monitorControllerPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
return monitorMethodPerformance(joinPoint, "Controller");
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public class PerformanceAspect {
|
||||
/**
|
||||
* 监控Service方法性能
|
||||
*/
|
||||
@Around("execution(* com.aida.lanecarford.service..*(..))")
|
||||
// @Around("execution(* com.aida.lanecarford.service..*(..))")
|
||||
public Object monitorServicePerformance(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
return monitorMethodPerformance(joinPoint, "Service");
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public class PerformanceAspect {
|
||||
/**
|
||||
* 监控数据库操作性能
|
||||
*/
|
||||
@Around("execution(* com.aida.lanecarford.mapper..*(..))")
|
||||
// @Around("execution(* com.aida.lanecarford.mapper..*(..))")
|
||||
public Object monitorMapperPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
return monitorMethodPerformance(joinPoint, "Mapper");
|
||||
}
|
||||
@@ -49,28 +49,28 @@ public class PerformanceAspect {
|
||||
private Object monitorMethodPerformance(ProceedingJoinPoint joinPoint, String layer) throws Throwable {
|
||||
long startTime = System.currentTimeMillis();
|
||||
String methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
|
||||
|
||||
|
||||
try {
|
||||
Object result = joinPoint.proceed();
|
||||
long endTime = System.currentTimeMillis();
|
||||
long executionTime = endTime - startTime;
|
||||
|
||||
|
||||
// 记录性能日志
|
||||
logPerformance(layer, methodName, executionTime, true);
|
||||
|
||||
|
||||
// 如果执行时间过长,记录警告
|
||||
if (executionTime > getWarningThreshold(layer)) {
|
||||
logger.warn("{}方法执行时间过长: {} - {}ms", layer, methodName, executionTime);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
long executionTime = endTime - startTime;
|
||||
|
||||
|
||||
// 记录异常性能日志
|
||||
logPerformance(layer, methodName, executionTime, false);
|
||||
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -80,10 +80,10 @@ public class PerformanceAspect {
|
||||
*/
|
||||
private void logPerformance(String layer, String methodName, long executionTime, boolean success) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("性能监控 - {}: {} - {}ms - {}",
|
||||
layer, methodName, executionTime, success ? "成功" : "失败");
|
||||
logger.debug("性能监控 - {}: {} - {}ms - {}",
|
||||
layer, methodName, executionTime, success ? "成功" : "失败");
|
||||
}
|
||||
|
||||
|
||||
// 可以在这里添加性能数据收集逻辑,比如发送到监控系统
|
||||
collectPerformanceMetrics(layer, methodName, executionTime, success);
|
||||
}
|
||||
@@ -114,7 +114,7 @@ public class PerformanceAspect {
|
||||
// - 发送到时序数据库
|
||||
// - 更新内存中的统计信息
|
||||
// - 发送到监控系统
|
||||
|
||||
|
||||
// 示例:简单的内存统计
|
||||
PerformanceMetrics.recordExecution(layer, methodName, executionTime, success);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public class PerformanceAspect {
|
||||
* 简单的性能指标收集器
|
||||
*/
|
||||
private static class PerformanceMetrics {
|
||||
|
||||
|
||||
public static void recordExecution(String layer, String methodName, long executionTime, boolean success) {
|
||||
// 简单的日志记录,实际项目中可以替换为更复杂的指标收集
|
||||
if (executionTime > 1000) { // 超过1秒的操作
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.aida.lanecarford.common.enums;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -8,13 +9,18 @@ import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "生成状态枚举")
|
||||
public enum StatusEnum {
|
||||
@Schema(description = "等待中")
|
||||
PENDING(0),
|
||||
|
||||
@Schema(description = "成功")
|
||||
SUCCEEDED(1),
|
||||
|
||||
@Schema(description = "失败")
|
||||
FAILED(2),
|
||||
|
||||
@Schema(description = "运行中")
|
||||
RUNNING(3);
|
||||
|
||||
private int code;
|
||||
@@ -24,5 +30,4 @@ public enum StatusEnum {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ import java.util.stream.Stream;
|
||||
@AllArgsConstructor
|
||||
public enum StylistPathEnum {
|
||||
|
||||
STYLIST_ONE("crystal", "lanecarford/stylist_guide/crystal_en.md"),
|
||||
STYLIST_ONE("crystal", "lanecarford/stylist_guide/latest/crystal_en.md"),
|
||||
|
||||
STYLIST_TWO("mini", "lanecarford/stylist_guide/mini_en.md");
|
||||
STYLIST_TWO("mini", "lanecarford/stylist_guide/latest/mini_en.md");
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.aida.lanecarford.controller;
|
||||
|
||||
import com.aida.lanecarford.common.ApiResponse;
|
||||
import com.aida.lanecarford.dto.LoginRequest;
|
||||
import com.aida.lanecarford.entity.User;
|
||||
import com.aida.lanecarford.service.LoginService;
|
||||
import com.aida.lanecarford.vo.LoginVO;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
@@ -23,8 +24,8 @@ public class LoginController {
|
||||
private final LoginService loginService;
|
||||
|
||||
@Operation(
|
||||
summary = "预检查并发送邮箱验证码",
|
||||
description = "根据操作类型验证邮箱有效性并发送验证码。支持注册、登录、忘记密码三种操作类型。"
|
||||
summary = "预检查并发送邮箱验证码",
|
||||
description = "根据操作类型验证邮箱有效性并发送验证码。支持注册、登录、忘记密码三种操作类型。"
|
||||
)
|
||||
@PostMapping("/precheckAndSendEmail")
|
||||
@Hidden
|
||||
@@ -44,8 +45,8 @@ public class LoginController {
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "用户注册或登录",
|
||||
description = "通过验证码完成用户注册或登录,返回JWT令牌和用户信息。"
|
||||
summary = "用户注册或登录",
|
||||
description = "通过验证码完成用户注册或登录,返回JWT令牌和用户信息。"
|
||||
)
|
||||
@PostMapping("/registerOrLogin")
|
||||
public ApiResponse<LoginVO> registerOrLogin(@Valid @RequestBody LoginRequest loginRequest) {
|
||||
@@ -53,8 +54,8 @@ public class LoginController {
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "用户登出",
|
||||
description = "清除用户登录状态,使当前JWT令牌失效。"
|
||||
summary = "用户登出",
|
||||
description = "清除用户登录状态,使当前JWT令牌失效。"
|
||||
)
|
||||
@GetMapping("/logout")
|
||||
public ApiResponse<String> logout() {
|
||||
@@ -63,8 +64,8 @@ public class LoginController {
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "忘记密码",
|
||||
description = "通过邮箱验证码重置用户密码。需要先获取验证码,然后提供新密码。"
|
||||
summary = "忘记密码",
|
||||
description = "通过邮箱验证码重置用户密码。需要先获取验证码,然后提供新密码。"
|
||||
)
|
||||
@PostMapping("/forgotPwd")
|
||||
public ApiResponse<String> forgotPwd(@Valid @RequestBody LoginRequest loginRequest) {
|
||||
@@ -73,8 +74,8 @@ public class LoginController {
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "检查登录状态",
|
||||
description = "验证当前用户的登录状态是否有效,检查JWT令牌是否过期。"
|
||||
summary = "检查登录状态",
|
||||
description = "验证当前用户的登录状态是否有效,检查JWT令牌是否过期。"
|
||||
)
|
||||
@GetMapping("/checkLoginStatus")
|
||||
public ApiResponse<String> checkLoginStatus() {
|
||||
@@ -86,4 +87,13 @@ public class LoginController {
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "获取用户信息",
|
||||
description = "通过token获取当前用户信息"
|
||||
)
|
||||
@GetMapping("/getUserInfo")
|
||||
public ApiResponse<User> getUserInfo() {
|
||||
return ApiResponse.success(loginService.getUserInfo());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,17 +5,15 @@ import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 请求参数基类
|
||||
*
|
||||
* @author AI Assistant
|
||||
* @since 2024-01-01
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "请求参数基类")
|
||||
public abstract class BaseRequest implements Serializable {
|
||||
public class BaseRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -71,8 +69,8 @@ public abstract class BaseRequest implements Serializable {
|
||||
* 是否有时间范围筛选
|
||||
*/
|
||||
public boolean hasTimeRange() {
|
||||
return startTime != null && !startTime.trim().isEmpty()
|
||||
&& endTime != null && !endTime.trim().isEmpty();
|
||||
return startTime != null && !startTime.trim().isEmpty()
|
||||
&& endTime != null && !endTime.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.aida.lanecarford.dto;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class OutfitCallbackDTO {
|
||||
@@ -14,5 +15,5 @@ public class OutfitCallbackDTO {
|
||||
|
||||
private String path;
|
||||
|
||||
private List<String> items;
|
||||
private List<Map<String, String>> items;
|
||||
}
|
||||
|
||||
@@ -26,4 +26,6 @@ public interface LoginService extends IService<User> {
|
||||
void forgotPwd(LoginRequest loginRequest);
|
||||
|
||||
boolean checkLoginStatus();
|
||||
|
||||
User getUserInfo();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.aida.lanecarford.service.impl;
|
||||
import com.aida.lanecarford.common.constant.RedisURIConstants;
|
||||
import com.aida.lanecarford.common.enums.AuthenticationOperationTypeEnum;
|
||||
import com.aida.lanecarford.common.enums.LanguageEnum;
|
||||
import com.aida.lanecarford.common.response.ResultEnum;
|
||||
import com.aida.lanecarford.common.security.JwtUtil;
|
||||
import com.aida.lanecarford.common.security.context.UserContext;
|
||||
import com.aida.lanecarford.dto.LoginRequest;
|
||||
@@ -246,11 +247,18 @@ public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements L
|
||||
return false;
|
||||
}
|
||||
|
||||
// 谷歌登录
|
||||
|
||||
|
||||
// todo 谷歌登录
|
||||
|
||||
|
||||
// 获取用户信息
|
||||
public User getUserInfo() {
|
||||
AuthPrincipalVO userHolder = UserContext.getUserHolder();
|
||||
User user = getById(userHolder.getId());
|
||||
if (Objects.isNull(user)) {
|
||||
throw new BusinessException("User information cannot be found", ResultEnum.ERROR.getCode());
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class StyleServiceImpl extends ServiceImpl<StyleMapper, Style> implements
|
||||
outfitRequest.setGender(requestOutfitDTO.getGender());
|
||||
outfitRequestMapper.insert(outfitRequest);
|
||||
|
||||
String response = SendRequestUtil.sendPost(CommonConstants.REQUEST_OUTFIT, JSON.toJSONString(params));
|
||||
String response = SendRequestUtil.sendPostWithRetry(CommonConstants.REQUEST_OUTFIT, JSON.toJSONString(params));
|
||||
|
||||
JSONObject jsonObject = JSONObject.parseObject(response); // todo 确认这里的status的取值
|
||||
if (Objects.isNull(response) /*|| !jsonObject.getString("status").equals("ok")*/) {
|
||||
@@ -75,7 +75,7 @@ public class StyleServiceImpl extends ServiceImpl<StyleMapper, Style> implements
|
||||
|
||||
List<String> requestIds = jsonObject.getJSONArray("outfit_ids").toJavaList(String.class);
|
||||
|
||||
for(String requestId : requestIds) {
|
||||
for (String requestId : requestIds) {
|
||||
// 生成需要 6~8s, 所以这里可以先请求再存储
|
||||
Style style = new Style();
|
||||
style.setCustomerId(requestOutfitDTO.getCustomerId());
|
||||
@@ -175,7 +175,7 @@ public class StyleServiceImpl extends ServiceImpl<StyleMapper, Style> implements
|
||||
String key = RedisURIConstants.outfitResultCache + requestID;
|
||||
Object outfit = cacheUtil.getCache(key);
|
||||
|
||||
if (Objects.isNull(outfit)){
|
||||
if (Objects.isNull(outfit)) {
|
||||
reQueryIds.add(requestID);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
@Component
|
||||
public class SendRequestUtil {
|
||||
|
||||
public static String sendPost(String url, String requestBodyStr){
|
||||
public static String sendPost(String url, String requestBodyStr) {
|
||||
int status;
|
||||
String body;
|
||||
try (HttpResponse execute = HttpRequest.post(url)
|
||||
@@ -53,6 +53,61 @@ public class SendRequestUtil {
|
||||
throw new BusinessException("System error (External interface failure)");
|
||||
}
|
||||
|
||||
public static String sendPostWithRetry(String url, String requestBodyStr) {
|
||||
return sendPost(url, requestBodyStr, 3, 1000); // 默认重试3次,间隔1秒
|
||||
}
|
||||
|
||||
public static String sendPost(String url, String requestBodyStr, int maxRetries, long retryInterval) {
|
||||
int status = 0;
|
||||
String body = null;
|
||||
int retryCount = 0;
|
||||
|
||||
while (retryCount <= maxRetries) {
|
||||
try {
|
||||
log.debug("发送POST请求,URL: {}, 重试次数: {}/{}", url, retryCount, maxRetries);
|
||||
|
||||
HttpResponse execute = HttpRequest.post(url)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(requestBodyStr)
|
||||
.timeout(180000)
|
||||
.execute();
|
||||
|
||||
status = execute.getStatus();
|
||||
body = execute.body();
|
||||
|
||||
if (status == 200) {
|
||||
log.debug("请求成功,URL: {}, 状态码: {}", url, status);
|
||||
return body;
|
||||
} else {
|
||||
log.warn("请求返回非200状态码,URL: {}, 状态码: {}, Body: {}", url, status, body);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("请求发生异常,URL: {}, 异常信息: {}, 重试次数: {}/{}",
|
||||
url, e.getMessage(), retryCount, maxRetries);
|
||||
}
|
||||
|
||||
// 判断是否继续重试
|
||||
if (retryCount < maxRetries) {
|
||||
retryCount++;
|
||||
try {
|
||||
log.debug("等待 {}ms 后重试...", retryInterval);
|
||||
Thread.sleep(retryInterval);
|
||||
// 可选:递增重试间隔(指数退避)
|
||||
retryInterval = (long) (retryInterval * 1.5);
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException("重试被中断", ie);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log.error("请求最终失败,URL: {}, 最大重试次数: {}, 最后状态码: {}, 最后响应: {}",
|
||||
url, maxRetries, status, body);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class StringListConverter {
|
||||
@@ -16,7 +17,7 @@ public class StringListConverter {
|
||||
/**
|
||||
* 将 List<String> 转换为 JSON 字符串
|
||||
*/
|
||||
public static String listToJson(List<String> list) {
|
||||
public static String listToJson(List<Map<String, String>> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return "[]";
|
||||
}
|
||||
@@ -31,12 +32,13 @@ public class StringListConverter {
|
||||
/**
|
||||
* 将 JSON 字符串转换为 List<String>
|
||||
*/
|
||||
public static List<String> jsonToList(String json) {
|
||||
public static List<Map<String, String>> jsonToList(String json) {
|
||||
if (json == null || json.trim().isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
try {
|
||||
return objectMapper.readValue(json, new TypeReference<List<String>>() {});
|
||||
return objectMapper.readValue(json, new TypeReference<>() {
|
||||
});
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("JSON转List失败: {}", json, e);
|
||||
throw new RuntimeException("JSON转List失败", e);
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
package com.aida.lanecarford.vo;
|
||||
|
||||
import com.aida.lanecarford.common.enums.StatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Schema(description = "AI穿搭推荐结果响应参数")
|
||||
public class OutfitResultVO {
|
||||
|
||||
@Schema(description = "记录ID", example = "21")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "请求ID", example = "7c30e8f6-fdc6-4699-9239-ae6a9d3cf948")
|
||||
private String requestId;
|
||||
|
||||
@Schema(description = "图片路径", example = "https://example.com/images/outfit_123.jpg")
|
||||
private String path;
|
||||
|
||||
@Schema(
|
||||
description = "处理状态",
|
||||
implementation = StatusEnum.class,
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
private String status;
|
||||
|
||||
public OutfitResultVO(Long id, String requestId, String status) {
|
||||
|
||||
@@ -45,7 +45,7 @@ spring:
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
logic-delete-field: deleted
|
||||
|
||||
Reference in New Issue
Block a user