diff --git a/src/main/java/com/gxwebsoft/cms/entity/CmsNavigation.java b/src/main/java/com/gxwebsoft/cms/entity/CmsNavigation.java index 1570a9a..449cf54 100644 --- a/src/main/java/com/gxwebsoft/cms/entity/CmsNavigation.java +++ b/src/main/java/com/gxwebsoft/cms/entity/CmsNavigation.java @@ -43,6 +43,10 @@ public class CmsNavigation implements Serializable { @Schema(description = "模型") private String model; + @Schema(description = "模型名称") + @TableField(exist = false) + private String modelName; + @Schema(description = "标识") private String code; @@ -114,9 +118,6 @@ public class CmsNavigation implements Serializable { @TableField(exist = false) private Integer parentPosition; - @Schema(description = "模型名称") - private String modelName; - @Schema(description = "绑定的页面(已废弃)") private Integer pageId; diff --git a/src/main/java/com/gxwebsoft/cms/mapper/xml/CmsNavigationMapper.xml b/src/main/java/com/gxwebsoft/cms/mapper/xml/CmsNavigationMapper.xml index 837a948..20903aa 100644 --- a/src/main/java/com/gxwebsoft/cms/mapper/xml/CmsNavigationMapper.xml +++ b/src/main/java/com/gxwebsoft/cms/mapper/xml/CmsNavigationMapper.xml @@ -4,9 +4,10 @@ - SELECT a.*, b.title as parentName, b.position as parentPosition + SELECT a.*, b.title as parentName, b.position as parentPosition, c.name as modelName FROM cms_navigation a LEFT JOIN cms_navigation b ON a.parent_id = b.navigation_id + LEFT JOIN cms_model c ON a.model = c.model AND a.navigation_id = #{param.navigationId} diff --git a/src/main/java/com/gxwebsoft/common/core/utils/JSONUtil.java b/src/main/java/com/gxwebsoft/common/core/utils/JSONUtil.java index 8d63168..3c32d8e 100644 --- a/src/main/java/com/gxwebsoft/common/core/utils/JSONUtil.java +++ b/src/main/java/com/gxwebsoft/common/core/utils/JSONUtil.java @@ -1,8 +1,13 @@ package com.gxwebsoft.common.core.utils; import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.util.TimeZone; /** * JSON解析工具类 @@ -11,8 +16,21 @@ import com.fasterxml.jackson.databind.ObjectWriter; * @since 2017-06-10 10:10:39 */ public class JSONUtil { - private static final ObjectMapper objectMapper = new ObjectMapper(); - private static final ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter(); + /** + * 注意:不要直接 new ObjectMapper() 否则不支持 Java8 时间类型(LocalDateTime 等)。 + * 这里做最小可用配置,避免在 Redis/日志/签名等场景序列化失败。 + */ + private static final ObjectMapper objectMapper; + private static final ObjectWriter objectWriter; + + static { + objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); + objectWriter = objectMapper.writerWithDefaultPrettyPrinter(); + } /** * 对象转json字符串 diff --git a/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java b/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java index 4bb8394..9ed476a 100644 --- a/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java +++ b/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java @@ -54,7 +54,7 @@ import static com.gxwebsoft.common.core.constants.RedisConstants.MP_WX_KEY; public class WxLoginController extends BaseController { private final StringRedisTemplate redisTemplate; private final OkHttpClient http = new OkHttpClient(); - private final ObjectMapper om = new ObjectMapper(); + private final ObjectMapper om; private volatile long tokenExpireEpoch = 0L; // 过期的 epoch 秒 @Resource private SettingService settingService; @@ -80,8 +80,9 @@ public class WxLoginController extends BaseController { private CmsWebsiteService cmsWebsiteService; - public WxLoginController(StringRedisTemplate redisTemplate) { + public WxLoginController(StringRedisTemplate redisTemplate, ObjectMapper objectMapper) { this.redisTemplate = redisTemplate; + this.om = objectMapper; } @Operation(summary = "获取微信AccessToken") diff --git a/src/main/java/com/gxwebsoft/payment/service/WxTransferService.java b/src/main/java/com/gxwebsoft/payment/service/WxTransferService.java index 2925e65..a5ebfb9 100644 --- a/src/main/java/com/gxwebsoft/payment/service/WxTransferService.java +++ b/src/main/java/com/gxwebsoft/payment/service/WxTransferService.java @@ -16,6 +16,7 @@ import com.wechat.pay.java.core.http.JsonRequestBody; import com.wechat.pay.java.core.http.MediaType; import com.wechat.pay.java.core.exception.ServiceException; import com.wechat.pay.java.core.util.GsonUtil; +import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -121,6 +122,18 @@ public class WxTransferService { userName = null; } + // 升级版接口必填:transfer_scene_report_infos(且必须与 transfer_scene_id 的报备信息一致) + List sceneReportInfos = parseTransferSceneReportInfos(); + if (sceneReportInfos == null + || sceneReportInfos.isEmpty() + || sceneReportInfos.stream().anyMatch(i -> i == null + || StrUtil.isBlank(i.getInfoType()) + || StrUtil.isBlank(i.getInfoContent()))) { + throw PaymentException.paramError( + "未传入完整且对应的转账场景报备信息:请在配置中设置 wechatpay.transfer.scene-report-infos-json(需与 transfer_scene_id=" + + transferSceneId + " 的报备信息一致)"); + } + Payment paymentConfig = wxPayConfigService.getPaymentConfigForStrategy(tenantId); Config wxPayConfig = wxPayConfigService.getWxPayConfig(tenantId); @@ -135,10 +148,9 @@ public class WxTransferService { request.setOpenid(openid); request.setTransferAmount(amountFen); request.setTransferRemark(limitLen(remark, 32)); - List sceneReportInfos = parseTransferSceneReportInfos(); - if (sceneReportInfos != null && !sceneReportInfos.isEmpty()) { - request.setTransferSceneReportInfos(sceneReportInfos); - } + request.setTransferSceneReportInfos(sceneReportInfos); + log.debug("微信商家转账(升级版)请求参数: tenantId={}, outBillNo={}, transferSceneId={}, sceneReportInfosCount={}", + tenantId, outBillNo, transferSceneId, sceneReportInfos.size()); // 可选:转账结果通知地址(必须 https) if (StrUtil.isNotBlank(paymentConfig.getNotifyUrl()) && paymentConfig.getNotifyUrl().startsWith("https://")) { @@ -244,7 +256,9 @@ public class WxTransferService { @lombok.Data private static class TransferSceneReportInfo { + @SerializedName(value = "info_type", alternate = {"infoType"}) private String infoType; + @SerializedName(value = "info_content", alternate = {"infoContent"}) private String infoContent; } diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopDealerUserController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopDealerUserController.java index 1023cd1..9d5d469 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopDealerUserController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopDealerUserController.java @@ -3,6 +3,7 @@ package com.gxwebsoft.shop.controller; import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gxwebsoft.common.core.utils.JSONUtil; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.shop.service.ShopDealerUserService; @@ -67,6 +68,10 @@ public class ShopDealerUserController extends BaseController { if (loginUser != null) { shopDealerUser.setUserId(loginUser.getUserId()); } + // 排重 + if (shopDealerUserService.count(new LambdaQueryWrapper().eq(ShopDealerUser::getMobile, shopDealerUser.getMobile())) > 0) { + return fail("添加失败,手机号码已存在!"); + } if (shopDealerUserService.save(shopDealerUser)) { return success("添加成功", shopDealerUser); } diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopDealerWithdrawController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopDealerWithdrawController.java index 3ae7905..b9f1f06 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopDealerWithdrawController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopDealerWithdrawController.java @@ -66,7 +66,6 @@ public class ShopDealerWithdrawController extends BaseController { } @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:save')") - @OperationLog @Transactional(rollbackFor = {Exception.class}) @Operation(summary = "添加分销商提现明细表") @PostMapping() @@ -87,7 +86,6 @@ public class ShopDealerWithdrawController extends BaseController { } @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:update')") - @OperationLog @Transactional(rollbackFor = {Exception.class}) @Operation(summary = "修改分销商提现明细表") @PutMapping() diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopDealerUser.java b/src/main/java/com/gxwebsoft/shop/entity/ShopDealerUser.java index d020fe8..2184e28 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/ShopDealerUser.java +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopDealerUser.java @@ -37,6 +37,12 @@ public class ShopDealerUser implements Serializable { @TableField(exist = false) private String openid; + @Schema(description = "店铺名称") + private String dealerName; + + @Schema(description = "小区名称") + private String community; + @Schema(description = "头像") @TableField(exist = false) private String avatar; diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java b/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java index 953b867..9d3f303 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java @@ -2,6 +2,7 @@ package com.gxwebsoft.shop.entity; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import java.time.LocalDateTime; import com.fasterxml.jackson.annotation.JsonFormat; @@ -44,6 +45,10 @@ public class ShopGoods implements Serializable { @Schema(description = "产品分类ID") private Integer categoryId; + @Schema(description = "分类名称") + @TableField(exist = false) + private String categoryName; + @Schema(description = "路由地址") private String path; diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerUserMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerUserMapper.xml index 75809be..de01801 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerUserMapper.xml +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerUserMapper.xml @@ -64,6 +64,7 @@ AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + OR a.user_id = #{param.keywords} OR a.dealer_name LIKE CONCAT('%', #{param.keywords}, '%') OR a.real_name LIKE CONCAT('%', #{param.keywords}, '%') OR a.mobile LIKE CONCAT('%', #{param.keywords}, '%') ) diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGoodsMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGoodsMapper.xml index bb91f03..a14c354 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGoodsMapper.xml +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGoodsMapper.xml @@ -4,8 +4,9 @@ - SELECT a.* + SELECT a.*, b.title AS categoryName FROM shop_goods a + LEFT JOIN cms_navigation b ON a.category_id = b.navigation_id AND a.goods_id = #{param.goodsId} diff --git a/src/main/resources/application-cms.yml b/src/main/resources/application-cms.yml index f086352..aba37b5 100644 --- a/src/main/resources/application-cms.yml +++ b/src/main/resources/application-cms.yml @@ -75,3 +75,9 @@ payment: key-prefix: "Payment:1" # 缓存过期时间(小时) expire-hours: 24 + +# 微信支付-商家转账(升级版)转账场景报备信息(必须与商户平台 transfer_scene_id=1005 的报备信息一致) +wechatpay: + transfer: + scene-id: 1005 + scene-report-infos-json: '[{"info_type":"岗位类型","info_content":"业务员"},{"info_type":"报酬说明","info_content":"配送费"}]' diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 2ff0825..9c123f1 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -63,3 +63,9 @@ aliyun: access-key-id: LTAI5tEsyhW4GCKbds1qsopg access-key-secret: zltFlQrYVAoq2KMFDWgLa3GhkMNeyO endpoint: mt.cn-hangzhou.aliyuncs.com + +# 微信支付-商家转账(升级版)转账场景报备信息(必须与商户平台 transfer_scene_id=1005 的报备信息一致) +wechatpay: + transfer: + scene-id: 1005 + scene-report-infos-json: '[{"info_type":"岗位类型","info_content":"业务员"},{"info_type":"报酬说明","info_content":"配送费"}]' diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 7c17894..c077478 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -77,3 +77,7 @@ aliyun: access-key-id: LTAI5tEsyhW4GCKbds1qsopg access-key-secret: zltFlQrYVAoq2KMFDWgLa3GhkMNeyO endpoint: mt.cn-hangzhou.aliyuncs.com +wechatpay: + transfer: + scene-id: 1005 + scene-report-infos-json: '[{"info_type":"岗位类型","info_content":"业务员"},{"info_type":"报酬说明","info_content":"配送费"}]' diff --git a/src/main/resources/application-yd.yml b/src/main/resources/application-yd.yml index b163af1..834efcb 100644 --- a/src/main/resources/application-yd.yml +++ b/src/main/resources/application-yd.yml @@ -75,3 +75,9 @@ payment: key-prefix: "Payment:1" # 缓存过期时间(小时) expire-hours: 24 + +# 微信支付-商家转账(升级版)转账场景报备信息(必须与商户平台 transfer_scene_id=1005 的报备信息一致) +wechatpay: + transfer: + scene-id: 1005 + scene-report-infos-json: '[{"info_type":"岗位类型","info_content":"业务员"},{"info_type":"报酬说明","info_content":"配送费"}]'