企微开发目录

master
wujingtao 2 years ago
parent bb81651c9e
commit c5e7cc1461

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cdp-wechat</artifactId>
<groupId>com.baiye</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cdp-wechat-api</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<exclusions>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>cdp-common-exception</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>cdp-wechat-server</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>cdp-common-mybatis-plus</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>cdp-common-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,69 @@
package com.baiye.aop;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.core.constant.AppConstant;
import com.baiye.core.util.AppUtils;
import com.baiye.exception.global.BadRequestException;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @author Enzo
* @date : 2022/6/28
*/
@Aspect
@Component
@RequiredArgsConstructor
public class LogAdvice {
@Pointcut("execution(public * com.baiye.foreignController.WechatController.*(..))")
private void logAdvicePointcut() {
}
@SneakyThrows
@Before("logAdvicePointcut()")
public void logAdvice(JoinPoint joinPoint) {
HttpServletRequest request = getHttpServletRequest();
String appKey = request.getParameter(AppConstant.APP_KEY);
String appSecret = request.getParameter(AppConstant.APP_SECRET);
if (StringUtils.isBlank(appKey) && StringUtils.isBlank(appSecret)) {
Object[] args = joinPoint.getArgs();
JSONObject jsonObject = new JSONObject(JSONUtil.toJsonStr(args[0]));
if (jsonObject.get(AppConstant.APP_KEY) != null) {
appKey = jsonObject.get(AppConstant.APP_KEY).toString();
}
if (jsonObject.get(AppConstant.APP_SECRET) != null) {
appSecret = jsonObject.get(AppConstant.APP_SECRET).toString();
}
}
if (StringUtils.isBlank(appKey) || StringUtils.isBlank(appSecret)) {
throw new BadRequestException("appKey与appSecret不能为空");
}
String parseSecret = AppUtils.getAppSecret(appKey);
if (!appSecret.equalsIgnoreCase(parseSecret)) {
throw new BadRequestException("appKey与appSecret解析失败!");
}
}
private HttpServletRequest getHttpServletRequest() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
return attributes.getRequest();
}
}

