运费提示更加精细化,完善程序
This commit is contained in:
parent
ea94c40b72
commit
b18497cb93
@ -56,10 +56,10 @@ public class ShopStoreSameCityTransportBase implements Serializable {
|
||||
private String store_address;
|
||||
|
||||
@ApiModelProperty(value = "店铺经度")
|
||||
private BigDecimal store_longitude;
|
||||
private String store_longitude;
|
||||
|
||||
@ApiModelProperty(value = "店铺纬度")
|
||||
private BigDecimal store_latitude;
|
||||
private String store_latitude;
|
||||
|
||||
@ApiModelProperty(value = "区域类型:1-按不同距离")
|
||||
private Integer area_type;
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.suisung.mall.common.pojo.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 同城配送运费计算结果实体
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DeliveryFeeResultDTO implements Serializable {
|
||||
// 规则id
|
||||
private Long id;
|
||||
// 显示优先级
|
||||
private Integer level;
|
||||
// 全部通过
|
||||
private Boolean allPassed;
|
||||
// 距离通过
|
||||
private Boolean distancePassed;
|
||||
|
||||
// 超出多少距离
|
||||
private Integer diffDistance;
|
||||
// 金额通过
|
||||
private Boolean moneyPassed;
|
||||
|
||||
// 还差多少金额可以起送
|
||||
private BigDecimal diffMoney;
|
||||
|
||||
// 距离不通过具体原因
|
||||
private String distanceReason;
|
||||
// 金额不通过具体原因
|
||||
private String moneyReason;
|
||||
// 豁免金额
|
||||
private BigDecimal fee;
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.suisung.mall.common.pojo.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 经纬度实体类
|
||||
*/
|
||||
public class GpsDTO implements Serializable {
|
||||
private double wgLat;
|
||||
private double wgLon;
|
||||
|
||||
public GpsDTO(double lat, double lon) {
|
||||
wgLat = lat;
|
||||
wgLon = lon;
|
||||
}
|
||||
|
||||
public double getWgLat() {
|
||||
return wgLat;
|
||||
}
|
||||
|
||||
public void setWgLat(double wgLat) {
|
||||
this.wgLat = wgLat;
|
||||
}
|
||||
|
||||
public double getWgLon() {
|
||||
return wgLon;
|
||||
}
|
||||
|
||||
public void setWgLon(double wgLon) {
|
||||
this.wgLon = wgLon;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.suisung.mall.common.pojo.res;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 百度地图坐标转换返回实体类
|
||||
*/
|
||||
public class BaiduMapLbsRes implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer status;
|
||||
private List<BaiduMapLbsResult> result;
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public List<BaiduMapLbsResult> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(List<BaiduMapLbsResult> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public class BaiduMapLbsResult implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Double x;
|
||||
private Double y;
|
||||
|
||||
public Double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(Double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public Double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(Double y) {
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.suisung.mall.common.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.suisung.mall.common.pojo.dto.GpsDTO;
|
||||
import com.suisung.mall.common.pojo.res.BaiduMapLbsRes;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
/**
|
||||
* 百度坐标系转换类
|
||||
*/
|
||||
@Service
|
||||
public class BaiduMapServiceImpl {
|
||||
|
||||
@Value("${baidu.map.ak}")
|
||||
private final String ak = "qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v";
|
||||
|
||||
@Value("${baidu.map.url}")
|
||||
private final String url = "https://api.map.baidu.com/geoconv/v2/?";
|
||||
|
||||
public static void main(String[] args) {
|
||||
GpsDTO g = new BaiduMapServiceImpl().convGpsLntLat("116.418036", "39.922861", 5);
|
||||
System.out.printf("%f,%f", g.getWgLon(), g.getWgLat());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 百度 API 坐标转换
|
||||
* 参考:https://lbsyun.baidu.com/faq/api?title=webapi/guide/changeposition-base
|
||||
* 默认ak
|
||||
* model: 1:amap/tencent to bd09ll
|
||||
* 2:gps to bd09ll
|
||||
* 3:bd09ll to bd09mc
|
||||
* 4:bd09mc to bd09ll
|
||||
* 5:bd09ll to amap/tencent
|
||||
* 6:bd09mc to amap/tencent
|
||||
* 选择了ak,使用IP白名单校验:
|
||||
* 根据您选择的AK已为您生成调用代码
|
||||
* 检测到您当前的ak设置了IP白名单校验
|
||||
* 您的IP白名单中的IP非公网IP,请设置为公网IP,否则将请求失败
|
||||
* 请在IP地址为0.0.0.0/0 外网IP的计算发起请求,否则将请求失败
|
||||
*/
|
||||
public GpsDTO convGpsLntLat(String lng, String lat, int model) {
|
||||
if (StrUtil.isBlank(lng) || StrUtil.isBlank(lat)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder queryString = new StringBuilder();
|
||||
queryString.append(url);
|
||||
queryString.append("ak=").append(ak).append("&model=").append(model).append("&coords=").append(lng).append(",").append(lat);
|
||||
|
||||
InputStreamReader isr = null;
|
||||
BufferedReader reader = null;
|
||||
|
||||
try {
|
||||
java.net.URL url = new URL(queryString.toString());
|
||||
System.out.println(queryString);
|
||||
URLConnection httpConnection = url.openConnection();
|
||||
httpConnection.connect();
|
||||
|
||||
isr = new InputStreamReader(httpConnection.getInputStream());
|
||||
reader = new BufferedReader(isr);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
buffer.append(line);
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(buffer.toString())) {
|
||||
return null;
|
||||
}
|
||||
BaiduMapLbsRes respJson = JSONUtil.toBean(buffer.toString(), BaiduMapLbsRes.class);
|
||||
if (respJson != null && respJson.getStatus() != null && respJson.getStatus().equals(0) && CollUtil.isNotEmpty(respJson.getResult())) {
|
||||
return new GpsDTO(respJson.getResult().get(0).getY(), respJson.getResult().get(0).getX());
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (isr != null) {
|
||||
try {
|
||||
isr.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
package com.suisung.mall.common.utils;
|
||||
|
||||
import com.suisung.mall.common.pojo.dto.GpsDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.awt.geom.GeneralPath;
|
||||
@ -19,13 +20,59 @@ import java.util.List;
|
||||
* 地图计算两点距离工具类,该类只是候选类,
|
||||
* 建议优先从百度api或高德api上获取两点距离,这样更加准确
|
||||
* 无法获取到距离时,再使用该类的方法
|
||||
* <p>
|
||||
* 坐标系 解释 使用地图
|
||||
* WGS84 地球坐标系, 国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,最基础的坐标,谷歌地图在非中国地区使用的坐标系 GPS/谷歌地图卫星
|
||||
* GCJ02 火星坐标系, 是由中国国家测绘局制订的地理信息系统的坐标系统。并要求在中国使用的地图产品使用的都必须是加密后的坐标,而这套WGS84加密后的坐标就是gcj02。 腾讯(搜搜)地图,阿里云地图,高德地图,谷歌国内地图
|
||||
* BD09 百度坐标系, 百度在GCJ02的基础上进行了二次加密,官方解释是为了进一步保护用户隐私 百度地图
|
||||
* 小众坐标系 类似于百度地图,在GCJ02基础上使用自己的加密算法进行二次加密的坐标系 搜狗地图、图吧地图 等
|
||||
*
|
||||
* @author 潘军杰
|
||||
* @since 2024-01-22
|
||||
*/
|
||||
public class PositionUtil {
|
||||
|
||||
private final static double EARTH_RADIUS = 6378137;//地球半径
|
||||
public static double pi = Math.PI;
|
||||
public static double a = 6378245.0;
|
||||
public static double ee = 0.00669342162296594323;
|
||||
|
||||
//(116.368904, 39.923423) (116.387271, 39.772501)
|
||||
public static void main(String[] args) {
|
||||
double lon1 = 110.08;
|
||||
double lat1 = 23.39;
|
||||
double lon2 = 110.084376;
|
||||
double lat2 = 23.394216;
|
||||
|
||||
//116.411490, 39.916157, 116.35295465843627, 40.014744649795254
|
||||
|
||||
double dist = getDistance1(116.4116491767874, 39.91657857138054, 116.35295465843627, 40.014744649795254);
|
||||
System.out.println("输出结果:" + dist);
|
||||
// BigDecimal times = NumberUtil.div(BigDecimal.valueOf(3.01), 1.0).setScale(0, RoundingMode.UP);
|
||||
// System.out.println(times);
|
||||
|
||||
GpsDTO g = bd09ToGcj02( 116.418036,39.922861);
|
||||
System.out.printf("%f,%f", g.getWgLon(), g.getWgLat());
|
||||
|
||||
}
|
||||
|
||||
public static boolean outOfChina(double lat, double lon) {
|
||||
if (lon < 72.004 || lon > 137.8347) return true;
|
||||
return lat < 0.8293 || lat > 55.8271;
|
||||
}
|
||||
|
||||
/**
|
||||
* 经纬度转化为弧度(rad)
|
||||
*
|
||||
* @param d 经度/纬度
|
||||
*/
|
||||
private static double rad(double d) {
|
||||
return d * Math.PI / 180.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法一:(反余弦计算方式)
|
||||
* 计算国内 Gcj02 坐标系两点之间的直线距离(高德地图)
|
||||
*
|
||||
* @param longitude1 第一个点的经度
|
||||
* @param latitude1 第一个点的纬度
|
||||
@ -49,12 +96,11 @@ public class PositionUtil {
|
||||
// 弧长乘赤道半径, 返回单位: 米
|
||||
|
||||
// 赤道半径(单位:米)
|
||||
double EQUATOR_RADIUS = 6378137;
|
||||
double EQUATOR_RADIUS = EARTH_RADIUS;
|
||||
s = s * EQUATOR_RADIUS;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法二:(反余弦计算方式)
|
||||
*
|
||||
@ -64,7 +110,7 @@ public class PositionUtil {
|
||||
* @param latitude2 第二点的纬度
|
||||
* @return 返回的距离,单位m
|
||||
*/
|
||||
public static double getDistance3(double longitude1, double latitude1, double longitude2, double latitude2) {
|
||||
public static double getDistance2(double longitude1, double latitude1, double longitude2, double latitude2) {
|
||||
// 经纬度(角度)转弧度。弧度作为作参数,用以调用Math.cos和Math.sin
|
||||
// A经弧度
|
||||
double radiansAX = Math.toRadians(longitude1);
|
||||
@ -92,15 +138,6 @@ public class PositionUtil {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 经纬度转化为弧度(rad)
|
||||
*
|
||||
* @param d 经度/纬度
|
||||
*/
|
||||
private static double rad(double d) {
|
||||
return d * Math.PI / 180.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法三:(基于googleMap中的算法得到两经纬度之间的距离,计算精度与谷歌地图的距离精度差不多。)
|
||||
*
|
||||
@ -110,7 +147,7 @@ public class PositionUtil {
|
||||
* @param latitude2 第二点的纬度
|
||||
* @return 返回的距离,单位m
|
||||
*/
|
||||
public static double getDistance2(double longitude1, double latitude1, double longitude2, double latitude2) {
|
||||
public static double getDistance3(double longitude1, double latitude1, double longitude2, double latitude2) {
|
||||
double radLat1 = rad(latitude1);
|
||||
double radLat2 = rad(latitude2);
|
||||
double a = radLat1 - radLat2;
|
||||
@ -158,11 +195,8 @@ public class PositionUtil {
|
||||
var20[2] = var6;
|
||||
|
||||
return Math.asin(Math.sqrt((var10[0] - var20[0]) * (var10[0] - var20[0]) + (var10[1] - var20[1]) * (var10[1] - var20[1]) + (var10[2] - var20[2]) * (var10[2] - var20[2])) / 2.0) * 1.27420015798544E7;
|
||||
// 结果四舍五入 保留2位小数
|
||||
//return new BigDecimal(distance).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断坐标点是否在圆形区域内
|
||||
* 计算这个坐标点和圆心点之间的距离,然后跟圆的半径进行比较,如果比半径大,就不在圆形区域内,如果小于等于圆的半径,则该坐标点在圆形区域内
|
||||
@ -229,4 +263,92 @@ public class PositionUtil {
|
||||
// 测试指定的 Point2D 是否在 Shape 的边界内。
|
||||
return generalPath.contains(point);
|
||||
}
|
||||
|
||||
|
||||
private static double transformLat(double x, double y) {
|
||||
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
|
||||
+ 0.2 * Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static double transformLon(double x, double y) {
|
||||
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
|
||||
* Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
|
||||
*/
|
||||
public static GpsDTO gcj02ToBd09(double lng,double lat) {
|
||||
double x = lng, y = lat;
|
||||
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
|
||||
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
|
||||
double bd_lon = z * Math.cos(theta) + 0.0065;
|
||||
double bd_lat = z * Math.sin(theta) + 0.006;
|
||||
return new GpsDTO(bd_lat, bd_lon);
|
||||
}
|
||||
|
||||
/**
|
||||
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 BD-09 坐标转换成GCJ-02 坐标
|
||||
*/
|
||||
public static GpsDTO bd09ToGcj02(double lng,double lat) {
|
||||
double x = lng - 0.0065, y = lat - 0.006;
|
||||
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
|
||||
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
|
||||
double gg_lon = z * Math.cos(theta);
|
||||
double gg_lat = z * Math.sin(theta);
|
||||
return new GpsDTO(gg_lat, gg_lon);
|
||||
}
|
||||
|
||||
/**
|
||||
* 地球坐标系 (WGS84) 与火星坐标系 (GCJ-02) 的转换算法 将 WGS84 坐标转换成 GCJ-02 坐标
|
||||
*/
|
||||
public static GpsDTO gps84ToGcj02( double lon,double lat) {
|
||||
if (outOfChina(lat, lon)) {
|
||||
return null;
|
||||
}
|
||||
double dLat = transformLat(lon - 105.0, lat - 35.0);
|
||||
double dLon = transformLon(lon - 105.0, lat - 35.0);
|
||||
double radLat = lat / 180.0 * pi;
|
||||
double magic = Math.sin(radLat);
|
||||
magic = 1 - ee * magic * magic;
|
||||
double sqrtMagic = Math.sqrt(magic);
|
||||
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
|
||||
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
|
||||
double mgLat = lat + dLat;
|
||||
double mgLon = lon + dLon;
|
||||
return new GpsDTO(mgLat, mgLon);
|
||||
}
|
||||
|
||||
/**
|
||||
* 地球坐标系 (WGS84) 与火星坐标系 (GCJ-02) 的转换算法 将 GCJ-02 坐标转换成 WGS84 坐标
|
||||
*/
|
||||
public static GpsDTO gcjToGps84(double lng,double lat) {
|
||||
GpsDTO gps = transform(lat, lng);
|
||||
double lontitude = lng * 2 - gps.getWgLon();
|
||||
double latitude = lat * 2 - gps.getWgLat();
|
||||
return new GpsDTO(latitude, lontitude);
|
||||
}
|
||||
|
||||
private static GpsDTO transform(double lng,double lat) {
|
||||
if (outOfChina(lat, lng)) return new GpsDTO(lat, lng);
|
||||
double dLat = transformLat(lng - 105.0, lat - 35.0);
|
||||
double dLon = transformLon(lng - 105.0, lat - 35.0);
|
||||
double radLat = lat / 180.0 * pi;
|
||||
double magic = Math.sin(radLat);
|
||||
magic = 1 - ee * magic * magic;
|
||||
double sqrtMagic = Math.sqrt(magic);
|
||||
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
|
||||
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
|
||||
double mgLat = lat + dLat;
|
||||
double mgLon = lng + dLon;
|
||||
return new GpsDTO(mgLat, mgLon);
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,4 +26,10 @@ licence:
|
||||
redis:
|
||||
id: "1001"
|
||||
separator: ":"
|
||||
expire: 3600
|
||||
expire: 3600
|
||||
|
||||
baidu:
|
||||
map:
|
||||
app_id: 116444176
|
||||
ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
|
||||
url: https://api.map.baidu.com/geoconv/v2/?
|
||||
@ -26,4 +26,10 @@ licence:
|
||||
redis:
|
||||
id: "1001"
|
||||
separator: ":"
|
||||
expire: 3600
|
||||
expire: 3600
|
||||
|
||||
baidu:
|
||||
map:
|
||||
app_id: 116444176
|
||||
ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
|
||||
url: https://api.map.baidu.com/geoconv/v2/?
|
||||
@ -27,3 +27,9 @@ redis:
|
||||
id: "1001"
|
||||
separator: ":"
|
||||
expire: 3600
|
||||
|
||||
baidu:
|
||||
map:
|
||||
app_id: 116444176
|
||||
ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
|
||||
url: https://api.map.baidu.com/geoconv/v2/?
|
||||
|
||||
@ -26,4 +26,10 @@ licence:
|
||||
redis:
|
||||
id: "1001"
|
||||
separator: ":"
|
||||
expire: 3600
|
||||
expire: 3600
|
||||
|
||||
baidu:
|
||||
map:
|
||||
app_id: 116444176
|
||||
ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
|
||||
url: https://api.map.baidu.com/geoconv/v2/?
|
||||
@ -27,3 +27,9 @@ redis:
|
||||
id: "1001"
|
||||
separator: ":"
|
||||
expire: 3600
|
||||
|
||||
baidu:
|
||||
map:
|
||||
app_id: 116444176
|
||||
ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
|
||||
url: https://api.map.baidu.com/geoconv/v2/?
|
||||
|
||||
@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -37,11 +38,12 @@ public class ShopStorePrinterController {
|
||||
@ApiOperation(value = "内部测试案例", notes = "内部测试案例")
|
||||
@RequestMapping(value = "/testcase", method = {RequestMethod.GET})
|
||||
public CommonResult TestCase() {
|
||||
// Object data = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(3L, BigDecimal.valueOf(110.07123874241765), BigDecimal.valueOf(23.366250981849255), 100, BigDecimal.valueOf(0.5), BigDecimal.valueOf(5.5), BigDecimal.valueOf(5.5), true);
|
||||
Double distanceD = PositionUtil.getDistance4(110.084376,23.394216,110.11752034714767,23.31704849881646);
|
||||
Object data = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(3L, "110.078141", "23.375037", 100, BigDecimal.valueOf(19), BigDecimal.valueOf(5.5), BigDecimal.valueOf(5.5), true);
|
||||
// Double distanceD = PositionUtil.getDistance4(110.084376,23.394216,110.11752034714767,23.31704849881646);
|
||||
|
||||
// BigDecimal s = new BigDecimal(2.50).setScale(2, RoundingMode.HALF_UP);
|
||||
// List<Integer> list = shopStoreEmployeeService.selectEmployeeByStoreId(3,"店铺管理员");
|
||||
return CommonResult.success(distanceD);
|
||||
return CommonResult.success(data);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "测试打印模版消息", notes = "测试打印模版消息")
|
||||
|
||||
@ -77,6 +77,6 @@ public interface ShopStoreSameCityTransportBaseService {
|
||||
* @param canThrow 能否抛出异常?
|
||||
* @return
|
||||
*/
|
||||
SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, BigDecimal orderLongitude, BigDecimal orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow);
|
||||
SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, String orderLongitude, String orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow);
|
||||
|
||||
}
|
||||
@ -42,11 +42,10 @@ import com.suisung.mall.common.modules.product.ShopProductBase;
|
||||
import com.suisung.mall.common.modules.product.ShopProductIndex;
|
||||
import com.suisung.mall.common.modules.store.*;
|
||||
import com.suisung.mall.common.modules.user.ShopUserFavoritesStore;
|
||||
import com.suisung.mall.common.pojo.dto.GpsDTO;
|
||||
import com.suisung.mall.common.pojo.dto.StandardAddressDTO;
|
||||
import com.suisung.mall.common.utils.CSVUtils;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.I18nUtil;
|
||||
import com.suisung.mall.common.utils.UserInfoService;
|
||||
import com.suisung.mall.common.service.impl.BaiduMapServiceImpl;
|
||||
import com.suisung.mall.common.utils.*;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
|
||||
import com.suisung.mall.shop.base.service.ShopBaseProductTagService;
|
||||
@ -170,6 +169,10 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
@Autowired
|
||||
private ThreadPoolExecutor executor;
|
||||
|
||||
@Autowired
|
||||
private BaiduMapServiceImpl baiduMapService;
|
||||
|
||||
|
||||
/**
|
||||
* 读取分页列表
|
||||
*
|
||||
@ -1456,6 +1459,10 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
return new HashMap();
|
||||
}
|
||||
}
|
||||
|
||||
// 火星坐标系GCJ02经纬度 转出 百度坐标系BD09经纬度(因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
gcj02ToBd09Gps(row);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
@ -2268,6 +2275,10 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
base.setSubsite_id(subsite_id);
|
||||
}
|
||||
|
||||
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
base = bd09ToGcj02Gps(base);
|
||||
|
||||
AccountUserBase userInfo = new AccountUserBase();
|
||||
userInfo.setUser_id(getParameter("user_id", Integer.class));
|
||||
userInfo.setUser_password(getParameter("user_password"));
|
||||
@ -2411,6 +2422,9 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
}
|
||||
}
|
||||
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
base = bd09ToGcj02Gps(base);
|
||||
|
||||
if (!saveInfo(base, info, null, company)) {
|
||||
throw new ApiException(I18nUtil._("保存店铺信息失败"));
|
||||
}
|
||||
@ -2917,4 +2931,86 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
});
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度坐标系 Bd09 经纬度转出火星坐标系 Gcj02
|
||||
*
|
||||
* @param lng
|
||||
* @param lat
|
||||
* @return
|
||||
*/
|
||||
public GpsDTO bd09ToGcj02Gps(String lng, String lat) {
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
GpsDTO gps = baiduMapService.convGpsLntLat(lng, lat, 5);
|
||||
if (gps == null) {
|
||||
logger.error("百度api坐标系Bd09ToGcj02转换失败!");
|
||||
return PositionUtil.bd09ToGcj02(NumberUtil.parseDouble(lng), NumberUtil.parseDouble(lat));
|
||||
}
|
||||
|
||||
logger.debug("百度api坐标系Bd09ToGcj02转换结果 lng,lat:{},{},原始经纬度 lng,lat:{},{}", gps.getWgLon(), gps.getWgLat(),lng, lat);
|
||||
return gps;
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度坐标系 Bd09 经纬度转出火星坐标系 Gcj02
|
||||
*
|
||||
* @param shopStoreBase
|
||||
* @return
|
||||
*/
|
||||
public ShopStoreBase bd09ToGcj02Gps(ShopStoreBase shopStoreBase) {
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
if (shopStoreBase == null || StrUtil.isBlank(shopStoreBase.getStore_longitude()) || StrUtil.isBlank(shopStoreBase.getStore_latitude())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
GpsDTO gps = bd09ToGcj02Gps(shopStoreBase.getStore_longitude(), shopStoreBase.getStore_latitude());
|
||||
if (gps == null || gps.getWgLon() == 0 || gps.getWgLat() == 0) {
|
||||
return null;
|
||||
}
|
||||
shopStoreBase.setStore_longitude(String.valueOf(gps.getWgLon()));
|
||||
shopStoreBase.setStore_latitude(String.valueOf(gps.getWgLat()));
|
||||
|
||||
return shopStoreBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* 火星坐标系Gcj02经纬度 转成 百度坐标系Bd09经纬度
|
||||
*
|
||||
* @param lng
|
||||
* @param lat
|
||||
* @return
|
||||
*/
|
||||
public GpsDTO gcj02ToBd09Gps(String lng, String lat) {
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
GpsDTO gps = baiduMapService.convGpsLntLat(lng, lat, 1);
|
||||
if (gps == null) {
|
||||
logger.debug("百度api坐标系Gcj02Tobd09转换失败!");
|
||||
return PositionUtil.gcj02ToBd09(NumberUtil.parseDouble(lng), NumberUtil.parseDouble(lat));
|
||||
}
|
||||
logger.debug("百度api坐标系Gcj02Tobd09转换结果 lng,lat:{},{},原始经纬度 lng,lat:{},{}", gps.getWgLon(), gps.getWgLat());
|
||||
return gps;
|
||||
}
|
||||
|
||||
/**
|
||||
* 火星坐标系Gcj02经纬度 转成 百度坐标系Bd09经纬度
|
||||
*
|
||||
* @param row
|
||||
* @return
|
||||
*/
|
||||
public void gcj02ToBd09Gps(Map<String, Object> row) {
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
if (row == null || row.get("store_longitude") == null || row.get("store_latitude") == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
GpsDTO gps = gcj02ToBd09Gps(row.get("store_longitude").toString(), row.get("store_latitude").toString());
|
||||
if (gps == null || gps.getWgLon() == 0 || gps.getWgLat() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
row.put("store_longitude", gps.getWgLon());
|
||||
row.put("store_latitude", gps.getWgLat());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -9,10 +9,12 @@
|
||||
package com.suisung.mall.shop.store.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.comparator.FieldComparator;
|
||||
import cn.hutool.core.comparator.FieldsComparator;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
@ -21,6 +23,7 @@ import com.suisung.mall.common.exception.ApiException;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreBase;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreSameCityTransport;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreSameCityTransportBase;
|
||||
import com.suisung.mall.common.pojo.dto.DeliveryFeeResultDTO;
|
||||
import com.suisung.mall.common.pojo.dto.KeyValueDTO;
|
||||
import com.suisung.mall.common.pojo.dto.SameCityDeliveryFeeRespDTO;
|
||||
import com.suisung.mall.common.pojo.dto.ShopStoreSameCityTransportBaseDTO;
|
||||
@ -33,7 +36,6 @@ import com.suisung.mall.shop.store.mapper.ShopStoreSameCityTransportBaseMapper;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportService;
|
||||
import io.swagger.models.auth.In;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.util.Pair;
|
||||
@ -41,7 +43,11 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
|
||||
|
||||
@ -101,8 +107,17 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
return CommonResult.failed("参数有误");
|
||||
}
|
||||
|
||||
ShopStoreBase store = shopStoreBaseService.getById(storeId);
|
||||
if (store == null || StrUtil.isBlank(store.getStore_longitude()) || StrUtil.isBlank(store.getStore_latitude())) {
|
||||
CommonResult.failed("无法获取店铺信息!");
|
||||
}
|
||||
|
||||
ShopStoreSameCityTransportBase transportBase = shopStoreSameCityTransportBaseDTO.getTransportBase();
|
||||
transportBase.setUpdated_by(userId);
|
||||
transportBase.setStore_longitude(store.getStore_longitude());
|
||||
transportBase.setStore_latitude(store.getStore_latitude());
|
||||
transportBase.setStore_address(store.getStore_address());
|
||||
|
||||
// 新增或更新同城配送基础设置
|
||||
Pair<Long, String> pair = saveOrUpdateShopStoreSameCityTransportBase(transportBase);
|
||||
|
||||
@ -130,43 +145,43 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
return CommonResult.failed("无权限操作!");
|
||||
}
|
||||
|
||||
List<KeyValueDTO> list = new ArrayList<KeyValueDTO>(){{
|
||||
add(new KeyValueDTO(1,"快餐"));
|
||||
add(new KeyValueDTO(2,"药品"));
|
||||
add(new KeyValueDTO(3,"百货"));
|
||||
add(new KeyValueDTO(4,"脏衣服收"));
|
||||
add(new KeyValueDTO(5,"干净衣服派"));
|
||||
add(new KeyValueDTO(6,"生鲜"));
|
||||
add(new KeyValueDTO(8,"高端饮品"));
|
||||
add(new KeyValueDTO(10,"快递"));
|
||||
add(new KeyValueDTO(12,"文件"));
|
||||
add(new KeyValueDTO(13,"蛋糕"));
|
||||
add(new KeyValueDTO(14,"鲜花"));
|
||||
add(new KeyValueDTO(15,"数码"));
|
||||
add(new KeyValueDTO(16,"服装"));
|
||||
add(new KeyValueDTO(17,"汽配"));
|
||||
add(new KeyValueDTO(18,"珠宝"));
|
||||
add(new KeyValueDTO(20,"披萨"));
|
||||
add(new KeyValueDTO(21,"中餐"));
|
||||
add(new KeyValueDTO(22,"水产"));
|
||||
add(new KeyValueDTO(32,"中端饮品"));
|
||||
add(new KeyValueDTO(33,"便利店"));
|
||||
add(new KeyValueDTO(34,"面包糕点"));
|
||||
add(new KeyValueDTO(35,"火锅"));
|
||||
add(new KeyValueDTO(36,"证照"));
|
||||
add(new KeyValueDTO(40,"烧烤小龙虾"));
|
||||
add(new KeyValueDTO(41,"外部落地配"));
|
||||
add(new KeyValueDTO(44,"年夜饭"));
|
||||
add(new KeyValueDTO(47,"烟酒行"));
|
||||
add(new KeyValueDTO(48,"成人用品"));
|
||||
add(new KeyValueDTO(53,"冷链医药"));
|
||||
add(new KeyValueDTO(55,"宠物用品"));
|
||||
add(new KeyValueDTO(56,"母婴用品"));
|
||||
add(new KeyValueDTO(57,"美妆用品"));
|
||||
add(new KeyValueDTO(58,"家居建材"));
|
||||
add(new KeyValueDTO(59,"眼镜行"));
|
||||
add(new KeyValueDTO(60,"图文广告"));
|
||||
add(new KeyValueDTO(81,"中药"));
|
||||
List<KeyValueDTO> list = new ArrayList<KeyValueDTO>() {{
|
||||
add(new KeyValueDTO(1, "快餐"));
|
||||
add(new KeyValueDTO(2, "药品"));
|
||||
add(new KeyValueDTO(3, "百货"));
|
||||
add(new KeyValueDTO(4, "脏衣服收"));
|
||||
add(new KeyValueDTO(5, "干净衣服派"));
|
||||
add(new KeyValueDTO(6, "生鲜"));
|
||||
add(new KeyValueDTO(8, "高端饮品"));
|
||||
add(new KeyValueDTO(10, "快递"));
|
||||
add(new KeyValueDTO(12, "文件"));
|
||||
add(new KeyValueDTO(13, "蛋糕"));
|
||||
add(new KeyValueDTO(14, "鲜花"));
|
||||
add(new KeyValueDTO(15, "数码"));
|
||||
add(new KeyValueDTO(16, "服装"));
|
||||
add(new KeyValueDTO(17, "汽配"));
|
||||
add(new KeyValueDTO(18, "珠宝"));
|
||||
add(new KeyValueDTO(20, "披萨"));
|
||||
add(new KeyValueDTO(21, "中餐"));
|
||||
add(new KeyValueDTO(22, "水产"));
|
||||
add(new KeyValueDTO(32, "中端饮品"));
|
||||
add(new KeyValueDTO(33, "便利店"));
|
||||
add(new KeyValueDTO(34, "面包糕点"));
|
||||
add(new KeyValueDTO(35, "火锅"));
|
||||
add(new KeyValueDTO(36, "证照"));
|
||||
add(new KeyValueDTO(40, "烧烤小龙虾"));
|
||||
add(new KeyValueDTO(41, "外部落地配"));
|
||||
add(new KeyValueDTO(44, "年夜饭"));
|
||||
add(new KeyValueDTO(47, "烟酒行"));
|
||||
add(new KeyValueDTO(48, "成人用品"));
|
||||
add(new KeyValueDTO(53, "冷链医药"));
|
||||
add(new KeyValueDTO(55, "宠物用品"));
|
||||
add(new KeyValueDTO(56, "母婴用品"));
|
||||
add(new KeyValueDTO(57, "美妆用品"));
|
||||
add(new KeyValueDTO(58, "家居建材"));
|
||||
add(new KeyValueDTO(59, "眼镜行"));
|
||||
add(new KeyValueDTO(60, "图文广告"));
|
||||
add(new KeyValueDTO(81, "中药"));
|
||||
}};
|
||||
|
||||
return CommonResult.success(list, "");
|
||||
@ -213,15 +228,15 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
|
||||
// 从 shop_store_base 表获取店铺的地址和经纬度
|
||||
transportBase.setStore_address(StrUtil.removeAll(shopStoreBase.getStore_area(), "/") + shopStoreBase.getStore_address());
|
||||
transportBase.setStore_longitude(Convert.toBigDecimal(shopStoreBase.getStore_longitude()));
|
||||
transportBase.setStore_latitude(Convert.toBigDecimal(shopStoreBase.getStore_latitude()));
|
||||
transportBase.setStore_longitude(shopStoreBase.getStore_longitude());
|
||||
transportBase.setStore_latitude(shopStoreBase.getStore_latitude());
|
||||
}
|
||||
|
||||
ShopStoreSameCityTransportBaseDTO shopStoreSameCityTransportBaseDTO = new ShopStoreSameCityTransportBaseDTO();
|
||||
shopStoreSameCityTransportBaseDTO.setTransportBase(transportBase);
|
||||
|
||||
// 多个店铺同城快递运费设置(起送条件+优惠条件)
|
||||
List<ShopStoreSameCityTransport> transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(transportBase.getTransport_base_id());
|
||||
List<ShopStoreSameCityTransport> transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(transportBase.getStore_id());
|
||||
shopStoreSameCityTransportBaseDTO.setTransportList(transportList);
|
||||
|
||||
return shopStoreSameCityTransportBaseDTO;
|
||||
@ -325,7 +340,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, BigDecimal orderLongitude, BigDecimal orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow) {
|
||||
public SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, String orderLongitude, String orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow) {
|
||||
// 计算订单同城配送费,该函数的流程说明:
|
||||
// 1.先获取订单的经纬度,计算配送距离,获取配送范围,确定是否能配送,如果能计算基础运费?
|
||||
// 2.如果能配送,再订单总重量,订单原价金额,订单折后金额,订单实付金额
|
||||
@ -342,58 +357,79 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
|
||||
// 获取基础运费设置记录
|
||||
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId);
|
||||
if (transportBase==null || transportBase.getStore_longitude()==null || transportBase.getStore_latitude()==null || transportBase.getDistance_base()==null || transportBase.getDelivery_base_fee()==null ) {
|
||||
logger.error("同城配送费计算:无法获取基础运费设置记录,或店铺经纬度为空");
|
||||
if (transportBase == null) {
|
||||
logger.error("同城配送费计算:无法获取基础运费设置记录。");
|
||||
if (canThrow) {
|
||||
throw new ApiException(I18nUtil._("商家尚未配置同城配送相关设置。"));
|
||||
}
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "商家尚未配置同城配送相关设置。");
|
||||
}
|
||||
String storeLng = transportBase.getStore_longitude();
|
||||
String storeLat = transportBase.getStore_latitude();
|
||||
if (StrUtil.isBlank(storeLng) || StrUtil.isBlank(storeLat)) {
|
||||
logger.error("同城配送费计算:店铺经纬度为空");
|
||||
if (canThrow) {
|
||||
throw new ApiException(I18nUtil._("无法获取店铺的具体位置,请联系商家。"));
|
||||
}
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "无法获取店铺的具体位置,请联系商家。");
|
||||
}
|
||||
|
||||
if (transportBase.getDistance_base() == null) {
|
||||
transportBase.setDistance_base(0);
|
||||
}
|
||||
if (transportBase.getWeight_base() == null) {
|
||||
transportBase.setWeight_base(0);
|
||||
}
|
||||
if (transportBase.getDelivery_base_fee() == null) {
|
||||
transportBase.setDelivery_base_fee(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 通过高德或百度地图api,计算两点的距离,如果服务不可用或无法计算,使用内部算法计算距离(单位米)
|
||||
Double distanceD = PositionUtil.getDistance4(transportBase.getStore_longitude().doubleValue(), transportBase.getStore_latitude().doubleValue(), orderLongitude.doubleValue(), orderLatitude.doubleValue());
|
||||
Double distanceD = PositionUtil.getDistance1(Convert.toDouble(storeLng), Convert.toDouble(storeLat), Convert.toDouble(orderLongitude), Convert.toDouble(orderLatitude));
|
||||
if (distanceD == null) {
|
||||
distanceD = Double.valueOf(0);
|
||||
}
|
||||
// 实际配送距离,单位米
|
||||
Integer distance = distanceD.intValue();
|
||||
logger.debug("下单时,店铺与收货地址的距离:{} 米", distance);
|
||||
logger.debug("下单时,店铺与收货地址两地,经纬度:{},{}|{},{} 距离:{} 米", storeLng, storeLat, orderLongitude, orderLatitude, distance);
|
||||
|
||||
// ### 基础配送费计算
|
||||
BigDecimal deliveryBaseFee = transportBase.getDelivery_base_fee();
|
||||
// 只能大于等于0
|
||||
if (deliveryBaseFee.compareTo(BigDecimal.ZERO) < 0) {
|
||||
deliveryBaseFee = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
// 每增加一个距离累加运费
|
||||
if (transportBase.getDistance_increase_km() != null && transportBase.getDistance_increase_fee() != null && transportBase.getDistance_base() != null && distance > transportBase.getDistance_base() * 1000) {
|
||||
if (transportBase.getDistance_increase_km() != null && transportBase.getDistance_increase_fee() != null && distance > transportBase.getDistance_base() * 1000) {
|
||||
// 实际配送距离超出基础距离,单位km
|
||||
BigDecimal diffDistanceM = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(distance - transportBase.getDistance_base() * 1000).divide(BigDecimal.valueOf(1000)));
|
||||
// 累加的次数
|
||||
Integer times = 0;
|
||||
if (diffDistanceM.intValue() > transportBase.getDistance_increase_km()) {
|
||||
times = diffDistanceM.intValue() / transportBase.getDistance_increase_km();
|
||||
// 求余,如果有余数,增加一次倍数
|
||||
if (diffDistanceM.intValue() % transportBase.getDistance_increase_km() > 0) {
|
||||
times += 1;
|
||||
}
|
||||
// 倍数
|
||||
BigDecimal times = BigDecimal.ZERO;
|
||||
if (transportBase.getDistance_increase_km() > 0 && diffDistanceM.intValue() > transportBase.getDistance_increase_km()) {
|
||||
// 末尾非零进位,比如:2.1将是3, 2.0将是2,2.001将是3
|
||||
times = NumberUtil.div(diffDistanceM, transportBase.getDistance_increase_km()).setScale(0, RoundingMode.UP);
|
||||
}
|
||||
|
||||
// 超过基础运费距离后,累加上运费
|
||||
deliveryBaseFee = deliveryBaseFee.add(transportBase.getDistance_increase_fee().multiply(BigDecimal.valueOf(times)));
|
||||
deliveryBaseFee = deliveryBaseFee.add(transportBase.getDistance_increase_fee().multiply(times));
|
||||
}
|
||||
|
||||
// 每增加一个重量累加运费(重量暂时忽略,配置的时候设置0)
|
||||
if (transportBase.getWeight_increase_kg() != null && transportBase.getWeight_increase_fee() != null && transportBase.getWeight_base() != null && weightGram > transportBase.getWeight_base() * 1000) {
|
||||
if (transportBase.getWeight_increase_kg() != null && transportBase.getWeight_increase_fee() != null && weightGram > transportBase.getWeight_base() * 1000) {
|
||||
// 实际配送重量超出基础重量,单位kg
|
||||
BigDecimal diffWeightKg = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(weightGram - transportBase.getWeight_base() * 1000).divide(BigDecimal.valueOf(1000)));
|
||||
// 累加的次数
|
||||
Integer times = 0;
|
||||
if (diffWeightKg.intValue() > transportBase.getWeight_increase_kg()) {
|
||||
times = diffWeightKg.intValue() / transportBase.getWeight_increase_kg();
|
||||
// 求余,如果有余数,增加一次倍数
|
||||
if (diffWeightKg.intValue() % transportBase.getWeight_increase_kg() > 0) {
|
||||
times += 1;
|
||||
}
|
||||
// 倍数
|
||||
BigDecimal times = BigDecimal.ZERO;
|
||||
if (transportBase.getWeight_increase_kg() > 0 && diffWeightKg.intValue() > transportBase.getWeight_increase_kg()) {
|
||||
// 末尾非零进位,比如:2.1将是3, 2.0将是2,2.001将是3
|
||||
times = NumberUtil.div(diffWeightKg, transportBase.getDistance_increase_km()).setScale(0, RoundingMode.UP);
|
||||
}
|
||||
|
||||
deliveryBaseFee = deliveryBaseFee.add(transportBase.getWeight_increase_fee().multiply(BigDecimal.valueOf(times)));
|
||||
deliveryBaseFee = deliveryBaseFee.add(transportBase.getWeight_increase_fee().multiply(times));
|
||||
}
|
||||
|
||||
logger.debug("下单时,店铺与收货地址超出基本距离:额外增加的 {}元 运费", deliveryBaseFee);
|
||||
logger.debug("下单时,店铺与收货地址超出基础距离和重量:额外增加 {} 元运费。", deliveryBaseFee);
|
||||
// #### 基础配送费计算完毕
|
||||
|
||||
|
||||
@ -402,51 +438,112 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
|
||||
// 通过配送范围和起送金额,决定使用哪个配送费优惠规则
|
||||
// 获取运费配送范围和优惠信息
|
||||
List<ShopStoreSameCityTransport> transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(transportBase.getTransport_base_id());
|
||||
List<ShopStoreSameCityTransport> transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(storeId);
|
||||
|
||||
if (CollUtil.isEmpty(transportList)) {
|
||||
// 没有配送范围和起配金额规则的时候,直接以基础配送费来配送
|
||||
return new SameCityDeliveryFeeRespDTO(true, false, deliveryBaseFee, BigDecimal.ZERO, deliveryBaseFee, "");
|
||||
}
|
||||
|
||||
int canDeliveryAreaCnt = 0;
|
||||
String canNotDeliveryReason = "有订单不在配送范围内或订单未达起送金额,请检查!";
|
||||
// 未通过的规则
|
||||
List<DeliveryFeeResultDTO> noPassed = new ArrayList<DeliveryFeeResultDTO>();
|
||||
// 已通过的规则
|
||||
List<DeliveryFeeResultDTO> passed = new ArrayList<DeliveryFeeResultDTO>();
|
||||
for (ShopStoreSameCityTransport transport : transportList) {
|
||||
DeliveryFeeResultDTO deliveryFeeResultDTO = new DeliveryFeeResultDTO();
|
||||
deliveryFeeResultDTO.setId(transport.getTransport_id());
|
||||
logger.debug("下单时,店铺与收货地址的距离是{}米,最大配送范围是{}米以内", distance, transport.getMax_delivery_radius());
|
||||
|
||||
// 判断订单距离在不在配送范围内?
|
||||
if (transport.getMax_delivery_radius() < distance) {
|
||||
|
||||
// 订单距离不在配送范围内,返回不送了
|
||||
// canNotDeliveryReason = "有订单超出配送范围,请检查下单店铺位置!";//String.format("有订单超出%d米的配送范围!",transport.getMax_delivery_radius());
|
||||
canDeliveryAreaCnt += 1;
|
||||
continue;
|
||||
}
|
||||
deliveryFeeResultDTO.setLevel(2);
|
||||
deliveryFeeResultDTO.setDistancePassed(false);
|
||||
deliveryFeeResultDTO.setDistanceReason("订单不在配送范围内,订单无法配送。");
|
||||
|
||||
// 判断订单达到起配金额没有?
|
||||
if ((CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type()) && transport.getMin_delivery_amount().compareTo(orderProductAmount) > 0) ||
|
||||
(CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type()) && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) > 0) ||
|
||||
(CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type()) && transport.getMin_delivery_amount().compareTo(orderPayAmount) > 0)) {
|
||||
// 订单原价金额小于起送金额,返回订单不能送达了
|
||||
// canNotDeliveryReason ="有订单未满足起送金额,请检查您的订单金额!"; //String.format("有订单未满足%.2f元起送金额!",transport.getMin_delivery_amount());
|
||||
continue;
|
||||
}
|
||||
noPassed.add(deliveryFeeResultDTO);
|
||||
|
||||
canDeliveryAreaCnt += 1;
|
||||
canNotDeliveryReason = "";
|
||||
} else {
|
||||
deliveryFeeResultDTO.setLevel(1);
|
||||
deliveryFeeResultDTO.setDistancePassed(true);
|
||||
// 距离在配送范围内,继续判断金额是否符合起配金额额度?
|
||||
if (CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type())) {
|
||||
if (transport.getMin_delivery_amount().compareTo(orderProductAmount) > 0) {
|
||||
deliveryFeeResultDTO.setMoneyPassed(false);
|
||||
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderProductAmount);
|
||||
deliveryFeeResultDTO.setDiffMoney(diffMoney);
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("商品原价金额还差%.2f元,达到起送金额,订单无法配送。", diffMoney));
|
||||
} else {
|
||||
deliveryFeeResultDTO.setMoneyPassed(true);
|
||||
}
|
||||
} else if (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type())) {
|
||||
if (transport.getMin_delivery_amount().compareTo(orderDiscountAmount) > 0) {
|
||||
deliveryFeeResultDTO.setMoneyPassed(false);
|
||||
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderDiscountAmount);
|
||||
deliveryFeeResultDTO.setDiffMoney(diffMoney);
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("订单折后金额还差%.2f元,达到起送金额,订单无法配送。", diffMoney));
|
||||
} else {
|
||||
deliveryFeeResultDTO.setMoneyPassed(true);
|
||||
}
|
||||
} else if (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type())) {
|
||||
|
||||
if (transport.getMin_delivery_amount().compareTo(orderPayAmount) > 0) {
|
||||
deliveryFeeResultDTO.setMoneyPassed(false);
|
||||
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderDiscountAmount);
|
||||
deliveryFeeResultDTO.setDiffMoney(diffMoney);
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("应支付订单金额还差%.2f元,达到起送金额,订单无法配送。", diffMoney));
|
||||
} else {
|
||||
deliveryFeeResultDTO.setMoneyPassed(true);
|
||||
}
|
||||
|
||||
// 获取优惠的配送费
|
||||
if ((CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getDelivery_discount_type()) && transport.getMin_delivery_discount_amount().compareTo(orderProductAmount) <= 0) ||
|
||||
(CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getDelivery_discount_type()) && transport.getMin_delivery_discount_amount().compareTo(orderDiscountAmount) <= 0) ||
|
||||
(CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getDelivery_discount_type()) && transport.getMin_delivery_discount_amount().compareTo(orderPayAmount) <= 0)) {
|
||||
// 订单实付金额小于起送金额,返回不送了
|
||||
if (reduceDeliveryFee.compareTo(transport.getDelivery_discount()) < 0) {
|
||||
// 采用优惠最大的一个豁免设置
|
||||
reduceDeliveryFee = transport.getDelivery_discount();
|
||||
}
|
||||
|
||||
deliveryFeeResultDTO.setFee(BigDecimal.ZERO);
|
||||
// 在配送范围内,并符合起配金额,计算能优惠的配送费
|
||||
if (deliveryFeeResultDTO.getDistancePassed() && deliveryFeeResultDTO.getMoneyPassed()) {
|
||||
// 计算能优惠的配送费
|
||||
if ((CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getDelivery_discount_type()) && transport.getMin_delivery_discount_amount().compareTo(orderProductAmount) <= 0) ||
|
||||
(CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getDelivery_discount_type()) && transport.getMin_delivery_discount_amount().compareTo(orderDiscountAmount) <= 0) ||
|
||||
(CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getDelivery_discount_type()) && transport.getMin_delivery_discount_amount().compareTo(orderPayAmount) <= 0)) {
|
||||
|
||||
deliveryFeeResultDTO.setFee(transport.getDelivery_discount());
|
||||
|
||||
// 采用优惠最大的一个豁免设置
|
||||
if (reduceDeliveryFee.compareTo(transport.getDelivery_discount()) < 0) {
|
||||
// 采用优惠最大的一个豁免设置
|
||||
reduceDeliveryFee = transport.getDelivery_discount();
|
||||
}
|
||||
}
|
||||
|
||||
deliveryFeeResultDTO.setAllPassed(true);
|
||||
passed.add(deliveryFeeResultDTO);
|
||||
} else {
|
||||
noPassed.add(deliveryFeeResultDTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logger.debug("下单时,根据规则减免 {}元 运费", reduceDeliveryFee);
|
||||
logger.debug("下单时,根据商家运费设置规则减免{}元运费", reduceDeliveryFee);
|
||||
logger.debug("下单时,不符合规则的:\n {}\n符合规则的:{}", JSONUtil.toJsonStr(noPassed), JSONUtil.toJsonStr(passed));
|
||||
|
||||
if (passed.size() == 0 && noPassed.size() > 0) {
|
||||
// 没有一个满足起送距离和起送金额的规则订单
|
||||
String canNotDeliveryReason="有订单不在配送范围内或订单未达起送金额,请检查!";
|
||||
|
||||
// 根据 level 优先级升序排序
|
||||
noPassed = CollUtil.sort(noPassed, new FieldsComparator<>(DeliveryFeeResultDTO.class,"level","diffMoney"));
|
||||
DeliveryFeeResultDTO deliveryFeeResultNoPassed = noPassed.get(0);
|
||||
|
||||
// 优先级显示不符合规定的提示语
|
||||
if(!deliveryFeeResultNoPassed.getDistancePassed()){
|
||||
canNotDeliveryReason = deliveryFeeResultNoPassed.getDistanceReason();
|
||||
}else if(!deliveryFeeResultNoPassed.getMoneyPassed()){
|
||||
canNotDeliveryReason = deliveryFeeResultNoPassed.getMoneyReason();
|
||||
}
|
||||
|
||||
if (canDeliveryAreaCnt <= 0) {
|
||||
if (canThrow) {
|
||||
throw new ApiException(I18nUtil._(canNotDeliveryReason));
|
||||
}
|
||||
|
||||
@ -64,17 +64,17 @@ public class ShopStoreSameCityTransportServiceImpl extends BaseServiceImpl<ShopS
|
||||
/**
|
||||
* 根据同城配送基础配置自增 Id 获取同城配送扩展设置列表
|
||||
*
|
||||
* @param transportBaseId
|
||||
* @param storeId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<ShopStoreSameCityTransport> selectShopStoreSameCityTransportList(Long transportBaseId) {
|
||||
if (transportBaseId == null || transportBaseId <= 0) {
|
||||
public List<ShopStoreSameCityTransport> selectShopStoreSameCityTransportList(Long storeId) {
|
||||
if (storeId == null || storeId <= 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
QueryWrapper<ShopStoreSameCityTransport> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("transport_base_id", transportBaseId);
|
||||
queryWrapper.eq("store_id", storeId);
|
||||
queryWrapper.eq("status", CommonConstant.Enable);
|
||||
queryWrapper.orderByAsc("transport_id");
|
||||
|
||||
|
||||
@ -758,6 +758,8 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
|
||||
if (Convert.toBool(is_delivery)) {
|
||||
// 重要:配送运费校验和计算(涉及的东西比较多)
|
||||
calTransportFreight(data, district_id);
|
||||
// 订单地址和金额不在配送范围,抛出异常提示
|
||||
// tryCalTransportFreight(data, district_id,true);
|
||||
data.put("has_stock", data.get("can_delivery")); // 是否有货
|
||||
} else {
|
||||
data.put("can_delivery", true); // 是否可以派送
|
||||
@ -2507,8 +2509,8 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
|
||||
|
||||
// 一个店铺的订单
|
||||
Long storeId = Convert.toLong(store_row.get("store_id"));
|
||||
BigDecimal storeLng = Convert.toBigDecimal(store_row.get("store_longitude"));
|
||||
BigDecimal storeLat = Convert.toBigDecimal(store_row.get("store_latitude"));
|
||||
String orderLng = uAddress.getUd_longitude();
|
||||
String orderLat = uAddress.getUd_latitude();
|
||||
// 订单商品原价金额
|
||||
BigDecimal productMoneyOriginGoods = Convert.toBigDecimal(store_row.get("productMoneyOriginGoods"));
|
||||
// 订单折扣后金额
|
||||
@ -2517,7 +2519,7 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
|
||||
BigDecimal orderPaymentAmount = Convert.toBigDecimal(store_row.get("productMoneySelGoods"));
|
||||
|
||||
// 同城配送运费检查和计算(只返回数据,不能配送不抛异常)
|
||||
SameCityDeliveryFeeRespDTO sameCityDeliveryFeeResp = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(storeId, storeLng, storeLat, 0, productMoneyOriginGoods, orderSelDiscountAmount, orderPaymentAmount, canThrow);
|
||||
SameCityDeliveryFeeRespDTO sameCityDeliveryFeeResp = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(storeId, orderLng, orderLat, 0, productMoneyOriginGoods, orderSelDiscountAmount, orderPaymentAmount, canThrow);
|
||||
|
||||
// 是否能配送(在配送范围内)
|
||||
Boolean canDelivery = sameCityDeliveryFeeResp.getCanDelivery();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user