From 872d3ec5183cd05b619aade57d44edb24af067c7 Mon Sep 17 00:00:00 2001 From: daikon <1059907724@qq.com> Date: Wed, 24 Apr 2024 11:38:29 +0800 Subject: [PATCH] Class (#939) --- .../headless/api/pojo/request/ClassReq.java | 16 +++ .../api/pojo/request/SqlExecuteReq.java | 4 +- .../headless/api/pojo/response/ClassResp.java | 39 ++++++ headless/server/pom.xml | 6 + .../persistence/dataobject/ClassDO.java | 42 ++++++ .../persistence/mapper/ClassMapper.java | 9 ++ .../repository/ClassRepository.java | 21 +++ .../repository/impl/ClassRepositoryImpl.java | 78 ++++++++++++ .../headless/server/pojo/ClassFilter.java | 11 ++ .../headless/server/rest/ClassController.java | 100 +++++++++++++++ .../headless/server/service/ClassService.java | 19 +++ .../server/service/TagObjectService.java | 4 + .../server/service/impl/ClassServiceImpl.java | 111 ++++++++++++++++ .../service/impl/DatabaseServiceImpl.java | 3 + .../service/impl/TagObjectServiceImpl.java | 17 ++- .../headless/server/utils/ClassConverter.java | 120 ++++++++++++++++++ 16 files changed, 596 insertions(+), 4 deletions(-) create mode 100644 headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ClassReq.java create mode 100644 headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/response/ClassResp.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/dataobject/ClassDO.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/mapper/ClassMapper.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/ClassRepository.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/ClassRepositoryImpl.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/ClassFilter.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/ClassController.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/service/ClassService.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ClassServiceImpl.java create mode 100644 headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ClassConverter.java diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ClassReq.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ClassReq.java new file mode 100644 index 000000000..45bc6119a --- /dev/null +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ClassReq.java @@ -0,0 +1,16 @@ +package com.tencent.supersonic.headless.api.pojo.request; + +import com.tencent.supersonic.headless.api.pojo.SchemaItem; +import lombok.Data; + +import java.util.List; + +@Data +public class ClassReq extends SchemaItem { + + private Long domainId; + private Long tagObjectId; + private Long parentId; + private List itemIds; + +} \ No newline at end of file diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/SqlExecuteReq.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/SqlExecuteReq.java index c4f6f2f8f..fee5d077d 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/SqlExecuteReq.java +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/SqlExecuteReq.java @@ -20,11 +20,13 @@ public class SqlExecuteReq { private List sqlVariables; + private Integer limit = 1000; + public String getSql() { if (StringUtils.isNotBlank(sql) && sql.endsWith(";")) { sql = sql.substring(0, sql.length() - 1); } - return String.format(LIMIT_WRAPPER, sql); + return String.format(LIMIT_WRAPPER, sql, limit); } } diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/response/ClassResp.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/response/ClassResp.java new file mode 100644 index 000000000..0c16e0bf9 --- /dev/null +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/response/ClassResp.java @@ -0,0 +1,39 @@ +package com.tencent.supersonic.headless.api.pojo.response; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class ClassResp { + + private Long id; + + private Long domainId; + private String domainName; + private Long dataSetId; + + private String name; + private String bizName; + private String description; + + private String fullPath; + + /** + * 分类状态 + */ + private Integer status; + + /** + * METRIC、DIMENSION、TAG + */ + private String type; + private List itemIds; + + private Date createdAt; + private String createdBy; + private Date updatedAt; + private String updatedBy; + +} \ No newline at end of file diff --git a/headless/server/pom.xml b/headless/server/pom.xml index bd7c2578a..973f4704c 100644 --- a/headless/server/pom.xml +++ b/headless/server/pom.xml @@ -118,6 +118,12 @@ postgresql ${postgresql.version} + + com.tencent.supersonic + headless-api + 0.9.0-SNAPSHOT + compile + diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/dataobject/ClassDO.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/dataobject/ClassDO.java new file mode 100644 index 000000000..ea5ac1c60 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/dataobject/ClassDO.java @@ -0,0 +1,42 @@ +package com.tencent.supersonic.headless.server.persistence.dataobject; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("s2_class") +public class ClassDO { + + @TableId(type = IdType.AUTO) + private Long id; + + private Long domainId; + private Long dataSetId; + + private String name; + private String bizName; + private String description; + private Long parentId; + + /** + * 分类状态 + */ + private Integer status; + + /** + * METRIC、DIMENSION、TAG + */ + private String type; + private String itemIds; + + private Date createdAt; + private String createdBy; + private Date updatedAt; + private String updatedBy; + + +} \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/mapper/ClassMapper.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/mapper/ClassMapper.java new file mode 100644 index 000000000..fc1857326 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/mapper/ClassMapper.java @@ -0,0 +1,9 @@ +package com.tencent.supersonic.headless.server.persistence.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.tencent.supersonic.headless.server.persistence.dataobject.ClassDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface ClassMapper extends BaseMapper { +} \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/ClassRepository.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/ClassRepository.java new file mode 100644 index 000000000..8befa35bf --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/ClassRepository.java @@ -0,0 +1,21 @@ +package com.tencent.supersonic.headless.server.persistence.repository; + +import com.tencent.supersonic.headless.server.persistence.dataobject.ClassDO; +import com.tencent.supersonic.headless.server.pojo.ClassFilter; + +import java.util.List; + +public interface ClassRepository { + + Long create(ClassDO classDO); + + Long update(ClassDO classDO); + + Integer delete(List ids); + + ClassDO getClassById(Long id); + + List getClassDOList(ClassFilter filter); + + List getAllClassDOList(); +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/ClassRepositoryImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/ClassRepositoryImpl.java new file mode 100644 index 000000000..32464ae53 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/ClassRepositoryImpl.java @@ -0,0 +1,78 @@ +package com.tencent.supersonic.headless.server.persistence.repository.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.tencent.supersonic.headless.server.persistence.dataobject.ClassDO; +import com.tencent.supersonic.headless.server.persistence.mapper.ClassMapper; +import com.tencent.supersonic.headless.server.persistence.repository.ClassRepository; +import com.tencent.supersonic.headless.server.pojo.ClassFilter; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.logging.log4j.util.Strings; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Objects; + +@Repository +public class ClassRepositoryImpl implements ClassRepository { + + private final ClassMapper mapper; + + public ClassRepositoryImpl(ClassMapper mapper) { + this.mapper = mapper; + } + + @Override + public Long create(ClassDO classDO) { + mapper.insert(classDO); + return classDO.getId(); + } + + @Override + public Long update(ClassDO classDO) { + mapper.updateById(classDO); + return classDO.getId(); + } + + @Override + public Integer delete(List ids) { + return mapper.deleteBatchIds(ids); + } + + @Override + public ClassDO getClassById(Long id) { + return mapper.selectById(id); + } + + @Override + public List getClassDOList(ClassFilter filter) { + QueryWrapper wrapper = new QueryWrapper(); + if (Objects.nonNull(filter.getDomainId())) { + wrapper.lambda().eq(ClassDO::getDomainId, filter.getDomainId()); + } + if (Objects.nonNull(filter.getDataSetId())) { + wrapper.lambda().eq(ClassDO::getDataSetId, filter.getDataSetId()); + } + if (Strings.isNotEmpty(filter.getType())) { + wrapper.lambda().eq(ClassDO::getType, filter.getType()); + } + if (CollectionUtils.isNotEmpty(filter.getIds())) { + wrapper.lambda().in(ClassDO::getId, filter.getIds()); + } + if (Objects.nonNull(filter.getCreatedBy())) { + wrapper.lambda().eq(ClassDO::getCreatedBy, filter.getCreatedBy()); + } + if (Objects.nonNull(filter.getStatus())) { + wrapper.lambda().eq(ClassDO::getStatus, filter.getStatus()); + } + if (Objects.nonNull(filter.getBizName())) { + wrapper.lambda().eq(ClassDO::getBizName, filter.getBizName()); + } + return mapper.selectList(wrapper); + } + + @Override + public List getAllClassDOList() { + QueryWrapper wrapper = new QueryWrapper(); + return mapper.selectList(wrapper); + } +} \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/ClassFilter.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/ClassFilter.java new file mode 100644 index 000000000..90fb1d9d4 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/ClassFilter.java @@ -0,0 +1,11 @@ +package com.tencent.supersonic.headless.server.pojo; + +import lombok.Data; + +@Data +public class ClassFilter extends MetaFilter { + + private String type; + private Long dataSetId; + private Long classId; +} \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/ClassController.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/ClassController.java new file mode 100644 index 000000000..8b6a81345 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/ClassController.java @@ -0,0 +1,100 @@ +package com.tencent.supersonic.headless.server.rest; + +import com.tencent.supersonic.auth.api.authentication.pojo.User; +import com.tencent.supersonic.auth.api.authentication.utils.UserHolder; +import com.tencent.supersonic.headless.api.pojo.request.ClassReq; +import com.tencent.supersonic.headless.api.pojo.response.ClassResp; +import com.tencent.supersonic.headless.server.pojo.ClassFilter; +import com.tencent.supersonic.headless.server.service.ClassService; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.List; + +@RestController +@RequestMapping("/api/semantic/class") +public class ClassController { + + private final ClassService classService; + + public ClassController(ClassService classService) { + this.classService = classService; + } + + /** + * 新建目录 + * + * @param classReq + * @param request + * @param response + * @return + */ + @PostMapping("/create") + public ClassResp create(@RequestBody @Valid ClassReq classReq, + HttpServletRequest request, + HttpServletResponse response) { + User user = UserHolder.findUser(request, response); + return classService.create(classReq, user); + } + + /** + * 修改目录 + * + * @param classReq + * @param request + * @param response + * @return + */ + @PutMapping("/update") + public ClassResp update(@RequestBody @Valid ClassReq classReq, + HttpServletRequest request, + HttpServletResponse response) { + User user = UserHolder.findUser(request, response); + return classService.update(classReq, user); + } + + /** + * 删除目录 + * + * @param id + * @param request + * @param response + * @return + * @throws Exception + */ + @DeleteMapping("delete/{id}/{force}") + public Boolean delete(@PathVariable("id") Long id, + @PathVariable("force") Boolean force, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + User user = UserHolder.findUser(request, response); + return classService.delete(id, force, user); + } + + /** + * 删除目录 + * + * @param filter + * @param request + * @param response + * @return + * @throws Exception + */ + @GetMapping("delete/{id}/{force}") + public List get(@RequestBody @Valid ClassFilter filter, + HttpServletRequest request, + HttpServletResponse response) { + User user = UserHolder.findUser(request, response); + return classService.getClassList(filter, user); + } + +} \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/ClassService.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/ClassService.java new file mode 100644 index 000000000..996549a50 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/ClassService.java @@ -0,0 +1,19 @@ +package com.tencent.supersonic.headless.server.service; + +import com.tencent.supersonic.auth.api.authentication.pojo.User; +import com.tencent.supersonic.headless.api.pojo.request.ClassReq; +import com.tencent.supersonic.headless.api.pojo.response.ClassResp; +import com.tencent.supersonic.headless.server.pojo.ClassFilter; + +import java.util.List; + +public interface ClassService { + + ClassResp create(ClassReq classReq, User user); + + ClassResp update(ClassReq classReq, User user); + + Boolean delete(Long id, Boolean force, User user) throws Exception; + + List getClassList(ClassFilter filter, User user); +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/TagObjectService.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/TagObjectService.java index bcab01e95..a56208ba8 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/TagObjectService.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/TagObjectService.java @@ -6,6 +6,7 @@ import com.tencent.supersonic.headless.api.pojo.response.TagObjectResp; import com.tencent.supersonic.headless.server.pojo.TagObjectFilter; import java.util.List; +import java.util.Map; public interface TagObjectService { @@ -18,4 +19,7 @@ public interface TagObjectService { TagObjectResp getTagObject(Long id, User user); List getTagObjects(TagObjectFilter filter, User user); + + Map getAllTagObjectMap(); + } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ClassServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ClassServiceImpl.java new file mode 100644 index 000000000..44957760c --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ClassServiceImpl.java @@ -0,0 +1,111 @@ +package com.tencent.supersonic.headless.server.service.impl; + + +import com.tencent.supersonic.auth.api.authentication.pojo.User; +import com.tencent.supersonic.common.pojo.enums.StatusEnum; +import com.tencent.supersonic.common.util.BeanMapper; +import com.tencent.supersonic.headless.api.pojo.request.ClassReq; +import com.tencent.supersonic.headless.api.pojo.response.ClassResp; +import com.tencent.supersonic.headless.server.persistence.dataobject.ClassDO; +import com.tencent.supersonic.headless.server.persistence.repository.ClassRepository; +import com.tencent.supersonic.headless.server.pojo.ClassFilter; +import com.tencent.supersonic.headless.server.service.ClassService; +import com.tencent.supersonic.headless.server.utils.ClassConverter; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Service +public class ClassServiceImpl implements ClassService { + + private final ClassRepository classRepository; + private final ClassConverter converter; + + public ClassServiceImpl(ClassRepository classRepository, ClassConverter converter) { + this.classRepository = classRepository; + this.converter = converter; + } + + @Override + public ClassResp create(ClassReq classReq, User user) { + + ClassDO classDO = converter.convert(classReq); + classDO.setId(null); + Date date = new Date(); + classDO.setCreatedBy(user.getName()); + classDO.setCreatedAt(date); + classDO.setUpdatedBy(user.getName()); + classDO.setUpdatedAt(date); + classDO.setStatus(StatusEnum.ONLINE.getCode()); + + classRepository.create(classDO); + ClassDO classDOById = classRepository.getClassById(classDO.getId()); + + return converter.convert2Resp(classDOById); + } + + @Override + public ClassResp update(ClassReq classReq, User user) { + ClassDO classDO = classRepository.getClassById(classReq.getId()); + BeanMapper.mapper(classReq, classDO); + classDO.setUpdatedAt(new Date()); + classDO.setUpdatedBy(user.getName()); + classRepository.update(classDO); + return converter.convert2Resp(classRepository.getClassById(classReq.getId())); + } + + @Override + public Boolean delete(Long id, Boolean force, User user) throws Exception { + ClassDO classDO = classRepository.getClassById(id); + checkDeletePermission(classDO, user); + checkDeleteValid(classDO, force); + classRepository.delete(new ArrayList<>(Arrays.asList(id))); + + if (force) { + // 删除子分类 + List classDOList = classRepository.getAllClassDOList(); + Set deleteClassList = extractSubClass(id, classDOList); + classRepository.delete(new ArrayList<>(deleteClassList)); + } + return true; + } + + private Set extractSubClass(Long id, List classDOList) { + Set classIdSet = new HashSet<>(); + for (ClassDO classDO : classDOList) { + if (id.equals(classDO.getParentId())) { + classIdSet.add(classDO.getId()); + classIdSet.addAll(extractSubClass(classDO.getId(), classDOList)); + } + } + return classIdSet; + } + + private void checkDeleteValid(ClassDO classDelete, Boolean force) { + List classDOList = classRepository.getAllClassDOList(); + for (ClassDO classDO : classDOList) { + if (classDO.getParentId().equals(classDelete.getId()) && !force) { + throw new RuntimeException("该分类下还存在子分类, 暂不能删除, 请确认"); + } + } + } + + private void checkDeletePermission(ClassDO classDO, User user) throws Exception { + if (user.getName().equalsIgnoreCase(classDO.getCreatedBy()) || user.isSuperAdmin()) { + return; + } + throw new Exception("delete operation is not supported at the moment. Please contact the admin."); + } + + @Override + public List getClassList(ClassFilter filter, User user) { + List classDOList = classRepository.getClassDOList(filter); + return converter.convert2RespList(classDOList); + } + +} \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java index 0cd2f2297..f71e4d4ad 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java @@ -22,6 +22,7 @@ import com.tencent.supersonic.headless.server.service.DatabaseService; import com.tencent.supersonic.headless.server.service.ModelService; import com.tencent.supersonic.headless.server.utils.DatabaseConverter; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -35,6 +36,8 @@ import java.util.stream.Collectors; @Slf4j @Service public class DatabaseServiceImpl implements DatabaseService { + @Value("${inMemoryEmbeddingStore.persistent.path:/tmp}") + private String embeddingStorePersistentPath; private final SqlUtils sqlUtils; private DatabaseRepository databaseRepository; diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/TagObjectServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/TagObjectServiceImpl.java index f303ce275..40d09ed53 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/TagObjectServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/TagObjectServiceImpl.java @@ -15,6 +15,7 @@ import org.springframework.util.CollectionUtils; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @Service @@ -37,7 +38,7 @@ public class TagObjectServiceImpl implements TagObjectService { tagObjectDO.setUpdatedBy(user.getName()); tagObjectDO.setUpdatedAt(date); tagObjectDO.setStatus(StatusEnum.ONLINE.getCode()); - tagObjectRepository.create(tagObjectDO).longValue(); + tagObjectRepository.create(tagObjectDO); TagObjectDO tagObjectById = tagObjectRepository.getTagObjectById(tagObjectDO.getId()); return TagObjectConverter.convert2Resp(tagObjectById); } @@ -54,10 +55,10 @@ public class TagObjectServiceImpl implements TagObjectService { .collect(Collectors.toList()); for (TagObjectResp tagObject : tagObjectRespList) { if (tagObject.getBizName().equalsIgnoreCase(tagObjectReq.getBizName())) { - throw new Exception(String.format("the bizName %s is exit", tagObjectReq.getBizName())); + throw new Exception(String.format("the bizName %s is exist", tagObjectReq.getBizName())); } if (tagObject.getName().equalsIgnoreCase(tagObjectReq.getName())) { - throw new Exception(String.format("the name %s is exit", tagObjectReq.getName())); + throw new Exception(String.format("the name %s is exist", tagObjectReq.getName())); } } } @@ -102,4 +103,14 @@ public class TagObjectServiceImpl implements TagObjectService { List tagObjectDOList = tagObjectRepository.query(filter); return TagObjectConverter.convert2RespList(tagObjectDOList); } + + @Override + public Map getAllTagObjectMap() { + TagObjectFilter filter = new TagObjectFilter(); + List tagObjectDOList = tagObjectRepository.query(filter); + List tagObjectRespList = TagObjectConverter.convert2RespList(tagObjectDOList); + Map map = + tagObjectRespList.stream().collect(Collectors.toMap(TagObjectResp::getId, a -> a, (k1, k2) -> k1)); + return map; + } } \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ClassConverter.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ClassConverter.java new file mode 100644 index 000000000..281006863 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/ClassConverter.java @@ -0,0 +1,120 @@ +package com.tencent.supersonic.headless.server.utils; + +import com.tencent.supersonic.common.util.JsonUtil; +import com.tencent.supersonic.headless.api.pojo.request.ClassReq; +import com.tencent.supersonic.headless.api.pojo.response.ClassResp; +import com.tencent.supersonic.headless.api.pojo.response.DomainResp; +import com.tencent.supersonic.headless.api.pojo.response.TagObjectResp; +import com.tencent.supersonic.headless.server.persistence.dataobject.ClassDO; +import com.tencent.supersonic.headless.server.persistence.repository.ClassRepository; +import com.tencent.supersonic.headless.server.service.DomainService; +import com.tencent.supersonic.headless.server.service.TagObjectService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class ClassConverter { + + private final ClassRepository classRepository; + private final DomainService domainService; + private final TagObjectService tagObjectService; + + public ClassConverter(ClassRepository classRepository, DomainService domainService, + TagObjectService tagObjectService) { + this.classRepository = classRepository; + this.domainService = domainService; + this.tagObjectService = tagObjectService; + } + + public ClassDO convert(ClassReq classReq) { + ClassDO classDO = new ClassDO(); + BeanUtils.copyProperties(classReq, classDO); + classDO.setType(classReq.getTypeEnum().name()); + List itemIds = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(classReq.getItemIds())) { + itemIds = classReq.getItemIds(); + } + classDO.setItemIds(JsonUtil.toString(itemIds)); + + return classDO; + } + + public ClassResp convert2Resp(ClassDO classDO) { + Map idAndDomain = getIdAndDomain(); + Map classFullPathMap = getClassFullPathMap(); + return convert2RespInternal(classDO, idAndDomain, classFullPathMap); + } + + private ClassResp convert2RespInternal(ClassDO classDO, Map idAndDomain, + Map classFullPathMap) { + ClassResp classResp = new ClassResp(); + BeanUtils.copyProperties(classDO, classResp); + + Long domainId = classResp.getDomainId(); + if (Objects.nonNull(idAndDomain) && idAndDomain.containsKey(domainId) + && Objects.nonNull(idAndDomain.get(domainId))) { + classResp.setDomainName(idAndDomain.get(domainId).getName()); + } + + if (Objects.nonNull(classFullPathMap) && classFullPathMap.containsKey(classResp.getId())) { + classResp.setFullPath(classFullPathMap.get(classResp.getId())); + } + + return classResp; + } + + public List convert2RespList(List classDOList) { + List classRespList = new ArrayList<>(); + Map idAndDomain = getIdAndDomain(); + Map classFullPathMap = getClassFullPathMap(); + for (ClassDO classDO : classDOList) { + ClassResp classResp = convert2RespInternal(classDO, idAndDomain, classFullPathMap); + if (Objects.nonNull(classResp)) { + classRespList.add(classResp); + } + } + return classRespList; + } + + public Map getClassFullPathMap() { + Map classFullPathMap = new HashMap<>(); + List classDOList = classRepository.getAllClassDOList(); + Map classDOMap = classDOList.stream() + .collect(Collectors.toMap(ClassDO::getId, a -> a, (k1, k2) -> k1)); + for (ClassDO classDO : classDOList) { + final Long domainId = classDO.getId(); + StringBuilder fullPath = new StringBuilder(classDO.getBizName() + "/"); + Long parentId = classDO.getParentId(); + while (parentId != null && parentId > 0) { + classDO = classDOMap.get(parentId); + if (classDO == null) { + String message = String.format("get domain : %s failed", parentId); + throw new RuntimeException(message); + } + fullPath.insert(0, classDO.getBizName() + "/"); + parentId = classDO.getParentId(); + } + classFullPathMap.put(domainId, fullPath.toString()); + } + return classFullPathMap; + } + + public Map getIdAndDomain() { + return domainService.getDomainMap(); + } + + public Map getIdAndTagSet() { + return tagObjectService.getAllTagObjectMap(); + } + +} \ No newline at end of file