From dfbd7cd2b57cb36f5854bccbd3136fc4338f105b Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Thu, 5 Jun 2025 23:24:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A5=E9=A9=BB=E7=94=B3=E8=AF=B7=20fix=20bu?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/PayUserPayServiceImpl.java | 3 +- .../service/impl/ShopMchEntryServiceImpl.java | 60 ++++++------ .../controller/WxOrderShippingController.java | 22 +++++ .../service/WxOrderShippingService.java | 34 +++++++ .../shop/wechat/service/WxQrCodeService.java | 7 -- .../impl/WxOrderShippingServiceImpl.java | 91 +++++++++++++++++++ .../service/impl/WxQrCodeServiceImpl.java | 44 ++------- .../mall/shop/wechat/utils/WxUtil.java | 75 +++++++++++++++ pom.xml | 5 +- 9 files changed, 263 insertions(+), 78 deletions(-) create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxOrderShippingController.java create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/wechat/utils/WxUtil.java diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java index c549e054..163befeb 100644 --- a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java @@ -36,6 +36,7 @@ import com.ijpay.wxpay.model.RefundModel; import com.ijpay.wxpay.model.UnifiedOrderModel; import com.lkl.laop.sdk.LKLSDK; import com.suisung.mall.common.api.*; +import com.suisung.mall.common.constant.CommonConstant; import com.suisung.mall.common.constant.ConfigConstant; import com.suisung.mall.common.domain.OssDto; import com.suisung.mall.common.domain.UserDto; @@ -596,7 +597,7 @@ public class PayUserPayServiceImpl extends BaseServiceImpl isApplied = isApplied(loginMobile, record.getBiz_license_number()); + if (isApplied.getFirst()) { + return CommonResult.failed(isApplied.getSecond()); + } // 检查企业、法人或个人的营业执照或身份证 if (ObjectUtil.isNotEmpty(record.getEntity_type()) && record.getEntity_type().equals(CommonConstant.MCH_ENTITY_TYPE_GR)) { @@ -240,11 +247,6 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl isApplied = isApplied(record.getLogin_mobile(), record.getBiz_license_number()); - if (isApplied.getFirst()) { - return CommonResult.failed(isApplied.getSecond()); - } // 营业执照经营范围内容 if (ObjectUtil.isEmpty(record.getSales_info())) { @@ -636,35 +638,33 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl isApplied(String mobile, String bizLicenseNumber) { - String msg = ""; if (StrUtil.isBlank(mobile) && StrUtil.isBlank(bizLicenseNumber)) { - msg = "缺少必要参数!"; - return Pair.of(false, msg); + return Pair.of(false, "缺少必要参数!"); } QueryWrapper queryWrapper = new QueryWrapper<>(); - if (StrUtil.isNotBlank(mobile) && StrUtil.isBlank(bizLicenseNumber)) { + queryWrapper.eq("status", CommonConstant.Enable); + + boolean isApplied = false; + String msg = ""; + + if (StrUtil.isNotBlank(mobile)) { queryWrapper.eq("login_mobile", mobile); - boolean isApplied = count(queryWrapper) > 0; - if (isApplied) { - msg = "手机号已申请入驻过!"; - } - return Pair.of(isApplied, msg); - } else if (StrUtil.isBlank(mobile) && StrUtil.isNotBlank(bizLicenseNumber)) { - queryWrapper.eq("biz_license_number", bizLicenseNumber); - boolean isApplied = count(queryWrapper) > 0; - if (isApplied) { - msg = "营业执照已申请入驻过!"; - } - return Pair.of(isApplied, msg); - } else { - queryWrapper.eq("login_mobile", mobile).eq("biz_license_number", bizLicenseNumber); - boolean isApplied = count(queryWrapper) > 0; - if (isApplied) { - msg = "已申请入驻过!"; - } - return Pair.of(isApplied, msg); + isApplied = count(queryWrapper) > 0; + if (isApplied) msg = "手机已申请过入驻!"; + queryWrapper.clear(); } + + if (StrUtil.isNotBlank(bizLicenseNumber)) { + queryWrapper.eq("biz_license_number", bizLicenseNumber); + boolean licenseApplied = count(queryWrapper) > 0; + if (licenseApplied) { + isApplied = true; + msg = StrUtil.isNotBlank(msg) ? "手机和营业执照已申请过入驻!" : "营业执照已申请过入驻!"; + } + } + + return Pair.of(isApplied, msg); } /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxOrderShippingController.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxOrderShippingController.java new file mode 100644 index 00000000..ecb77385 --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxOrderShippingController.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025. 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.shop.wechat.controller; + +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 小程序发货信息管理服务 前端控制器 + */ +@Api(tags = "小程序发货信息管理服务") +@RestController +@RequestMapping("/admin/shop/order-shipping") +public class WxOrderShippingController { +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java new file mode 100644 index 00000000..ee3c906d --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025. 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.shop.wechat.service; + +import org.springframework.data.util.Pair; + +public interface WxOrderShippingService { + + /** + * 上传发货信息到微信 + * 参考:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%80%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3 + * + * @param orderId 订单ID + * @param expressNo 快递公司编号 + * @param trackingNo 物流单号 + * @return 返回上传结果,包含成功状态和错误消息 + */ + Pair uploadShippingInfoToWx(String orderId, String expressNo, String trackingNo); + + /** + * 通知微信用户确认收货 + * 参考:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%BA%94%E3%80%81%E7%A1%AE%E8%AE%A4%E6%94%B6%E8%B4%A7%E6%8F%90%E9%86%92%E6%8E%A5%E5%8F%A3 + * + * @param orderId 订单ID + * @return 返回确认收货结果,包含成功状态和错误消息 + */ + Pair notifyConfirmReceive(String orderId); +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java index 1c54fcfd..edb20f3e 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java @@ -15,13 +15,6 @@ import java.util.Map; */ public interface WxQrCodeService { - /** - * 获取微信的 accessToken - * - * @return - */ - String getAccessToken(); - /** * 生成(永久)小程序太阳码 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java new file mode 100644 index 00000000..7ad2552d --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025. 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.shop.wechat.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import com.suisung.mall.common.utils.RestTemplateHttpUtil; +import com.suisung.mall.shop.wechat.service.WxOrderShippingService; +import com.suisung.mall.shop.wechat.utils.WxUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.util.Pair; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class WxOrderShippingServiceImpl implements WxOrderShippingService { + + @Lazy + @Autowired + private WxUtil wxUtil; + + /** + * 上传发货信息到微信 + * 参考:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%80%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3 + * + * @param orderId 订单ID + * @param expressNo 快递公司编号 + * @param trackingNo 物流单号 + * @return 返回上传结果,包含成功状态和错误消息 + */ + @Override + public Pair uploadShippingInfoToWx(String orderId, String expressNo, String trackingNo) { + return null; + } + + /** + * 通知微信用户确认收货 + * 参考:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%BA%94%E3%80%81%E7%A1%AE%E8%AE%A4%E6%94%B6%E8%B4%A7%E6%8F%90%E9%86%92%E6%8E%A5%E5%8F%A3 + * + * @param orderId 订单ID + * @return 返回确认收货结果,包含成功状态和错误消息 + */ + @Override + public Pair notifyConfirmReceive(String orderId) { + if (StrUtil.isBlank(orderId)) { + return Pair.of(false, "订单ID不能为空"); + } + + try { + + String accessToken = wxUtil.getAccessToken(); + if (StrUtil.isBlank(accessToken)) { + return Pair.of(false, "获取AccessToken失败"); + } + + JSONObject paramsJSON = new JSONObject(); + paramsJSON.put("transaction_id", orderId); + paramsJSON.put("merchant_id", orderId); + paramsJSON.put("merchant_trade_no", orderId); + paramsJSON.put("received_time", System.currentTimeMillis() / 1000); + + + JSONObject respObj = RestTemplateHttpUtil.sendPost("https://api.weixin.qq.com/wxa/sec/order/notify_confirm_receive?access_token=" + accessToken, null, paramsJSON, JSONObject.class); + if (respObj == null) { + log.error("通知微信用户确认收货失败,订单ID: {}, 返回结果为空", orderId); + return Pair.of(false, "通知微信用户确认收货失败,返回结果为空"); + } + + if (respObj.getInt("errcode") != 0) { + String errorMsg = respObj.getStr("errmsg"); + log.error("通知微信用户确认收货失败,订单ID: {}, 错误信息: {}", orderId, errorMsg); + return Pair.of(false, "通知微信用户确认收货失败: " + errorMsg); + } + + log.info("通知微信用户确认收货成功,订单号:{}", orderId); + return Pair.of(true, "通知微信用户确认收货成功"); + + } catch (Exception e) { + log.error("通知微信确认收货失败,订单ID: {}, 错误信息: {}", orderId, e.getMessage(), e); + return Pair.of(false, "通知微信确认收货失败: " + e.getMessage()); + } + } +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java index 958515be..530a473b 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java @@ -3,16 +3,12 @@ package com.suisung.mall.shop.wechat.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; -import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpUtil; import cn.hutool.json.JSON; -import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.alibaba.nacos.common.util.Md5Utils; import com.suisung.mall.common.api.CommonResult; -import com.suisung.mall.common.api.StateCode; import com.suisung.mall.common.constant.ConfigConstant; import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.feignService.AccountService; @@ -21,6 +17,7 @@ import com.suisung.mall.core.web.service.RedisService; import com.suisung.mall.shop.base.service.AccountBaseConfigService; import com.suisung.mall.shop.page.service.OssService; import com.suisung.mall.shop.wechat.service.WxQrCodeService; +import com.suisung.mall.shop.wechat.utils.WxUtil; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -68,6 +65,9 @@ public class WxQrCodeServiceImpl implements WxQrCodeService { @Autowired private AccountService accountService; + @Autowired + private WxUtil wxUtil; + @Value("${aliyun.oss.dir.prefix}") private String ALIYUN_OSS_DIR_PREFIX; @@ -129,38 +129,6 @@ public class WxQrCodeServiceImpl implements WxQrCodeService { return resultMap; } - public String getAccessToken() { - if (!redisService.hasKey(StateCode.WX_XCX_ACCESSTOKEN)) { - getToken(); - } - return Convert.toStr(redisService.get(StateCode.WX_XCX_ACCESSTOKEN)); - } - - private void getToken() { - String xcx_app_id = accountBaseConfigService.getConfig("wechat_xcx_app_id"); - String xcx_app_secret = accountBaseConfigService.getConfig("wechat_xcx_app_secret"); - - Map params = new HashMap<>(); - params.put("appid", xcx_app_id); - params.put("secret", xcx_app_secret); -// params.put("cache_name", "wechat"); - params.put("grant_type", "client_credential"); - - JSONObject resultObj = new JSONObject(); - String response = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", params); - JSONObject jsonObject = JSONUtil.parseObj(response); - - Object errmsg = jsonObject.get("errmsg"); - if (ObjectUtil.isNotEmpty(errmsg)) { - String errmsgStr = Convert.toStr(resultObj.get("errmsg")); - if (!errmsgStr.equals("0")) { - throw new ApiException(I18nUtil._("获取access_token失败")); - } - } - Integer expiresIn = Convert.toInt(jsonObject.get("expires_in"), 0); - redisService.set(StateCode.WX_XCX_ACCESSTOKEN, Convert.toStr(jsonObject.get("access_token")), expiresIn); - } - /** * 生成(永久)小程序太阳码 * @@ -191,7 +159,7 @@ public class WxQrCodeServiceImpl implements WxQrCodeService { env_version = "release"; } - String reqUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + getAccessToken(); + String reqUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + wxUtil.getAccessToken(); Map params = new HashMap(); params.put("scene", scene); params.put("page", page); @@ -269,7 +237,7 @@ public class WxQrCodeServiceImpl implements WxQrCodeService { public Map genUnlimitedWxQrCode(String preparedUrl, Map param) { try { String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="; - String reqUrl = url + getAccessToken(); + String reqUrl = url + wxUtil.getAccessToken(); Map params = new HashMap(); Map map = parseUrl(preparedUrl); Map lineColor = new HashMap<>(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/utils/WxUtil.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/utils/WxUtil.java new file mode 100644 index 00000000..1d6f6fc2 --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/utils/WxUtil.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025. 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.shop.wechat.utils; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.suisung.mall.common.api.StateCode; +import com.suisung.mall.common.exception.ApiException; +import com.suisung.mall.common.utils.I18nUtil; +import com.suisung.mall.core.web.service.RedisService; +import com.suisung.mall.shop.base.service.AccountBaseConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Repository; + +import java.util.HashMap; +import java.util.Map; + +@Repository +public class WxUtil { + + @Lazy + @Autowired + private RedisService redisService; + + @Lazy + @Autowired + private AccountBaseConfigService accountBaseConfigService; + + + /** + * 获取小程序的access_token, 并做了 redis 缓存 + * + * @return + */ + public String getAccessToken() { + if (!redisService.hasKey(StateCode.WX_XCX_ACCESSTOKEN)) { + getToken(); + } + return Convert.toStr(redisService.get(StateCode.WX_XCX_ACCESSTOKEN)); + } + + private void getToken() { + String xcx_app_id = accountBaseConfigService.getConfig("wechat_xcx_app_id"); + String xcx_app_secret = accountBaseConfigService.getConfig("wechat_xcx_app_secret"); + + Map params = new HashMap<>(); + params.put("appid", xcx_app_id); + params.put("secret", xcx_app_secret); + params.put("grant_type", "client_credential"); + + JSONObject resultObj = new JSONObject(); + String response = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", params); + JSONObject jsonObject = JSONUtil.parseObj(response); + + Object errmsg = jsonObject.get("errmsg"); + if (ObjectUtil.isNotEmpty(errmsg)) { + String errmsgStr = Convert.toStr(resultObj.get("errmsg")); + if (!errmsgStr.equals("0")) { + throw new ApiException(I18nUtil._("获取access_token失败")); + } + } + Integer expiresIn = Convert.toInt(jsonObject.get("expires_in"), 0); + redisService.set(StateCode.WX_XCX_ACCESSTOKEN, Convert.toStr(jsonObject.get("access_token")), expiresIn); + } +} diff --git a/pom.xml b/pom.xml index 867b418a..f5f55dbf 100644 --- a/pom.xml +++ b/pom.xml @@ -320,8 +320,8 @@ 42.194.196.179 3306 mall_dev - root - B1x1GuKZr55PPmox + webdev + jbFr9YewcA9Mihx6fnw51Kzq com.mysql.cj.jdbc.Driver @@ -534,6 +534,7 @@ ["java", "-jar", "-Xms128m", "-Xmx512m", "-XX:PermSize=64M", "-XX:MaxPermSize=512M", "-Dspring.profiles.active=${spring.profile}", "-Duser.timezone=Asia/Shanghai", "/${project.build.finalName}.jar"] + ${docker.ca}