@ -0,0 +1,217 @@
package com.baiye.aop;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import com.baiye.core.annotation.Log;
import com.baiye.core.util.IPUtil;
import com.baiye.core.util.RequestUtils;
import com.baiye.entity.CommonLog;
import com.baiye.event.LogEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author pangu
*/
@Slf4j
@Aspect
@Component
public class LogAspect {
@Autowired
private final ApplicationContext applicationContext;
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
public LogAspect(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Pointcut("@annotation(com.baiye.core.annotation.Log)")
public void pointcut() {
}
/**
* ,使logPointcut()
*
* @param point
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object recordLog(ProceedingJoinPoint point) throws Throwable {
Object result;
// 获取request
HttpServletRequest request = RequestUtils.getHttpServletRequest();
// 判断为空则直接跳过执行
if (ObjectUtils.isEmpty(request)) {
return point.proceed();
}
// 获取注解里的value值
Method targetMethod = resolveMethod(point);
Log logAnn = targetMethod.getAnnotation(Log.class);
// 打印执行时间
long startTime = System.nanoTime();
// 请求方法
String method = request.getMethod();
String url = request.getRequestURI();
// 获取IP和地区
String ip = RequestUtils.getIp();
String region = IPUtil.getCityInfo(ip);
//获取请求参数
//Map<String, Object> paramMap = logIngArgs(point);
// 参数
Object[] args = point.getArgs();
String requestParam = getArgs(args, request);
// 计算耗时
long tookTime = 0L;
try {
result = point.proceed();
} finally {
tookTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);
}
// 封装SysLog
CommonLog commonLog = new CommonLog();
commonLog.setIp(ip)
.setMethod(method)
.setUrl(url)
.setOperation(String.valueOf(result))
.setLocation(StringUtils.isEmpty(region) ? "本地" : region)
.setExecuteTime(tookTime)
.setTitle(logAnn.value())
.setParams(JSONUtil.toJsonStr(requestParam));
log.info("Http Request: {}", JSONUtil.toJsonStr(commonLog));
// 发布事件
applicationContext.publishEvent(new LogEvent(commonLog));
return result;
}
/**
*
*
* @param point join point for advice
* @param e exception
*/
@AfterThrowing(pointcut = "pointcut()", throwing = "e")
public void logAfterThrowing(JoinPoint point, Throwable e) {
// 打印执行时间
long startTime = System.nanoTime();
CommonLog commonLog = new CommonLog();
// 获取IP和地区
String ip = RequestUtils.getIp();
String region = IPUtil.getCityInfo(ip);
// 获取request
HttpServletRequest request = RequestUtils.getHttpServletRequest();
// 请求方法
String method = request.getMethod();
String url = request.getRequestURI();
// 获取注解里的value值
Method targetMethod = resolveMethod((ProceedingJoinPoint) point);
Log logAnn = targetMethod.getAnnotation(Log.class);
commonLog.setExecuteTime
(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)).setIp(ip)
.setLocation(region)
.setMethod(method)
.setUrl(url)
.setType("2")
.setTitle(logAnn.value());
// 发布事件
applicationContext.publishEvent(new LogEvent(commonLog));
log.info("Error Result: {}", commonLog);
}
private Method resolveMethod(ProceedingJoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
Class<?> targetClass = point.getTarget().getClass();
Method method = getDeclaredMethod(targetClass, signature.getName(),
signature.getMethod().getParameterTypes());
if (method == null) {
throw new IllegalStateException("无法解析目标方法: " + signature.getMethod().getName());
}
return method;
}
private Method getDeclaredMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
try {
return clazz.getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException e) {
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
return getDeclaredMethod(superClass, name, parameterTypes);
}
}
return null;
}
/**
*
*
* @param args args
* @param request request
* @return
*/
private String getArgs(Object[] args, HttpServletRequest request) {
String strArgs = CharSequenceUtil.EMPTY;
try {
if (!request.getContentType().contains("multipart/form-data")) {
strArgs = JSONUtil.toJsonStr(args);
}
} catch (Exception e) {
try {
strArgs = Arrays.toString(args);
} catch (Exception ex) {
log.warn("解析参数异常", ex);
}
}
return strArgs;
}
/**
*
*
* @param method
* @param parameterIndex
* @return {MethodParameter}
*/
public static MethodParameter getMethodParameter(Method method, int parameterIndex) {
MethodParameter methodParameter = new SynthesizingMethodParameter(method, parameterIndex);
methodParameter.initParameterNameDiscovery(PARAMETER_NAME_DISCOVERER);
return methodParameter;
}
}

@ -0,0 +1,19 @@
package com.baiye.event;
import com.baiye.entity.CommonLog;
import org.springframework.context.ApplicationEvent;
/**
*
*
* @author pangu 7333791@qq.com
* @since 2020-7-15
*/
public class LogEvent extends ApplicationEvent {
private static final long serialVersionUID = 4848619607994751366L;
public LogEvent(CommonLog source) {
super(source);
}
}

@ -0,0 +1,34 @@
package com.baiye.event;
import com.baiye.dao.CommonLogMapper;
import com.baiye.entity.CommonLog;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
*
*
* @author pangu 7333791@qq.com
* @since 2020-7-15
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class LogListener {
private final CommonLogMapper commonLogMapper;
@Async
@Order
@EventListener(LogEvent.class)
public void saveSysLog(LogEvent event) {
CommonLog commonLog = (CommonLog) event.getSource();
commonLogMapper.insert(commonLog);
}
}

