From 7b08c42c681d4884426deff2137f5846343d764f Mon Sep 17 00:00:00 2001
From: chen-xin-zhi <3588068430@qq.com>
Date: Mon, 6 Jan 2025 10:25:41 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E5=95=86=E5=93=81?=
=?UTF-8?q?=E7=B1=BB=E5=88=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 11 +-
.../heritage/config/WxAccessToken.java | 31 ++++
.../heritage/config/WxWaybillToken.java | 35 +++++
.../controller/order/OrderController.java | 2 +
.../wx/WeChatLogisticsController.java | 148 ++++++++++++++++++
.../controller/wx/WeChatPayController.java | 2 +-
.../model/vo/good/GoodLogisticsInfoVO.java | 32 ++++
.../heritage/model/vo/good/GoodsInfo.java | 27 ++++
.../service/wx/WeChatLogisticsService.java | 19 +++
.../service/{wxpay => wx}/WeChatService.java | 2 +-
.../wx/impl/WeChatLogisticsServiceImpl.java | 71 +++++++++
.../{wxpay => wx}/impl/WeChatServiceImpl.java | 4 +-
12 files changed, 379 insertions(+), 5 deletions(-)
create mode 100644 src/main/java/com/cultural/heritage/config/WxAccessToken.java
create mode 100644 src/main/java/com/cultural/heritage/config/WxWaybillToken.java
create mode 100644 src/main/java/com/cultural/heritage/controller/wx/WeChatLogisticsController.java
create mode 100644 src/main/java/com/cultural/heritage/model/vo/good/GoodLogisticsInfoVO.java
create mode 100644 src/main/java/com/cultural/heritage/model/vo/good/GoodsInfo.java
create mode 100644 src/main/java/com/cultural/heritage/service/wx/WeChatLogisticsService.java
rename src/main/java/com/cultural/heritage/service/{wxpay => wx}/WeChatService.java (96%)
create mode 100644 src/main/java/com/cultural/heritage/service/wx/impl/WeChatLogisticsServiceImpl.java
rename src/main/java/com/cultural/heritage/service/{wxpay => wx}/impl/WeChatServiceImpl.java (99%)
diff --git a/pom.xml b/pom.xml
index 53b9a3a..8c93ac0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,18 +164,27 @@
1.2.62
+
+
+
org.springframework.boot
spring-boot-configuration-processor
true
-
+
redis.clients
jedis
5.2.0
+
+
+ com.google.code.gson
+ gson
+ 2.8.8
+
diff --git a/src/main/java/com/cultural/heritage/config/WxAccessToken.java b/src/main/java/com/cultural/heritage/config/WxAccessToken.java
new file mode 100644
index 0000000..e8a3b22
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/config/WxAccessToken.java
@@ -0,0 +1,31 @@
+package com.cultural.heritage.config;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 微信小程序获取token响应体
+ */
+@Configuration
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxAccessToken implements Serializable {
+
+ @Schema(description = "获取到的凭证")
+ private String access_token;
+
+ @Schema(description = "凭证有效时间,单位:秒。目前是7200秒之内的值。")
+ private String expires_in;
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+}
diff --git a/src/main/java/com/cultural/heritage/config/WxWaybillToken.java b/src/main/java/com/cultural/heritage/config/WxWaybillToken.java
new file mode 100644
index 0000000..a4da28d
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/config/WxWaybillToken.java
@@ -0,0 +1,35 @@
+package com.cultural.heritage.config;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 微信小程序获取waybillToken响应体
+ */
+@Configuration
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxWaybillToken implements Serializable {
+
+ @Schema(description = "返回码")
+ private Integer errcode;
+
+ @Schema(description = "错误信息")
+ private String errmsg;
+
+ @Schema(description = "物流查询id")
+ private String waybill_token;
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+}
diff --git a/src/main/java/com/cultural/heritage/controller/order/OrderController.java b/src/main/java/com/cultural/heritage/controller/order/OrderController.java
index b27961b..dab5b67 100644
--- a/src/main/java/com/cultural/heritage/controller/order/OrderController.java
+++ b/src/main/java/com/cultural/heritage/controller/order/OrderController.java
@@ -67,6 +67,8 @@ public class OrderController {
private CartRecordService cartRecordService;
+
+
@Resource
private GoodService goodService;
diff --git a/src/main/java/com/cultural/heritage/controller/wx/WeChatLogisticsController.java b/src/main/java/com/cultural/heritage/controller/wx/WeChatLogisticsController.java
new file mode 100644
index 0000000..9fe6f18
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/controller/wx/WeChatLogisticsController.java
@@ -0,0 +1,148 @@
+package com.cultural.heritage.controller.wx;
+
+
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.cultural.heritage.common.BaseResponse;
+import com.cultural.heritage.common.ErrorCode;
+import com.cultural.heritage.common.ResultUtils;
+import com.cultural.heritage.config.WxAccessToken;
+import com.cultural.heritage.config.WxWaybillToken;
+import com.cultural.heritage.exception.BusinessException;
+import com.cultural.heritage.exception.ThrowUtils;
+import com.cultural.heritage.model.dto.CommonRequest;
+import com.cultural.heritage.model.dto.snapshot.AddressSnapshot;
+import com.cultural.heritage.model.dto.snapshot.GoodSnapshot;
+import com.cultural.heritage.model.entity.Order;
+import com.cultural.heritage.model.entity.OrderItems;
+import com.cultural.heritage.model.entity.User;
+import com.cultural.heritage.model.vo.good.GoodLogisticsInfoVO;
+import com.cultural.heritage.model.vo.good.GoodsInfo;
+import com.cultural.heritage.service.order.OrderItemService;
+import com.cultural.heritage.service.order.OrderService;
+import com.cultural.heritage.service.user.UserService;
+import com.cultural.heritage.service.wx.WeChatLogisticsService;
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 微信小程序查看物流相关接口
+ **/
+@Slf4j
+@RestController
+@Tag(name = "微信物流接口")
+@RequestMapping("/logistics")
+public class WeChatLogisticsController {
+
+
+ private final static String ACCESS_TOKEN_KEY = "accessToken";
+
+
+ @Resource
+ private UserService userService;
+
+
+ @Resource
+ private WeChatLogisticsService weChatLogisticsService;
+
+
+ @Resource
+ private RedisTemplate redisTemplate;
+
+
+ @Resource
+ private Gson gson;
+
+
+ @Resource
+ private OrderService orderService;
+
+
+ @Resource
+ private OrderItemService orderItemService;
+
+
+ /**
+ * (小程序端)获取接口调用凭据
+ *
+ * @param request
+ */
+ @GetMapping("/get/token")
+ @Operation(summary = "(小程序端)微信小程序获取接口调用凭据", description = "参数:无, 权限:所有人, 方法名:getAccessToken")
+ public BaseResponse getAccessToken(HttpServletRequest request) {
+ userService.getLoginUser(request);
+ String accessToken = (String) redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
+ if (accessToken == null) {
+ weChatLogisticsService.addAccessToken();
+ accessToken = (String) redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
+ }
+ WxAccessToken wxAccessToken = WxAccessToken.builder()
+ .access_token(accessToken)
+ .expires_in("7200").build();
+ return ResultUtils.success(wxAccessToken);
+ }
+
+
+ /**
+ * (小程序端)根据订单id查询物流信息
+ */
+ @PostMapping("/get/info")
+ @Operation(summary = "(小程序端)微信小程序获取接口调用凭据", description = "参数:无, 权限:所有人, 方法名:getAccessToken")
+ public BaseResponse getWaybillToken(@RequestBody CommonRequest commonRequest, HttpServletRequest request) throws IOException {
+ if (commonRequest == null || commonRequest.getId() <= 0) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+ User loginUser = userService.getLoginUser(request);
+ String miniOpenId = loginUser.getMiniOpenId();
+ String accessToken = (String) redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
+ if (accessToken == null) {
+ weChatLogisticsService.addAccessToken();
+ accessToken = (String) redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
+ }
+ Long id = commonRequest.getId();
+ Order order = orderService.getById(id);
+ ThrowUtils.throwIf(order == null, ErrorCode.SYSTEM_ERROR, "订单不存在");
+ String trackingNumber = order.getTrackingNumber();
+ AddressSnapshot addressSnapshot = order.getAddressSnapshot();
+ String phone = addressSnapshot.getPhone();
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("orderId", id);
+ List orderItemsList = orderItemService.list(queryWrapper);
+ List goodLogisticsInfoVOS = orderItemsList.stream().map(orderItems -> {
+ GoodSnapshot goodSnapshot = orderItems.getGoodSnapshot();
+ String name = goodSnapshot.getName();
+ String goodImg = goodSnapshot.getGoodImg();
+ return GoodLogisticsInfoVO.builder().goods_name(name).goods_img_url(goodImg).build();
+ }).toList();
+ GoodsInfo goodsInfo = GoodsInfo.builder().detail_list(goodLogisticsInfoVOS).build();
+ Map param = new HashMap<>();
+ param.put("openid", miniOpenId);
+ param.put("waybill_id", trackingNumber);
+ param.put("receiver_phone", phone);
+ param.put("goods_info", goodsInfo);
+ String url = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/trace_waybill?access_token=" + accessToken;
+
+ String jsonParams = JSONUtil.toJsonStr(param);
+ String response = HttpUtil.createPost(url)
+ .header("Content-Type", "application/json")
+ .body(jsonParams)
+ .execute()
+ .body();
+
+ WxWaybillToken wxWaybillToken = gson.fromJson(response, WxWaybillToken.class);
+ return ResultUtils.success(wxWaybillToken);
+ }
+
+}
diff --git a/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java b/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java
index 1856879..ae26dfe 100644
--- a/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java
+++ b/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java
@@ -14,7 +14,7 @@ import com.cultural.heritage.model.entity.Order;
import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.service.order.OrderService;
import com.cultural.heritage.service.user.UserService;
-import com.cultural.heritage.service.wxpay.WeChatService;
+import com.cultural.heritage.service.wx.WeChatService;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.Refund;
diff --git a/src/main/java/com/cultural/heritage/model/vo/good/GoodLogisticsInfoVO.java b/src/main/java/com/cultural/heritage/model/vo/good/GoodLogisticsInfoVO.java
new file mode 100644
index 0000000..79a05d7
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/model/vo/good/GoodLogisticsInfoVO.java
@@ -0,0 +1,32 @@
+package com.cultural.heritage.model.vo.good;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class GoodLogisticsInfoVO implements Serializable {
+
+ /**
+ * 商品名
+ */
+ private String goods_name;
+
+
+ /**
+ * 商品图片
+ */
+ private String goods_img_url;
+
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+}
diff --git a/src/main/java/com/cultural/heritage/model/vo/good/GoodsInfo.java b/src/main/java/com/cultural/heritage/model/vo/good/GoodsInfo.java
new file mode 100644
index 0000000..8f93b8e
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/model/vo/good/GoodsInfo.java
@@ -0,0 +1,27 @@
+package com.cultural.heritage.model.vo.good;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class GoodsInfo implements Serializable {
+
+
+ /**
+ * 物流信息商品列表
+ */
+ private List detail_list;
+
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+}
diff --git a/src/main/java/com/cultural/heritage/service/wx/WeChatLogisticsService.java b/src/main/java/com/cultural/heritage/service/wx/WeChatLogisticsService.java
new file mode 100644
index 0000000..1f14be3
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/service/wx/WeChatLogisticsService.java
@@ -0,0 +1,19 @@
+package com.cultural.heritage.service.wx;
+
+import com.cultural.heritage.config.WxAccessToken;
+
+public interface WeChatLogisticsService {
+
+ /**
+ * 获取微信token
+ */
+ WxAccessToken getAccessToken();
+
+
+ /**
+ * 两小时内重新获取token
+ */
+ void addAccessToken();
+
+
+}
diff --git a/src/main/java/com/cultural/heritage/service/wxpay/WeChatService.java b/src/main/java/com/cultural/heritage/service/wx/WeChatService.java
similarity index 96%
rename from src/main/java/com/cultural/heritage/service/wxpay/WeChatService.java
rename to src/main/java/com/cultural/heritage/service/wx/WeChatService.java
index b163dad..fb4a2b4 100644
--- a/src/main/java/com/cultural/heritage/service/wxpay/WeChatService.java
+++ b/src/main/java/com/cultural/heritage/service/wx/WeChatService.java
@@ -1,4 +1,4 @@
-package com.cultural.heritage.service.wxpay;
+package com.cultural.heritage.service.wx;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
diff --git a/src/main/java/com/cultural/heritage/service/wx/impl/WeChatLogisticsServiceImpl.java b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatLogisticsServiceImpl.java
new file mode 100644
index 0000000..5628abe
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatLogisticsServiceImpl.java
@@ -0,0 +1,71 @@
+package com.cultural.heritage.service.wx.impl;
+
+import cn.hutool.http.HttpUtil;
+import com.cultural.heritage.config.WxAccessToken;
+import com.cultural.heritage.service.wx.WeChatLogisticsService;
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Service
+public class WeChatLogisticsServiceImpl implements WeChatLogisticsService {
+
+
+ private final static String ACCESS_TOKEN_KEY = "accessToken";
+
+ Logger logger = LoggerFactory.getLogger(WeChatLogisticsService.class);
+
+ @Resource
+ private RedisTemplate redisTemplate;
+
+ @Resource
+ private Gson gson;
+
+
+ @Schema(description = "小程序 appId")
+ @Value("${wx.mini.appId}")
+ private String appId;
+
+ @Schema(description = "小程序 appSecret")
+ @Value("${wx.mini.appSecret}")
+ private String appSecret;
+
+
+ /**
+ * 获取微信token
+ */
+ @Override
+ public WxAccessToken getAccessToken() {
+ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
+ String jsonString = null;
+ try {
+ jsonString = HttpUtil.get(url);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return gson.fromJson(jsonString, WxAccessToken.class);
+ }
+
+
+ /**
+ * 两小时内重新获取token
+ */
+ @Scheduled(fixedDelay = 7080000)
+ @Override
+ public void addAccessToken() {
+ String accessToken = getAccessToken().getAccess_token();
+ logger.info("定时任务启用===========" + accessToken);
+ //微信token2小时过期,每2小时重新获得一次
+ redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken, 7200, TimeUnit.SECONDS);
+ }
+}
diff --git a/src/main/java/com/cultural/heritage/service/wxpay/impl/WeChatServiceImpl.java b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java
similarity index 99%
rename from src/main/java/com/cultural/heritage/service/wxpay/impl/WeChatServiceImpl.java
rename to src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java
index a7cbe13..9fce07d 100644
--- a/src/main/java/com/cultural/heritage/service/wxpay/impl/WeChatServiceImpl.java
+++ b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java
@@ -1,4 +1,4 @@
-package com.cultural.heritage.service.wxpay.impl;
+package com.cultural.heritage.service.wx.impl;
import cn.binarywang.wx.miniapp.api.WxMaMsgService;
@@ -19,7 +19,7 @@ import com.cultural.heritage.model.entity.OrderItems;
import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.order.OrderItemService;
import com.cultural.heritage.service.order.OrderService;
-import com.cultural.heritage.service.wxpay.WeChatService;
+import com.cultural.heritage.service.wx.WeChatService;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;