You've already forked DataMate
@@ -1,8 +1,10 @@
|
||||
package com.datamate.operator.application;
|
||||
|
||||
|
||||
import com.datamate.operator.domain.contants.OperatorConstant;
|
||||
import com.datamate.operator.domain.repository.CategoryRelationRepository;
|
||||
import com.datamate.operator.domain.repository.CategoryRepository;
|
||||
import com.datamate.operator.domain.repository.OperatorRepository;
|
||||
import com.datamate.operator.interfaces.dto.CategoryDto;
|
||||
import com.datamate.operator.interfaces.dto.CategoryRelationDto;
|
||||
import com.datamate.operator.interfaces.dto.CategoryTreeResponse;
|
||||
@@ -11,9 +13,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -21,6 +21,8 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CategoryService {
|
||||
private final OperatorRepository operatorRepo;
|
||||
|
||||
private final CategoryRepository categoryRepo;
|
||||
|
||||
private final CategoryRelationRepository categoryRelationRepo;
|
||||
@@ -40,7 +42,7 @@ public class CategoryService {
|
||||
.filter(relation -> !StringUtils.equals(relation.getParentId(), "0"))
|
||||
.collect(Collectors.groupingBy(CategoryDto::getParentId));
|
||||
|
||||
return groupedByParentId.entrySet().stream()
|
||||
List<CategoryTreeResponse> categoryTreeResponses = groupedByParentId.entrySet().stream()
|
||||
.sorted(categoryComparator(nameMap))
|
||||
.map(entry -> {
|
||||
String parentId = entry.getKey();
|
||||
@@ -55,7 +57,11 @@ public class CategoryService {
|
||||
}).sorted(Comparator.comparing(CategoryDto::getCreatedAt)).toList());
|
||||
response.setCount(totalCount.get());
|
||||
return response;
|
||||
}).toList();
|
||||
}).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
int stars = operatorRepo.countOperatorByStar(true);
|
||||
categoryTreeResponses.add(buildStarCategoryTree(stars));
|
||||
return categoryTreeResponses;
|
||||
}
|
||||
|
||||
private Comparator<Map.Entry<String, List<CategoryDto>>> categoryComparator(Map<String, CategoryDto> categoryMap) {
|
||||
@@ -65,4 +71,21 @@ public class CategoryService {
|
||||
return index1.compareTo(index2);
|
||||
};
|
||||
}
|
||||
|
||||
private CategoryTreeResponse buildStarCategoryTree(int stars) {
|
||||
CategoryTreeResponse starResponse = new CategoryTreeResponse();
|
||||
starResponse.setName("收藏状态");
|
||||
starResponse.setCount(stars);
|
||||
starResponse.setId("257b27e0-bba9-11f0-89d7-00155d0a6153");
|
||||
CategoryDto star = new CategoryDto();
|
||||
star.setId(OperatorConstant.CATEGORY_STAR_ID);
|
||||
star.setName("已收藏");
|
||||
star.setValue("isStar");
|
||||
star.setCount(stars);
|
||||
star.setParentId("257b27e0-bba9-11f0-89d7-00155d0a6153");
|
||||
star.setCreatedAt(LocalDateTime.now());
|
||||
star.setType("predefined");
|
||||
starResponse.setCategories(Collections.singletonList(star));
|
||||
return starResponse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,35 @@ package com.datamate.operator.application;
|
||||
|
||||
import com.datamate.common.domain.model.ChunkUploadPreRequest;
|
||||
import com.datamate.common.domain.service.FileService;
|
||||
import com.datamate.common.infrastructure.exception.BusinessException;
|
||||
import com.datamate.operator.domain.contants.OperatorConstant;
|
||||
import com.datamate.operator.infrastructure.converter.OperatorConverter;
|
||||
import com.datamate.operator.domain.model.OperatorView;
|
||||
import com.datamate.operator.domain.repository.CategoryRelationRepository;
|
||||
import com.datamate.operator.domain.repository.OperatorRepository;
|
||||
import com.datamate.operator.domain.repository.OperatorViewRepository;
|
||||
import com.datamate.operator.infrastructure.exception.OperatorErrorCode;
|
||||
import com.datamate.operator.infrastructure.parser.ParserHolder;
|
||||
import com.datamate.operator.interfaces.dto.OperatorDto;
|
||||
import com.datamate.operator.interfaces.dto.UploadOperatorRequest;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class OperatorService {
|
||||
private final OperatorRepository operatorRepo;
|
||||
@@ -32,6 +43,8 @@ public class OperatorService {
|
||||
|
||||
private final FileService fileService;
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Value("${operator.base.path:/operators}")
|
||||
private String operatorBasePath;
|
||||
|
||||
@@ -53,19 +66,25 @@ public class OperatorService {
|
||||
|
||||
@Transactional
|
||||
public OperatorDto createOperator(OperatorDto req) {
|
||||
overrideSettings(req);
|
||||
operatorRepo.insertOperator(req);
|
||||
relationRepo.batchInsert(req.getId(), req.getCategories());
|
||||
parserHolder.extractTo(getFileType(req.getFileName()), getUploadPath(req.getFileName()),
|
||||
getExtractPath(getFileNameWithoutExtension(req.getFileName())));
|
||||
getExtractPath(getFileNameWithoutExtension(req.getFileName())));
|
||||
return getOperatorById(req.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public OperatorDto updateOperator(String id, OperatorDto req) {
|
||||
overrideSettings(req);
|
||||
operatorRepo.updateOperator(req);
|
||||
relationRepo.batchInsert(id, req.getCategories());
|
||||
parserHolder.extractTo(getFileType(req.getFileName()), getUploadPath(req.getFileName()),
|
||||
getExtractPath(getFileNameWithoutExtension(req.getFileName())));
|
||||
if (CollectionUtils.isNotEmpty(req.getCategories())) {
|
||||
relationRepo.batchUpdate(id, req.getCategories());
|
||||
}
|
||||
if (StringUtils.isNotBlank(req.getFileName())) {
|
||||
parserHolder.extractTo(getFileType(req.getFileName()), getUploadPath(req.getFileName()),
|
||||
getExtractPath(getFileNameWithoutExtension(req.getFileName())));
|
||||
}
|
||||
return getOperatorById(id);
|
||||
}
|
||||
|
||||
@@ -77,7 +96,7 @@ public class OperatorService {
|
||||
|
||||
public OperatorDto uploadOperator(String fileName) {
|
||||
return parserHolder.parseYamlFromArchive(getFileType(fileName), new File(getUploadPath(fileName)),
|
||||
OperatorConstant.YAML_PATH);
|
||||
OperatorConstant.YAML_PATH);
|
||||
}
|
||||
|
||||
public String preUpload() {
|
||||
@@ -107,4 +126,76 @@ public class OperatorService {
|
||||
private String getExtractPath(String fileName) {
|
||||
return operatorBasePath + File.separator + "extract" + File.separator + fileName;
|
||||
}
|
||||
|
||||
private void overrideSettings(OperatorDto operatorDto) {
|
||||
if (StringUtils.isBlank(operatorDto.getSettings()) || MapUtils.isEmpty(operatorDto.getOverrides())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Map<String, Map<String, Object>> settings = objectMapper.readValue(operatorDto.getSettings(), Map.class);
|
||||
for (Map.Entry<String, Object> entry : operatorDto.getOverrides().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!settings.containsKey(key)) {
|
||||
continue;
|
||||
}
|
||||
Object value = entry.getValue();
|
||||
Map<String, Object> setting = settings.get(key);
|
||||
String type = setting.get("type").toString();
|
||||
switch (type) {
|
||||
case "slider":
|
||||
case "switch":
|
||||
case "select":
|
||||
case "input":
|
||||
case "radio":
|
||||
setting.put("defaultVal", value);
|
||||
break;
|
||||
case "checkbox":
|
||||
setting.put("defaultVal", convertObjectToListString(value));
|
||||
break;
|
||||
case "range":
|
||||
updateProperties(setting, value);
|
||||
default:
|
||||
}
|
||||
settings.put(key, setting);
|
||||
}
|
||||
operatorDto.setSettings(objectMapper.writeValueAsString(settings));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw BusinessException.of(OperatorErrorCode.SETTINGS_PARSE_FAILED, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String convertObjectToListString(Object object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
} else if (object instanceof List<?> list) {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Object item : list) {
|
||||
result.add(String.valueOf(item));
|
||||
}
|
||||
return String.join(",", result);
|
||||
} else {
|
||||
return object.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProperties(Map<String, Object> setting, Object value) {
|
||||
List<Object> defaultValue = new ArrayList<>();
|
||||
if (value instanceof List) {
|
||||
defaultValue.addAll((List<?>) value);
|
||||
}
|
||||
|
||||
Object properties = setting.get("properties");
|
||||
if (properties instanceof List<?> list) {
|
||||
if (defaultValue.size() != list.size()) {
|
||||
return;
|
||||
}
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Map<String, Object> map = objectMapper.convertValue(list.get(i), Map.class);
|
||||
map.put("defaultVal", defaultValue.get(i));
|
||||
result.add(map);
|
||||
}
|
||||
setting.put("properties", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ public class OperatorConstant {
|
||||
|
||||
public static String CATEGORY_ALL_ID = "4d7dbd77-0a92-44f3-9056-2cd62d4a71e4";
|
||||
|
||||
public static String CATEGORY_STAR_ID = "51847c24-bba9-11f0-888b-5b143cb738aa";
|
||||
|
||||
public static Map<String, String> CATEGORY_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
|
||||
@@ -12,5 +12,7 @@ public interface CategoryRelationRepository extends IRepository<CategoryRelation
|
||||
|
||||
void batchInsert(String operatorId, List<String> categories);
|
||||
|
||||
void batchUpdate(String operatorId, List<String> categories);
|
||||
|
||||
void deleteByOperatorId(String operatorId);
|
||||
}
|
||||
|
||||
@@ -14,4 +14,6 @@ public interface OperatorRepository extends IRepository<Operator> {
|
||||
void insertOperator(OperatorDto operator);
|
||||
|
||||
void deleteOperator(String id);
|
||||
|
||||
int countOperatorByStar(boolean isStar);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,9 @@ public enum OperatorErrorCode implements ErrorCode {
|
||||
|
||||
YAML_NOT_FOUND("op.0002", "算子中缺少元数据文件"),
|
||||
|
||||
FIELD_NOT_FOUND("op.0003", "缺少必要的字段");
|
||||
FIELD_NOT_FOUND("op.0003", "缺少必要的字段"),
|
||||
|
||||
SETTINGS_PARSE_FAILED("op.0004", "settings字段解析失败");
|
||||
|
||||
private final String code;
|
||||
private final String message;
|
||||
|
||||
@@ -31,6 +31,17 @@ public class CategoryRelationRepositoryImpl extends CrudRepository<CategoryRelat
|
||||
mapper.insert(categoryRelations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchUpdate(String operatorId, List<String> categories) {
|
||||
List<CategoryRelation> categoryRelations = categories.stream()
|
||||
.map(category -> new CategoryRelation(category, operatorId))
|
||||
.toList();
|
||||
LambdaQueryWrapper<CategoryRelation> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CategoryRelation::getOperatorId, operatorId);
|
||||
mapper.delete(queryWrapper);
|
||||
mapper.insert(categoryRelations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByOperatorId(String operatorId) {
|
||||
LambdaQueryWrapper<CategoryRelation> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.datamate.operator.infrastructure.persistence.Impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.repository.CrudRepository;
|
||||
import com.datamate.operator.infrastructure.converter.OperatorConverter;
|
||||
import com.datamate.operator.domain.model.Operator;
|
||||
@@ -35,4 +36,11 @@ public class OperatorRepositoryImpl extends CrudRepository<OperatorMapper, Opera
|
||||
public void deleteOperator(String id) {
|
||||
mapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countOperatorByStar(boolean isStar) {
|
||||
LambdaQueryWrapper<Operator> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Operator::getIsStar, isStar);
|
||||
return Math.toIntExact(mapper.selectCount(queryWrapper));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ public class OperatorViewRepositoryImpl extends CrudRepository<OperatorViewMappe
|
||||
queryWrapper.in(CollectionUtils.isNotEmpty(categories), "category_id", categories)
|
||||
.like(StringUtils.isNotBlank(operatorName), "operator_name", operatorName)
|
||||
.eq(isStar != null, "is_star", isStar)
|
||||
.groupBy("operator_id");
|
||||
.groupBy("operator_id")
|
||||
.orderByDesc("created_at");
|
||||
Page<OperatorView> queryPage = null;
|
||||
if (size != null && page != null) {
|
||||
queryPage = new Page<>(page + 1, size);
|
||||
|
||||
@@ -24,7 +24,7 @@ public interface OperatorViewMapper extends BaseMapper<OperatorView> {
|
||||
|
||||
@Select("SELECT operator_id AS id, operator_name AS name, description, version, inputs, outputs, runtime, " +
|
||||
"settings, is_star, created_at, updated_at, " +
|
||||
"GROUP_CONCAT(category_id ORDER BY created_at DESC SEPARATOR ',') AS categories " +
|
||||
"GROUP_CONCAT(category_name ORDER BY created_at DESC SEPARATOR ',') AS categories " +
|
||||
"FROM v_operator WHERE operator_id = #{id}")
|
||||
OperatorView findOperatorById(@Param("id") String id);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* OperatorDto
|
||||
@@ -32,6 +33,8 @@ public class OperatorDto {
|
||||
|
||||
private String settings;
|
||||
|
||||
private Map<String, Object> overrides;
|
||||
|
||||
private String fileName;
|
||||
|
||||
private Boolean isStar;
|
||||
|
||||
@@ -2,10 +2,12 @@ package com.datamate.operator.interfaces.rest;
|
||||
|
||||
import com.datamate.common.interfaces.PagedResponse;
|
||||
import com.datamate.operator.application.OperatorService;
|
||||
import com.datamate.operator.domain.contants.OperatorConstant;
|
||||
import com.datamate.operator.interfaces.dto.OperatorDto;
|
||||
import com.datamate.operator.interfaces.dto.OperatorsListPostRequest;
|
||||
import com.datamate.operator.interfaces.dto.UploadOperatorRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -19,10 +21,16 @@ public class OperatorController {
|
||||
|
||||
@PostMapping("/list")
|
||||
public PagedResponse<OperatorDto> operatorsListPost(@RequestBody OperatorsListPostRequest request) {
|
||||
Boolean isStar = null;
|
||||
List<String> categories = request.getCategories();
|
||||
if (CollectionUtils.isNotEmpty(request.getCategories()) &&
|
||||
request.getCategories().contains(OperatorConstant.CATEGORY_STAR_ID)) {
|
||||
isStar = true;
|
||||
categories.remove(OperatorConstant.CATEGORY_STAR_ID);
|
||||
}
|
||||
List<OperatorDto> responses = operatorService.getOperators(request.getPage(), request.getSize(),
|
||||
request.getCategories(), request.getOperatorName(), request.getIsStar());
|
||||
int count = operatorService.getOperatorsCount(request.getCategories(), request.getOperatorName(),
|
||||
request.getIsStar());
|
||||
categories, request.getOperatorName(), isStar);
|
||||
int count = operatorService.getOperatorsCount(categories, request.getOperatorName(), isStar);
|
||||
int totalPages = (count + request.getSize() + 1) / request.getSize();
|
||||
return PagedResponse.of(responses, request.getPage(), count, totalPages);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user