@ -0,0 +1,39 @@
package com.baiye.foreignController;
import com.baiye.core.base.api.Result;
import com.baiye.core.constant.WeChatResponse;
import com.baiye.service.WeChatUserService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Enzo
* @date : 2022/6/24
*/
@Slf4j
@RestController
@Api(tags = "微信回调")
@RequestMapping("/wechat")
@RequiredArgsConstructor
public class WeChatCallbackController {
private final WeChatUserService weChatUserService;
/**
*
*
* @return
*/
@PostMapping(value = "/callback")
public Result<String> frontRcvResponse(@RequestBody WeChatResponse weChatResponse) {
weChatUserService.analyticalData(weChatResponse);
return Result.success();
}
}

@ -0,0 +1,81 @@
package com.baiye.foreignController;
import cn.hutool.core.collection.CollUtil;
import com.baiye.core.annotation.Log;
import com.baiye.core.base.api.Result;
import com.baiye.core.base.api.ResultCode;
import com.baiye.entity.dto.WeChatAddBulkFriendDTO;
import com.baiye.entity.dto.WeChatAddFriendDTO;
import com.baiye.entity.dto.WeChatFriendInfoDTO;
import com.baiye.service.WeChatUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
*
* @author wjt
* @date 2022/07/08
*/
@Validated
@RestController
@Api(tags = "微信相关接口")
@RequestMapping("/wechat")
@RequiredArgsConstructor
public class WechatController {
private final WeChatUserService weChatUserService;
@Log("获取二维码")
@ApiOperation("获取二维码")
@GetMapping("/getQrCode")
public Result<String> getQrCode(String wechatId, String uuid, String appKey, String appSecret) {
return weChatUserService.getQrCode(wechatId, uuid, appKey, appSecret);
}
@Log("添加好友")
@ApiOperation("添加好友")
@PostMapping("/addFriend")
public Result<Object> addFriend
(@Validated @RequestBody WeChatAddFriendDTO weChatFriendDTO) {
return weChatUserService.addFriend(weChatFriendDTO);
}
@Log("添加好友")
@ApiOperation("是否在线")
@GetMapping("/onlineStatus")
public Result<Object> onlineStatus(String wechat, Integer loginType,
Boolean needDetailInfo, String randomId) {
return weChatUserService.isOnlineByWechat(wechat, loginType, needDetailInfo, randomId);
}
@Log("获取好友信息")
@ApiOperation("friendInfo")
@PostMapping("/friendInfo")
public Result<Object> friendInfo
(@Validated @RequestBody WeChatFriendInfoDTO weChatFriendInfoDTO) {
return weChatUserService.friendInfo(weChatFriendInfoDTO);
}
@Log("批量添加好友")
@ApiOperation("批量添加好友")
@PostMapping("/bulkAddFriend")
public Result<List<String>> bulkAddFriend
(@Validated @RequestBody WeChatAddBulkFriendDTO bulkFriendDTO) {
if (CollUtil.isEmpty(bulkFriendDTO.getWeChatList())) {
return Result.fail
(ResultCode.WE_CHAT_COLLECTION_EMPTY.getMsg());
}
return weChatUserService.addBulkFriend(bulkFriendDTO);
}
}

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cdp-wechat</artifactId>
<groupId>com.baiye</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cdp-wechat-server</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<exclusions>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>cdp-common-exception</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>cdp-common-mybatis-plus</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>cdp-common-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,15 @@
package com.baiye.dao;
import com.baiye.entity.AppUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @author wjt
* @date 2022/07/13
*/
@Mapper
public interface AppUserMapper extends BaseMapper<AppUser> {
AppUser findByAppKey(@Param("appKey") String appKey);
}

@ -0,0 +1,11 @@
package com.baiye.dao;
import com.baiye.entity.CommonLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author wjt
* @date 2022/07/13
*/
public interface CommonLogMapper extends BaseMapper<CommonLog> {
}

@ -0,0 +1,16 @@
package com.baiye.dao;
import com.baiye.entity.QrCodeRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author wjt
* @date 2022/07/13
*/
public interface QrCodeRecordMapper extends BaseMapper<QrCodeRecord> {
List<QrCodeRecord> findByUuid(@Param("uuid") String uuid);
}

@ -0,0 +1,13 @@
package com.baiye.dao;
import com.baiye.entity.WeChatCallbackLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author wjt
* @date 2022/07/13
*/
@Mapper
public interface WeChatCallbackLogMapper extends BaseMapper<WeChatCallbackLog> {
}

@ -0,0 +1,54 @@
package com.baiye.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.util.Date;
/**
* @author Enzo
* @date : 2022/6/30
*/
@Data
@TableName("app_user")
@Accessors(chain = true)
@ApiModel(value = "CommonLog对象", description = "app_user")
public class AppUser {
@ApiModelProperty(value = "普通日志主键id自动递增")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@Column(name = "app_key")
@ApiModelProperty(value = "appKey")
private String appKey;
@Column(name = "app_secret")
@ApiModelProperty(value = "appSecret")
private String appSecret;
@Column(name = "company_flag")
@ApiModelProperty(value = "公司标识")
private String companyFlag;
@CreationTimestamp
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
@Column(name = "callback_url")
@ApiModelProperty(value = "回调地址")
private String callbackUrl;
@Column(name = "status")
@ApiModelProperty(value = "状态值")
private Integer status;
}

@ -0,0 +1,100 @@
package com.baiye.entity;
import com.baiye.core.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
*
*
* @author xuzhanfu
*/
@Data
@TableName("tb_source")
@Accessors(chain = true)
@ApiModel(value = "CommonLog对象", description = "普通日志封装")
public class CommonLog extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "普通日志主键id自动递增")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
@ApiModelProperty(value = "日志类型")
private String type;
/**
* ID
*/
@ApiModelProperty(value = "跟踪ID")
private String traceId;
/**
*
*/
@ApiModelProperty(value = "日志标题")
private String title;
/**
*
*/
@ApiModelProperty(value = "操作内容")
private String operation;
/**
*
*/
@ApiModelProperty(value = "执行方法")
private String method;
/**
*
*/
@ApiModelProperty(value = "请求路径")
private String url;
/**
*
*/
@ApiModelProperty(value = "参数")
private String params;
/**
* ip
*/
@ApiModelProperty(value = "ip地址")
private String ip;
/**
*
*/
@ApiModelProperty(value = "耗时")
private Long executeTime;
/**
*
*/
@ApiModelProperty(value = "地区")
private String location;
/**
*
*/
@ApiModelProperty(value = "删除标识")
private String isDeleted;
/**
* ID
*/
@ApiModelProperty(value = "租户ID")
private Integer tenantId;
/**
*
*/
@ApiModelProperty(value = "异常信息")
private String exception;
}

@ -0,0 +1,55 @@
package com.baiye.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author Enzo
* @date : 2022/6/29
*/
@Data
@TableName("tb_qr_code_record")
@Accessors(chain = true)
@ApiModel(value = "QrCodeRecord对象", description = "获取二维码请求")
public class QrCodeRecord implements Serializable {
private static final long serialVersionUID = -4781283127753278046L;
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID")
private Long id;
@Column(name = "uuid")
@ApiModelProperty(value = "uuid")
private String uuid;
@Column(name = "qr_url")
@ApiModelProperty(value = "二维码地址")
private String qrUrl;
@Column(name = "app_key")
@ApiModelProperty(value = "appKey")
private String appKey;
@Column(name = "wechat_id")
@ApiModelProperty(value = "微信id")
private String wechatId;
@Column(name = "callback_url")
@ApiModelProperty(value = "回调接口")
private String callbackUrl;
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

@ -0,0 +1,54 @@
package com.baiye.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.persistence.*;
import java.util.Date;
/**
* @author Enzo
* @date : 2022/6/30
*/
@Data
@TableName("tb_we_chat_callback_log")
@Accessors(chain = true)
@ApiModel(value = "CommonLog对象", description = "普通日志封装")
public class WeChatCallbackLog {
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID")
private Long id;
/**
*
*/
@Column(name = "status")
@ApiModelProperty(value = "回调状态")
private Integer status;
/**
*
*/
@Column(name = "cus_qr_uu_id")
@ApiModelProperty(value = "标识")
private String cusQrUuId;
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
*
*/
@Column(name = "call_str")
@ApiModelProperty(value = "回调内容")
private String callStr;
}

@ -0,0 +1,40 @@
package com.baiye.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NonNull;
import java.util.List;
/**
* @author Enzo
* @date : 2022/6/27
*/
@Data
public class WeChatAddBulkFriendDTO {
@NonNull
@ApiModelProperty(value = "机器人微信号码")
private String wechat;
@NonNull
@ApiModelProperty(value = "添加类型 0-手机号 1-微信号")
private Integer type;
@ApiModelProperty(value = "添加微信关键字(微信号、手机号)集合")
private List<String> weChatList;
@NonNull
@ApiModelProperty(value = "打招呼、验证的内容")
private String helloContent;
@NonNull
@ApiModelProperty(value = "appKey")
private String appKey;
@NonNull
@ApiModelProperty(value = "appKey")
private String appSecret;
}

@ -0,0 +1,39 @@
package com.baiye.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NonNull;
/**
* @author Enzo
* @date : 2022/6/27
*/
@Data
public class WeChatAddFriendDTO {
@NonNull
@ApiModelProperty(value = "机器人微信号码")
private String wechat;
@NonNull
@ApiModelProperty(value = "添加类型 0-手机号 1-微信号")
private Integer type;
@NonNull
@ApiModelProperty(value = "添加微信关键字(微信号、手机号)")
private String tagetWxId;
@NonNull
@ApiModelProperty(value = "打招呼、验证的内容")
private String helloContent;
@NonNull
@ApiModelProperty(value = "appKey")
private String appKey;
@NonNull
@ApiModelProperty(value = "appKey")
private String appSecret;
}

@ -0,0 +1,32 @@
package com.baiye.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NonNull;
/**
* @author Enzo
* @date : 2022/6/27
*/
@Data
public class WeChatFriendInfoDTO {
@NonNull
@ApiModelProperty(value = "机器人微信号码")
private String wechat;
@NonNull
@ApiModelProperty(value = "添加微信关键字(微信号、手机号)")
private String targetWx;
@NonNull
@ApiModelProperty(value = "appKey")
private String appKey;
@NonNull
@ApiModelProperty(value = "appKey")
private String appSecret;
}

@ -0,0 +1,51 @@
package com.baiye.entity.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author Enzo
* @date : 2022/6/30
*/
@Data
public class WeChatUserLoginDTO implements Serializable {
private String cusQrUuId;
private Integer loginType;
private Boolean newDevice;
private String qrCodeKey;
private Boolean newWxLogin;
private String wxid;
private String serverid;
private Boolean second;
private Integer protoVer;
private String randomid;
private String wxdat;
private String softwareId;
private Integer sourceType;
private String qrCodeUrl;
private String host;
private String nickname;
private Integer strategy;
private String usercode;
}

@ -0,0 +1,24 @@
package com.baiye.entity.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author Enzo
* @date : 2022/6/28
*/
@Data
public class WeChatUserLoginFailDTO extends WeChatUserLoginDTO implements Serializable {
private static final long serialVersionUID = -3405251435086857475L;
private Integer ret;
private String result;
private String uniquekey;
}

@ -0,0 +1,24 @@
package com.baiye.entity.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author Enzo
* @date : 2022/6/28
*/
@Data
public class WeChatUserLoginSuccessDTO extends WeChatUserLoginDTO implements Serializable {
private static final long serialVersionUID = -3405251435086857475L;
private String account;
private String token;
private String smallHeadImgUrl;
}

@ -0,0 +1,22 @@
package com.baiye.properties;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author Enzo
* @date : 2022/6/24
*/
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "wechat")
public class WeChatProperties {
@ApiModelProperty("请求地址")
private String gatewayHost;
}

