|
|
@@ -0,0 +1,156 @@
|
|
|
+package org.dromara.system.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.lang.tree.Tree;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.common.core.constant.CacheNames;
|
|
|
+import org.dromara.common.core.utils.TreeBuildUtils;
|
|
|
+import org.dromara.common.redis.utils.CacheUtils;
|
|
|
+import org.dromara.system.domain.SysRegion;
|
|
|
+import org.dromara.system.mapper.SysRegionMapper;
|
|
|
+import org.dromara.system.service.ISysRegionService;
|
|
|
+import org.springframework.cache.annotation.CachePut;
|
|
|
+import org.springframework.cache.annotation.Cacheable;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 地区信息Service业务层处理
|
|
|
+ *
|
|
|
+ * @Author: Antigravity
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+public class SysRegionServiceImpl implements ISysRegionService {
|
|
|
+
|
|
|
+ private final SysRegionMapper baseMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量同步并保存地区数据
|
|
|
+ *
|
|
|
+ * @param regionData 地区原始数据列表
|
|
|
+ */
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ public void syncRegionData(List<Map<String, Object>> regionData) {
|
|
|
+ // 1. 同步前先清除历史数据(防止重复同步产生垃圾数据)
|
|
|
+ baseMapper.delete(new LambdaQueryWrapper<SysRegion>());
|
|
|
+ // 2. 清除所有相关缓存
|
|
|
+ CacheUtils.clear(CacheNames.SYS_REGION);
|
|
|
+ // 3. 递归保存
|
|
|
+ saveRecursive(regionData, 0L);
|
|
|
+ log.info("地区数据同步完成");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 递归保存子节点
|
|
|
+ */
|
|
|
+ private void saveRecursive(List<Map<String, Object>> data, Long parentId) {
|
|
|
+ if (data == null || data.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (Map<String, Object> map : data) {
|
|
|
+ String code = String.valueOf(map.get("value"));
|
|
|
+ String name = String.valueOf(map.get("label"));
|
|
|
+
|
|
|
+ SysRegion region = new SysRegion();
|
|
|
+ region.setId(IdWorker.getId());
|
|
|
+ region.setParentId(parentId);
|
|
|
+ region.setCode(code);
|
|
|
+ region.setName(name);
|
|
|
+ // 每一个插入项都可能被 CachePut,但在批量保存时通常直接清理总缓存更有效
|
|
|
+ // 此处满足用户对 CachePut 的参考需求,实际通过 syncRegionData 整体维护
|
|
|
+ this.insertRegionWithCache(region);
|
|
|
+
|
|
|
+ Object children = map.get("children");
|
|
|
+ if (children instanceof List) {
|
|
|
+ saveRecursive((List<Map<String, Object>>) children, region.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 带缓存的新增(参考 CachePut 用法)
|
|
|
+ */
|
|
|
+ @CachePut(cacheNames = CacheNames.SYS_REGION, key = "#region.code")
|
|
|
+ public SysRegion insertRegionWithCache(SysRegion region) {
|
|
|
+ baseMapper.insert(region);
|
|
|
+ return region;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据代码查询地区信息(参考 Cacheable 用法)
|
|
|
+ */
|
|
|
+ @Cacheable(cacheNames = CacheNames.SYS_REGION, key = "#code")
|
|
|
+ @Override
|
|
|
+ public SysRegion selectByCode(String code) {
|
|
|
+ return baseMapper.selectOne(new LambdaQueryWrapper<SysRegion>()
|
|
|
+ .eq(SysRegion::getCode, code));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询地区树结构
|
|
|
+ */
|
|
|
+ @Cacheable(cacheNames = CacheNames.SYS_REGION, key = "'tree'")
|
|
|
+ @Override
|
|
|
+ public List<SysRegion> selectRegionTree() {
|
|
|
+ List<SysRegion> list = baseMapper.selectList(new LambdaQueryWrapper<SysRegion>()
|
|
|
+ .orderByAsc(SysRegion::getCode));
|
|
|
+ return buildRegionTree(list, 0L);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建地区树
|
|
|
+ */
|
|
|
+ private List<SysRegion> buildRegionTree(List<SysRegion> list, Long parentId) {
|
|
|
+ List<SysRegion> returnList = new java.util.ArrayList<>();
|
|
|
+ for (SysRegion region : list) {
|
|
|
+ if (region.getParentId().equals(parentId)) {
|
|
|
+ recursionFn(list, region);
|
|
|
+ returnList.add(region);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return returnList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 递归列表
|
|
|
+ */
|
|
|
+ private void recursionFn(List<SysRegion> list, SysRegion t) {
|
|
|
+ List<SysRegion> childList = getChildList(list, t);
|
|
|
+ t.setChildren(childList);
|
|
|
+ for (SysRegion tChild : childList) {
|
|
|
+ if (hasChild(list, tChild)) {
|
|
|
+ recursionFn(list, tChild);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 得到子节点列表
|
|
|
+ */
|
|
|
+ private List<SysRegion> getChildList(List<SysRegion> list, SysRegion t) {
|
|
|
+ List<SysRegion> tlist = new java.util.ArrayList<>();
|
|
|
+ for (SysRegion n : list) {
|
|
|
+ if (n.getParentId().equals(t.getId())) {
|
|
|
+ tlist.add(n);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return tlist;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否有子节点
|
|
|
+ */
|
|
|
+ private boolean hasChild(List<SysRegion> list, SysRegion t) {
|
|
|
+ return !getChildList(list, t).isEmpty();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|