Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -11,16 +13,16 @@
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;

@Service
@RequiredArgsConstructor
public class CategoryService {
private final OperatorRepository operatorRepo;

private final CategoryRepository categoryRepo;

private final CategoryRelationRepository categoryRelationRepo;
Expand All @@ -40,7 +42,7 @@ public List<CategoryTreeResponse> getAllCategories() {
.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();
Expand All @@ -55,7 +57,11 @@ public List<CategoryTreeResponse> getAllCategories() {
}).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) {
Expand All @@ -65,4 +71,21 @@ private Comparator<Map.Entry<String, List<CategoryDto>>> categoryComparator(Map<
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,35 @@

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;
Expand All @@ -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;

Expand All @@ -53,19 +66,25 @@ public OperatorDto getOperatorById(String id) {

@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);
}

Expand All @@ -77,7 +96,7 @@ public void deleteOperator(String id) {

public OperatorDto uploadOperator(String fileName) {
return parserHolder.parseYamlFromArchive(getFileType(fileName), new File(getUploadPath(fileName)),
OperatorConstant.YAML_PATH);
OperatorConstant.YAML_PATH);
}

public String preUpload() {
Expand Down Expand Up @@ -107,4 +126,76 @@ private String getUploadPath(String fileName) {
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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public interface OperatorRepository extends IRepository<Operator> {
void insertOperator(OperatorDto operator);

void deleteOperator(String id);

int countOperatorByStar(boolean isStar);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ public void batchInsert(String operatorId, List<String> categories) {
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<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -35,4 +36,11 @@ public void insertOperator(OperatorDto operator) {
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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public List<OperatorView> findOperatorsByCriteria(Integer page, Integer size, St
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ IPage<OperatorView> findOperatorsByCriteria(IPage<OperatorView> page,

@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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
* OperatorDto
Expand All @@ -32,6 +33,8 @@ public class OperatorDto {

private String settings;

private Map<String, Object> overrides;

private String fileName;

private Boolean isStar;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

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.*;

Expand All @@ -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);
}
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/DetailHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ function DetailHeader<T>({
key={op.key}
{...op.confirm}
onConfirm={() => {
op?.confirm?.onConfirm?.();
if (op.onClick) {
op.onClick()
} else {
op?.confirm?.onConfirm?.();
}
}}
okType={op.danger ? "danger" : "primary"}
overlayStyle={{ zIndex: 9999 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ const ParamConfig: React.FC<ParamConfigProps> = ({
return (
<div className="pl-4 border-l border-gray-300">
{param.properties.map((subParam) => (
<Config
<ParamConfig
key={subParam.key}
operator={operator}
paramKey={subParam.key}
Expand Down
Loading