(improvement)(headless) add tag logic (#831)

This commit is contained in:
daikon
2024-03-19 19:40:06 +08:00
committed by GitHub
parent af53812d08
commit bd95552854
23 changed files with 448 additions and 761 deletions

View File

@@ -31,6 +31,7 @@ import com.tencent.supersonic.headless.server.pojo.yaml.MetricTypeParamsYamlTpl;
import com.tencent.supersonic.headless.server.pojo.yaml.MetricYamlTpl;
import com.tencent.supersonic.headless.server.service.Catalog;
import com.tencent.supersonic.headless.server.utils.DatabaseConverter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -41,6 +42,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.stereotype.Service;
@@ -123,12 +125,14 @@ public class SemanticSchemaManager {
private void addTagModel(TagResp tagResp, List<Dimension> modelDimensions, List<Metric> modelMetrics)
throws Exception {
switch (tagResp.getTagDefineType()) {
TagDefineType tagDefineType = TagDefineType.valueOf(tagResp.getTagDefineType());
switch (tagDefineType) {
case FIELD:
case DIMENSION:
if (TagDefineType.DIMENSION.equals(tagResp.getTagDefineType())) {
Optional<Dimension> modelDimension = modelDimensions.stream()
.filter(d -> d.getBizName().equals(tagResp.getExpr())).findFirst();
// .filter(d -> d.getBizName().equals(tagResp.getExpr()))
.findFirst();
if (modelDimension.isPresent()) {
modelDimension.get().setName(tagResp.getBizName());
return;
@@ -136,7 +140,7 @@ public class SemanticSchemaManager {
}
Dimension dimension = Dimension.builder().build();
dimension.setType("");
dimension.setExpr(tagResp.getExpr());
// dimension.setExpr(tagResp.getExpr());
dimension.setName(tagResp.getBizName());
dimension.setOwners("");
dimension.setBizName(tagResp.getBizName());
@@ -150,12 +154,12 @@ public class SemanticSchemaManager {
return;
case METRIC:
Optional<Metric> modelMetric = modelMetrics.stream()
.filter(m -> m.getName().equalsIgnoreCase(tagResp.getExpr())).findFirst();
// .filter(m -> m.getName().equalsIgnoreCase(tagResp.getExpr()))
.findFirst();
if (modelMetric.isPresent()) {
modelMetric.get().setName(tagResp.getBizName());
} else {
throw new Exception(String.format("tag [{}] cant find the metric [{}]", tagResp.getBizName(),
tagResp.getExpr()));
throw new Exception(String.format("tag [{}] cant find the metric", tagResp.getBizName()));
}
return;
default:

View File

@@ -14,37 +14,12 @@ public class TagDO {
private Long id;
/**
* 主体域ID
* itemID
*/
private Long modelId;
private Long itemId;
/**
* 标签名称
*/
private String name;
/**
* 标签业务名称
*/
private String bizName;
/**
* 描述
*/
private String description;
/**
* 指标状态,0正常,1下架,2删除
*/
private Integer status;
/**
* 敏感级别
*/
private Integer sensitiveLevel;
/**
* 类型 DERIVED,ATOMIC
* 标签类型
*/
private String type;
@@ -68,12 +43,4 @@ public class TagDO {
*/
private String updatedBy;
/**
* 类型参数
*/
private String defineType;
private String typeParams;
private String ext;
}

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.headless.server.persistence.mapper;
import com.tencent.supersonic.headless.api.pojo.response.TagResp;
import com.tencent.supersonic.headless.server.persistence.dataobject.TagDO;
import com.tencent.supersonic.headless.server.pojo.TagFilter;
import java.util.List;
@@ -7,7 +8,12 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TagCustomMapper {
List<TagDO> query(TagFilter tagFilter);
Boolean batchUpdateStatus(List<TagDO> tagDOList);
List<TagResp> queryTagRespList(TagFilter tagFilter);
List<TagDO> getTagDOList(TagFilter tagFilter);
Boolean deleteById(Long id);
void deleteBatch(List<Long> itemIds, List<Long> ids, String type);
}

View File

@@ -1,6 +1,8 @@
package com.tencent.supersonic.headless.server.persistence.repository;
import com.tencent.supersonic.headless.api.pojo.request.TagDeleteReq;
import com.tencent.supersonic.headless.api.pojo.response.TagResp;
import com.tencent.supersonic.headless.server.persistence.dataobject.TagDO;
import com.tencent.supersonic.headless.server.pojo.TagFilter;
import java.util.List;
@@ -14,7 +16,11 @@ public interface TagRepository {
TagDO getTagById(Long id);
List<TagDO> query(TagFilter tagFilter);
List<TagDO> getTagDOList(TagFilter tagFilter);
Boolean batchUpdateStatus(List<TagDO> tagDOList);
List<TagResp> queryTagRespList(TagFilter tagFilter);
Boolean delete(Long id);
void deleteBatch(TagDeleteReq tagDeleteReq);
}

View File

@@ -1,5 +1,7 @@
package com.tencent.supersonic.headless.server.persistence.repository.impl;
import com.tencent.supersonic.headless.api.pojo.request.TagDeleteReq;
import com.tencent.supersonic.headless.api.pojo.response.TagResp;
import com.tencent.supersonic.headless.server.persistence.dataobject.TagDO;
import com.tencent.supersonic.headless.server.persistence.mapper.TagCustomMapper;
import com.tencent.supersonic.headless.server.persistence.mapper.TagMapper;
@@ -38,12 +40,22 @@ public class TagRepositoryImpl implements TagRepository {
}
@Override
public List<TagDO> query(TagFilter tagFilter) {
return tagCustomMapper.query(tagFilter);
public List<TagDO> getTagDOList(TagFilter tagFilter) {
return tagCustomMapper.getTagDOList(tagFilter);
}
@Override
public Boolean batchUpdateStatus(List<TagDO> tagDOList) {
return tagCustomMapper.batchUpdateStatus(tagDOList);
public List<TagResp> queryTagRespList(TagFilter tagFilter) {
return tagCustomMapper.queryTagRespList(tagFilter);
}
@Override
public Boolean delete(Long id) {
return tagCustomMapper.deleteById(id);
}
@Override
public void deleteBatch(TagDeleteReq tagDeleteReq) {
tagCustomMapper.deleteBatch(tagDeleteReq.getItemIds(), tagDeleteReq.getIds(), tagDeleteReq.getType().name());
}
}

View File

@@ -1,17 +1,14 @@
package com.tencent.supersonic.headless.server.pojo;
import java.util.List;
import com.tencent.supersonic.headless.api.pojo.enums.TagDefineType;
import lombok.Data;
import java.util.List;
@Data
public class TagFilter extends MetaFilter {
private String type;
private List<Integer> statusList;
private List<Long> itemIds;
private TagDefineType tagDefineType;
private List<String> bizNames;
}

View File

@@ -1,13 +0,0 @@
package com.tencent.supersonic.headless.server.pojo;
import com.tencent.supersonic.headless.api.pojo.enums.TagDefineType;
import com.tencent.supersonic.headless.api.pojo.request.PageSchemaItemReq;
import java.util.List;
public class TagFilterPage extends PageSchemaItemReq {
private String type;
private List<Integer> statusList;
private TagDefineType tagDefineType;
}

View File

@@ -4,12 +4,13 @@ import com.github.pagehelper.PageInfo;
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.ItemValueReq;
import com.tencent.supersonic.headless.api.pojo.request.MetaBatchReq;
import com.tencent.supersonic.headless.api.pojo.request.TagBatchCreateReq;
import com.tencent.supersonic.headless.api.pojo.request.TagDeleteReq;
import com.tencent.supersonic.headless.api.pojo.request.TagFilterPageReq;
import com.tencent.supersonic.headless.api.pojo.request.TagReq;
import com.tencent.supersonic.headless.api.pojo.response.ItemValueResp;
import com.tencent.supersonic.headless.api.pojo.response.TagResp;
import com.tencent.supersonic.headless.server.pojo.TagFilterPage;
import com.tencent.supersonic.headless.server.persistence.dataobject.TagDO;
import com.tencent.supersonic.headless.server.pojo.TagFilter;
import com.tencent.supersonic.headless.server.service.TagMetaService;
import javax.servlet.http.HttpServletRequest;
@@ -24,12 +25,15 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/semantic/tag")
public class TagController {
private final TagMetaService tagMetaService;
private final TagQueryService tagQueryService;
public TagController(TagMetaService tagMetaService,
TagQueryService tagQueryService) {
this.tagMetaService = tagMetaService;
@@ -38,6 +42,7 @@ public class TagController {
/**
* 新建标签
*
* @param tagReq
* @param request
* @param response
@@ -46,61 +51,49 @@ public class TagController {
*/
@PostMapping("/create")
public TagResp create(@RequestBody TagReq tagReq,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
HttpServletRequest request,
HttpServletResponse response) throws Exception {
User user = UserHolder.findUser(request, response);
return tagMetaService.create(tagReq, user);
}
/**
* 从现有维度/指标批量新建标签
* @param tagBatchReq
*
* @param tagReqList
* @param request
* @param response
* @return
* @throws Exception
*/
@PostMapping("/create/batch")
public Integer createBatch(@RequestBody TagBatchCreateReq tagBatchReq,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
public Integer createBatch(@RequestBody List<TagReq> tagReqList,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
User user = UserHolder.findUser(request, response);
return tagMetaService.createBatch(tagBatchReq, user);
return tagMetaService.createBatch(tagReqList, user);
}
/**
* 编辑标签信息
* @param tagReq
* 批量删除标签
*
* @param tagDeleteReq
* @param request
* @param response
* @return
* @throws Exception
*/
@PostMapping("/update")
public TagResp update(@RequestBody TagReq tagReq,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
@PostMapping("/delete/batch")
public Boolean deleteBatch(@RequestBody TagDeleteReq tagDeleteReq,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
User user = UserHolder.findUser(request, response);
return tagMetaService.update(tagReq, user);
}
/**
* 批量更新标签状态
* @param metaBatchReq
* @param request
* @param response
* @return
*/
@PostMapping("/batchUpdateStatus")
public Boolean batchUpdateStatus(@RequestBody MetaBatchReq metaBatchReq,
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return tagMetaService.batchUpdateStatus(metaBatchReq, user);
return tagMetaService.deleteBatch(tagDeleteReq, user);
}
/**
* 标签删除
*
* @param id
* @param request
* @param response
@@ -109,8 +102,8 @@ public class TagController {
*/
@DeleteMapping("delete/{id}")
public Boolean delete(@PathVariable("id") Long id,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
tagMetaService.delete(id, user);
return true;
@@ -118,6 +111,7 @@ public class TagController {
/**
* 标签详情获取
*
* @param id
* @param request
* @param response
@@ -125,31 +119,33 @@ public class TagController {
*/
@GetMapping("getTag/{id}")
public TagResp getTag(@PathVariable("id") Long id,
HttpServletRequest request,
HttpServletResponse response) {
HttpServletRequest request,
HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
return tagMetaService.getTag(id, user);
}
/**
* 标签市场-分页查询
* @param tagFilterPage
* 标签查询
*
* @param tagFilter
* @param request
* @param response
* @return
* @throws Exception
*/
@PostMapping("/queryTag")
public PageInfo<TagResp> queryPage(@RequestBody TagFilterPage tagFilterPage,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
public List<TagDO> queryPage(@RequestBody TagFilter tagFilter,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
User user = UserHolder.findUser(request, response);
return tagMetaService.queryPage(tagFilterPage, user);
return tagMetaService.getTagDOList(tagFilter, user);
}
/**
* 获取标签值分布信息
*
* @param itemValueReq
* @param request
* @param response
@@ -164,4 +160,21 @@ public class TagController {
return tagQueryService.queryTagValue(itemValueReq, user);
}
/**
* 标签市场-分页查询
*
* @param tagMarketPageReq
* @param request
* @param response
* @return
* @throws Exception
*/
@PostMapping("/queryTag/market")
public PageInfo<TagResp> queryTagMarketPage(@RequestBody TagFilterPageReq tagMarketPageReq,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
User user = UserHolder.findUser(request, response);
return tagMetaService.queryTagMarketPage(tagMarketPageReq, user);
}
}

View File

@@ -2,29 +2,30 @@ package com.tencent.supersonic.headless.server.service;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.headless.api.pojo.request.MetaBatchReq;
import com.tencent.supersonic.headless.api.pojo.request.TagBatchCreateReq;
import com.tencent.supersonic.headless.api.pojo.request.TagDeleteReq;
import com.tencent.supersonic.headless.api.pojo.request.TagFilterPageReq;
import com.tencent.supersonic.headless.api.pojo.request.TagReq;
import com.tencent.supersonic.headless.api.pojo.response.TagResp;
import com.tencent.supersonic.headless.server.persistence.dataobject.TagDO;
import com.tencent.supersonic.headless.server.pojo.TagFilter;
import com.tencent.supersonic.headless.server.pojo.TagFilterPage;
import java.util.List;
public interface TagMetaService {
TagResp create(TagReq tagReq, User user);
TagResp update(TagReq tagReq, User user);
Integer createBatch(List<TagReq> tagReqList, User user);
void delete(Long id, User user);
Boolean delete(Long id, User user);
Boolean deleteBatch(TagDeleteReq tagDeleteReq, User user);
TagResp getTag(Long id, User user);
List<TagResp> getTags(TagFilter tagFilter);
PageInfo<TagResp> queryPage(TagFilterPage tagFilterPage, User user);
List<TagDO> getTagDOList(TagFilter tagFilter, User user);
Boolean batchUpdateStatus(MetaBatchReq metaBatchReq, User user);
Integer createBatch(TagBatchCreateReq tagBatchReq, User user);
PageInfo<TagResp> queryTagMarketPage(TagFilterPageReq tagMarketPageReq, User user);
}

View File

@@ -1,40 +1,34 @@
package com.tencent.supersonic.headless.server.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.common.pojo.Constants;
import com.tencent.supersonic.common.pojo.DataEvent;
import com.tencent.supersonic.common.pojo.DataItem;
import com.tencent.supersonic.common.pojo.enums.AuthType;
import com.tencent.supersonic.common.pojo.enums.EventType;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
import com.tencent.supersonic.headless.api.pojo.SchemaElementType;
import com.tencent.supersonic.headless.api.pojo.TagDefineParams;
import com.tencent.supersonic.headless.api.pojo.enums.TagDefineType;
import com.tencent.supersonic.headless.api.pojo.request.MetaBatchReq;
import com.tencent.supersonic.headless.api.pojo.request.TagBatchCreateReq;
import com.tencent.supersonic.headless.api.pojo.request.TagDeleteReq;
import com.tencent.supersonic.headless.api.pojo.request.TagFilterPageReq;
import com.tencent.supersonic.headless.api.pojo.request.TagReq;
import com.tencent.supersonic.headless.api.pojo.response.DimensionResp;
import com.tencent.supersonic.headless.api.pojo.response.DomainResp;
import com.tencent.supersonic.headless.api.pojo.response.MetricResp;
import com.tencent.supersonic.headless.api.pojo.response.ModelResp;
import com.tencent.supersonic.headless.api.pojo.response.TagObjectResp;
import com.tencent.supersonic.headless.api.pojo.response.TagResp;
import com.tencent.supersonic.headless.server.persistence.dataobject.CollectDO;
import com.tencent.supersonic.headless.server.persistence.dataobject.TagDO;
import com.tencent.supersonic.headless.server.persistence.repository.TagRepository;
import com.tencent.supersonic.headless.server.pojo.MetaFilter;
import com.tencent.supersonic.headless.server.pojo.TagFilter;
import com.tencent.supersonic.headless.server.pojo.TagFilterPage;
import com.tencent.supersonic.headless.server.pojo.TagObjectFilter;
import com.tencent.supersonic.headless.server.service.CollectService;
import com.tencent.supersonic.headless.server.service.DimensionService;
import com.tencent.supersonic.headless.server.service.DomainService;
import com.tencent.supersonic.headless.server.service.MetricService;
import com.tencent.supersonic.headless.server.service.ModelService;
import com.tencent.supersonic.headless.server.service.TagMetaService;
import com.tencent.supersonic.headless.server.utils.NameCheckUtils;
import com.tencent.supersonic.headless.server.service.TagObjectService;
import java.util.ArrayList;
import java.util.Arrays;
@@ -47,10 +41,7 @@ import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -61,189 +52,186 @@ public class TagMetaServiceImpl implements TagMetaService {
private final TagRepository tagRepository;
private final ModelService modelService;
private final CollectService collectService;
private ApplicationEventPublisher eventPublisher;
private final DimensionService dimensionService;
private final MetricService metricService;
private final TagObjectService tagObjectService;
private final DomainService domainService;
public TagMetaServiceImpl(TagRepository tagRepository, ModelService modelService,
CollectService collectService, ApplicationEventPublisher eventPublisher,
@Lazy DimensionService dimensionService, @Lazy MetricService metricService) {
CollectService collectService, @Lazy DimensionService dimensionService,
@Lazy MetricService metricService, TagObjectService tagObjectService,
DomainService domainService) {
this.tagRepository = tagRepository;
this.modelService = modelService;
this.collectService = collectService;
this.eventPublisher = eventPublisher;
this.dimensionService = dimensionService;
this.metricService = metricService;
this.tagObjectService = tagObjectService;
this.domainService = domainService;
}
@Override
public TagResp create(TagReq tagReq, User user) {
checkParam(tagReq);
checkExit(tagReq);
TagDO tagDO = convert(tagReq);
Date date = new Date();
tagDO.setId(null);
tagDO.setCreatedBy(user.getName());
tagDO.setCreatedAt(date);
tagDO.setUpdatedBy(user.getName());
tagDO.setUpdatedAt(date);
if (Objects.nonNull(tagReq.getStatus())) {
tagDO.setStatus(tagReq.getStatus());
} else {
tagDO.setStatus(StatusEnum.ONLINE.getCode());
}
tagRepository.create(tagDO);
sendEventBatch(Lists.newArrayList(tagDO), EventType.ADD);
return convert(tagDO);
}
private void sendEventBatch(List<TagDO> tagDOS, EventType eventType) {
List<DataItem> dataItems = tagDOS.stream().map(this::getDataItem)
.collect(Collectors.toList());
eventPublisher.publishEvent(new DataEvent(this, dataItems, eventType));
}
private void sendEvent(DataItem dataItem, EventType eventType) {
eventPublisher.publishEvent(new DataEvent(this,
Lists.newArrayList(dataItem), eventType));
}
private DataItem getDataItem(TagDO tagDO) {
return DataItem.builder().id(tagDO.getId() + Constants.UNDERLINE).name(tagDO.getName())
.bizName(tagDO.getBizName()).modelId(tagDO.getModelId() + Constants.UNDERLINE)
.type(TypeEnums.TAG).build();
return convert2Resp(tagDO);
}
@Override
public TagResp update(TagReq tagReq, User user) {
if (Objects.isNull(tagReq.getId()) || tagReq.getId() <= 0) {
throw new RuntimeException("id is empty");
}
TagDO tagDO = tagRepository.getTagById(tagReq.getId());
String oldName = tagDO.getName();
tagDO = fillUpdateInfo(tagReq, tagDO);
tagDO.setUpdatedBy(user.getName());
tagDO.setUpdatedAt(new Date());
tagRepository.update(tagDO);
if (!oldName.equals(tagReq.getName())) {
DataItem dataItem = getDataItem(tagDO);
dataItem.setName(oldName);
dataItem.setNewName(tagReq.getName());
sendEvent(getDataItem(tagDO), EventType.UPDATE);
}
return convert(tagDO);
public Integer createBatch(List<TagReq> tagReqList, User user) {
tagReqList.stream().forEach(tagReq -> {
create(tagReq, user);
});
return tagReqList.size();
}
@Override
public void delete(Long id, User user) {
TagDO tagDO = tagRepository.getTagById(id);
if (Objects.isNull(tagDO)) {
throw new RuntimeException("tag not found");
}
tagDO.setStatus(StatusEnum.DELETED.getCode());
tagDO.setUpdatedBy(user.getName());
tagDO.setUpdatedAt(new Date());
tagRepository.update(tagDO);
sendEventBatch(Lists.newArrayList(tagDO), EventType.DELETE);
public Boolean delete(Long id, User user) {
tagRepository.delete(id);
return true;
}
@Override
public Boolean deleteBatch(TagDeleteReq tagDeleteReq, User user) {
tagRepository.deleteBatch(tagDeleteReq);
return true;
}
@Override
public TagResp getTag(Long id, User user) {
TagDO tagDO = tagRepository.getTagById(id);
TagResp tagResp = fillCollectAndAdminInfo(tagDO, user);
tagResp = fillModelInfo(tagResp);
TagResp tagResp = convert2Resp(tagDO);
tagResp = fillTagObjectInfo(tagResp, user);
tagResp = fillCollectAndAdminInfo(tagResp, user);
return tagResp;
}
@Override
public List<TagResp> getTags(TagFilter tagFilter) {
List<TagDO> tagDOS = tagRepository.query(tagFilter);
if (!CollectionUtils.isEmpty(tagDOS)) {
return tagDOS.stream().map(tagDO -> convert(tagDO)).collect(Collectors.toList());
}
return new ArrayList<>();
List<TagResp> tagRespList = tagRepository.queryTagRespList(tagFilter);
return tagRespList;
}
@Override
public PageInfo<TagResp> queryPage(TagFilterPage tagFilterPage, User user) {
TagFilter tagFilter = new TagFilter();
BeanUtils.copyProperties(tagFilterPage, tagFilter);
List<ModelResp> modelRespList = modelService.getAllModelByDomainIds(tagFilterPage.getDomainIds());
List<Long> modelIds = modelRespList.stream().map(ModelResp::getId).collect(Collectors.toList());
tagFilterPage.getModelIds().addAll(modelIds);
tagFilter.setModelIds(tagFilterPage.getModelIds());
public List<TagDO> getTagDOList(TagFilter tagFilter, User user) {
return tagRepository.getTagDOList(tagFilter);
}
List<CollectDO> collectList = collectService.getCollectList(user.getName())
.stream().filter(collectDO -> TypeEnums.TAG.name().equalsIgnoreCase(collectDO.getType()))
.collect(Collectors.toList());
List<Long> collectIds = collectList.stream().map(CollectDO::getCollectId).collect(Collectors.toList());
if (tagFilterPage.isHasCollect()) {
if (CollectionUtils.isEmpty(collectIds)) {
tagFilter.setIds(Lists.newArrayList(-1L));
} else {
tagFilter.setIds(collectIds);
/**
* 分页查询标签列表信息
*
* @param tagMarketPageReq
* @param user
* @return
*/
@Override
public PageInfo<TagResp> queryTagMarketPage(TagFilterPageReq tagMarketPageReq, User user) {
List<ModelResp> modelRespList = getRelatedModel(tagMarketPageReq);
List<Long> modelIds = modelRespList.stream().map(model -> model.getId()).collect(Collectors.toList());
TagFilter tagFilter = new TagFilter();
BeanUtils.copyProperties(tagMarketPageReq, tagFilter);
tagFilter.setModelIds(modelIds);
PageInfo<TagResp> tagDOPageInfo = PageHelper.startPage(tagMarketPageReq.getCurrent(),
tagMarketPageReq.getPageSize())
.doSelectPageInfo(() -> getTags(tagFilter));
List<TagResp> tagRespList = tagDOPageInfo.getList();
fillModelInfo(tagRespList);
fillDomainInfo(tagRespList);
fillTagObjectInfo(tagRespList, user);
return tagDOPageInfo;
}
private void fillTagObjectInfo(List<TagResp> tagRespList, User user) {
TagObjectFilter filter = new TagObjectFilter();
List<TagObjectResp> tagObjects = tagObjectService.getTagObjects(filter, user);
if (CollectionUtils.isEmpty(tagObjects)) {
return;
}
Map<Long, TagObjectResp> tagObjectMap = tagObjects.stream()
.collect(Collectors.toMap(TagObjectResp::getId, tagObject -> tagObject, (v1, v2) -> v2));
if (CollectionUtils.isNotEmpty(tagRespList)) {
tagRespList.stream().forEach(tagResp -> {
if (tagObjectMap.containsKey(tagResp.getTagObjectId())) {
tagResp.setTagObjectName(tagObjectMap.get(tagResp.getTagObjectId()).getName());
}
});
}
}
private TagResp fillTagObjectInfo(TagResp tagResp, User user) {
Long modelId = tagResp.getModelId();
ModelResp model = modelService.getModel(modelId);
TagObjectResp tagObject = tagObjectService.getTagObject(model.getTagObjectId(), user);
tagResp.setTagObjectId(tagObject.getId());
tagResp.setTagObjectName(tagObject.getName());
return tagResp;
}
private void fillDomainInfo(List<TagResp> tagRespList) {
Map<Long, DomainResp> domainMap = domainService.getDomainList().stream()
.collect(Collectors.toMap(DomainResp::getId, domain -> domain, (v1, v2) -> v2));
if (CollectionUtils.isNotEmpty(tagRespList) && Objects.nonNull(domainMap)) {
tagRespList.stream().forEach(tagResp -> {
if (domainMap.containsKey(tagResp.getDomainId())) {
tagResp.setDomainName(domainMap.get(tagResp.getDomainId()).getName());
}
});
}
}
private TagResp convert2Resp(TagDO tagDO) {
TagResp tagResp = new TagResp();
BeanUtils.copyProperties(tagDO, tagResp);
if (TagDefineType.METRIC.name().equalsIgnoreCase(tagDO.getType())) {
MetricResp metric = metricService.getMetric(tagDO.getItemId());
tagResp.setBizName(metric.getBizName());
tagResp.setName(metric.getName());
tagResp.setModelId(metric.getModelId());
tagResp.setModelName(metric.getModelName());
tagResp.setDomainId(metric.getDomainId());
}
if (TagDefineType.DIMENSION.name().equalsIgnoreCase(tagDO.getType())) {
DimensionResp dimensionResp = dimensionService.getDimension(tagDO.getItemId());
tagResp.setBizName(dimensionResp.getBizName());
tagResp.setName(dimensionResp.getName());
tagResp.setModelId(dimensionResp.getModelId());
tagResp.setModelName(dimensionResp.getModelName());
}
return tagResp;
}
private List<ModelResp> getRelatedModel(TagFilterPageReq tagMarketPageReq) {
List<ModelResp> modelRespList = new ArrayList<>();
Map<Long, ModelResp> modelMap = modelService.getModelMap();
for (Long modelId : modelMap.keySet()) {
ModelResp modelResp = modelMap.get(modelId);
if (Objects.isNull(modelResp)) {
continue;
}
if (tagMarketPageReq.getTagObjectId().equals(modelResp.getTagObjectId())) {
if (CollectionUtils.isNotEmpty(tagMarketPageReq.getDomainIds())) {
if (!tagMarketPageReq.getDomainIds().contains(modelResp.getDomainId())) {
continue;
}
}
if (CollectionUtils.isNotEmpty(tagMarketPageReq.getModelIds())) {
if (!tagMarketPageReq.getModelIds().contains(modelResp.getId())) {
continue;
}
}
modelRespList.add(modelResp);
}
}
PageInfo<TagDO> tagDOPageInfo = PageHelper.startPage(tagFilterPage.getCurrent(),
tagFilterPage.getPageSize())
.doSelectPageInfo(() -> getTags(tagFilter));
PageInfo<TagResp> pageInfo = new PageInfo<>();
BeanUtils.copyProperties(tagDOPageInfo, pageInfo);
List<TagResp> tagRespList = convertList(tagDOPageInfo.getList(), collectIds);
fillAdminRes(tagRespList, user);
fillModelInfo(tagRespList);
pageInfo.setList(tagRespList);
return pageInfo;
}
@Override
public Boolean batchUpdateStatus(MetaBatchReq metaBatchReq, User user) {
if (Objects.isNull(metaBatchReq)) {
return false;
}
TagFilter tagFilter = new TagFilter();
BeanUtils.copyProperties(metaBatchReq, tagFilter);
tagFilter.setStatus(null);
List<TagDO> tagDOList = tagRepository.query(tagFilter);
log.info("tagFilter:{},{}", tagFilter.getModelIds(), tagFilter.getBizNames());
if (CollectionUtils.isEmpty(tagDOList)) {
return true;
}
tagDOList.stream().forEach(tagDO -> {
tagDO.setStatus(metaBatchReq.getStatus());
tagDO.setUpdatedAt(new Date());
tagDO.setUpdatedBy(user.getName());
});
tagRepository.batchUpdateStatus(tagDOList);
if (StatusEnum.OFFLINE.getCode().equals(metaBatchReq.getStatus())
|| StatusEnum.DELETED.getCode().equals(metaBatchReq.getStatus())) {
sendEventBatch(tagDOList, EventType.DELETE);
} else if (StatusEnum.ONLINE.getCode().equals(metaBatchReq.getStatus())) {
sendEventBatch(tagDOList, EventType.ADD);
}
return true;
}
@Override
public Integer createBatch(TagBatchCreateReq tagLoadReq, User user) {
Long modelId = tagLoadReq.getModelId();
int num = 0;
MetaFilter metaFilter = new MetaFilter();
List<Long> modelIds = new ArrayList<>();
modelIds.add(modelId);
metaFilter.setModelIds(modelIds);
if (Objects.isNull(tagLoadReq.getType()) || SchemaElementType.DIMENSION.equals(tagLoadReq.getType())) {
List<DimensionResp> dimensions = dimensionService.getDimensions(metaFilter);
num += loadDimTagBatch(tagLoadReq, dimensions, user);
}
if (Objects.isNull(tagLoadReq.getType()) || SchemaElementType.METRIC.equals(tagLoadReq.getType())) {
List<MetricResp> metrics = metricService.getMetrics(metaFilter);
num += loadMetricTagBatch(tagLoadReq, metrics, user);
}
log.info("loadTagBatch finished ,tag num:{}", num);
return num;
return modelRespList;
}
private int loadMetricTagBatch(TagBatchCreateReq tagLoadReq, List<MetricResp> metrics, User user) {
@@ -255,12 +243,10 @@ public class TagMetaServiceImpl implements TagMetaService {
TagReq tagReq = new TagReq();
BeanUtils.copyProperties(metric, tagReq);
tagReq.setId(null);
tagReq.setBizName(metric.getBizName());
tagReq.setTagDefineType(TagDefineType.METRIC);
TagDefineParams tagDefineParams = new TagDefineParams();
tagDefineParams.setExpr(metric.getBizName());
tagDefineParams.setDependencies(new ArrayList<>(Arrays.asList(metric.getId())));
tagReq.setTagDefineParams(tagDefineParams);
try {
create(tagReq, user);
} catch (Exception e) {
@@ -279,12 +265,10 @@ public class TagMetaServiceImpl implements TagMetaService {
TagReq tagReq = new TagReq();
BeanUtils.copyProperties(dim, tagReq);
tagReq.setId(null);
tagReq.setBizName(dim.getBizName());
tagReq.setTagDefineType(TagDefineType.DIMENSION);
TagDefineParams tagDefineParams = new TagDefineParams();
tagDefineParams.setExpr(dim.getBizName());
tagDefineParams.setDependencies(new ArrayList<>(Arrays.asList(dim.getId())));
tagReq.setTagDefineParams(tagDefineParams);
try {
create(tagReq, user);
} catch (Exception e) {
@@ -295,35 +279,6 @@ public class TagMetaServiceImpl implements TagMetaService {
return dimensions.size();
}
private TagDO fillUpdateInfo(TagReq tagReq, TagDO tagDO) {
if (Objects.nonNull(tagDO) && tagDO.getId() > 0) {
if (Objects.nonNull(tagReq.getExt()) && !tagReq.getExt().isEmpty()) {
tagDO.setExt(tagReq.getExtJson());
}
}
if (Objects.nonNull(tagReq.getTagDefineType())) {
tagDO.setDefineType(tagReq.getTagDefineType().name());
}
if (Objects.nonNull(tagReq.getTagDefineParams()) && !StringUtils.isBlank(
tagReq.getTagDefineParams().getExpr())) {
tagDO.setTypeParams(tagReq.getTypeParamsJson());
}
if (Strings.isNotEmpty(tagReq.getDescription())) {
tagDO.setDescription(tagReq.getDescription());
}
if (Objects.nonNull(tagReq.getSensitiveLevel())) {
tagDO.setSensitiveLevel(tagReq.getSensitiveLevel());
}
if (Strings.isNotEmpty(tagReq.getName())) {
tagDO.setName(tagReq.getName());
}
if (Objects.nonNull(tagReq.getStatus())) {
tagDO.setStatus(tagReq.getStatus());
}
return tagDO;
}
private TagResp fillModelInfo(TagResp tagResp) {
ModelResp model = modelService.getModel(tagResp.getModelId());
tagResp.setModelName(model.getName());
@@ -337,16 +292,19 @@ public class TagMetaServiceImpl implements TagMetaService {
if (Objects.nonNull(modelIdAndRespMap) && modelIdAndRespMap.containsKey(tagResp.getModelId())) {
tagResp.setModelName(modelIdAndRespMap.get(tagResp.getModelId()).getName());
tagResp.setDomainId(modelIdAndRespMap.get(tagResp.getModelId()).getDomainId());
tagResp.setTagObjectId(modelIdAndRespMap.get(tagResp.getModelId()).getTagObjectId());
}
});
}
private TagResp fillCollectAndAdminInfo(TagDO tagDO, User user) {
private TagResp fillCollectAndAdminInfo(TagResp tagResp, User user) {
List<Long> collectIds = collectService.getCollectList(user.getName())
.stream().filter(collectDO -> TypeEnums.TAG.name().equalsIgnoreCase(collectDO.getType()))
.map(CollectDO::getCollectId).collect(Collectors.toList());
List<TagResp> tagRespList = convertList(new ArrayList<>(Arrays.asList(tagDO)), collectIds);
if (CollectionUtils.isNotEmpty(collectIds) && collectIds.contains(tagResp.getId())) {
tagResp.setIsCollect(true);
}
List<TagResp> tagRespList = Arrays.asList(tagResp);
fillAdminRes(tagRespList, user);
return tagRespList.get(0);
}
@@ -366,85 +324,23 @@ public class TagMetaServiceImpl implements TagMetaService {
}
}
private List<TagResp> convertList(List<TagDO> tagDOList, List<Long> collectIds) {
List<TagResp> tagRespList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(tagDOList)) {
tagDOList.stream().forEach(tagDO -> {
TagResp tagResp = convert(tagDO);
tagResp.setTypeEnum(TypeEnums.TAG);
if (CollectionUtils.isNotEmpty(collectIds) && collectIds.contains(tagDO.getId())) {
tagResp.setIsCollect(true);
} else {
tagResp.setIsCollect(false);
}
tagRespList.add(tagResp);
});
}
return tagRespList;
}
private void checkExit(TagReq tagReq) {
TagFilter tagFilter = new TagFilter();
tagFilter.setModelIds(Arrays.asList(tagReq.getModelId()));
List<TagResp> tagResps = getTags(tagFilter);
if (!CollectionUtils.isEmpty(tagResps)) {
Long bizNameSameCount = tagResps.stream().filter(tagResp -> !tagResp.getId().equals(tagReq.getId()))
.filter(tagResp -> tagResp.getBizName().equalsIgnoreCase(tagReq.getBizName())).count();
if (bizNameSameCount > 0) {
throw new RuntimeException(String.format("the bizName %s is exit", tagReq.getBizName()));
}
Long nameSameCount = tagResps.stream().filter(tagResp -> !tagResp.getId().equals(tagReq.getId()))
.filter(tagResp -> tagResp.getName().equalsIgnoreCase(tagReq.getName())).count();
if (nameSameCount > 0) {
throw new RuntimeException(String.format("the name %s is exit", tagReq.getName()));
}
}
}
private void checkParam(TagReq tagReq) {
if (Objects.isNull(tagReq.getModelId()) || tagReq.getModelId() <= 0) {
throw new RuntimeException("the modelId is empty");
}
if (Objects.isNull(tagReq.getBizName()) || tagReq.getBizName().isEmpty() || Objects.isNull(tagReq.getName())
|| tagReq.getName().isEmpty()) {
throw new RuntimeException("the bizName or name is empty");
}
if (Objects.isNull(tagReq.getTagDefineType()) || Objects.isNull(tagReq.getTagDefineParams())
|| StringUtils.isBlank(tagReq.getTagDefineParams().getExpr())) {
throw new InvalidArgumentException("表达式不可为空");
tagFilter.setTagDefineType(tagReq.getTagDefineType());
if (Objects.nonNull(tagReq.getItemId())) {
tagFilter.setItemIds(Arrays.asList(tagReq.getItemId()));
}
if (NameCheckUtils.containsSpecialCharacters(tagReq.getBizName())) {
throw new InvalidArgumentException("名称包含特殊字符, 请修改");
List<TagDO> tagRespList = tagRepository.getTagDOList(tagFilter);
if (!CollectionUtils.isEmpty(tagRespList)) {
throw new RuntimeException(String.format("the tag is exit, itemId:{}", tagReq.getItemId()));
}
}
private TagResp convert(TagDO tagDO) {
TagResp tagResp = new TagResp();
BeanUtils.copyProperties(tagDO, tagResp);
if (Objects.nonNull(tagDO.getExt()) && !tagDO.getExt().isEmpty()) {
Map<String, Object> ext = JSONObject.parseObject(tagDO.getExt(),
Map.class);
tagResp.setExt(ext);
}
tagResp.setTagDefineType(TagDefineType.valueOf(tagDO.getDefineType()));
if (Objects.nonNull(tagDO.getTypeParams()) && !tagDO.getTypeParams().isEmpty()) {
TagDefineParams tagDefineParams = JSONObject.parseObject(tagDO.getTypeParams(),
TagDefineParams.class);
tagResp.setTagDefineParams(tagDefineParams);
}
return tagResp;
}
private TagDO convert(TagReq tagReq) {
TagDO tagDO = new TagDO();
BeanUtils.copyProperties(tagReq, tagDO);
tagDO.setDefineType(tagReq.getTagDefineType().name());
tagDO.setType(tagReq.getType().name());
tagDO.setTypeParams(tagReq.getTypeParamsJson());
tagDO.setExt(tagReq.getExtJson());
tagDO.setType(tagReq.getTagDefineType().name());
return tagDO;
}
}

View File

@@ -58,7 +58,7 @@ public class TagObjectServiceImpl implements TagObjectService {
throw new Exception(String.format("the bizName %s is exit", tagObjectReq.getBizName()));
}
if (tagObject.getName().equalsIgnoreCase(tagObjectReq.getName())) {
throw new Exception(String.format("the bizName %s is exit", tagObjectReq.getName()));
throw new Exception(String.format("the name %s is exit", tagObjectReq.getName()));
}
}
}

View File

@@ -2,129 +2,132 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tencent.supersonic.headless.server.persistence.mapper.TagCustomMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.headless.server.persistence.dataobject.TagDO">
<resultMap id="BaseTagDO" type="com.tencent.supersonic.headless.server.persistence.dataobject.TagDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="model_id" jdbcType="BIGINT" property="modelId" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="biz_name" jdbcType="VARCHAR" property="bizName" />
<result column="description" jdbcType="VARCHAR" property="description" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="sensitive_level" jdbcType="INTEGER" property="sensitiveLevel" />
<result column="item_id" jdbcType="BIGINT" property="itemId" />
<result column="type" jdbcType="VARCHAR" property="type" />
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
<result column="define_type" jdbcType="VARCHAR" property="defineType" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.headless.server.persistence.dataobject.TagDO">
<result column="type_params" jdbcType="LONGVARCHAR" property="typeParams" />
<resultMap id="TagResp" type="com.tencent.supersonic.headless.api.pojo.response.TagResp">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="domain_id" jdbcType="BIGINT" property="domainId" />
<result column="domain_name" jdbcType="VARCHAR" property="domainName" />
<result column="model_id" jdbcType="BIGINT" property="modelId" />
<result column="model_name" jdbcType="VARCHAR" property="modelName" />
<result column="tag_object_id" jdbcType="BIGINT" property="tagObjectId" />
<result column="tag_object_name" jdbcType="VARCHAR" property="tagObjectName" />
<result column="tag_define_type" jdbcType="VARCHAR" property="tagDefineType" />
<result column="item_id" jdbcType="VARCHAR" property="itemId" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="biz_name" jdbcType="VARCHAR" property="bizName" />
<result column="description" jdbcType="VARCHAR" property="description" />
</resultMap>
<sql id="Example_Where_Clause">
<select id="getTagDOList" resultMap="BaseTagDO">
select * from s2_tag
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and
#{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem"
open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
<if test="itemIds != null and itemIds.size >0">
and item_id in
<foreach collection="itemIds" index="index" item="itemId" open="(" close=")"
separator=",">
#{itemId}
</foreach>
</if>
<if test="ids != null and ids.size >0">
and id in
<foreach collection="ids" index="index" item="tagId" open="(" close=")"
separator=",">
#{tagId}
</foreach>
</if>
<if test="tagDefineType != null">
and tag_define_type = #{tagDefineType}
</if>
</where>
</sql>
<sql id="Base_Column_List">
id, model_id, name, biz_name, description, status, sensitive_level, type, created_at,
created_by, updated_at, updated_by, define_type
</sql>
<sql id="Blob_Column_List">
type_params
</sql>
</select>
<select id="queryTagRespList" resultMap="TagResp">
select * from (
select s2_tag.id as id, s2_dimension.model_id as model_id, "DIMENSION" as tag_define_type, s2_dimension.id as item_id,
s2_dimension.name as name, s2_dimension.biz_name as biz_name, s2_dimension.description as description, s2_tag.updated_at as updated_at
from s2_tag join s2_dimension
on s2_tag.item_id = s2_dimension.id
where s2_dimension.status=1
union
select s2_tag.id as id, s2_metric.model_id as model_id, "METRIC" as tag_define_type, s2_metric.id as item_id,
s2_metric.name as name, s2_metric.biz_name as biz_name, s2_metric.description as description, s2_tag.updated_at as updated_at
from s2_tag join s2_metric
on s2_tag.item_id = s2_metric.id
where s2_metric.status=1
)t
<where>
<if test="tagDefineType != null">
and tag_define_type = #{tagDefineType}
</if>
<if test="itemIds != null and itemIds.size >0">
and item_id in
<foreach collection="itemIds" index="index" item="itemId" open="(" close=")"
separator=",">
#{itemId}
</foreach>
</if>
<if test="ids != null and ids.size >0">
and id in
<foreach collection="ids" index="index" item="tagId" open="(" close=")"
separator=",">
#{tagId}
</foreach>
</if>
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="bizName != null and bizName != ''">
and biz_Name = #{bizName}
</if>
<if test="modelIds != null and modelIds.size >0">
and model_id in
<foreach collection="modelIds" index="index" item="modelId" open="(" close=")"
separator=",">
#{modelId}
</foreach>
</if>
<if test="key != null and key != ''">
and ( id like CONCAT('%',#{key , jdbcType=VARCHAR},'%') or
name like CONCAT('%',#{key , jdbcType=VARCHAR},'%') or
biz_name like CONCAT('%',#{key , jdbcType=VARCHAR},'%') or
description like CONCAT('%',#{key , jdbcType=VARCHAR},'%'))
</if>
</where>
order by updated_at desc
</select>
<select id="query" resultMap="ResultMapWithBLOBs">
select *
from s2_tag
where status != 3
<if test="type != null and type != ''">
and type = #{type}
</if>
<if test="tagDefineType != null">
and define_type = #{tagDefineType}
</if>
<if test="key != null and key != ''">
and ( id like CONCAT('%',#{key , jdbcType=VARCHAR},'%') or
name like CONCAT('%',#{key , jdbcType=VARCHAR},'%') or
biz_name like CONCAT('%',#{key , jdbcType=VARCHAR},'%') or
description like CONCAT('%',#{key , jdbcType=VARCHAR},'%'))
</if>
<if test="id != null">
and id like CONCAT('%',#{id , jdbcType=VARCHAR},'%')
</if>
<if test="name != null and name != '' ">
and name like CONCAT('%',#{name , jdbcType=VARCHAR},'%')
</if>
<if test="bizName != null and bizName != ''">
and biz_name like CONCAT('%',#{bizName , jdbcType=VARCHAR},'%')
</if>
<if test="sensitiveLevel != null">
and sensitive_level = #{sensitiveLevel}
</if>
<if test="status != null">
and status = #{status}
</if>
<if test="modelIds != null and modelIds.size >0">
and model_id in
<foreach collection="modelIds" index="index" item="model" open="(" close=")"
<delete id="deleteById">
delete from s2_tag where id = #{id}
</delete>
<delete id="deleteBatch">
delete from s2_tag
where type = #{type}
<if test="itemIds != null and itemIds.size >0">
and item_id in
<foreach collection="itemIds" index="index" item="itemId" open="(" close=")"
separator=",">
#{model}
#{itemId}
</foreach>
</if>
<if test="ids != null and ids.size >0">
and id in
<foreach collection="ids" index="index" item="id" open="(" close=")"
<foreach collection="ids" index="index" item="tagId" open="(" close=")"
separator=",">
#{id}
#{tagId}
</foreach>
</if>
<if test="bizNames != null and bizNames.size >0">
and biz_name in
<foreach collection="bizNames" index="index" item="bizName" open="(" close=")"
separator=",">
#{bizName}
</foreach>
</if>
<if test="createdBy != null">
and created_by = #{createdBy}
</if>
</select>
<update id="batchUpdateStatus" parameterType="java.util.List">
<foreach collection="list" item="tag" separator=";">
update s2_tag
set status = #{tag.status,jdbcType=INTEGER},
updated_at = #{tag.updatedAt,jdbcType=TIMESTAMP},
updated_by = #{tag.updatedBy,jdbcType=VARCHAR}
where id = #{tag.id,jdbcType=BIGINT}
</foreach>
</update>
</delete>
</mapper>