From 73325667d0bba834e1404f1f98be929bf4afd5dd Mon Sep 17 00:00:00 2001
From: uname <2986773479@qq.com>
Date: Wed, 14 Jan 2026 17:28:23 +0800
Subject: [PATCH 1/3] feature: add user login and signup functions
---
backend/api-gateway/pom.xml | 50 +++++++
.../gateway/ApiGatewayApplication.java | 8 ++
.../application/UserApplicationService.java | 59 ++++++++
.../gateway/common/config/JwtConfig.java | 46 +++++++
.../gateway/common/config/SecurityConfig.java | 25 ++++
.../common/filter/UserContextFilter.java | 83 ++++++++++++
.../datamate/gateway/domain/entity/User.java | 37 +++++
.../domain/repository/UserRepository.java | 12 ++
.../gateway/domain/service/UserService.java | 126 ++++++++++++++++++
.../gateway/filter/UserContextFilter.java | 34 -----
.../infrastructure/mapper/UserMapper.java | 14 ++
.../repository/UserRepositoryImpl.java | 18 +++
.../gateway/interfaces/dto/LoginRequest.java | 16 +++
.../gateway/interfaces/dto/LoginResponse.java | 20 +++
.../interfaces/dto/RegisterRequest.java | 24 ++++
.../interfaces/rest/UserController.java | 51 +++++++
.../src/main/resources/application.yml | 16 +++
backend/pom.xml | 4 +
.../services/data-annotation-service/pom.xml | 96 -------------
.../services/data-evaluation-service/pom.xml | 87 ------------
.../services/data-synthesis-service/pom.xml | 87 ------------
.../services/execution-engine-service/pom.xml | 91 -------------
backend/services/main-application/pom.xml | 30 -----
.../pipeline-orchestration-service/pom.xml | 91 -------------
backend/services/pom.xml | 10 --
backend/services/rag-query-service/pom.xml | 63 ---------
.../exception/CommonErrorCode.java | 4 +-
deployment/docker/datamate/docker-compose.yml | 2 +
deployment/helm/datamate/values.yaml | 3 +
scripts/db/data-management-init.sql | 3 +-
scripts/images/backend/Dockerfile | 2 +-
scripts/images/gateway/Dockerfile | 2 +-
32 files changed, 620 insertions(+), 594 deletions(-)
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/application/UserApplicationService.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/common/config/JwtConfig.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/common/config/SecurityConfig.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/common/filter/UserContextFilter.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/domain/entity/User.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/domain/repository/UserRepository.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/domain/service/UserService.java
delete mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/filter/UserContextFilter.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/mapper/UserMapper.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/repository/UserRepositoryImpl.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginRequest.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginResponse.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/RegisterRequest.java
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/rest/UserController.java
delete mode 100644 backend/services/data-annotation-service/pom.xml
delete mode 100644 backend/services/data-evaluation-service/pom.xml
delete mode 100644 backend/services/data-synthesis-service/pom.xml
delete mode 100644 backend/services/execution-engine-service/pom.xml
delete mode 100644 backend/services/pipeline-orchestration-service/pom.xml
delete mode 100644 backend/services/rag-query-service/pom.xml
diff --git a/backend/api-gateway/pom.xml b/backend/api-gateway/pom.xml
index 067e6af2f..98a8066e6 100644
--- a/backend/api-gateway/pom.xml
+++ b/backend/api-gateway/pom.xml
@@ -20,13 +20,31 @@
3.5.6
2025.0.0
+ 0.11.5
+
+ com.datamate
+ domain-common
+ ${project.version}
+
+
+ spring-boot-starter-web
+ org.springframework.boot
+
+
+
org.springframework.cloud
spring-cloud-starter-gateway
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
org.springframework.boot
@@ -36,6 +54,38 @@
com.alibaba.fastjson2
fastjson2
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+
+
+ com.baomidou
+ mybatis-plus-jsqlparser
+
+
+
+ org.postgresql
+ postgresql
+
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ ${jjwt.version}
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ ${jjwt.version}
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ ${jjwt.version}
+ runtime
+
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java b/backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java
index caac81e74..722f83a0a 100644
--- a/backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java
@@ -1,10 +1,12 @@
package com.datamate.gateway;
+import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
/**
* API Gateway & Auth Service Application
@@ -12,6 +14,8 @@
* 提供路由、鉴权、限流等功能
*/
@SpringBootApplication
+@ComponentScan(basePackages = {"com.datamate"})
+@MapperScan(basePackages = {"com.datamate.**.mapper"})
public class ApiGatewayApplication {
public static void main(String[] args) {
@@ -47,6 +51,10 @@ public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
.filters(f -> f.stripPrefix(1).prefixPath("/api"))
.uri("http://deer-flow-backend:8000"))
+ // 网关服务(用户)
+ .route("gateway", r -> r.path("/api/user/**")
+ .uri("http://localhost:8080"))
+
// 其他后端服务
.route("default", r -> r.path("/api/**")
.uri("http://datamate-backend:8080"))
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/application/UserApplicationService.java b/backend/api-gateway/src/main/java/com/datamate/gateway/application/UserApplicationService.java
new file mode 100644
index 000000000..b02c18945
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/application/UserApplicationService.java
@@ -0,0 +1,59 @@
+package com.datamate.gateway.application;
+
+import com.datamate.gateway.domain.entity.User;
+import com.datamate.gateway.domain.service.UserService;
+import com.datamate.gateway.interfaces.dto.LoginRequest;
+import com.datamate.gateway.interfaces.dto.LoginResponse;
+import com.datamate.gateway.interfaces.dto.RegisterRequest;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Optional;
+
+/**
+ * UserApplicationServices
+ *
+ * @since 2026/1/14
+ */
+@Slf4j
+@Service
+@Transactional
+@RequiredArgsConstructor
+public class UserApplicationService {
+ private final UserService userService;
+
+ public Optional login(LoginRequest loginRequest) {
+ User user = new User();
+ user.setUsername(loginRequest.getUsername());
+ user.setPassword(loginRequest.getPassword());
+
+ Optional authenticatedUser = userService.authenticate(user);
+ if (authenticatedUser.isPresent()) {
+ User userEntity = authenticatedUser.get();
+ return Optional.of(convertToLoginResponse(userEntity));
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Register a new user
+ *
+ * @param registerRequest registration request
+ * @return LoginResponse with user details and token if registration successful, empty otherwise
+ */
+ public Optional register(RegisterRequest registerRequest) {
+ return userService.register(registerRequest)
+ .map(this::convertToLoginResponse);
+ }
+
+ private LoginResponse convertToLoginResponse(User user) {
+ return LoginResponse.builder()
+ .id(user.getId())
+ .username(user.getUsername())
+ .email(user.getEmail())
+ .token(user.getToken())
+ .build();
+ }
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/common/config/JwtConfig.java b/backend/api-gateway/src/main/java/com/datamate/gateway/common/config/JwtConfig.java
new file mode 100644
index 000000000..c57ecc7af
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/common/config/JwtConfig.java
@@ -0,0 +1,46 @@
+package com.datamate.gateway.common.config;
+
+import jakarta.annotation.PostConstruct;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * JwtConfig
+ *
+ * @since 2026/1/14
+ */
+@Getter
+@Setter
+@Slf4j
+@Configuration
+@ConfigurationProperties(prefix = "datamate.jwt")
+public class JwtConfig {
+ private String secret;
+
+ @PostConstruct
+ public void validate() {
+ if (secret == null || secret.trim().isEmpty()) {
+ throw new IllegalStateException(
+ """
+ JWT secret is required. Please configure datamate.jwt.secret
+ Options:
+ 1. Add to application.yml:
+ datamate:
+ jwt:
+ secret: your-strong-secret-key-here
+ 2. Set environment variable:
+ export JWT_SECRET=your-strong-secret-key-here
+ 3. Run with system property:
+ -Ddatamate.jwt.secret=your-strong-secret-key-here"""
+ );
+ }
+
+ // 额外验证
+ if (secret.length() < 32) {
+ log.warn("\n⚠️ JWT secret is only {} characters. For security, use at least 32 characters.\n", secret.length());
+ }
+ }
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/common/config/SecurityConfig.java b/backend/api-gateway/src/main/java/com/datamate/gateway/common/config/SecurityConfig.java
new file mode 100644
index 000000000..ab1bac242
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/common/config/SecurityConfig.java
@@ -0,0 +1,25 @@
+package com.datamate.gateway.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
+import org.springframework.security.config.web.server.ServerHttpSecurity;
+import org.springframework.security.web.server.SecurityWebFilterChain;
+
+/**
+ * 安全配置 - 暂时禁用所有认证
+ */
+@Configuration
+@EnableWebFluxSecurity
+public class SecurityConfig {
+
+ @Bean
+ public SecurityWebFilterChain filterChain(ServerHttpSecurity http) throws Exception {
+ http.csrf(ServerHttpSecurity.CsrfSpec::disable)
+ .authorizeExchange(exchange ->
+ exchange.pathMatchers("**").permitAll() // 允许所有请求无需认证
+ );
+
+ return http.build();
+ }
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/common/filter/UserContextFilter.java b/backend/api-gateway/src/main/java/com/datamate/gateway/common/filter/UserContextFilter.java
new file mode 100644
index 000000000..950dcb0ec
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/common/filter/UserContextFilter.java
@@ -0,0 +1,83 @@
+package com.datamate.gateway.common.filter;
+
+import com.datamate.common.infrastructure.common.Response;
+import com.datamate.common.infrastructure.exception.CommonErrorCode;
+import com.datamate.gateway.domain.service.UserService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 用户信息过滤器
+ *
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class UserContextFilter implements GlobalFilter {
+ private static final String AUTH_HEADER = "Authorization";
+
+ private static final String TOKEN_PREFIX = "Bearer ";
+
+ private final UserService userService;
+
+ @Value("${datamate.jwt.enable:false}")
+ private Boolean jwtEnable;
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ ServerHttpRequest request = exchange.getRequest();
+ String path = request.getURI().getPath();
+ if (path.equals("/api/user/login") || path.equals("/api/user/signup")) {
+ return chain.filter(exchange);
+ }
+ try {
+ if (!jwtEnable) {
+ return chain.filter(exchange);
+ }
+ // Get token from Authorization header
+ String authHeader = request.getHeaders().getFirst(AUTH_HEADER);
+ if (authHeader == null || !authHeader.startsWith(TOKEN_PREFIX)) {
+ return sendUnauthorizedResponse(exchange);
+ }
+ String token = authHeader.substring(TOKEN_PREFIX.length());
+ if (!userService.validateToken(token)) {
+ return sendUnauthorizedResponse(exchange);
+ }
+ return chain.filter(exchange);
+ } catch (Exception e) {
+ log.error("get current user info error", e);
+ return sendUnauthorizedResponse(exchange);
+ }
+ }
+
+ private Mono sendUnauthorizedResponse(ServerWebExchange exchange) {
+ ServerHttpResponse response = exchange.getResponse();
+ response.setStatusCode(HttpStatus.UNAUTHORIZED);
+ response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+ ObjectMapper objectMapper = new ObjectMapper();
+ byte[] bytes;
+ try {
+ bytes = objectMapper.writeValueAsString(Response.error(CommonErrorCode.UNAUTHORIZED)).getBytes(StandardCharsets.UTF_8);
+ } catch (JsonProcessingException e) {
+ String responseBody = "{\"code\":401,\"message\":\"登录失败:用户名或密码错误\",\"data\":null}";
+ bytes = responseBody.getBytes(StandardCharsets.UTF_8);
+ }
+ DataBuffer buffer = response.bufferFactory().wrap(bytes);
+ return response.writeWith(Mono.just(buffer));
+ }
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/domain/entity/User.java b/backend/api-gateway/src/main/java/com/datamate/gateway/domain/entity/User.java
new file mode 100644
index 000000000..cdc282a40
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/domain/entity/User.java
@@ -0,0 +1,37 @@
+package com.datamate.gateway.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户
+ *
+ * @since 2026/1/12
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "users", autoResultMap = true)
+public class User {
+ private Long id;
+ private String username;
+ private String email;
+ private String passwordHash;
+ private String fullName;
+ private String role;
+ private boolean enabled;
+ private LocalDateTime lastLoginAt;
+
+ @TableField(exist = false)
+ private String password;
+
+ @TableField(exist = false)
+ private String token;
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/domain/repository/UserRepository.java b/backend/api-gateway/src/main/java/com/datamate/gateway/domain/repository/UserRepository.java
new file mode 100644
index 000000000..0254d1fb5
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/domain/repository/UserRepository.java
@@ -0,0 +1,12 @@
+package com.datamate.gateway.domain.repository;
+
+import com.baomidou.mybatisplus.extension.repository.IRepository;
+import com.datamate.gateway.domain.entity.User;
+
+/**
+ * UserRepository
+ *
+ * @since 2026/1/12
+ */
+public interface UserRepository extends IRepository {
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/domain/service/UserService.java b/backend/api-gateway/src/main/java/com/datamate/gateway/domain/service/UserService.java
new file mode 100644
index 000000000..938dfa575
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/domain/service/UserService.java
@@ -0,0 +1,126 @@
+package com.datamate.gateway.domain.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.datamate.gateway.domain.entity.User;
+import com.datamate.gateway.domain.repository.UserRepository;
+import io.jsonwebtoken.JwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.security.Keys;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.Optional;
+
+import com.datamate.gateway.interfaces.dto.RegisterRequest;
+
+/**
+ * UserService
+ *
+ * @since 2026/1/12
+ */
+@Service
+@RequiredArgsConstructor
+public class UserService {
+ private final UserRepository userRepository;
+
+ @Value("${datamate.jwt.expiration-seconds:3600}")
+ private long expirationSeconds;
+
+ @Value("${datamate.jwt.secret}")
+ private String secret;
+
+ /**
+ * Authenticate user with username and password
+ *
+ * @param user user to authenticate
+ * @return authenticated user with token if successful, empty otherwise
+ */
+ public Optional authenticate(User user) {
+ LambdaQueryWrapper userWrapper = new LambdaQueryWrapper<>();
+ userWrapper.eq(User::getUsername, user.getUsername());
+ User userInDB = userRepository.getOne(userWrapper);
+
+ if (userInDB != null && validPassword(user, userInDB)) {
+ String token = generateToken(userInDB);
+ userInDB.setToken(token);
+ return Optional.of(userInDB);
+ }
+ return Optional.empty();
+ }
+
+ private boolean validPassword(User user, User userInDB) {
+ BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10); // cost=10
+ return encoder.matches(user.getPassword(), userInDB.getPasswordHash());
+ }
+
+ private String generateToken(User user) {
+ long now = System.currentTimeMillis();
+ return Jwts.builder()
+ .setSubject(user.getUsername())
+ .claim("uid", user.getId())
+ .claim("role", user.getRole())
+ .setIssuedAt(new Date(now))
+ .setExpiration(new Date(now + expirationSeconds * 1000))
+ .signWith(Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)), SignatureAlgorithm.HS256)
+ .compact();
+ }
+
+ public boolean validateToken(String token) {
+ try {
+ Jwts.parser().setSigningKey(secret.getBytes()).parseClaimsJws(token);
+ return true;
+ } catch (JwtException | IllegalArgumentException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * Register a new user
+ *
+ * @param registerRequest registration request containing user details
+ * @return registered user with token if successful, empty if username or email already exists
+ */
+ public Optional register(RegisterRequest registerRequest) {
+ // Check if username already exists
+ LambdaQueryWrapper usernameQuery = new LambdaQueryWrapper<>();
+ usernameQuery.eq(User::getUsername, registerRequest.getUsername());
+ if (userRepository.getOne(usernameQuery) != null) {
+ return Optional.empty();
+ }
+
+ // Check if email already exists
+ LambdaQueryWrapper emailQuery = new LambdaQueryWrapper<>();
+ emailQuery.eq(User::getEmail, registerRequest.getEmail());
+ if (userRepository.getOne(emailQuery) != null) {
+ return Optional.empty();
+ }
+
+ // Create new user
+ User user = new User();
+ user.setUsername(registerRequest.getUsername());
+ user.setEmail(registerRequest.getEmail());
+ user.setFullName(registerRequest.getUsername());
+
+ // Encode password
+ BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
+ user.setPasswordHash(encoder.encode(registerRequest.getPassword()));
+
+ // Set default role and enabled status
+ user.setRole("USER");
+ user.setEnabled(true);
+
+ // Save user
+ userRepository.save(user);
+
+ // Generate token
+ String token = generateToken(user);
+ user.setToken(token);
+
+ return Optional.of(user);
+ }
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/filter/UserContextFilter.java b/backend/api-gateway/src/main/java/com/datamate/gateway/filter/UserContextFilter.java
deleted file mode 100644
index d549a3999..000000000
--- a/backend/api-gateway/src/main/java/com/datamate/gateway/filter/UserContextFilter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.datamate.gateway.filter;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.cloud.gateway.filter.GatewayFilterChain;
-import org.springframework.cloud.gateway.filter.GlobalFilter;
-import org.springframework.stereotype.Component;
-import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Mono;
-
-/**
- * 用户信息过滤器
- *
- */
-@Slf4j
-@Component
-public class UserContextFilter implements GlobalFilter {
- @Value("${commercial.switch:false}")
- private boolean isCommercial;
-
- @Override
- public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
- if (!isCommercial) {
- return chain.filter(exchange);
- }
- try {
-
- } catch (Exception e) {
- log.error("get current user info error", e);
- return chain.filter(exchange);
- }
- return chain.filter(exchange);
- }
-}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/mapper/UserMapper.java b/backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/mapper/UserMapper.java
new file mode 100644
index 000000000..bb548c0ff
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/mapper/UserMapper.java
@@ -0,0 +1,14 @@
+package com.datamate.gateway.infrastructure.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.datamate.gateway.domain.entity.User;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * UserMapper
+ *
+ * @since 2026/1/12
+ */
+@Mapper
+public interface UserMapper extends BaseMapper {
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/repository/UserRepositoryImpl.java b/backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/repository/UserRepositoryImpl.java
new file mode 100644
index 000000000..6bd0c00fe
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/infrastructure/repository/UserRepositoryImpl.java
@@ -0,0 +1,18 @@
+package com.datamate.gateway.infrastructure.repository;
+
+import com.baomidou.mybatisplus.extension.repository.CrudRepository;
+import com.datamate.gateway.domain.entity.User;
+import com.datamate.gateway.domain.repository.UserRepository;
+import com.datamate.gateway.infrastructure.mapper.UserMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * UserRepositoryImpl
+ *
+ * @since 2026/1/12
+ */
+@Repository
+@RequiredArgsConstructor
+public class UserRepositoryImpl extends CrudRepository implements UserRepository {
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginRequest.java b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginRequest.java
new file mode 100644
index 000000000..0b26c21f5
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginRequest.java
@@ -0,0 +1,16 @@
+package com.datamate.gateway.interfaces.dto;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+/**
+ * Login Request DTO
+ */
+@Data
+public class LoginRequest {
+ @NotBlank(message = "Username cannot be empty")
+ private String username;
+
+ @NotBlank(message = "Password cannot be empty")
+ private String password;
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginResponse.java b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginResponse.java
new file mode 100644
index 000000000..7f088bd43
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/LoginResponse.java
@@ -0,0 +1,20 @@
+package com.datamate.gateway.interfaces.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Login Response DTO
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class LoginResponse {
+ private Long id;
+ private String username;
+ private String email;
+ private String token;
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/RegisterRequest.java b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/RegisterRequest.java
new file mode 100644
index 000000000..6f47e5c2a
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/dto/RegisterRequest.java
@@ -0,0 +1,24 @@
+package com.datamate.gateway.interfaces.dto;
+
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+
+/**
+ * Register Request DTO
+ */
+@Data
+public class RegisterRequest {
+ @NotBlank(message = "Username cannot be empty")
+ @Size(min = 3, max = 50, message = "Username must be between 3 and 50 characters")
+ private String username;
+
+ @NotBlank(message = "Email cannot be empty")
+ @Email(message = "Email should be valid")
+ private String email;
+
+ @NotBlank(message = "Password cannot be empty")
+ @Size(min = 6, max = 100, message = "Password must be between 6 and 100 characters")
+ private String password;
+}
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/rest/UserController.java b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/rest/UserController.java
new file mode 100644
index 000000000..b755be065
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/rest/UserController.java
@@ -0,0 +1,51 @@
+package com.datamate.gateway.interfaces.rest;
+
+import com.datamate.common.infrastructure.common.IgnoreResponseWrap;
+import com.datamate.common.infrastructure.common.Response;
+import com.datamate.common.infrastructure.exception.CommonErrorCode;
+import com.datamate.gateway.application.UserApplicationService;
+import com.datamate.gateway.interfaces.dto.LoginRequest;
+import com.datamate.gateway.interfaces.dto.LoginResponse;
+import com.datamate.gateway.interfaces.dto.RegisterRequest;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * UserController
+ *
+ * @since 2026/1/14
+ */
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/api/user")
+@RequiredArgsConstructor
+public class UserController {
+ private final UserApplicationService userApplicationService;
+
+ @PostMapping("/login")
+ @IgnoreResponseWrap
+ public ResponseEntity> login(@Valid @RequestBody LoginRequest loginRequest) {
+ return userApplicationService.login(loginRequest)
+ .map(response -> ResponseEntity.ok(Response.ok(response)))
+ .orElseGet(() -> ResponseEntity.status(HttpStatus.UNAUTHORIZED)
+ .body(Response.error(CommonErrorCode.UNAUTHORIZED)));
+ }
+
+ @PostMapping("/signup")
+ @IgnoreResponseWrap
+ public ResponseEntity> register(@Valid @RequestBody RegisterRequest registerRequest) {
+ return userApplicationService.register(registerRequest)
+ .map(response -> ResponseEntity.ok(Response.ok(response)))
+ .orElseGet(() -> ResponseEntity.status(HttpStatus.BAD_REQUEST)
+ .body(Response.error(CommonErrorCode.SIGNUP_ERROR)));
+ }
+}
diff --git a/backend/api-gateway/src/main/resources/application.yml b/backend/api-gateway/src/main/resources/application.yml
index 46908fe8d..a6603b6c9 100644
--- a/backend/api-gateway/src/main/resources/application.yml
+++ b/backend/api-gateway/src/main/resources/application.yml
@@ -17,6 +17,22 @@ spring:
secure: true
cluster-name: DEFAULT
+ datasource:
+ driver-class-name: org.postgresql.Driver
+ url: jdbc:postgresql://datamate-database:5432/datamate?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
+ username: ${DB_USERNAME:postgres}
+ password: ${DB_PASSWORD:password}
+ hikari:
+ maximum-pool-size: 20
+ minimum-idle: 5
+ connection-timeout: 30000
+ idle-timeout: 600000
+ max-lifetime: 1800000
+
+datamate:
+ jwt:
+ secret: ${JWT_SECRET}
+ expiration-seconds: 3600
# 服务器端口配置
server:
port: 8080 # 必须有这个配置
\ No newline at end of file
diff --git a/backend/pom.xml b/backend/pom.xml
index f71a3b644..b5626074a 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -42,6 +42,10 @@
+
+ ./shared/domain-common
+ ./shared/security-common
+
services
diff --git a/backend/services/data-annotation-service/pom.xml b/backend/services/data-annotation-service/pom.xml
deleted file mode 100644
index 9652adbc1..000000000
--- a/backend/services/data-annotation-service/pom.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
- 4.0.0
-
-
- com.datamate
- services
- 1.0.0-SNAPSHOT
- ../pom.xml
-
-
- data-annotation-service
- Data Annotation Service
- 数据标注服务
-
-
-
- com.datamate
- domain-common
- ${project.version}
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-websocket
-
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-ui
- 2.0.4
-
-
- org.openapitools
- jackson-databind-nullable
- 0.2.6
-
-
- jakarta.validation
- jakarta.validation-api
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
- org.openapitools
- openapi-generator-maven-plugin
- 6.6.0
-
-
-
- generate
-
-
- ${project.basedir}/../../openapi/specs/data-annotation.yaml
- spring
-
- com.datamate.annotation.interfaces.api
- com.datamate.annotation.interfaces.dto
-
- true
- true
- true
- true
- true
- java8
- true
- true
- true
- springdoc
-
-
-
-
-
-
-
-
-
diff --git a/backend/services/data-evaluation-service/pom.xml b/backend/services/data-evaluation-service/pom.xml
deleted file mode 100644
index 718afb0af..000000000
--- a/backend/services/data-evaluation-service/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
- 4.0.0
-
-
- com.datamate
- services
- 1.0.0-SNAPSHOT
- ../pom.xml
-
-
- data-evaluation-service
- Data Evaluation Service
- 数据评估服务
-
-
-
- com.datamate
- domain-common
- ${project.version}
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.cloud
- spring-cloud-starter-openfeign
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-ui
-
-
- org.openapitools
- jackson-databind-nullable
-
-
- jakarta.validation
- jakarta.validation-api
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
- org.openapitools
- openapi-generator-maven-plugin
- 6.6.0
-
-
-
- generate
-
-
- ${project.basedir}/../../openapi/specs/data-evaluation.yaml
- spring
-
- com.datamate.evaluation.interfaces.api
- com.datamate.evaluation.interfaces.dto
-
- true
- true
- true
- springdoc
-
-
-
-
-
-
-
-
-
-
diff --git a/backend/services/data-synthesis-service/pom.xml b/backend/services/data-synthesis-service/pom.xml
deleted file mode 100644
index c4e34007c..000000000
--- a/backend/services/data-synthesis-service/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
- 4.0.0
-
-
- com.datamate
- services
- 1.0.0-SNAPSHOT
- ../pom.xml
-
-
- data-synthesis-service
- Data Synthesis Service
- 数据合成服务
-
-
-
- com.datamate
- domain-common
- ${project.version}
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.cloud
- spring-cloud-starter-openfeign
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-ui
-
-
- org.openapitools
- jackson-databind-nullable
-
-
- jakarta.validation
- jakarta.validation-api
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
- org.openapitools
- openapi-generator-maven-plugin
- 6.6.0
-
-
-
- generate
-
-
- ${project.basedir}/../../openapi/specs/data-synthesis.yaml
- spring
-
- com.datamate.synthesis.interfaces.api
- com.datamate.synthesis.interfaces.dto
-
- true
- true
- true
- springdoc
-
-
-
-
-
-
-
-
-
-
diff --git a/backend/services/execution-engine-service/pom.xml b/backend/services/execution-engine-service/pom.xml
deleted file mode 100644
index aeda8d56f..000000000
--- a/backend/services/execution-engine-service/pom.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
- 4.0.0
-
-
- com.datamate
- services
- 1.0.0-SNAPSHOT
- ../pom.xml
-
-
- execution-engine-service
- Execution Engine Service
- 执行引擎服务
-
-
-
- com.datamate
- domain-common
- ${project.version}
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.cloud
- spring-cloud-starter-openfeign
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-ui
-
-
- org.openapitools
- jackson-databind-nullable
-
-
- jakarta.validation
- jakarta.validation-api
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
- org.openapitools
- openapi-generator-maven-plugin
- 6.6.0
-
-
-
- generate
-
-
- ${project.basedir}/../../openapi/specs/execution-engine.yaml
- spring
-
- com.datamate.execution.interfaces.api
- com.datamate.execution.interfaces.dto
-
- true
- true
- true
- springdoc
-
-
-
-
-
-
-
-
-
-
diff --git a/backend/services/main-application/pom.xml b/backend/services/main-application/pom.xml
index e7f871972..d49f05b04 100644
--- a/backend/services/main-application/pom.xml
+++ b/backend/services/main-application/pom.xml
@@ -66,31 +66,6 @@
data-cleaning-service
${project.version}
-
- com.datamate
- data-synthesis-service
- ${project.version}
-
-
- com.datamate
- data-annotation-service
- ${project.version}
-
-
- com.datamate
- data-evaluation-service
- ${project.version}
-
-
- com.datamate
- pipeline-orchestration-service
- ${project.version}
-
-
- com.datamate
- execution-engine-service
- ${project.version}
-
@@ -98,11 +73,6 @@
rag-indexer-service
${project.version}
-
- com.datamate
- rag-query-service
- ${project.version}
-
diff --git a/backend/services/pipeline-orchestration-service/pom.xml b/backend/services/pipeline-orchestration-service/pom.xml
deleted file mode 100644
index 53ca81006..000000000
--- a/backend/services/pipeline-orchestration-service/pom.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
- 4.0.0
-
-
- com.datamate
- services
- 1.0.0-SNAPSHOT
- ../pom.xml
-
-
- pipeline-orchestration-service
- Pipeline Orchestration Service
- 流程编排服务
-
-
-
- com.datamate
- domain-common
- ${project.version}
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.cloud
- spring-cloud-starter-openfeign
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-ui
-
-
- org.openapitools
- jackson-databind-nullable
-
-
- jakarta.validation
- jakarta.validation-api
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
- org.openapitools
- openapi-generator-maven-plugin
- 6.6.0
-
-
-
- generate
-
-
- ${project.basedir}/../../openapi/specs/pipeline-orchestration.yaml
- spring
-
- com.datamate.pipeline.interfaces.api
- com.datamate.pipeline.interfaces.dto
-
- true
- true
- true
- springdoc
-
-
-
-
-
-
-
-
-
-
diff --git a/backend/services/pom.xml b/backend/services/pom.xml
index 912227210..f103535b9 100644
--- a/backend/services/pom.xml
+++ b/backend/services/pom.xml
@@ -18,23 +18,13 @@
Services
-
- ../shared/domain-common
- ../shared/security-common
-
data-management-service
operator-market-service
data-cleaning-service
- data-synthesis-service
- data-annotation-service
- data-evaluation-service
- pipeline-orchestration-service
- execution-engine-service
rag-indexer-service
- rag-query-service
main-application
diff --git a/backend/services/rag-query-service/pom.xml b/backend/services/rag-query-service/pom.xml
deleted file mode 100644
index b8e0df4a6..000000000
--- a/backend/services/rag-query-service/pom.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
- 4.0.0
-
-
- com.datamate
- services
- 1.0.0-SNAPSHOT
- ../pom.xml
-
-
- rag-query-service
- RAG Query Service
- RAG查询服务
-
-
-
- com.datamate
- domain-common
- ${project.version}
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.cloud
- spring-cloud-starter-openfeign
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-ui
-
-
- org.openapitools
- jackson-databind-nullable
-
-
- jakarta.validation
- jakarta.validation-api
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
-
-
diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/CommonErrorCode.java b/backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/CommonErrorCode.java
index 0e5e98426..05bad840a 100644
--- a/backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/CommonErrorCode.java
+++ b/backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/CommonErrorCode.java
@@ -12,7 +12,9 @@
@AllArgsConstructor
public enum CommonErrorCode implements ErrorCode{
PARAM_ERROR("common.0001", "参数错误"),
- PRE_UPLOAD_REQUEST_NOT_EXIST("common.0101", "预上传请求不存在");
+ PRE_UPLOAD_REQUEST_NOT_EXIST("common.0101", "预上传请求不存在"),
+ SIGNUP_ERROR("common.0400", "用户名或者邮箱已经存在"),
+ UNAUTHORIZED("common.0401", "认证失败");
private final String code;
private final String message;
}
diff --git a/deployment/docker/datamate/docker-compose.yml b/deployment/docker/datamate/docker-compose.yml
index 2b4ee2b95..5b42b9376 100644
--- a/deployment/docker/datamate/docker-compose.yml
+++ b/deployment/docker/datamate/docker-compose.yml
@@ -38,6 +38,8 @@ services:
image: ${REGISTRY:-}datamate-gateway
restart: on-failure
privileged: true
+ environment:
+ - JWT_SECRET=default-insecure-key-change-in-production
networks: [ datamate ]
datamate-frontend:
diff --git a/deployment/helm/datamate/values.yaml b/deployment/helm/datamate/values.yaml
index fc9051e5e..4276518a3 100644
--- a/deployment/helm/datamate/values.yaml
+++ b/deployment/helm/datamate/values.yaml
@@ -121,6 +121,9 @@ backend-python:
mountPath: /var/log/datamate
gateway:
+ env:
+ - name: JWT_SECRET
+ value: &JWT_SECRET "default-insecure-key-change-in-production"
volumes:
- *logVolume
volumeMounts:
diff --git a/scripts/db/data-management-init.sql b/scripts/db/data-management-init.sql
index 549721fdd..f606a149e 100644
--- a/scripts/db/data-management-init.sql
+++ b/scripts/db/data-management-init.sql
@@ -290,8 +290,7 @@ CREATE TRIGGER update_users_updated_at
-- 插入初始数据
INSERT INTO users (username, email, password_hash, full_name, role, organization)
VALUES
-('admin', 'admin@datamate.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7q7U3.XUO', '系统管理员', 'ADMIN', 'DataMate'),
-('knowledge_user', 'knowledge@datamate.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7q7U3.XUO', '知识库用户', 'USER', '三甲医院')
+ ('admin', 'admin@datamate.com', '$2a$10$/esawo436yxg2eodpl/JJ.3Xu6y9m91/ihXRHie9al.LUoNQR5fF.', '系统管理员', 'ADMIN', 'DataMate')
ON CONFLICT (username) DO NOTHING;
-- 创建视图:数据集统计摘要
diff --git a/scripts/images/backend/Dockerfile b/scripts/images/backend/Dockerfile
index 5d8015b6e..f75e9200b 100644
--- a/scripts/images/backend/Dockerfile
+++ b/scripts/images/backend/Dockerfile
@@ -1,7 +1,7 @@
FROM maven:3-eclipse-temurin-21 AS builder
COPY backend/ /opt/backend
-RUN cd /opt/backend/services && \
+RUN cd /opt/backend/ && \
mvn -U clean package -Dmaven.test.skip=true
diff --git a/scripts/images/gateway/Dockerfile b/scripts/images/gateway/Dockerfile
index 06e642847..8974a39d0 100644
--- a/scripts/images/gateway/Dockerfile
+++ b/scripts/images/gateway/Dockerfile
@@ -2,7 +2,7 @@ FROM maven:3-eclipse-temurin-21 AS builder
COPY backend/ /opt/gateway
-RUN cd /opt/gateway/api-gateway && \
+RUN cd /opt/gateway/ && \
mvn -U clean package -Dmaven.test.skip=true
From 666b932ba57e49b8a72db6a52736f22e36df7cc1 Mon Sep 17 00:00:00 2001
From: uname <2986773479@qq.com>
Date: Wed, 14 Jan 2026 17:34:27 +0800
Subject: [PATCH 2/3] =?UTF-8?q?fix:=20change=20the=20collection=20template?=
=?UTF-8?q?=20"OBS=E5=BD=92=E9=9B=86=E6=A8=A1=E6=9D=BF"=20to=20"S3?=
=?UTF-8?q?=E5=AD=98=E5=82=A8=E5=BD=92=E9=9B=86=E6=A8=A1=E6=9D=BF"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
scripts/db/data-collection-init.sql | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/scripts/db/data-collection-init.sql b/scripts/db/data-collection-init.sql
index caa38d121..362af9227 100644
--- a/scripts/db/data-collection-init.sql
+++ b/scripts/db/data-collection-init.sql
@@ -173,13 +173,13 @@ INSERT INTO t_dc_collection_templates (
),
(
'2',
- 'OBS归集模板',
- '将OBS存储上的文件归集到DataMate平台上。',
- 'obsreader',
- 'obsreader',
- 'obswriter',
- 'obswriter',
- '{"parameter": {"endpoint": {"name": "服务地址","description": "OBS的服务地址。","type": "input", "required": true, "index": 1},"bucket": {"name": "存储桶名称","description": "OBS存储桶名称。","type": "input", "required": true, "index": 2},"accessKey": {"name": "AK","description": "OBS访问密钥。","type": "input", "required": true, "index": 3},"secretKey": {"name": "SK","description": "OBS密钥。","type": "password", "required": true, "index": 4},"prefix": {"name": "匹配前缀","description": "按照匹配前缀去选中OBS中的文件进行归集。","type": "input", "required": true, "index": 5}}, "reader": {}, "writer": {}}',
+ 'S3存储归集模板',
+ '将S3对象存储(如OBS、MinIO、Ceph等)上的文件归集到DataMate平台上。',
+ 's3reader',
+ 's3reader',
+ 's3writer',
+ 's3writer',
+ '{"parameter": {"endpoint": {"name": "服务地址","description": "S3兼容存储的服务地址(如http://minio.example.com:9000)。","type": "input", "required": true, "index": 1}, "bucket": {"name": "存储桶名称","description": "S3存储桶名称。","type": "input", "required": true, "index": 2}, "accessKey": {"name": "Access Key","description": "S3访问密钥(Access Key ID)。","type": "input", "required": true, "index": 3}, "secretKey": {"name": "Secret Key","description": "S3密钥(Secret Access Key)。","type": "password", "required": true, "index": 4}, "prefix": {"name": "匹配前缀","description": "按照匹配前缀选中S3中的文件进行归集。","type": "input", "required": false, "index": 5}, "region": {"name": "区域","description": "S3区域(默认us-east-1)。","type": "input", "required": false, "index": 6}}, "reader": {}, "writer": {}}',
TRUE,
'system',
'system'
From 78882d4a03fd0a4fb8fffd9485209f58e4f914ac Mon Sep 17 00:00:00 2001
From: uname <2986773479@qq.com>
Date: Wed, 14 Jan 2026 17:45:46 +0800
Subject: [PATCH 3/3] refactor: refactor the generate_datx_config function
---
.../app/module/collection/client/datax_client.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/runtime/datamate-python/app/module/collection/client/datax_client.py b/runtime/datamate-python/app/module/collection/client/datax_client.py
index 01bddfef7..94891d81f 100644
--- a/runtime/datamate-python/app/module/collection/client/datax_client.py
+++ b/runtime/datamate-python/app/module/collection/client/datax_client.py
@@ -50,6 +50,7 @@ def validate_json_string(self) -> Dict[str, Any]:
@staticmethod
def generate_datx_config(task_config: CollectionConfig, template: CollectionTemplate, target_path: str):
# 校验参数
+ dest_path_target = {"nfswriter", "s3writer", "glusterfswriter"}
reader_parameter = {
**(task_config.parameter if task_config.parameter else {}),
**(task_config.reader if task_config.reader else {})
@@ -61,11 +62,7 @@ def generate_datx_config(task_config: CollectionConfig, template: CollectionTemp
"fileName": "collection_result",
"writeMode": "truncate"
}
- elif template.target_type == "nfswriter":
- dest_parameter = {
- "destPath": target_path
- }
- elif template.target_type == "s3writer" or template.target_type == "glusterfswriter" or template.target_type == "localwriter":
+ elif dest_path_target.__contains__(template.target_type):
dest_parameter = {
"destPath": target_path
}