mirror of
https://github.com/dataease/dataease.git
synced 2026-05-24 06:18:10 +08:00
feat: 自定义地图设置
This commit is contained in:
@@ -21,12 +21,16 @@ public class DeMvcConfig implements WebMvcConfigurer {
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
String workDir = FILE_PROTOCOL + ensureSuffix(WORK_DIR, FILE_SEPARATOR);
|
||||
String uploadUrlPattern = ensureBoth(URL_SEPARATOR + UPLOAD_URL_PREFIX, AuthConstant.DE_API_PREFIX, URL_SEPARATOR) + "**";
|
||||
registry.addResourceHandler(uploadUrlPattern)
|
||||
.addResourceLocations(workDir);
|
||||
registry.addResourceHandler(uploadUrlPattern).addResourceLocations(workDir);
|
||||
|
||||
// map
|
||||
String mapDir = FILE_PROTOCOL + ensureSuffix(MAP_DIR, FILE_SEPARATOR);
|
||||
String mapUrlPattern = ensureBoth(MAP_URL, AuthConstant.DE_API_PREFIX, URL_SEPARATOR) + "**";
|
||||
registry.addResourceHandler(mapUrlPattern)
|
||||
.addResourceLocations(mapDir);
|
||||
registry.addResourceHandler(mapUrlPattern).addResourceLocations(mapDir);
|
||||
|
||||
String geoDir = FILE_PROTOCOL + ensureSuffix(CUSTOM_MAP_DIR, FILE_SEPARATOR);
|
||||
String geoUrlPattern = ensureBoth(GEO_URL, AuthConstant.DE_API_PREFIX, URL_SEPARATOR) + "**";
|
||||
registry.addResourceHandler(geoUrlPattern).addResourceLocations(geoDir);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.dataease.map.bo;
|
||||
|
||||
import io.dataease.map.dao.auto.entity.Area;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class AreaBO extends Area implements Serializable {
|
||||
private boolean custom = false;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.dataease.map.dao.ext.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class CoreAreaCustom implements Serializable {
|
||||
|
||||
private String id;
|
||||
|
||||
private String pid;
|
||||
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package io.dataease.map.dao.ext.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import io.dataease.map.dao.ext.entity.CoreAreaCustom;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface CoreAreaCustomMapper extends BaseMapper<CoreAreaCustom> {
|
||||
}
|
||||
@@ -1,17 +1,34 @@
|
||||
package io.dataease.map.manage;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import io.dataease.api.map.dto.GeometryNodeCreator;
|
||||
import io.dataease.api.map.vo.AreaNode;
|
||||
import io.dataease.constant.StaticResourceConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.map.bo.AreaBO;
|
||||
import io.dataease.map.dao.auto.entity.Area;
|
||||
import io.dataease.map.dao.auto.mapper.AreaMapper;
|
||||
import io.dataease.map.dao.ext.entity.CoreAreaCustom;
|
||||
import io.dataease.map.dao.ext.mapper.CoreAreaCustomMapper;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.CommonBeanFactory;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.dataease.constant.CacheConstant.CommonCacheConstant.WORLD_MAP_CACHE;
|
||||
|
||||
@@ -19,6 +36,8 @@ import static io.dataease.constant.CacheConstant.CommonCacheConstant.WORLD_MAP_C
|
||||
public class MapManage {
|
||||
private final static AreaNode WORLD;
|
||||
|
||||
private static final String GEO_PREFIX = "geo_";
|
||||
|
||||
static {
|
||||
WORLD = AreaNode.builder()
|
||||
.id("000")
|
||||
@@ -30,13 +49,34 @@ public class MapManage {
|
||||
@Resource
|
||||
private AreaMapper areaMapper;
|
||||
|
||||
@Resource
|
||||
private CoreAreaCustomMapper coreAreaCustomMapper;
|
||||
|
||||
public List<Area> defaultArea() {
|
||||
return areaMapper.selectList(null);
|
||||
}
|
||||
|
||||
private MapManage proxy() {
|
||||
return CommonBeanFactory.getBean(MapManage.class);
|
||||
}
|
||||
|
||||
@Cacheable(value = WORLD_MAP_CACHE, key = "'world_map'")
|
||||
public AreaNode getWorldTree() {
|
||||
List<Area> areas = areaMapper.selectList(null);
|
||||
List<Area> areas = proxy().defaultArea();
|
||||
List<AreaBO> areaBOS = areas.stream().map(item -> BeanUtils.copyBean(new AreaBO(), item)).collect(Collectors.toList());
|
||||
List<CoreAreaCustom> coreAreaCustoms = coreAreaCustomMapper.selectList(null);
|
||||
if (CollectionUtils.isNotEmpty(coreAreaCustoms)) {
|
||||
List<AreaBO> customBoList = coreAreaCustoms.stream().map(item -> {
|
||||
AreaBO areaBO = BeanUtils.copyBean(new AreaBO(), item);
|
||||
areaBO.setCustom(true);
|
||||
return areaBO;
|
||||
}).toList();
|
||||
areaBOS.addAll(customBoList);
|
||||
}
|
||||
WORLD.setChildren(new ArrayList<>());
|
||||
var areaNodeMap = new HashMap<String, AreaNode>();
|
||||
areaNodeMap.put(WORLD.getId(), WORLD);
|
||||
areas.forEach(area -> {
|
||||
areaBOS.forEach(area -> {
|
||||
var node = areaNodeMap.get(area.getId());
|
||||
if (node == null) {
|
||||
node = AreaNode.builder().build();
|
||||
@@ -64,5 +104,80 @@ public class MapManage {
|
||||
return WORLD;
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = WORLD_MAP_CACHE, key = "'world_map'")
|
||||
@Transactional
|
||||
public void saveMapGeo(GeometryNodeCreator request, MultipartFile file) {
|
||||
List<Area> areas = proxy().defaultArea();
|
||||
String code = getBusiGeoCode(request.getCode());
|
||||
|
||||
AtomicReference<String> atomicReference = new AtomicReference<>();
|
||||
if (areas.stream().anyMatch(area -> {
|
||||
boolean exist = area.getId().equals(code);
|
||||
if (exist) {
|
||||
atomicReference.set(area.getName());
|
||||
}
|
||||
return exist;
|
||||
})) {
|
||||
DEException.throwException(String.format("Area code [%s] is already exists for [%s]", code, atomicReference.get()));
|
||||
}
|
||||
|
||||
CoreAreaCustom originData = null;
|
||||
if (ObjectUtils.isNotEmpty(originData = coreAreaCustomMapper.selectById(getDaoGeoCode(code)))) {
|
||||
DEException.throwException(String.format("Area code [%s] is already exists for [%s]", code, originData.getName()));
|
||||
}
|
||||
|
||||
CoreAreaCustom coreAreaCustom = new CoreAreaCustom();
|
||||
coreAreaCustom.setId(getDaoGeoCode(code));
|
||||
coreAreaCustom.setPid(request.getPid());
|
||||
coreAreaCustom.setName(request.getName());
|
||||
coreAreaCustomMapper.insert(coreAreaCustom);
|
||||
|
||||
File geoFile = buildGeoFile(code);
|
||||
try {
|
||||
file.transferTo(geoFile);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e.getMessage());
|
||||
DEException.throwException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = WORLD_MAP_CACHE, key = "'world_map'")
|
||||
@Transactional
|
||||
public void deleteGeo(String code) {
|
||||
if (!StringUtils.startsWith(code, GEO_PREFIX)) {
|
||||
DEException.throwException("内置Geometry,禁止删除");
|
||||
}
|
||||
coreAreaCustomMapper.deleteById(code);
|
||||
File file = buildGeoFile(code);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private String getDaoGeoCode(String code) {
|
||||
return StringUtils.startsWith(code, GEO_PREFIX) ? code : (GEO_PREFIX + code);
|
||||
}
|
||||
|
||||
private String getBusiGeoCode(String code) {
|
||||
return StringUtils.startsWith(code, GEO_PREFIX) ? code.substring(GEO_PREFIX.length()) : code;
|
||||
}
|
||||
|
||||
private File buildGeoFile(String code) {
|
||||
String id = getBusiGeoCode(code);
|
||||
String customMapDir = StaticResourceConstants.CUSTOM_MAP_DIR;
|
||||
String countryCode = countryCode(id);
|
||||
String fileDirPath = customMapDir + "/" + countryCode + "/";
|
||||
File dir = new File(fileDirPath);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
String filePath = fileDirPath + id + ".json";
|
||||
return new File(filePath);
|
||||
}
|
||||
|
||||
private String countryCode(String code) {
|
||||
return code.substring(0, 3);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.dataease.map.server;
|
||||
|
||||
import io.dataease.api.map.GeoApi;
|
||||
import io.dataease.api.map.dto.GeometryNodeCreator;
|
||||
import io.dataease.map.manage.MapManage;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/geometry")
|
||||
public class GeoServer implements GeoApi {
|
||||
|
||||
@Resource
|
||||
private MapManage mapManage;
|
||||
@Override
|
||||
public void saveMapGeo(GeometryNodeCreator request, MultipartFile file) {
|
||||
mapManage.saveMapGeo(request, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteGeo(String id) {
|
||||
mapManage.deleteGeo(id);
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,25 @@ VALUES (20, 15, 2, 'template-setting', 'system/template-setting', 4, 'icon_templ
|
||||
COMMIT;
|
||||
|
||||
DROP TABLE IF EXISTS `visualization_template_extend_data`;
|
||||
CREATE TABLE `visualization_template_extend_data` (
|
||||
`id` bigint NOT NULL,
|
||||
`dv_id` bigint DEFAULT NULL,
|
||||
`view_id` bigint DEFAULT NULL,
|
||||
`view_details` longtext,
|
||||
`copy_from` varchar(255) DEFAULT NULL,
|
||||
`copy_id` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
CREATE TABLE `visualization_template_extend_data`
|
||||
(
|
||||
`id` bigint NOT NULL,
|
||||
`dv_id` bigint DEFAULT NULL,
|
||||
`view_id` bigint DEFAULT NULL,
|
||||
`view_details` longtext,
|
||||
`copy_from` varchar(255) DEFAULT NULL,
|
||||
`copy_id` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for core_area_custom
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `core_area_custom`;
|
||||
CREATE TABLE `core_area_custom`
|
||||
(
|
||||
`id` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`pid` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user