派送成本预估逻辑
功能想达到效果: 所有订单的成本能准确计算出来
难点:末端报价千奇百怪,没什么规律
解决思想:分类找报价,先把大部分的地区报价规律化,根据已有的报价方式总结规律
解决方案:分类根据固定格式导入报价,计算报价时根据类型,写死的格式查找
结果:目前基本上涵盖了所有报价方式
缺点:产品经理导入报价不灵活,必须根据后端提供的几种格式导入报价
方案二: 灵活组排,按规则查找报价,导入任意组合
都在图里:
1.目前系统写的查找逻辑
/**
* 写死的查找顺序
* @param logisticsId 派送商id
* @param keys 参与查找报价的字段 {"GB","LHR","103","N"}
* @param type 报价类型 1.邮编分区 2.国家邮编分区 3.目的港邮编分区 4.混合分区 其它或0.国家分区
* @return
*/
public static List<String> findLogistPriceKeys(String logisticsId,String [] keys,Integer type){
List<String> returnKeys = new ArrayList<>();
if(type == 1){
//邮编找报价
if (keys[2].length() >= 5) {
returnKeys.add(logisticsId + keys[2].substring(0, 5));
}
returnKeys.add(logisticsId+keys[2].substring(0,3));
}else if(type ==2){
//国家+邮编找报价
if (keys[2].length() >= 5) {
returnKeys.add(logisticsId + keys[0] + keys[2].substring(0, 5));
}
returnKeys.add(logisticsId+keys[0]+keys[2].substring(0,3));
}else if(type == 3){
//按目的港+邮编找报价
if (keys[2].length() >= 5) {
returnKeys.add(logisticsId + keys[1] + keys[2].substring(0, 5));
}
returnKeys.add(logisticsId+keys[1]+keys[2].substring(0,3));
}else if(type ==4){
//混合查找
//1.国家+港口+邮编+是否一票多件找
if (keys[2].length() >= 5) {
returnKeys.add(logisticsId + keys[0] + "-" + keys[1] + "-" + keys[2].substring(0, 5) + "-" + keys[3]);
}
returnKeys.add(logisticsId + keys[0] + "-" + keys[1] + "-" + keys[2].substring(0, 3) + "-" + keys[3]);
//2.国家+邮编+是否一票多件找
if (keys[2].length() >= 5) {
returnKeys.add(logisticsId + keys[0] + "--" + keys[2].substring(0, 5) + "-" + keys[3]);
}
returnKeys.add(logisticsId + keys[0] + "--" + keys[2].substring(0, 3) + "-" + keys[3]);
//3.国家+是否一票多件找
returnKeys.add(logisticsId + keys[0] + "---" + keys[3]);
//4.国家+港口+邮编
if (keys[2].length() >= 5) {
returnKeys.add(logisticsId + keys[0] + "-" + keys[1] + "-" + keys[2].substring(0, 5) + "-" );
}
returnKeys.add(logisticsId + keys[0] + "-" + keys[1] + "-" + keys[2].substring(0, 3) + "-" );
//5.国家+邮编
if (keys[2].length() >= 5) {
returnKeys.add(logisticsId + keys[0] + "--" + keys[2].substring(0, 5) + "-" );
}
returnKeys.add(logisticsId + keys[0] + "--" + keys[2].substring(0, 3) + "-" );
//6.国家
returnKeys.add(logisticsId + keys[0] + "---");
}else{
//按国家查询
returnKeys.add(logisticsId+keys[0]);
}
return returnKeys;
}
2.按规律灵活组排(考虑是否要使用)
/**
* 动态的查找顺序
* @param ss 参与查找的字段项 {"GB","LHR","103","N"} {1,2,3,4}
* @param selected 每个字段项是否必需有 {0,0,0,0}
* @param postIndex 邮编数组下标
* @return
*/
public static List<String> sortKeys(String[] ss,Integer[] selected,int postIndex){
Set<Map<String,Object>> keyList = new HashSet<>();
String postCode = ss[postIndex];
//找出参与查找字段项顺序不变情况下的所有组合
getArray(keyList,ss,new Integer[ss.length],0,selected,postIndex);
//按设置好的数字大小排序,规则数组越后面越先查找规则
List<Map<String, Object>> list = new ArrayList<>(keyList);
Collections.sort(list, new Comparator<Map<String, Object>>() {
public int compare(Map<String, Object> u1, Map<String, Object> u2) {
Double diff = Double.parseDouble(u2.get("key")+"")-Double.parseDouble(u1.get("key")+"");
if (diff > 0) {
return 1;
}else if (diff < 0) {
return -1;
}
return 0; //相等为0
}
});
List<String> keys = new ArrayList<>();
if(StringUtils.isNotEmpty(postCode) && postCode.length() > 5){
ss[postIndex] = postCode.substring(0,5);
keys.add(String.join("-",ss));
}
ss[postIndex] = postCode.substring(0,3);
keys.add(String.join("-", ss));
for(Map<String,Object> m:list){
System.out.println(m.get("key"));
System.out.println(m.get("value"));
keys.add(String.valueOf(m.get("value")));
}
return keys;
}
public static void getArray(Set<Map<String,Object>> keyList,String[] ss,Integer[] indexs,Integer n,Integer[] selected,Integer postIndex){
for(int b =0 ; b < ss.length;b++) {
indexs[n]=b;
if(n == (ss.length-1)){
String[] ss1 = new String[ss.length];
for (int c = 0; c < ss.length; c++) {
ss1[c] = ss[c] + "";
}
for (Integer i : indexs) {
ss1[i] = "";
}
boolean isSelected = true;
for(int l = 0; l < ss1.length; l++){
if(StringUtils.isEmpty(ss1[l]) && selected[l] ==1){
isSelected = false;
break;
}
}
double index = 0;
for (int x = 0; x < ss1.length; x++) {
if (StringUtils.isNotEmpty(ss1[x])) {
index = index + (x + 1) * Math.pow(10, x);
}
}
String postCode = ss1[postIndex];
if(StringUtils.isNotEmpty(postCode) && postCode.length() > 5) {
ss1[postIndex] = postCode.substring(0,5);
String str1 = String.join("-", ss1);
if (!str1.equals("---") && isSelected) {
Map<String, Object> m = new HashMap<>();
m.put("key", index + 0.1);
m.put("value", str1);
keyList.add(m);
}
}
if(StringUtils.isNotEmpty(postCode)) {
ss1[postIndex] = postCode.substring(0, 3);
}
String str1 = String.join("-", ss1);
if (!str1.equals("---") && isSelected) {
Map<String, Object> m = new HashMap<>();
m.put("key", index);
m.put("value", str1);
keyList.add(m);
}
}
if(n<(ss.length-1)){
getArray(keyList,ss,indexs,n+1,selected,postIndex);
}
}
}
public static void main(String[] args) {
/**
* 参选项按顺序排,数组下标越大越优先查询
*/
String[] sss = new String[]{"GB","LHR","123456","N"};
/**
* 数组填1 必选
*/
Integer[] selected = new Integer[]{0,0,0,0};
List<String> sortList = LogisticsPriceKeyUtil.sortKeys(sss,selected,2);
System.out.println("排序结果:---------------------");
for(String sort : sortList) {
System.out.println(sort);
}
}