最新一版9.0
parent
c87c4a8bac
commit
f5bdf00167
|
@ -3,12 +3,14 @@ package net.srt.controller;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.srt.framework.common.cache.bean.Neo4jInfo;
|
||||||
import net.srt.framework.common.utils.Result;
|
import net.srt.framework.common.utils.Result;
|
||||||
import net.srt.framework.common.utils.TreeNodeVo;
|
import net.srt.framework.common.utils.TreeNodeVo;
|
||||||
import net.srt.service.MetadataService;
|
import net.srt.service.MetadataService;
|
||||||
import net.srt.vo.MetadataVO;
|
import net.srt.vo.MetadataVO;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -58,4 +60,31 @@ public class MetadataController {
|
||||||
metadataService.save(vo);
|
metadataService.save(vo);
|
||||||
return Result.ok();
|
return Result.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@Operation(summary = "修改")
|
||||||
|
public Result<String> update(@RequestBody @Valid MetadataVO vo) {
|
||||||
|
metadataService.update(vo);
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("{id}")
|
||||||
|
@Operation(summary = "删除")
|
||||||
|
public Result<String> delete(@PathVariable Long id) {
|
||||||
|
metadataService.delete(id);
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/neo4j")
|
||||||
|
@Operation(summary = "更新neo4j的url")
|
||||||
|
public Result<String> upNeo4jInfo(@RequestBody Neo4jInfo neo4jInfo){
|
||||||
|
metadataService.upNeo4jInfo(neo4jInfo);
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/neo4j")
|
||||||
|
@Operation(summary = "获取neo4j的url")
|
||||||
|
public Result<Neo4jInfo> getNeo4jInfo(){
|
||||||
|
return Result.ok(metadataService.getNeo4jInfo());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,15 @@ package net.srt.controller;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.srt.convert.MetadataPropertyConvert;
|
||||||
|
import net.srt.entity.MetadataPropertyEntity;
|
||||||
import net.srt.framework.common.utils.Result;
|
import net.srt.framework.common.utils.Result;
|
||||||
import net.srt.service.MetadataPropertyService;
|
import net.srt.service.MetadataPropertyService;
|
||||||
import net.srt.vo.MetadataPropertyVo;
|
import net.srt.vo.MetadataPropertyVo;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import javax.validation.Valid;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("metadata-property")
|
@RequestMapping("metadata-property")
|
||||||
|
@ -21,6 +23,29 @@ public class MetadataPropertyController {
|
||||||
@GetMapping("{id}")
|
@GetMapping("{id}")
|
||||||
@Operation(summary = "信息")
|
@Operation(summary = "信息")
|
||||||
public Result<MetadataPropertyVo> get(@PathVariable("id") Long id) {
|
public Result<MetadataPropertyVo> get(@PathVariable("id") Long id) {
|
||||||
return Result.ok();
|
MetadataPropertyEntity entity = metadataPropertyService.getById(id);
|
||||||
|
return Result.ok(MetadataPropertyConvert.INSTANCE.convert(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@Operation(summary = "保存")
|
||||||
|
public Result<String> save(@RequestBody MetadataPropertyVo vo){
|
||||||
|
metadataPropertyService.save(vo);
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@Operation(summary = "修改")
|
||||||
|
public Result<String> update(@RequestBody @Valid MetadataPropertyVo vo){
|
||||||
|
metadataPropertyService.update(vo);
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
@Operation(summary = "删除")
|
||||||
|
public Result<String> delete(@RequestBody List<Long> idList){
|
||||||
|
metadataPropertyService.delete(idList);
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package net.srt.convert;
|
||||||
|
|
||||||
|
import net.srt.api.module.data.governance.dto.DataGovernanceMetadataPropertyDto;
|
||||||
|
import net.srt.entity.MetadataPropertyEntity;
|
||||||
|
import net.srt.vo.MetadataPropertyVo;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface MetadataPropertyConvert {
|
||||||
|
MetadataPropertyConvert INSTANCE = Mappers.getMapper(MetadataPropertyConvert.class);
|
||||||
|
|
||||||
|
MetadataPropertyEntity convert(MetadataPropertyVo vo);
|
||||||
|
|
||||||
|
MetadataPropertyEntity convert(DataGovernanceMetadataPropertyDto dto);
|
||||||
|
|
||||||
|
MetadataPropertyVo convert(MetadataPropertyEntity entity);
|
||||||
|
|
||||||
|
DataGovernanceMetadataPropertyDto convertDto(MetadataPropertyEntity entity);
|
||||||
|
|
||||||
|
List<MetadataPropertyVo> convertList(List<MetadataPropertyEntity> list);
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,14 @@ package net.srt.service;
|
||||||
|
|
||||||
import net.srt.entity.MetadataPropertyEntity;
|
import net.srt.entity.MetadataPropertyEntity;
|
||||||
import net.srt.framework.mybatis.service.BaseService;
|
import net.srt.framework.mybatis.service.BaseService;
|
||||||
|
import net.srt.vo.MetadataPropertyVo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface MetadataPropertyService extends BaseService<MetadataPropertyEntity> {
|
public interface MetadataPropertyService extends BaseService<MetadataPropertyEntity> {
|
||||||
|
void save(MetadataPropertyVo vo);
|
||||||
|
|
||||||
|
void update(MetadataPropertyVo vo);
|
||||||
|
|
||||||
|
void delete(List<Long> idList);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package net.srt.service;
|
package net.srt.service;
|
||||||
|
|
||||||
import net.srt.entity.MetadataEntity;
|
import net.srt.entity.MetadataEntity;
|
||||||
|
import net.srt.framework.common.cache.bean.Neo4jInfo;
|
||||||
import net.srt.framework.common.utils.TreeNodeVo;
|
import net.srt.framework.common.utils.TreeNodeVo;
|
||||||
import net.srt.framework.mybatis.service.BaseService;
|
import net.srt.framework.mybatis.service.BaseService;
|
||||||
import net.srt.vo.MetadataVO;
|
import net.srt.vo.MetadataVO;
|
||||||
|
@ -21,4 +22,11 @@ public interface MetadataService extends BaseService<MetadataEntity> {
|
||||||
void save(MetadataVO vo);
|
void save(MetadataVO vo);
|
||||||
|
|
||||||
|
|
||||||
|
void update(MetadataVO vo);
|
||||||
|
|
||||||
|
void delete(Long id);
|
||||||
|
|
||||||
|
void upNeo4jInfo(Neo4jInfo neo4jInfo);
|
||||||
|
|
||||||
|
Neo4jInfo getNeo4jInfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,35 @@
|
||||||
package net.srt.service.impl;
|
package net.srt.service.impl;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.srt.convert.MetadataPropertyConvert;
|
||||||
import net.srt.dao.MetadataPropertyDao;
|
import net.srt.dao.MetadataPropertyDao;
|
||||||
import net.srt.entity.MetadataPropertyEntity;
|
import net.srt.entity.MetadataPropertyEntity;
|
||||||
import net.srt.framework.mybatis.service.impl.BaseServiceImpl;
|
import net.srt.framework.mybatis.service.impl.BaseServiceImpl;
|
||||||
import net.srt.service.MetadataPropertyService;
|
import net.srt.service.MetadataPropertyService;
|
||||||
|
import net.srt.vo.MetadataPropertyVo;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class MetadataPropertyServiceImpl extends BaseServiceImpl<MetadataPropertyDao, MetadataPropertyEntity> implements MetadataPropertyService {
|
public class MetadataPropertyServiceImpl extends BaseServiceImpl<MetadataPropertyDao, MetadataPropertyEntity> implements MetadataPropertyService {
|
||||||
|
@Override
|
||||||
|
public void save(MetadataPropertyVo vo) {
|
||||||
|
MetadataPropertyEntity entity = MetadataPropertyConvert.INSTANCE.convert(vo);
|
||||||
|
baseMapper.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(MetadataPropertyVo vo) {
|
||||||
|
MetadataPropertyEntity entity = MetadataPropertyConvert.INSTANCE.convert(vo);
|
||||||
|
updateById(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void delete(List<Long> idList) {
|
||||||
|
removeByIds(idList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,197 +0,0 @@
|
||||||
package net.srt.service.impl;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.servers.Server;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import net.srt.api.module.data.governance.constant.BuiltInMetamodel;
|
|
||||||
import net.srt.convert.MetadataConvert;
|
|
||||||
import net.srt.dao.MetadataDao;
|
|
||||||
import net.srt.dao.MetadataPropertyDao;
|
|
||||||
import net.srt.entity.MetadataEntity;
|
|
||||||
import net.srt.entity.MetadataPropertyEntity;
|
|
||||||
import net.srt.framework.common.utils.BeanUtil;
|
|
||||||
import net.srt.framework.common.utils.BuildTreeUtils;
|
|
||||||
import net.srt.framework.common.utils.Result;
|
|
||||||
import net.srt.framework.common.utils.TreeNodeVo;
|
|
||||||
import net.srt.framework.mybatis.service.impl.BaseServiceImpl;
|
|
||||||
import net.srt.service.MetadataService;
|
|
||||||
import net.srt.vo.MetadataVO;
|
|
||||||
import net.srt.vo.MetamodelPropertyVO;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import srt.cloud.framework.dbswitch.common.util.StringUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Server
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class MetadataServiceImpl extends BaseServiceImpl<MetadataDao, MetadataEntity> implements MetadataService {
|
|
||||||
|
|
||||||
private final MetadataDao metadataDao;
|
|
||||||
private final MetadataPropertyDao metadataPropertyDao;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TreeNodeVo> listByParentId(Long parentId) {
|
|
||||||
LambdaQueryWrapper<MetadataEntity> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(MetadataEntity::getParentId,parentId)
|
|
||||||
.orderByAsc(MetadataEntity::getOrderNo);
|
|
||||||
dataScopeWithOrgId(wrapper);
|
|
||||||
List<MetadataEntity> metadataEntities = baseMapper.selectList(wrapper);
|
|
||||||
return BeanUtil.copyListProperties(metadataEntities,TreeNodeVo::new, (oldItem, newItem) ->{
|
|
||||||
newItem.setLabel(oldItem.getName());
|
|
||||||
newItem.setValue(oldItem.getId());
|
|
||||||
newItem.setLeaf(BuiltInMetamodel.COLUMN.getId().equals(oldItem.getMetamodelId()));
|
|
||||||
if(newItem.getPath().contains("/")){
|
|
||||||
newItem.setParentPath(newItem.getPath().substring(0,newItem.getPath().lastIndexOf("/")));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TreeNodeVo> listFloder() {
|
|
||||||
LambdaQueryWrapper<MetadataEntity> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(MetadataEntity::getIfLeaf,1)
|
|
||||||
.orderByAsc(MetadataEntity::getOrderNo)
|
|
||||||
.orderByAsc(MetadataEntity::getId);
|
|
||||||
dataScopeWithOrgId(wrapper);
|
|
||||||
List<MetadataEntity> metadatas = baseMapper.selectList(wrapper);
|
|
||||||
List<TreeNodeVo> treeNodeVos = BeanUtil.copyListProperties(metadatas, TreeNodeVo::new, (oldItem, newItem) -> {
|
|
||||||
newItem.setLabel(oldItem.getName());
|
|
||||||
newItem.setValue(oldItem.getId());
|
|
||||||
if (newItem.getPath().contains("/")) {
|
|
||||||
newItem.setParentPath(newItem.getPath().substring(0, newItem.getPath().lastIndexOf("/")));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return BuildTreeUtils.buildTree(treeNodeVos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TreeNodeVo> listDb() {
|
|
||||||
LambdaQueryWrapper<MetadataEntity> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.in(MetadataEntity::getMetamodelId,BuiltInMetamodel.SCHEMA.getId(),BuiltInMetamodel.TABLE.getId())
|
|
||||||
.or()
|
|
||||||
.isNull(MetadataEntity::getMetamodelId)
|
|
||||||
.orderByAsc(MetadataEntity::getOrderNo);
|
|
||||||
dataScopeWithOrgId(wrapper);
|
|
||||||
List<MetadataEntity> metadatas = baseMapper.selectList(wrapper);
|
|
||||||
List<TreeNodeVo> treeNodeVos = BeanUtil.copyListProperties(metadatas,TreeNodeVo::new, (oldItem, newItem) -> {
|
|
||||||
newItem.setLabel(oldItem.getName());
|
|
||||||
newItem.setValue(oldItem.getId());
|
|
||||||
newItem.setDisabled(!BuiltInMetamodel.TABLE.getId().equals(oldItem.getMetamodelId()));
|
|
||||||
if(newItem.getPath().contains("/")) {
|
|
||||||
newItem.setParentPath(newItem.getPath().substring(0,newItem.getPath().lastIndexOf("/")));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return BuildTreeUtils.buildTree(treeNodeVos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TreeNodeVo> listByKeyword(String keyword) {
|
|
||||||
if(StringUtil.isBlank(keyword)){
|
|
||||||
return listByParentId(0L);
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<MetadataEntity> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.like(MetadataEntity::getName,keyword)
|
|
||||||
.or()
|
|
||||||
.like(MetadataEntity::getCode,keyword)
|
|
||||||
.orderByAsc(MetadataEntity::getOrderNo)
|
|
||||||
.orderByAsc(MetadataEntity::getId);
|
|
||||||
dataScopeWithOrgId(wrapper);
|
|
||||||
List<MetadataEntity> metadatas = baseMapper.selectList(wrapper);
|
|
||||||
List<MetadataEntity> resultList = new ArrayList<>();
|
|
||||||
//递归获取父级
|
|
||||||
for (MetadataEntity metadata : metadatas) {
|
|
||||||
recursionAddParent(metadata,resultList);
|
|
||||||
}
|
|
||||||
List<MetadataEntity> result = resultList.stream().sorted(Comparator.comparing(MetadataEntity::getOrderNo)).collect(Collectors.toList());
|
|
||||||
List<TreeNodeVo> treeNodeVos = BeanUtil.copyListProperties(result ,TreeNodeVo::new, (oldItem, newItem) -> {
|
|
||||||
newItem.setLabel(oldItem.getName());
|
|
||||||
newItem.setValue(oldItem.getId());
|
|
||||||
newItem.setLeaf(BuiltInMetamodel.COLUMN.getId().equals(oldItem.getMetamodelId()));
|
|
||||||
if(newItem.getPath().contains("/")) {
|
|
||||||
newItem.setParentPath(newItem.getPath().substring(0,newItem.getPath().lastIndexOf("/")));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return BuildTreeUtils.buildTree(treeNodeVos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetadataVO get(Long id) {
|
|
||||||
MetadataEntity metadataEntity = getById(id);
|
|
||||||
MetadataVO metadataVO = MetadataConvert.INSTANCE.convert(metadataEntity);
|
|
||||||
metadataVO.setProperties(metadataPropertyDao.listPropertyById(id,metadataEntity.getMetamodelId()));
|
|
||||||
return metadataVO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(MetadataVO vo) {
|
|
||||||
MetadataEntity entity = MetadataConvert.INSTANCE.convert(vo);
|
|
||||||
entity.setProjectId(getProjectId());
|
|
||||||
entity.setPath(recursionPath(entity,null));
|
|
||||||
buildField(entity);
|
|
||||||
MetadataEntity parentMetadata = baseMapper.selectById(vo.getParentId());
|
|
||||||
if(parentMetadata != null) {
|
|
||||||
entity.setDbType(parentMetadata.getDbType());
|
|
||||||
entity.setDatasourceId(parentMetadata.getDatasourceId());
|
|
||||||
entity.setCollectTaskId(parentMetadata.getCollectTaskId());
|
|
||||||
}
|
|
||||||
baseMapper.insert(entity);
|
|
||||||
buildProperties(entity,vo.getProperties());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recursionAddParent(MetadataEntity metadataEntity, List<MetadataEntity> resultList){
|
|
||||||
if(resultList.stream().noneMatch(item -> metadataEntity.getId().equals(item.getId()))) {
|
|
||||||
resultList.add(metadataEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(metadataEntity.getParentId()!=0){
|
|
||||||
MetadataEntity parent = getById(metadataEntity.getParentId());
|
|
||||||
recursionAddParent(parent,resultList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildField(MetadataEntity entity){
|
|
||||||
if(entity.getMetamodelId()!=null){
|
|
||||||
entity.setIcon(metadataDao.selectById(entity.getMetamodelId()).getIcon());
|
|
||||||
}
|
|
||||||
if(entity.getIfLeaf() == 1 && entity.getMetamodelId() == null) {
|
|
||||||
entity.setIcon("/src/assets/folder.png");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String recursionPath(MetadataEntity metadataEntity, String path) {
|
|
||||||
if(StringUtil.isBlank(path)){
|
|
||||||
path = metadataEntity.getName();
|
|
||||||
}
|
|
||||||
if(metadataEntity.getParentId()!=0){
|
|
||||||
MetadataEntity parent = getById(metadataEntity.getParentId());
|
|
||||||
path = parent.getName() + "/" +path;
|
|
||||||
return recursionPath(parent,path);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildProperties(MetadataEntity entity, List<MetamodelPropertyVO> properties){
|
|
||||||
if(!CollectionUtils.isEmpty(properties)){
|
|
||||||
LambdaQueryWrapper<MetadataPropertyEntity> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(MetadataPropertyEntity::getMetadataId,entity.getId());
|
|
||||||
for (MetamodelPropertyVO property : properties) {
|
|
||||||
MetadataPropertyEntity metadataPropertyEntity = new MetadataPropertyEntity();
|
|
||||||
metadataPropertyEntity.setMetamodelPropertyId(property.getId());
|
|
||||||
metadataPropertyEntity.setMetadataId(entity.getId());
|
|
||||||
metadataPropertyEntity.setProperty(property.getValue());
|
|
||||||
metadataPropertyEntity.setProjectId(entity.getProjectId());
|
|
||||||
if(property.getMetadataPropertyId()!=null){
|
|
||||||
metadataPropertyEntity.setId(property.getMetadataPropertyId());
|
|
||||||
metadataPropertyDao.updateById(metadataPropertyEntity);
|
|
||||||
}else {
|
|
||||||
metadataPropertyDao.insert(metadataPropertyEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue