调整品牌添加商城开启管理;调整微信支付包存放位置;

This commit is contained in:
DB 2023-11-15 16:33:56 +08:00
parent f70c265487
commit 299bc55db7
23 changed files with 360 additions and 87 deletions

View File

@ -6,11 +6,16 @@ import com.cpop.common.enums.ErrorCodeEnum;
import io.jsonwebtoken.JwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
@ -24,7 +29,6 @@ import java.util.Objects;
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 业务异常
*/

View File

@ -19,7 +19,7 @@ public class StringToArraySerializer extends JsonSerializer<String> {
@Override
public void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (StringUtils.isNotBlank(str)) {
if (null != str) {
String[] split = str.split(",");
jsonGenerator.writeArray(split, 0, split.length);
}

View File

@ -5,6 +5,7 @@ import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.loginInfo.MiniUserLoginInfo;
import com.cpop.core.base.enums.SourceType;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.CpopAuthenticationException;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.SysUser;
import com.mybatisflex.core.row.Db;
@ -87,6 +88,19 @@ public class MiniLoginStrategy implements LoginStrategy {
* @return: void
*/
private void changeJamboxUser(MiniUserLoginInfo loginInfo, Map<String, Object> credentials, SourceType sourceType) {
//获取品牌表
Row brand = DbChain.table("cp_sys_brand")
.select("csb.id", "csb.is_open_sharing")
.from("cp_sys_brand").as("csb")
.leftJoin("cp_j_brand_extend").as("cjbe").on("cjbe.brand_id = csb.id")
.and("cjbe.brand_cloud_id = ?", credentials.get("brandId"))
.one();
if (brand == null) {
throw new CpopAuthenticationException("用户登陆失败,果酱品牌暂未录入系统");
}
if (!brand.getBoolean("isOpenSharing")){
throw new CpopAuthenticationException("用户登陆失败,当前品牌暂未开通分账");
}
//构建用户信息
Row row = DbChain.table("cp_mini_user")
.select("cmu.id","cmu.open_id","cmu.app_id","cmu.user_id","cmu.brand_id","cmu.nick_name","cmu.avatar","cmu.source_type")
@ -101,16 +115,6 @@ public class MiniLoginStrategy implements LoginStrategy {
.and("cmu.is_delete = 0")
.one();
if (row == null) {
//获取品牌表
Row brand = DbChain.table("cp_sys_brand")
.select("csb.id")
.from("cp_sys_brand").as("csb")
.leftJoin("cp_j_brand_extend").as("cjbe").on("cjbe.brand_id = csb.id")
.and("cjbe.brand_cloud_id = ?", credentials.get("brandId"))
.one();
if (brand == null) {
throw new ServiceException("用户登陆失败,果酱品牌暂未录入系统");
}
//保存小程序用户信息
LocalDateTime now = LocalDateTime.now();
Row miniUser = Row.ofKey(RowKey.SNOW_FLAKE_ID);

View File

@ -18,6 +18,11 @@
<groupId>com.cpop</groupId>
<artifactId>Cpop-Core</artifactId>
</dependency>
<!--微信支付-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -115,11 +115,11 @@ mall:
wx:
pay:
# p12证书的位置可以指定绝对路径也可以指定类路径以classpath:开头)
keyPath: E:/Cpop/Cpop-Union/Cpop-Mall/Cpop-Mall-Web/src/main/resources/static/keyPair/wxPay_cert.p12
keyPath: E:/Cpop/Cpop-Union/Cpop-Core/src/main/resources/static/keyPair/wxPay_cert.p12
# 私钥证书
privateKeyPath: E:/Cpop/Cpop-Union/Cpop-Mall/Cpop-Mall-Web/src/main/resources/static/keyPair/wxPay_key.pem
privateKeyPath: E:/Cpop/Cpop-Union/Cpop-Core/src/main/resources/static/keyPair/wxPay_key.pem
# 私钥文件
privateCertPath: E:/Cpop/Cpop-Union/Cpop-Mall/Cpop-Mall-Web/src/main/resources/static/keyPair/wxPay_cert.pem
privateCertPath: E:/Cpop/Cpop-Union/Cpop-Core/src/main/resources/static/keyPair/wxPay_cert.pem
#支付通知地址
notifyUrl: https://frp-oak.top:11899/Cpop-Mall/wxPay/callback/notify/order
#退款通知地址

View File

@ -139,3 +139,4 @@ wx:
apiV3Key: JamBox20230919174000000000000002
#分账服务商账号
sharingAccount: 1618884922
sharingAccountName: 果酱盒子

View File

@ -27,11 +27,6 @@
<groupId>com.cpop</groupId>
<artifactId>Cpop-Jambox</artifactId>
</dependency>
<!--微信支付-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -304,7 +304,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//查询是否是服务商系品牌
String brandId = loginUserInfo.getString("brandId");
Brand brand = SpringUtils.getBean(BrandService.class).getById(brandId);
if (StringUtils.isBlank(brand.getWxAppId()) || !StringUtils.equals(brand.getWxAppId(), wxPayService.getConfig().getAppId())) {
//需要分账
if (order.getTotalAmount().scaleByPowerOfTen(2).intValue() >= 10) {
//需要分账
orderRequest.setProfitSharing("Y");
}
@ -529,11 +530,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
Order order = this.getById(orderId);
//获取订单品牌信息
Brand brand = SpringUtils.getBean(BrandService.class).getById(order.getBrandId());
if (StringUtils.isBlank(brand.getWxAppId()) || !StringUtils.equals(brand.getWxAppId(), wxPayService.getConfig().getAppId())) {
//需要分账
if (notifyResult.getTotalFee() >= 10) {
wxPayAsyncTask.asyncWxPayProfitSharing(orderId, notifyResult, wxPayService);
}
//需要分账
if (notifyResult.getTotalFee() >= 10) {
wxPayAsyncTask.asyncWxPayProfitSharing(orderId, notifyResult, wxPayService);
}
//异步更新
SpringUtils.getBean(ProductRecordSyncStockTask.class).asyncUpdateRecords(orderNumMap);
@ -639,7 +638,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//查询是否是服务商系品牌
String brandId = loginUserInfo.getString("brandId");
Brand brand = SpringUtils.getBean(BrandService.class).getById(brandId);
if (StringUtils.isBlank(brand.getWxAppId()) || !StringUtils.equals(brand.getWxAppId(), wxPayService.getConfig().getAppId())) {
//需要分账
if (order.getTotalAmount().scaleByPowerOfTen(2).intValue() >= 10) {
//需要分账
orderRequest.setProfitSharing("Y");
}
@ -653,7 +653,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//元转分
.setTotalFee(order.getTotalAmount().scaleByPowerOfTen(2).intValue())
.setTradeType("JSAPI");
return wxPayService.createOrder(orderRequest);
} else {
return pointPay(recordNumIsEnough, order, loginUserInfo);

View File

@ -45,14 +45,4 @@ public class WxPayConfiguration {
return wxPayService;
}
/**
* @descriptions 读取微信支付配置文件
* @author DB
* @date 2023/11/01 17:27
* @return: com.cpop.mall.framework.config.wxPay.WxPayProperties
*/
public WxPayProperties getProperties() {
return properties;
}
}

View File

@ -66,6 +66,11 @@ public class WxPayProperties {
*/
private String sharingAccount;
/**
* 分账账号名
*/
private String sharingAccountName;
/**
* 分账通知
*/

View File

@ -82,4 +82,14 @@ knife4j:
group-name: Oam
api-rule: package
api-rule-resources:
- com.cpop.oam
- com.cpop.oam
#微信支付
wx:
pay:
# p12证书的位置可以指定绝对路径也可以指定类路径以classpath:开头)
keyPath: E:/Cpop/Cpop-Union/Cpop-Core/src/main/resources/static/keyPair/wxPay_cert.p12
# 私钥证书
privateKeyPath: E:/Cpop/Cpop-Union/Cpop-Core/src/main/resources/static/keyPair/wxPay_key.pem
# 私钥文件
privateCertPath: E:/Cpop/Cpop-Union/Cpop-Core/src/main/resources/static/keyPair/wxPay_cert.pem

View File

@ -62,4 +62,14 @@ mybatis-flex:
jambox:
url: jdbc:mysql://sh-cynosdbmysql-grp-fggo83js.sql.tencentcdb.com:20965/jambox_association?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
username: root
password: Customer0401
password: Customer0401
#微信支付
wx:
pay:
# p12证书的位置可以指定绝对路径也可以指定类路径以classpath:开头)
keyPath: /root/cpop-union/cpop-oam/script/secretKey/wxPay_cert.p12
# 私钥证书
privateKeyPath: /root/cpop-union/cpop-oam/script/secretKey/wxPay_key.pem
# 私钥文件
privateCertPath: /root/cpop-union/cpop-oam/script/secretKey/wxPay_cert.pem

View File

@ -83,4 +83,14 @@ knife4j:
group-name: Oam
api-rule: package
api-rule-resources:
- com.cpop.oam
- com.cpop.oam
#微信支付
wx:
pay:
# p12证书的位置可以指定绝对路径也可以指定类路径以classpath:开头)
keyPath: /root/cpop-union/cpop-oam/script/secretKey/wxPay_cert.p12
# 私钥证书
privateKeyPath: /root/cpop-union/cpop-oam/script/secretKey/wxPay_key.pem
# 私钥文件
privateCertPath: /root/cpop-union/cpop-oam/script/secretKey/wxPay_cert.pem

View File

@ -147,4 +147,16 @@ wx:
componentSecret: fc2e9457aaa32342751cc655b5a1d273
componentToken: jambox
componentAesKey: 1a3NBxmCFwkCJvfoQ7WhJHB6iX3qHPsc9JbaDznE1i0
redirectUri: https://empower.oamapi.cpopsz.com/test/openPlatform/thirdPartyPlatform/redirectUrl
redirectUri: https://empower.oamapi.cpopsz.com/test/openPlatform/thirdPartyPlatform/redirectUrl
#微信支付
pay:
#微信公众号或者小程序等的appid
appId: wx20853d18c455e874
#微信支付商户号
mchId: 1618884922
#微信支付商户密钥
mchKey: JamBox20230919174000000000000002
apiV3Key: JamBox20230919174000000000000002
#分账服务商账号
sharingAccount: 1618884922
sharingAccountName: 果酱盒子

View File

@ -0,0 +1,95 @@
package com.cpop.oam.business.controller;
import com.alibaba.fastjson.JSONObject;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.R;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.oam.framework.config.wxPay.WxPayConfiguration;
import com.cpop.system.business.bo.ChangeWechatSharingBo;
import com.cpop.system.business.entity.Brand;
import com.cpop.system.business.service.BrandService;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingReceiverRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import static com.cpop.system.business.entity.table.BrandTableDef.BRAND;
/**
* @author DB
* @createTime 2023/11/15 11:21
* @description
*/
@RestController
@Api(tags = "微信支付模块")
@RequestMapping("/wxPay")
public class WxPayController {
@Autowired
private WxPayConfiguration wxPayConfiguration;
@Autowired
private WxPayService wxPayService;
@Autowired
private BrandService brandService;
/**
* @descriptions 开通微信分账
* @author DB
* @date 2023/11/15 11:06
* @return: com.cpop.core.base.R<java.lang.Void>
*/
@PreAuthorize("@aps.hasPermission('brandStore:brand:update')")
@ApiOperation("开通品牌商城")
@PutMapping("/changeBrandMall")
public R<Void> changeWechatSharing(@RequestBody @Validated ChangeWechatSharingBo bo) {
//获取品牌下属商户
Brand brand = brandService.getById(bo.getBrandId());
if (StringUtils.isBlank(brand.getWxMchId())) {
throw new ServiceException("当前品牌暂未绑定系统,请联系相关人员绑定");
}
//固定商户信息
Map<String, Object> mapReceiver = new HashMap<>(4);
mapReceiver.put("type", "MERCHANT_ID");
mapReceiver.put("account", wxPayConfiguration.getProperties().getSharingAccount());
//添加分账接收方
ProfitSharingReceiverRequest profitSharingReceiver = new ProfitSharingReceiverRequest();
//开启
if (bo.getIsOpenMall()) {
mapReceiver.put("relation_type", "SERVICE_PROVIDER");
mapReceiver.put("name", wxPayConfiguration.getProperties().getSharingAccountName());
profitSharingReceiver.setReceiver(JSONObject.toJSONString(mapReceiver));
WxPayConfig config = wxPayService.getConfig();
config.setSubMchId(brand.getWxMchId());
try {
wxPayService.getProfitSharingService().addReceiver(profitSharingReceiver);
} catch (WxPayException e) {
throw new ServiceException(e.getMessage());
}
} else {
//关闭
profitSharingReceiver.setReceiver(JSONObject.toJSONString(mapReceiver));
WxPayConfig config = wxPayService.getConfig();
config.setSubMchId(brand.getWxMchId());
try {
wxPayService.getProfitSharingService().removeReceiver(profitSharingReceiver);
} catch (WxPayException e) {
throw new ServiceException(e.getMessage());
}
}
brandService.updateChain().set(BRAND.IS_OPEN_MALL, bo.getIsOpenMall()).where(BRAND.ID.eq(bo.getBrandId())).update();
return R.ok();
}
}

View File

@ -0,0 +1,51 @@
package com.cpop.oam.framework.config.wxPay;
import com.cpop.common.utils.StringUtils;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author DB
* @Description:
* @create 2023-10-26 22:38
*/
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {
private WxPayProperties properties;
@Bean
@ConditionalOnMissingBean
public WxPayService wxService() {
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
//服务商模式微信支付
payConfig.setApiV3Key(this.properties.getApiV3Key());
payConfig.setCertSerialNo(this.properties.getCertSerialNo());
payConfig.setKeyPath(this.properties.getKeyPath());
payConfig.setPrivateKeyPath(this.properties.getPrivateKeyPath());
payConfig.setPrivateCertPath(this.properties.getPrivateCertPath());
//通知地址
payConfig.setNotifyUrl(this.properties.getNotifyUrl());
// 可以指定是否使用沙箱环境
payConfig.setUseSandboxEnv(false);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
return wxPayService;
}
public WxPayProperties getProperties() {
return properties;
}
}

View File

@ -0,0 +1,78 @@
package com.cpop.oam.framework.config.wxPay;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author DB
* @Description:
* @create 2023-10-26 22:39
*/
@Data
@ConfigurationProperties(prefix = "wx.pay")
public class WxPayProperties {
/**
* 设置微信公众号或者小程序等的appid
*/
private String appId;
/**
* 微信支付商户号
*/
private String mchId;
/**
* 微信支付商户密钥
*/
private String mchKey;
/**
* apiclient_cert.p12文件的绝对路径或者如果放在项目中请以classpath:开头指定
*/
private String keyPath;
/**
* apiV3 秘钥值
*/
private String apiV3Key;
/**
* apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径
*/
private String privateKeyPath;
/**
* apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径
*/
private String privateCertPath;
/**
* apiV3 证书序列号值
*/
private String certSerialNo;
/**
* 支付通知地址
*/
private String notifyUrl;
/**
* 退款通知
*/
private String notifyRefund;
/**
* 分账账号
*/
private String sharingAccount;
/**
* 分账账号名
*/
private String sharingAccountName;
/**
* 分账通知
*/
private String notifySharing;
}

View File

@ -33,28 +33,9 @@ public class BrandBo {
/**
* 微信商户号
*/
@NotBlank(message = "商户号不能为空")
@ApiModelProperty(value = "微信商户号",required = true)
@ApiModelProperty(value = "微信商户号")
private String wxMchId;
/**
* 微信Appid
*/
@ApiModelProperty("微信Appid")
private String wxAppId;
/**
* 微信支付密钥
*/
@ApiModelProperty("微信支付密钥")
private String wxMchKey;
/**
* 微信支付keypath
*/
@ApiModelProperty("微信支付keypath")
private String wxKeyPath;
/**
* 背景图
*/

View File

@ -0,0 +1,33 @@
package com.cpop.system.business.bo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @author DB
* @createTime 2023/11/15 11:52
* @description
*/
@Data
@ApiModel(value = "微信分账相关参数")
public class ChangeWechatSharingBo implements Serializable {
/**
* 品牌id
*/
@NotBlank(message = "不能为空")
@ApiModelProperty(value = "品牌id",required = true)
private String brandId;
/**
* 是否开启分账
*/
@NotNull(message = "是否开启商城不能为空")
@ApiModelProperty(value = "是否开启商城",required = true)
private Boolean isOpenMall;
}

View File

@ -40,26 +40,11 @@ public class Brand extends BaseEntity implements Serializable {
*/
private String brandName;
/**
* 微信appid
*/
private String wxAppId;
/**
* 微信商户号
*/
private String wxMchId;
/**
* 微信支付密钥
*/
private String wxMchKey;
/**
* 微信支付keypath
*/
private String wxKeyPath;
/**
* 数据来源
*/
@ -70,6 +55,11 @@ public class Brand extends BaseEntity implements Serializable {
*/
private String backgroundUrl;
/**
* 是否开通商城
*/
private Boolean isOpenMall;
/**
* 逻辑删除0否1是
*/

View File

@ -26,7 +26,7 @@ public interface BrandService extends IService<Brand> {
* @descriptions 查询品牌分页列表
* @author DB
* @date 2023/10/25 17:32
* @param bo 请求参数
* @param brandName 请求参数
* @return: com.mybatisflex.core.paginate.Page<com.cpop.system.business.vo.BrandPageVo>
*/
Page<BrandPageVo> getBrandPage(String brandName);
@ -39,4 +39,5 @@ public interface BrandService extends IService<Brand> {
* @return: void
*/
void removeBrandById(String id);
}

View File

@ -1,7 +1,6 @@
package com.cpop.system.business.service.impl;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.base.enums.SourceType;
@ -24,10 +23,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import static com.cpop.system.business.entity.table.BrandTableDef.BRAND;
@ -76,10 +72,7 @@ public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements
}
Brand sysBrand = new Brand();
sysBrand.setBrandName(brand.getString("name"))
.setWxAppId(brand.getString("appid"))
.setWxMchId(brand.getString("wxMchId"))
.setWxMchKey(brand.getString("wxMchKey"))
.setWxKeyPath(brand.getString("wxKeyPath"))
.setBackgroundUrl(brand.getString("brandBg"))
.setSourceType(SourceType.JAMBOX.toString());
this.save(sysBrand);
@ -159,7 +152,7 @@ public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements
PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
return this.mapper.paginateAs(pageDomain.getPageNum(), pageDomain.getPageSize(),
QueryWrapper.create()
.select(BRAND.ID, BRAND.BRAND_NAME, BRAND.WX_MCH_ID, BRAND.CREATE_TIME, BRAND.BACKGROUND_URL, BRAND.WX_APP_ID, BRAND.WX_MCH_KEY, BRAND.WX_KEY_PATH)
.select(BRAND.ID, BRAND.BRAND_NAME, BRAND.WX_MCH_ID, BRAND.CREATE_TIME, BRAND.BACKGROUND_URL, BRAND.IS_OPEN_MALL)
.and(BRAND.BRAND_NAME.like(brandName)),
BrandPageVo.class);
}

View File

@ -65,6 +65,12 @@ public class BrandPageVo implements Serializable {
@ApiModelProperty("背景图")
private String backgroundUrl;
/**
* 是否开通微信分账
*/
@ApiModelProperty("是否开通微信分账")
private Boolean isOpenSharing;
/**
* 创建时间
*/