@ -0,0 +1,72 @@
package com.baiye.service;
import com.baiye.core.base.api.Result;
import com.baiye.core.constant.WeChatResponse;
import com.baiye.entity.dto.WeChatAddBulkFriendDTO;
import com.baiye.entity.dto.WeChatAddFriendDTO;
import com.baiye.entity.dto.WeChatFriendInfoDTO;
import java.util.List;
/**
* @author Enzo
* @date : 2022/6/23
*/
public interface WeChatUserService {
/**
*
*
* @param wechatId
* @param uuid
* @param appKey
* @param appSecret
* @return
*/
Result<String> getQrCode(String wechatId, String uuid, String appKey, String appSecret);
/**
*
*
* @param weChatResponse
*/
void analyticalData(WeChatResponse weChatResponse);
/**
*
*
* @param weChatFriendDTO
* @return
*/
Result<Object> addFriend(WeChatAddFriendDTO weChatFriendDTO);
/**
*
*
* @param bulkFriendDTO
* @return
*/
Result<List<String>> addBulkFriend(WeChatAddBulkFriendDTO bulkFriendDTO);
/**
* 线
*
* @param wechat
* @param loginType
* @param needDetailInfo
* @param randomId
* @return
*/
Result<Object> isOnlineByWechat(String wechat, Integer loginType, Boolean needDetailInfo, String randomId);
/**
*
*
* @param weChatFriendInfoDTO
* @return
*/
Result<Object> friendInfo(WeChatFriendInfoDTO weChatFriendInfoDTO);
}

@ -0,0 +1,225 @@
package com.baiye.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baiye.core.base.api.Result;
import com.baiye.core.base.api.ResultCode;
import com.baiye.core.constant.WeChatRequestConstants;
import com.baiye.core.constant.WeChatResponse;
import com.baiye.core.util.DesUtil;
import com.baiye.dao.AppUserMapper;
import com.baiye.dao.QrCodeRecordMapper;
import com.baiye.dao.WeChatCallbackLogMapper;
import com.baiye.entity.AppUser;
import com.baiye.entity.QrCodeRecord;
import com.baiye.entity.WeChatCallbackLog;
import com.baiye.entity.dto.*;
import com.baiye.exception.global.BadRequestException;
import com.baiye.properties.WeChatProperties;
import com.baiye.service.WeChatUserService;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import static javax.security.auth.callback.ConfirmationCallback.INFORMATION;
import static org.aspectj.apache.bcel.Constants.GETSTATIC2_QUICK;
/**
* @author Enzo
* @date : 2022/6/23
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WeChatUserServiceImpl implements WeChatUserService {
private final WeChatProperties weChatProperties;
private final AppUserMapper appUserMapper;
private final QrCodeRecordMapper qrCodeRecordMapper;
private final WeChatCallbackLogMapper weChatCallbackLogMapper;
@Override
public Result<String> getQrCode(String wechatId, String uuid, String appKey, String appSecret) {
if (StringUtils.isBlank(wechatId) && StringUtils.isBlank(uuid)) {
throw new BadRequestException(ResultCode.PARAMETER_ERROR.getMsg());
}
log.info("============== uuid as {} ================", uuid);
Map<String, Object> getQrCodeMap = Maps.newConcurrentMap();
QrCodeRecord qrCodeRecord = new QrCodeRecord();
qrCodeRecord.setUuid(uuid);
getQrCodeMap.put("uuid", uuid);
if (StringUtils.isNotBlank(wechatId)) {
getQrCodeMap.put("wechat", wechatId);
getQrCodeMap.remove("uuid");
qrCodeRecord.setWechatId(wechatId);
}
qrCodeRecord.setAppKey(DesUtil.getEncryptData(appKey));
String getQrCodeResult = HttpUtil.get
(weChatProperties.getGatewayHost().
concat(WeChatRequestConstants.GET_QR_CODE), getQrCodeMap);
if (StringUtils.isNotBlank(getQrCodeResult)) {
WeChatResponse weChatResponse =
JSONUtil.toBean(getQrCodeResult, WeChatResponse.class);
String msg = weChatResponse.getMsg();
qrCodeRecord.setQrUrl(msg);
qrCodeRecordMapper.insert(qrCodeRecord);
return Result.success(msg);
}
throw new BadRequestException(ResultCode.QR_CODE_GENERATION_FAILED.getMsg());
}
@Override
public Result<Object> addFriend(WeChatAddFriendDTO weChatFriendDTO) {
Map<String, Object> map = BeanUtil.beanToMap(weChatFriendDTO);
String addedFriendResult = HttpUtil.post
(weChatProperties.getGatewayHost().
concat(WeChatRequestConstants.WE_CHAT_ADD_FRIEND), map);
if (addedFriendResult.contains(ResultCode.SUCCESS.getMsg())) {
WeChatResponse weChatResponse =
JSONUtil.toBean(addedFriendResult, WeChatResponse.class);
if (weChatResponse.getStatus() == HttpStatus.HTTP_OK) {
return Result.data(weChatResponse.getData());
}
return Result.fail(ResultCode.FAILED_ADD_FRIEND.getMsg());
}
return Result.fail();
}
/**
* @param bulkFriendDTO
* @return
* @date 2022-7-4
* @deprecated
*/
@Override
public Result<List<String>> addBulkFriend(WeChatAddBulkFriendDTO bulkFriendDTO) {
List<String> resultList = Lists.newArrayList();
if (!CollUtil.isEmpty(bulkFriendDTO.getWeChatList())) {
Map<String, Object> bulkFriendMap = Maps.newConcurrentMap();
bulkFriendMap.put("type", bulkFriendDTO.getType());
bulkFriendMap.put("wechat", bulkFriendDTO.getWechat());
bulkFriendMap.put("helloContent", bulkFriendDTO.getHelloContent());
for (String wechatId : bulkFriendDTO.getWeChatList()) {
bulkFriendMap.put("tagetWxId", wechatId);
String bulkFriendResult = HttpUtil.post
(weChatProperties.getGatewayHost().
concat(WeChatRequestConstants.WE_CHAT_ADD_FRIEND), bulkFriendMap);
if (bulkFriendResult.contains(ResultCode.SUCCESS.getMsg())) {
WeChatResponse weChatResponse =
JSONUtil.toBean(bulkFriendResult, WeChatResponse.class);
if (weChatResponse.getStatus() == HttpStatus.HTTP_OK) {
continue;
}
resultList.add(wechatId.concat(StrPool.COLON).concat(weChatResponse.getMsg()));
}
}
}
return CollUtil.isEmpty(resultList)
? Result.success()
: Result.data(resultList);
}
@Override
public void analyticalData(WeChatResponse weChatResponse) {
Map<String, Object> map = Maps.newHashMap();
// 处理登录请求
if (weChatResponse.getStatus() == HttpStatus.HTTP_CREATED
|| weChatResponse.getStatus() == GETSTATIC2_QUICK) {
WeChatCallbackLog callbackLog = new WeChatCallbackLog();
WeChatUserLoginDTO userLoginDTO = weChatResponse.getStatus() == HttpStatus.HTTP_CREATED ?
JSONUtil.toBean(JSONUtil.toJsonStr(weChatResponse.getData()),
WeChatUserLoginSuccessDTO.class)
: JSONUtil.toBean(JSONUtil.toJsonStr(weChatResponse.getData()),
WeChatUserLoginFailDTO.class);
String cusQrUuId = userLoginDTO.getCusQrUuId();
if (weChatResponse.getStatus() == GETSTATIC2_QUICK && cusQrUuId.contains(StrPool.COLON)) {
cusQrUuId = cusQrUuId.substring(INFORMATION, cusQrUuId.indexOf(StrPool.COLON)).trim();
userLoginDTO.setCusQrUuId(cusQrUuId);
}
map.put("msg", weChatResponse.getMsg());
map.put("data", userLoginDTO);
map.put("status", weChatResponse.getStatus());
// 插入日志
callbackLog.setCusQrUuId(cusQrUuId);
callbackLog.setCreateTime(DateUtil.date());
callbackLog.setStatus(weChatResponse.getStatus());
callbackLog.setCallStr(JSONUtil.toJsonStr(weChatResponse));
weChatCallbackLogMapper.insert(callbackLog);
log.info("============= the response as {} ==========", JSONUtil.toJsonStr(weChatResponse));
List<QrCodeRecord> byUuid = qrCodeRecordMapper.findByUuid(cusQrUuId);
if (CollUtil.isNotEmpty(byUuid) && StringUtils.isNotBlank(byUuid.get(0).getAppKey())) {
String appKey = byUuid.get(0).getAppKey();
if (StringUtils.isNotBlank(appKey)) {
AppUser byAppKey = appUserMapper.findByAppKey(appKey.trim());
HttpUtil.post(byAppKey.getCallbackUrl(), JSONUtil.toJsonStr(map));
log.info("============= the send callback success uuid as {} date as {} ============", cusQrUuId, DateUtil.date());
}
}
}
}
@Override
public Result<Object> isOnlineByWechat
(String wechat, Integer loginType, Boolean needDetailInfo, String randomId) {
Map<String, Object> map = Maps.newHashMap();
map.put("loginType", loginType);
map.put("needDetailInfo", needDetailInfo);
if (StringUtils.isNotBlank(wechat)) {
map.put("wechat", wechat);
}
if (StringUtils.isNotBlank(randomId)) {
map.put("randomId", randomId);
}
// 发送请求
String onlineByWechat = HttpUtil.get
(weChatProperties.getGatewayHost().
concat(WeChatRequestConstants.WE_CHAT_STATUS), map);
if (onlineByWechat.contains(ResultCode.SUCCESS.getMsg())) {
WeChatResponse weChatResponse =
JSONUtil.toBean(onlineByWechat, WeChatResponse.class);
return Result.data(weChatResponse.getData());
}
return Result.fail
(ResultCode.FAILED_FRIEND_INFO.getMsg());
}
@Override
public Result<Object> friendInfo(WeChatFriendInfoDTO weChatFriendInfoDTO) {
Map<String, Object> map =
ImmutableMap.of("wechat", weChatFriendInfoDTO.getWechat(),
"targetWx", weChatFriendInfoDTO.getTargetWx(), "type", 1);
// 发送请求
String friendsInfo = HttpUtil.post
(weChatProperties.getGatewayHost().
concat(WeChatRequestConstants.WE_CHAT_FRIEND_INFORMATION), map);
if (friendsInfo.contains(ResultCode.SUCCESS.getMsg())) {
WeChatResponse weChatResponse =
JSONUtil.toBean(friendsInfo, WeChatResponse.class);
return Result.data(weChatResponse.getData());
}
return Result.fail
(ResultCode.FAILED_FRIEND_INFO.getMsg());
}
}

@ -0,0 +1,18 @@
<?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.baiye.dao.AppUserMapper">
<resultMap id="appUserMap" type="com.baiye.entity.AppUser">
<id column="id" property="id"/>
</resultMap>
<select id="findByAppKey" resultType="com.baiye.entity.AppUser">
select * from app_user
<where>
<if test="appKey!=null ">
and app_key = #{appKey}
</if>
</where>
</select>
</mapper>

@ -0,0 +1,18 @@
<?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.baiye.dao.QrCodeRecordMapper">
<resultMap id="qrCodeRecordMap" type="com.baiye.entity.QrCodeRecord">
<id column="id" property="id"/>
</resultMap>
<select id="findByUuid" resultType="com.baiye.entity.QrCodeRecord">
select * from tb_qr_code_record
<where>
<if test="uuid!=null ">
and uuid = #{uuid}
</if>
</where>
</select>
</mapper>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>by-cdp</artifactId>
<groupId>com.baiye</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cdp-wechat</artifactId>
<packaging>pom</packaging>
<modules>
<module>cdp-wechat-server</module>
<module>cdp-wechat-api</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
Loading…
Cancel
Save