From 1f910992d6a8f5aa5b24dc652bde62de9b341ab8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 2 Oct 2023 21:18:52 +0800 Subject: [PATCH] =?UTF-8?q?trade=EF=BC=9A=E6=96=B0=E5=A2=9E=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E8=87=AA=E6=8F=90=E7=9A=84=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/number/NumberUtils.java | 24 ++++++++ .../admin/config/TradeConfigController.java | 10 +++- .../admin/config/vo/TradeConfigBaseVO.java | 4 ++ .../admin/config/vo/TradeConfigRespVO.java | 3 + .../app/config/AppTradeConfigController.java | 8 ++- .../app/config/vo/AppTradeConfigRespVO.java | 10 ++++ .../AppDeliverPickUpStoreController.java | 55 ++++++------------- .../pickup/AppDeliveryPickUpStoreRespVO.java | 4 +- .../delivery/DeliveryPickUpStoreConvert.java | 17 ++++++ .../dal/dataobject/config/TradeConfigDO.java | 5 ++ .../src/main/resources/application-dev.yaml | 1 + .../src/main/resources/application-local.yaml | 1 + 12 files changed, 100 insertions(+), 42 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java index 822510096..55ab367a3 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java @@ -13,4 +13,28 @@ public class NumberUtils { return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null; } + /** + * 通过经纬度获取地球上两点之间的距离 + * + * 参考 <DistanceUtil> 实现,目前它已经被 hutool 删除 + * + * @param lat1 经度1 + * @param lng1 纬度1 + * @param lat2 经度2 + * @param lng2 纬度2 + * @return 距离,单位:千米 + */ + public static double getDistance(double lat1, double lng1, double lat2, double lng2) { + double radLat1 = lat1 * Math.PI / 180.0; + double radLat2 = lat2 * Math.PI / 180.0; + double a = radLat1 - radLat2; + double b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0; + double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + + Math.cos(radLat1) * Math.cos(radLat2) + * Math.pow(Math.sin(b / 2), 2))); + distance = distance * 6378.137; + distance = Math.round(distance * 10000d) / 10000d; + return distance; + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java index e41f98081..5e0558fbf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -26,6 +27,9 @@ public class TradeConfigController { @Resource private TradeConfigService tradeConfigService; + @Value("${yudao.tencent-lbs-key}") + private String tencentLbsKey; + @PutMapping("/save") @Operation(summary = "更新交易中心配置") @PreAuthorize("@ss.hasPermission('trade:config:save')") @@ -39,7 +43,11 @@ public class TradeConfigController { @PreAuthorize("@ss.hasPermission('trade:config:query')") public CommonResult getConfig() { TradeConfigDO config = tradeConfigService.getTradeConfig(); - return success(TradeConfigConvert.INSTANCE.convert(config)); + TradeConfigRespVO configVO = TradeConfigConvert.INSTANCE.convert(config); + if (configVO != null) { + configVO.setTencentLbsKey(tencentLbsKey); + } + return success(configVO); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java index 5531a3ace..1507e2b8f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java @@ -44,6 +44,10 @@ public class TradeConfigBaseVO { @PositiveOrZero(message = "全场包邮的最小金额不能是负数") private Integer deliveryExpressFreePrice; + @Schema(description = "是否开启自提", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + @NotNull(message = "是否开启自提不能为空") + private Boolean deliveryPickUpEnabled; + // ========== 分销相关 ========== @Schema(description = "是否启用分佣", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java index 52aff751f..5ded00ace 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java @@ -14,4 +14,7 @@ public class TradeConfigRespVO extends TradeConfigBaseVO { @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long id; + @Schema(description = "腾讯地图 KEY", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") + private String tencentLbsKey; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java index 6b7660a1c..5046c6512 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java @@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -30,11 +31,14 @@ public class AppTradeConfigController { @Resource private TradeConfigService tradeConfigService; + @Value("${yudao.tencent-lbs-key}") + private String tencentLbsKey; + @GetMapping("/get") @Operation(summary = "获得交易配置") public CommonResult getTradeConfig() { - TradeConfigDO tradeConfig = ObjUtil.defaultIfNull(tradeConfigService.getTradeConfig(), new TradeConfigDO()); - return success(TradeConfigConvert.INSTANCE.convert02(tradeConfig)); + TradeConfigDO config = ObjUtil.defaultIfNull(tradeConfigService.getTradeConfig(), new TradeConfigDO()); + return success(TradeConfigConvert.INSTANCE.convert02(config).setTencentLbsKey(tencentLbsKey)); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java index a9515f609..c80472c8b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java @@ -3,12 +3,22 @@ package cn.iocoder.yudao.module.trade.controller.app.config.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.constraints.NotNull; import java.util.List; @Schema(description = "用户 App - 交易配置 Response VO") @Data public class AppTradeConfigRespVO { + @Schema(description = "腾讯地图 KEY", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") + private String tencentLbsKey; + + // ========== 配送相关 ========== + + @Schema(description = "是否开启自提", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + @NotNull(message = "是否开启自提不能为空") + private Boolean deliveryPickUpEnabled; + // ========== 售后相关 ========== @Schema(description = "售后的退款理由", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverPickUpStoreController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverPickUpStoreController.java index 3b49fb6ae..fcc4993f1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverPickUpStoreController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverPickUpStoreController.java @@ -1,10 +1,14 @@ package cn.iocoder.yudao.module.trade.controller.app.delivery; -import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup.AppDeliveryPickUpStoreRespVO; +import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryPickUpStoreConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -12,9 +16,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.ArrayList; +import javax.annotation.Resource; import java.util.List; -import java.util.Random; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -24,51 +27,29 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Validated public class AppDeliverPickUpStoreController { - // TODO 待实现[门店自提]:如果 latitude、longitude 非空,计算经纬度,并排序。计算的库,可以使用 hutool 的 DistanceUtil 计算。 + @Resource + private DeliveryPickUpStoreService deliveryPickUpStoreService; + @GetMapping("/list") @Operation(summary = "获得自提门店列表") + @Parameters({ + @Parameter(name = "latitude", description = "精度", example = "110"), + @Parameter(name = "longitude", description = "纬度", example = "120") + }) public CommonResult> getDeliveryPickUpStoreList( @RequestParam(value = "latitude", required = false) Double latitude, @RequestParam(value = "longitude", required = false) Double longitude) { - List list = new ArrayList<>(); - Random random = new Random(); - for (int i = 0; i < 10; i++) { - AppDeliveryPickUpStoreRespVO store = new AppDeliveryPickUpStoreRespVO(); - store.setId(random.nextLong()); - store.setName(RandomUtil.randomString(10)); - store.setLogo("https://www.iocoder.cn/" + (i + 1) + ".png"); - store.setPhone("15601691300"); - store.setAreaId(random.nextInt(100000)); - store.setAreaName("上海-" + RandomUtil.randomString(10)); - store.setDetailAddress("普陀区-" + RandomUtil.randomString(10)); - store.setLatitude(random.nextDouble() * 10); - store.setLongitude(random.nextDouble() * 10); - store.setDistance(random.nextInt(1000)); - - list.add(store); - } - - return success(list); + List list = deliveryPickUpStoreService.getDeliveryPickUpStoreListByStatus( + CommonStatusEnum.ENABLE.getStatus()); + return success(DeliveryPickUpStoreConvert.INSTANCE.convertList(list, latitude, longitude)); } - // TODO 待实现[门店自提]: @GetMapping("/get") @Operation(summary = "获得自提门店") @Parameter(name = "id", description = "门店编号") public CommonResult getOrder(@RequestParam("id") Long id) { - AppDeliveryPickUpStoreRespVO store = new AppDeliveryPickUpStoreRespVO(); - Random random = new Random(); - store.setId(random.nextLong()); - store.setName(RandomUtil.randomString(10)); - store.setLogo("https://www.iocoder.cn/" + (1) + ".png"); - store.setPhone("15601691300"); - store.setAreaId(random.nextInt(100000)); - store.setAreaName("上海-" + RandomUtil.randomString(10)); - store.setDetailAddress("普陀区-" + RandomUtil.randomString(10)); - store.setLatitude(random.nextDouble() * 10); - store.setLongitude(random.nextDouble() * 10); - store.setDistance(random.nextInt(1000)); - return success(store); + DeliveryPickUpStoreDO store = deliveryPickUpStoreService.getDeliveryPickUpStore(id); + return success(DeliveryPickUpStoreConvert.INSTANCE.convert03(store)); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/pickup/AppDeliveryPickUpStoreRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/pickup/AppDeliveryPickUpStoreRespVO.java index 6ceb200ad..1ca25ade5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/pickup/AppDeliveryPickUpStoreRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/pickup/AppDeliveryPickUpStoreRespVO.java @@ -34,7 +34,7 @@ public class AppDeliveryPickUpStoreRespVO { @Schema(description = "经度", requiredMode = Schema.RequiredMode.REQUIRED, example = "6.99") private Double longitude; - @Schema(description = "距离,单位:米", example = "100") // 只有在用户传递了经纬度时,才进行计算 - private Integer distance; + @Schema(description = "距离,单位:千米", example = "100") // 只有在用户传递了经纬度时,才进行计算 + private Double distance; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java index 6522f3281..1d5b360a5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.trade.convert.delivery; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreCreateReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreRespVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreSimpleRespVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO; +import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup.AppDeliveryPickUpStoreRespVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -38,4 +41,18 @@ public interface DeliveryPickUpStoreConvert { return AreaUtils.format(areaId); } + default List convertList(List list, + Double latitude, Double longitude) { + List voList = CollectionUtils.convertList(list, store -> { + AppDeliveryPickUpStoreRespVO storeVO = convert03(store); + if (latitude != null && longitude != null) { + storeVO.setDistance(NumberUtils.getDistance(latitude, longitude, storeVO.getLatitude(), storeVO.getLongitude())); + } + return storeVO; + }); + return voList; + } + @Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToAreaName") + AppDeliveryPickUpStoreRespVO convert03(DeliveryPickUpStoreDO bean); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java index f5b20d4c5..fabd02622 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java @@ -59,6 +59,11 @@ public class TradeConfigDO extends BaseDO { */ private Integer deliveryExpressFreePrice; + /** + * 是否开启自提 + */ + private Boolean deliveryPickUpEnabled; + // ========== 分销相关 ========== /** diff --git a/yudao-server/src/main/resources/application-dev.yaml b/yudao-server/src/main/resources/application-dev.yaml index f4e7bc020..2e9db5599 100644 --- a/yudao-server/src/main/resources/application-dev.yaml +++ b/yudao-server/src/main/resources/application-dev.yaml @@ -170,6 +170,7 @@ yudao: order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址 refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址 demo: true # 开启演示模式 + tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc justauth: enabled: true diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 4f7d1a18a..a262fe333 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -213,6 +213,7 @@ yudao: error-code: # 错误码相关配置项 enable: false demo: false # 关闭演示模式 + tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc clean-job: access-retain-day: 7 error-retain-day: 8