Commit 131204ec by 程裕兵

Merge branch 'feature/mini-pay' into release/rc

parents ac44ca4c 3db0a744
...@@ -4,18 +4,22 @@ import com.jiejing.common.model.JsonResult; ...@@ -4,18 +4,22 @@ import com.jiejing.common.model.JsonResult;
import com.jiejing.common.model.PageVO; import com.jiejing.common.model.PageVO;
import com.jiejing.fitness.finance.api.merchant.request.ApplyStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.ApplyStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.AuthStudioSubChannelRequest; import com.jiejing.fitness.finance.api.merchant.request.AuthStudioSubChannelRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantXcxAppIdRequest; import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantXcxAppIdRequest;
import com.jiejing.fitness.finance.api.merchant.request.CheckUnbindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.CheckUnbindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetAuthStudioSubChannelRequest; import com.jiejing.fitness.finance.api.merchant.request.GetAuthStudioSubChannelRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetOpenIdRequest; import com.jiejing.fitness.finance.api.merchant.request.GetOpenIdRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioLatestMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioLatestMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.PageStudioMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.PageStudioMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantPayRequest; import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantPayRequest;
import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantRefundRequest; import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantRefundRequest;
import com.jiejing.fitness.finance.api.merchant.request.SyncStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.UnbindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.UnbindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.vo.StudioEmbeddedXcxVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO;
...@@ -106,4 +110,16 @@ public interface StudioMerchantApi { ...@@ -106,4 +110,16 @@ public interface StudioMerchantApi {
@PostMapping(value = "/private/studioMerchant/refund") @PostMapping(value = "/private/studioMerchant/refund")
JsonResult<StudioMerchantRefundVO> refund(StudioMerchantRefundRequest request); JsonResult<StudioMerchantRefundVO> refund(StudioMerchantRefundRequest request);
@ApiOperation(value = "获取半屏小程序", tags = {TAG})
@PostMapping(value = "/private/studio/getEmbeddedXcx")
JsonResult<StudioEmbeddedXcxVO> getEmbeddedXcx(GetStudioEmbeddedXcxRequest request);
@ApiOperation(value = "绑定半屏小程序", tags = {TAG})
@PostMapping(value = "/private/studio/bindEmbeddedXcx")
JsonResult<Void> bindEmbeddedXcx(BindStudioEmbeddedXcxRequest request);
@ApiOperation(value = "同步半屏小程序状态", tags = {TAG})
@PostMapping(value = "/private/studio/syncEmbeddedXcx")
JsonResult<Void> syncEmbeddedXcx(SyncStudioEmbeddedXcxRequest request);
} }
\ No newline at end of file
...@@ -4,18 +4,22 @@ import com.jiejing.common.model.JsonResult; ...@@ -4,18 +4,22 @@ import com.jiejing.common.model.JsonResult;
import com.jiejing.common.model.PageVO; import com.jiejing.common.model.PageVO;
import com.jiejing.fitness.finance.api.merchant.request.ApplyStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.ApplyStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.AuthStudioSubChannelRequest; import com.jiejing.fitness.finance.api.merchant.request.AuthStudioSubChannelRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantXcxAppIdRequest; import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantXcxAppIdRequest;
import com.jiejing.fitness.finance.api.merchant.request.CheckUnbindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.CheckUnbindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetAuthStudioSubChannelRequest; import com.jiejing.fitness.finance.api.merchant.request.GetAuthStudioSubChannelRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetOpenIdRequest; import com.jiejing.fitness.finance.api.merchant.request.GetOpenIdRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioLatestMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioLatestMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.PageStudioMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.PageStudioMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantPayRequest; import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantPayRequest;
import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantRefundRequest; import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantRefundRequest;
import com.jiejing.fitness.finance.api.merchant.request.SyncStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.UnbindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.UnbindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.vo.StudioEmbeddedXcxVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO;
...@@ -126,6 +130,21 @@ public class StudioMerchantApiFallback implements FallbackFactory<StudioMerchant ...@@ -126,6 +130,21 @@ public class StudioMerchantApiFallback implements FallbackFactory<StudioMerchant
public JsonResult<StudioMerchantRefundVO> refund(StudioMerchantRefundRequest request) { public JsonResult<StudioMerchantRefundVO> refund(StudioMerchantRefundRequest request) {
return JsonResult.rpcError(); return JsonResult.rpcError();
} }
@Override
public JsonResult<StudioEmbeddedXcxVO> getEmbeddedXcx(GetStudioEmbeddedXcxRequest request) {
return JsonResult.rpcError();
}
@Override
public JsonResult<Void> bindEmbeddedXcx(BindStudioEmbeddedXcxRequest request) {
return JsonResult.rpcError();
}
@Override
public JsonResult<Void> syncEmbeddedXcx(SyncStudioEmbeddedXcxRequest request) {
return JsonResult.rpcError();
}
}; };
} }
} }
...@@ -79,4 +79,7 @@ public class ApplyStudioMerchantRequest { ...@@ -79,4 +79,7 @@ public class ApplyStudioMerchantRequest {
@ApiModelProperty(value = "操作人ID") @ApiModelProperty(value = "操作人ID")
private Long operatorId; private Long operatorId;
@ApiModelProperty(value = "不校验验证码", notes = "true-不校验;null或者false-校验验证码")
private Boolean notCheckSmsCode;
} }
package com.jiejing.fitness.finance.api.merchant.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author chengyubing
* @since 2024/8/13 15:28
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(description = "绑定半屏小程序")
public class BindStudioEmbeddedXcxRequest {
@ApiModelProperty(value = "场馆ID", required = true)
@NotNull(message = "场馆ID不能为空")
private Long studioId;
@ApiModelProperty(value = "小程序appId", required = true)
@NotBlank(message = "小程序appId不能为空")
private String appId;
}
package com.jiejing.fitness.finance.api.merchant.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author chengyubing
* @since 2024/8/13 15:28
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(description = "获取半屏小程序")
public class GetStudioEmbeddedXcxRequest {
@ApiModelProperty(value = "场馆ID", required = true)
@NotNull(message = "场馆ID不能为空")
private Long studioId;
@ApiModelProperty(value = "小程序appId", required = true)
@NotBlank(message = "小程序appId不能为空")
private String appId;
}
package com.jiejing.fitness.finance.api.merchant.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author chengyubing
* @since 2024/8/13 15:28
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(description = "同步半屏小程序状态")
public class SyncStudioEmbeddedXcxRequest {
@ApiModelProperty(value = "场馆ID")
private Long studioId;
}
package com.jiejing.fitness.finance.api.merchant.vo;
import com.jiejing.common.swagger.EnumMapping;
import com.jiejing.fitness.enums.finance.EmbededXcxEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* <p>
* 场馆半屏小程序申请记录
* </p>
*
* @author chengyubing, created on 2024-08-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "半屏小程序VO")
public class StudioEmbeddedXcxVO {
@ApiModelProperty("ID")
private Long id;
@ApiModelProperty("品牌ID")
private Long brandId;
@ApiModelProperty("场馆ID")
private Long studioId;
@ApiModelProperty("小程序appId")
private String appId;
@ApiModelProperty("授权方appId")
private String authorizerAppId;
@EnumMapping(enumClass = EmbededXcxEnum.class)
@ApiModelProperty("状态")
private String state;
@ApiModelProperty("失败原因")
private String message;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("更新时间")
private Date updateTime;
}
...@@ -2,16 +2,20 @@ package com.jiejing.fitness.finance.app.controller; ...@@ -2,16 +2,20 @@ package com.jiejing.fitness.finance.app.controller;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.jiejing.common.model.JsonResult; import com.jiejing.common.model.JsonResult;
import com.jiejing.common.request.IdRequest;
import com.jiejing.filecenter.api.authority.AuthorityApi; import com.jiejing.filecenter.api.authority.AuthorityApi;
import com.jiejing.filecenter.api.authority.request.GetAuthorityRequest; import com.jiejing.filecenter.api.authority.request.GetAuthorityRequest;
import com.jiejing.filecenter.api.authority.vo.SignatureVO; import com.jiejing.filecenter.api.authority.vo.SignatureVO;
import com.jiejing.filecenter.api.common.enums.AccessTypeEnum; import com.jiejing.filecenter.api.common.enums.AccessTypeEnum;
import com.jiejing.filecenter.api.common.util.UploadUtil; import com.jiejing.filecenter.api.common.util.UploadUtil;
import com.jiejing.filecenter.api.resource.ResourceApi; import com.jiejing.filecenter.api.resource.ResourceApi;
import com.jiejing.fitness.finance.repository.entity.StudioMerchantApply;
import com.jiejing.fitness.finance.repository.service.StudioCashierRecordRpService; import com.jiejing.fitness.finance.repository.service.StudioCashierRecordRpService;
import com.jiejing.fitness.finance.repository.service.StudioMerchantApplyRpService;
import com.jiejing.fitness.finance.service.merchant.StudioMerchantService; import com.jiejing.fitness.finance.service.merchant.StudioMerchantService;
import com.jiejing.fitness.finance.service.utils.FileUtils; import com.jiejing.fitness.finance.service.utils.FileUtils;
import com.jiejing.paycenter.api.merchant.MerchantQueryApi; import com.jiejing.paycenter.api.merchant.MerchantQueryApi;
import com.jiejing.paycenter.common.enums.common.OpenStateEnums;
import com.jiejing.paycenter.common.event.MerchantEvent; import com.jiejing.paycenter.common.event.MerchantEvent;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
......
package com.jiejing.fitness.finance.app.controller.merchant; package com.jiejing.fitness.finance.app.controller.merchant;
import com.google.common.collect.Lists;
import com.jiejing.common.model.JsonResult; import com.jiejing.common.model.JsonResult;
import com.jiejing.common.model.PageVO; import com.jiejing.common.model.PageVO;
import com.jiejing.common.utils.convert.BeanUtil; import com.jiejing.common.utils.convert.BeanUtil;
import com.jiejing.fitness.finance.api.merchant.StudioMerchantApi; import com.jiejing.fitness.finance.api.merchant.StudioMerchantApi;
import com.jiejing.fitness.finance.api.merchant.request.ApplyStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.ApplyStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.AuthStudioSubChannelRequest; import com.jiejing.fitness.finance.api.merchant.request.AuthStudioSubChannelRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantXcxAppIdRequest; import com.jiejing.fitness.finance.api.merchant.request.BindStudioMerchantXcxAppIdRequest;
import com.jiejing.fitness.finance.api.merchant.request.CheckUnbindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.CheckUnbindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetAuthStudioSubChannelRequest; import com.jiejing.fitness.finance.api.merchant.request.GetAuthStudioSubChannelRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetOpenIdRequest; import com.jiejing.fitness.finance.api.merchant.request.GetOpenIdRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioLatestMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioLatestMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.GetStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.request.PageStudioMerchantApplyRequest; import com.jiejing.fitness.finance.api.merchant.request.PageStudioMerchantApplyRequest;
import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantPayRequest; import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantPayRequest;
import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantRefundRequest; import com.jiejing.fitness.finance.api.merchant.request.StudioMerchantRefundRequest;
import com.jiejing.fitness.finance.api.merchant.request.SyncStudioEmbeddedXcxRequest;
import com.jiejing.fitness.finance.api.merchant.request.UnbindStudioMerchantRequest; import com.jiejing.fitness.finance.api.merchant.request.UnbindStudioMerchantRequest;
import com.jiejing.fitness.finance.api.merchant.vo.StudioEmbeddedXcxVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO;
...@@ -197,4 +202,29 @@ public class StudioMerchantController implements StudioMerchantApi { ...@@ -197,4 +202,29 @@ public class StudioMerchantController implements StudioMerchantApi {
return JsonResult.success(refundService.merchantRefund(params)); return JsonResult.success(refundService.merchantRefund(params));
} }
@ApiOperation(value = "获取半屏小程序", tags = {TAG})
@PostMapping(value = "/private/studio/getEmbeddedXcx")
@Override
public JsonResult<StudioEmbeddedXcxVO> getEmbeddedXcx(
@RequestBody @Valid GetStudioEmbeddedXcxRequest request) {
return JsonResult.success(
studioMerchantService.getEmbeddedXcx(request.getStudioId(), request.getAppId()));
}
@ApiOperation(value = "绑定半屏小程序", tags = {TAG})
@PostMapping(value = "/private/studio/bindEmbeddedXcx")
@Override
public JsonResult<Void> bindEmbeddedXcx(@RequestBody @Valid BindStudioEmbeddedXcxRequest request) {
studioMerchantService.bindEmbeddedXcx(request.getStudioId(), Lists.newArrayList(request.getAppId()));
return JsonResult.success();
}
@ApiOperation(value = "同步半屏小程序状态", tags = {TAG})
@PostMapping(value = "/private/studio/syncEmbeddedXcx")
@Override
public JsonResult<Void> syncEmbeddedXcx(@RequestBody @Valid SyncStudioEmbeddedXcxRequest request) {
studioMerchantService.syncEmbeddedXcx();
return JsonResult.success();
}
} }
...@@ -22,4 +22,10 @@ finance: ...@@ -22,4 +22,10 @@ finance:
ali_app: "002" ali_app: "002"
wx_app: "003" wx_app: "003"
url: url:
transDetail: /pay/transaction-record/detail?id= transDetail: /pay/transaction-record/detail?id=
\ No newline at end of file
wx:
component:
appId: wxe6c4979bafd48126
embedded:
appId: wx06a084dcba4f0a05
\ No newline at end of file
...@@ -22,4 +22,10 @@ finance: ...@@ -22,4 +22,10 @@ finance:
ali_app: "002" ali_app: "002"
wx_app: "003" wx_app: "003"
url: url:
transDetail: /pay/transaction-record/detail?id= transDetail: /pay/transaction-record/detail?id=
\ No newline at end of file
wx:
component:
appId: wxda913f3b6f1439b4
embedded:
appId: wxf187be22c2234300
\ No newline at end of file
...@@ -27,4 +27,10 @@ finance: ...@@ -27,4 +27,10 @@ finance:
ali_app: "002" ali_app: "002"
wx_app: "003" wx_app: "003"
url: url:
transDetail: /pay/transaction-record/detail?id= transDetail: /pay/transaction-record/detail?id=
\ No newline at end of file
wx:
component:
appId: wxda913f3b6f1439b4
embedded:
appId: wxf187be22c2234300
...@@ -22,4 +22,10 @@ finance: ...@@ -22,4 +22,10 @@ finance:
ali_app: "002" ali_app: "002"
wx_app: "003" wx_app: "003"
url: url:
transDetail: /pay/transaction-record/detail?id= transDetail: /pay/transaction-record/detail?id=
\ No newline at end of file
wx:
component:
appId: wxe6c4979bafd48126
embedded:
appId: wx06a084dcba4f0a05
\ No newline at end of file
...@@ -22,4 +22,10 @@ finance: ...@@ -22,4 +22,10 @@ finance:
ali_app: "002" ali_app: "002"
wx_app: "003" wx_app: "003"
url: url:
transDetail: /pay/transaction-record/detail?id= transDetail: /pay/transaction-record/detail?id=
\ No newline at end of file
wx:
component:
appId: wxfe4c26daa7e85d14
embedded:
appId: wxf187be22c2234300
\ No newline at end of file
/*
* Copyright © 2024 Hangzhou Jiejing Technology Co., Ltd. All rights reserved.
*
* The copyright of the company's program code belongs to Hangzhou Jiejing Technology Co., Ltd. No one can illegally copy it without the explicit permission of this website.
* Official website: www.xiaomai5.com
*
*
*
* Copyright © 2024 杭州杰竞科技有限公司 版权所有.
*
* 本公司程序代码的版权归杭州杰竞科技有限公司所有,未经本网站的明确许可,任何人不得非法复制。
* 官网: www.xiaomai5.com
*/
package com.jiejing.fitness.finance.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* <p>
* 场馆半屏小程序申请记录
* </p>
*
* @author chengyubing, created on 2024-08-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class StudioEmbeddedXcxApply implements Serializable {
private static final long serialVersionUID = -4415580599984265484L;
/**
* 备注: 主键 是否允许为null: NO
*/
@TableId(value = "id", type = IdType.ID_WORKER)
private Long id;
/**
* 备注: 场馆ID 是否允许为null: YES
*/
private Long studioId;
/**
* 备注: 第三方平台appId 是否允许为null: YES
*/
private String componentAppId;
/**
* 备注: 授权方appId(申请小程序appId) 是否允许为null: YES
*/
private String authorizerAppId;
/**
* 备注: 半屏小程序appId 是否允许为null: YES
*/
private String embeddedAppId;
/**
* 备注: 状态 是否允许为null: YES
*/
private String state;
/**
* 备注: 失败原因 是否允许为null: YES
*/
private String message;
/**
* 备注: 创建时间 是否允许为null: YES
*/
private Date createTime;
/**
* 备注: 更新时间 是否允许为null: YES
*/
private Date updateTime;
public static final String ID = "id";
public static final String STUDIO_ID = "studio_id";
public static final String COMPONENT_APP_ID = "component_app_id";
public static final String AUTHORIZER_APP_ID = "authorizer_app_id";
public static final String EMBEDDED_APP_ID = "embedded_app_id";
public static final String STATE = "state";
public static final String MESSAGE = "message";
public static final String CREATE_TIME = "create_time";
public static final String UPDATE_TIME = "update_time";
}
/*
* Copyright © 2024 Hangzhou Jiejing Technology Co., Ltd. All rights reserved.
*
* The copyright of the company's program code belongs to Hangzhou Jiejing Technology Co., Ltd. No one can illegally copy it without the explicit permission of this website.
* Official website: www.xiaomai5.com
*
*
*
* Copyright © 2024 杭州杰竞科技有限公司 版权所有.
*
* 本公司程序代码的版权归杭州杰竞科技有限公司所有,未经本网站的明确许可,任何人不得非法复制。
* 官网: www.xiaomai5.com
*/
package com.jiejing.fitness.finance.repository.mapper;
import com.jiejing.fitness.finance.repository.entity.StudioEmbeddedXcxApply;
import com.jiejing.mbp.inject.XBaseMapper;
/**
* <p>
* 场馆半屏小程序申请记录 Mapper 接口
* </p>
*
* @author chengyubing, created on 2024-08-13
*/
public interface StudioEmbeddedXcxApplyMapper extends XBaseMapper<StudioEmbeddedXcxApply> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright © 2024 Hangzhou Jiejing Technology Co., Ltd. All rights reserved.
~
~ The copyright of the company's program code belongs to Hangzhou Jiejing Technology Co., Ltd. No one can illegally copy it without the explicit permission of this website.
~ Official website: www.xiaomai5.com
~
~
~
~ Copyright © 2024 杭州杰竞科技有限公司 版权所有.
~
~ 本公司程序代码的版权归杭州杰竞科技有限公司所有,未经本网站的明确许可,任何人不得非法复制。
~ 官网: www.xiaomai5.com
-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jiejing.fitness.finance.repository.mapper.StudioEmbeddedXcxApplyMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, studio_id, component_app_id, embedded_app_id, authorizer_app_id, state, message, create_time, update_time
</sql>
</mapper>
/*
* Copyright © 2024 Hangzhou Jiejing Technology Co., Ltd. All rights reserved.
*
* The copyright of the company's program code belongs to Hangzhou Jiejing Technology Co., Ltd. No one can illegally copy it without the explicit permission of this website.
* Official website: www.xiaomai5.com
*
*
*
* Copyright © 2024 杭州杰竞科技有限公司 版权所有.
*
* 本公司程序代码的版权归杭州杰竞科技有限公司所有,未经本网站的明确许可,任何人不得非法复制。
* 官网: www.xiaomai5.com
*/
package com.jiejing.fitness.finance.repository.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jiejing.fitness.finance.repository.entity.StudioEmbeddedXcxApply;
import com.jiejing.fitness.finance.repository.mapper.StudioEmbeddedXcxApplyMapper;
import com.jiejing.mbp.MapperRepoService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
/**
* <p>
* 场馆半屏小程序申请记录 服务实现类
* </p>
*
* @author chengyubing, created on 2024-08-13
*/
@Service
public class StudioEmbeddedXcxApplyRpService extends
MapperRepoService<Long, StudioEmbeddedXcxApply, StudioEmbeddedXcxApplyMapper> {
public Map<String, StudioEmbeddedXcxApply> mapByStudioIdAndAppId(Long studioId,
String componentAppId, String embeddedAppId, List<String> appIds) {
return this.listByStudioIdAndAppId(studioId, componentAppId, embeddedAppId, appIds)
.stream().collect(Collectors.toMap(StudioEmbeddedXcxApply::getAuthorizerAppId, e -> e));
}
public List<StudioEmbeddedXcxApply> listByStudioIdAndAppId(Long studioId, String componentAppId,
String embeddedAppId, List<String> appIds) {
QueryWrapper<StudioEmbeddedXcxApply> wrapper = new QueryWrapper<>();
wrapper.eq(StudioEmbeddedXcxApply.STUDIO_ID, studioId);
wrapper.eq(StudioEmbeddedXcxApply.COMPONENT_APP_ID, componentAppId);
wrapper.eq(StudioEmbeddedXcxApply.EMBEDDED_APP_ID, embeddedAppId);
wrapper.in(StudioEmbeddedXcxApply.AUTHORIZER_APP_ID, appIds);
return Optional.ofNullable(this.baseMapper.selectList(wrapper)).orElse(new ArrayList<>(1));
}
public StudioEmbeddedXcxApply getByStudioIdAndAppId(Long studioId, String componentAppId,
String embeddedAppId, String appId) {
QueryWrapper<StudioEmbeddedXcxApply> wrapper = new QueryWrapper<>();
wrapper.eq(StudioEmbeddedXcxApply.STUDIO_ID, studioId);
wrapper.eq(StudioEmbeddedXcxApply.COMPONENT_APP_ID, componentAppId);
wrapper.eq(StudioEmbeddedXcxApply.EMBEDDED_APP_ID, embeddedAppId);
wrapper.eq(StudioEmbeddedXcxApply.AUTHORIZER_APP_ID, appId);
return Optional.ofNullable(this.baseMapper.selectList(wrapper))
.orElse(new ArrayList<>(1))
.stream().findFirst().orElse(null);
}
public List<StudioEmbeddedXcxApply> listByAppIds(String componentAppId, String embeddedAppId,
List<String> appIds) {
QueryWrapper<StudioEmbeddedXcxApply> wrapper = new QueryWrapper<>();
wrapper.eq(StudioEmbeddedXcxApply.COMPONENT_APP_ID, componentAppId);
wrapper.eq(StudioEmbeddedXcxApply.EMBEDDED_APP_ID, embeddedAppId);
wrapper.in(StudioEmbeddedXcxApply.AUTHORIZER_APP_ID, appIds);
return Optional.ofNullable(this.baseMapper.selectList(wrapper)).orElse(new ArrayList<>(1));
}
}
...@@ -59,7 +59,8 @@ public class GeneratorServiceEntity { ...@@ -59,7 +59,8 @@ public class GeneratorServiceEntity {
// "branch_bank", // "branch_bank",
// "studio_settle_record", // "studio_settle_record",
// "studio_check_settle_record", // "studio_check_settle_record",
"merchant_settle_record" // "merchant_settle_record"
"studio_embedded_xcx_apply"
}; };
/** /**
......
...@@ -7,6 +7,7 @@ import com.jiejing.common.exception.BizException; ...@@ -7,6 +7,7 @@ import com.jiejing.common.exception.BizException;
import com.jiejing.common.model.PageVO; import com.jiejing.common.model.PageVO;
import com.jiejing.common.utils.collection.CollectionUtil; import com.jiejing.common.utils.collection.CollectionUtil;
import com.jiejing.common.utils.convert.BeanUtil; import com.jiejing.common.utils.convert.BeanUtil;
import com.jiejing.common.utils.http.HttpAgent;
import com.jiejing.common.utils.text.StringUtil; import com.jiejing.common.utils.text.StringUtil;
import com.jiejing.fitness.enums.finance.BrandCashierTransTypeEnum; import com.jiejing.fitness.enums.finance.BrandCashierTransTypeEnum;
import com.jiejing.fitness.finance.api.cashier.vo.StudioCashierRecordVO; import com.jiejing.fitness.finance.api.cashier.vo.StudioCashierRecordVO;
...@@ -181,4 +182,12 @@ public class StudioCashierServiceImpl implements StudioCashierService { ...@@ -181,4 +182,12 @@ public class StudioCashierServiceImpl implements StudioCashierService {
return CashierConvert.convertList(records); return CashierConvert.convertList(records);
} }
public static void main(String[] args) {
String token = "83_5IJi4qSVAhY4leEebVWVzDuNZT5RAbwl9cEWi_iw6N5DWqWZ0jS2A1FvOn7lrxJaFqzwqXRAnowcDkoQW8vRmEr6H9lKUe-4khE8GCgXML7MSqxWmm8ZwDBWIPFEriqiAYYTfpybdKrK0FXxGSGgAEDWIW";
String url = "https://api.weixin.qq.com/wxaapi/wxaembedded/add_embedded?access_token=%s";
JSONObject json = HttpAgent.postAsJson(String.format(url, token),
new JSONObject().fluentPut("appid", "wx2e1e65f65f6e257d")).asJSONObject();
System.out.println(json);
}
} }
...@@ -8,6 +8,7 @@ import com.jiejing.fitness.finance.service.merchant.StudioMerchantService; ...@@ -8,6 +8,7 @@ import com.jiejing.fitness.finance.service.merchant.StudioMerchantService;
import com.jiejing.fitness.finance.service.pay.PayService; import com.jiejing.fitness.finance.service.pay.PayService;
import com.jiejing.fitness.finance.service.pay.RefundService; import com.jiejing.fitness.finance.service.pay.RefundService;
import com.jiejing.paycenter.common.event.MerchantEvent; import com.jiejing.paycenter.common.event.MerchantEvent;
import com.jiejing.paycenter.common.event.MerchantSubChannelEvent;
import com.jiejing.paycenter.common.event.PayEvent; import com.jiejing.paycenter.common.event.PayEvent;
import com.jiejing.paycenter.common.event.RefundEvent; import com.jiejing.paycenter.common.event.RefundEvent;
import com.xiaomai.event.annotation.EventHandler; import com.xiaomai.event.annotation.EventHandler;
...@@ -78,4 +79,15 @@ public class ListenerService { ...@@ -78,4 +79,15 @@ public class ListenerService {
} }
} }
@EventHandler(value = MerchantSubChannelEvent.class, binder = "biz-kafka", maxAttempts = MAX_RETRY)
public void merchantSubChannelEventCallback(MerchantSubChannelEvent event,
@Header(DELIVERY_ATTEMPT) int retryNum) {
try {
log.info("start process merchantSubChannelEventCallback event {}", JSON.toJSONString(event));
studioMerchantService.merchantSubChannelEventCallback(event);
} catch (Exception e) {
log.info("process merchantSubChannelEventCallback event fail {}", event.getId(), e);
}
}
} }
package com.jiejing.fitness.finance.service.merchant; package com.jiejing.fitness.finance.service.merchant;
import com.jiejing.common.model.PageVO; import com.jiejing.common.model.PageVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioEmbeddedXcxVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO;
...@@ -11,6 +12,7 @@ import com.jiejing.fitness.finance.service.merchant.params.PageStudioMerchantApp ...@@ -11,6 +12,7 @@ import com.jiejing.fitness.finance.service.merchant.params.PageStudioMerchantApp
import com.jiejing.paycenter.common.enums.merchant.SubChannelAuthTypeEnums; import com.jiejing.paycenter.common.enums.merchant.SubChannelAuthTypeEnums;
import com.jiejing.paycenter.common.enums.merchant.SubChannelEnums; import com.jiejing.paycenter.common.enums.merchant.SubChannelEnums;
import com.jiejing.paycenter.common.event.MerchantEvent; import com.jiejing.paycenter.common.event.MerchantEvent;
import com.jiejing.paycenter.common.event.MerchantSubChannelEvent;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
...@@ -66,6 +68,13 @@ public interface StudioMerchantService { ...@@ -66,6 +68,13 @@ public interface StudioMerchantService {
void callback(MerchantEvent event); void callback(MerchantEvent event);
/** /**
* 商户子渠道事件处理
*
* @param event 事件
*/
void merchantSubChannelEventCallback(MerchantSubChannelEvent event);
/**
* 获取场馆当前绑定的商户信息 * 获取场馆当前绑定的商户信息
* *
* @param studioId 场馆ID * @param studioId 场馆ID
...@@ -160,4 +169,26 @@ public interface StudioMerchantService { ...@@ -160,4 +169,26 @@ public interface StudioMerchantService {
*/ */
StudioMerchantApplyVO getLatestSuccessApply(Long studioId); StudioMerchantApplyVO getLatestSuccessApply(Long studioId);
/**
* 获取半屏小程序绑定信息
*
* @param studioId 场馆ID
* @param appId 小程序appId
* @return 结果
*/
StudioEmbeddedXcxVO getEmbeddedXcx(Long studioId, String appId);
/**
* 绑定半屏小程序
*
* @param studioId 场馆ID
* @param appIds 小程序appId
*/
void bindEmbeddedXcx(Long studioId, List<String> appIds);
/**
* 同步半屏小程序状态
*/
void syncEmbeddedXcx();
} }
...@@ -14,9 +14,11 @@ import com.jiejing.fitness.finance.api.merchant.vo.BrandBankCardVO; ...@@ -14,9 +14,11 @@ import com.jiejing.fitness.finance.api.merchant.vo.BrandBankCardVO;
import com.jiejing.fitness.finance.api.merchant.vo.BrandLegalVO; import com.jiejing.fitness.finance.api.merchant.vo.BrandLegalVO;
import com.jiejing.fitness.finance.api.merchant.vo.BrandLicenseVO; import com.jiejing.fitness.finance.api.merchant.vo.BrandLicenseVO;
import com.jiejing.fitness.finance.api.merchant.vo.BrandMerchantVO; import com.jiejing.fitness.finance.api.merchant.vo.BrandMerchantVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioEmbeddedXcxVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantVO;
import com.jiejing.fitness.finance.repository.entity.PartyToMerchant; import com.jiejing.fitness.finance.repository.entity.PartyToMerchant;
import com.jiejing.fitness.finance.repository.entity.StudioEmbeddedXcxApply;
import com.jiejing.fitness.finance.repository.entity.StudioMerchantApply; import com.jiejing.fitness.finance.repository.entity.StudioMerchantApply;
import com.jiejing.fitness.finance.service.global.dto.SubChannelInfoDTO; import com.jiejing.fitness.finance.service.global.dto.SubChannelInfoDTO;
import com.jiejing.fitness.finance.service.merchant.params.ApplyStudioMerchantParams; import com.jiejing.fitness.finance.service.merchant.params.ApplyStudioMerchantParams;
......
package com.jiejing.fitness.finance.service.merchant.convert;
import com.jiejing.common.config.idgen.adapter.IdWorker;
import com.jiejing.fitness.enums.finance.EmbededXcxEnum;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO;
import com.jiejing.fitness.finance.repository.entity.StudioEmbeddedXcxApply;
import com.jiejing.wechat.vo.xcx.HalfScreenXcxAuthVO.AuthXcxInfo;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author chengyubing
* @since 2024/8/13 15:02
*/
public class StudioEmbeddedXcxConvert {
public static StudioEmbeddedXcxApply toEntity(Long studioId, String componentAppId, String embeddedAppId,
String appId) {
StudioEmbeddedXcxApply record = new StudioEmbeddedXcxApply();
record.setId(IdWorker.getId());
record.setComponentAppId(componentAppId);
record.setAuthorizerAppId(appId);
record.setEmbeddedAppId(embeddedAppId);
record.setStudioId(studioId);
record.setState(EmbededXcxEnum.INIT.getCode());
record.setCreateTime(new Date());
record.setUpdateTime(new Date());
return record;
}
public static StudioEmbeddedXcxApply toRefuse(Long id, String fail) {
return StudioEmbeddedXcxApply.builder()
.id(id)
.state(EmbededXcxEnum.REFUSE.getCode())
.message(fail)
.updateTime(new Date())
.build();
}
public static StudioEmbeddedXcxApply toSuccess(Long id) {
return StudioEmbeddedXcxApply.builder()
.id(id)
.state(EmbededXcxEnum.SUCCESS.getCode())
.updateTime(new Date())
.build();
}
public static List<Long> filterAppIds(List<StudioEmbeddedXcxApply> applies, List<String> appIds) {
return applies.stream()
.filter(e -> !EmbededXcxEnum.SUCCESS.getCode().equals(e.getState()))
.filter(e -> appIds.contains(e.getAuthorizerAppId()))
.map(StudioEmbeddedXcxApply::getId)
.collect(Collectors.toList());
}
public static List<StudioEmbeddedXcxApply> toFailList(EmbededXcxEnum status,
List<StudioEmbeddedXcxApply> applies, List<AuthXcxInfo> authXcxInfos) {
Map<String, AuthXcxInfo> map = authXcxInfos.stream()
.collect(Collectors.toMap(AuthXcxInfo::getAppId, e -> e));
return applies.stream()
.filter(e -> null != map.get(e.getAuthorizerAppId()))
.filter(e -> {
AuthXcxInfo info = map.get(e.getAuthorizerAppId());
return EmbededXcxEnum.valueOf(e.getState()) != EmbededXcxEnum.getByWxCode(
Integer.parseInt(info.getStatus()));
})
.map(e -> StudioEmbeddedXcxApply.builder()
.id(e.getId())
.state(status.getCode())
.updateTime(new Date())
.build())
.collect(Collectors.toList());
}
public static StudioEmbeddedXcxApply toInit(StudioEmbeddedXcxApply entity) {
StudioEmbeddedXcxApply toInit = new StudioEmbeddedXcxApply();
toInit.setId(entity.getId());
toInit.setState(EmbededXcxEnum.INIT.getCode());
toInit.setCreateTime(new Date());
toInit.setUpdateTime(new Date());
return toInit;
}
}
package com.jiejing.fitness.finance.service.merchant.impl; package com.jiejing.fitness.finance.service.merchant.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.jiejing.common.exception.BizException; import com.jiejing.common.exception.BizException;
import com.jiejing.common.model.PageVO; import com.jiejing.common.model.PageVO;
import com.jiejing.common.utils.collection.CollectionUtil; import com.jiejing.common.utils.collection.CollectionUtil;
import com.jiejing.common.utils.convert.BeanUtil; import com.jiejing.common.utils.convert.BeanUtil;
import com.jiejing.common.utils.text.StringUtil;
import com.jiejing.common.utils.time.TimeUtil;
import com.jiejing.filecenter.api.resource.vo.ResourceInfoVO; import com.jiejing.filecenter.api.resource.vo.ResourceInfoVO;
import com.jiejing.fitness.enums.finance.EmbededXcxEnum;
import com.jiejing.fitness.enums.finance.PartyTypeEnum; import com.jiejing.fitness.enums.finance.PartyTypeEnum;
import com.jiejing.fitness.finance.api.merchant.request.model.BrandResourceInfo; import com.jiejing.fitness.finance.api.merchant.request.model.BrandResourceInfo;
import com.jiejing.fitness.finance.api.merchant.vo.StudioEmbeddedXcxVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantApplyVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantAuthSubChannelVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantVO; import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantVO;
import com.jiejing.fitness.finance.repository.entity.PartyToMerchant; import com.jiejing.fitness.finance.repository.entity.PartyToMerchant;
import com.jiejing.fitness.finance.repository.entity.StudioEmbeddedXcxApply;
import com.jiejing.fitness.finance.repository.entity.StudioMerchantApply; import com.jiejing.fitness.finance.repository.entity.StudioMerchantApply;
import com.jiejing.fitness.finance.repository.query.PageStudioMerchantApplyQuery; import com.jiejing.fitness.finance.repository.query.PageStudioMerchantApplyQuery;
import com.jiejing.fitness.finance.repository.service.PartyToMerchantRpService; import com.jiejing.fitness.finance.repository.service.PartyToMerchantRpService;
import com.jiejing.fitness.finance.repository.service.StudioEmbeddedXcxApplyRpService;
import com.jiejing.fitness.finance.repository.service.StudioMerchantApplyRpService; import com.jiejing.fitness.finance.repository.service.StudioMerchantApplyRpService;
import com.jiejing.fitness.finance.service.config.PayChannelProperties; import com.jiejing.fitness.finance.service.config.PayChannelProperties;
import com.jiejing.fitness.finance.service.enums.FinanceErrorEnums; import com.jiejing.fitness.finance.service.enums.FinanceErrorEnums;
...@@ -26,6 +33,7 @@ import com.jiejing.fitness.finance.service.global.dto.SubChannelInfoDTO; ...@@ -26,6 +33,7 @@ import com.jiejing.fitness.finance.service.global.dto.SubChannelInfoDTO;
import com.jiejing.fitness.finance.service.merchant.BrandMerchantService; import com.jiejing.fitness.finance.service.merchant.BrandMerchantService;
import com.jiejing.fitness.finance.service.merchant.StudioMerchantService; import com.jiejing.fitness.finance.service.merchant.StudioMerchantService;
import com.jiejing.fitness.finance.service.merchant.convert.MerchantConvert; import com.jiejing.fitness.finance.service.merchant.convert.MerchantConvert;
import com.jiejing.fitness.finance.service.merchant.convert.StudioEmbeddedXcxConvert;
import com.jiejing.fitness.finance.service.merchant.params.ApplyStudioMerchantParams; import com.jiejing.fitness.finance.service.merchant.params.ApplyStudioMerchantParams;
import com.jiejing.fitness.finance.service.merchant.params.PageStudioMerchantApplyParams; import com.jiejing.fitness.finance.service.merchant.params.PageStudioMerchantApplyParams;
import com.jiejing.fitness.finance.service.rpc.MerchantRpcService; import com.jiejing.fitness.finance.service.rpc.MerchantRpcService;
...@@ -36,6 +44,7 @@ import com.jiejing.message.enums.MsgChannelEnum; ...@@ -36,6 +44,7 @@ import com.jiejing.message.enums.MsgChannelEnum;
import com.jiejing.message.event.SendCommonMsgEvent; import com.jiejing.message.event.SendCommonMsgEvent;
import com.jiejing.paycenter.api.merchant.request.ApplyMerchantRequest; import com.jiejing.paycenter.api.merchant.request.ApplyMerchantRequest;
import com.jiejing.paycenter.common.enums.merchant.SubChannelOpenTypeEnums; import com.jiejing.paycenter.common.enums.merchant.SubChannelOpenTypeEnums;
import com.jiejing.paycenter.common.event.MerchantSubChannelEvent;
import com.jiejing.paycenter.common.model.request.SubChannelConfigInfo; import com.jiejing.paycenter.common.model.request.SubChannelConfigInfo;
import com.jiejing.paycenter.common.model.vo.AuthSubChannelVO; import com.jiejing.paycenter.common.model.vo.AuthSubChannelVO;
import com.jiejing.paycenter.common.model.vo.ConfigSubChannelVO; import com.jiejing.paycenter.common.model.vo.ConfigSubChannelVO;
...@@ -48,10 +57,16 @@ import com.jiejing.paycenter.common.enums.merchant.SubChannelConfigTypeEnums; ...@@ -48,10 +57,16 @@ import com.jiejing.paycenter.common.enums.merchant.SubChannelConfigTypeEnums;
import com.jiejing.paycenter.common.enums.merchant.SubChannelEnums; import com.jiejing.paycenter.common.enums.merchant.SubChannelEnums;
import com.jiejing.paycenter.common.event.MerchantEvent; import com.jiejing.paycenter.common.event.MerchantEvent;
import com.jiejing.paycenter.common.model.request.ResourceInfo; import com.jiejing.paycenter.common.model.request.ResourceInfo;
import com.jiejing.paycenter.common.model.vo.SubChannelConfigVO;
import com.jiejing.paycenter.common.model.vo.SubChannelVO; import com.jiejing.paycenter.common.model.vo.SubChannelVO;
import com.jiejing.studio.api.studio.vo.StudioVO; import com.jiejing.studio.api.studio.vo.StudioVO;
import com.jiejing.wechat.WeXcxService;
import com.jiejing.wechat.vo.xcx.HalfScreenXcxAuthVO;
import com.jiejing.wechat.vo.xcx.HalfScreenXcxAuthVO.AuthXcxInfo;
import com.xiaomai.event.EventAgent; import com.xiaomai.event.EventAgent;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -62,7 +77,9 @@ import java.util.concurrent.Executor; ...@@ -62,7 +77,9 @@ import java.util.concurrent.Executor;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Resource; import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -102,9 +119,33 @@ public class StudioMerchantServiceImpl implements StudioMerchantService { ...@@ -102,9 +119,33 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
@Resource @Resource
private MessageRpcService messageRpcService; private MessageRpcService messageRpcService;
@Resource
private StudioEmbeddedXcxApplyRpService studioEmbeddedXcxApplyRpService;
@Resource
private WeXcxService weXcxService;
@Resource(name = "financeThreadPool") @Resource(name = "financeThreadPool")
private Executor executor; private Executor executor;
/**
* 第三方平台appId
*/
@Value("${wx.component.appId}")
private String wxComponentAppId;
/**
* 半屏小程序
*/
@Value("${wx.embedded.appId}")
private String embeddedAppId;
private static final Integer WX_SUCCESS_CODE = 0;
private final static List<String> SPECIAL_FAIL_LIST = Lists.newArrayList(
"该商户号类型暂不支持与该AppID关联"
);
@Override @Override
public Long apply(ApplyStudioMerchantParams params) { public Long apply(ApplyStudioMerchantParams params) {
...@@ -193,6 +234,23 @@ public class StudioMerchantServiceImpl implements StudioMerchantService { ...@@ -193,6 +234,23 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
} }
@Override @Override
public void merchantSubChannelEventCallback(MerchantSubChannelEvent event) {
// 如果是特定的失败,则绑定半屏支付小程序
if (!OpenStateEnums.FAIL.getCode().equals(event.getState())) {
return;
}
if (!SubChannelConfigTypeEnums.WX_XCX_OFFLINE.getCode().equals(event.getConfigType())) {
return;
}
if (!SPECIAL_FAIL_LIST.contains(event.getFailMessage())) {
return;
}
StudioMerchantApply apply = studioMerchantApplyRpService.getLatestOneSuccessByMerchantId(
event.getMerchantId());
this.bindEmbeddedXcx(apply.getStudioId(), Lists.newArrayList(event.getAppId()));
}
@Override
public StudioMerchantVO getMerchant(Long studioId) { public StudioMerchantVO getMerchant(Long studioId) {
PartyToMerchant relation = getRelation(studioId); PartyToMerchant relation = getRelation(studioId);
if (null == relation) { if (null == relation) {
...@@ -208,6 +266,119 @@ public class StudioMerchantServiceImpl implements StudioMerchantService { ...@@ -208,6 +266,119 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
} }
@Override @Override
public StudioEmbeddedXcxVO getEmbeddedXcx(Long studioId, String appId) {
StudioEmbeddedXcxApply embeddedXcx = studioEmbeddedXcxApplyRpService.getByStudioIdAndAppId(
studioId, wxComponentAppId, embeddedAppId, appId);
if (null == embeddedXcx) {
return null;
}
return BeanUtil.map(embeddedXcx, StudioEmbeddedXcxVO.class);
}
@Async("financeThreadPool")
@Override
public void bindEmbeddedXcx(Long studioId, List<String> appIds) {
if (CollectionUtil.isEmpty(appIds)) {
return;
}
Map<String, StudioEmbeddedXcxApply> existMap = studioEmbeddedXcxApplyRpService.mapByStudioIdAndAppId(
studioId, wxComponentAppId, embeddedAppId, appIds);
appIds.stream()
.filter(appId -> null == existMap.get(appId) || EmbededXcxEnum.isFail(existMap.get(appId).getState()))
.forEach(appId -> {
log.info("bind embedded xcx {}, {}", studioId, appId);
StudioEmbeddedXcxApply entity = existMap.get(appId);
if (null == entity) {
entity = StudioEmbeddedXcxConvert.toEntity(studioId, wxComponentAppId, embeddedAppId, appId);
studioEmbeddedXcxApplyRpService.insert(entity);
} else {
studioEmbeddedXcxApplyRpService.updateById(StudioEmbeddedXcxConvert.toInit(entity));
}
try {
JSONObject result = weXcxService.addEmbeddedXcx(wxComponentAppId, appId, embeddedAppId,
"申请半屏小程序");
Integer code = result.getInteger("errcode");
String message = result.getString("errmsg");
if (!WX_SUCCESS_CODE.equals(code)) {
studioEmbeddedXcxApplyRpService.updateById(
StudioEmbeddedXcxConvert.toRefuse(entity.getId(), message));
}
} catch (Exception e) {
log.error("bind embedded xcx fail {}, {}", studioId, appId, e);
String fail =
e instanceof BizException ? ((BizException) e).getDefaultErrorMessage() : "网络异常";
studioEmbeddedXcxApplyRpService.updateById(
StudioEmbeddedXcxConvert.toRefuse(entity.getId(), fail));
}
});
}
@Override
public void syncEmbeddedXcx() {
List<AuthXcxInfo> list = this.listBoundAppIds();
if (CollectionUtil.isEmpty(list)) {
return;
}
List<StudioEmbeddedXcxApply> applies = studioEmbeddedXcxApplyRpService.listByAppIds(wxComponentAppId,
embeddedAppId, list.stream().map(AuthXcxInfo::getAppId).collect(Collectors.toList()));
if (CollectionUtil.isEmpty(applies)) {
return;
}
Map<EmbededXcxEnum, List<AuthXcxInfo>> map = list.stream()
.collect(Collectors.groupingBy(e -> EmbededXcxEnum.getByWxCode(Integer.parseInt(e.getStatus()))));
map.keySet().forEach(status -> {
List<AuthXcxInfo> authXcxInfos = map.getOrDefault(status, Lists.newArrayList());
if (CollectionUtil.isEmpty(authXcxInfos)) {
return;
}
List<String> appIds = authXcxInfos.stream().map(AuthXcxInfo::getAppId)
.collect(Collectors.toList());
switch (status) {
case SUCCESS:
List<Long> toSuccessList = StudioEmbeddedXcxConvert.filterAppIds(applies, appIds);
if (CollectionUtil.isEmpty(toSuccessList)) {
break;
}
studioEmbeddedXcxApplyRpService.updateByIds(StudioEmbeddedXcxConvert.toSuccess(null),
toSuccessList);
break;
case CANCEL:
case REFUSE:
case TIMEOUT:
case REVOKE:
List<StudioEmbeddedXcxApply> toFailList = StudioEmbeddedXcxConvert.toFailList(status, applies,
authXcxInfos);
if (CollectionUtil.isEmpty(toFailList)) {
break;
}
studioEmbeddedXcxApplyRpService.updateBatchById(toFailList);
default:
break;
}
});
}
private List<AuthXcxInfo> listBoundAppIds() {
List<AuthXcxInfo> result = new ArrayList<>();
int num = 100;
for (int start = 0; start < 10; start++) {
HalfScreenXcxAuthVO vo = weXcxService.listEmbeddedXcx(wxComponentAppId, embeddedAppId, start, num);
if (CollectionUtil.isEmpty(vo.getWxaEmbeddedList())) {
break;
}
result.addAll(vo.getWxaEmbeddedList());
}
return result;
}
@Override
public StudioMerchantApplyVO getApply(Long id) { public StudioMerchantApplyVO getApply(Long id) {
StudioMerchantApply apply = studioMerchantApplyRpService.getById(id) StudioMerchantApply apply = studioMerchantApplyRpService.getById(id)
.orElseThrow(() -> new BizException(FinanceErrorEnums.NOT_EXIST)); .orElseThrow(() -> new BizException(FinanceErrorEnums.NOT_EXIST));
...@@ -402,29 +573,62 @@ public class StudioMerchantServiceImpl implements StudioMerchantService { ...@@ -402,29 +573,62 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
private void doAfterMerchantSuccess(MerchantEvent event, Long oldMerchantId) { private void doAfterMerchantSuccess(MerchantEvent event, Long oldMerchantId) {
// 1. 配置场馆小程序appId StudioMerchantApplyVO apply = this.getApply(Long.parseLong(event.getApplyNo()));
this.rebindMiniAppId(oldMerchantId, event.getMerchantId());
// 1. 绑定旧appId
this.bindAppIds(event, apply, oldMerchantId);
// 2. 短信 // 2. 短信
StudioMerchantApplyVO apply = this.getApply(Long.parseLong(event.getApplyNo()));
this.sendOpenSuccessMessage(apply); this.sendOpenSuccessMessage(apply);
} }
private void rebindMiniAppId(Long oldMerchantId, Long newMerchantId) { private void bindAppIds(MerchantEvent event, StudioMerchantApplyVO apply, Long oldMerchantId) {
if (null == oldMerchantId) { MerchantVO oldMerchant = merchantRpcService.getByMerchantId(oldMerchantId);
if (null == oldMerchant) {
return; return;
} }
List<String> systemXcxAppIds = configService.getDefaultBrandSubChannelInfo().getSubChannelConfigs()
.stream().filter(e -> SubChannelConfigTypeEnums.WX_XCX_OFFLINE == e.getConfigType())
.map(SubChannelConfigInfo::getAppId).collect(Collectors.toList());
MerchantVO merchant = merchantRpcService.getByMerchantId(oldMerchantId); // 场馆的非系统小程序AppId
merchant.getSubChannelConfigs().stream() List<SubChannelConfigVO> offlineXcxAppIds = this.getOwnOfflineXcxAppIds(oldMerchant);
if (CollectionUtil.isEmpty(offlineXcxAppIds)) {
return;
}
// 1. 将场馆旧商户已绑定的非系统小程序appId到新商户
this.rebindMiniAppId(oldMerchant, event.getMerchantId(), offlineXcxAppIds);
// 2. 将场馆旧商户已绑定的非系统小程序appId绑定系统半屏小程序
this.bindEmbeddedXcx(offlineXcxAppIds, apply.getStudioId());
}
private void bindEmbeddedXcx(List<SubChannelConfigVO> offlineXcxAppIds, Long studioId) {
// 当小程序为特定失败原因,则需要绑定半屏小程序
List<String> appIds = offlineXcxAppIds.stream()
.filter(e -> OpenStateEnums.FAIL.getCode().equals(e.getState()))
.filter(e -> SPECIAL_FAIL_LIST.contains(e.getFailMessage()))
.map(SubChannelConfigVO::getAppId).collect(Collectors.toList());
this.bindEmbeddedXcx(studioId, appIds);
}
private List<SubChannelConfigVO> getOwnOfflineXcxAppIds(MerchantVO oldMerchant) {
List<String> systemXcxAppIds = this.listSystemXcxAppIds();
return oldMerchant.getSubChannelConfigs().stream()
.filter(e -> SubChannelConfigTypeEnums.WX_XCX_OFFLINE.name().equals(e.getConfigType())) .filter(e -> SubChannelConfigTypeEnums.WX_XCX_OFFLINE.name().equals(e.getConfigType()))
.filter(e -> !systemXcxAppIds.contains(e.getAppId())) .filter(e -> !systemXcxAppIds.contains(e.getAppId()))
.forEach( .collect(Collectors.toList());
config -> merchantRpcService.bindAppIdWxXcxOffline(merchant.getChannelNo(), newMerchantId, }
config.getAppId()));
private List<String> listSystemXcxAppIds() {
return configService.getDefaultBrandSubChannelInfo().getSubChannelConfigs()
.stream().filter(e -> SubChannelConfigTypeEnums.WX_XCX_OFFLINE == e.getConfigType())
.map(SubChannelConfigInfo::getAppId).collect(Collectors.toList());
}
private void rebindMiniAppId(MerchantVO oldMerchant, Long newMerchantId,
List<SubChannelConfigVO> offlineXcxAppIds) {
offlineXcxAppIds.forEach(
config -> merchantRpcService.bindAppIdWxXcxOffline(oldMerchant.getChannelNo(), newMerchantId,
config.getAppId()));
} }
private Map<ResourceTypeEnums, ResourceInfo> upload(ApplyStudioMerchantParams params, private Map<ResourceTypeEnums, ResourceInfo> upload(ApplyStudioMerchantParams params,
...@@ -533,7 +737,10 @@ public class StudioMerchantServiceImpl implements StudioMerchantService { ...@@ -533,7 +737,10 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
private void checkBeforeApply(ApplyStudioMerchantParams params) { private void checkBeforeApply(ApplyStudioMerchantParams params) {
// 校验验证码 // 校验验证码
this.validSmsCode(params.getBankCard().getPhone(), params.getSmsCode()); if (null == params.getNotCheckSmsCode() || !params.getNotCheckSmsCode()) {
this.validSmsCode(params.getBankCard().getPhone(), params.getSmsCode());
}
// 重复提交 // 重复提交
Integer count = studioMerchantApplyRpService.countProcessByStudioId(params.getStudioId()); Integer count = studioMerchantApplyRpService.countProcessByStudioId(params.getStudioId());
if (count.compareTo(0) > 0) { if (count.compareTo(0) > 0) {
......
...@@ -78,6 +78,9 @@ public class ApplyStudioMerchantParams { ...@@ -78,6 +78,9 @@ public class ApplyStudioMerchantParams {
@NotBlank(message = "验证码不能为空") @NotBlank(message = "验证码不能为空")
private String smsCode; private String smsCode;
@ApiModelProperty(value = "不校验验证码", notes = "true-不校验;null或者false-校验验证码")
private Boolean notCheckSmsCode;
@ApiModelProperty(value = "操作人ID") @ApiModelProperty(value = "操作人ID")
private Long operatorId; private Long operatorId;
......
package com.jiejing.fitness.finance.service.rpc; package com.jiejing.fitness.finance.service.rpc;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.google.common.collect.Maps;
import com.jiejing.common.model.JsonResult; import com.jiejing.common.model.JsonResult;
import com.jiejing.common.utils.text.StringUtil;
import com.jiejing.paycenter.api.merchant.MerchantApi; import com.jiejing.paycenter.api.merchant.MerchantApi;
import com.jiejing.paycenter.api.merchant.MerchantQueryApi; import com.jiejing.paycenter.api.merchant.MerchantQueryApi;
import com.jiejing.paycenter.api.merchant.request.ApplyMerchantRequest; import com.jiejing.paycenter.api.merchant.request.ApplyMerchantRequest;
...@@ -11,6 +13,7 @@ import com.jiejing.paycenter.api.merchant.request.GetMerchantByIdRequest; ...@@ -11,6 +13,7 @@ import com.jiejing.paycenter.api.merchant.request.GetMerchantByIdRequest;
import com.jiejing.paycenter.api.merchant.request.ListMerchantByIdsRequest; import com.jiejing.paycenter.api.merchant.request.ListMerchantByIdsRequest;
import com.jiejing.paycenter.api.merchant.request.SyncSubChannelAuthRequest; import com.jiejing.paycenter.api.merchant.request.SyncSubChannelAuthRequest;
import com.jiejing.paycenter.api.merchant.request.UploadRequest; import com.jiejing.paycenter.api.merchant.request.UploadRequest;
import com.jiejing.paycenter.common.model.request.Address;
import com.jiejing.paycenter.common.model.vo.ApplyMerchantResultVO; import com.jiejing.paycenter.common.model.vo.ApplyMerchantResultVO;
import com.jiejing.paycenter.common.model.vo.AuthSubChannelVO; import com.jiejing.paycenter.common.model.vo.AuthSubChannelVO;
import com.jiejing.paycenter.common.model.vo.ConfigSubChannelVO; import com.jiejing.paycenter.common.model.vo.ConfigSubChannelVO;
...@@ -22,6 +25,7 @@ import com.jiejing.paycenter.common.enums.merchant.SubChannelAuthTypeEnums; ...@@ -22,6 +25,7 @@ import com.jiejing.paycenter.common.enums.merchant.SubChannelAuthTypeEnums;
import com.jiejing.paycenter.common.enums.merchant.SubChannelConfigTypeEnums; import com.jiejing.paycenter.common.enums.merchant.SubChannelConfigTypeEnums;
import com.jiejing.paycenter.common.enums.merchant.SubChannelEnums; import com.jiejing.paycenter.common.enums.merchant.SubChannelEnums;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -47,11 +51,39 @@ public class MerchantRpcService { ...@@ -47,11 +51,39 @@ public class MerchantRpcService {
} }
public ApplyMerchantResultVO apply(ApplyMerchantRequest request) { public ApplyMerchantResultVO apply(ApplyMerchantRequest request) {
// 重新映射下地址信息:系统行政区划存在错误,需要订正
this.resetAddress(request);
JsonResult<ApplyMerchantResultVO> result = merchantApi.apply(request); JsonResult<ApplyMerchantResultVO> result = merchantApi.apply(request);
result.assertSuccess(); result.assertSuccess();
return result.getResult(); return result.getResult();
} }
private void resetAddress(ApplyMerchantRequest request) {
// 重新映射下地址信息:系统行政区划存在错误,需要订正
this.resetAddress(null == request.getLegal() ? null : request.getLegal().getLegalAddress());
this.resetAddress(null == request.getBankCard() ? null : request.getBankCard().getCardAddress());
this.resetAddress(null == request.getLicense() ? null : request.getLicense().getLicenseAddress());
this.resetAddress(null == request.getBusiness() ? null : request.getBusiness().getBusinessAddress());
}
private static final Map<String, String> DISTRICT_CODE_MAP = Maps.newHashMap();
static {
// 东莞市
DISTRICT_CODE_MAP.put("441901", "441900");
// 中山市
DISTRICT_CODE_MAP.put("442001", "442000");
}
private void resetAddress(Address address) {
if (null == address) {
return;
}
if (StringUtil.isBlank(address.getDistrict())) {
return;
}
address.setDistrict(DISTRICT_CODE_MAP.getOrDefault(address.getDistrict(), address.getDistrict()));
}
public MerchantVO getByMerchantId(Long merchantId) { public MerchantVO getByMerchantId(Long merchantId) {
GetMerchantByIdRequest request = GetMerchantByIdRequest.builder().merchantId(merchantId).build(); GetMerchantByIdRequest request = GetMerchantByIdRequest.builder().merchantId(merchantId).build();
JsonResult<MerchantVO> result = merchantQueryApi.getById(request); JsonResult<MerchantVO> result = merchantQueryApi.getById(request);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment