Compare commits
38 Commits
23716984cc
...
dev/3.1_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c68ce74ac | ||
|
|
5745c334df | ||
| d9c0e67c07 | |||
| fe9cc99701 | |||
| 73c366d827 | |||
|
|
85e02a895c | ||
|
|
148bb84f3c | ||
|
|
931eef6f53 | ||
|
|
3d9a6aa9e9 | ||
| 11073690e5 | |||
|
|
921d2d956e | ||
|
|
d700f94f9d | ||
|
|
b277479e73 | ||
|
|
83cbd57dea | ||
|
|
4d3b22de82 | ||
|
|
6b5c2cfec0 | ||
|
|
b676de054a | ||
|
|
4c169ef67e | ||
|
|
f2bce066b6 | ||
|
|
6af442eb15 | ||
|
|
768df55309 | ||
|
|
f351277b73 | ||
|
|
a799162ea4 | ||
|
|
c035eb9d7d | ||
|
|
906a54b3c8 | ||
|
|
643799546b | ||
|
|
f582464cd3 | ||
|
|
b864b393bc | ||
|
|
c03a8762e7 | ||
|
|
cb87ad1099 | ||
|
|
fb229764f8 | ||
|
|
8bec1f842d | ||
|
|
b54bd04cff | ||
|
|
b4ccad6242 | ||
|
|
6068bf7d7d | ||
|
|
d36baf747f | ||
| 7c8f1bee6a | |||
|
|
62bd145e2c |
111
.gitea/workflows/develop_3.1_MS_build_manual.yaml
Normal file
111
.gitea/workflows/develop_3.1_MS_build_manual.yaml
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
name: 手动 AiDA back-java 开发分支构建部署
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_deploy:
|
||||||
|
runs-on: java21
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
build_status: ${{ job.status }}
|
||||||
|
build_url: ${{ gitea.server_url }}/${{ gitea.repository.owner.name }}/${{ gitea.repository.name }}/actions/runs/${{ gitea.run_id }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
REMOTE_DEPLOY_PATH: /workspace/workspace_aida/DevelopVersion/develop-MS-version-aida-back
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 0.记录开始时间
|
||||||
|
id: build_start_time
|
||||||
|
run: echo "current_time=$(TZ='Asia/Hong_Kong' date '+%Y-%m-%d %H:%M:%S %Z')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 1.检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: dev/3.1_release_merge_MS
|
||||||
|
|
||||||
|
|
||||||
|
- name: 3.缓存 Maven 依赖
|
||||||
|
uses: actions/cache@v5
|
||||||
|
with:
|
||||||
|
path: ~/.m2/repository
|
||||||
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-maven-
|
||||||
|
|
||||||
|
- name: 4.构建项目
|
||||||
|
run: |
|
||||||
|
java -version
|
||||||
|
mvn -v
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
|
||||||
|
- name: 5.生成Dockerfile
|
||||||
|
run: |
|
||||||
|
echo "===== 生成Dockerfile ====="
|
||||||
|
cat > Dockerfile << 'EOF'
|
||||||
|
FROM openjdk:21-ea-21-jdk-slim
|
||||||
|
VOLUME /tmp
|
||||||
|
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||||
|
RUN echo 'Asia/Shanghai' > /etc/timezone
|
||||||
|
ADD ./target/aida-0.0.1-SNAPSHOT.jar /app.jar
|
||||||
|
ENTRYPOINT ["java","-jar","/app.jar"]
|
||||||
|
EOF
|
||||||
|
echo "Dockerfile内容:"
|
||||||
|
cat Dockerfile
|
||||||
|
|
||||||
|
- name: 6.生成docker-compose.yml
|
||||||
|
run: |
|
||||||
|
echo "===== 生成docker-compose.yml ====="
|
||||||
|
cat > docker-compose.yml << 'EOF'
|
||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
aida_back:
|
||||||
|
container_name: develop-aida-ms
|
||||||
|
build: .
|
||||||
|
volumes:
|
||||||
|
# 数据挂载
|
||||||
|
- ./log:/log
|
||||||
|
- ./temp:/temp
|
||||||
|
- ./uploads:/temp/uploads
|
||||||
|
ports:
|
||||||
|
- '10092:10092'
|
||||||
|
restart: always
|
||||||
|
EOF
|
||||||
|
# 验证docker-compose.yml生成
|
||||||
|
echo "docker-compose.yml内容:"
|
||||||
|
cat docker-compose.yml
|
||||||
|
|
||||||
|
- name: 7.上传jar到远程服务器
|
||||||
|
uses: appleboy/scp-action@master
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
port: 22
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
source: "target/*.jar,Dockerfile,docker-compose.yml"
|
||||||
|
target: ${{ env.REMOTE_DEPLOY_PATH }}
|
||||||
|
preserve_host_directory_structure: false
|
||||||
|
|
||||||
|
- name: 8. 重启 Docker 服务
|
||||||
|
uses: appleboy/ssh-action@master # 👈 专门执行命令的 action
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
key_base64: true
|
||||||
|
script: |
|
||||||
|
echo "========= 进入部署目录 ========="
|
||||||
|
cd ${{ env.REMOTE_DEPLOY_PATH }}
|
||||||
|
ls -l
|
||||||
|
|
||||||
|
echo "========= 停止旧服务 ========="
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
echo "========= 启动新服务 ========="
|
||||||
|
docker compose up -d --build
|
||||||
|
|
||||||
|
echo "========= 查看运行状态 ========="
|
||||||
|
docker compose ps
|
||||||
@@ -103,7 +103,13 @@ jobs:
|
|||||||
- ./uploads:/temp/uploads
|
- ./uploads:/temp/uploads
|
||||||
ports:
|
ports:
|
||||||
- '10090:5567'
|
- '10090:5567'
|
||||||
|
networks:
|
||||||
|
- aida_java_net
|
||||||
restart: always
|
restart: always
|
||||||
|
networks:
|
||||||
|
aida_java_net:
|
||||||
|
external: true
|
||||||
|
name: aida_java_net
|
||||||
EOF
|
EOF
|
||||||
# 验证docker-compose.yml生成
|
# 验证docker-compose.yml生成
|
||||||
echo "docker-compose.yml内容:"
|
echo "docker-compose.yml内容:"
|
||||||
|
|||||||
6
pom.xml
6
pom.xml
@@ -263,6 +263,12 @@
|
|||||||
<version>2.15.1</version>
|
<version>2.15.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.13.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.stripe</groupId>
|
<groupId>com.stripe</groupId>
|
||||||
<artifactId>stripe-java</artifactId>
|
<artifactId>stripe-java</artifactId>
|
||||||
|
|||||||
@@ -222,16 +222,16 @@ public class SRConsumer {
|
|||||||
taskListService.updateTaskStatusOrOutputRedis(uniqueId, "fail", null);
|
taskListService.updateTaskStatusOrOutputRedis(uniqueId, "fail", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RabbitListener(queues = "#{rabbitMQProperties.queues.sr}")
|
// @RabbitListener(queues = "#{rabbitMQProperties.queues.sr}")
|
||||||
@RabbitHandler
|
// @RabbitHandler
|
||||||
public void SRConsumer1(Message msg, Channel channel) {
|
// public void SRConsumer1(Message msg, Channel channel) {
|
||||||
superResolution(msg, channel, "consumer 1");
|
// superResolution(msg, channel, "consumer 1");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@RabbitListener(queues = "#{rabbitMQProperties.queues.srResult}")
|
// @RabbitListener(queues = "#{rabbitMQProperties.queues.srResult}")
|
||||||
@RabbitHandler
|
// @RabbitHandler
|
||||||
public void SRResultConsumer1(Message msg, Channel channel) {
|
// public void SRResultConsumer1(Message msg, Channel channel) {
|
||||||
getSRResult(msg, channel, "consumer 1");
|
// getSRResult(msg, channel, "consumer 1");
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,11 @@ public class ControllerLoggingAspect {
|
|||||||
|
|
||||||
// 获取当前用户ID
|
// 获取当前用户ID
|
||||||
Long userId = null;
|
Long userId = null;
|
||||||
AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
|
try {
|
||||||
if (authPrincipalVo != null) {
|
AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
|
||||||
userId = authPrincipalVo.getId();
|
userId = authPrincipalVo.getId();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// 匿名接口,无认证上下文,忽略
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取请求参数
|
// 获取请求参数
|
||||||
@@ -121,9 +123,11 @@ public class ControllerLoggingAspect {
|
|||||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
|
||||||
Long userId = null;
|
Long userId = null;
|
||||||
AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
|
try {
|
||||||
if (authPrincipalVo != null) {
|
AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
|
||||||
userId = authPrincipalVo.getId();
|
userId = authPrincipalVo.getId();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// 匿名接口,无认证上下文,忽略
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取请求参数
|
// 获取请求参数
|
||||||
|
|||||||
@@ -1,89 +1,99 @@
|
|||||||
package com.ai.da.common.config.exception;
|
package com.ai.da.common.config.exception;
|
||||||
|
|
||||||
import com.ai.da.common.response.Response;
|
import com.ai.da.common.response.Response;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.ai.da.common.response.ResultEnum;
|
import com.ai.da.common.response.ResultEnum;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.validation.BindException;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.validation.BindException;
|
||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
/**
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
* @author: dangweijian
|
|
||||||
* @description: 全局异常捕获
|
/**
|
||||||
* @create: 2019-12-03 10:24
|
* @author: dangweijian
|
||||||
**/
|
* @description: 全局异常捕获
|
||||||
@Slf4j
|
* @create: 2019-12-03 10:24
|
||||||
@ControllerAdvice
|
**/
|
||||||
public class ExceptionCatch {
|
@Slf4j
|
||||||
|
@ControllerAdvice
|
||||||
/**
|
public class ExceptionCatch {
|
||||||
* 线程安全,且构建后不可更改
|
|
||||||
*/
|
/**
|
||||||
private static ImmutableMap<Class<? extends Throwable>, ResultEnum> EXCEPTIONS;
|
* 线程安全,且构建后不可更改
|
||||||
|
*/
|
||||||
/**
|
private static ImmutableMap<Class<? extends Throwable>, ResultEnum> EXCEPTIONS;
|
||||||
* 用于构建ImmutableMap
|
|
||||||
*/
|
/**
|
||||||
private static ImmutableMap.Builder<Class<? extends Throwable>, ResultEnum> builder = ImmutableMap.builder();
|
* 用于构建ImmutableMap
|
||||||
|
*/
|
||||||
@ResponseBody
|
private static ImmutableMap.Builder<Class<? extends Throwable>, ResultEnum> builder = ImmutableMap.builder();
|
||||||
@ExceptionHandler(BusinessException.class)
|
|
||||||
public Response<String> businessExceptionCatch(BusinessException e) {
|
@ResponseBody
|
||||||
log.error("发生业务异常,code:[{}],msg:[{}]", e.getCode(), e.getMsg(), e);
|
@ExceptionHandler(BusinessException.class)
|
||||||
return Response.error(e.getCode(), e.getMsg());
|
public Response<String> businessExceptionCatch(BusinessException e) {
|
||||||
}
|
log.error("发生业务异常,code:[{}],msg:[{}]", e.getCode(), e.getMsg(), e);
|
||||||
|
return Response.error(e.getCode(), e.getMsg());
|
||||||
@ResponseBody
|
}
|
||||||
@ExceptionHandler(Exception.class)
|
|
||||||
public Response<String> exceptionCatch(Exception e) {
|
@ResponseBody
|
||||||
log.error("发生系统异常,message:[{}]", e.getMessage(), e);
|
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||||
//如果ImmutableMap集合为空,构建ImmutableMap
|
@ExceptionHandler(UnauthorizedException.class)
|
||||||
if (EXCEPTIONS == null || EXCEPTIONS.size() == 0) {
|
public Response<String> unauthorizedExceptionCatch(UnauthorizedException e) {
|
||||||
EXCEPTIONS = builder.build();
|
log.error("Unauthorized: {}", e.getMessage());
|
||||||
}
|
return Response.error(401, e.getMessage());
|
||||||
//获取不可预知异常自定义错误码
|
}
|
||||||
if (EXCEPTIONS != null) {
|
|
||||||
ResultEnum resultEnum = EXCEPTIONS.get(e.getClass());
|
@ResponseBody
|
||||||
if (resultEnum != null) {
|
@ExceptionHandler(Exception.class)
|
||||||
return Response.error(resultEnum.getCode(), resultEnum.getMsg());
|
public Response<String> exceptionCatch(Exception e) {
|
||||||
}
|
log.error("发生系统异常,message:[{}]", e.getMessage(), e);
|
||||||
}
|
//如果ImmutableMap集合为空,构建ImmutableMap
|
||||||
return Response.error(ResultEnum.ERROR.getCode(), e.getMessage() == null ? ResultEnum.ERROR.getMsg() : e.getMessage());
|
if (EXCEPTIONS == null || EXCEPTIONS.size() == 0) {
|
||||||
}
|
EXCEPTIONS = builder.build();
|
||||||
|
}
|
||||||
/**
|
//获取不可预知异常自定义错误码
|
||||||
* 处理参数校验异常
|
if (EXCEPTIONS != null) {
|
||||||
*
|
ResultEnum resultEnum = EXCEPTIONS.get(e.getClass());
|
||||||
* @param e
|
if (resultEnum != null) {
|
||||||
* @return ResponseData
|
return Response.error(resultEnum.getCode(), resultEnum.getMsg());
|
||||||
*/
|
}
|
||||||
@ResponseBody
|
}
|
||||||
@ExceptionHandler(BindException.class)
|
return Response.error(ResultEnum.ERROR.getCode(), e.getMessage() == null ? ResultEnum.ERROR.getMsg() : e.getMessage());
|
||||||
public Response<String> bindExceptionHandler(BindException e) {
|
}
|
||||||
log.error("参数错误bind:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
|
||||||
BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
/**
|
||||||
return Response.error(businessException.getCode(), businessException.getMsg());
|
* 处理参数校验异常
|
||||||
}
|
*
|
||||||
|
* @param e
|
||||||
/**
|
* @return ResponseData
|
||||||
* 处理参数校验异常
|
*/
|
||||||
*
|
@ResponseBody
|
||||||
* @param e
|
@ExceptionHandler(BindException.class)
|
||||||
* @return ResponseData
|
public Response<String> bindExceptionHandler(BindException e) {
|
||||||
*/
|
log.error("参数错误bind:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||||
@ResponseBody
|
BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
return Response.error(businessException.getCode(), businessException.getMsg());
|
||||||
public Response<String> handleValidationException(MethodArgumentNotValidException e) {
|
}
|
||||||
log.error("参数错误bind:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
|
||||||
BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
/**
|
||||||
return Response.error(businessException.getCode(), businessException.getMsg());
|
* 处理参数校验异常
|
||||||
}
|
*
|
||||||
|
* @param e
|
||||||
//初始化,不可预知异常自定义错误编码
|
* @return ResponseData
|
||||||
static {
|
*/
|
||||||
// builder.put(FileNotFoundException.class, ResultEnum.FILE_NOT_EXIST);
|
@ResponseBody
|
||||||
}
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
}
|
public Response<String> handleValidationException(MethodArgumentNotValidException e) {
|
||||||
|
log.error("参数错误bind:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||||
|
BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||||
|
return Response.error(businessException.getCode(), businessException.getMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化,不可预知异常自定义错误编码
|
||||||
|
static {
|
||||||
|
// builder.put(FileNotFoundException.class, ResultEnum.FILE_NOT_EXIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.ai.da.common.config.exception;
|
||||||
|
|
||||||
|
public class UnauthorizedException extends RuntimeException {
|
||||||
|
|
||||||
|
public UnauthorizedException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnauthorizedException() {
|
||||||
|
super("Gateway token verification failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ public class CommonConstant {
|
|||||||
// 单位 秒 两天过期
|
// 单位 秒 两天过期
|
||||||
public static final Long CREDITS_EXPIRE_TIME = 2 * 24 * 60 * 60L;
|
public static final Long CREDITS_EXPIRE_TIME = 2 * 24 * 60 * 60L;
|
||||||
// 单位 分钟
|
// 单位 分钟
|
||||||
public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60;
|
public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60 * 7;
|
||||||
// 单位 秒 一天过期 in redis
|
// 单位 秒 一天过期 in redis
|
||||||
public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L;
|
public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L;
|
||||||
// 单位 秒 7天过期
|
// 单位 秒 7天过期
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ public class ModelConstants {
|
|||||||
|
|
||||||
// 模型名称常量
|
// 模型名称常量
|
||||||
public static final String PRINTBOARD_ADVANCED_T2I = "qwen-image";
|
public static final String PRINTBOARD_ADVANCED_T2I = "qwen-image";
|
||||||
public static final String MOODBOARD_ADVANCED = "doubao-seedream-3-0-t2i-250415";
|
public static final String MOODBOARD_ADVANCED = "doubao-seedream-4-5-251128";
|
||||||
public static final String PRINTBOARD_HIGH_T2I = "doubao-seedream-3-0-t2i-250415";
|
public static final String PRINTBOARD_HIGH_T2I = "doubao-seedream-4-0-250828-high";
|
||||||
public static final String PRINTBOARD_HIGH_I2I = "doubao-seedream-4-0-250828-fast";
|
public static final String PRINTBOARD_HIGH_I2I = "doubao-seedream-4-0-250828-fast";
|
||||||
public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828";
|
public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828";
|
||||||
public static final String IMAGEN_MODEL = "imagen-4.0-generate-001";
|
public static final String IMAGEN_MODEL = "imagen-4.0-generate-001";
|
||||||
|
|||||||
@@ -1,19 +1,41 @@
|
|||||||
package com.ai.da.common.context;
|
package com.ai.da.common.context;
|
||||||
|
|
||||||
import com.ai.da.model.vo.AuthPrincipalVo;
|
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||||
|
|
||||||
public class UserContext {
|
public class UserContext {
|
||||||
private static ThreadLocal<AuthPrincipalVo> userHolder = new ThreadLocal<AuthPrincipalVo>();
|
private static final ThreadLocal<AuthPrincipalVo> userHolder = new ThreadLocal<>();
|
||||||
|
|
||||||
public static AuthPrincipalVo getUserHolder() {
|
public static void setUserHolder(AuthPrincipalVo authPrincipalVo) {
|
||||||
return userHolder.get();
|
userHolder.set(authPrincipalVo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void delete() {
|
public static AuthPrincipalVo getUserHolder() {
|
||||||
userHolder.remove();
|
AuthPrincipalVo holder = userHolder.get();
|
||||||
}
|
if (holder == null) {
|
||||||
|
throw new RuntimeException("User not authenticated");
|
||||||
public static void setUserHolder(AuthPrincipalVo authPrincipalVo) {
|
}
|
||||||
userHolder.set(authPrincipalVo);
|
if (!"AIDA".equals(holder.getSource())) {
|
||||||
}
|
throw new RuntimeException("Access denied: source must be AIDA");
|
||||||
}
|
}
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void delete() {
|
||||||
|
userHolder.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getUserId() {
|
||||||
|
return getUserHolder().getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getBuyerId() {
|
||||||
|
AuthPrincipalVo holder = userHolder.get();
|
||||||
|
if (holder == null) {
|
||||||
|
throw new RuntimeException("User not authenticated");
|
||||||
|
}
|
||||||
|
if (!"BUYER".equals(holder.getSource())) {
|
||||||
|
throw new RuntimeException("Access denied: source must be BUYER");
|
||||||
|
}
|
||||||
|
return holder.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class AccountTask {
|
|||||||
* 每个月月初只刷新教育子账号的积分
|
* 每个月月初只刷新教育子账号的积分
|
||||||
*/
|
*/
|
||||||
// @Scheduled(cron = "0 25 14 * * ?")
|
// @Scheduled(cron = "0 25 14 * * ?")
|
||||||
@Scheduled(cron = "0 0 0 1 * ?")
|
// @Scheduled(cron = "0 0 0 1 * ?")
|
||||||
public void refreshCreditsMonthly() {
|
public void refreshCreditsMonthly() {
|
||||||
log.info("每月1号0点 重置教育版子账号为默认积分");
|
log.info("每月1号0点 重置教育版子账号为默认积分");
|
||||||
accountService.refreshCreditsMonthly();
|
accountService.refreshCreditsMonthly();
|
||||||
@@ -54,7 +54,7 @@ public class AccountTask {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
// 每天检测正式用户到期情况,每天凌晨0点执行
|
// 每天检测正式用户到期情况,每天凌晨0点执行
|
||||||
@Scheduled(cron = "0 0 0 * * ?")
|
// @Scheduled(cron = "0 0 0 * * ?")
|
||||||
public void paidUserToVisitor() {
|
public void paidUserToVisitor() {
|
||||||
// 1、查询当前已过期正式用户或试用用户
|
// 1、查询当前已过期正式用户或试用用户
|
||||||
List<Account> accountList = accountService.getExpiredUserBySystemUser(1);
|
List<Account> accountList = accountService.getExpiredUserBySystemUser(1);
|
||||||
@@ -77,7 +77,7 @@ public class AccountTask {
|
|||||||
accountService.registerUserToVisitor();
|
accountService.registerUserToVisitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 0 0 1 * ?")
|
// @Scheduled(cron = "0 0 0 1 * ?")
|
||||||
// 每月初刷新所有用户用户名剩余修改次数
|
// 每月初刷新所有用户用户名剩余修改次数
|
||||||
public void resetUsernameModifyTimes(){
|
public void resetUsernameModifyTimes(){
|
||||||
log.info("重置所有用户的用户名修改次数");
|
log.info("重置所有用户的用户名修改次数");
|
||||||
@@ -85,17 +85,17 @@ public class AccountTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Scheduled(cron = "0 35 14 * * ?")
|
// @Scheduled(cron = "0 35 14 * * ?")
|
||||||
@Scheduled(cron = "0 5 0 * * ?")
|
// @Scheduled(cron = "0 5 0 * * ?")
|
||||||
public void checkEduAdminExpireStatus() {
|
public void checkEduAdminExpireStatus() {
|
||||||
accountService.checkEduAdminExpireStatus();
|
accountService.checkEduAdminExpireStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 5 0 * * ?")
|
// @Scheduled(cron = "0 5 0 * * ?")
|
||||||
public void activeSubscriptionPlan() {
|
public void activeSubscriptionPlan() {
|
||||||
subscriptionPlanService.activeSubscriptionPlan(null);
|
subscriptionPlanService.activeSubscriptionPlan(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
||||||
public void expireSubscription() {
|
public void expireSubscription() {
|
||||||
subscriptionPlanService.expireSubscription();
|
subscriptionPlanService.expireSubscription();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class GenerateTask {
|
|||||||
* 故这里通过定时任务做补偿
|
* 故这里通过定时任务做补偿
|
||||||
* flux五分钟查询一次,万相1小时查询一次
|
* flux五分钟查询一次,万相1小时查询一次
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "0 */4 * * * ?")
|
// @Scheduled(cron = "0 */4 * * * ?")
|
||||||
public void fluxCompensationMechanism(){
|
public void fluxCompensationMechanism(){
|
||||||
// 1、查所有 任务还没成功、还没失败,正在等待或者执行中的任务id有哪些
|
// 1、查所有 任务还没成功、还没失败,正在等待或者执行中的任务id有哪些
|
||||||
// (由于获取结果的polling_url在redis中只存一天,大部分结果超过一天之后就无法再找到任务,小部分可以通过公共路径查到结果)
|
// (由于获取结果的polling_url在redis中只存一天,大部分结果超过一天之后就无法再找到任务,小部分可以通过公共路径查到结果)
|
||||||
@@ -98,7 +98,7 @@ public class GenerateTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 万相 -> pose transformation 补偿 当前任务执行完后,5分钟再执行一次(不会出现任务重叠的情况)
|
// 万相 -> pose transformation 补偿 当前任务执行完后,5分钟再执行一次(不会出现任务重叠的情况)
|
||||||
@Scheduled(fixedDelay = 5 * 60 * 1000)
|
// @Scheduled(fixedDelay = 5 * 60 * 1000)
|
||||||
public void wxCompensationMechanism(){
|
public void wxCompensationMechanism(){
|
||||||
List<APIGenerate> apiGenerates = apiGenerateService.getPendingTaskByStatus("wx");
|
List<APIGenerate> apiGenerates = apiGenerateService.getPendingTaskByStatus("wx");
|
||||||
if (apiGenerates != null && !apiGenerates.isEmpty()){
|
if (apiGenerates != null && !apiGenerates.isEmpty()){
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class PaymentTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 定时同步(每分钟一次)
|
// 定时同步(每分钟一次)
|
||||||
@Scheduled(fixedRate = 60000)
|
// @Scheduled(fixedRate = 60000)
|
||||||
public void syncLinkViewCountToDB(){
|
public void syncLinkViewCountToDB(){
|
||||||
affiliateService.syncLinkViewCountToDB();
|
affiliateService.syncLinkViewCountToDB();
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ public class PaymentTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
||||||
public void calcCouponsCommission(){
|
public void calcCouponsCommission(){
|
||||||
// log.info("优惠券佣金计算定时器");
|
// log.info("优惠券佣金计算定时器");
|
||||||
affiliateService.calcCouponsCommission();
|
affiliateService.calcCouponsCommission();
|
||||||
|
|||||||
@@ -1,171 +1,171 @@
|
|||||||
package com.ai.da.common.utils;
|
package com.ai.da.common.utils;
|
||||||
|
|
||||||
import com.ai.da.common.constant.CommonConstant;
|
import com.ai.da.common.constant.CommonConstant;
|
||||||
import com.ai.da.model.dto.BasicEmailParamDTO;
|
import com.ai.da.model.dto.BasicEmailParamDTO;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.io.InputStreamSource;
|
import org.springframework.core.io.InputStreamSource;
|
||||||
import org.springframework.mail.MailException;
|
import org.springframework.mail.MailException;
|
||||||
import org.springframework.mail.javamail.JavaMailSender;
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.thymeleaf.TemplateEngine;
|
import org.thymeleaf.TemplateEngine;
|
||||||
import org.thymeleaf.context.Context;
|
import org.thymeleaf.context.Context;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.mail.MessagingException;
|
import jakarta.mail.MessagingException;
|
||||||
import jakarta.mail.internet.*;
|
import jakarta.mail.internet.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class MailUtil {
|
public class MailUtil {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private JavaMailSender javaMailSender;
|
private JavaMailSender javaMailSender;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private TemplateEngine templateEngine;
|
private TemplateEngine templateEngine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送邮件 - 默认发件人
|
* 发送邮件 - 默认发件人
|
||||||
*
|
*
|
||||||
* @param basicEmailParamDTO 发送邮件所需参数
|
* @param basicEmailParamDTO 发送邮件所需参数
|
||||||
* @param fileName 附件名(如果有)
|
* @param fileName 附件名(如果有)
|
||||||
* @param inputStreamSource 附件(如果有)
|
* @param inputStreamSource 附件(如果有)
|
||||||
*/
|
*/
|
||||||
public int sendMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
|
public int sendMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
|
||||||
MimeMessage mimeMessage = createSimpleMail(basicEmailParamDTO, fileName, inputStreamSource);
|
MimeMessage mimeMessage = createSimpleMail(basicEmailParamDTO, fileName, inputStreamSource);
|
||||||
// 提取配置
|
// 提取配置
|
||||||
String host;
|
String host;
|
||||||
String username;
|
String username;
|
||||||
String password;
|
String password;
|
||||||
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
|
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
|
||||||
host = ((JavaMailSenderImpl) javaMailSender).getHost();
|
host = ((JavaMailSenderImpl) javaMailSender).getHost();
|
||||||
} else {
|
} else {
|
||||||
host = basicEmailParamDTO.getServiceAddress();
|
host = basicEmailParamDTO.getServiceAddress();
|
||||||
}
|
}
|
||||||
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getSenderUser())) {
|
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getSenderUser())) {
|
||||||
username = ((JavaMailSenderImpl) javaMailSender).getUsername();
|
username = ((JavaMailSenderImpl) javaMailSender).getUsername();
|
||||||
} else {
|
} else {
|
||||||
username = basicEmailParamDTO.getSenderUser();
|
username = basicEmailParamDTO.getSenderUser();
|
||||||
}
|
}
|
||||||
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
|
if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
|
||||||
password = ((JavaMailSenderImpl) javaMailSender).getPassword();
|
password = ((JavaMailSenderImpl) javaMailSender).getPassword();
|
||||||
} else {
|
} else {
|
||||||
password = basicEmailParamDTO.getPassword();
|
password = basicEmailParamDTO.getPassword();
|
||||||
}
|
}
|
||||||
return sendMail(mimeMessage, host, username, password);
|
return sendMail(mimeMessage, host, username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int sendMail(MimeMessage mimeMessage, String host, String username, String password) throws MessagingException {
|
private int sendMail(MimeMessage mimeMessage, String host, String username, String password) throws MessagingException {
|
||||||
try {
|
try {
|
||||||
// 配置连接属性
|
// 配置连接属性
|
||||||
java.util.Properties props = mimeMessage.getSession().getProperties();
|
java.util.Properties props = mimeMessage.getSession().getProperties();
|
||||||
props.put("mail.smtp.auth", "true");
|
props.put("mail.smtp.auth", "true");
|
||||||
props.put("mail.smtp.host", host);
|
props.put("mail.smtp.host", host);
|
||||||
props.put("mail.user", username);
|
props.put("mail.user", username);
|
||||||
props.put("mail.password", password);
|
props.put("mail.password", password);
|
||||||
|
|
||||||
// 使用 JavaMailSender 发送邮件(Spring Boot 3.x 标准方式)
|
// 使用 JavaMailSender 发送邮件(Spring Boot 3.x 标准方式)
|
||||||
javaMailSender.send(mimeMessage);
|
javaMailSender.send(mimeMessage);
|
||||||
log.info("邮件发送成功至: {}", host);
|
log.info("邮件发送成功至: {}", host);
|
||||||
return 1;
|
return 1;
|
||||||
} catch (MailException e) {
|
} catch (MailException e) {
|
||||||
log.info("邮件发送失败:{}", e.getMessage());
|
log.info("邮件发送失败:{}", e.getMessage());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一封邮件
|
* 创建一封邮件
|
||||||
*
|
*
|
||||||
* @param basicEmailParamDTO 创建邮件需要的参数
|
* @param basicEmailParamDTO 创建邮件需要的参数
|
||||||
* @param inputStreamSource 附件(如果有)
|
* @param inputStreamSource 附件(如果有)
|
||||||
* @return 一封邮件
|
* @return 一封邮件
|
||||||
*/
|
*/
|
||||||
private MimeMessage createSimpleMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
|
private MimeMessage createSimpleMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
|
||||||
// 创建邮件对象
|
// 创建邮件对象
|
||||||
MimeMessage message = javaMailSender.createMimeMessage();
|
MimeMessage message = javaMailSender.createMimeMessage();
|
||||||
// 使用 MimeMessageHelper 简化邮件内容和附件的设置
|
// 使用 MimeMessageHelper 简化邮件内容和附件的设置
|
||||||
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true);
|
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true);
|
||||||
// 设置发件人
|
// 设置发件人
|
||||||
mimeMessageHelper.setFrom(new InternetAddress(basicEmailParamDTO.getSenderUserMail()));
|
mimeMessageHelper.setFrom(new InternetAddress(basicEmailParamDTO.getSenderUserMail()));
|
||||||
// 设置收件人
|
// 设置收件人
|
||||||
mimeMessageHelper.setTo(basicEmailParamDTO.getMailTo());
|
mimeMessageHelper.setTo(basicEmailParamDTO.getMailTo());
|
||||||
// 设置抄送人
|
// 设置抄送人
|
||||||
if (basicEmailParamDTO.getCc() != null && basicEmailParamDTO.getCc().length > 0) {
|
if (basicEmailParamDTO.getCc() != null && basicEmailParamDTO.getCc().length > 0) {
|
||||||
mimeMessageHelper.setCc(basicEmailParamDTO.getCc());
|
mimeMessageHelper.setCc(basicEmailParamDTO.getCc());
|
||||||
}
|
}
|
||||||
// 设置暗送人
|
// 设置暗送人
|
||||||
if (basicEmailParamDTO.getBcc() != null && basicEmailParamDTO.getBcc().length > 0) {
|
if (basicEmailParamDTO.getBcc() != null && basicEmailParamDTO.getBcc().length > 0) {
|
||||||
mimeMessageHelper.setBcc(basicEmailParamDTO.getBcc());
|
mimeMessageHelper.setBcc(basicEmailParamDTO.getBcc());
|
||||||
}
|
}
|
||||||
// 设置邮件主题
|
// 设置邮件主题
|
||||||
mimeMessageHelper.setSubject(basicEmailParamDTO.getSubject());
|
mimeMessageHelper.setSubject(basicEmailParamDTO.getSubject());
|
||||||
// 设置邮件内容(HTML 格式)
|
// 设置邮件内容(HTML 格式)
|
||||||
mimeMessageHelper.setText(basicEmailParamDTO.getContent(), true);
|
mimeMessageHelper.setText(basicEmailParamDTO.getContent(), true);
|
||||||
// 设置附件
|
// 设置附件
|
||||||
if (inputStreamSource != null) {
|
if (inputStreamSource != null) {
|
||||||
mimeMessageHelper.addAttachment(fileName, inputStreamSource);
|
mimeMessageHelper.addAttachment(fileName, inputStreamSource);
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置实体参数
|
* 设置实体参数
|
||||||
*
|
*
|
||||||
* @param mailTo 接收邮件的邮箱地址
|
* @param mailTo 接收邮件的邮箱地址
|
||||||
* @param jsonObject 模板中变量的值
|
* @param jsonObject 模板中变量的值
|
||||||
* @return 返回一个MailEntity
|
* @return 返回一个MailEntity
|
||||||
* @throws AddressException 邮箱地址值异常
|
* @throws AddressException 邮箱地址值异常
|
||||||
*/
|
*/
|
||||||
public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, JSONObject jsonObject, String templatePath, String title) throws AddressException {
|
public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, JSONObject jsonObject, String templatePath, String title) throws AddressException {
|
||||||
BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
|
BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
|
||||||
// basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
|
// basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
|
||||||
basicEmailParamDTO.setSenderUserMail(CommonConstant.senderEmail);
|
basicEmailParamDTO.setSenderUserMail(CommonConstant.senderEmail);
|
||||||
basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
|
basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
|
||||||
basicEmailParamDTO.setSubject(title);
|
basicEmailParamDTO.setSubject(title);
|
||||||
// todo 邮件模板不存在的报错与重试机制
|
// todo 邮件模板不存在的报错与重试机制
|
||||||
basicEmailParamDTO.setContent(setContent(jsonObject, templatePath));
|
basicEmailParamDTO.setContent(setContent(jsonObject, templatePath));
|
||||||
return basicEmailParamDTO;
|
return basicEmailParamDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, String title) throws AddressException {
|
public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, String title) throws AddressException {
|
||||||
BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
|
BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
|
||||||
basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
|
basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
|
||||||
basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
|
basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
|
||||||
basicEmailParamDTO.setSubject(title);
|
basicEmailParamDTO.setSubject(title);
|
||||||
return basicEmailParamDTO;
|
return basicEmailParamDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将地址转换为InternetAddress类型
|
* 将地址转换为InternetAddress类型
|
||||||
*
|
*
|
||||||
* @param addressList 普通的地址字符串列表
|
* @param addressList 普通的地址字符串列表
|
||||||
* @return InternetAddress类型的地址列表
|
* @return InternetAddress类型的地址列表
|
||||||
* @throws AddressException 地址异常
|
* @throws AddressException 地址异常
|
||||||
*/
|
*/
|
||||||
public InternetAddress[] getInternetAddressList(List<String> addressList) throws AddressException {
|
public InternetAddress[] getInternetAddressList(List<String> addressList) throws AddressException {
|
||||||
InternetAddress[] toAddress = new InternetAddress[addressList.size()];
|
InternetAddress[] toAddress = new InternetAddress[addressList.size()];
|
||||||
for (String address : addressList) {
|
for (String address : addressList) {
|
||||||
toAddress[addressList.indexOf(address)] = new InternetAddress(address);
|
toAddress[addressList.indexOf(address)] = new InternetAddress(address);
|
||||||
}
|
}
|
||||||
return toAddress;
|
return toAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String setContent(JSONObject jsonObject, String templatePath) {
|
public String setContent(JSONObject jsonObject, String templatePath) {
|
||||||
Context context = new Context();
|
Context context = new Context();
|
||||||
if (Objects.nonNull(jsonObject)) {
|
if (Objects.nonNull(jsonObject)) {
|
||||||
for (String key : jsonObject.keySet()) {
|
for (String key : jsonObject.keySet()) {
|
||||||
context.setVariable(key, jsonObject.get(key));
|
context.setVariable(key, jsonObject.get(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return templateEngine.process(templatePath, context);
|
return templateEngine.process(templatePath, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import io.netty.util.internal.StringUtil;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@@ -41,6 +42,9 @@ public class MinioUtil {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private MinioClient minioClient;
|
private MinioClient minioClient;
|
||||||
|
|
||||||
|
@Value("${minio.endpoint}")
|
||||||
|
private String endpoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取MinIO客户端实例
|
* 获取MinIO客户端实例
|
||||||
*/
|
*/
|
||||||
@@ -48,6 +52,18 @@ public class MinioUtil {
|
|||||||
return minioClient;
|
return minioClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis缓存key前缀,用于Minio签名URL缓存
|
||||||
|
*/
|
||||||
|
private static final String REDIS_MINIO_URL_PREFIX = "minio:url:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名URL缓存过期时间(秒),默认1天
|
||||||
|
*/
|
||||||
|
private static final long URL_CACHE_EXPIRE_SECONDS = 24 * 60 * 60;
|
||||||
/**
|
/**
|
||||||
* description: 判断bucket是否存在,不存在则创建
|
* description: 判断bucket是否存在,不存在则创建
|
||||||
*
|
*
|
||||||
@@ -388,6 +404,11 @@ public class MinioUtil {
|
|||||||
* @return 文件的临时URL,如果出现异常则返回null
|
* @return 文件的临时URL,如果出现异常则返回null
|
||||||
*/
|
*/
|
||||||
public String getPreSignedUrl(String bucketName, String fileName, int expiry) {
|
public String getPreSignedUrl(String bucketName, String fileName, int expiry) {
|
||||||
|
String cacheKey = REDIS_MINIO_URL_PREFIX + bucketName + "/" + fileName;
|
||||||
|
Object cachedUrl = redisUtil.getFromString(cacheKey);
|
||||||
|
if (cachedUrl != null) {
|
||||||
|
return cachedUrl.toString();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String lowerName = fileName.toLowerCase();
|
String lowerName = fileName.toLowerCase();
|
||||||
@@ -415,8 +436,9 @@ public class MinioUtil {
|
|||||||
|
|
||||||
builder.extraQueryParams(queryParams);
|
builder.extraQueryParams(queryParams);
|
||||||
}
|
}
|
||||||
|
String presignedObjectUrl = minioClient.getPresignedObjectUrl(builder.build());
|
||||||
return minioClient.getPresignedObjectUrl(builder.build());
|
redisUtil.addToString(cacheKey, presignedObjectUrl, URL_CACHE_EXPIRE_SECONDS);
|
||||||
|
return presignedObjectUrl;
|
||||||
} catch (MinioException | InvalidKeyException
|
} catch (MinioException | InvalidKeyException
|
||||||
| IOException | NoSuchAlgorithmException | IllegalArgumentException e) {
|
| IOException | NoSuchAlgorithmException | IllegalArgumentException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -958,6 +980,166 @@ public class MinioUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测字符串是否为预签名URL
|
||||||
|
* 通过检查URL中是否包含minio endpoint来判断
|
||||||
|
*
|
||||||
|
* @param str 待检测的字符串
|
||||||
|
* @return true表示是预签名URL,false表示不是
|
||||||
|
*/
|
||||||
|
public boolean isPresignedUrl(String str) {
|
||||||
|
if (str == null || str.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 检查字符串是否是一个有效的URL
|
||||||
|
URL url = new URL(str);
|
||||||
|
String host = url.getHost();
|
||||||
|
// 获取endpoint中的主机部分(去掉http://或https://)
|
||||||
|
String endpointHost = endpoint;
|
||||||
|
if (endpointHost.startsWith("http://")) {
|
||||||
|
endpointHost = endpointHost.substring(7);
|
||||||
|
} else if (endpointHost.startsWith("https://")) {
|
||||||
|
endpointHost = endpointHost.substring(8);
|
||||||
|
}
|
||||||
|
// 去掉端口号
|
||||||
|
if (endpointHost.contains(":")) {
|
||||||
|
endpointHost = endpointHost.substring(0, endpointHost.indexOf(":"));
|
||||||
|
}
|
||||||
|
// 检查URL的host是否与endpoint的host匹配
|
||||||
|
return host.equals(endpointHost);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 不是有效的URL
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测字符串是否为MinIO逻辑路径(bucketName/objectName格式)
|
||||||
|
* 逻辑路径特点:
|
||||||
|
* 1. 包含 "/"(桶名和对象名之间的分隔符)
|
||||||
|
* 2. 不是完整的URL(不以http://或https://开头)
|
||||||
|
* 3. 路径中没有查询参数
|
||||||
|
*
|
||||||
|
* @param str 待检测的字符串
|
||||||
|
* @return true表示是MinIO逻辑路径,false表示不是
|
||||||
|
*/
|
||||||
|
public boolean isMinioLogicalPath(String str) {
|
||||||
|
if (str == null || str.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 必须是字符串
|
||||||
|
if (!(str instanceof String)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String trimStr = str.trim();
|
||||||
|
// 不应该以http://或https://开头
|
||||||
|
if (trimStr.startsWith("http://") || trimStr.startsWith("https://")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 应该包含 "/"(bucket/object格式)
|
||||||
|
if (!trimStr.contains("/")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 不应该包含空格或特殊字符
|
||||||
|
if (trimStr.contains(" ") || trimStr.contains("\n") || trimStr.contains("\t")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将预签名URL转换为逻辑路径
|
||||||
|
*
|
||||||
|
* @param presignedUrl 预签名URL
|
||||||
|
* @return 逻辑路径(格式:bucketName/objectName)
|
||||||
|
*/
|
||||||
|
public String getLogicalPathFromPresignedUrl(String presignedUrl) {
|
||||||
|
try {
|
||||||
|
// 解析URL
|
||||||
|
URL url = new URL(presignedUrl);
|
||||||
|
|
||||||
|
// 获取路径部分(去掉开头的/)
|
||||||
|
String path = url.getPath();
|
||||||
|
if (path.startsWith("/")) {
|
||||||
|
path = path.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路径格式为 bucketName/objectName
|
||||||
|
// Minio路径中可能包含多个/,需要正确分割
|
||||||
|
int firstSlashIndex = path.indexOf("/");
|
||||||
|
if (firstSlashIndex <= 0) {
|
||||||
|
throw new MinioException("预签名URL路径格式无效,应包含桶名和对象名: " + presignedUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
String bucketName = path.substring(0, firstSlashIndex);
|
||||||
|
String objectName = path.substring(firstSlashIndex + 1);
|
||||||
|
|
||||||
|
// log.info("预签名URL转换成功,桶名: {}, 对象名: {}", bucketName, objectName);
|
||||||
|
return bucketName + "/" + objectName;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("预签名URL解析失败: {}", e.getMessage(), e);
|
||||||
|
throw new BusinessException("system.error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理MinIO资源(预签名URL或逻辑路径),统一生成预签名URL
|
||||||
|
*
|
||||||
|
* @param resource 预签名URL或逻辑路径
|
||||||
|
* @param expires 过期时间(秒)
|
||||||
|
* @return 新的预签名URL
|
||||||
|
*/
|
||||||
|
public String processMinioResource(String resource, int expires) {
|
||||||
|
try {
|
||||||
|
String logicalPath;
|
||||||
|
if (isPresignedUrl(resource)) {
|
||||||
|
// 是预签名URL,解析为逻辑路径
|
||||||
|
logicalPath = getLogicalPathFromPresignedUrl(resource);
|
||||||
|
} else if (isMinioLogicalPath(resource)) {
|
||||||
|
// 本身就是逻辑路径
|
||||||
|
logicalPath = resource.trim();
|
||||||
|
} else {
|
||||||
|
// 不认识的内容,直接返回原始值
|
||||||
|
log.warn("未识别的MinIO资源格式: {}", resource);
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一生成预签名URL
|
||||||
|
return getPreSignedUrl(logicalPath, expires);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理MinIO资源失败: {}, error: {}", resource, e.getMessage(), e);
|
||||||
|
// 如果失败,返回原始内容
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将任意MinIO URL转换为逻辑路径
|
||||||
|
* 检测URL类型并转换为逻辑路径返回
|
||||||
|
*
|
||||||
|
* @param url 预签名URL或逻辑路径
|
||||||
|
* @return 逻辑路径(格式:bucketName/objectName)
|
||||||
|
* @throws MinioException 如果不是有效的MinIO资源
|
||||||
|
*/
|
||||||
|
public String convertToLogicalPath(String url) {
|
||||||
|
if (url == null || url.isEmpty()) {
|
||||||
|
throw new BusinessException("url.cannot.be.empty");
|
||||||
|
}
|
||||||
|
if (isMinioLogicalPath(url)) {
|
||||||
|
// 本身就是逻辑路径,直接返回
|
||||||
|
return url.trim();
|
||||||
|
} else if (isPresignedUrl(url)) {
|
||||||
|
// 是预签名URL,转换为逻辑路径
|
||||||
|
return getLogicalPathFromPresignedUrl(url);
|
||||||
|
} else {
|
||||||
|
// 不认识的内容,抛出异常
|
||||||
|
throw new BusinessException("无法识别的MinIO资源格式: " + url + ",请提供有效的预签名URL或逻辑路径");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1076,4 +1076,45 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static Long SELLER_APPROVED = 184414L;
|
||||||
|
private final static Long SELLER_REJECTED = 184415L;
|
||||||
|
public static void sellerApproval(String receiver, boolean isApproved) {
|
||||||
|
try {
|
||||||
|
// 实例化一个认证对象
|
||||||
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
|
||||||
|
SendEmailRequest req = new SendEmailRequest();
|
||||||
|
req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS);
|
||||||
|
req.setDestination(new String[]{receiver});
|
||||||
|
|
||||||
|
// 根据邮件类型设置不同的主题和模板
|
||||||
|
String subject;
|
||||||
|
Template template = new Template();
|
||||||
|
if (isApproved) {
|
||||||
|
subject = "AiDA卖家权限已开通 AiDA Seller Access Enabled";
|
||||||
|
template.setTemplateID(SELLER_APPROVED);
|
||||||
|
}else {
|
||||||
|
subject = "AiDA卖家权限审批不通过 Seller Access Not Approved";
|
||||||
|
template.setTemplateID(SELLER_REJECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.setSubject(subject);
|
||||||
|
req.setTemplate(template);
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
|
SendEmailResponse resp = client.SendEmail(req);
|
||||||
|
log.info("邮件发送成功,收件人地址:{}", receiver);
|
||||||
|
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
log.info(receiver);
|
||||||
|
log.error("邮件发送失败###{},收件人地址:{}", e.toString(), receiver);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.ai.da.model.dto.GetNotificationDTO;
|
|||||||
import com.ai.da.model.vo.NotificationVO;
|
import com.ai.da.model.vo.NotificationVO;
|
||||||
import com.ai.da.model.dto.PublishSysNotificationDTO;
|
import com.ai.da.model.dto.PublishSysNotificationDTO;
|
||||||
import com.ai.da.service.MessageCenterService;
|
import com.ai.da.service.MessageCenterService;
|
||||||
|
import io.swagger.v3.oas.annotations.Hidden;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -60,4 +61,12 @@ public class MessageCenterController {
|
|||||||
messageCenterService.setReadAll(type);
|
messageCenterService.setReadAll(type);
|
||||||
return Response.success("success");
|
return Response.success("success");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Hidden
|
||||||
|
@Operation(summary = "卖家审批结果站内信通知")
|
||||||
|
@PostMapping("/sellerApprovalNotice")
|
||||||
|
public Response<String> sellerApprovalNotice(@RequestParam("userId") Long userId, @RequestParam("isApproved") boolean isApproved) {
|
||||||
|
messageCenterService.sellerApprovalNotice(userId, isApproved);
|
||||||
|
return Response.success("success");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,10 @@ public interface GatewayFeignClient {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
Response<Void> logout(@RequestParam("userId") Long userId);
|
Response<Void> logout(@RequestParam("userId") Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除用户黑名单,允许该用户重新登录(登录时会自动调用)。
|
||||||
|
*/
|
||||||
|
@PostMapping("/clear-blacklist")
|
||||||
|
Response<Void> clearBlacklist(@RequestParam("userId") Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class PythonService {
|
|||||||
@Value("${access.python.generate_sr_port}")
|
@Value("${access.python.generate_sr_port}")
|
||||||
private String srServicePort;
|
private String srServicePort;
|
||||||
|
|
||||||
@Value("${design.callback.url}")
|
@Value("${design.callback.url.aida}")
|
||||||
private String callbackUrl;
|
private String callbackUrl;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|||||||
37
src/main/java/com/ai/da/seller/DesignUrlsDTO.java
Normal file
37
src/main/java/com/ai/da/seller/DesignUrlsDTO.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package com.ai.da.seller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设计URLs DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "设计URLs数据传输对象")
|
||||||
|
public class DesignUrlsDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设计项ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "设计项ID", example = "1")
|
||||||
|
private Long designItemId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TO_PRODUCT_IMAGE类型的URL列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "TO_PRODUCT_IMAGE类型的URL列表")
|
||||||
|
private List<String> toProductImageUrls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DesignItemDetail的path列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "DesignItemDetail的path列表")
|
||||||
|
private List<String> clothes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 姿势转换视频信息列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "姿势转换视频信息列表")
|
||||||
|
private List<PoseTransformationVideoDTO> videos;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.ai.da.seller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 姿势转换视频信息DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "姿势转换视频信息数据传输对象")
|
||||||
|
public class PoseTransformationVideoDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIF第一帧截图URL
|
||||||
|
*/
|
||||||
|
@Schema(description = "GIF第一帧截图URL")
|
||||||
|
private String firstFrameUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIF视频URL
|
||||||
|
*/
|
||||||
|
@Schema(description = "GIF视频URL")
|
||||||
|
private String gifUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频URL
|
||||||
|
*/
|
||||||
|
@Schema(description = "视频URL")
|
||||||
|
private String videoUrl;
|
||||||
|
}
|
||||||
44
src/main/java/com/ai/da/seller/SellerController.java
Normal file
44
src/main/java/com/ai/da/seller/SellerController.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package com.ai.da.seller;
|
||||||
|
|
||||||
|
import com.ai.da.common.response.Response;
|
||||||
|
import com.ai.da.service.UserLikeGroupService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seller Controller
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/seller")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "Seller", description = "Seller相关接口")
|
||||||
|
public class SellerController {
|
||||||
|
|
||||||
|
private final UserLikeGroupService userLikeGroupService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据designItemId列表获取设计相关的URL列表
|
||||||
|
* @param designItemIds designItemId列表
|
||||||
|
* @return 设计URLs DTO列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/sketchDetail")
|
||||||
|
@Operation(summary = "获取设计相关URL列表", description = "根据designItemId列表获取设计相关的URL列表,包括TO_PRODUCT_IMAGE类型的URL和DesignItemDetail的path列表")
|
||||||
|
public Response<List<DesignUrlsDTO>> getDesignUrlsByDesignItemIds(
|
||||||
|
@Parameter(description = "设计项ID列表", required = true, example = "1,2,3")
|
||||||
|
@RequestParam List<Long> designItemIds) {
|
||||||
|
List<DesignUrlsDTO> designUrlsDTOList = new ArrayList<>();
|
||||||
|
for (Long designItemId : designItemIds) {
|
||||||
|
DesignUrlsDTO designUrlsDTO = userLikeGroupService.getToProductImageUrlsByDesignItemId(designItemId);
|
||||||
|
designUrlsDTOList.add(designUrlsDTO);
|
||||||
|
}
|
||||||
|
return Response.success(designUrlsDTOList);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,4 +29,6 @@ public interface MessageCenterService extends IService<Notification> {
|
|||||||
void publishSystemNotification(PublishSysNotificationDTO message);
|
void publishSystemNotification(PublishSysNotificationDTO message);
|
||||||
|
|
||||||
void videoFinishedMsg(Long userId, String projectName, boolean isSuccess);
|
void videoFinishedMsg(Long userId, String projectName, boolean isSuccess);
|
||||||
|
|
||||||
|
void sellerApprovalNotice(Long userId, boolean isApproved);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +1,132 @@
|
|||||||
package com.ai.da.service;
|
package com.ai.da.service;
|
||||||
|
|
||||||
import com.ai.da.common.response.PageBaseResponse;
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
import com.ai.da.mapper.primary.entity.*;
|
import com.ai.da.mapper.primary.entity.*;
|
||||||
import com.ai.da.model.dto.*;
|
import com.ai.da.model.dto.*;
|
||||||
import com.ai.da.model.vo.*;
|
import com.ai.da.model.vo.*;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.ai.da.seller.DesignUrlsDTO;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import io.minio.errors.MinioException;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import io.minio.errors.MinioException;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.util.List;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
/**
|
|
||||||
* 服务类
|
/**
|
||||||
*
|
* 服务类
|
||||||
* @author yanglei
|
*
|
||||||
* @since 2022-09-11
|
* @author yanglei
|
||||||
*/
|
* @since 2022-09-11
|
||||||
public interface UserLikeGroupService extends IService<UserLikeGroup> {
|
*/
|
||||||
|
public interface UserLikeGroupService extends IService<UserLikeGroup> {
|
||||||
void deleteUserGroup(Long userGroupId);
|
|
||||||
|
void deleteUserGroup(Long userGroupId);
|
||||||
HistoryUpdateVO updateUserGroupName(Long userGroupId, String userGroupName, String timeZone);
|
|
||||||
|
HistoryUpdateVO updateUserGroupName(Long userGroupId, String userGroupName, String timeZone);
|
||||||
Long insertUserGroup(Long userId, Long collectionId, String timeZone, Long projectId);
|
|
||||||
|
Long insertUserGroup(Long userId, Long collectionId, String timeZone, Long projectId);
|
||||||
/**
|
|
||||||
* choose
|
/**
|
||||||
*
|
* choose
|
||||||
* @param userGroupId
|
*
|
||||||
* @return
|
* @param userGroupId
|
||||||
*/
|
* @return
|
||||||
UserLikeChooseVO choose(Long userGroupId);
|
*/
|
||||||
|
UserLikeChooseVO choose(Long userGroupId);
|
||||||
ProjectChooseVO choose(ProjectDTO projectDTO);
|
|
||||||
|
ProjectChooseVO choose(ProjectDTO projectDTO);
|
||||||
UserLikeGroup getByProjectId(Long projectId);
|
|
||||||
|
UserLikeGroup getByProjectId(Long projectId);
|
||||||
void deleteTrialData(Long id);
|
|
||||||
|
void deleteTrialData(Long id);
|
||||||
void updateDate(Long id, String timeZone);
|
|
||||||
|
void updateDate(Long id, String timeZone);
|
||||||
Long exportSave(MultipartFile file, Long projectId, String module, Long designItemDetailId);
|
|
||||||
|
Long exportSave(MultipartFile file, Long projectId, String module, Long designItemDetailId);
|
||||||
List<ToProductImageResultVO> toProduct(ToProductImageDTO toProductImageDTO);
|
|
||||||
|
List<ToProductImageResultVO> toProduct(ToProductImageDTO toProductImageDTO);
|
||||||
void toProduct(String taskId);
|
|
||||||
|
void toProduct(String taskId);
|
||||||
ToProductElementVO toProductImageElementUpload(MultipartFile file, Long projectId, String type);
|
|
||||||
|
ToProductElementVO toProductImageElementUpload(MultipartFile file, Long projectId, String type);
|
||||||
CollectionSort productImageLike(ProductImageLikeDTO productImageLikeDTO);
|
|
||||||
|
CollectionSort productImageLike(ProductImageLikeDTO productImageLikeDTO);
|
||||||
List<MagicToolResultVO> getToProductImageResultList(List<String> taskIdList);
|
|
||||||
|
List<MagicToolResultVO> getToProductImageResultList(List<String> taskIdList);
|
||||||
JSONObject exportSearch(ExportSearchDTO exportSearchDTO);
|
|
||||||
|
JSONObject exportSearch(ExportSearchDTO exportSearchDTO);
|
||||||
CanvasElementUpload canvasElementUpload(MultipartFile file);
|
|
||||||
|
CanvasElementUpload canvasElementUpload(MultipartFile file);
|
||||||
List<ToProductImageResultVO> productImageLikeList(ToProductImageDTO toProductImageDTO);
|
|
||||||
|
List<ToProductImageResultVO> productImageLikeList(ToProductImageDTO toProductImageDTO);
|
||||||
Boolean productImageUnLike(ProductImageLikeDTO productImageLikeDTO);
|
|
||||||
|
Boolean productImageUnLike(ProductImageLikeDTO productImageLikeDTO);
|
||||||
void relight(String taskId);
|
|
||||||
|
void relight(String taskId);
|
||||||
List<ToProductImageResultVO> relight(ToProductImageDTO toProductImageDTO);
|
|
||||||
|
List<ToProductImageResultVO> relight(ToProductImageDTO toProductImageDTO);
|
||||||
List<MagicToolResultVO> getRelightResult(List<String> taskIdList);
|
|
||||||
|
List<MagicToolResultVO> getRelightResult(List<String> taskIdList);
|
||||||
void deleteToProductRelightResult(Long id, Long projectId, String type);
|
|
||||||
|
void deleteToProductRelightResult(Long id, Long projectId, String type);
|
||||||
String likeHistoryRelSketch();
|
|
||||||
|
String likeHistoryRelSketch();
|
||||||
String download();
|
|
||||||
|
String download();
|
||||||
Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO);
|
|
||||||
|
Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO);
|
||||||
InitializeProgressVO getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO);
|
|
||||||
|
InitializeProgressVO getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO);
|
||||||
IPage<ProjectVO> getPage(ProjectQueryDTO projectQueryDTO);
|
|
||||||
|
IPage<ProjectVO> getPage(ProjectQueryDTO projectQueryDTO);
|
||||||
ModuleChooseVO getModuleContent(ProjectDTO projectDTO);
|
|
||||||
|
ModuleChooseVO getModuleContent(ProjectDTO projectDTO);
|
||||||
ModuleChooseVO saveModuleContent(ModuleSaveDTO moduleSaveDTO);
|
|
||||||
|
ModuleChooseVO saveModuleContent(ModuleSaveDTO moduleSaveDTO);
|
||||||
QueryLibraryPageVO getMannequinDetail(MannequinDTO mannequinDTO);
|
|
||||||
|
QueryLibraryPageVO getMannequinDetail(MannequinDTO mannequinDTO);
|
||||||
BrandLogoUploadVO brandLogoUpload(MultipartFile file);
|
|
||||||
|
BrandLogoUploadVO brandLogoUpload(MultipartFile file);
|
||||||
Boolean brandDNASaveOrUpdate(BrandDNADTO brandDNADTO);
|
|
||||||
|
Boolean brandDNASaveOrUpdate(BrandDNADTO brandDNADTO);
|
||||||
LibraryUpdateVo brandDNAUpload(MultipartFile file, Long brandId) throws IOException;
|
|
||||||
|
LibraryUpdateVo brandDNAUpload(MultipartFile file, Long brandId) throws IOException;
|
||||||
PageBaseResponse<BrandDNAVO> brandDNAPage(BrandDNAQueryDTO brandDNAQueryDTO);
|
|
||||||
|
PageBaseResponse<BrandDNAVO> brandDNAPage(BrandDNAQueryDTO brandDNAQueryDTO);
|
||||||
BrandDNAGenerateVO brandDNAGenerate(String prompt);
|
|
||||||
|
BrandDNAGenerateVO brandDNAGenerate(String prompt);
|
||||||
IPage<ThreeDLayoutVO> getThreeDLayoutPage(ThreeDLayoutQueryDTO threeDLayoutQueryDTO);
|
|
||||||
|
IPage<ThreeDLayoutVO> getThreeDLayoutPage(ThreeDLayoutQueryDTO threeDLayoutQueryDTO);
|
||||||
ThreeDVO getLayoutDetail(Long threeDSimpleId);
|
|
||||||
|
ThreeDVO getLayoutDetail(Long threeDSimpleId);
|
||||||
ThreeDSizeVO getThreeDSize(Long threeDSimpleId);
|
|
||||||
|
ThreeDSizeVO getThreeDSize(Long threeDSimpleId);
|
||||||
void getThreeDGlb(Long threeDSimpleId, HttpServletResponse response) throws MinioException, IOException;
|
|
||||||
|
void getThreeDGlb(Long threeDSimpleId, HttpServletResponse response) throws MinioException, IOException;
|
||||||
String downloadZip(Long threeDSimpleId, String sizeType, String size, HttpServletResponse response) throws MinioException, IOException;
|
|
||||||
|
String downloadZip(Long threeDSimpleId, String sizeType, String size, HttpServletResponse response) throws MinioException, IOException;
|
||||||
Boolean delete(Long projectId);
|
|
||||||
|
Boolean delete(Long projectId);
|
||||||
Boolean brandDNADelete(BrandDNADTO brandDNADTO);
|
|
||||||
|
Boolean brandDNADelete(BrandDNADTO brandDNADTO);
|
||||||
void toProductBatch(String taskId, String url, String progress) throws InterruptedException;
|
|
||||||
|
void toProductBatch(String taskId, String url, String progress) throws InterruptedException;
|
||||||
void relightBatch(String taskId, String url, String progress);
|
|
||||||
|
void relightBatch(String taskId, String url, String progress);
|
||||||
Boolean collectionLikeUpdate(CollectionLikeUpdateDTO collectionLikeUpdateDTO);
|
|
||||||
|
Boolean collectionLikeUpdate(CollectionLikeUpdateDTO collectionLikeUpdateDTO);
|
||||||
Boolean toProductImageElementDelete(Long id);
|
|
||||||
|
Boolean toProductImageElementDelete(Long id);
|
||||||
ToProductElementVO convertRelightElement(Long id);
|
|
||||||
}
|
ToProductElementVO convertRelightElement(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据designItemId获取TO_PRODUCT_IMAGE类型的URL列表和DesignItemDetail的path列表
|
||||||
|
* @param designItemId designItemId
|
||||||
|
* @return 包含TO_PRODUCT_IMAGE类型的URL列表和DesignItemDetail的path列表的对象
|
||||||
|
*/
|
||||||
|
DesignUrlsDTO getToProductImageUrlsByDesignItemId(Long designItemId);
|
||||||
|
}
|
||||||
|
|||||||
@@ -358,12 +358,20 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
principal.setUsername(account.getUserName());
|
principal.setUsername(account.getUserName());
|
||||||
principal.setLanguage(account.getLanguage());
|
principal.setLanguage(account.getLanguage());
|
||||||
principal.setCountry(account.getCountry());
|
principal.setCountry(account.getCountry());
|
||||||
|
//区分买家端登录
|
||||||
|
principal.setSource("AIDA");
|
||||||
String token2 = tokenGenerateUtils.createToken(principal);
|
String token2 = tokenGenerateUtils.createToken(principal);
|
||||||
// 本地 JVM 缓存(适配旧逻辑)
|
// 本地 JVM 缓存(适配旧逻辑)
|
||||||
LocalCacheUtils.setTokenCache(String.valueOf(account.getId()), token2);
|
LocalCacheUtils.setTokenCache(String.valueOf(account.getId()), token2);
|
||||||
// 同步写入 Redis,重启后仍然可用
|
// 同步写入 Redis,重启后仍然可用
|
||||||
long jwtExpiration = tokenGenerateUtils.getJwtExpiration();
|
long jwtExpiration = tokenGenerateUtils.getJwtExpiration();
|
||||||
redisUtil.setLoginToken(account.getId(), token2, jwtExpiration);
|
redisUtil.setLoginToken(account.getId(), token2, jwtExpiration);
|
||||||
|
// 清除黑名单,允许用户重新登录(仅当黑名单功能开启时)
|
||||||
|
try {
|
||||||
|
gatewayFeignClient.clearBlacklist(account.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("登录时清除黑名单失败,userId={}, error={}", account.getId(), e.getMessage());
|
||||||
|
}
|
||||||
return token2;
|
return token2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1553,11 +1553,11 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
if (imagePath != null) {
|
if (imagePath != null) {
|
||||||
requestBuilder.image(finalImagePath1);
|
requestBuilder.image(finalImagePath1);
|
||||||
}
|
}
|
||||||
if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_I2I)) {
|
if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_I2I)|| useModel.equals(ModelConstants.PRINTBOARD_HIGH_T2I)) {
|
||||||
GenerateImagesRequest.OptimizePromptOptions optimizePromptOptions = new GenerateImagesRequest.OptimizePromptOptions();
|
GenerateImagesRequest.OptimizePromptOptions optimizePromptOptions = new GenerateImagesRequest.OptimizePromptOptions();
|
||||||
optimizePromptOptions.setMode("fast");
|
optimizePromptOptions.setMode("fast");
|
||||||
requestBuilder.optimizePromptOptions(optimizePromptOptions);
|
requestBuilder.optimizePromptOptions(optimizePromptOptions);
|
||||||
//由于PRINTBOARD_HIGH_I2I与PRINTBOARD_ADVANCED_I2I使用模型一致,为了区别积分扣除,PRINTBOARD_HIGH_I2I加入了-fast,但传入模型时需要去掉-fast,用PRINTBOARD_ADVANCED_I2I的常量做替代
|
//由于PRINTBOARD_HIGH_T2I,PRINTBOARD_HIGH_I2I与PRINTBOARD_ADVANCED_I2I使用模型一致,为了区别积分扣除,PRINTBOARD_HIGH_I2I加入了-fast或者-high,但传入模型时需要去掉-fast或者-high,用PRINTBOARD_ADVANCED_I2I的常量做替代
|
||||||
requestBuilder.model(ModelConstants.PRINTBOARD_ADVANCED_I2I);
|
requestBuilder.model(ModelConstants.PRINTBOARD_ADVANCED_I2I);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4225,8 +4225,11 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 发送POST请求到Flux API
|
// 发送POST请求到Flux API
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
String resp = sendRequestUtil.sendFluxPost(fluxRequestUrl, requestBody.toString());
|
String resp = sendRequestUtil.sendFluxPost(fluxRequestUrl, requestBody.toString());
|
||||||
JSONObject respObj = JSONUtil.parseObj(resp);
|
JSONObject respObj = JSONUtil.parseObj(resp);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
log.info("flux 耗时:{}ms", end - start);
|
||||||
log.info("flux 发起生成请求返回结果: {}", respObj);
|
log.info("flux 发起生成请求返回结果: {}", respObj);
|
||||||
|
|
||||||
// 从响应中提取任务ID
|
// 从响应中提取任务ID
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.ai.da.common.response.PageBaseResponse;
|
|||||||
import com.ai.da.common.utils.CopyUtil;
|
import com.ai.da.common.utils.CopyUtil;
|
||||||
import com.ai.da.common.utils.MinioUtil;
|
import com.ai.da.common.utils.MinioUtil;
|
||||||
import com.ai.da.common.utils.RedisUtil;
|
import com.ai.da.common.utils.RedisUtil;
|
||||||
|
import com.ai.da.common.utils.SendEmailUtil;
|
||||||
import com.ai.da.common.websocket.NotificationConnection;
|
import com.ai.da.common.websocket.NotificationConnection;
|
||||||
import com.ai.da.mapper.primary.*;
|
import com.ai.da.mapper.primary.*;
|
||||||
import com.ai.da.mapper.primary.entity.*;
|
import com.ai.da.mapper.primary.entity.*;
|
||||||
@@ -441,4 +442,50 @@ public class MessageCenterServiceImpl extends ServiceImpl<NotificationMapper, No
|
|||||||
pushMessage("system", userId);
|
pushMessage("system", userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static String APPROVED_MESSAGE = "尊敬的用户,您的卖家权限已开通。" +
|
||||||
|
"现在可通过\"成为卖家\"的同一入口进入卖家中心。\n在卖家中心中,您可以:" +
|
||||||
|
"\n·从设计项目中批量选择服装设计,并创建上架内容 " +
|
||||||
|
"\n·将设计及高级工具媒体转为可售卖的数字商品 " +
|
||||||
|
"\n·编辑、保存、发布并管理商品状态" +
|
||||||
|
"\n\nDear User, your seller access has been enabled. " +
|
||||||
|
"You can now enter the Seller Dashboard from the same entry point used to become a seller.\nIn the Seller Dashboard, you can:" +
|
||||||
|
"\n·Batch select apparel designs from a design project and create listings" +
|
||||||
|
"\n·Turn designs and Advanced Tools media into sellable digital items " +
|
||||||
|
"\n·Edit, save, publish, and manage item status";
|
||||||
|
|
||||||
|
private final static String REJECTED_MESSAGE = "尊敬的用户,您的卖家权限申请审批未通过。 请检查您提交的信息,并确保您的卖家资料符合平台要求。您可以更新相关信息后重新提交申请。\n\n" +
|
||||||
|
"Dear User, your seller access request was not approved. Please review the information you submitted and make sure your seller profile meets the platform requirements. You may update the relevant information and resubmit your application.";
|
||||||
|
|
||||||
|
public void sellerApprovalNotice(Long userId, boolean isApproved) {
|
||||||
|
if (userId != null && userId != 0) {
|
||||||
|
PublishSysNotificationDTO sysNotificationDTO = new PublishSysNotificationDTO();
|
||||||
|
Notification notification = new Notification();
|
||||||
|
notification.setType("system");
|
||||||
|
notification.setReceiverId(userId);
|
||||||
|
if (isApproved) {
|
||||||
|
sysNotificationDTO.setTitle("卖家权限审批通过 Seller Access Enabled");
|
||||||
|
sysNotificationDTO.setContent(APPROVED_MESSAGE);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sysNotificationDTO.setTitle("卖家权限审批不通过 Seller Access Not Approved");
|
||||||
|
sysNotificationDTO.setContent(REJECTED_MESSAGE);
|
||||||
|
|
||||||
|
}
|
||||||
|
notification.setContent(JSON.toJSONString(sysNotificationDTO));
|
||||||
|
notification.setIsRead(0);
|
||||||
|
notification.setCreateTime(LocalDateTime.now());
|
||||||
|
// 保存消息内容
|
||||||
|
save(notification);
|
||||||
|
// 推送系统消息
|
||||||
|
pushMessage("system", userId);
|
||||||
|
|
||||||
|
Account account = accountService.getById(userId);
|
||||||
|
if (account != null) {
|
||||||
|
// 发送邮件
|
||||||
|
SendEmailUtil.sellerApproval(account.getUserEmail(), isApproved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理结束时间(只能延长)
|
* 处理结束时间,不允许订阅结束时间早于当前时间和订阅开始时间
|
||||||
*/
|
*/
|
||||||
private void handlePeriodEnd(UpdateSubscriptionPlanDTO dto, SubscriptionPlan plan) {
|
private void handlePeriodEnd(UpdateSubscriptionPlanDTO dto, SubscriptionPlan plan) {
|
||||||
Long newEnd = dto.getCurrentPeriodEnd();
|
Long newEnd = dto.getCurrentPeriodEnd();
|
||||||
@@ -177,9 +177,20 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEnd < plan.getCurrentPeriodEnd()) {
|
long currentTimeSec = System.currentTimeMillis() / 1000;
|
||||||
|
long startTime = plan.getCurrentPeriodStart();
|
||||||
|
|
||||||
|
// 检查是否早于开始时间(不能等于,否则周期长度为0)
|
||||||
|
if (newEnd <= startTime) {
|
||||||
throw new BusinessException(
|
throw new BusinessException(
|
||||||
"the.subscription.end.date.can.be.extended.only.not.reduced"
|
"end.time.cannot.be.earlier.than.or.equal.to.start.time"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否早于当前时间(不能等于,否则立即过期)
|
||||||
|
if (newEnd <= currentTimeSec) {
|
||||||
|
throw new BusinessException(
|
||||||
|
"end.time.cannot.be.earlier.than.or.equal.to.the.current.time"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -547,7 +547,7 @@ public class UploadServiceImpl implements UploadService {
|
|||||||
/**
|
/**
|
||||||
* 清理过期上传任务(每小时执行一次)
|
* 清理过期上传任务(每小时执行一次)
|
||||||
*/
|
*/
|
||||||
@Scheduled(fixedDelay = 3600000) // 1小时
|
// @Scheduled(fixedDelay = 3600000) // 1小时
|
||||||
public void cleanupExpiredUploads() {
|
public void cleanupExpiredUploads() {
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
uploadTasks.entrySet().removeIf(entry -> {
|
uploadTasks.entrySet().removeIf(entry -> {
|
||||||
|
|||||||
@@ -5,28 +5,12 @@
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
server:
|
server:
|
||||||
port: 5567
|
port: 10092
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: aida-back
|
name: aida-back
|
||||||
|
|
||||||
# ---------- 副数据源(back 私有,由 Nacos 统一管理) ----------
|
|
||||||
|
|
||||||
# ---------- Token 生成参数(由 TokenGenerateUtils 使用) ----------
|
|
||||||
security:
|
|
||||||
jwtSecret: JWTSECRET
|
|
||||||
jwtTokenHeader: Authorization
|
|
||||||
jwtTokenPrefix: Bearer-
|
|
||||||
jwtExpiration: 8640000000
|
|
||||||
|
|
||||||
# ---------- Python 服务 ----------
|
|
||||||
access:
|
|
||||||
python:
|
|
||||||
ip: http://18.167.251.121
|
|
||||||
port: 9994
|
|
||||||
generate_sr_port: 9994
|
|
||||||
address: http://18.167.251.121:9994
|
|
||||||
|
|
||||||
# ---------- MinIO Buckets ----------
|
# ---------- MinIO Buckets ----------
|
||||||
minio:
|
minio:
|
||||||
@@ -65,17 +49,17 @@ redis:
|
|||||||
# ---------- RabbitMQ 队列 ----------
|
# ---------- RabbitMQ 队列 ----------
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
queues:
|
queues:
|
||||||
generate: generate-queue
|
generate: generate-queue-dev
|
||||||
sr: SR-queue
|
sr: SR-queue-dev
|
||||||
srResult: SuperResolution
|
srResult: SuperResolution-dev
|
||||||
generateResult: GenerateImage
|
generateResult: GenerateImage-dev
|
||||||
toProductImageResult: ToProductImage
|
toProductImageResult: ToProductImage-dev
|
||||||
relightResult: Relight
|
relightResult: Relight-dev
|
||||||
poseTransform: PoseTransform
|
poseTransform: PoseTransform-dev
|
||||||
designBatch: DesignBatch
|
designBatch: DesignBatch-dev
|
||||||
relightBatch: BatchRelight
|
relightBatch: BatchRelight-dev
|
||||||
toProductImageBatch: BatchToProductImage
|
toProductImageBatch: BatchToProductImage-dev
|
||||||
poseTransformBatch: BatchPoseTransform
|
poseTransformBatch: BatchPoseTransform-dev
|
||||||
emailRetry: emailRetry-business
|
emailRetry: emailRetry-business
|
||||||
exchange:
|
exchange:
|
||||||
generate: generate-exchange
|
generate: generate-exchange
|
||||||
@@ -101,10 +85,6 @@ google:
|
|||||||
redirect:
|
redirect:
|
||||||
uri: https://develop.api.aida.com.hk/api/third/party/auth/google_callback
|
uri: https://develop.api.aida.com.hk/api/third/party/auth/google_callback
|
||||||
|
|
||||||
design:
|
|
||||||
callback:
|
|
||||||
url: https://darkish-copied-sprinkler.ngrok-free.dev/api/third/party/receiveDesignResults
|
|
||||||
|
|
||||||
redirect:
|
redirect:
|
||||||
url: http://18.167.251.121:7788
|
url: http://18.167.251.121:7788
|
||||||
|
|
||||||
|
|||||||
@@ -4,18 +4,31 @@
|
|||||||
# 示例:docker run -e NACOS_NAMESPACE=prod ...
|
# 示例:docker run -e NACOS_NAMESPACE=prod ...
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
|
nacos:
|
||||||
|
namespace: dev
|
||||||
|
host: 18.167.251.121:28848
|
||||||
|
username: nacos
|
||||||
|
password: Aidlab123123!
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: aida-back
|
name: aida-back
|
||||||
config:
|
config:
|
||||||
import: optional:nacos:aida-public-${NACOS_NAMESPACE:test}.yml
|
import: optional:nacos:aida-public-${nacos.namespace}.yml
|
||||||
cloud:
|
cloud:
|
||||||
nacos:
|
nacos:
|
||||||
discovery:
|
discovery:
|
||||||
server-addr: ${NACOS_HOST:127.0.0.1:8848}
|
server-addr: ${nacos.host}
|
||||||
namespace: ${NACOS_NAMESPACE:test}
|
namespace: ${nacos.namespace}
|
||||||
|
username: ${nacos.username}
|
||||||
|
password: ${nacos.password}
|
||||||
|
# ip: 18.167.251.121
|
||||||
|
port: 10092
|
||||||
|
# ip-type: ipv4
|
||||||
|
# prefer-ip-address: true
|
||||||
config:
|
config:
|
||||||
server-addr: ${NACOS_HOST:127.0.0.1:8848}
|
server-addr: ${nacos.host}
|
||||||
namespace: ${NACOS_NAMESPACE:test}
|
namespace: ${nacos.namespace}
|
||||||
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
|
||||||
file-extension: yaml
|
file-extension: yaml
|
||||||
|
username: ${nacos.username}
|
||||||
|
password: ${nacos.password}
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ waistbandRight.cannot.be.empty=waistbandRight cannot be empty.
|
|||||||
handLeft.cannot.be.empty=handLeft cannot be empty.
|
handLeft.cannot.be.empty=handLeft cannot be empty.
|
||||||
handRight.cannot.be.empty=handRight cannot be empty.
|
handRight.cannot.be.empty=handRight cannot be empty.
|
||||||
id.cannot.be.empty=id cannot be empty.
|
id.cannot.be.empty=id cannot be empty.
|
||||||
|
url.cannot.be.empty=url cannot be empty.
|
||||||
type.cannot.be.empty=type cannot be empty.
|
type.cannot.be.empty=type cannot be empty.
|
||||||
color.cannot.be.empty=color cannot be empty.
|
color.cannot.be.empty=color cannot be empty.
|
||||||
generateDetailId.cannot.be.empty=generateDetailId cannot be empty.
|
generateDetailId.cannot.be.empty=generateDetailId cannot be empty.
|
||||||
@@ -210,6 +211,8 @@ please.specify.the.organizationId=Please specify the organizationId.
|
|||||||
switch.failed.sub-account.not.under.your.active.subscription=Switch failed. Sub-account not under your active subscription.
|
switch.failed.sub-account.not.under.your.active.subscription=Switch failed. Sub-account not under your active subscription.
|
||||||
Sub-accounts.cannot.be.admins=Sub-accounts in a subscription cannot be designated as admins.
|
Sub-accounts.cannot.be.admins=Sub-accounts in a subscription cannot be designated as admins.
|
||||||
only.subscription.plans.with.a.PENDING.status.can.have.their.start.time.modified=Only subscription plans with a PENDING status can have their start time modified.
|
only.subscription.plans.with.a.PENDING.status.can.have.their.start.time.modified=Only subscription plans with a PENDING status can have their start time modified.
|
||||||
|
end.time.cannot.be.earlier.than.or.equal.to.start.time=End time cannot be earlier than or equal to start time.
|
||||||
|
end.time.cannot.be.earlier.than.or.equal.to.the.current.time=End time cannot be earlier than or equal to the current time.
|
||||||
the.subscription.end.date.can.be.extended.only.not.reduced=The subscription end date can be extended only, not reduced.
|
the.subscription.end.date.can.be.extended.only.not.reduced=The subscription end date can be extended only, not reduced.
|
||||||
total.sub-account.quota.cannot.be.lower.than.existing.sub-accounts=Total sub-account quota cannot be lower than existing sub-accounts.
|
total.sub-account.quota.cannot.be.lower.than.existing.sub-accounts=Total sub-account quota cannot be lower than existing sub-accounts.
|
||||||
the.credit.limit.set.cannot.be.lower.than.the.amount.of.credits.already.used=The credit limit set cannot be lower than the amount of credits already used.
|
the.credit.limit.set.cannot.be.lower.than.the.amount.of.credits.already.used=The credit limit set cannot be lower than the amount of credits already used.
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ waistbandRight.cannot.be.empty=waistbandRight不能为空。
|
|||||||
handLeft.cannot.be.empty=handLeft不能为空。
|
handLeft.cannot.be.empty=handLeft不能为空。
|
||||||
handRight.cannot.be.empty=handRight不能为空。
|
handRight.cannot.be.empty=handRight不能为空。
|
||||||
id.cannot.be.empty=id不能为空。
|
id.cannot.be.empty=id不能为空。
|
||||||
|
url.cannot.be.empty=url不能为空。
|
||||||
type.cannot.be.empty=type不能为空。
|
type.cannot.be.empty=type不能为空。
|
||||||
color.cannot.be.empty=color不能为空。
|
color.cannot.be.empty=color不能为空。
|
||||||
generateDetailId.cannot.be.empty=generateDetailId不能为空。
|
generateDetailId.cannot.be.empty=generateDetailId不能为空。
|
||||||
@@ -206,6 +207,8 @@ please.specify.the.organizationId=请指定organizationId
|
|||||||
switch.failed.sub-account.not.under.your.active.subscription=切换失败,该子账号不属于您当前管理的订阅计划
|
switch.failed.sub-account.not.under.your.active.subscription=切换失败,该子账号不属于您当前管理的订阅计划
|
||||||
Sub-accounts.cannot.be.admins=在订阅中的子账号不能被指定为管理员
|
Sub-accounts.cannot.be.admins=在订阅中的子账号不能被指定为管理员
|
||||||
only.subscription.plans.with.a.PENDING.status.can.have.their.start.time.modified=只有PENDING状态的订阅计划可以修改订阅开始时间
|
only.subscription.plans.with.a.PENDING.status.can.have.their.start.time.modified=只有PENDING状态的订阅计划可以修改订阅开始时间
|
||||||
|
end.time.cannot.be.earlier.than.or.equal.to.start.time=订阅结束时间不能早于或等于开始时间
|
||||||
|
end.time.cannot.be.earlier.than.or.equal.to.the.current.time=订阅结束时间不能早于或等于当前时间
|
||||||
the.subscription.end.date.can.be.extended.only.not.reduced=订阅的到期时间不能缩短,只能延长
|
the.subscription.end.date.can.be.extended.only.not.reduced=订阅的到期时间不能缩短,只能延长
|
||||||
total.sub-account.quota.cannot.be.lower.than.existing.sub-accounts=设置的子账号总数量不能低于现存已添加的子账号数量
|
total.sub-account.quota.cannot.be.lower.than.existing.sub-accounts=设置的子账号总数量不能低于现存已添加的子账号数量
|
||||||
the.credit.limit.set.cannot.be.lower.than.the.amount.of.credits.already.used=设置的积分上限不能低于已使用的积分量
|
the.credit.limit.set.cannot.be.lower.than.the.amount.of.credits.already.used=设置的积分上限不能低于已使用的积分量
|
||||||
|
|||||||
Reference in New Issue
Block a user