辅助地址拆分

stwzhj
luyya 2025-12-15 11:18:31 +08:00
parent e5d32cce80
commit 7346030a2f
5 changed files with 208 additions and 7 deletions

View File

@ -2,11 +2,13 @@ package org.dromara.extract.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.web.core.BaseController;
import org.dromara.extract.service.impl.DataMigrationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@ -25,7 +27,10 @@ public class AddressController extends BaseController {
private boolean isRunning = false;
@GetMapping("/start")
public ResponseEntity<String> startMigration() {
public ResponseEntity<String> startMigration(@RequestParam String xzqh,@RequestParam String startTime) {
if (StringUtils.isBlank(xzqh) || StringUtils.isBlank(startTime)){
return ResponseEntity.ok("参数不能为空");
}
if (isRunning) {
return ResponseEntity.badRequest()
.body("迁移任务已在运行中,请勿重复提交!");
@ -36,7 +41,7 @@ public class AddressController extends BaseController {
new Thread(() -> {
try {
log.info("🚀 开始异步执行数据迁移任务...");
dataMigrationService.startMigration();
dataMigrationService.startMigration(xzqh,startTime);
} catch (Exception e) {
log.error("❌ 迁移任务执行异常", e);
} finally {

View File

@ -25,6 +25,14 @@ public class Jqd implements Serializable {
private String yzb;
private String jzssfjdm;
private String jzssfjmc;
private String xqdwdm;
private String xqdwmc;
private String jzxqdwdm;
private String jzxqdwmc;

View File

@ -71,5 +71,13 @@ public class PoiAddress implements Serializable {
private String gadwmc;
private String jzssfjdm;
private String jzssfjmc;
private String xqdwdm;
private String xqdwmc;
}

View File

@ -2,6 +2,7 @@ package org.dromara.extract.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -59,8 +60,63 @@ public class DataMigrationService {
// 分页大小
private static final int PAGE_SIZE = 500;
private static final String SYSTEM_PROMPT = """
JSON
1. AOI广
广广
"期数""分区""二期""B区""南区""东苑"
``````````````````
西B使AOI
2. POI
"庐江百大超市"
"蜜雪冰城""雅韵皖酒厂"
"中国人寿保险(江淮路营业部)""工商银行XX支行"
"邮政大楼""科技馆""中医院康复楼"
"杨楼中队""XX派出所""XX卫生院"
"宋庄""葛庄""大王庄"
"孙湾火车站""合肥客运中心""汽车站"
"观堂镇政府""张村老镇政府""车管所""政务服务中心"
"[道路A]与[道路B]交口""[道路A]与[道路B]交叉口"
绿"`[地标]红绿灯`""县政府红绿灯""`[交口]红绿灯`""南一环与长江路交口红绿灯"POI
````````
POI `广```````
/POI广POI="";
使POI
addressPOI
3. "AOI + 方位词""大摩广场对面"AOI = POI = "";
"道路交口"POI =
"XX街道红绿灯"POI = ""
4. address
"高新银泰""亚珠加油站"
"期数""分区"
"宋庄""葛庄"
````````````````````````````````
"祁门路与庐州大道路口大摩广场对面" address: "祁门路与庐州大道路口大摩广场""三阳路小学门口(西区)" address: "三阳路小学(西区)"
"红星美凯龙东红绿灯" address: "红星美凯龙""城西大市场南加油站" address: "城西大市场""亚珠加油站桥南" address: "亚珠加油站"
"张寨汽贸城南门雅韵皖酒厂后面" aoi: "张寨汽贸城", poi: "雅韵皖酒厂", address: "张寨汽贸城雅韵皖酒厂"
"高铁南站南边交控集团" poi: "交控集团", address: "交控集团""店集镇蜜雪冰城门口" poi: "蜜雪冰城", address: "店集镇蜜雪冰城"
"二桥北头加油站" aoi: "", poi: "", address: """中医院康复楼(庄周西区)" aoi: "", poi: "中医院康复楼", address: "中医院康复楼(庄周西区)"
"吉峰农机大市场西门(庄周西区)" aoi: "吉峰农机大市场", poi: "", address: "吉峰农机大市场(庄周西区)""陈大镇杨楼中队后面" poi: "杨楼中队", address: "陈大镇杨楼中队"
"芦庙镇宋庄" poi: "宋庄", address: "芦庙镇宋庄""涡南镇葛庄东北角" poi: "葛庄", address: "涡南镇葛庄"
"板桥双陆大王庄" poi: "大王庄", address: "板桥双陆大王庄""观堂镇政府门口" poi: "观堂镇政府", address: "观堂镇政府"
"张村老镇政府院里" poi: "张村老镇政府", address: "张村老镇政府""客运中心门口" poi: "客运中心", address: "客运中心"
"孙湾火车站出站口" poi: "孙湾火车站", address: "孙湾火车站""车管所院内" poi: "车管所", address: "车管所"
"火车站西路口往北" poi: "火车站西路口", address: "火车站西路口"
address"桥南""东红绿灯""北头"poi"南加油站""加油站"aoi"庄周西区""西区"
5. JSON{
"aoi": "匹配的AOI名称无则为空字符串",
"poi": "最可能的POI名称无有效POI则为空字符串",
"address": "清洗后的核心地址,若无有效定位信息则为空字符串"}
JSONmarkdown
""";
// 启动迁移
public void startMigration() {
public void startMigration(String xzqh, String startTime) {
log.info("参数xzqh={},startTime={}",xzqh,startTime);
log.info("开始迁移数据...");
// 1. 先加载目标库中已存在的 name只需一次
@ -69,8 +125,8 @@ public class DataMigrationService {
// 2. 分页读取源数据
LambdaQueryWrapper<Jqd> jqlqw = new LambdaQueryWrapper<>();
jqlqw.likeRight(Jqd::getXzqh,"3401")
.ge(Jqd::getScbjsj,"2025-07-01")
jqlqw.likeRight(Jqd::getXzqh,xzqh)
.ge(Jqd::getScbjsj,startTime)
.isNotNull(Jqd::getSfdz)
.ne(Jqd::getSfdz,"地址不详")
.ne(Jqd::getSfdz,"地址未知")
@ -145,7 +201,7 @@ public class DataMigrationService {
if (StrUtil.isBlank(query)) continue;
log.debug("📡 正在调用第三方 API 查询: {}", query); // ✅ 加日志
// 调用接口获取解析结果
ParsedResult result = callThirdPartyApi(query);
ParsedResult result = callThirdPartyApiNew(query);
if (result == null || StrUtil.isBlank(result.getName())) {
continue;
}
@ -165,6 +221,10 @@ public class DataMigrationService {
poi.setAddress(result.getAddress());
poi.setLatitude(src.getYzb());
poi.setLongitude(src.getXzb());
poi.setJzssfjdm(src.getJzssfjdm());
poi.setJzssfjmc(src.getJzssfjmc());
poi.setXqdwdm(src.getXqdwdm());
poi.setXqdwmc(src.getXqdwmc());
poi.setGadwdm(src.getJzxqdwdm());
poi.setGadwmc(src.getJzxqdwmc());
poi.setPoiTypeCode(src.getSfdzfldm());
@ -181,6 +241,10 @@ public class DataMigrationService {
poi.setAddress(result.getAddress());
poi.setLatitude(src.getYzb());
poi.setLongitude(src.getXzb());
poi.setJzssfjdm(src.getJzssfjdm());
poi.setJzssfjmc(src.getJzssfjmc());
poi.setXqdwdm(src.getXqdwdm());
poi.setXqdwmc(src.getXqdwmc());
poi.setGadwdm(src.getJzxqdwdm());
poi.setGadwmc(src.getJzxqdwmc());
poi.setPoiTypeCode(src.getSfdzfldm());
@ -197,6 +261,10 @@ public class DataMigrationService {
poi.setAddress(result.getAddress());
poi.setLatitude(src.getYzb());
poi.setLongitude(src.getXzb());
poi.setJzssfjdm(src.getJzssfjdm());
poi.setJzssfjmc(src.getJzssfjmc());
poi.setXqdwdm(src.getXqdwdm());
poi.setXqdwmc(src.getXqdwmc());
poi.setGadwdm(src.getJzxqdwdm());
poi.setGadwmc(src.getJzxqdwmc());
poi.setPoiTypeCode(src.getSfdzfldm());
@ -212,6 +280,10 @@ public class DataMigrationService {
aoi.setAddress(result.getAddress().replaceAll(result.getPoi(),""));
aoi.setLatitude(src.getYzb());
aoi.setLongitude(src.getXzb());
poi.setJzssfjdm(src.getJzssfjdm());
poi.setJzssfjmc(src.getJzssfjmc());
poi.setXqdwdm(src.getXqdwdm());
poi.setXqdwmc(src.getXqdwmc());
aoi.setGadwdm(src.getJzxqdwdm());
aoi.setGadwmc(src.getJzxqdwmc());
aoi.setPoiTypeCode(src.getSfdzfldm());
@ -295,6 +367,114 @@ public class DataMigrationService {
}
}
/*
*
*
* */
private ParsedResult callThirdPartyApiNew(String query) {
try {
// 构造 messages
JSONArray messages = new JSONArray();
messages.add(new JSONObject().set("role", "system").set("content", SYSTEM_PROMPT));
messages.add(new JSONObject().set("role", "user").set("content", query));
// 构建请求体
JSONObject requestBody = new JSONObject()
.set("model", "Qwen3-32B")
.set("messages", messages)
.set("max_tokens", 3000)
.set("temperature", 0)
.set("seed",42)
.set("top_p", 0.9);
// 发送 HTTP 请求
String response = HttpUtil.createPost(apiUrl)
.header("Authorization", "Bearer " + bearerToken)
.header("Content-Type", "application/json")
.timeout(15000)
.body(requestBody.toString())
.execute()
.body();
log.debug("📡 原始响应: {}", response);
// 解析响应
JSONObject jsonResponse = JSONUtil.parseObj(response);
JSONArray choices = jsonResponse.getJSONArray("choices");
if (choices == null || choices.isEmpty()) {
log.warn("❌ API 返回无 choices");
return null;
}
String content = choices.get(0, JSONObject.class)
.getJSONObject("message")
.getStr("content");
if (StrUtil.isBlank(content)) {
log.warn("❌ content 为空");
return null;
}
// 提取纯 JSON
String cleanJson = extractPureJsonFromContent(content);
if (StrUtil.isBlank(cleanJson)) {
log.warn("❌ 无法提取有效 JSON原始内容: {}", content);
return null;
}
JSONObject resultJson = JSONUtil.parseObj(cleanJson);
String aoi = resultJson.getStr("aoi", "");
String poi = resultJson.getStr("poi", "");
String address = resultJson.getStr("address", "");
String name = StrUtil.isNotBlank(aoi) ? aoi : address;
if (StrUtil.isBlank(name)) {
log.warn("❌ name 为空,跳过该结果");
return null;
}
return new ParsedResult(name, aoi, poi, address);
} catch (Exception e) {
log.error("调用新接口失败query={}", query, e);
return null;
}
}
/*
*
*
* */
private String extractPureJsonFromContent(String content) {
if (StrUtil.isBlank(content)) return null;
// 移除 <think>...</think>
content = content.replaceAll("(?s)<think>.*?</think>", "");
// 去掉首尾空白
content = content.trim();
// 尝试直接解析
if (JSONUtil.isJson(content)) {
return content;
}
// 尝试从可能包含的 markdown 或文本中提取 {...}
Pattern pattern = Pattern.compile("\\{\\s*\"aoi\"\\s*:.*?\\}", Pattern.DOTALL);
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
String jsonCandidate = matcher.group().trim();
if (JSONUtil.isJson(jsonCandidate)) {
return jsonCandidate;
}
}
// 最后尝试修复常见问题:补全引号、去掉注释等(可选)
return null;
}
// 提取 ```json{...}``` 中内容
private String extractJsonFromMarkdown(String answer) {
Pattern pattern = Pattern.compile("```json\\s*([\\s\\S]*?)\\s*```", Pattern.CASE_INSENSITIVE);

View File

@ -9,7 +9,7 @@
</resultMap>
<select id="selectJq" resultMap="jqdResult">
select sfdz,sfdzfldm,sfdzflmc,xzb,yzb,jzxqdwdm,jzxqdwmc,scbjsj from jqd
select sfdz,sfdzfldm,sfdzflmc,xzb,yzb,jzssfjdm,jzssfjmc,xqdwdm,xqdwmc,jzxqdwdm,jzxqdwmc,scbjsj from jqd
${ew.getCustomSqlSegment}
</select>