Commit 5cf40f4a by 程裕兵

feat:添加半屏小程序

parent 95e75898
......@@ -4,18 +4,22 @@ import com.jiejing.common.model.JsonResult;
import com.jiejing.common.model.PageVO;
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.BindStudioEmbeddedXcxRequest;
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.CheckUnbindStudioMerchantRequest;
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.GetStudioEmbeddedXcxRequest;
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.GetStudioMerchantRequest;
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.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.vo.StudioEmbeddedXcxVO;
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.StudioMerchantBindXcxAppIdVO;
......@@ -106,4 +110,16 @@ public interface StudioMerchantApi {
@PostMapping(value = "/private/studioMerchant/refund")
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;
import com.jiejing.common.model.PageVO;
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.BindStudioEmbeddedXcxRequest;
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.CheckUnbindStudioMerchantRequest;
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.GetStudioEmbeddedXcxRequest;
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.GetStudioMerchantRequest;
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.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.vo.StudioEmbeddedXcxVO;
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.StudioMerchantBindXcxAppIdVO;
......@@ -126,6 +130,21 @@ public class StudioMerchantApiFallback implements FallbackFactory<StudioMerchant
public JsonResult<StudioMerchantRefundVO> refund(StudioMerchantRefundRequest request) {
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();
}
};
}
}
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;
}
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.PageVO;
import com.jiejing.common.utils.convert.BeanUtil;
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.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.BindStudioMerchantXcxAppIdRequest;
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.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.GetStudioMerchantApplyRequest;
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.StudioMerchantPayRequest;
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.vo.StudioEmbeddedXcxVO;
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.StudioMerchantBindXcxAppIdVO;
......@@ -197,4 +202,29 @@ public class StudioMerchantController implements StudioMerchantApi {
return JsonResult.success(refundService.merchantRefund(params));
}
@ApiOperation(value = "获取半屏小程序", tags = {TAG})
@PostMapping(value = "/private/studioMerchant/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();
}
}
/*
* 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 = 4288943338021568638L;
/**
* 备注: 主键 是否允许为null: NO
*/
@TableId(value = "id", type = IdType.ID_WORKER)
private Long id;
/**
* 备注: 品牌ID 是否允许为null: YES
*/
private Long brandId;
/**
* 备注: 场馆ID 是否允许为null: YES
*/
private Long studioId;
/**
* 备注: 小程序appId 是否允许为null: YES
*/
private String appId;
/**
* 备注: 授权方appId 是否允许为null: YES
*/
private String authorizerAppId;
/**
* 备注: 状态 是否允许为null: YES
*/
private String state;
/**
* 失败原因
*/
private String message;
/**
* 备注: 创建时间 是否允许为null: YES
*/
private Date createTime;
/**
* 备注: 更新时间 是否允许为null: YES
*/
private Date updateTime;
public static final String ID = "id";
public static final String BRAND_ID = "brand_id";
public static final String STUDIO_ID = "studio_id";
public static final String APP_ID = "app_id";
public static final String AUTHORIZER_APP_ID = "authorizer_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, brand_id, studio_id, 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.google.common.collect.Lists;
import com.jiejing.fitness.enums.finance.EmbededXcxEnum;
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.Date;
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, List<String> appIds) {
return this.listByStudioIdAndAppId(studioId, appIds).stream()
.collect(Collectors.toMap(StudioEmbeddedXcxApply::getAppId, e -> e));
}
public List<StudioEmbeddedXcxApply> listByStudioIdAndAppId(Long studioId, List<String> appIds) {
QueryWrapper<StudioEmbeddedXcxApply> wrapper = new QueryWrapper<>();
wrapper.eq(StudioEmbeddedXcxApply.STUDIO_ID, studioId);
wrapper.in(StudioEmbeddedXcxApply.APP_ID, appIds);
return Optional.ofNullable(this.baseMapper.selectList(wrapper)).orElse(new ArrayList<>(1));
}
public StudioEmbeddedXcxApply getByStudioIdAndAppId(Long studioId, String appId) {
QueryWrapper<StudioEmbeddedXcxApply> wrapper = new QueryWrapper<>();
wrapper.eq(StudioEmbeddedXcxApply.STUDIO_ID, studioId);
wrapper.eq(StudioEmbeddedXcxApply.APP_ID, appId);
return Optional.ofNullable(this.baseMapper.selectList(wrapper))
.orElse(new ArrayList<>(1))
.stream().findFirst().orElse(null);
}
public List<StudioEmbeddedXcxApply> listByStudioId(Long studioId) {
QueryWrapper<StudioEmbeddedXcxApply> wrapper = new QueryWrapper<>();
wrapper.eq(StudioEmbeddedXcxApply.STUDIO_ID, studioId);
return Optional.ofNullable(this.baseMapper.selectList(wrapper)).orElse(new ArrayList<>(1));
}
public List<StudioEmbeddedXcxApply> listByAppIds(List<String> appIds) {
QueryWrapper<StudioEmbeddedXcxApply> wrapper = new QueryWrapper<>();
wrapper.in(StudioEmbeddedXcxApply.APP_ID, appIds);
return Optional.ofNullable(this.baseMapper.selectList(wrapper)).orElse(new ArrayList<>(1));
}
}
......@@ -59,7 +59,8 @@ public class GeneratorServiceEntity {
// "branch_bank",
// "studio_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;
import com.jiejing.common.model.PageVO;
import com.jiejing.common.utils.collection.CollectionUtil;
import com.jiejing.common.utils.convert.BeanUtil;
import com.jiejing.common.utils.http.HttpAgent;
import com.jiejing.common.utils.text.StringUtil;
import com.jiejing.fitness.enums.finance.BrandCashierTransTypeEnum;
import com.jiejing.fitness.finance.api.cashier.vo.StudioCashierRecordVO;
......@@ -181,4 +182,12 @@ public class StudioCashierServiceImpl implements StudioCashierService {
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);
}
}
package com.jiejing.fitness.finance.service.merchant;
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.StudioMerchantAuthSubChannelVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO;
......@@ -160,4 +161,26 @@ public interface StudioMerchantService {
*/
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;
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.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.StudioMerchantVO;
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.service.global.dto.SubChannelInfoDTO;
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 appId) {
StudioEmbeddedXcxApply record = new StudioEmbeddedXcxApply();
record.setId(IdWorker.getId());
record.setAppId(appId);
// record.setAuthorizerAppId(vo.getAuthorizerAppId());
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.getAppId()))
.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.getAppId()))
.filter(e -> {
AuthXcxInfo info = map.get(e.getAppId());
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());
}
}
......@@ -7,17 +7,22 @@ import com.jiejing.common.exception.BizException;
import com.jiejing.common.model.PageVO;
import com.jiejing.common.utils.collection.CollectionUtil;
import com.jiejing.common.utils.convert.BeanUtil;
import com.jiejing.common.utils.time.TimeUtil;
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.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.StudioMerchantAuthSubChannelVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantBindXcxAppIdVO;
import com.jiejing.fitness.finance.api.merchant.vo.StudioMerchantVO;
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.query.PageStudioMerchantApplyQuery;
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.service.config.PayChannelProperties;
import com.jiejing.fitness.finance.service.enums.FinanceErrorEnums;
......@@ -26,6 +31,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.StudioMerchantService;
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.PageStudioMerchantApplyParams;
import com.jiejing.fitness.finance.service.rpc.MerchantRpcService;
......@@ -48,10 +54,15 @@ import com.jiejing.paycenter.common.enums.merchant.SubChannelConfigTypeEnums;
import com.jiejing.paycenter.common.enums.merchant.SubChannelEnums;
import com.jiejing.paycenter.common.event.MerchantEvent;
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.studio.api.studio.vo.StudioVO;
import com.jiejing.wechat.WeXcxService;
import com.jiejing.wechat.vo.xcx.HalfScreenXcxAuthVO.AuthXcxInfo;
import com.xiaomai.event.EventAgent;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -63,6 +74,7 @@ import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
......@@ -102,6 +114,16 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
@Resource
private MessageRpcService messageRpcService;
@Resource
private StudioEmbeddedXcxApplyRpService studioEmbeddedXcxApplyRpService;
@Resource
private WeXcxService weXcxService;
private final static List<String> SPECIAL_FAIL_LIST = Lists.newArrayList(
"该商户号类型暂不支持与该AppID关联"
);
@Resource(name = "financeThreadPool")
private Executor executor;
......@@ -208,6 +230,98 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
}
@Override
public StudioEmbeddedXcxVO getEmbeddedXcx(Long studioId, String appId) {
StudioEmbeddedXcxApply embeddedXcx = studioEmbeddedXcxApplyRpService.getByStudioIdAndAppId(studioId,
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, appIds);
appIds.stream()
.filter(appId -> null == existMap.get(appId))
.forEach(appId -> {
log.info("bind embedded xcx {}, {}", studioId, appId);
StudioEmbeddedXcxApply entity = StudioEmbeddedXcxConvert.toEntity(studioId, appId);
studioEmbeddedXcxApplyRpService.insert(entity);
try {
// TODO
// weXcxService.addHalfScreenXcxAuth();
studioEmbeddedXcxApplyRpService.updateById(StudioEmbeddedXcxConvert.toSuccess(entity.getId()));
} 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(
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() {
// TODO
// weXcxService.getHalfScreenXcxAuthList();
return Lists.newArrayList();
}
@Override
public StudioMerchantApplyVO getApply(Long id) {
StudioMerchantApply apply = studioMerchantApplyRpService.getById(id)
.orElseThrow(() -> new BizException(FinanceErrorEnums.NOT_EXIST));
......@@ -402,29 +516,62 @@ public class StudioMerchantServiceImpl implements StudioMerchantService {
private void doAfterMerchantSuccess(MerchantEvent event, Long oldMerchantId) {
// 1. 配置场馆小程序appId
this.rebindMiniAppId(oldMerchantId, event.getMerchantId());
StudioMerchantApplyVO apply = this.getApply(Long.parseLong(event.getApplyNo()));
// 1. 绑定旧appId
this.bindAppIds(event, apply, oldMerchantId);
// 2. 短信
StudioMerchantApplyVO apply = this.getApply(Long.parseLong(event.getApplyNo()));
this.sendOpenSuccessMessage(apply);
}
private void rebindMiniAppId(Long oldMerchantId, Long newMerchantId) {
if (null == oldMerchantId) {
private void bindAppIds(MerchantEvent event, StudioMerchantApplyVO apply, Long oldMerchantId) {
MerchantVO oldMerchant = merchantRpcService.getByMerchantId(oldMerchantId);
if (null == oldMerchant) {
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);
merchant.getSubChannelConfigs().stream()
// 场馆的非系统小程序AppId
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 -> !systemXcxAppIds.contains(e.getAppId()))
.forEach(
config -> merchantRpcService.bindAppIdWxXcxOffline(merchant.getChannelNo(), newMerchantId,
config.getAppId()));
.collect(Collectors.toList());
}
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,
......
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