Compare commits
47 Commits
fa7271567e
...
a643338916
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a643338916 | ||
|
|
9344a946ad | ||
|
|
aa0a787e3f | ||
|
|
964ee1c5cc | ||
| ac98cd01db | |||
| 70d498b90d | |||
| ae1a2eff2a | |||
| b54eaea7e3 | |||
| aa2363b9a5 | |||
| 41ef9132e9 | |||
| 3b5b57ab08 | |||
| 2ec9ef3290 | |||
| fe3fbbe135 | |||
|
|
e085275aee | ||
| 05049ae7a2 | |||
| 00c0a65547 | |||
| 77aab576de | |||
| 5b2c77f81b | |||
| 96040f2349 | |||
| 62bf538d96 | |||
| 456cb1ff19 | |||
| cbca666e7b | |||
| d622195f9d | |||
| 1917fd518d | |||
| 8f72686809 | |||
| 37ddf6f441 | |||
| dbf9b2d722 | |||
| a91f9ccdd4 | |||
| dac51afe73 | |||
| 3aa744895f | |||
| 9535d8ce59 | |||
| 6c8b316dfd | |||
| e366d5a2c5 | |||
| b6add404b3 | |||
|
|
b58b8df88f | ||
|
|
c09f734a30 | ||
| 1464689657 | |||
| 9ae1626309 | |||
| 70a41bdfbc | |||
|
|
8757db4f3d | ||
| c1a5799da7 | |||
| 94c0e81335 | |||
| b9641474ba | |||
| 059d6edc12 | |||
| 97c5be7b22 | |||
| c4da4ea111 | |||
| bbc8b025a9 |
174
.gitea/workflows/develop_build_manual.yaml
Normal file
174
.gitea/workflows/develop_build_manual.yaml
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
name: 手动 AiDA back-java 开发分支构建部署
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
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-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
|
||||||
|
|
||||||
|
- name: 2.Set up JDK 21
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
java-version: '21'
|
||||||
|
distribution: 'temurin'
|
||||||
|
|
||||||
|
- name: 3.设置JAVA Maven 环境
|
||||||
|
run: |
|
||||||
|
# 适配root/普通用户
|
||||||
|
SUDO=""
|
||||||
|
[ "$(id -u)" != "0" ] && SUDO="sudo"
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
$SUDO apt update && $SUDO apt install -y wget tar --no-install-recommends
|
||||||
|
|
||||||
|
# 下载Maven
|
||||||
|
MAVEN_VERSION="3.9.11"
|
||||||
|
MAVEN_TAR="apache-maven-${MAVEN_VERSION}-bin.tar.gz"
|
||||||
|
MAVEN_URL="https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/${MAVEN_TAR}"
|
||||||
|
wget --no-verbose -O /tmp/${MAVEN_TAR} ${MAVEN_URL}
|
||||||
|
|
||||||
|
# 解压+软链接
|
||||||
|
$SUDO tar -xzf /tmp/${MAVEN_TAR} -C /usr/local/
|
||||||
|
$SUDO ln -sf /usr/local/apache-maven-${MAVEN_VERSION} /usr/local/maven
|
||||||
|
|
||||||
|
# 配置PATH
|
||||||
|
echo "/usr/local/maven/bin" >> $GITHUB_PATH
|
||||||
|
export PATH="/usr/local/maven/bin:$PATH"
|
||||||
|
|
||||||
|
# 验证
|
||||||
|
mvn -v
|
||||||
|
|
||||||
|
- name: 4.构建jar包
|
||||||
|
run: |
|
||||||
|
echo "===== 开始构建JAR包 ====="
|
||||||
|
# 新增:打印当前构建分支(两种方式双重确认)
|
||||||
|
echo "当前工作目录分支:$(git branch --show-current)"
|
||||||
|
echo "Gitea检出分支:${{ github.ref_name }}"
|
||||||
|
echo "预期构建分支:dev/3.1_release_merge"
|
||||||
|
echo "========================"
|
||||||
|
mvn -B clean install -DskipTests -Pdev 2>&1
|
||||||
|
# 检查构建是否成功
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "JAR包构建失败!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- 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 ./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-version-aida-back
|
||||||
|
build: .
|
||||||
|
volumes:
|
||||||
|
# 数据挂载
|
||||||
|
- ./log:/log
|
||||||
|
ports:
|
||||||
|
- '10090:5567'
|
||||||
|
restart: always
|
||||||
|
EOF
|
||||||
|
# 验证docker-compose.yml生成
|
||||||
|
echo "docker-compose.yml内容:"
|
||||||
|
cat docker-compose.yml
|
||||||
|
|
||||||
|
- name: 7.安装SSH工具
|
||||||
|
run: |
|
||||||
|
$SUDO apt install -y sshpass openssh-client --no-install-recommends
|
||||||
|
# 配置SSH免密
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: 8.同步文件到远程服务器
|
||||||
|
run: |
|
||||||
|
echo "===== 同步文件到远程服务器 ====="
|
||||||
|
# 使用scp同步文件
|
||||||
|
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||||
|
./target/*.jar ./Dockerfile ./docker-compose.yml \
|
||||||
|
${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:${{ env.REMOTE_DEPLOY_PATH }} 2>&1
|
||||||
|
|
||||||
|
- name: 9.部署和运行服务
|
||||||
|
run: |
|
||||||
|
echo "===== 开始部署服务 ====="
|
||||||
|
# SSH执行部署命令
|
||||||
|
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||||
|
${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << 'EOF_SSH'
|
||||||
|
cd ${{ env.REMOTE_DEPLOY_PATH }}
|
||||||
|
echo "停止旧容器..."
|
||||||
|
docker compose down || true
|
||||||
|
echo "清理Docker资源..."
|
||||||
|
docker system prune -f
|
||||||
|
echo "构建镜像..."
|
||||||
|
docker compose build --no-cache
|
||||||
|
echo "启动服务..."
|
||||||
|
docker compose up -d
|
||||||
|
echo "验证容器状态..."
|
||||||
|
docker compose ps
|
||||||
|
echo "部署完成!"
|
||||||
|
EOF_SSH
|
||||||
|
|
||||||
|
- name: 10.发送构建结果邮件
|
||||||
|
if: always() # 无论上一步是否失败,都执行此步骤
|
||||||
|
uses: dawidd6/action-send-mail@v3
|
||||||
|
with:
|
||||||
|
|
||||||
|
from: ${{ secrets.MAIL_USERNAME }}
|
||||||
|
# --- 邮件配置 ---
|
||||||
|
server_address: smtp.gmail.com # 替换为你的SMTP服务器地址
|
||||||
|
server_port: 465 # 替换为你的SMTP端口 (通常是465或587)
|
||||||
|
username: ${{ secrets.MAIL_USERNAME }} # 存储在Secrets中的邮箱用户名
|
||||||
|
password: ${{ secrets.MAIL_PASSWORD }} # 存储在Secrets中的邮箱密码
|
||||||
|
subject: 'Gitea Actions 构建通知: ${{ job.status }} - AiDA back-java Develop'
|
||||||
|
# 收件人列表,可以根据需要更改
|
||||||
|
to: 'xupei3360@163.com,txli@aidlab.hk,cgzhou@aidlab.hk,zchengrong@yeah.net' # 替换为实际收件人邮箱
|
||||||
|
|
||||||
|
# --- 邮件正文内容 ---
|
||||||
|
body: |
|
||||||
|
项目: AiDA back-java Develop
|
||||||
|
分支: dev/3.1_release_merge
|
||||||
|
|
||||||
|
🎉 构建结果: ${{ job.status }}
|
||||||
|
|
||||||
|
📅 构建时间: ${{ steps.build_start_time.outputs.current_time }}
|
||||||
|
|
||||||
|
🔗 构建链接: ${{ gitea.server_url }}/${{ gitea.repository.owner.name }}/${{ gitea.repository.name }}/actions/runs/${{ gitea.run_id }}
|
||||||
|
|
||||||
|
# 确保邮件内容为纯文本,或者你可以设置为 html: true 并调整 body
|
||||||
|
content_type: text/plain
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
FROM openjdk:8
|
|
||||||
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"]
|
|
||||||
7
pom.xml
7
pom.xml
@@ -135,9 +135,14 @@
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.xiaoymin</groupId>
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
|
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||||
<version>4.4.0</version>
|
<version>4.4.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
|
</dependency>
|
||||||
<!-- Swagger 2 annotations for backward compatibility -->
|
<!-- Swagger 2 annotations for backward compatibility -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.swagger</groupId>
|
<groupId>io.swagger</groupId>
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ public class MyTaskScheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Scheduled(cron = "0 0 9 * * ?")
|
// @Scheduled(cron = "0 0 9 * * ?")
|
||||||
public void sendTrialOrderExcelToManagements() {
|
public void sendTrialOrderExcelToManagements() {
|
||||||
// 获取前一天日期
|
// 获取前一天日期
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.ai.da.common.constant;
|
||||||
|
|
||||||
|
public class AffiliateConstants {
|
||||||
|
public static final String STATUS_ACTIVE = "Active";
|
||||||
|
public static final String STATUS_INACTIVE = "Inactive";
|
||||||
|
public static final String STATUS_DELETE = "Delete";
|
||||||
|
public static final Integer DELETED = 1;
|
||||||
|
public static final Integer NOT_DELETED = 0;
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
@@ -17,6 +18,7 @@ import org.springframework.security.web.SecurityFilterChain;
|
|||||||
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
|
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
@@ -57,8 +59,17 @@ public class SecurityConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
|
||||||
httpSecurity
|
httpSecurity
|
||||||
.cors(AbstractHttpConfigurer::disable)
|
.cors(Customizer.withDefaults())
|
||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
|
.requestMatchers(
|
||||||
|
new AntPathRequestMatcher("/doc.html"),
|
||||||
|
new AntPathRequestMatcher("/swagger-ui.html"),
|
||||||
|
new AntPathRequestMatcher("/swagger-ui/**"),
|
||||||
|
new AntPathRequestMatcher("/swagger-resources/**"),
|
||||||
|
new AntPathRequestMatcher("/v2/api-docs"),
|
||||||
|
new AntPathRequestMatcher("/v3/api-docs/**"),
|
||||||
|
new AntPathRequestMatcher("/webjars/**")
|
||||||
|
).permitAll()
|
||||||
.requestMatchers(securityProperties.getIgnorePaths()).permitAll()
|
.requestMatchers(securityProperties.getIgnorePaths()).permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
)
|
)
|
||||||
@@ -75,7 +86,6 @@ public class SecurityConfig {
|
|||||||
.successHandler(userLoginSuccessHandler)
|
.successHandler(userLoginSuccessHandler)
|
||||||
.failureHandler(userLoginFailureHandler)
|
.failureHandler(userLoginFailureHandler)
|
||||||
)
|
)
|
||||||
.cors(AbstractHttpConfigurer::disable)
|
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
.sessionManagement(session -> session
|
.sessionManagement(session -> session
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
|
|||||||
@@ -42,8 +42,11 @@ public class AuthenticationFilter extends OncePerRequestFilter {
|
|||||||
private SecurityProperties properties;
|
private SecurityProperties properties;
|
||||||
|
|
||||||
private static final List<String> FILTER_URL =
|
private static final List<String> FILTER_URL =
|
||||||
Arrays.asList("/favicon.ico", "/doc.html", "/api/account/login", "/api/account/preLogin", "api/account/sendEmail","api/account/noLoginRequired",
|
Arrays.asList("/favicon.ico", "/doc.html", "/swagger-ui.html",
|
||||||
"/webjars/", "/swagger-resources", "/v2/api-docs", "/api/account/resetPwd",
|
"/swagger-resources", "/swagger-resources/", "/swagger-resources/configuration/ui", "/swagger-resources/configuration/security",
|
||||||
|
"/webjars/", "/v2/api-docs", "/v3/api-docs", "/v3/api-docs/swagger-config",
|
||||||
|
"/api/account/login", "/api/account/preLogin", "api/account/sendEmail","api/account/noLoginRequired",
|
||||||
|
"/api/account/resetPwd",
|
||||||
"/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId",
|
"/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId",
|
||||||
"/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile",
|
"/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile",
|
||||||
"/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew","/api/third/party/updateNoLoginRequiredNew",
|
"/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew","/api/third/party/updateNoLoginRequiredNew",
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class AccountTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 每天凌晨0点执行一次
|
// 每天凌晨0点执行一次
|
||||||
// @Scheduled(cron = "0 0 0 * * ?")
|
@Scheduled(cron = "0 0 0 * * ?")
|
||||||
public void cancelActivityBenefits() {
|
public void cancelActivityBenefits() {
|
||||||
// 1、查询当前所有参与了活动且过期的用户
|
// 1、查询当前所有参与了活动且过期的用户
|
||||||
List<Account> accountList = accountService.getExpiredUserBySystemUser(4);
|
List<Account> accountList = accountService.getExpiredUserBySystemUser(4);
|
||||||
|
|||||||
@@ -100,9 +100,9 @@ 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(){
|
||||||
log.info("=====万相补偿获取结果开始=====");
|
|
||||||
List<APIGenerate> apiGenerates = apiGenerateService.getPendingTaskByStatus("wx");
|
List<APIGenerate> apiGenerates = apiGenerateService.getPendingTaskByStatus("wx");
|
||||||
if (apiGenerates != null && !apiGenerates.isEmpty()){
|
if (apiGenerates != null && !apiGenerates.isEmpty()){
|
||||||
|
log.info("=====万相补偿获取结果开始=====");
|
||||||
for (APIGenerate apiGenerate : apiGenerates){
|
for (APIGenerate apiGenerate : apiGenerates){
|
||||||
String taskId = apiGenerate.getTaskId();
|
String taskId = apiGenerate.getTaskId();
|
||||||
PoseTransformation poseTransformation = poseTransformationMapper.selectOne(new QueryWrapper<PoseTransformation>().eq("unique_id", taskId));
|
PoseTransformation poseTransformation = poseTransformationMapper.selectOne(new QueryWrapper<PoseTransformation>().eq("unique_id", taskId));
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class PaymentTask {
|
|||||||
@Resource
|
@Resource
|
||||||
private PayPalCheckoutService payPalCheckoutService;
|
private PayPalCheckoutService payPalCheckoutService;
|
||||||
|
|
||||||
@Scheduled(cron = "0/30 * * * * ?")
|
// @Scheduled(cron = "0/30 * * * * ?")
|
||||||
public void orderConfirmForPaypal() throws SerializeException {
|
public void orderConfirmForPaypal() throws SerializeException {
|
||||||
|
|
||||||
// log.info("PayPal orderConfirm 被执行......");
|
// log.info("PayPal orderConfirm 被执行......");
|
||||||
@@ -104,7 +104,7 @@ public class PaymentTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 定时同步(每分钟一次)
|
// 定时同步(每分钟一次)
|
||||||
// @Scheduled(fixedRate = 60000)
|
@Scheduled(fixedRate = 60000)
|
||||||
public void syncLinkViewCountToDB(){
|
public void syncLinkViewCountToDB(){
|
||||||
affiliateService.syncLinkViewCountToDB();
|
affiliateService.syncLinkViewCountToDB();
|
||||||
}
|
}
|
||||||
@@ -120,9 +120,9 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.ai.da.mapper.primary.entity.Account;
|
|||||||
import com.ai.da.mapper.primary.entity.SubscriptionInfo;
|
import com.ai.da.mapper.primary.entity.SubscriptionInfo;
|
||||||
import com.ai.da.service.StripeService;
|
import com.ai.da.service.StripeService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import io.netty.util.internal.StringUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@@ -45,6 +46,11 @@ public class SubscriptionReminderTask {
|
|||||||
log.warn("未知的订阅类型: {}", subscriptionInfo.getType());
|
log.warn("未知的订阅类型: {}", subscriptionInfo.getType());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
String emailType = subscriptionInfo.getStatus().equals("active") ? "reminder_subscriber" : subscriptionInfo.getStatus().equals("canceled") ? "reminder_expire" : null;
|
||||||
|
if (StringUtil.isNullOrEmpty(emailType)) {
|
||||||
|
log.warn("未知订阅状态:{}", subscriptionInfo.getStatus());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
boolean success = stripeService.sendEmail(subscriptionInfo.getSubscriptionId(), "reminder_subscriber", null);
|
boolean success = stripeService.sendEmail(subscriptionInfo.getSubscriptionId(), "reminder_subscriber", null);
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -78,7 +84,7 @@ public class SubscriptionReminderTask {
|
|||||||
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
|
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
|
||||||
qw.ge("current_period_end", startTimestamp);
|
qw.ge("current_period_end", startTimestamp);
|
||||||
qw.lt("current_period_end", endTimestamp);
|
qw.lt("current_period_end", endTimestamp);
|
||||||
qw.eq("status", "active");
|
// qw.eq("status", "active");
|
||||||
qw.eq("subscription_type", subscriptionType);
|
qw.eq("subscription_type", subscriptionType);
|
||||||
|
|
||||||
return subscriptionInfoMapper.selectList(qw);
|
return subscriptionInfoMapper.selectList(qw);
|
||||||
|
|||||||
@@ -840,6 +840,18 @@ public class SendEmailUtil {
|
|||||||
templateUser.setTemplateID(156074L);
|
templateUser.setTemplateID(156074L);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "reminder_expire":
|
||||||
|
if (language.equals("ENGLISH")) {
|
||||||
|
user.setSubject("[Code-Create] AiDA account is about to expire");
|
||||||
|
templateUser.setTemplateID(156749L);
|
||||||
|
} else if (language.equals("CHINESE")){
|
||||||
|
user.setSubject("[Code-Create] 您的AiDA账号即将到期");
|
||||||
|
templateUser.setTemplateID(156750L);
|
||||||
|
} else {
|
||||||
|
user.setSubject("[Code-Create] 您的AiDA帳號即將到期");
|
||||||
|
templateUser.setTemplateID(156751L);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "reminder_trial":
|
case "reminder_trial":
|
||||||
if (language.equals("ENGLISH")) {
|
if (language.equals("ENGLISH")) {
|
||||||
user.setSubject("[Code-Create] AiDA — Free Trial Ending");
|
user.setSubject("[Code-Create] AiDA — Free Trial Ending");
|
||||||
|
|||||||
@@ -292,8 +292,8 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
setEduAdminToExpire(account);
|
setEduAdminToExpire(account);
|
||||||
} else {
|
} else {
|
||||||
toVisitor(account);
|
toVisitor(account);
|
||||||
return;
|
// return;
|
||||||
// throw new BusinessException("user.expired");
|
throw new BusinessException("account.expired", ResultEnum.PROMPT.getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2479,8 +2479,15 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
if (Objects.nonNull(subAccount) && personAccRole.contains(subAccount.getSystemUser())) {
|
if (Objects.nonNull(subAccount) && personAccRole.contains(subAccount.getSystemUser())) {
|
||||||
log.info("将用户{} 加入组织{}", addSubAccountDTO.getUserEmail(), adminAcc.getOrganizationName());
|
log.info("将用户{} 加入组织{}", addSubAccountDTO.getUserEmail(), adminAcc.getOrganizationName());
|
||||||
subAccount.setUserName(addSubAccountDTO.getUserName());
|
subAccount.setUserName(addSubAccountDTO.getUserName());
|
||||||
if (!StringUtil.isNullOrEmpty(addSubAccountDTO.getUserPassword()))
|
if (!StringUtil.isNullOrEmpty(addSubAccountDTO.getUserPassword())){
|
||||||
subAccount.setUserPassword(addSubAccountDTO.getUserPassword());
|
subAccount.setUserPassword(addSubAccountDTO.getUserPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断当前账号的有效期是否与管理员同步
|
||||||
|
if (subAccount.getValidEndTime() < adminAcc.getValidEndTime()){
|
||||||
|
subAccount.setValidEndTime(adminAcc.getValidEndTime());
|
||||||
|
}
|
||||||
|
|
||||||
subAccount.setSystemUser(subUserRole);
|
subAccount.setSystemUser(subUserRole);
|
||||||
subAccount.setOrganizationName(adminAcc.getOrganizationName());
|
subAccount.setOrganizationName(adminAcc.getOrganizationName());
|
||||||
subAccount.setParentId(adminAcc.getId());
|
subAccount.setParentId(adminAcc.getId());
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.ai.da.service.impl;
|
package com.ai.da.service.impl;
|
||||||
|
|
||||||
import com.ai.da.common.config.exception.BusinessException;
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
|
import com.ai.da.common.constant.AffiliateConstants;
|
||||||
import com.ai.da.common.constant.CommonConstant;
|
import com.ai.da.common.constant.CommonConstant;
|
||||||
import com.ai.da.common.context.UserContext;
|
import com.ai.da.common.context.UserContext;
|
||||||
import com.ai.da.common.response.PageBaseResponse;
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
@@ -200,29 +201,70 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void editAffiliate(Long id, Float commission, String operationType) {
|
public void editAffiliate(Long id, Float commission, String operationType) {
|
||||||
Affiliate affiliate = baseMapper.selectById(id);
|
// 参数验证
|
||||||
if (Objects.isNull(affiliate)){
|
if (id == null) {
|
||||||
log.info("未知affiliate id :{}", id);
|
throw new BusinessException("affiliate.id.cannot.be.null");
|
||||||
throw new BusinessException("unknown affiliate");
|
|
||||||
}
|
|
||||||
if (!Objects.equals(affiliate.getCommissionPercent(), commission)){
|
|
||||||
affiliate.setCommissionPercent(commission);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// operationType Active -> 激活 | Inactive -> 关闭 | Delete -> 删除
|
Affiliate affiliate = baseMapper.selectById(id);
|
||||||
|
if (affiliate == null) {
|
||||||
|
log.warn("未知affiliate id: {}", id); // 使用warn级别更合适
|
||||||
|
throw new BusinessException("unknown.affiliate");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建更新条件
|
||||||
|
UpdateWrapper<Affiliate> updateWrapper = buildUpdateWrapper(affiliate, commission, operationType);
|
||||||
|
baseMapper.update(null, updateWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UpdateWrapper<Affiliate> buildUpdateWrapper(Affiliate affiliate, Float commission, String operationType) {
|
||||||
|
UpdateWrapper<Affiliate> updateWrapper = new UpdateWrapper<>();
|
||||||
|
updateWrapper.lambda()
|
||||||
|
.eq(Affiliate::getId, affiliate.getId())
|
||||||
|
.set(Affiliate::getUpdateTime, LocalDateTime.now());
|
||||||
|
|
||||||
|
// 处理佣金更新
|
||||||
|
handleCommissionUpdate(affiliate, commission, updateWrapper);
|
||||||
|
|
||||||
|
// 处理操作类型
|
||||||
if (!StringUtil.isNullOrEmpty(operationType)) {
|
if (!StringUtil.isNullOrEmpty(operationType)) {
|
||||||
if (operationType.equals("Delete")) {
|
handleOperationType(affiliate, operationType, updateWrapper);
|
||||||
baseMapper.deleteById(id);
|
}
|
||||||
return;
|
|
||||||
} else if (operationType.equals("Active") || operationType.equals("Inactive")) {
|
return updateWrapper;
|
||||||
affiliate.setStatus(operationType);
|
}
|
||||||
} else {
|
|
||||||
|
private void handleCommissionUpdate(Affiliate affiliate, Float commission,
|
||||||
|
UpdateWrapper<Affiliate> updateWrapper) {
|
||||||
|
if (commission != null && !Objects.equals(affiliate.getCommissionPercent(), commission)) {
|
||||||
|
updateWrapper.lambda().set(Affiliate::getCommissionPercent, commission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleOperationType(Affiliate affiliate, String operationType,
|
||||||
|
UpdateWrapper<Affiliate> updateWrapper) {
|
||||||
|
switch (operationType) {
|
||||||
|
case AffiliateConstants.STATUS_DELETE:
|
||||||
|
updateWrapper.lambda()
|
||||||
|
.set(Affiliate::getStatus, AffiliateConstants.STATUS_DELETE)
|
||||||
|
.set(Affiliate::getIsDeleted, AffiliateConstants.DELETED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AffiliateConstants.STATUS_ACTIVE:
|
||||||
|
case AffiliateConstants.STATUS_INACTIVE:
|
||||||
|
updateWrapper.lambda().set(Affiliate::getStatus, operationType);
|
||||||
|
// 激活时生成链接
|
||||||
|
if (AffiliateConstants.STATUS_ACTIVE.equals(operationType) &&
|
||||||
|
StringUtil.isNullOrEmpty(affiliate.getLink())) {
|
||||||
|
updateWrapper.lambda().set(Affiliate::getLink,
|
||||||
|
CommonConstant.AFFILIATE_LINK + affiliate.getId());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
throw new BusinessException("unknown.operationType");
|
throw new BusinessException("unknown.operationType");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
affiliate.setUpdateTime(LocalDateTime.now());
|
|
||||||
baseMapper.updateById(affiliate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定时计算佣金
|
// 定时计算佣金
|
||||||
public void updateAffiliateInfoWithPayment(){
|
public void updateAffiliateInfoWithPayment(){
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementMapper, CollectionElement> implements CollectionElementService {
|
public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementMapper, CollectionElement> implements CollectionElementService {
|
||||||
private final CollectionElementMapper collectionElementMapper;
|
private final CollectionElementMapper collectionElementMapper;
|
||||||
private final EmailService emailService;
|
// private final EmailService emailService;
|
||||||
private final FileProperties fileProperties;
|
private final FileProperties fileProperties;
|
||||||
private final GenerateMapper generateMapper;
|
private final GenerateMapper generateMapper;
|
||||||
private final GenerateDetailMapper generateDetailMapper;
|
private final GenerateDetailMapper generateDetailMapper;
|
||||||
|
|||||||
@@ -402,21 +402,27 @@ public class MessageCenterServiceImpl extends ServiceImpl<NotificationMapper, No
|
|||||||
notification.setType("system");
|
notification.setType("system");
|
||||||
notification.setReceiverId(userId);
|
notification.setReceiverId(userId);
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
if (language.equals(Language.ENGLISH.name())) {
|
sysNotificationDTO.setTitle("System Notification 系统通知");
|
||||||
|
sysNotificationDTO.setContent("Your video generation task in Project " + projectName + " is ready!\n"
|
||||||
|
+ "您在项目 " + projectName + " 中创建的视频生成任务已完成!");
|
||||||
|
/*if (language.equals(Language.ENGLISH.name())) {
|
||||||
sysNotificationDTO.setTitle("System Notification");
|
sysNotificationDTO.setTitle("System Notification");
|
||||||
sysNotificationDTO.setContent("Your video generation task in Project " + projectName + " is ready!");
|
sysNotificationDTO.setContent("Your video generation task in Project " + projectName + " is ready!");
|
||||||
} else {
|
} else {
|
||||||
sysNotificationDTO.setTitle("系统通知");
|
sysNotificationDTO.setTitle("系统通知");
|
||||||
sysNotificationDTO.setContent("您在项目 " + projectName + " 中创建的视频生成任务已完成!");
|
sysNotificationDTO.setContent("您在项目 " + projectName + " 中创建的视频生成任务已完成!");
|
||||||
}
|
}*/
|
||||||
} else {
|
} else {
|
||||||
if (language.equals(Language.ENGLISH.name())) {
|
sysNotificationDTO.setTitle("System Notification 系统通知");
|
||||||
|
sysNotificationDTO.setContent("Your video generation task in Project " + projectName + " has failed.\n"
|
||||||
|
+ "您在项目 " + projectName + " 中创建的视频生成任务失败。");
|
||||||
|
/*if (language.equals(Language.ENGLISH.name())) {
|
||||||
sysNotificationDTO.setTitle("System Notification");
|
sysNotificationDTO.setTitle("System Notification");
|
||||||
sysNotificationDTO.setContent("Your video generation task in Project " + projectName + " has failed.");
|
sysNotificationDTO.setContent("Your video generation task in Project " + projectName + " has failed.");
|
||||||
} else {
|
} else {
|
||||||
sysNotificationDTO.setTitle("系统通知");
|
sysNotificationDTO.setTitle("系统通知");
|
||||||
sysNotificationDTO.setContent("视频生成任务失败。");
|
sysNotificationDTO.setContent("视频生成任务失败。");
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
notification.setContent(JSON.toJSONString(sysNotificationDTO));
|
notification.setContent(JSON.toJSONString(sysNotificationDTO));
|
||||||
notification.setIsRead(0);
|
notification.setIsRead(0);
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
String orderId = orderInfo.getOrderNo();
|
String orderId = orderInfo.getOrderNo();
|
||||||
|
|
||||||
|
|
||||||
|
// Alipay - Not supported when using Checkout in subscription mode or setup mode.
|
||||||
if (payType.equals("recurring")){
|
if (payType.equals("recurring")){
|
||||||
sessionBuilder.setMode(SessionCreateParams.Mode.SUBSCRIPTION);
|
sessionBuilder.setMode(SessionCreateParams.Mode.SUBSCRIPTION);
|
||||||
sessionBuilder.setSubscriptionData(SessionCreateParams.SubscriptionData.builder().setDescription("AiDA - " + orderId).build());
|
sessionBuilder.setSubscriptionData(SessionCreateParams.SubscriptionData.builder().setDescription("AiDA - " + orderId).build());
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
server.port=5567
|
server.port=5567
|
||||||
|
|
||||||
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
|
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
#spring.datasource.primary.jdbcUrl=jdbc:mysql://18.167.251.121:33008/aida?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
|
||||||
spring.datasource.primary.jdbcUrl=jdbc:mysql://18.167.251.121:33008/aida_back?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
spring.datasource.primary.jdbcUrl=jdbc:mysql://18.167.251.121:33008/aida_back?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||||
|
#spring.datasource.primary.jdbcUrl=jdbc:mysql://18.167.251.121:33008/aida_back?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||||
#spring.datasource.primary.jdbcUrl=jdbc:mysql://18.167.251.121:33008/test_aida_3.1?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
#spring.datasource.primary.jdbcUrl=jdbc:mysql://18.167.251.121:33008/test_aida_3.1?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||||
spring.datasource.primary.username=aida_con
|
spring.datasource.primary.username=aida_con
|
||||||
spring.datasource.primary.password=123456
|
spring.datasource.primary.password=123456
|
||||||
@@ -71,15 +71,15 @@ spring.rabbitmq.username=rabbit
|
|||||||
spring.rabbitmq.password=123456
|
spring.rabbitmq.password=123456
|
||||||
spring.rabbitmq.virtual-host=/
|
spring.rabbitmq.virtual-host=/
|
||||||
|
|
||||||
spring.redis.host=172.31.11.32
|
spring.data.redis.host=172.31.11.32
|
||||||
#spring.redis.host=18.167.251.121
|
#spring.data.redis.host=18.167.251.121
|
||||||
spring.redis.port=6379
|
spring.data.redis.port=6379
|
||||||
spring.redis.database=1
|
spring.data.redis.database=1
|
||||||
spring.redis.password=Aidlab
|
spring.data.redis.password=Aidlab
|
||||||
spring.redis.lettuce.pool.max-active=8
|
spring.data.redis.lettuce.pool.max-active=8
|
||||||
spring.redis.lettuce.pool.max-idle=8
|
spring.data.redis.lettuce.pool.max-idle=8
|
||||||
spring.redis.lettuce.pool.min-idle=0
|
spring.data.redis.lettuce.pool.min-idle=0
|
||||||
spring.redis.lettuce.pool.max-wait=5
|
spring.data.redis.lettuce.pool.max-wait=5
|
||||||
|
|
||||||
redis.key.orderForGenerate=OrderForGenerate
|
redis.key.orderForGenerate=OrderForGenerate
|
||||||
redis.key.generateCancelSet=GenerateCancelSet
|
redis.key.generateCancelSet=GenerateCancelSet
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
<if test="affiliateId != null">
|
<if test="affiliateId != null">
|
||||||
AND f.id = #{affiliateId}
|
AND f.id = #{affiliateId}
|
||||||
</if>
|
</if>
|
||||||
|
AND f.is_deleted = 0
|
||||||
</where>
|
</where>
|
||||||
<choose>
|
<choose>
|
||||||
<when test="sortField != null and sortField != ''">
|
<when test="sortField != null and sortField != ''">
|
||||||
@@ -83,6 +84,7 @@
|
|||||||
AND f.id = #{affiliateId}
|
AND f.id = #{affiliateId}
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
|
AND f.is_deleted = 0
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectAllAffiliateUsername" resultType="java.util.Map">
|
<select id="selectAllAffiliateUsername" resultType="java.util.Map">
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ hsv.value.cannot.exceed.the.maximum.of.8=hsv value cannot exceed the maximum of
|
|||||||
the.workspaceName.already.exists=A workspace with this name already exists.
|
the.workspaceName.already.exists=A workspace with this name already exists.
|
||||||
unable.to.delete.the.workspace.you.are.currently.using=The workspace you are currently using cannot be deleted. Please select another workspace before trying to delete.
|
unable.to.delete.the.workspace.you.are.currently.using=The workspace you are currently using cannot be deleted. Please select another workspace before trying to delete.
|
||||||
classificationName.already.exists=The label name you've entered already exists. Please enter a different label name to avoid duplication.
|
classificationName.already.exists=The label name you've entered already exists. Please enter a different label name to avoid duplication.
|
||||||
|
account.expired=Your subscription has expired, and your account has been reset to a visitor account. Please log in again from the [Individual] entry. If you have any questions, please contact us at info@code-create.com.hk
|
||||||
|
|
||||||
# Warnings:
|
# Warnings:
|
||||||
# 用来提醒用户可能会导致不良后果的操作,但不一定是错误。用户需要认真考虑是否继续当前操作。
|
# 用来提醒用户可能会导致不良后果的操作,但不一定是错误。用户需要认真考虑是否继续当前操作。
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ generate.interface.error=生成接口出现错误。(请稍后再试。如果
|
|||||||
chat-bot.interface.exception=聊天机器人接口出现错误。(请稍后再试。如果问题持续,请联系我们的help@aida.com.hk)
|
chat-bot.interface.exception=聊天机器人接口出现错误。(请稍后再试。如果问题持续,请联系我们的help@aida.com.hk)
|
||||||
compose-layer.interface.exception=图层合并时出现问题。(请稍后再试。如果问题持续,请联系我们的help@aida.com.hk)
|
compose-layer.interface.exception=图层合并时出现问题。(请稍后再试。如果问题持续,请联系我们的help@aida.com.hk)
|
||||||
cloth-classification.interface.exception=获取服装类别时出现问题。(请稍后再试。如果问题持续,请联系我们的help@aida.com.hk)
|
cloth-classification.interface.exception=获取服装类别时出现问题。(请稍后再试。如果问题持续,请联系我们的help@aida.com.hk)
|
||||||
|
account.expired=您的订阅已过期,账号已被重置为访客身份,请从【个人账号】入口重新登录。如有疑问,请联系 info@code-create.com.hk。
|
||||||
|
|
||||||
# 多语言返回
|
# 多语言返回
|
||||||
OVERALL=整体
|
OVERALL=整体
|
||||||
|
|||||||
Reference in New Issue
Block a user