引言:因为业务员外出打卡,用的纷享销客CRM的定位,有时候无法回传对应的乡镇信息(估计相当一部分客户估计都没有这个字段),如果此时详细地址有填写的情况下,可以使用本文方法。groovy,只适用于初级学习开发者。高手大神略过。
注意:因为CRM系统调用高德定位回传,接口并没有暴露出现,所以我就自己用最笨的方法写了,适用于地址结构为:国-省-市-区-乡镇的,因为我的方法就是截取对应的字符回查,之前全网搜索对应的技术都并没有适合CRM的,所以就自己摸索写了,里面部分逻辑可能有点乱,备注信息是我自己看的,不建议直接理解。读者可以自己修改。
//查客户信息
String Addresss = context.data.address
log.debug(Addresss)
String id = context.data._id
/当前地址解析方式,只适用于当前的省市区县乡镇的排序使用,其余暂无匹配
def processAddress = { String addr ->
int cityCount = Addresss.count('市');
int districyCount = addr.count('区');
boolean streetIndex = Addresss.contains("街道");
def directMunicipalities = ['天津', '上海', '北京', '重庆'];
def directMunicipalities2 = ['广西壮族自治区', '宁夏回族自治区', '新疆维吾尔自治区', '香港特别行政区', '澳门特别行政区', '西藏自治区', '内蒙古自治区'];
def directMunicipalities3 = ['黔西南布依族苗族自治州', '黔东南苗族侗族自治州', '黔南布依族苗族自治州', '延边朝鲜族自治州',"红河哈尼族彝族自治州","文山壮族苗族自治州","阿坝藏族芜族自治州","西双版咋傣族自治州","甘孜藏族自治州","大理白族自治州","凉山彝族自治州","海南藏族自治州","果洛藏族自治州","楚雄彝族自治州","湘西土家族苗族自治州","西双版纳傣族自治州","黄南藏族自治州","海北藏族自治州","临夏回族自治州"];
/洲府地址处理方式
if( directMunicipalities3.any { municipality -> addr.contains(municipality)} )
{
def cityIdx = addr.indexOf("县")
if (cityIdx ==-1)
cityIdx = addr.indexOf("区")
if (cityIdx ==-1)
cityIdx = addr.indexOf("市")
if (cityIdx ==-1)
cityIdx = addr.indexOf("街道")
// 确定起始位置
def startIdx = cityIdx + 1
// 确定结束位置
def endIdx
def endIdxCandidates = [
addr.indexOf("区", startIdx),
addr.indexOf("乡", startIdx),
addr.indexOf("镇", startIdx),
addr.indexOf("街道", startIdx),
addr.indexOf("县", startIdx),
]
// 去除-1的无效值
endIdxCandidates = endIdxCandidates.findAll { it != -1 }
// 如果没有找到任何有效结束位置,则直接返回空字符串
if (endIdxCandidates.isEmpty()) {
println("")
return
}
// 取最小的有效结束位置
endIdx = endIdxCandidates.min()
// 特殊处理“街道”
if (addr.contains("街道")) {
endIdx += 2
} else {
// 防止索引越界
endIdx = Math.min(endIdx + 1, addr.length())
}
// 返回截取的子串
return addr.substring(startIdx, endIdx)
}
/洲府地址处理方式
/自治区地址处理方式
/判断地址最后2个字符是不是包含“区”
def lastTwoChars = addr.substring(addr.length() - 2)
def containsQu = lastTwoChars.contains("区")
/判断地址最后2个字符是不是包含“区”,记得加上自治区条件
if( containsQu && directMunicipalities2.any { municipality -> addr.contains(municipality) }){
addr = addr.substring(0, addr.length() - 1) // 去掉最后一个字符
// 找到“区”的位置
def cityIdx = addr.indexOf("县")
if (cityIdx ==-1)
cityIdx = addr.indexOf("区")
if (cityIdx ==-1)
cityIdx = addr.indexOf("市")
// 确定起始位置
def startIdx = cityIdx + 1
// 确定结束位置
def endIdx
def endIdxCandidates = [
addr.indexOf("区", startIdx),
addr.indexOf("乡", startIdx),
addr.indexOf("镇", startIdx),
addr.indexOf("街道", startIdx),
addr.indexOf("县", startIdx),
]
// 去除-1的无效值
endIdxCandidates = endIdxCandidates.findAll { it != -1 }
// 如果没有找到任何有效结束位置,则直接返回空字符串
if (endIdxCandidates.isEmpty()) {
println("")
return
}
// 取最小的有效结束位置
endIdx = endIdxCandidates.min()
// 特殊处理“街道”
if (addr.substring(startIdx, endIdx).contains("街道")) {
endIdx += 2
} else {
// 防止索引越界
endIdx = Math.min(endIdx + 1, addr.length())
}
// 返回截取的子串
return addr.substring(startIdx, endIdx)
}
if (directMunicipalities2.any { municipality -> addr.contains(municipality) }) {
//包含2个“区”以上的处理方式
if( districyCount>=2 ){
def firstCityIdx = addr.indexOf("区")
def secondCityIdx = addr.indexOf("区", firstCityIdx + 1)
// 初始化startIdx为第二个“区”的索引值
def startIdx = secondCityIdx
if (startIdx != -1) {
startIdx += 1 // 跳过“区”本身
} else {
// 如果没有找到第二个“区”,直接返回空字符串
return ""
}
// 确定endIdx
def endIdx
def endIdxCandidates = [
addr.indexOf("区", startIdx),
addr.indexOf("乡", startIdx),
addr.indexOf("镇", startIdx),
addr.indexOf("街道", startIdx),
addr.indexOf("县", startIdx),
addr.indexOf("市", startIdx)
]
// 去除-1的无效值
endIdxCandidates = endIdxCandidates.findAll { it != -1 }
// 如果没有找到任何有效结束位置,则直接返回空字符串
if (endIdxCandidates.isEmpty()) {
return ""
}
// 取最小的有效结束位置
endIdx = endIdxCandidates.min()
// 特殊处理“街道”
if (addr.contains("街道")) {
endIdx = Math.min(endIdx+2, addr.length())
} else {
// 防止索引越界
endIdx = Math.min(endIdx+1, addr.length())
}
// 返回截取的子串
return addr.substring(startIdx, endIdx)
}
//包含一个“区”的处理方式
else{
// 找到“区”的位置
def cityIdx = addr.indexOf("县")
if (cityIdx ==-1)
cityIdx = addr.indexOf("区")
if (cityIdx ==-1)
cityIdx = addr.indexOf("市")
// 确定起始位置
def startIdx = cityIdx + 1
// 确定结束位置
def endIdx
def endIdxCandidates = [
addr.indexOf("区", startIdx),
addr.indexOf("乡", startIdx),
addr.indexOf("镇", startIdx),
addr.indexOf("街道", startIdx),
addr.indexOf("县", startIdx),
]
// 去除-1的无效值
endIdxCandidates = endIdxCandidates.findAll { it != -1 }
// 如果没有找到任何有效结束位置,则直接返回空字符串
if (endIdxCandidates.isEmpty()) {
println("")
return
}
// 取最小的有效结束位置
endIdx = endIdxCandidates.min()
// 特殊处理“街道”
if (addr.substring(startIdx, endIdx).contains("街道")) {
endIdx += 2
} else {
// 防止索引越界
endIdx = Math.min(endIdx + 2, addr.length())
}
// 返回截取的子串
return addr.substring(startIdx, endIdx)
}
}
/自治区地址处理方式
if (cityCount == 1 && streetIndex == true|| addr.contains("市场")) {
def startIdx = addr.indexOf("区")
if (startIdx == -1) {
startIdx = addr.indexOf("县")
}
if (startIdx == -1) return ""
// 增加对"乡"和"镇"的支持
def endIdx = Math.max(addr.indexOf("街道"), Math.max(addr.indexOf("乡"), addr.indexOf("镇")))
if (endIdx == -1) {
return "" // 如果找不到结束位置,直接返回空字符串
}
if(directMunicipalities.any { municipality ->addr.contains(municipality) && (addr.contains("乡") || addr.contains("镇"))})
{
endIdx = Math.min(endIdx + 1, addr.length()) // 防止索引越界,并确保包含“街道”
startIdx += ("区".equals(addr.substring(startIdx, startIdx + 1)) || "县".equals(addr.substring(startIdx, startIdx + 1))) ? 1 : 0
return addr.substring(startIdx, endIdx)
}else{
endIdx = Math.min(endIdx + 2, addr.length()) // 防止索引越界,并确保包含“街道”
startIdx += ("区".equals(addr.substring(startIdx, startIdx + 1)) || "县".equals(addr.substring(startIdx, startIdx + 1))) ? 1 : 0
return addr.substring(startIdx, endIdx)
}
}
else if (cityCount == 1) { def startIdx = addr.indexOf("区")
if (startIdx == -1) {
startIdx = addr.indexOf("县")
}
if (startIdx == -1) return ""
// 增加对"乡"和"镇"的支持
def endIdx = addr.indexOf("街道")
if (endIdx == -1) {
endIdx = Math.max(
Math.max(addr.indexOf("区"),
Math.max(addr.indexOf("乡"), addr.indexOf("镇"))),
addr.indexOf("农场")
)
// 防止索引越界,并确保包含“街道”或“农场”
if( addr.contains("街道")||addr.contains("农场")){
endIdx = Math.min(endIdx +=2, addr.length())
}else if( addr.contains("区")||addr.contains("镇")||addr.contains("乡") ){
endIdx = Math.min(endIdx +=1, addr.length())
}
}else{
endIdx = Math.max(endIdx +=1, addr.length())
}
// 调整 startIdx 以跳过“区”或“县”
startIdx += ("区".equals(addr.substring(startIdx, startIdx + 1)) || "县".equals(addr.substring(startIdx, startIdx + 1))) ? 1 : 0
//endIdx = Math.min(addr.indexOf("镇") + 1, addr.length())
return addr.substring(startIdx, endIdx)
}
else if (cityCount >= 2) {
def firstCityIdx = addr.indexOf("市")
def secondCityIdx = addr.indexOf("市", firstCityIdx + 1)
def startIdx = addr.indexOf("市", secondCityIdx)
if (startIdx == -1)
startIdx = addr.indexOf("区", secondCityIdx)
if (startIdx == -1)
startIdx = addr.indexOf("街道", secondCityIdx)
if (startIdx == -1)
startIdx = addr.indexOf("县", secondCityIdx)
if (startIdx == -1)
startIdx = addr.indexOf("镇", secondCityIdx)
// 寻找结束索引
def endIdx = addr.indexOf("街道", secondCityIdx)
if (endIdx == -1) {
endIdx = Math.max(
Math.max(addr.indexOf("区", secondCityIdx),
Math.max(addr.indexOf("乡", secondCityIdx), addr.indexOf("镇", secondCityIdx))),
addr.indexOf("街道", secondCityIdx)
)
endIdx = Math.min(endIdx + 1, addr.length()) // 防止索引越界
// 返回截取的子串
return addr.substring(secondCityIdx + 1, endIdx)
}else{
endIdx = Math.min(endIdx + 2, addr.length()) // 防止索引越界,同时如果是”街道“,则需要+2。
// 返回截取的子串
return addr.substring(secondCityIdx + 1, endIdx)
}
}
// 如果没有找到符合条件的部分,则返回空字符串或错误信息
return ""
}
/当前地址解析方式,只适用于当前的省市区县乡镇的排序使用,其余暂无匹配
// 测试函数
def testAddresses = [
Addresss
]
testAddresses.each { addr ->
log.debug("处理地址:$addr")
log.debug("提取结果:" + processAddress(addr))
String xiangzhen = processAddress(addr)
log.debug(xiangzhen)
//转换成数字代码
String town = Fx.location.findCountryAreaCode(xiangzhen,"town")
log.debug(town)
//更新对应的乡镇
if( context.data.town==null ){
String objectAPIName = 'AccountObj'
String dataId = id
Map updateData = [
"town":town
]
def (Boolean error1, Map data1, String errorMessage1) = Fx.object.update(objectAPIName, dataId, updateData, UpdateAttribute.builder().triggerWorkflow(true).build())
if (error1) {
log.info("error:" + errorMessage1 )
}
log.info("已更新乡镇字段为"+xiangzhen)
}else{
log.info("无需更新")
}
}