Commit b62266e0 by zhangxingmin

push

parent 0e51e2e8
package com.yd.user.api.controller;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiProjectThirdPartyBindService;
import com.yd.user.feign.client.thirdpartyplatform.ApiProjectThirdPartyBindFeignClient;
import com.yd.user.feign.request.thirdpartyplatform.ApiProjectThirdPartyBindRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiProjectThirdPartyBindResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 项目与第三方平台绑定
*
* @author zxm
* @since 2026-10-13
*/
@RestController
@RequestMapping("/projectThirdPartyBind")
@Validated
public class ApiProjectThirdPartyBindController implements ApiProjectThirdPartyBindFeignClient {
@Autowired
private ApiProjectThirdPartyBindService apiProjectThirdPartyBindService;
@Override
public Result bind(ApiProjectThirdPartyBindRequest request) {
return apiProjectThirdPartyBindService.bind(request);
}
@Override
public Result unbind(Long id) {
return apiProjectThirdPartyBindService.unbind(id);
}
@Override
public Result<List<ApiProjectThirdPartyBindResponse>> list(String projectBizId) {
return apiProjectThirdPartyBindService.list(projectBizId);
}
}
package com.yd.user.api.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiThirdPartyPlatformService;
import com.yd.user.feign.client.thirdpartyplatform.ApiThirdPartyPlatformFeignClient;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformAddRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformEditRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformPageRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformDetailResponse;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformPageResponse;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 第三方平台配置
*
* @author zxm
* @since 2026-10-13
*/
@RestController
@RequestMapping("/thirdPartyPlatform")
@Validated
public class ApiThirdPartyPlatformController implements ApiThirdPartyPlatformFeignClient {
@Resource
private ApiThirdPartyPlatformService apiThirdPartyPlatformService;
@Override
public Result<IPage<ApiThirdPartyPlatformPageResponse>> page(ApiThirdPartyPlatformPageRequest request) {
return apiThirdPartyPlatformService.page(request);
}
@Override
public Result<ApiThirdPartyPlatformDetailResponse> detail(Long id) {
return apiThirdPartyPlatformService.detail(id);
}
@Override
public Result add(ApiThirdPartyPlatformAddRequest request) {
return apiThirdPartyPlatformService.add(request);
}
@Override
public Result edit(ApiThirdPartyPlatformEditRequest request) {
return apiThirdPartyPlatformService.edit(request);
}
@Override
public Result del(Long id) {
return apiThirdPartyPlatformService.del(id);
}
@Override
public Result editStatus(Long id, Integer status) {
return apiThirdPartyPlatformService.editStatus(id, status);
}
}
package com.yd.user.api.controller;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiThirdPartyScanLoginService;
import com.yd.user.feign.client.thirdscanlogin.ApiThirdPartyScanLoginFeignClient;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateLoginQrCodeRequest;
import com.yd.user.feign.request.thirdscanlogin.ApiVerifyTicketRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiScanStatusResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiVerifyTicketResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 第三方扫码登录信息
*
* @author zxm
* @since 2026-10-13
*/
@RestController
@RequestMapping("/thirdPartyScanLogin")
@Validated
public class ApiThirdPartyScanLoginController implements ApiThirdPartyScanLoginFeignClient {
@Autowired
private ApiThirdPartyScanLoginService apiThirdPartyScanLoginService;
/**
* 生成登录二维码
* @param request 请求参数
* @return 二维码信息
*/
@Override
public Result<ApiGenerateQrCodeResponse> generateLoginQrCode(ApiGenerateLoginQrCodeRequest request) {
return apiThirdPartyScanLoginService.generateLoginQrCode(request);
}
/**
* 扫码回调(微信服务器调用,xml解析出来二维码业务类型,根据业务类型处理不同的业务逻辑,目前两种类型:分享绑定和扫码登录)
* @param appId 公众号appId
* @param xml 微信XML
* @return success
*/
@Override
public String loginWechatCallback(String appId, String xml) {
return apiThirdPartyScanLoginService.handleLoginWechatCallback(appId, xml);
}
/**
* 查询扫码状态
* @param qrId 二维码参数
* @return 扫码状态
*/
@Override
public Result<ApiScanStatusResponse> queryScanStatus(String qrId) {
return apiThirdPartyScanLoginService.queryScanStatus(qrId);
}
/**
* 校验 loginTicket
* @param request 校验参数
* @return 校验结果
*/
@Override
public Result<ApiVerifyTicketResponse> verifyTicket(ApiVerifyTicketRequest request) {
return apiThirdPartyScanLoginService.verifyTicket(request);
}
/**
* 消费 loginTicket
* @param request 消费参数
* @return 是否成功
*/
@Override
public Result<Boolean> consumeTicket(ApiVerifyTicketRequest request) {
return apiThirdPartyScanLoginService.consumeTicket(request);
}
}
package com.yd.user.api.controller;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiUserThirdPartyBindService;
import com.yd.user.feign.client.thirdscanlogin.ApiUserThirdPartyBindFeignClient;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateShareBindQrCodeRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiUserThirdPartyBindResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 用户与第三方绑定关系信息
*
* @author zxm
* @since 2026-10-13
*/
@RestController
@RequestMapping("/userThirdPartyBind")
@Validated
public class ApiUserThirdPartyBindController implements ApiUserThirdPartyBindFeignClient {
@Autowired
private ApiUserThirdPartyBindService apiUserThirdPartyBindService;
/**
* 生成分享绑定二维码
* @param request 请求参数
* @return 二维码信息
*/
@Override
public Result<ApiGenerateQrCodeResponse> generateShareBindQrCode(ApiGenerateShareBindQrCodeRequest request) {
return apiUserThirdPartyBindService.generateShareBindQrCode(request);
}
// /**
// * 分享扫码关注回调(微信服务器调用)
// * @param appId 公众号appId
// * @param xml 微信XML
// * @return success
// */
// @Override
// public String shareWechatCallback(String appId, String xml) {
// return apiUserThirdPartyBindService.handleShareWechatCallback(appId, xml);
// }
/**
* 查询绑定关系
* @param unionid 微信unionid
* @param projectBizId 项目ID
* @return 绑定列表
*/
@Override
public Result<List<ApiUserThirdPartyBindResponse>> queryBind(String unionid, String projectBizId) {
return apiUserThirdPartyBindService.queryBind(unionid, projectBizId);
}
/**
* 解绑
* @param id 主键
* @return 操作结果
*/
@Override
public Result unbind(Long id) {
return apiUserThirdPartyBindService.unbind(id);
}
}
package com.yd.user.api.service;
import com.yd.common.result.Result;
import com.yd.user.feign.request.thirdpartyplatform.ApiProjectThirdPartyBindRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiProjectThirdPartyBindResponse;
import java.util.List;
/**
* 项目与第三方平台绑定 API Service
*/
public interface ApiProjectThirdPartyBindService {
/**
* 绑定
* @param request 绑定参数
* @return 操作结果
*/
Result bind(ApiProjectThirdPartyBindRequest request);
/**
* 解绑
* @param id 主键
* @return 操作结果
*/
Result unbind(Long id);
/**
* 查询项目绑定列表
* @param projectBizId 项目ID
* @return 绑定列表
*/
Result<List<ApiProjectThirdPartyBindResponse>> list(String projectBizId);
}
package com.yd.user.api.service;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateLoginQrCodeRequest;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateShareBindQrCodeRequest;
import com.yd.user.feign.request.thirdscanlogin.ApiVerifyTicketRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiScanStatusResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiVerifyTicketResponse;
/**
* 扫码登录核心服务
*/
public interface ApiScanLoginService {
/**
* 生成分享绑定二维码
*
* @param request 请求参数
* @return 二维码信息
*/
ApiGenerateQrCodeResponse generateShareBindQrCode(ApiGenerateShareBindQrCodeRequest request);
/**
* 处理分享扫码回调
*
* @param appId 公众号appId
* @param xml 微信XML
*/
void handleShareWechatCallback(String appId, String xml);
/**
* 生成登录二维码
*
* @param request 请求参数
* @return 二维码信息
*/
ApiGenerateQrCodeResponse generateLoginQrCode(ApiGenerateLoginQrCodeRequest request);
/**
* 处理登录扫码回调
*
* @param appId 公众号appId
* @param xml 微信XML
*/
void handleLoginWechatCallback(String appId, String xml);
/**
* 查询扫码状态
*
* @param qrId 二维码参数
* @return 扫码状态
*/
ApiScanStatusResponse queryScanStatus(String qrId);
/**
* 校验 loginTicket
*
* @param request 校验参数
* @return 校验结果
*/
ApiVerifyTicketResponse verifyTicket(ApiVerifyTicketRequest request);
/**
* 消费 loginTicket
*
* @param request 消费参数
* @return 是否成功
*/
boolean consumeTicket(ApiVerifyTicketRequest request);
}
package com.yd.user.api.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yd.common.result.Result;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformAddRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformEditRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformPageRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformDetailResponse;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformPageResponse;
/**
* 第三方平台配置 API Service
*/
public interface ApiThirdPartyPlatformService {
/**
* 分页查询
* @param request 查询条件
* @return 分页结果
*/
Result<IPage<ApiThirdPartyPlatformPageResponse>> page(ApiThirdPartyPlatformPageRequest request);
/**
* 详情
* @param id 主键
* @return 详情
*/
Result<ApiThirdPartyPlatformDetailResponse> detail(Long id);
/**
* 新增
* @param request 新增参数
* @return 操作结果
*/
Result add(ApiThirdPartyPlatformAddRequest request);
/**
* 编辑
* @param request 编辑参数
* @return 操作结果
*/
Result edit(ApiThirdPartyPlatformEditRequest request);
/**
* 删除
* @param id 主键
* @return 操作结果
*/
Result del(Long id);
/**
* 启用/禁用
* @param id 主键
* @param status 状态
* @return 操作结果
*/
Result editStatus(Long id, Integer status);
}
package com.yd.user.api.service;
import com.yd.common.result.Result;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateLoginQrCodeRequest;
import com.yd.user.feign.request.thirdscanlogin.ApiVerifyTicketRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiScanStatusResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiVerifyTicketResponse;
/**
* 第三方扫码登录 API Service
*/
public interface ApiThirdPartyScanLoginService {
/**
* 生成登录二维码
* @param request 请求参数
* @return 二维码信息
*/
Result<ApiGenerateQrCodeResponse> generateLoginQrCode(ApiGenerateLoginQrCodeRequest request);
/**
* 扫码回调(微信服务器调用,xml解析出来二维码业务类型,根据业务类型处理不同的业务逻辑,目前两种类型:分享绑定和扫码登录)
* @param appId 公众号appId
* @param xml 微信XML
* @return success
*/
String handleLoginWechatCallback(String appId, String xml);
/**
* 查询扫码状态
* @param qrId 二维码参数
* @return 扫码状态
*/
Result<ApiScanStatusResponse> queryScanStatus(String qrId);
/**
* 校验 loginTicket
* @param request 校验参数
* @return 校验结果
*/
Result<ApiVerifyTicketResponse> verifyTicket(ApiVerifyTicketRequest request);
/**
* 消费 loginTicket
* @param request 消费参数
* @return 是否成功
*/
Result<Boolean> consumeTicket(ApiVerifyTicketRequest request);
}
package com.yd.user.api.service;
import com.yd.common.result.Result;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateShareBindQrCodeRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiUserThirdPartyBindResponse;
import java.util.List;
/**
* 用户与第三方绑定关系 API Service
*/
public interface ApiUserThirdPartyBindService {
/**
* 生成分享绑定二维码
* @param request 请求参数
* @return 二维码信息
*/
Result<ApiGenerateQrCodeResponse> generateShareBindQrCode(ApiGenerateShareBindQrCodeRequest request);
/**
* 处理分享扫码回调
* @param appId 公众号appId
* @param xml 微信XML
* @return success
*/
String handleShareWechatCallback(String appId, String xml);
/**
* 查询绑定关系
* @param unionid 微信unionid
* @param projectBizId 项目ID
* @return 绑定列表
*/
Result<List<ApiUserThirdPartyBindResponse>> queryBind(String unionid, String projectBizId);
/**
* 解绑
* @param id 主键
* @return 操作结果
*/
Result unbind(Long id);
}
package com.yd.user.api.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiProjectThirdPartyBindService;
import com.yd.user.feign.request.thirdpartyplatform.ApiProjectThirdPartyBindRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiProjectThirdPartyBindResponse;
import com.yd.user.service.model.ProjectThirdPartyBind;
import com.yd.user.service.service.IProjectThirdPartyBindService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* 项目与第三方平台绑定 API Service 实现
*/
@Service
public class ApiProjectThirdPartyBindServiceImpl implements ApiProjectThirdPartyBindService {
@Autowired
private IProjectThirdPartyBindService iProjectThirdPartyBindService;
@Override
public Result bind(ApiProjectThirdPartyBindRequest request) {
// 校验是否已绑定
long count = iProjectThirdPartyBindService.count(new LambdaQueryWrapper<ProjectThirdPartyBind>()
.eq(ProjectThirdPartyBind::getProjectBizId, request.getProjectBizId())
.eq(ProjectThirdPartyBind::getPlatformCode, request.getPlatformCode())
.eq(ProjectThirdPartyBind::getIsDeleted, 0));
if (count > 0) {
throw new BusinessException("该项目已绑定此平台");
}
ProjectThirdPartyBind entity = new ProjectThirdPartyBind();
BeanUtils.copyProperties(request, entity);
entity.setIsDeleted(0);
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
iProjectThirdPartyBindService.save(entity);
return Result.success();
}
@Override
public Result unbind(Long id) {
ProjectThirdPartyBind entity = iProjectThirdPartyBindService.getById(id);
if (entity == null) {
throw new BusinessException("绑定关系不存在");
}
entity.setIsDeleted(1);
entity.setUpdateTime(LocalDateTime.now());
iProjectThirdPartyBindService.updateById(entity);
return Result.success();
}
@Override
public Result<List<ApiProjectThirdPartyBindResponse>> list(String projectBizId) {
List<ProjectThirdPartyBind> list = iProjectThirdPartyBindService.list(
new LambdaQueryWrapper<ProjectThirdPartyBind>()
.eq(ProjectThirdPartyBind::getProjectBizId, projectBizId)
.eq(ProjectThirdPartyBind::getIsDeleted, 0));
List<ApiProjectThirdPartyBindResponse> responseList = list.stream().map(entity -> {
ApiProjectThirdPartyBindResponse response = new ApiProjectThirdPartyBindResponse();
BeanUtils.copyProperties(entity, response);
return response;
}).collect(Collectors.toList());
return Result.success(responseList);
}
}
package com.yd.user.api.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiThirdPartyPlatformService;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformAddRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformEditRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformPageRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformDetailResponse;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformPageResponse;
import com.yd.user.service.model.ThirdPartyPlatform;
import com.yd.user.service.service.IThirdPartyPlatformService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Objects;
/**
* 第三方平台配置 API Service 实现
*/
@Service
public class ApiThirdPartyPlatformServiceImpl implements ApiThirdPartyPlatformService {
@Autowired
private IThirdPartyPlatformService iThirdPartyPlatformService;
@Override
public Result<IPage<ApiThirdPartyPlatformPageResponse>> page(ApiThirdPartyPlatformPageRequest request) {
Page<ThirdPartyPlatform> page = new Page<>(request.getPageNo(), request.getPageSize());
LambdaQueryWrapper<ThirdPartyPlatform> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(request.getPlatformCode()), ThirdPartyPlatform::getPlatformCode, request.getPlatformCode())
.like(StringUtils.isNotBlank(request.getPlatformName()), ThirdPartyPlatform::getPlatformName, request.getPlatformName())
.eq(Objects.nonNull(request.getPlatformType()), ThirdPartyPlatform::getPlatformType, request.getPlatformType())
.eq(Objects.nonNull(request.getStatus()), ThirdPartyPlatform::getStatus, request.getStatus())
.eq(ThirdPartyPlatform::getIsDeleted, 0)
.orderByDesc(ThirdPartyPlatform::getCreateTime);
IPage<ThirdPartyPlatform> entityPage = iThirdPartyPlatformService.page(page, wrapper);
IPage<ApiThirdPartyPlatformPageResponse> responsePage = entityPage.convert(entity -> {
ApiThirdPartyPlatformPageResponse response = new ApiThirdPartyPlatformPageResponse();
BeanUtils.copyProperties(entity, response);
return response;
});
return Result.success(responsePage);
}
@Override
public Result<ApiThirdPartyPlatformDetailResponse> detail(Long id) {
ThirdPartyPlatform entity = iThirdPartyPlatformService.getById(id);
if (entity == null || entity.getIsDeleted() == 1) {
throw new BusinessException("平台配置不存在");
}
ApiThirdPartyPlatformDetailResponse response = new ApiThirdPartyPlatformDetailResponse();
BeanUtils.copyProperties(entity, response);
return Result.success(response);
}
@Override
public Result add(ApiThirdPartyPlatformAddRequest request) {
long count = iThirdPartyPlatformService.count(new LambdaQueryWrapper<ThirdPartyPlatform>()
.eq(ThirdPartyPlatform::getPlatformCode, request.getPlatformCode())
.eq(ThirdPartyPlatform::getIsDeleted, 0));
if (count > 0) {
throw new BusinessException("平台编码已存在");
}
ThirdPartyPlatform entity = new ThirdPartyPlatform();
BeanUtils.copyProperties(request, entity);
entity.setIsDeleted(0);
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
iThirdPartyPlatformService.save(entity);
return Result.success();
}
@Override
public Result edit(ApiThirdPartyPlatformEditRequest request) {
ThirdPartyPlatform entity = iThirdPartyPlatformService.getById(request.getId());
if (entity == null || entity.getIsDeleted() == 1) {
throw new BusinessException("平台配置不存在");
}
BeanUtils.copyProperties(request, entity);
entity.setUpdateTime(LocalDateTime.now());
iThirdPartyPlatformService.updateById(entity);
return Result.success();
}
@Override
public Result del(Long id) {
ThirdPartyPlatform entity = iThirdPartyPlatformService.getById(id);
if (entity == null) {
throw new BusinessException("平台配置不存在");
}
entity.setIsDeleted(1);
entity.setUpdateTime(LocalDateTime.now());
iThirdPartyPlatformService.updateById(entity);
return Result.success();
}
@Override
public Result editStatus(Long id, Integer status) {
ThirdPartyPlatform entity = iThirdPartyPlatformService.getById(id);
if (entity == null) {
throw new BusinessException("平台配置不存在");
}
entity.setStatus(status);
entity.setUpdateTime(LocalDateTime.now());
iThirdPartyPlatformService.updateById(entity);
return Result.success();
}
}
package com.yd.user.api.service.impl;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiScanLoginService;
import com.yd.user.api.service.ApiThirdPartyScanLoginService;
import com.yd.user.api.utils.WeChatApiUtil;
import com.yd.user.feign.constants.ScanLoginConstants;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateLoginQrCodeRequest;
import com.yd.user.feign.request.thirdscanlogin.ApiVerifyTicketRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiScanStatusResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiVerifyTicketResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 第三方扫码登录 API Service 实现
*/
@Slf4j
@Service
public class ApiThirdPartyScanLoginServiceImpl implements ApiThirdPartyScanLoginService {
@Autowired
private ApiScanLoginService scanLoginService;
@Autowired
private WeChatApiUtil weChatApiUtil;
/**
* 生成登录二维码
* @param request 请求参数
* @return 二维码信息
*/
@Override
public Result<ApiGenerateQrCodeResponse> generateLoginQrCode(ApiGenerateLoginQrCodeRequest request) {
ApiGenerateQrCodeResponse response = scanLoginService.generateLoginQrCode(request);
return Result.success(response);
}
/**
* 扫码回调(微信服务器调用,xml解析出来二维码业务类型,根据业务类型处理不同的业务逻辑,目前两种类型:分享绑定和扫码登录)
* @param appId 公众号appId
* @param xml 微信XML
* @return success
*/
@Override
public String handleLoginWechatCallback(String appId, String xml) {
//解析微信XML
String eventKey = weChatApiUtil.getEventKey(xml);
if (StringUtils.isBlank(eventKey)) {
log.warn("扫码回调参数缺失,eventKey={}", eventKey);
return "fail";
}
//解析eventKey
String[] parts = eventKey.split(":");
if (parts.length < 1) {
log.warn("登录扫码 EventKey 格式错误:{}", eventKey);
return "fail";
}
//二维码业务类型
String bizType = parts[0];
if (ScanLoginConstants.BIZ_TYPE_LOGIN.equals(bizType)) {
//二维码业务类型:扫码登录
scanLoginService.handleLoginWechatCallback(appId, xml);
}else if (ScanLoginConstants.BIZ_TYPE_SHARE_BIND.equals(bizType)) {
//二维码业务类型:分享绑定
scanLoginService.handleShareWechatCallback(appId, xml);
}
return "success";
}
/**
* 查询扫码状态
* @param qrId 二维码参数
* @return 扫码状态
*/
@Override
public Result<ApiScanStatusResponse> queryScanStatus(String qrId) {
ApiScanStatusResponse response = scanLoginService.queryScanStatus(qrId);
return Result.success(response);
}
/**
* 校验 loginTicket
* @param request 校验参数
* @return 校验结果
*/
@Override
public Result<ApiVerifyTicketResponse> verifyTicket(ApiVerifyTicketRequest request) {
ApiVerifyTicketResponse response = scanLoginService.verifyTicket(request);
return Result.success(response);
}
/**
* 消费 loginTicket
* @param request 消费参数
* @return 是否成功
*/
@Override
public Result<Boolean> consumeTicket(ApiVerifyTicketRequest request) {
boolean success = scanLoginService.consumeTicket(request);
return Result.success(success);
}
}
package com.yd.user.api.service.impl;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.user.api.service.ApiScanLoginService;
import com.yd.user.api.service.ApiUserThirdPartyBindService;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateShareBindQrCodeRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiUserThirdPartyBindResponse;
import com.yd.user.service.model.UserThirdPartyBind;
import com.yd.user.service.service.IUserThirdPartyBindService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户与第三方绑定关系 API Service 实现
*/
@Service
public class ApiUserThirdPartyBindServiceImpl implements ApiUserThirdPartyBindService {
@Autowired
private ApiScanLoginService scanLoginService;
@Autowired
private IUserThirdPartyBindService userThirdPartyBindService;
@Override
public Result<ApiGenerateQrCodeResponse> generateShareBindQrCode(ApiGenerateShareBindQrCodeRequest request) {
ApiGenerateQrCodeResponse response = scanLoginService.generateShareBindQrCode(request);
return Result.success(response);
}
@Override
public String handleShareWechatCallback(String appId, String xml) {
scanLoginService.handleShareWechatCallback(appId, xml);
return "success";
}
@Override
public Result<List<ApiUserThirdPartyBindResponse>> queryBind(String unionid, String projectBizId) {
List<UserThirdPartyBind> list = userThirdPartyBindService.queryByUnionidAndProject(unionid, projectBizId);
List<ApiUserThirdPartyBindResponse> responseList = list.stream().map(entity -> {
ApiUserThirdPartyBindResponse response = new ApiUserThirdPartyBindResponse();
BeanUtils.copyProperties(entity, response);
return response;
}).collect(Collectors.toList());
return Result.success(responseList);
}
@Override
public Result unbind(Long id) {
boolean success = userThirdPartyBindService.unbind(id);
if (!success) {
throw new BusinessException("解绑失败");
}
return Result.success();
}
}
package com.yd.user.api.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yd.common.utils.RedisUtil;
import com.yd.user.service.model.ThirdPartyPlatform;
import com.yd.user.service.service.IThirdPartyPlatformService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
/**
* 微信 API 工具类
* 提供 access_token 获取、临时二维码创建、openid 换 unionid、XML 解析等功能
*/
@Slf4j
@Component
public class WeChatApiUtil {
/**
* 获取 access_token 的 URL 模板
*/
private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
/**
* 创建二维码的 URL 模板
*/
private static final String QRCODE_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s";
/**
* 获取用户信息的 URL 模板
*/
private static final String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN";
/**
* Redis 缓存 access_token 的 key 前缀
*/
private static final String REDIS_KEY_ACCESS_TOKEN = "yd:wechat:access_token:";
/**
* HTTP 客户端
*/
private final RestTemplate restTemplate = new RestTemplate();
/**
* JSON 解析器
*/
private final ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private RedisUtil redisUtil;
@Autowired
private IThirdPartyPlatformService thirdPartyPlatformService;
/**
* 获取微信 access_token,优先从 Redis 缓存中读取
*
* @param appId 公众号 appId
* @param appSecret 公众号 appSecret
* @return access_token
*/
public String getAccessToken(String appId, String appSecret) {
String cacheKey = REDIS_KEY_ACCESS_TOKEN + appId;
// 从 Redis 缓存中读取
String cached = redisUtil.getCacheObject(cacheKey);
if (cached != null) {
return cached;
}
String url = String.format(ACCESS_TOKEN_URL, appId, appSecret);
String response = restTemplate.getForObject(url, String.class);
try {
JsonNode node = objectMapper.readTree(response);
if (node.has("access_token")) {
String accessToken = node.get("access_token").asText();
int expiresIn = node.get("expires_in").asInt();
// 提前 300 秒过期,避免临界时间失效
redisUtil.setCacheObject(cacheKey, accessToken, expiresIn - 300, TimeUnit.SECONDS);
return accessToken;
} else {
log.error("获取微信 access_token 失败: {}", response);
throw new RuntimeException("获取微信 access_token 失败: " + response);
}
} catch (Exception e) {
log.error("解析 access_token 响应异常", e);
throw new RuntimeException("解析微信 access_token 异常", e);
}
}
/**
* 创建带参数的临时二维码
*
* @param appId 公众号 appId
* @param appSecret 公众号 appSecret
* @param sceneStr 自定义参数,放入 scene_str
* @param expireSeconds 二维码有效期(秒),最大 2592000
* @return 二维码 ticket
*/
public String createTemporaryQrCode(String appId, String appSecret, String sceneStr, int expireSeconds) {
String accessToken = getAccessToken(appId, appSecret);
String url = String.format(QRCODE_CREATE_URL, accessToken);
// 构造请求体
String body = "{\"expire_seconds\":" + expireSeconds + ",\"action_name\":\"QR_STR_SCENE\",\"action_info\":{\"scene\":{\"scene_str\":\"" + sceneStr + "\"}}}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>(body, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
String response = responseEntity.getBody();
try {
JsonNode node = objectMapper.readTree(response);
if (node.has("ticket")) {
return node.get("ticket").asText();
} else {
log.error("创建微信二维码失败: {}", response);
throw new RuntimeException("创建微信二维码失败: " + response);
}
} catch (Exception e) {
log.error("解析二维码响应异常", e);
throw new RuntimeException("解析微信二维码响应异常", e);
}
}
/**
* 用 openid 换取 unionid
*
* @param appId 公众号 appId
* @param openid 用户 openid
* @return unionid,获取失败返回 null
*/
public String getUnionIdByOpenId(String appId, String openid) {
// 根据 appId 查询平台配置获取 appSecret
ThirdPartyPlatform platform = thirdPartyPlatformService.getByAppId(appId);
if (platform == null || platform.getAppSecret() == null) {
log.error("未找到 appId 对应的平台配置或 appSecret 为空: {}", appId);
return null;
}
String appSecret = platform.getAppSecret();
String accessToken = getAccessToken(appId, appSecret);
String url = String.format(USER_INFO_URL, accessToken, openid);
String response = restTemplate.getForObject(url, String.class);
try {
JsonNode node = objectMapper.readTree(response);
if (node.has("unionid")) {
return node.get("unionid").asText();
} else {
log.warn("获取 unionid 失败,可能未绑定开放平台: {}", response);
return null;
}
} catch (Exception e) {
log.error("解析用户信息响应异常", e);
return null;
}
}
/**
* 解析微信 XML 获取事件类型
*
* @param xml 微信回调 XML
* @return Event 字段值
*/
public String getEventType(String xml) {
return getXmlField(xml, "Event");
}
/**
* 解析微信 XML 获取 FromUserName(openid)
*
* @param xml 微信回调 XML
* @return FromUserName 字段值
*/
public String getFromUserName(String xml) {
return getXmlField(xml, "FromUserName");
}
/**
* 解析微信 XML 获取 EventKey
*
* @param xml 微信回调 XML
* @return EventKey 字段值
*/
public String getEventKey(String xml) {
return getXmlField(xml, "EventKey");
}
/**
* 通用解析微信 XML 字段
*
* @param xml 微信回调 XML
* @param fieldName 字段名称
* @return 字段值,解析失败返回 null
*/
private String getXmlField(String xml, String fieldName) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 防止 XXE 攻击
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
NodeList nodeList = document.getElementsByTagName(fieldName);
if (nodeList.getLength() > 0) {
Element element = (Element) nodeList.item(0);
return element.getTextContent();
}
} catch (Exception e) {
log.error("解析微信 XML 失败,field={}, xml={}", fieldName, xml, e);
}
return null;
}
}
package com.yd.user.feign.client.thirdpartyplatform;
import com.yd.common.result.Result;
import com.yd.user.feign.fallback.thirdpartyplatform.ApiProjectThirdPartyBindFeignFallbackFactory;
import com.yd.user.feign.request.thirdpartyplatform.ApiProjectThirdPartyBindRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiProjectThirdPartyBindResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 项目与第三方平台绑定 Feign 客户端
*/
@FeignClient(name = "yd-user-api", contextId = "apiProjectThirdPartyBindFeignClient",
fallbackFactory = ApiProjectThirdPartyBindFeignFallbackFactory.class)
public interface ApiProjectThirdPartyBindFeignClient {
/**
* 绑定
* @param request 绑定参数
* @return 操作结果
*/
@PostMapping("/projectThirdPartyBind/bind")
Result bind(@Validated @RequestBody ApiProjectThirdPartyBindRequest request);
/**
* 解绑
* @param id 主键
* @return 操作结果
*/
@DeleteMapping("/projectThirdPartyBind/unbind")
Result unbind(@RequestParam("id") Long id);
/**
* 查询项目绑定列表
* @param projectBizId 项目ID
* @return 绑定列表
*/
@GetMapping("/projectThirdPartyBind/list")
Result<List<ApiProjectThirdPartyBindResponse>> list(@RequestParam("projectBizId") String projectBizId);
}
package com.yd.user.feign.client.thirdpartyplatform;
import com.yd.common.result.Result;
import com.yd.user.feign.fallback.thirdpartyplatform.ApiThirdPartyPlatformFeignFallbackFactory;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformAddRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformEditRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformPageRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformDetailResponse;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformPageResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 用户服务-第三方平台配置 Feign 客户端
*/
@FeignClient(name = "yd-user-api", contextId = "apiThirdPartyPlatformFeignClient",
fallbackFactory = ApiThirdPartyPlatformFeignFallbackFactory.class)
public interface ApiThirdPartyPlatformFeignClient {
/**
* 分页查询
* @param request 查询条件
* @return 分页结果
*/
@PostMapping("/thirdPartyPlatform/page")
Result page(@RequestBody ApiThirdPartyPlatformPageRequest request);
/**
* 详情
* @param id 主键
* @return 详情
*/
@GetMapping("/thirdPartyPlatform/detail")
Result<ApiThirdPartyPlatformDetailResponse> detail(@RequestParam("id") Long id);
/**
* 新增
* @param request 新增参数
* @return 操作结果
*/
@PostMapping("/thirdPartyPlatform/add")
Result add(@Validated @RequestBody ApiThirdPartyPlatformAddRequest request);
/**
* 编辑
* @param request 编辑参数
* @return 操作结果
*/
@PutMapping("/thirdPartyPlatform/edit")
Result edit(@Validated @RequestBody ApiThirdPartyPlatformEditRequest request);
/**
* 删除
* @param id 主键
* @return 操作结果
*/
@DeleteMapping("/thirdPartyPlatform/del")
Result del(@RequestParam("id") Long id);
/**
* 启用/禁用
* @param id 主键
* @param status 状态
* @return 操作结果
*/
@PatchMapping("/thirdPartyPlatform/edit/status")
Result editStatus(@RequestParam("id") Long id, @RequestParam("status") Integer status);
}
package com.yd.user.feign.client.thirdscanlogin;
import com.yd.common.result.Result;
import com.yd.user.feign.fallback.thirdscanlogin.ApiThirdPartyScanLoginFeignFallbackFactory;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateLoginQrCodeRequest;
import com.yd.user.feign.request.thirdscanlogin.ApiVerifyTicketRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiScanStatusResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiVerifyTicketResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 第三方扫码登录 Feign 客户端
*/
@FeignClient(name = "yd-user-api", path = "/user/api/thirdPartyScanLogin", fallbackFactory = ApiThirdPartyScanLoginFeignFallbackFactory.class)
public interface ApiThirdPartyScanLoginFeignClient {
/**
* 生成登录二维码
* @param request 请求参数
* @return 二维码信息
*/
@PostMapping("/qrcode")
Result<ApiGenerateQrCodeResponse> generateLoginQrCode(
@Validated @RequestBody ApiGenerateLoginQrCodeRequest request);
/**
* 扫码回调(微信服务器调用,xml解析出来二维码业务类型,根据业务类型处理不同的业务逻辑,目前两种类型:分享绑定和扫码登录)
* @param appId 公众号appId
* @param xml 微信XML
* @return success
*/
@PostMapping("/wechat/callback/{appId}")
String loginWechatCallback(@PathVariable("appId") String appId, @RequestBody String xml);
/**
* 查询扫码状态
* @param qrId 二维码参数
* @return 扫码状态
*/
@GetMapping("/status")
Result<ApiScanStatusResponse> queryScanStatus(@RequestParam("qrId") String qrId);
/**
* 校验 loginTicket
* @param request 校验参数
* @return 校验结果
*/
@PostMapping("/verifyTicket")
Result<ApiVerifyTicketResponse> verifyTicket(@Validated @RequestBody ApiVerifyTicketRequest request);
/**
* 消费 loginTicket
* @param request 消费参数
* @return 是否成功
*/
@PostMapping("/consumeTicket")
Result<Boolean> consumeTicket(@Validated @RequestBody ApiVerifyTicketRequest request);
}
package com.yd.user.feign.client.thirdscanlogin;
import com.yd.common.result.Result;
import com.yd.user.feign.fallback.thirdscanlogin.ApiUserThirdPartyBindFeignFallbackFactory;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateShareBindQrCodeRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiUserThirdPartyBindResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户与第三方绑定关系 Feign 客户端
*/
@FeignClient(name = "yd-user-api", path = "/user/api/userThirdPartyBind",fallbackFactory = ApiUserThirdPartyBindFeignFallbackFactory.class)
public interface ApiUserThirdPartyBindFeignClient {
/**
* 生成分享绑定二维码
* @param request 请求参数
* @return 二维码信息
*/
@PostMapping("/share/qrcode")
Result<ApiGenerateQrCodeResponse> generateShareBindQrCode(
@Validated @RequestBody ApiGenerateShareBindQrCodeRequest request);
// /**
// * 分享扫码关注回调(微信服务器调用)
// * @param appId 公众号appId
// * @param xml 微信XML
// * @return success
// */
// @PostMapping("/wechat/callback/{appId}")
// String shareWechatCallback(@PathVariable("appId") String appId, @RequestBody String xml);
/**
* 查询绑定关系
* @param unionid 微信unionid
* @param projectBizId 项目ID
* @return 绑定列表
*/
@GetMapping("/query")
Result<List<ApiUserThirdPartyBindResponse>> queryBind(@RequestParam("unionid") String unionid,
@RequestParam("projectBizId") String projectBizId);
/**
* 解绑
* @param id 主键
* @return 操作结果
*/
@PostMapping("/unbind")
Result unbind(@RequestParam("id") Long id);
}
package com.yd.user.feign.constants;
/**
* 扫码登录常量类
*/
public class ScanLoginConstants {
/**
* 二维码业务类型:分享绑定
*/
public static final String BIZ_TYPE_SHARE_BIND = "share_bind";
/**
* 二维码业务类型:扫码登录
*/
public static final String BIZ_TYPE_LOGIN = "login";
/**
* 扫码状态:待扫码
*/
public static final String STATUS_WAIT_SCAN = "WAIT_SCAN";
/**
* 扫码状态:已扫码
*/
public static final String STATUS_SCANNED = "SCANNED";
/**
* 扫码状态:已确认
*/
public static final String STATUS_CONFIRMED = "CONFIRMED";
/**
* 扫码状态:已消费
*/
public static final String STATUS_CONSUMED = "CONSUMED";
/**
* 扫码状态:已过期
*/
public static final String STATUS_EXPIRED = "EXPIRED";
/**
* 扫码状态:已取消
*/
public static final String STATUS_CANCELLED = "CANCELLED";
/**
* 扫码状态:未绑定
*/
public static final String STATUS_UNBOUND = "UNBOUND";
/**
* 扫码状态:已禁用
*/
public static final String STATUS_DISABLED = "DISABLED";
/**
* 扫码状态:已离职
*/
public static final String STATUS_RESIGNED = "RESIGNED";
/**
* 扫码状态:无权限
*/
public static final String STATUS_NO_PERMISSION = "NO_PERMISSION";
/**
* Redis Key 前缀:二维码会话
*/
public static final String REDIS_KEY_QR = "yd:scan:login:qr:";
/**
* Redis Key 前缀:loginTicket
*/
public static final String REDIS_KEY_TICKET = "yd:scan:login:ticket:";
/**
* Redis Key 前缀:幂等控制
*/
public static final String REDIS_KEY_IDEMPOTENT = "yd:scan:login:idempotent:";
/**
* 二维码有效期(秒)
*/
public static final int QR_EXPIRE_SECONDS = 120;
/**
* loginTicket 有效期(秒)
*/
public static final int TICKET_EXPIRE_SECONDS = 60;
/**
* 平台类型:公众号
*/
public static final int PLATFORM_TYPE_GZH = 1;
/**
* 平台类型:小程序
*/
public static final int PLATFORM_TYPE_MINI = 2;
/**
* 平台类型:网站
*/
public static final int PLATFORM_TYPE_WEBSITE = 3;
/**
* 绑定状态:已绑定
*/
public static final int BIND_STATUS_BOUND = 1;
/**
* 绑定状态:已解绑
*/
public static final int BIND_STATUS_UNBOUND = 0;
/**
* 绑定来源:PC分享扫码绑定
*/
public static final int BIND_SOURCE_SHARE = 1;
/**
* 绑定来源:扫码登录绑定
*/
public static final int BIND_SOURCE_LOGIN = 2;
/**
* 绑定来源:个人中心绑定
*/
public static final int BIND_SOURCE_USER_CENTER = 3;
/**
* 绑定来源:公众号菜单绑定
*/
public static final int BIND_SOURCE_GZH_MENU = 4;
}
package com.yd.user.feign.fallback.thirdpartyplatform;
import com.yd.common.result.Result;
import com.yd.user.feign.client.thirdpartyplatform.ApiProjectThirdPartyBindFeignClient;
import com.yd.user.feign.request.thirdpartyplatform.ApiProjectThirdPartyBindRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiProjectThirdPartyBindResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
/**
* 项目第三方绑定 Feign 降级
*/
@Slf4j
@Component
public class ApiProjectThirdPartyBindFeignFallbackFactory implements FallbackFactory<ApiProjectThirdPartyBindFeignClient> {
@Override
public ApiProjectThirdPartyBindFeignClient create(Throwable cause) {
log.error("项目第三方绑定服务降级", cause);
return new ApiProjectThirdPartyBindFeignClient() {
@Override
public Result bind(ApiProjectThirdPartyBindRequest request) {
return Result.fail("服务降级");
}
@Override
public Result unbind(Long id) {
return Result.fail("服务降级");
}
@Override
public Result<List<ApiProjectThirdPartyBindResponse>> list(String projectBizId) {
return Result.success(Collections.emptyList());
}
};
}
}
package com.yd.user.feign.fallback.thirdpartyplatform;
import com.yd.common.result.Result;
import com.yd.user.feign.client.thirdpartyplatform.ApiThirdPartyPlatformFeignClient;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformAddRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformEditRequest;
import com.yd.user.feign.request.thirdpartyplatform.ApiThirdPartyPlatformPageRequest;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformDetailResponse;
import com.yd.user.feign.response.thirdpartyplatform.ApiThirdPartyPlatformPageResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 第三方平台配置 Feign 降级
*/
@Slf4j
@Component
public class ApiThirdPartyPlatformFeignFallbackFactory implements FallbackFactory<ApiThirdPartyPlatformFeignClient> {
@Override
public ApiThirdPartyPlatformFeignClient create(Throwable cause) {
log.error("第三方平台配置服务降级", cause);
return new ApiThirdPartyPlatformFeignClient() {
@Override
public Result page(ApiThirdPartyPlatformPageRequest request) {
return Result.fail("服务降级");
}
@Override
public Result<ApiThirdPartyPlatformDetailResponse> detail(Long id) {
return Result.fail("服务降级");
}
@Override
public Result add(ApiThirdPartyPlatformAddRequest request) {
return Result.fail("服务降级");
}
@Override
public Result edit(ApiThirdPartyPlatformEditRequest request) {
return Result.fail("服务降级");
}
@Override
public Result del(Long id) {
return Result.fail("服务降级");
}
@Override
public Result editStatus(Long id, Integer status) {
return Result.fail("服务降级");
}
};
}
}
package com.yd.user.feign.fallback.thirdscanlogin;
import com.yd.common.result.Result;
import com.yd.user.feign.client.thirdscanlogin.ApiThirdPartyScanLoginFeignClient;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateLoginQrCodeRequest;
import com.yd.user.feign.request.thirdscanlogin.ApiVerifyTicketRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiScanStatusResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiVerifyTicketResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 扫码登录 Feign 降级
*/
@Slf4j
@Component
public class ApiThirdPartyScanLoginFeignFallbackFactory implements FallbackFactory<ApiThirdPartyScanLoginFeignClient> {
@Override
public ApiThirdPartyScanLoginFeignClient create(Throwable cause) {
log.error("扫码登录服务降级", cause);
return new ApiThirdPartyScanLoginFeignClient() {
@Override
public Result<ApiGenerateQrCodeResponse> generateLoginQrCode(ApiGenerateLoginQrCodeRequest request) {
return Result.fail("服务降级");
}
@Override
public String loginWechatCallback(String appId, String xml) {
return "success";
}
@Override
public Result<ApiScanStatusResponse> queryScanStatus(String qrId) {
return Result.fail("服务降级");
}
@Override
public Result<ApiVerifyTicketResponse> verifyTicket(ApiVerifyTicketRequest request) {
return Result.fail("服务降级");
}
@Override
public Result<Boolean> consumeTicket(ApiVerifyTicketRequest request) {
return Result.fail("服务降级");
}
};
}
}
package com.yd.user.feign.fallback.thirdscanlogin;
import com.yd.common.result.Result;
import com.yd.user.feign.client.thirdscanlogin.ApiUserThirdPartyBindFeignClient;
import com.yd.user.feign.request.thirdscanlogin.ApiGenerateShareBindQrCodeRequest;
import com.yd.user.feign.response.thirdscanlogin.ApiGenerateQrCodeResponse;
import com.yd.user.feign.response.thirdscanlogin.ApiUserThirdPartyBindResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
/**
* 用户第三方绑定 Feign 降级
*/
@Slf4j
@Component
public class ApiUserThirdPartyBindFeignFallbackFactory implements FallbackFactory<ApiUserThirdPartyBindFeignClient> {
@Override
public ApiUserThirdPartyBindFeignClient create(Throwable cause) {
log.error("用户第三方绑定服务降级", cause);
return new ApiUserThirdPartyBindFeignClient() {
@Override
public Result<ApiGenerateQrCodeResponse> generateShareBindQrCode(ApiGenerateShareBindQrCodeRequest request) {
return Result.fail("服务降级");
}
// @Override
// public String shareWechatCallback(String appId, String xml) {
// return "success";
// }
@Override
public Result<List<ApiUserThirdPartyBindResponse>> queryBind(String unionid, String projectBizId) {
return Result.success(Collections.emptyList());
}
@Override
public Result unbind(Long id) {
return Result.fail("服务降级");
}
};
}
}
package com.yd.user.feign.request.thirdpartyplatform;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* 项目绑定第三方平台请求
*/
@Data
public class ApiProjectThirdPartyBindRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 租户唯一业务ID
*/
private String tenantBizId;
/**
* 项目唯一业务ID
*/
@NotBlank(message = "项目ID不能为空")
private String projectBizId;
/**
* 项目名称
*/
private String projectName;
/**
* 平台编码
*/
@NotBlank(message = "平台编码不能为空")
private String platformCode;
/**
* 平台类型:1=公众号 2=小程序 3=网站
*/
private Integer platformType;
/**
* 备注
*/
private String remark;
}
package com.yd.user.feign.request.thirdpartyplatform;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 新增第三方平台配置请求
*/
@Data
public class ApiThirdPartyPlatformAddRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 平台编码,如 YD_GZH
*/
@NotBlank(message = "平台编码不能为空")
private String platformCode;
/**
* 平台名称
*/
@NotBlank(message = "平台名称不能为空")
private String platformName;
/**
* 平台类型:1=公众号 2=小程序 3=网站
*/
@NotNull(message = "平台类型不能为空")
private Integer platformType;
/**
* appId
*/
private String appId;
/**
* appSecret
*/
private String appSecret;
/**
* 微信服务器配置 Token
*/
private String token;
/**
* 微信服务器配置 EncodingAESKey
*/
private String encodingAesKey;
/**
* 固定公众号二维码地址
*/
private String gzhQrCodeUrl;
/**
* 状态:1=启用 0=禁用
*/
private Integer status = 1;
/**
* 备注
*/
private String remark;
}
package com.yd.user.feign.request.thirdpartyplatform;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 编辑第三方平台配置请求
*/
@Data
public class ApiThirdPartyPlatformEditRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@NotNull(message = "id不能为空")
private Long id;
/**
* 平台编码
*/
private String platformCode;
/**
* 平台名称
*/
private String platformName;
/**
* 平台类型
*/
private Integer platformType;
/**
* appId
*/
private String appId;
/**
* appSecret
*/
private String appSecret;
/**
* Token
*/
private String token;
/**
* EncodingAESKey
*/
private String encodingAesKey;
/**
* 固定公众号二维码地址
*/
private String gzhQrCodeUrl;
/**
* 状态
*/
private Integer status;
/**
* 备注
*/
private String remark;
}
package com.yd.user.feign.request.thirdpartyplatform;
import lombok.Data;
import java.io.Serializable;
/**
* 第三方平台配置分页查询请求
*/
@Data
public class ApiThirdPartyPlatformPageRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 页码
*/
private Integer pageNo = 1;
/**
* 每页条数
*/
private Integer pageSize = 10;
/**
* 平台编码,如 YD_GZH
*/
private String platformCode;
/**
* 平台名称,如 银盾公众号
*/
private String platformName;
/**
* 平台类型:1=公众号 2=小程序 3=网站
*/
private Integer platformType;
/**
* 状态:1=启用 0=禁用
*/
private Integer status;
}
package com.yd.user.feign.request.thirdscanlogin;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* 生成登录二维码请求
*/
@Data
public class ApiGenerateLoginQrCodeRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 租户唯一业务ID
*/
@NotBlank(message = "租户唯一业务ID不能为空")
private String tenantBizId;
/**
* 项目唯一业务ID
*/
@NotBlank(message = "项目ID不能为空")
private String projectBizId;
/**
* 项目名称
*/
private String projectName;
/**
* 平台类型:1=公众号 2=小程序 3=网站
*/
private Integer platformType = 1;
}
package com.yd.user.feign.request.thirdscanlogin;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 生成分享绑定二维码请求
*/
@Data
public class ApiGenerateShareBindQrCodeRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 租户唯一业务ID
*/
@NotBlank(message = "租户ID不能为空")
private String tenantBizId;
/**
* 项目唯一业务ID
*/
@NotBlank(message = "项目ID不能为空")
private String projectBizId;
/**
* 项目名称
*/
private String projectName;
/**
* 项目用户ID
*/
@NotBlank(message = "用户ID不能为空")
private String userId;
/**
* 项目用户手机号
*/
private String mobile;
/**
* 平台类型:1=公众号 2=小程序 3=网站
*/
@NotNull(message = "平台类型不能为空")
private Integer platformType = 1;
}
package com.yd.user.feign.request.thirdscanlogin;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* 校验 loginTicket 请求
*/
@Data
public class ApiVerifyTicketRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 二维码参数
*/
@NotBlank(message = "qrId不能为空")
private String qrId;
/**
* 一次性登录凭证
*/
@NotBlank(message = "loginTicket不能为空")
private String loginTicket;
/**
* 项目ID
*/
@NotBlank(message = "项目ID不能为空")
private String projectBizId;
}
package com.yd.user.feign.response.thirdpartyplatform;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 项目绑定第三方平台响应
*/
@Data
public class ApiProjectThirdPartyBindResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Long id;
/**
* 租户唯一业务ID
*/
private String tenantBizId;
/**
* 项目唯一业务ID
*/
private String projectBizId;
/**
* 项目名称
*/
private String projectName;
/**
* 平台编码
*/
private String platformCode;
/**
* 平台类型
*/
private Integer platformType;
/**
* 平台名称
*/
private String platformName;
/**
* 创建时间
*/
private LocalDateTime createTime;
}
package com.yd.user.feign.response.thirdpartyplatform;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 第三方平台配置详情响应
*/
@Data
public class ApiThirdPartyPlatformDetailResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Long id;
/**
* 平台编码
*/
private String platformCode;
/**
* 平台名称
*/
private String platformName;
/**
* 平台类型
*/
private Integer platformType;
/**
* appId
*/
private String appId;
/**
* appSecret
*/
private String appSecret;
/**
* Token
*/
private String token;
/**
* EncodingAESKey
*/
private String encodingAesKey;
/**
* 固定公众号二维码地址
*/
private String gzhQrCodeUrl;
/**
* 状态
*/
private Integer status;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
package com.yd.user.feign.response.thirdpartyplatform;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 第三方平台配置分页响应
*/
@Data
public class ApiThirdPartyPlatformPageResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Long id;
/**
* 平台编码
*/
private String platformCode;
/**
* 平台名称
*/
private String platformName;
/**
* 平台类型
*/
private Integer platformType;
/**
* appId
*/
private String appId;
/**
* 状态
*/
private Integer status;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
package com.yd.user.feign.response.thirdscanlogin;
import lombok.Data;
import java.io.Serializable;
/**
* 生成二维码响应
*/
@Data
public class ApiGenerateQrCodeResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 二维码参数
*/
private String qrId;
/**
* 二维码图片地址
*/
private String qrCodeUrl;
/**
* 过期秒数
*/
private Long expireSeconds;
}
package com.yd.user.feign.response.thirdscanlogin;
import lombok.Data;
import java.io.Serializable;
/**
* 扫码状态响应
*/
@Data
public class ApiScanStatusResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 二维码参数
*/
private String qrId;
/**
* 状态:待扫码/已扫码/已确认/已消费/已过期/已取消/未绑定/已禁用/已离职/无权限
*/
private String status;
/**
* 一次性登录凭证
*/
private String loginTicket;
/**
* 用户ID
*/
private String userId;
/**
* 项目ID
*/
private String projectBizId;
/**
* 提示信息
*/
private String message;
}
package com.yd.user.feign.response.thirdscanlogin;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户第三方绑定关系响应
*/
@Data
public class ApiUserThirdPartyBindResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Long id;
/**
* 租户唯一业务ID
*/
private String tenantBizId;
/**
* 项目唯一业务ID
*/
private String projectBizId;
/**
* 项目名称
*/
private String projectName;
/**
* 项目用户ID
*/
private String userId;
/**
* 项目用户手机号
*/
private String mobile;
/**
* 微信开放平台 unionid
*/
private String unionid;
/**
* 公众号 openid
*/
private String gzhOpenid;
/**
* 绑定来源
*/
private Integer bindSource;
/**
* 绑定状态
*/
private Integer bindStatus;
/**
* 绑定时间
*/
private LocalDateTime bindTime;
/**
* 解绑时间
*/
private LocalDateTime unbindTime;
}
package com.yd.user.feign.response.thirdscanlogin;
import lombok.Data;
import java.io.Serializable;
/**
* 校验 loginTicket 响应
*/
@Data
public class ApiVerifyTicketResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否有效
*/
private boolean valid;
/**
* 用户ID
*/
private String userId;
/**
* 项目ID
*/
private String projectBizId;
/**
* 提示信息
*/
private String message;
}
package com.yd.user.service.dao;
import com.yd.user.service.model.ProjectThirdPartyBind;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 项目和第三方平台绑定关系表 Mapper 接口
* </p>
*
* @author zxm
* @since 2026-10-13
*/
public interface ProjectThirdPartyBindMapper extends BaseMapper<ProjectThirdPartyBind> {
}
package com.yd.user.service.dao;
import com.yd.user.service.model.ThirdPartyPlatform;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 第三方平台基础配置表 Mapper 接口
* </p>
*
* @author zxm
* @since 2026-10-13
*/
public interface ThirdPartyPlatformMapper extends BaseMapper<ThirdPartyPlatform> {
}
package com.yd.user.service.dao;
import com.yd.user.service.model.UserThirdPartyBind;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户与第三方绑定关系表 Mapper 接口
* </p>
*
* @author zxm
* @since 2026-10-13
*/
public interface UserThirdPartyBindMapper extends BaseMapper<UserThirdPartyBind> {
}
package com.yd.user.service.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 项目和第三方平台绑定关系表
* </p>
*
* @author zxm
* @since 2026-10-13
*/
@Getter
@Setter
@TableName("project_third_party_bind")
public class ProjectThirdPartyBind implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 租户唯一业务ID
*/
@TableField("tenant_biz_id")
private String tenantBizId;
/**
* 项目唯一业务ID
*/
@TableField("project_biz_id")
private String projectBizId;
/**
* 项目名称
*/
@TableField("project_name")
private String projectName;
/**
* 关联 third_party_platform.platform_code
*/
@TableField("platform_code")
private String platformCode;
/**
* 平台类型,冗余方便查询:1=公众号 2=小程序 3=网站
*/
@TableField("platform_type")
private Integer platformType;
/**
* 通用备注
*/
@TableField("remark")
private String remark;
/**
* 删除标识: 0-正常, 1-删除
*/
@TableField("is_deleted")
private Integer isDeleted;
/**
* 创建人ID
*/
@TableField("creator_id")
private String creatorId;
/**
* 创建人名称
*/
@TableField("creator_name")
private String creatorName;
/**
* 更新人ID
*/
@TableField("updater_id")
private String updaterId;
/**
* 更新人名称
*/
@TableField("updater_name")
private String updaterName;
/**
* 创建时间
*/
@TableField("create_time")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField("update_time")
private LocalDateTime updateTime;
}
package com.yd.user.service.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 第三方平台基础配置表
* </p>
*
* @author zxm
* @since 2026-10-13
*/
@Getter
@Setter
@TableName("third_party_platform")
public class ThirdPartyPlatform implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 平台编码,如 YD_GZH、YD_MALL_MINI、YD_WEBSITE
*/
@TableField("platform_code")
private String platformCode;
/**
* 平台名称,如 银盾公众号、银盾家办商城小程序、银盾网站
*/
@TableField("platform_name")
private String platformName;
/**
* 平台类型:1=公众号 2=小程序 3=网站
*/
@TableField("platform_type")
private Integer platformType;
/**
* 公众号/小程序/应用 appId
*/
@TableField("app_id")
private String appId;
/**
* appSecret(加密存储)
*/
@TableField("app_secret")
private String appSecret;
/**
* 微信服务器配置 Token
*/
@TableField("token")
private String token;
/**
* 微信服务器配置 EncodingAESKey
*/
@TableField("encoding_aes_key")
private String encodingAesKey;
/**
* 固定公众号二维码地址
*/
@TableField("gzh_qr_code_url")
private String gzhQrCodeUrl;
/**
* 1=启用 0=禁用
*/
@TableField("status")
private Integer status;
/**
* 通用备注
*/
@TableField("remark")
private String remark;
/**
* 删除标识: 0-正常, 1-删除
*/
@TableField("is_deleted")
private Integer isDeleted;
/**
* 创建人ID
*/
@TableField("creator_id")
private String creatorId;
/**
* 创建人名称
*/
@TableField("creator_name")
private String creatorName;
/**
* 更新人ID
*/
@TableField("updater_id")
private String updaterId;
/**
* 更新人名称
*/
@TableField("updater_name")
private String updaterName;
/**
* 创建时间
*/
@TableField("create_time")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField("update_time")
private LocalDateTime updateTime;
}
package com.yd.user.service.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 用户与第三方绑定关系表
* </p>
*
* @author zxm
* @since 2026-10-13
*/
@Getter
@Setter
@TableName("user_third_party_bind")
public class UserThirdPartyBind implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 租户唯一业务ID
*/
@TableField("tenant_biz_id")
private String tenantBizId;
/**
* 项目唯一业务ID
*/
@TableField("project_biz_id")
private String projectBizId;
/**
* 项目名称
*/
@TableField("project_name")
private String projectName;
/**
* 项目用户ID
*/
@TableField("user_id")
private String userId;
/**
* 项目用户手机号
*/
@TableField("mobile")
private String mobile;
/**
* 微信开放平台 unionid
*/
@TableField("unionid")
private String unionid;
/**
* 公众号 openid
*/
@TableField("gzh_openid")
private String gzhOpenid;
/**
* 绑定来源 1-PC分享扫码绑定
*/
@TableField("bind_source")
private Integer bindSource;
/**
* 绑定状态 1=已绑定 0=已解绑
*/
@TableField("bind_status")
private Integer bindStatus;
/**
* 绑定时间
*/
@TableField("bind_time")
private LocalDateTime bindTime;
/**
* 解绑时间
*/
@TableField("unbind_time")
private LocalDateTime unbindTime;
/**
* 通用备注
*/
@TableField("remark")
private String remark;
/**
* 删除标识: 0-正常, 1-删除
*/
@TableField("is_deleted")
private Integer isDeleted;
/**
* 创建人ID
*/
@TableField("creator_id")
private String creatorId;
/**
* 创建人名称
*/
@TableField("creator_name")
private String creatorName;
/**
* 更新人ID
*/
@TableField("updater_id")
private String updaterId;
/**
* 更新人名称
*/
@TableField("updater_name")
private String updaterName;
/**
* 创建时间
*/
@TableField("create_time")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField("update_time")
private LocalDateTime updateTime;
}
package com.yd.user.service.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yd.user.service.model.ProjectThirdPartyBind;
/**
* 项目和第三方平台绑定关系表 服务类
*/
public interface IProjectThirdPartyBindService extends IService<ProjectThirdPartyBind> {
/**
* 根据项目ID和平台类型查询绑定关系
* @param tenantBizId 租户ID
* @param projectBizId 项目ID
* @param platformType 平台类型
* @return 绑定关系
*/
ProjectThirdPartyBind getByProjectAndType(String tenantBizId, String projectBizId, Integer platformType);
}
package com.yd.user.service.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yd.user.service.model.ThirdPartyPlatform;
/**
* 第三方平台基础配置表 服务类
*/
public interface IThirdPartyPlatformService extends IService<ThirdPartyPlatform> {
/**
* 根据 appId 查询平台配置
* @param appId 应用ID
* @return 平台配置
*/
ThirdPartyPlatform getByAppId(String appId);
/**
* 根据平台编码查询平台配置
* @param platformCode 平台编码
* @return 平台配置
*/
ThirdPartyPlatform getByPlatformCode(String platformCode);
}
package com.yd.user.service.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yd.user.service.model.UserThirdPartyBind;
import java.util.List;
/**
* 用户与第三方绑定关系表 服务类
*/
public interface IUserThirdPartyBindService extends IService<UserThirdPartyBind> {
/**
* 根据 unionid 和项目ID查询绑定关系
* @param unionid 微信unionid
* @param projectBizId 项目ID
* @return 绑定列表
*/
List<UserThirdPartyBind> queryByUnionidAndProject(String unionid, String projectBizId);
/**
* 根据 openid 和项目ID查询绑定关系
* @param openid 公众号openid
* @param projectBizId 项目ID
* @return 绑定关系
*/
UserThirdPartyBind queryByOpenidAndProject(String openid, String projectBizId);
/**
* 多条件查询绑定关系
* @param tenantBizId
* @param projectBizId
* @param unionid
* @param gzhOpenid
* @return
*/
UserThirdPartyBind queryBind(String tenantBizId,String projectBizId,String unionid,String gzhOpenid);
/**
* 绑定关系
* @param bind 绑定实体
* @return 是否成功
*/
boolean bind(UserThirdPartyBind bind);
/**
* 解绑
* @param id 主键
* @return 是否成功
*/
boolean unbind(Long id);
}
package com.yd.user.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yd.user.service.dao.ProjectThirdPartyBindMapper;
import com.yd.user.service.model.ProjectThirdPartyBind;
import com.yd.user.service.service.IProjectThirdPartyBindService;
import org.springframework.stereotype.Service;
/**
* 项目和第三方平台绑定关系表 服务实现类
*/
@Service
public class ProjectThirdPartyBindServiceImpl extends ServiceImpl<ProjectThirdPartyBindMapper, ProjectThirdPartyBind>
implements IProjectThirdPartyBindService {
@Override
public ProjectThirdPartyBind getByProjectAndType(String tenantBizId, String projectBizId, Integer platformType) {
return getOne(new LambdaQueryWrapper<ProjectThirdPartyBind>()
.eq(ProjectThirdPartyBind::getTenantBizId, tenantBizId)
.eq(ProjectThirdPartyBind::getProjectBizId, projectBizId)
.eq(ProjectThirdPartyBind::getPlatformType, platformType)
.eq(ProjectThirdPartyBind::getIsDeleted, 0));
}
}
package com.yd.user.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yd.user.service.dao.ThirdPartyPlatformMapper;
import com.yd.user.service.model.ThirdPartyPlatform;
import com.yd.user.service.service.IThirdPartyPlatformService;
import org.springframework.stereotype.Service;
/**
* 第三方平台基础配置表 服务实现类
*/
@Service
public class ThirdPartyPlatformServiceImpl extends ServiceImpl<ThirdPartyPlatformMapper, ThirdPartyPlatform>
implements IThirdPartyPlatformService {
@Override
public ThirdPartyPlatform getByAppId(String appId) {
return getOne(new LambdaQueryWrapper<ThirdPartyPlatform>()
.eq(ThirdPartyPlatform::getAppId, appId)
.eq(ThirdPartyPlatform::getStatus, 1)
.eq(ThirdPartyPlatform::getIsDeleted, 0));
}
@Override
public ThirdPartyPlatform getByPlatformCode(String platformCode) {
return getOne(new LambdaQueryWrapper<ThirdPartyPlatform>()
.eq(ThirdPartyPlatform::getPlatformCode, platformCode)
.eq(ThirdPartyPlatform::getStatus, 1)
.eq(ThirdPartyPlatform::getIsDeleted, 0));
}
}
package com.yd.user.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yd.user.service.dao.UserThirdPartyBindMapper;
import com.yd.user.service.model.UserThirdPartyBind;
import com.yd.user.service.service.IUserThirdPartyBindService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
/**
* 用户与第三方绑定关系表 服务实现类
*/
@Service
public class UserThirdPartyBindServiceImpl extends ServiceImpl<UserThirdPartyBindMapper, UserThirdPartyBind>
implements IUserThirdPartyBindService {
@Override
public List<UserThirdPartyBind> queryByUnionidAndProject(String unionid, String projectBizId) {
return list(new LambdaQueryWrapper<UserThirdPartyBind>()
.eq(UserThirdPartyBind::getUnionid, unionid)
.eq(UserThirdPartyBind::getProjectBizId, projectBizId)
.eq(UserThirdPartyBind::getBindStatus, 1)
.eq(UserThirdPartyBind::getIsDeleted, 0));
}
@Override
public UserThirdPartyBind queryByOpenidAndProject(String openid, String projectBizId) {
return getOne(new LambdaQueryWrapper<UserThirdPartyBind>()
.eq(UserThirdPartyBind::getGzhOpenid, openid)
.eq(UserThirdPartyBind::getProjectBizId, projectBizId)
.eq(UserThirdPartyBind::getBindStatus, 1)
.eq(UserThirdPartyBind::getIsDeleted, 0));
}
/**
* 多条件查询绑定关系
* @param tenantBizId
* @param projectBizId
* @param unionid
* @param gzhOpenid
* @return
*/
@Override
public UserThirdPartyBind queryBind(String tenantBizId, String projectBizId, String unionid, String gzhOpenid) {
return getOne(new LambdaQueryWrapper<UserThirdPartyBind>()
.eq(UserThirdPartyBind::getTenantBizId, tenantBizId)
.eq(UserThirdPartyBind::getProjectBizId, projectBizId)
.eq(UserThirdPartyBind::getUnionid, unionid)
.eq(UserThirdPartyBind::getGzhOpenid, gzhOpenid)
.eq(UserThirdPartyBind::getBindStatus, 1)
.eq(UserThirdPartyBind::getIsDeleted, 0)
.last(" limit 1 "));
}
@Override
public boolean bind(UserThirdPartyBind bind) {
bind.setBindTime(LocalDateTime.now());
bind.setBindStatus(1);
bind.setIsDeleted(0);
return save(bind);
}
@Override
public boolean unbind(Long id) {
UserThirdPartyBind bind = getById(id);
if (bind == null) return false;
bind.setBindStatus(0);
bind.setUnbindTime(LocalDateTime.now());
return updateById(bind);
}
}
......@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
public class MyBatisPlusCodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://139.224.145.34:3308/yd?serverTimezone=GMT%2B8", "root", "Zxm7320017")
FastAutoGenerator.create("jdbc:mysql://139.224.145.34:3308/yd?serverTimezone=GMT%2B8", "root", "csF@dev#0920!")
.globalConfig(builder -> {
builder.author("zxm")
// .outputDir("src/main/java/com/yd/user/service");
......@@ -21,7 +21,7 @@ public class MyBatisPlusCodeGenerator {
})
.strategyConfig(builder -> {
builder.addInclude(
"user_sign_expand","user_sale_expand"
"third_party_platform","project_third_party_bind"
// "rel_dept_user", "rel_group_role", "rel_group_user",
// "rel_project_menu", "rel_project_role", "rel_project_user",
// "rel_project_user_group", "rel_role_menu", "rel_tenant_dept",
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd.user.service.dao.ProjectThirdPartyBindMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd.user.service.dao.ThirdPartyPlatformMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd.user.service.dao.UserThirdPartyBindMapper">
</mapper>
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