Commit 01791790 by zwb

新增城市数据处理与二级查询

parent 14e5fe5c
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
<dependencies> <dependencies>
<!-- Jackson JSON处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<dependency> <dependency>
<groupId>com.bkty</groupId> <groupId>com.bkty</groupId>
<artifactId>employmentBusiness-pc-common-nacos</artifactId> <artifactId>employmentBusiness-pc-common-nacos</artifactId>
......
...@@ -2,7 +2,6 @@ package com.bkty.system.controller; ...@@ -2,7 +2,6 @@ package com.bkty.system.controller;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.bkty.system.domain.dto.AnalysisCareerDto; import com.bkty.system.domain.dto.AnalysisCareerDto;
import com.bkty.system.init.*; import com.bkty.system.init.*;
import com.bkty.system.service.jobRecommend.AiAnalysisService; import com.bkty.system.service.jobRecommend.AiAnalysisService;
...@@ -11,15 +10,12 @@ import io.swagger.v3.oas.annotations.Operation; ...@@ -11,15 +10,12 @@ 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.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.JxgException; import org.dromara.common.core.exception.JxgException;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
...@@ -77,4 +73,10 @@ public class JobRecommendController { ...@@ -77,4 +73,10 @@ public class JobRecommendController {
String id = aiAnalysisService.saveAnalysisData(dto); String id = aiAnalysisService.saveAnalysisData(dto);
return new R<>(id); return new R<>(id);
} }
@Operation(summary = "城市二级分类查询")
@GetMapping("/citys")
public R<List<Level1City>> getAllCitys() {
return new R<>(categoryCacheManager.getCityCache());
}
} }
package com.bkty.system.domain.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("city_data")
public class CityData {
private Long id;
private String provinceCode;
private String provinceName;
private String cityCode;
private String cityName;
}
\ No newline at end of file
package com.bkty.system.domain.entity; package com.bkty.system.domain.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
/** /**
...@@ -8,6 +9,7 @@ import lombok.Data; ...@@ -8,6 +9,7 @@ import lombok.Data;
* @datetime 2025/12/3 18:22 * @datetime 2025/12/3 18:22
*/ */
@Data @Data
@TableName("positions_data")
public class PositionData { public class PositionData {
/** /**
* 主键id * 主键id
......
package com.bkty.system.init;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Zhang Wenbiao
* @description CItyCacheInitializer
* @datetime 2025/12/4 11:15
*/
@Component
public class CItyCacheInitializer implements CommandLineRunner {
@Autowired
private CityDataService cityDataService;
@Autowired
private CategoryCacheManager categoryCacheManager;
@Override
public void run(String... args) throws Exception {
try {
List<Level1City> cityDatas = cityDataService.getCitys();
// 加载到全局缓存
categoryCacheManager.loadCityCache(cityDatas);
} catch (Exception e) {
System.err.println("加载岗位数据缓存失败: " + e.getMessage());
e.printStackTrace();
}
}
}
...@@ -13,9 +13,13 @@ public class CategoryCacheManager { ...@@ -13,9 +13,13 @@ public class CategoryCacheManager {
// 全局缓存结构: 完整的层级结构列表 // 全局缓存结构: 完整的层级结构列表
private static List<Level1Group> positionCache = new CopyOnWriteArrayList<>(); private static List<Level1Group> positionCache = new CopyOnWriteArrayList<>();
private static List<Level1City> cityCache = new CopyOnWriteArrayList<>();
// 一级分类名称到Level1Group对象的映射,便于快速查找 // 一级分类名称到Level1Group对象的映射,便于快速查找
private static Map<String, Level1Group> positionNameMap = new ConcurrentHashMap<>(); private static Map<String, Level1Group> positionNameMap = new ConcurrentHashMap<>();
private static Map<String, Level1City> cityDataMap = new ConcurrentHashMap<>();
/** /**
* 将岗位数据加载到缓存 * 将岗位数据加载到缓存
*/ */
...@@ -29,13 +33,32 @@ public class CategoryCacheManager { ...@@ -29,13 +33,32 @@ public class CategoryCacheManager {
} }
/** /**
* 获取缓存数据 * 将城市数据加载到缓存
*/
public void loadCityCache(List<Level1City> data) {
cityCache = new CopyOnWriteArrayList<>(data);
// 更新名称映射
cityDataMap.clear();
for (Level1City group : data) {
cityDataMap.put(group.getName(), group);
}
}
/**
* 获取岗位缓存数据
*/ */
public List<Level1Group> getPositionCache() { public List<Level1Group> getPositionCache() {
return positionCache; return positionCache;
} }
/** /**
* 获取城市缓存数据
*/
public List<Level1City> getCityCache() {
return cityCache;
}
/**
* 根据一级分类名称获取数据 (更新后的方法) * 根据一级分类名称获取数据 (更新后的方法)
*/ */
public Level1Group getPositionDataByName(String level1Name) { public Level1Group getPositionDataByName(String level1Name) {
......
package com.bkty.system.init;
import com.bkty.system.domain.entity.CityData;
import com.bkty.system.mapper.CityDataMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author Zhang Wenbiao
* @description 城市数据service
* @datetime 2025/12/4 10:49
*/
@Service
public class CityDataService {
@Autowired
private CityDataMapper cityDataMapper;
/**
* 查询数据并封装为二级结构
*/
public List<Level1City> getCitys() {
// 从数据库查询数据
List<CityData> cityDataList = cityDataMapper.selectList(null);
// 使用Map来组织二级结构
Map<String, Level1City> level1Map = new LinkedHashMap<>();
for (CityData cityData : cityDataList) {
String level1Name = cityData.getProvinceName();
String level1Code = cityData.getProvinceCode();
String level2Name = cityData.getCityName();
String level2Code = cityData.getCityCode();
// 如果任何一级名称为空,跳过该记录
if (level1Name == null || level2Name == null ) {
continue;
}
// 构建第一级(省份类型)
Level1City level1 = level1Map.computeIfAbsent(level1Name,
k -> new Level1City(level1Name,level1Code));
// 构建第二级(岗位类型)
Level2City level2 = findOrCreateLevel2(level1.getLevel2City(), level2Name,level2Code);
}
return new ArrayList<>(level1Map.values());
}
/**
* 在第二级列表中查找或创建新的第二级
*/
private Level2City findOrCreateLevel2(List<Level2City> level2Cities, String level2Name, String level2Code) {
// 查找是否已存在
for (Level2City level2 : level2Cities) {
if (level2.getName().equals(level2Name)) {
return level2;
}
}
// 不存在则创建并添加到列表
Level2City newLevel2 = new Level2City(level2Name,level2Code);
level2Cities.add(newLevel2);
return newLevel2;
}
}
package com.bkty.system.init;
import java.util.ArrayList;
import java.util.List;
/**
* @author Zhang Wenbiao
* @description 城市一级分类(省)
* @datetime 2025/12/4 10:55
*/
public class Level1City {
private String name;
private String code;
private List<Level2City> Level2City;
public Level1City(String name, String code) {
this.name = name;
this.code = code;
this.Level2City = new ArrayList<>();
}
// getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
public List<Level2City> getLevel2City() { return Level2City; }
public void setLevel2City(List<Level2City> Level2City) { this.Level2City = Level2City; }
}
package com.bkty.system.init;
/**
* @author Zhang Wenbiao
* @description 城市二级分类(市)
* @datetime 2025/12/4 10:55
*/
public class Level2City {
private String name;
private String code;
public Level2City(String name,String code) {
this.name = name;
this.code = code;
}
// getters and setters
public String getName() { return name; }
public String getCode() { return code; }
public void setName(String name) { this.name = name; }
public void setCode(String code) { this.code = code; }
}
package com.bkty.system.init;
import com.bkty.system.domain.entity.CityData;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.dromara.common.core.constant.RegionConstants;
import java.sql.*;
import java.util.*;
import java.util.stream.Collectors;
public class RegionDataProcessor {
// 用于解析JSON数据的POJO类
@Data
public static class RegionItem {
private String label;
private String value;
}
// 数据库连接配置
private static final String DB_URL = "jdbc:mariadb://123.56.87.224:3306/employment_business_pc";
private static final String DB_USER = "innovate";
private static final String DB_PASSWORD = "X3f#)2#Ul-g8Fv6D";
// 处理JSON字符串并插入数据库
public void processAndInsertData(String regionJson) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
List<RegionItem> regionList = objectMapper.readValue(
regionJson,
new TypeReference<List<RegionItem>>() {}
);
// 分组:省级(2位编码)和市级(4位编码)
Map<String, String> provinces = regionList.stream()
.filter(item -> item.getValue().length() == 2)
.collect(Collectors.toMap(
RegionItem::getValue,
RegionItem::getLabel,
(v1, v2) -> v1 // 如果有重复,保留第一个
));
List<RegionItem> cities = regionList.stream()
.filter(item -> item.getValue().length() == 4)
.collect(Collectors.toList());
// 处理城市数据,关联省份
List<CityData> cityDataList = new ArrayList<>();
for (RegionItem city : cities) {
String cityCode = city.getValue();
String provinceCode = cityCode.substring(0, 2);
String provinceName = provinces.get(provinceCode);
if (provinceName != null) {
CityData cityData = new CityData();
cityData.setProvinceCode(provinceCode);
cityData.setProvinceName(provinceName);
cityData.setCityCode(cityCode);
cityData.setCityName(city.getLabel());
cityDataList.add(cityData);
}
}
// 插入数据库
insertIntoDatabase(cityDataList);
}
private void insertIntoDatabase(List<CityData> cityDataList) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 1. 建立数据库连接
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
// 2. 准备SQL语句
String sql = "INSERT INTO city_data (province_code, province_name, city_code, city_name) " +
"VALUES (?, ?, ?, ?)";
pstmt = conn.prepareStatement(sql);
// 3. 批量插入
int batchSize = 1000;
int count = 0;
for (CityData data : cityDataList) {
pstmt.setString(1, data.getProvinceCode());
pstmt.setString(2, data.getProvinceName());
pstmt.setString(3, data.getCityCode());
pstmt.setString(4, data.getCityName());
pstmt.addBatch();
if (++count % batchSize == 0) {
pstmt.executeBatch();
pstmt.clearBatch();
}
}
// 执行剩余批次
pstmt.executeBatch();
System.out.println("成功插入 " + count + " 条记录");
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 关闭资源
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 使用示例
public static void main(String[] args) {
try {
RegionDataProcessor processor = new RegionDataProcessor();
// 直接从你的常量类中获取JSON字符串
String jsonData = RegionConstants.REGION_JSON_ARRAY;
// 处理并插入数据
processor.processAndInsertData(jsonData);
} catch (Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package com.bkty.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bkty.system.domain.entity.CityData;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CityDataMapper extends BaseMapper<CityData> {
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment