项目初始化

main
bynt 4 months ago
parent 809762aa70
commit c32a0404ea

69
.gitignore vendored

@ -1,26 +1,45 @@
# ---> Java
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
!**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### custom ###
.flattened-pom.xml
/**/application-local.yml
/logs/
/log/
*/log/

@ -1,2 +1,3 @@
# marketing-scrm
百业营销

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.baiye</groupId>
<artifactId>admin</artifactId>
<version>1.0.0</version>
<properties>
<knife4j.version>3.0.3</knife4j.version>
</properties>
<dependencies>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>security-oauth2-authorization-server</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>admin-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-job</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>admin-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-redis</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-springdoc-ui</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-easyexcel</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-idempotent</artifactId>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,170 @@
<?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>marketing-scrm</artifactId>
<groupId>com.baiye</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>admin</artifactId>
<properties>
<knife4j.version>3.0.3</knife4j.version>
</properties>
<dependencies>
<!-- 基于 spring authorization server 的授权服务器 -->
<dependency>
<groupId>com.baiye</groupId>
<artifactId>security-oauth2-authorization-server</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>admin-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-job</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>admin-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-redis</artifactId>
<version>${revision}</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- openapi 扩展处理 -->
<!-- <dependency>-->
<!-- <groupId>com.baiye</groupId>-->
<!-- <artifactId>ballcat-extend-openapi</artifactId>-->
<!-- </dependency>-->
<!-- springdoc swagger-ui -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
</dependency>
<!-- swagger 增强版 ui -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-springdoc-ui</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!-- Java图形验证码 -->
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
</dependency>
<!-- API, java.xml.bind module -->
<!-- add it when jdk11 -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!--easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-easyexcel</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-idempotent</artifactId>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,26 @@
package com.baiye;
import org.ballcat.springsecurity.oauth2.server.authorization.annotation.EnableOauth2AuthorizationServer;
import org.ballcat.springsecurity.oauth2.server.resource.annotation.EnableOauth2ResourceServer;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author Hccake
*/
@EnableTransactionManagement
@EnableOauth2AuthorizationServer
@EnableOauth2ResourceServer
@MapperScan({ "com.baiye.**.mapper" })
@SpringBootApplication
@EnableScheduling
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}

@ -0,0 +1,118 @@
//package com.baiye.aspect;
//
//import cn.hutool.core.collection.CollUtil;
//import com.baiye.modules.distribute.entity.*;
//import com.baiye.modules.distribute.mapper.ClueMapper;
//import com.baiye.modules.distribute.mapper.ClueStageMapper;
//import com.baiye.modules.distribute.mapper.LabelMapper;
//import com.baiye.modules.distribute.mapper.LabelOrganizeMapper;
//import com.baiye.modules.distribute.service.ClueRecordService;
//import com.baiye.modules.distribute.service.DistributeTaskService;
//import com.baiye.security.util.SecurityUtils;
//import com.baiye.system.mapper.SysUserMapper;
//import com.baiye.system.model.dto.SysUserDTO;
//import com.baiye.system.model.entity.SysUser;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.JoinPoint;
//import org.aspectj.lang.annotation.AfterReturning;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Before;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.stereotype.Component;
//
//import java.util.List;
//import java.util.stream.Collectors;
//
///**
// * 系统用户方法AOP
// */
//@Aspect
//@Component
//@Slf4j
//@RequiredArgsConstructor
//public class SysUserAspect {
//
// private final ClueRecordService clueRecordService;
//
// private final ClueMapper clueMapper;
//
// private final SysUserMapper sysUserMapper;
//
// private final DistributeTaskService distributeTaskService;
//
// private final LabelMapper labelMapper;
//
// private final LabelOrganizeMapper labelOrganizeMapper;
//
// private final ClueStageMapper clueStageMapper;
//
// /**
// * 配置切入点
// */
// @Pointcut("execution(* com.baiye.system.service.impl.SysUserServiceImpl.addSysUser(..))")
// public void asyncAddSysUser() {
// }
//
// /**
// * 配置切入点
// */
// @Pointcut("execution(* com.baiye.system.service.impl.SysUserServiceImpl.deleteByUserId(..))")
// public void asyncDeleteByUserId() {
// }
//
// @AfterReturning("asyncAddSysUser()")
// public void beforeAddSysUser(JoinPoint joinPoint) {
// log.info("==========创建用户开始执行AOP切入业务==========");
// // 获取目标对象方法参数,添加业务管理员账号的默认上传记录
// if (SecurityUtils.getCurrentUserId() == 1) {
// Object[] args = joinPoint.getArgs();
// if (args[0] != null && args[0] instanceof SysUserDTO) {
// SysUserDTO sysUserDTO = (SysUserDTO) args[0];
// String username = sysUserDTO.getUsername();
// SysUser sysUser = sysUserMapper.selectByUsername(username);
// if (sysUser != null && sysUser.getUserId() != null) {
// // 创建默认的文件记录
// ClueRecordEntity entity = clueRecordService.addDefaultRecordService(sysUser.getUserId(), "资源推送",
// "资源推送");
// // 创建默认的执行任务
// distributeTaskService.addDefaultTask("资源推送", null, entity.getClueRecordId().toString(),
// sysUser.getUserId(), null);
// }
// }
// }
// }
//
// @Before("asyncDeleteByUserId()")
// public void beforeDeleteByUserId(JoinPoint joinPoint) {
// log.info("==========删除用户开始执行AOP切入业务==========");
// Object[] args = joinPoint.getArgs();
// Object obj = args[0];
// if (obj instanceof Long) {
// // 查询下级是否有子用户
// List<SysUser> userList = sysUserMapper
// .selectList(new LambdaQueryWrapper<SysUser>().eq(SysUser::getWhichUserId, obj));
// if (CollUtil.isNotEmpty(userList)) {
// List<Long> userIdList = userList.stream().map(SysUser::getUserId).collect(Collectors.toList());
// userIdList.add((Long) obj);
// clueMapper.delete(new LambdaQueryWrapper<ClueEntity>().in(ClueEntity::getAssignedBy, userIdList));
// }
// clueMapper.delete(new LambdaQueryWrapper<ClueEntity>().eq(ClueEntity::getAssignedBy, obj));
//
// // 删除用户的任务和上传记录
// BaseMapper<DistributeTaskEntity> taskMapper = distributeTaskService.getBaseMapper();
// taskMapper
// .delete(new LambdaQueryWrapper<DistributeTaskEntity>().eq(DistributeTaskEntity::getCreateBy, obj));
// BaseMapper<ClueRecordEntity> clueRecordMapper = clueRecordService.getBaseMapper();
// clueRecordMapper.delete(new LambdaQueryWrapper<ClueRecordEntity>().eq(ClueRecordEntity::getCreateBy, obj));
// // 删除用户标签和标签组 - 阶段信息
// labelMapper.delete(new LambdaQueryWrapper<LabelEntity>().eq(LabelEntity::getCreateBy, obj));
// labelOrganizeMapper
// .delete(new LambdaQueryWrapper<LabelOrganizeEntity>().eq(LabelOrganizeEntity::getCreateBy, obj));
// clueStageMapper.delete(new LambdaQueryWrapper<ClueStageEntity>().eq(ClueStageEntity::getCreateBy, obj));
// }
// }
//
//}

@ -0,0 +1,37 @@
package com.baiye.captcha;
import com.baiye.exception.BadRequestException;
import com.baiye.result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.ballcat.security.captcha.IValidateCodeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
*
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/captcha")
@Tag(name = "验证码")
public class CaptchaController {
private final IValidateCodeService codeService;
@GetMapping("/code")
@Operation(summary = "获取验证码")
public R<Object> getCode() {
Map<String,Object> captcha;
try {
captcha = this.codeService.createCapcha();
} catch (Exception e) {
throw new BadRequestException("生成验证码错误");
}
return R.ok(captcha);
}
}

@ -0,0 +1,51 @@
package com.baiye.captcha.config;
import com.wf.captcha.base.Captcha;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* {@link ArithmeticCaptchaRewrite}
*/
public abstract class ArithmeticCaptchaAbstractRewrite extends Captcha {
private String arithmeticString;
public ArithmeticCaptchaAbstractRewrite() {
this.setLen(2);
}
protected char[] alphas() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < this.len; ++i) {
sb.append(num(10));
if (i < this.len - 1) {
sb.append("+");
}
}
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
try {
this.chars = String.valueOf(engine.eval(sb.toString().replaceAll("x", "*")));
} catch (ScriptException var5) {
var5.printStackTrace();
}
sb.append("=?");
this.arithmeticString = sb.toString();
return this.chars.toCharArray();
}
public String getArithmeticString() {
this.checkAlpha();
return this.arithmeticString;
}
public void setArithmeticString(String arithmeticString) {
this.arithmeticString = arithmeticString;
}
}

@ -0,0 +1,78 @@
package com.baiye.captcha.config;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
/**
* {@link ArithmeticCaptchaAbstractRewrite}
*/
public class ArithmeticCaptchaRewrite extends ArithmeticCaptchaAbstractRewrite {
public ArithmeticCaptchaRewrite() {
}
public ArithmeticCaptchaRewrite(int width, int height) {
this();
this.setWidth(width);
this.setHeight(height);
}
public ArithmeticCaptchaRewrite(int width, int height, int len) {
this(width, height);
this.setLen(len);
}
public ArithmeticCaptchaRewrite(int width, int height, int len, Font font) {
this(width, height, len);
this.setFont(font);
}
public boolean out(OutputStream out) {
this.checkAlpha();
return this.graphicsImage(this.getArithmeticString().toCharArray(), out);
}
public String toBase64() {
return this.toBase64("data:image/png;base64,");
}
private boolean graphicsImage(char[] strs, OutputStream out) {
try {
BufferedImage bi = new BufferedImage(this.width, this.height, 1);
Graphics2D g2d = (Graphics2D)bi.getGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, this.width, this.height);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
this.drawOval(2, g2d);
g2d.setFont(this.getFont());
FontMetrics fontMetrics = g2d.getFontMetrics();
int fW = this.width / strs.length;
int fSp = (fW - (int)fontMetrics.getStringBounds("8", g2d).getWidth()) / 2;
for(int i = 0; i < strs.length; ++i) {
g2d.setColor(this.color());
int fY = this.height - (this.height - (int)fontMetrics.getStringBounds(String.valueOf(strs[i]), g2d).getHeight() >> 1);
g2d.drawString(String.valueOf(strs[i]), i * fW + fSp + 3, fY - 3);
}
g2d.dispose();
ImageIO.write(bi, "png", out);
out.flush();
boolean var20 = true;
return var20;
} catch (IOException var18) {
var18.printStackTrace();
} finally {
try {
out.close();
} catch (IOException var17) {
var17.printStackTrace();
}
}
return false;
}
}

@ -0,0 +1,47 @@
package com.baiye.captcha.config;
import com.baiye.captcha.enums.CaptchaEnum;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.annotation.Configuration;
/**
*
*/
@Getter
@Setter
@Configuration
public class CaptchaConfig {
/**
*
*/
private CaptchaEnum codeType = CaptchaEnum.arithmetic;
/**
*
*/
private Long expiration = 2L;
/**
*
*/
private int length = 2;
/**
*
*/
private int width = 111;
/**
*
*/
private int height = 36;
/**
*
*/
private String fontName;
/**
*
*/
private int fontSize = 25;
public CaptchaEnum getCodeType() {
return codeType;
}
}

@ -0,0 +1,80 @@
package com.baiye.captcha.config;
import com.baiye.captcha.enums.CaptchaEnum;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.awt.*;
import java.util.Objects;
/**
* @description
*/
@Component
public class KaptchaTextCreator {
private final CaptchaConfig captchaConfig;
public KaptchaTextCreator(CaptchaConfig captchaConfig) {
this.captchaConfig = captchaConfig;
}
/**
*
*
* @return /
*/
public Captcha getCaptcha() {
if (Objects.isNull(captchaConfig)) {
if (Objects.isNull(captchaConfig.getCodeType())) {
captchaConfig.setCodeType(CaptchaEnum.arithmetic);
}
}
return switchCaptcha(captchaConfig);
}
/**
*
*
* @param captchaConfig
* @return /
*/
private Captcha switchCaptcha(CaptchaConfig captchaConfig) {
Captcha captcha;
synchronized (this) {
switch (captchaConfig.getCodeType()) {
case arithmetic:
// 算术类型 https://gitee.com/whvse/EasyCaptcha
//captcha = new ArithmeticCaptcha(captchaConfig.getWidth(), captchaConfig.getHeight());
captcha = new ArithmeticCaptchaRewrite(captchaConfig.getWidth(), captchaConfig.getHeight());
// 几位数运算,默认是两位
captcha.setLen(captchaConfig.getLength());
break;
case chinese:
captcha = new ChineseCaptcha(captchaConfig.getWidth(), captchaConfig.getHeight());
captcha.setLen(captchaConfig.getLength());
break;
case chinese_gif:
captcha = new ChineseGifCaptcha(captchaConfig.getWidth(), captchaConfig.getHeight());
captcha.setLen(captchaConfig.getLength());
break;
case gif:
captcha = new GifCaptcha(captchaConfig.getWidth(), captchaConfig.getHeight());
captcha.setLen(captchaConfig.getLength());
break;
case spec:
captcha = new SpecCaptcha(captchaConfig.getWidth(), captchaConfig.getHeight());
captcha.setLen(captchaConfig.getLength());
break;
default:
throw new IllegalArgumentException("验证码配置信息错误!正确配置查看 CaptchaEnum ");
}
}
if(StringUtils.isNotBlank(captchaConfig.getFontName())){
captcha.setFont(new Font(captchaConfig.getFontName(), Font.PLAIN, captchaConfig.getFontSize()));
}
return captcha;
}
}

@ -0,0 +1,22 @@
package com.baiye.captcha.enums;
public enum CaptchaEnum {
/**
*
*/
arithmetic,
/**
*
*/
chinese,
/**
*
*/
chinese_gif,
/**
*
*/
gif,
spec
}

@ -0,0 +1,60 @@
package com.baiye.captcha.impl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import com.baiye.constant.CaptchaConstant;
import com.baiye.captcha.config.KaptchaTextCreator;
import com.baiye.exception.BadRequestException;
import com.baiye.util.RedisUtils;
import com.wf.captcha.base.Captcha;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ballcat.security.captcha.IValidateCodeService;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @description
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ValidateCodeServiceImpl implements IValidateCodeService {
private final RedisUtils redisUtils;
private final KaptchaTextCreator kaptchaTextCreator;
@Override
public Map<String, Object> createCapcha() {
// 获取验证码
Captcha captcha = this.kaptchaTextCreator.getCaptcha();
// 生成一个唯一的id
String uuid = CaptchaConstant.CAPTCHA_CODE_KEY + IdUtil.simpleUUID();
// 保存到redis中
this.redisUtils.set(uuid, captcha.text(), CaptchaConstant.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
Map<String, Object> map = new HashMap<>();
map.put("uuid", uuid);
map.put("img", captcha.toBase64());
return map;
}
@Override
public void checkCapcha(String key, String code) {
if (CharSequenceUtil.isBlank(code)) {
throw new BadRequestException("验证码不能为空");
}
String captcha = (String) redisUtils.get(key);
if (CharSequenceUtil.isBlank(captcha)) {
throw new BadRequestException("验证码已失效");
}
redisUtils.del(key);
if (!code.equalsIgnoreCase(captcha)) {
throw new BadRequestException("验证码错误");
}
}
}

@ -0,0 +1,20 @@
package com.baiye.constant;
/**
*
*
* @author ruoyi
*/
public final class CaptchaConstant {
/**
* redis key
*/
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/**
*
*/
public static final Integer CAPTCHA_EXPIRATION = 2;
}

@ -0,0 +1,26 @@
package com.baiye.constant;
/**
*
*
* @author Enzo
* @date : 2021/6/16
*/
public class PayConstants {
private PayConstants() {
}
/**
*
*/
public static final String PAY_TITLE = "回跟营销系统支付订单:";
/**
* key
*/
public static final String OUT_TRADE_NO = "out_trade_no";
}

@ -0,0 +1,11 @@
package com.baiye.constant;
/**
* @Author YQY
* @Date 2023/8/17
*/
public class PrefixKeyConstant {
public static final String JOB_KEY = "ad_distribute_distributeTask_id_";
}

@ -0,0 +1,17 @@
package com.baiye.constant;
/**
* @author Enzo
* @date : 2023/11/6
*/
public class ResponseConstant {
public static final int SUCCESS = 200;
public static final int OCENA_NO_PERMISSION = 40002;
public static final int OCEAN_FAIL = 200;
}

@ -0,0 +1,16 @@
package com.baiye.constant;
/**
*
*/
public class UploadTemplateHeadConstant {
public static final String HEAD_NID = "手机号";
public static final String HEAD_ORIGIN = "渠道来源";
public static final String HEAD_REMARK = "备注";
public static final String HEAD_DATE = "日期(****/**/** 00:00:00)";
}

@ -0,0 +1,18 @@
package com.baiye.constant;
/**
* @author Enzo
*/
public class UrlConstant {
public static String CONNECT_OAUTH2_AUTHORIZE_URL = "https://ad.oceanengine.com/openapi/audit/oauth.html?app_id=%s&state=%s&material_auth=1&redirect_uri=%s&material_auth=1";
public static String OAUTH2_ACCESS_TOKEN_URL = "https://ad.oceanengine.com/open_api/oauth2/access_token/";
public static String OAUTH2_REFRESH_TOKEN_URL = "https://ad.oceanengine.com/open_api/oauth2/refresh_token/";
public static String OAUTH2_AUTH_ADVERTISER_URL = "https://ad.oceanengine.com/open_api/oauth2/advertiser/get/?access_token=%s&app_id=%s&secret=%s";
public static String SYNC_CLUE_URL = "https://ad.oceanengine.com/open_api/2/tools/clue/get/";
public static String GET_ADVERTISER = "https://ad.oceanengine.com/open_api/2/majordomo/advertiser/select/";
public static String CALL_BACK_CLUE_URL="https://ad.oceanengine.com/open_api/2/tools/clue/callback/";
}

@ -0,0 +1,57 @@
package com.baiye.constant;
/**
* @author Enzo
* @date 2024-3-27
*/
public interface WeChatRequestConstants {
/**
*
*/
String GET_QR_CODE = "/api/qrCodeLogin/";
/**
* 线
*/
String ROBOT_LOGOUT = "/api/batchLogout/";
/**
*
*/
String GLOBAL_SETTING = "/api/global-settings/";
/**
*
*/
String GET_PUSH_LOGIN = "/api/pushLogin/";
/**
*
*/
String GET_ROBOT_TYPE = "/api/syncRobot/";
/**
*
*/
String CREATE_EQUIPMENT= "/api/addToScanRobotInfo/";
/**
*
*/
String WE_CHAT_ADD_FRIEND = "/api/add-now-friend-phone/";
}

@ -0,0 +1,27 @@
package com.baiye.event.system;
import com.baiye.schedule.handler.ScanDynamicJobHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* @author Enzo
* @date : 2024/5/28
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class RootApplication implements CommandLineRunner {
private final ScanDynamicJobHandler scanDynamicJobHandler;
@Override
public void run(String... args) throws Exception {
log.info(">>>>>>>>>>>>>>>服务启动执行,扫描动态任务列表,并添加任务<<<<<<<<<<<<<");
scanDynamicJobHandler.scanAddJob();
}
}

@ -0,0 +1,57 @@
package com.baiye.modules.distribute.controller;
import com.baiye.modules.distribute.dto.AliPayPcDTO;
import com.baiye.modules.distribute.entity.PayOrder;
import com.baiye.modules.distribute.service.AliPayService;
import com.baiye.result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author Enzo
*/
@Tag(name = "支付宝支付")
@Slf4j
@RestController
@RequestMapping(value = "/pay/aliPay")
@AllArgsConstructor
public class AliPayController {
private final AliPayService aliPayService;
@Operation(summary = "创建pc订单")
@PostMapping(value = "/pcPay")
public R<Map<String, Object>> pcPay(@Validated @RequestBody AliPayPcDTO aliPayPcDTO) {
return R.ok(aliPayService.aliPayPc(aliPayPcDTO));
}
@Operation(summary = "订单号查找")
@GetMapping(value = "/find/order")
public R<PayOrder> frontRcvResponse(@RequestParam("orderNo") String orderNo) {
return R.ok(aliPayService.findOrderByNo(orderNo));
}
/**
* pc
*
* @param request request
* @return
*/
@Operation(summary = "订单回调")
@RequestMapping(value = "/pay-notify", produces = "text/html;charset=utf-8")
public String frontRcvResponse(HttpServletRequest request) {
return aliPayService.pcNotifyResponse(request);
}
}

@ -0,0 +1,42 @@
package com.baiye.modules.distribute.controller;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.service.LoginEquipmentService;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baiye.result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Enzo
* @date : 2024/4/1
*/
@Tag(name = "微信设备")
@Slf4j
@RestController
@RequestMapping(value = "/equipment")
@AllArgsConstructor
public class LoginEquipmentController {
private LoginEquipmentService loginEquipmentService;
@GetMapping("/page")
@Operation(summary = "分页查询记录")
public R<PageResult<WeChatAccountVO>> getClueRecordPage(@Validated PageParam pageParam, AccountQo qo) {
return R.ok(loginEquipmentService.queryPage(pageParam, qo));
}
}

@ -0,0 +1,36 @@
package com.baiye.modules.distribute.controller;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.modules.distribute.qo.PayOrderQo;
import com.baiye.modules.distribute.service.PayOrderService;
import com.baiye.modules.distribute.vo.PayOrderVO;
import com.baiye.result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Enzo
* @date
*/
@RequiredArgsConstructor
@RestController
@Tag(name = "订单记录")
@RequestMapping("/pay/order")
public class PayOrderController {
private final PayOrderService payOrderService;
@GetMapping("/page")
@Operation(summary = "分页查询记录")
public R<PageResult<PayOrderVO>> getClueRecordPage(@Validated PageParam pageParam, PayOrderQo qo) {
return R.ok(payOrderService.queryPage(pageParam, qo));
}
}

@ -0,0 +1,133 @@
package com.baiye.modules.distribute.controller;
import cn.hutool.http.HttpUtil;
import com.baiye.constant.WeChatRequestConstants;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.modules.distribute.dto.CreateCodeDTO;
import com.baiye.modules.distribute.dto.PushCodeDTO;
import com.baiye.modules.distribute.dto.WeChatAddFriendDTO;
import com.baiye.modules.distribute.dto.WeChatStatisticsDTO;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.service.WeChatService;
import com.baiye.modules.distribute.service.WechatFriendService;
import com.baiye.modules.distribute.vo.AccountStatisticsVO;
import com.baiye.modules.distribute.vo.AddFriendVo;
import com.baiye.modules.distribute.vo.StatisticsFriendVO;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baiye.result.R;
import com.baiye.security.util.SecurityUtils;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author Enzo
* @date : 2024/3/27
*/
@RestController
@Tag(name = "微信账号")
@RequiredArgsConstructor
@RequestMapping("/wechat")
public class WeChatController {
private final WeChatService weChatService;
private final WechatFriendService wechatFriendService;
@GetMapping("/page")
@Operation(summary = "分页查询账号")
public R<PageResult<WeChatAccountVO>> getClueRecordPage(@Validated PageParam pageParam, AccountQo qo) {
return R.ok(weChatService.queryPage(pageParam, qo));
}
@GetMapping("/global/setting")
@Operation(summary = "全局设置")
public R<String> getClueRecordPage(String callbackUrl) {
return R.ok(weChatService.globalSetting(callbackUrl));
}
@PostMapping("/createCode")
@Operation(description = "创建二维码")
public R<Object> createCode(@RequestBody CreateCodeDTO createCodeDTO) {
return R.ok(weChatService.createQrCode(createCodeDTO));
}
@Operation(description = "弹窗登录接口")
@PostMapping("/push/code")
public R<Object> pushCode(@Validated @RequestBody PushCodeDTO pushCodeDTO) {
return R.ok(weChatService.pushCode(pushCodeDTO));
}
@Operation(description = "添加好友")
@PostMapping("/addFriend")
public R<Object> addFriend(@Validated @RequestBody WeChatAddFriendDTO weChatFriendDTO) {
return R.ok(weChatService.addFriend(weChatFriendDTO));
}
@GetMapping("/create/equipment")
@Operation(summary = "创建设备")
public R<String> createEquipment(Integer num, Integer packageType) {
return Boolean.TRUE.equals(weChatService.createEquipment(num, packageType, SecurityUtils.getCurrentUserId())) ? R.ok() : R.failed("创建设备失败");
}
@GetMapping("/friend/page")
@Operation(summary = "添加好友记录")
public R<PageResult<AddFriendVo>> getData(@Validated PageParam pageParam, AccountQo qo) {
return R.ok(weChatService.queryFirendData(pageParam, qo));
}
@GetMapping("/query/friend")
@Operation(summary = "时间统计统计粉丝记录")
public R<List<StatisticsFriendVO>> getDateBy(Integer queryType) {
return R.ok(wechatFriendService.statisticsFriendByType(queryType));
}
@PostMapping("/query/user/statistics")
@Operation(summary = "统计用户加粉数量")
public R<PageResult<AddFriendVo>> getDateBy(@RequestBody WeChatStatisticsDTO statisticsDTO) {
return R.ok(wechatFriendService.statisticsFriendByUserId(statisticsDTO));
}
@GetMapping("/query/account/statistics")
@Operation(summary = "统计账号信息数量")
public R<AccountStatisticsVO> accountStatistics() {
return R.ok(weChatService.statisticsAccountByUserId(SecurityUtils.getCurrentUserId()));
}
@GetMapping("/update/remark")
@Operation(summary = "修改备注")
public R<Boolean> accountStatistics(String wxId, String remark) {
return R.ok(weChatService.updateRemarkByWechatId(wxId, remark));
}
@GetMapping("/robot/logout")
@Operation(summary = "退出登录")
public R<Boolean> robotLogout(Integer robotId) {
return R.ok(weChatService.logoutByRobotId(robotId));
}
}

@ -0,0 +1,36 @@
package com.baiye.modules.distribute.controller;
import cn.hutool.json.JSONUtil;
import com.baiye.modules.distribute.service.WechatCallbackService;
import com.baiye.result.R;
import com.baiye.result.WeChatResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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-8-11
*/
@Slf4j
@RestController
@RequestMapping("/api/wechat")
@RequiredArgsConstructor
public class WechatCallbackController {
private final WechatCallbackService wechatCallbackService;
/**
*
*/
@PostMapping("/callback")
public R<String> wechatCallback(@RequestBody WeChatResponse weChatResponse) {
log.info("================== the response {} ==================", JSONUtil.toJsonStr(weChatResponse));
wechatCallbackService.analyticalData(weChatResponse);
return R.ok();
}
}

@ -0,0 +1,23 @@
package com.baiye.modules.distribute.converter;
import com.baiye.modules.distribute.entity.PayOrder;
import com.baiye.modules.distribute.vo.PayOrderVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author Enzo
* @date : 2024/3/28
*/
@Mapper
public interface PayOrderConverter {
PayOrderConverter INSTANCE = Mappers.getMapper(PayOrderConverter.class);
/**
* vo
* @param payOrder
* @return
*/
PayOrderVO entityToVo(PayOrder payOrder);
}

@ -0,0 +1,23 @@
package com.baiye.modules.distribute.converter;
import com.baiye.modules.distribute.entity.WeChatAccount;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author Enzo
* @date : 2024/3/29
*/
@Mapper
public interface WeChatAccountConverter {
WeChatAccountConverter INSTANCE = Mappers.getMapper(WeChatAccountConverter.class);
/**
* vo
* @param weChatAccount
* @return
*/
WeChatAccountVO entityToVo(WeChatAccount weChatAccount);
}

@ -0,0 +1,34 @@
package com.baiye.modules.distribute.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @author Enzo
* @date : 2022/3/16
*/
@Data
@NoArgsConstructor
public class AliPayPcDTO implements Serializable {
private static final long serialVersionUID = 6500373305956248683L;
@NotNull(message = "套餐类型不能为空")
private Integer packageType;
@NotNull(message = "数量不能为空")
@Min(value = 1,message = "最小为1")
private Integer num;
@NotNull(message = "续费类型不能为空")
private Boolean isRenew;
private Integer robotId;
private String remark;
}

@ -0,0 +1,21 @@
package com.baiye.modules.distribute.dto;
import lombok.Data;
/**
* @author Enzo
* @date : 2024/3/27
*/
@Data
public class CreateCodeDTO {
private String robotId;
private String wxId;
private String cityInfo;
private String changedUid;
private String robotVersion;
}

@ -0,0 +1,33 @@
package com.baiye.modules.distribute.dto;
import lombok.*;
import java.util.List;
/**
* @author Enzo
* @date : 2024/4/1
*/
@Data
public class EquipmentDTO {
private Integer status;
private List<RoBotDTO> data;
/**
*
*/
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Setter
public static class RoBotDTO {
private String robotAccount;
private Integer robotId;
}
}

@ -0,0 +1,18 @@
package com.baiye.modules.distribute.dto;
import lombok.Data;
/**
* @author Enzo
* @date : 2024/3/27
*/
@Data
public class PushCodeDTO {
private Integer robotId;
private String wxId;
private String cityInfo;
}

@ -0,0 +1,29 @@
package com.baiye.modules.distribute.dto;
import lombok.Data;
/**
* @author Enzo
* @date : 2024/4/10
*/
@Data
public class WeChatAccountDTO {
private String account;
private String wxid;
private String nickname;
private String smallHeadImgUrl;
private String pit;
private String wxVersion;
private String province;
private Integer status;
}

@ -0,0 +1,40 @@
package com.baiye.modules.distribute.dto;
import lombok.*;
/**
* @author Enzo
* @date : 2022/6/27
*/
@Data
@NoArgsConstructor
public class WeChatAddFriendDTO {
@NonNull
private String robotWxId;
private AddFriendDTO addData;
/**
*
*/
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Setter
public static class AddFriendDTO {
private String scene;
private String addKey;
private String content;
}
}

@ -0,0 +1,42 @@
package com.baiye.modules.distribute.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @author Enzo
* @date : 2022/6/27
*/
@Data
public class WeChatFriendDTO {
@Schema(title = "机器人微信ID")
private String robotWxId;
@Schema(title = "添加好友方式")
private Integer addFriendType;
@Schema(title = "省")
private String province;
@Schema(title = "城市")
private String city;
@Schema(title = "昵称")
private String nickName;
@Schema(title = "性别")
private Integer sex;
@Schema(title = "通过时间")
private Long addAcceptTime;
@Schema(title = "微信ID")
private String friendId;
@Schema(title = "头像")
private String bigHeadImgUrl;
}

@ -0,0 +1,25 @@
package com.baiye.modules.distribute.dto;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
/**
* @author Enzo
* @date : 2022/6/27
*/
@Data
public class WeChatStatisticsDTO {
private List<String> weChatIdList;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
}

@ -0,0 +1,24 @@
package com.baiye.modules.distribute.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author Enzo
* @date : 2022/6/30
*/
@Data
public class WeChatUserLoginDTO implements Serializable {
private String pit;
private String wxId;
private String nickname;
private String bigHeadImgUrl;
}

@ -0,0 +1,93 @@
package com.baiye.modules.distribute.entity;
import com.baiye.entity.LogicDeletedBaseEntity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baiye.extend.mybatis.plus.converter.JsonStringArrayTypeHandler;
import com.baiye.validation.group.UpdateGroup;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.NotNull;
import java.util.List;
@Getter
@Setter
@ToString
@TableName(value = "tb_clue", autoResultMap = true)
@Schema(title = "线索")
@TableAlias("ce")
public class ClueEntity extends LogicDeletedBaseEntity {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.INPUT)
@Schema(title = "线索ID")
@NotNull(message = "分发ID不能为空", groups = { UpdateGroup.class })
private Long clueId;
@Schema(title = "线索来源")
private String originName;
@Schema(title = "手机号")
private String nid;
@Schema(title = "线索时间")
private String clueTime;
@Schema(title = "线索备注")
private String remark;
@Schema(title = "记录ID")
private Long clueRecordId;
@Schema(title = "其它线索(jsonStr格式)")
private String otherClue;
@Schema(title = "分配人用户ID")
private Long assignedBy;
@Schema(title = "分配人用户名")
private String assignedName;
@Schema(title = "资源标签关联ID")
private String clueLabel;
@Schema(title = "资源所打标签信息(jsonStr格式)")
private String clueLabelName;
@Schema(title = "资源阶段关联ID")
private Long clueStageId;
@Schema(title = "资源所打的阶段名称")
private String clueStageName;
@Schema(title = "是否新线索")
private Boolean isNewClue;
@Schema(title = "是否有效")
private Boolean isEffective;
@Schema(title = "太空猫传递的线索ID")
private Long variable;
@Schema(title = "公司管理员用户ID")
private Long companyId;
@Schema(title = "性别(0-男1-女)")
private Integer sex;
@Schema(title = "客户资料")
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String customInformation;
@TableField(value = "channel_identifying", typeHandler = JsonStringArrayTypeHandler.class)
@Schema(title = "渠道标识")
private List<String> channelIdentifying;
@Schema(title = "渠道类型渠道类型(1 手动创建 2文件上传 3飞鱼回传 4话单回传 5 api回传)")
private Integer channelType;
@Schema(title = "客户ID")
private Long customId;
}

@ -0,0 +1,50 @@
package com.baiye.modules.distribute.entity;
import com.baiye.entity.BaseEntity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baiye.validation.group.UpdateGroup;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* @author Enzo
* @date : 2024/4/1
*/
@Getter
@Setter
@TableAlias("le")
@TableName(value = "tb_login_equipment")
public class LoginEquipment extends BaseEntity {
@TableId(type = IdType.AUTO)
@Schema(title = "id")
@NotNull(message = "id", groups = {UpdateGroup.class})
private Long id;
@Schema(name = "user_id")
private Long userId;
@Schema(name = "pit")
private String pit;
@Schema(name = "package_type")
private Integer packageType;
@Schema(name = "robot_id")
private Integer robotId;
@Schema(name = "device_number")
private String deviceNumber;
@Schema(name = "expiration_time")
private Date expirationTime;
}

@ -0,0 +1,72 @@
package com.baiye.modules.distribute.entity;
import cn.hutool.core.date.DatePattern;
import com.baiye.entity.BaseEntity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baiye.validation.group.UpdateGroup;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author Enzo
* @date 2021-10-28
*/
@Getter
@Setter
@TableAlias("po")
@TableName(value = "tb_pay_order")
public class PayOrder extends BaseEntity implements Serializable {
private static final long serialVersionUID = 2056458673691527927L;
@TableId(type = IdType.AUTO)
@Schema(title = "id")
@NotNull(message = "id", groups = {UpdateGroup.class})
private Long id;
@Schema(name = "pay_type")
private Integer payType;
@Schema(name = "order_no")
private String orderNo;
@Schema(name = "status")
private Integer status;
@Schema(name = "num")
private Integer num;
@Schema(name = "purchaser")
private String purchaser;
@Schema(name = "pay_time")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
private Date payTime;
@Schema(name = "amount")
private BigDecimal amount;
@Schema(name = "user_id")
private Long userId;
@Schema(name = "robot_id")
private Integer robotId;
@Schema(name = "is_renew")
private Boolean isRenew;
}

@ -0,0 +1,74 @@
package com.baiye.modules.distribute.entity;
import com.baiye.entity.LogicDeletedBaseEntity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baiye.validation.group.UpdateGroup;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* @author Enzo
* @date : 2024/3/26
*/
@Getter
@Setter
@ToString
@TableAlias("wa")
@TableName(value = "tb_wechat_account")
public class WeChatAccount extends LogicDeletedBaseEntity {
@TableId(type = IdType.INPUT)
@Schema(title = "id")
@NotNull(message = "id", groups = {UpdateGroup.class})
private Long id;
@Schema(title = "用户id")
private Long userId;
@Schema(title = "设备信息")
private String deviceInformation;
@Schema(title = "用户名称")
private String username;
@Schema(title = "用户id")
private String nickname;
@Schema(title = "城市信息")
private String cityInfo;
@Schema(title = "登录类型")
private Integer loginType;
@Schema(name = "登录时间")
private Date loginDate;
@Schema(name = "头像")
private String headerUrl;
@Schema(name = "微信ID")
private String wxId;
@Schema(name = "性别")
private Integer sex;
@Schema(title = "在线状态")
private Integer status;
@Schema(title = "备注")
private String remark;
@Schema(title = "微信号")
private String weChatNo;
}

@ -0,0 +1,46 @@
package com.baiye.modules.distribute.entity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
*
* @author Enzo
*
*
*/
@Data
@TableAlias("we")
@TableName("tb_wechat_equipment")
@Schema(title = "微信账号设备")
public class WeChatEquipment implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
/**
* ID
*/
@Schema(title = "用户id")
private Long accountId;
/**
* Code
*/
@Schema(title = "设备id")
private Long equipmentId;
@Schema(title = "用户ID")
private Long userId;
}

@ -0,0 +1,56 @@
package com.baiye.modules.distribute.entity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
* @author Enzo
* @date : 2024/4/2
*/
@Data
@TableAlias("we")
@TableName("tb_wechat_friend")
@Schema(title = "微信好友记录")
public class WeChatFriedRecord implements Serializable {
@TableId
private Long id;
@Schema(title = "机器人微信ID")
private String robotWxId;
@Schema(title = "添加好友方式")
private Integer addFriendType;
@Schema(title = "省")
private String province;
@Schema(title = "城市")
private String city;
@Schema(title = "昵称")
private String nickName;
@Schema(title = "性别")
private Integer sex;
@Schema(title = "通过时间")
private Long addAcceptTime;
@Schema(title = "微信ID")
private String friendId;
@Schema(title = "头像")
private String bigHeadImgUrl;
@Schema(title = "userId")
private Long userId;
}

@ -0,0 +1,108 @@
package com.baiye.modules.distribute.mapper;
import cn.hutool.core.date.DateTime;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.conditions.query.LambdaQueryWrapperX;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.entity.LoginEquipment;
import com.baiye.modules.distribute.entity.WeChatAccount;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baiye.modules.distribute.vo.WeChatAddFriendVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Enzo
* @date 2024-4-1
*/
@Mapper
public interface LoginEquipmentMapper extends ExtendMapper<LoginEquipment> {
default PageResult<WeChatAccountVO> queryPage(PageParam pageParam, AccountQo qo) {
IPage<WeChatAccountVO> page = this.prodPage(pageParam);
LambdaQueryWrapperX<WeChatAccount> wrapperX = WrappersX.lambdaQueryX(WeChatAccount.class);
if (StringUtils.isNotBlank(qo.getStartTime()) && StringUtils.isNotBlank(qo.getEndTime())) {
wrapperX.between(WeChatAccount::getCreateTime, qo.getStartTime(), qo.getEndTime());
}
wrapperX.likeIfPresent(WeChatAccount::getNickname, qo.getNickname()).likeIfPresent
(WeChatAccount::getWxId, qo.getWxId()).eqIfPresent(WeChatAccount::getUserId, qo.getUserId()).likeIfPresent(WeChatAccount::getWxId, qo.getWxId());
this.selectByPage(page, qo.getStartTime(), qo.getEndTime(), qo.getNickname(), qo.getWxId(), qo.getUserId());
return new PageResult<>(page.getRecords(), page.getTotal());
}
/**
*
*
* @param page
* @param startTime
* @param endTime
* @param username
* @param wxId
* @param userId
* @return
*/
IPage<WeChatAccountVO> selectByPage(IPage<WeChatAccountVO> page,
@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("username") String username, @Param("wxId") String wxId, @Param("userId") Long userId);
/**
*
*
* @param dayNum
* @param currentUserId
* @param wxId
* @return
*/
List<WeChatAddFriendVo> queryByDate(@Param("dayNum") Integer dayNum, @Param("userId") Long currentUserId, @Param("wxId") String wxId);
/**
* ID
*
* @param currentUserId
* @return
*/
List<WeChatAccountVO> queryByUserId(Long currentUserId);
/**
*
*
* @param currentUserId
* @param number
* @return
*/
default Long countFreeEquipment(Long currentUserId, Integer number) {
return this.selectCount
(WrappersX.lambdaQueryX(LoginEquipment.class).eq
(LoginEquipment::getUserId, currentUserId).eq(LoginEquipment::getPackageType, number));
}
/**
*
*
* @param wxId
* @return
*/
List<WeChatAccountVO> findEquipmentByAccountId(@Param("wxId") String wxId);
/**
*
*
* @param date
* @return
*/
default List<LoginEquipment> selectListByTime(DateTime date) {
return this.selectList(WrappersX.lambdaQueryX(LoginEquipment.class).gt(LoginEquipment::getExpirationTime, date));
}
}

@ -0,0 +1,55 @@
package com.baiye.modules.distribute.mapper;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.conditions.query.LambdaQueryWrapperX;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.converter.PayOrderConverter;
import com.baiye.modules.distribute.entity.PayOrder;
import com.baiye.modules.distribute.qo.PayOrderQo;
import com.baiye.modules.distribute.vo.PayOrderVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author Enzo
* @date 2024-4-1
*/
@Mapper
public interface PayOrderMapper extends ExtendMapper<PayOrder> {
/**
*
*
* @param orderNo
* @return
*/
default List<PayOrder> findByOrderNumber(String orderNo) {
LambdaQueryWrapperX<PayOrder> wrapperX = new LambdaQueryWrapperX<>();
return this.selectList(wrapperX.eq(PayOrder::getOrderNo, orderNo).orderByDesc(PayOrder::getId));
}
/**
*
*
* @param pageParam
* @param qo
* @return
*/
default PageResult<PayOrderVO> queryPage(PageParam pageParam, PayOrderQo qo) {
IPage<PayOrder> page = this.prodPage(pageParam);
LambdaQueryWrapperX<PayOrder> wrapperX = WrappersX.lambdaQueryX(PayOrder.class);
if (StringUtils.isNotBlank(qo.getStartTime()) && StringUtils.isNotBlank(qo.getEndTime())) {
wrapperX.between(PayOrder::getCreateTime, qo.getStartTime(), qo.getEndTime());
}
wrapperX.eqIfPresent(PayOrder::getOrderNo, qo.getOrderNo()).eqIfPresent(PayOrder::getUserId, qo.getUserId()).orderByDesc(PayOrder::getId);
this.selectPage(page, wrapperX);
IPage<PayOrderVO> voPage = page.convert(PayOrderConverter.INSTANCE::entityToVo);
return new PageResult<>(voPage.getRecords(), voPage.getTotal());
}
}

@ -0,0 +1,91 @@
package com.baiye.modules.distribute.mapper;
import cn.hutool.core.collection.CollUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.conditions.query.LambdaQueryWrapperX;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.converter.WeChatAccountConverter;
import com.baiye.modules.distribute.entity.WeChatAccount;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author Enzo
* @date 2024-3-27
*/
@Mapper
public interface WeChatAccountMapper extends ExtendMapper<WeChatAccount> {
/**
* id
*
* @param wxId
* @return
*/
default WeChatAccount findByWxId(String wxId) {
List<WeChatAccount> selectList = this.selectList(WrappersX.lambdaQueryX(WeChatAccount.class).eqIfPresent
(WeChatAccount::getWxId, wxId).eqIfPresent(WeChatAccount::getDeleted, DefaultNumberConstants.ZERO_NUMBER).orderByDesc(WeChatAccount::getId));
if (CollUtil.isNotEmpty(selectList)) {
return selectList.get(DefaultNumberConstants.ZERO_NUMBER);
}
return new WeChatAccount();
}
/**
*
*
* @param pageParam
* @param qo
* @return
*/
default PageResult<WeChatAccountVO> queryPage(PageParam pageParam, AccountQo qo) {
IPage<WeChatAccount> page = this.prodPage(pageParam);
LambdaQueryWrapperX<WeChatAccount> wrapperX = WrappersX.lambdaQueryX(WeChatAccount.class);
if (StringUtils.isNotBlank(qo.getStartTime()) && StringUtils.isNotBlank(qo.getEndTime())) {
wrapperX.between(WeChatAccount::getCreateTime, qo.getStartTime(), qo.getEndTime());
}
wrapperX.likeIfPresent(WeChatAccount::getNickname, qo.getNickname()).likeIfPresent(WeChatAccount::getWxId, qo.getWxId()).
eqIfPresent(WeChatAccount::getUserId, qo.getUserId()).orderByDesc(WeChatAccount::getId);
this.selectPage(page, wrapperX);
IPage<WeChatAccountVO> voPage = page.convert(WeChatAccountConverter.INSTANCE::entityToVo);
return new PageResult<>(voPage.getRecords(), voPage.getTotal());
}
/**
* ID
*
* @param currentUserId
* @return
*/
default List<WeChatAccount> queryByUserId(Long currentUserId) {
LambdaQueryWrapperX<WeChatAccount> wrapperX = WrappersX.lambdaQueryX(WeChatAccount.class);
return this.selectList(wrapperX.eq(WeChatAccount::getUserId, currentUserId));
}
/**
*
*
* @param wxId
* @param remark
* @return
*/
default Boolean updateRemark(String wxId, String remark) {
LambdaUpdateWrapper<WeChatAccount> wrapper = Wrappers.<WeChatAccount>lambdaUpdate()
.set(WeChatAccount::getRemark, remark)
.eq(WeChatAccount::getWxId, wxId)
.eq(WeChatAccount::getDeleted, DefaultNumberConstants.ZERO_NUMBER);
return SqlHelper.retBool(this.update(null, wrapper));
}
}

@ -0,0 +1,31 @@
package com.baiye.modules.distribute.mapper;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.entity.WeChatEquipment;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Enzo
* @date 2024-4-1
*/
@Mapper
public interface WeChatEquipmentMapper extends ExtendMapper<WeChatEquipment> {
/**
*
*
* @param accountId
* @param equipmentId
* @return
*/
default Long countEquipment(Long accountId, Long equipmentId) {
return this.selectCount
(WrappersX.lambdaQueryX(WeChatEquipment.class).eq
(WeChatEquipment::getAccountId, accountId).eq(WeChatEquipment::getEquipmentId, equipmentId));
}
}

@ -0,0 +1,64 @@
package com.baiye.modules.distribute.mapper;
import cn.hutool.core.date.DateTime;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.entity.WeChatFriedRecord;
import com.baiye.modules.distribute.vo.StatisticsFriendVO;
import com.baiye.modules.distribute.vo.WeChatAddFriendVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
* @author Enzo
* @date : 2024/4/2
*/
@Mapper
public interface WeChatFriendMapper extends ExtendMapper<WeChatFriedRecord> {
/**
*
*
* @param beginOfDay
* @param now
* @param currentUserId
* @return
*/
List<StatisticsFriendVO> queryByDate(@Param("startTime") DateTime beginOfDay, @Param("endTime") DateTime now, @Param("userId") Long currentUserId);
/**
*
*
* @param weChatIdList
* @param dayNum
* @param currentUserId
* @param startTime
* @param endTime
* @return
*/
List<WeChatAddFriendVo> queryByUserList(@Param("weChatIdList") List<String> weChatIdList,
@Param("dayNum") Long dayNum, @Param("userId") Long currentUserId,
@Param("startTime") Date startTime, @Param("endTime") Date endTime);
/**
* id
*
* @param currentUserId
* @return
*/
default Long queryByUserId(Long currentUserId) {
return this.selectCount(WrappersX.lambdaQueryX(WeChatFriedRecord.class).eq
(WeChatFriedRecord::getUserId, currentUserId));
}
/**
* id
* @param id
* @return
*/
List<StatisticsFriendVO> findEquipmentByAccountId(Long id);
}

@ -0,0 +1,30 @@
package com.baiye.modules.distribute.qo;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @author Enzo
* @date : 2024/3/29
*/
@Data
public class AccountQo {
@Parameter(description = "开始时间")
private String startTime;
@Parameter(description = "结束时间")
private String endTime;
@Parameter(description = "用户昵称")
private String nickname;
@Schema(title = "用户ID")
private Long userId;
@Schema(title = "微信id")
private String wxId;
}

@ -0,0 +1,21 @@
package com.baiye.modules.distribute.qo;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class PayOrderQo {
@Schema(title = "订单号")
private String orderNo;
@Parameter(description = "开始时间")
private String startTime;
@Parameter(description = "结束时间")
private String endTime;
@Schema(title = "用户ID")
private Long userId;
}

@ -0,0 +1,42 @@
package com.baiye.modules.distribute.service;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.dto.AliPayPcDTO;
import com.baiye.modules.distribute.entity.PayOrder;
import com.baiye.modules.distribute.entity.WeChatAccount;
import com.baiye.result.R;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* @author Enzo
* @date : 2021/6/16
*/
public interface AliPayService extends ExtendService<PayOrder> {
/**
* pc
* @param aliPayPcDTO
* @return
*/
Map<String,Object> aliPayPc(AliPayPcDTO aliPayPcDTO);
/**
*
*
* @param request
* @return
*/
String pcNotifyResponse(HttpServletRequest request);
/**
*
* @param orderNo
* @return
*/
PayOrder findOrderByNo(String orderNo);
}

@ -0,0 +1,74 @@
package com.baiye.modules.distribute.service;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.entity.LoginEquipment;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baiye.modules.distribute.vo.WeChatAddFriendVo;
import java.util.List;
/**
* @author Enzo
* @date : 2024/4/1
*/
public interface LoginEquipmentService extends ExtendService<LoginEquipment> {
/**
*
* @param pageParam
* @param qo
* @return
*/
PageResult<WeChatAccountVO> queryPage(PageParam pageParam, AccountQo qo);
/**
* ID
* @param pit
* @return
*/
LoginEquipment queryByRobot(String pit);
/**
*
*
* @param dayNum
* @param currentUserId
* @param wxId
* @return
*/
List<WeChatAddFriendVo> queryByDate(Integer dayNum, Long currentUserId, String wxId);
/**
*
* @param robotId
* @return
*/
LoginEquipment queryByRobotId(Integer robotId);
/**
*
* @param currentUserId
* @return
*/
List<WeChatAccountVO> queryByUserId(Long currentUserId);
/**
*
* @param currentUserId
* @param number
* @return
*/
Long countFreeEquipment(Long currentUserId, Integer number);
/**
*
* @return
*/
List<LoginEquipment> findExpiredAccount();
}

@ -0,0 +1,23 @@
package com.baiye.modules.distribute.service;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.entity.PayOrder;
import com.baiye.modules.distribute.qo.PayOrderQo;
import com.baiye.modules.distribute.vo.PayOrderVO;
/**
* @author Enzo
* @date : 2024/3/28
*/
public interface PayOrderService extends ExtendService<PayOrder> {
/**
*
* @param pageParam
* @param qo
* @return
*/
PageResult<PayOrderVO> queryPage(PageParam pageParam, PayOrderQo qo);
}

@ -0,0 +1,131 @@
package com.baiye.modules.distribute.service;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.dto.CreateCodeDTO;
import com.baiye.modules.distribute.dto.PushCodeDTO;
import com.baiye.modules.distribute.dto.WeChatAddFriendDTO;
import com.baiye.modules.distribute.dto.WeChatUserLoginDTO;
import com.baiye.modules.distribute.entity.WeChatAccount;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.vo.AccountStatisticsVO;
import com.baiye.modules.distribute.vo.AddFriendVo;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
/**
* @author Enzo
* @date 2023/9/5
*/
public interface WeChatService extends ExtendService<WeChatAccount> {
/**
*
*
* @param createCodeDTO
* @return
*/
String createQrCode(CreateCodeDTO createCodeDTO);
/**
*
*
* @param weChatFriendDTO
* @return
*/
Boolean addFriend(WeChatAddFriendDTO weChatFriendDTO);
/**
*
* @param pageParam
* @param qo
* @return
*/
PageResult<WeChatAccountVO> queryPage(PageParam pageParam, AccountQo qo);
/**
*
*
* @param num
* @param packageType
* @param userId
* @return
*/
Boolean createEquipment(Integer num, Integer packageType, Long userId);
/**
*
* @param pushCodeDTO
* @return
*/
String pushCode(PushCodeDTO pushCodeDTO);
/**
*
* @param callbackUrl
* @return
*/
String globalSetting(String callbackUrl);
/**
*
*
* @param userLoginDTO
* @param status
* @param userId
* @param id
* @return
*/
Boolean weChatAccountLoginByRespon(WeChatUserLoginDTO userLoginDTO, Integer status, Long userId, Long id);
/**
*
* @param pageParam
* @param qo
* @return
*/
PageResult<AddFriendVo> queryFirendData(PageParam pageParam, AccountQo qo);
/**
*
*
* @param robotId
* @param payType
* @return
*/
Boolean equipmentRenewal(Integer robotId, Integer payType);
/**
* ID
* @param robotWxId
* @return
*/
WeChatAccount findByWxId(String robotWxId);
/**
*
* @param currentUserId
* @return
*/
AccountStatisticsVO statisticsAccountByUserId(Long currentUserId);
/**
*
* @param wxId
* @param remark
* @return
*/
Boolean updateRemarkByWechatId(String wxId, String remark);
/**
* 退
* @param robotId
* @return
*/
Boolean logoutByRobotId(Integer robotId);
}

@ -0,0 +1,17 @@
package com.baiye.modules.distribute.service;
import com.baiye.result.WeChatResponse;
/**
* @author Enzo
* @date : 2024/4/1
*/
public interface WechatCallbackService {
/**
*
* @param body
*/
void analyticalData(WeChatResponse body);
}

@ -0,0 +1,49 @@
package com.baiye.modules.distribute.service;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.dto.WeChatFriendDTO;
import com.baiye.modules.distribute.dto.WeChatStatisticsDTO;
import com.baiye.modules.distribute.entity.WeChatFriedRecord;
import com.baiye.modules.distribute.vo.AddFriendVo;
import com.baiye.modules.distribute.vo.StatisticsFriendVO;
import java.util.List;
/**
* @author Enzo
* @date : 2024/4/2
*/
public interface WechatFriendService extends ExtendService<WeChatFriedRecord> {
/**
*
*
* @param weChatFriendDTO
*/
void addFriendByResponse(WeChatFriendDTO weChatFriendDTO);
/**
*
* @param queryType
* @return
*/
List<StatisticsFriendVO> statisticsFriendByType(Integer queryType);
/**
*
* @param currentUserId
* @return
*/
Long queryByUserId(Long currentUserId);
/**
*
*
* @param statisticsDTO
* @return
*/
PageResult<AddFriendVo> statisticsFriendByUserId(WeChatStatisticsDTO statisticsDTO);
}

@ -0,0 +1,205 @@
package com.baiye.modules.distribute.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.constant.PayConstants;
import com.baiye.constant.enums.ResponseCode;
import com.baiye.exception.BadRequestException;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.modules.distribute.dto.AliPayPcDTO;
import com.baiye.modules.distribute.entity.PayOrder;
import com.baiye.modules.distribute.mapper.PayOrderMapper;
import com.baiye.modules.distribute.service.AliPayService;
import com.baiye.modules.distribute.service.LoginEquipmentService;
import com.baiye.modules.distribute.service.WeChatService;
import com.baiye.security.util.SecurityUtils;
import com.baiye.system.properties.AliPayProperties;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Enzo
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AliPayServiceImpl extends ExtendServiceImpl<PayOrderMapper, PayOrder> implements AliPayService {
@Value("${snowflake.workerId}")
private int workerId;
@Value("${snowflake.datacenterId}")
private int datacenterId;
private final AliPayProperties aliPay;
private final WeChatService weChatService;
private final LoginEquipmentService loginEquipmentService;
@Override
@Transactional(rollbackFor = Exception.class)
public String pcNotifyResponse(HttpServletRequest request) {
log.info("================ the pay notify enter date as {} ================", DateUtil.date());
//获取支付宝GET过来反馈信息
Map<String, String> params = new HashMap<>(DefaultNumberConstants.SIXTEEN_NUMBER);
// 处理乱码问题
checkParam(request, params);
Boolean flag;
try {
flag = Factory.Payment.Common().verifyNotify(params);
//商户订单号
String orderNo = new String(request.getParameter(PayConstants.OUT_TRADE_NO).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
//前台回调验证签名 v1 or v2
if (flag != null && flag) {
log.info("========== order verify signature success the orderNumber as {} ==========", orderNo);
List<PayOrder> orderList = baseMapper.findByOrderNumber(orderNo);
if (CollUtil.isNotEmpty(orderList) && orderList.get(DefaultNumberConstants.ZERO_NUMBER).getStatus() == DefaultNumberConstants.ZERO_NUMBER) {
PayOrder order = orderList.get(DefaultNumberConstants.ZERO_NUMBER);
log.info("========== the order notify success date as {} ==========", DateUtil.date());
order.setPayTime(DateUtil.date());
order.setStatus(DefaultNumberConstants.ONE_NUMBER);
if (Boolean.FALSE.equals(order.getIsRenew())) {
// 创建设备
weChatService.createEquipment(order.getNum(), order.getPayType(), order.getUserId());
}
if (Boolean.TRUE.equals(order.getIsRenew())) {
// 续费操作设备
weChatService.equipmentRenewal(order.getRobotId(), order.getPayType());
}
return this.updateById(order) ? ResponseCode.SUCCESS.getDesc() : ResponseCode.FAILURE.getDesc();
}
}
} catch (Exception e) {
log.error("the pc response error time {}", LocalTime.now());
throw new BadRequestException(ResponseCode.CALLBACK_FAILED.getDesc());
}
return ResponseCode.FAILURE.getDesc();
}
private void checkParam(HttpServletRequest request, Map<String, String> params) {
Map<String, String[]> requestParams = request.getParameterMap();
if (CollectionUtils.isNotEmpty(requestParams.keySet())) {
for (Map.Entry<String, String[]> stringEntry : requestParams.entrySet()) {
String[] values = stringEntry.getValue();
String valueStr = CharSequenceUtil.EMPTY;
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + StrPool.COMMA;
}
/* //乱码解决,这段代码在出现乱码时使用
valueStr = new String(valueStr.getBytes
(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);*/
params.put(stringEntry.getKey(), valueStr);
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> aliPayPc(AliPayPcDTO aliPayPcDTO) {
Map<String, Object> map = Maps.newHashMap();
Long userId = SecurityUtils.getCurrentUserId();
BigDecimal amount = new BigDecimal(DefaultNumberConstants.ZERO_NUMBER);
Integer num = aliPayPcDTO.getNum();
Integer robotId = aliPayPcDTO.getRobotId();
Boolean isRenew = aliPayPcDTO.getIsRenew();
Integer packageType = aliPayPcDTO.getPackageType();
// 结算金额
if (packageType == DefaultNumberConstants.TWO_NUMBER) {
// 季度
amount = NumberUtil.mul
(String.valueOf(DefaultNumberConstants.THIRTY), String.valueOf(DefaultNumberConstants.THREE_NUMBER));
}
if (packageType == DefaultNumberConstants.THREE_NUMBER) {
// 年度八折
amount = NumberUtil.mul(NumberUtil.mul
(String.valueOf(DefaultNumberConstants.THIRTY), String.valueOf(DefaultNumberConstants.TWELVE_NUMBER)), 0.8);
}
amount = NumberUtil.mul(amount, num);
// 雪花算法id
String orderNo = String.valueOf(IdUtil.getSnowflake(workerId, datacenterId).nextId());
// 创建订单
savePayOrder(num, isRenew, robotId, packageType, amount, orderNo);
if (packageType == DefaultNumberConstants.ONE_NUMBER) {
Long countFreeEquipment = loginEquipmentService.countFreeEquipment(userId, DefaultNumberConstants.ONE_NUMBER);
if (ObjectUtil.isNotNull(countFreeEquipment)
&& countFreeEquipment + num > DefaultNumberConstants.THREE_NUMBER) {
throw new BadRequestException("至多创建三台免费设备!");
}
// 创建设备
weChatService.createEquipment(num, packageType, userId);
map.put("orderNo", orderNo);
return map;
}
// 查询记录
try {
// 生成返回对象
AlipayTradePagePayResponse response = Factory.Payment.Page().pay(PayConstants.PAY_TITLE + orderNo, orderNo, String.valueOf(amount), aliPay.getReturnUrl());
if (ResponseChecker.success(response)) {
map.put("payUrl", response.getBody());
map.put("orderNo", orderNo);
return map;
}
} catch (Exception e) {
log.error("the order failed purchaser {} time {}", aliPayPcDTO.getRemark(), LocalTime.now());
throw new BadRequestException(ResponseCode.ALI_PAY_ERROR.getDesc());
}
throw new BadRequestException(ResponseCode.ALI_PAY_ERROR.getDesc());
}
private Boolean savePayOrder(Integer num, Boolean isRenew, Integer robotId, Integer packageType, BigDecimal amount, String orderNo) {
PayOrder order = new PayOrder();
order.setNum(num);
order.setAmount(amount);
order.setRobotId(robotId);
order.setIsRenew(isRenew);
order.setOrderNo(orderNo);
order.setPayType(packageType);
order.setUserId(SecurityUtils.getCurrentUserId());
order.setStatus(packageType > DefaultNumberConstants.ONE_NUMBER
? DefaultNumberConstants.ZERO_NUMBER : DefaultNumberConstants.ONE_NUMBER);
return this.save(order);
}
@Override
public PayOrder findOrderByNo(String orderNo) {
List<PayOrder> payOrderList = baseMapper.findByOrderNumber(orderNo);
if (CollUtil.isNotEmpty(payOrderList)) {
return payOrderList.get(DefaultNumberConstants.ZERO_NUMBER);
}
return new PayOrder();
}
}

@ -0,0 +1,110 @@
package com.baiye.modules.distribute.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.constant.WeChatRequestConstants;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.dto.WeChatAccountDTO;
import com.baiye.modules.distribute.entity.LoginEquipment;
import com.baiye.modules.distribute.mapper.LoginEquipmentMapper;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.service.LoginEquipmentService;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baiye.modules.distribute.vo.WeChatAddFriendVo;
import com.baiye.result.WeChatResponse;
import com.baiye.security.util.SecurityUtils;
import com.baiye.system.properties.WeChatProperties;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @author Enzo
* @date : 2024/4/1
*/
@Service
@RequiredArgsConstructor
public class LoginEquipmentServiceImpl extends ExtendServiceImpl<LoginEquipmentMapper, LoginEquipment> implements
LoginEquipmentService {
private final WeChatProperties weChatProperties;
@Override
public PageResult<WeChatAccountVO> queryPage(PageParam pageParam, AccountQo qo) {
Map<String, Object> map = Maps.newHashMap();
qo.setUserId(SecurityUtils.getCurrentUserId());
PageResult<WeChatAccountVO> queryPage = baseMapper.queryPage(pageParam, qo);
queryPage.getRecords().forEach(accountVO -> {
// 默认离线状态
accountVO.setStatus(DefaultNumberConstants.ZERO_NUMBER);
map.put("robotId", accountVO.getRobotId());
String robotResult = HttpUtil.get
(weChatProperties.getGatewayHost().concat(WeChatRequestConstants.GET_ROBOT_TYPE)
.concat(weChatProperties.getAppKey()), map);
if (JSONUtil.isTypeJSON(robotResult)) {
WeChatResponse weChatResponse = JSONUtil.toBean(robotResult, WeChatResponse.class);
if (weChatResponse.getStatus() == HttpStatus.HTTP_OK) {
WeChatAccountDTO dto = BeanUtil.toBean(weChatResponse.getData(), WeChatAccountDTO.class);
if (ObjectUtil.isNotNull(dto) && dto.getPit().equals(accountVO.getPit())) {
accountVO.setCityInfo(dto.getProvince());
accountVO.setStatus(dto.getStatus());
}
}
}
});
return queryPage;
}
@Override
public LoginEquipment queryByRobot(String pit) {
LoginEquipment loginEquipment = baseMapper.selectOne
(WrappersX.lambdaQueryX(LoginEquipment.class).eq(LoginEquipment::getPit, pit));
if (ObjectUtil.isNotNull(loginEquipment) && ObjectUtil.isNotNull(loginEquipment.getUserId())) {
return loginEquipment;
}
return new LoginEquipment();
}
@Override
public List<WeChatAddFriendVo> queryByDate(Integer dayNum, Long currentUserId, String wxId) {
return baseMapper.queryByDate(dayNum, currentUserId, wxId);
}
@Override
public LoginEquipment queryByRobotId(Integer robotId) {
LoginEquipment loginEquipment = baseMapper.selectOne
(WrappersX.lambdaQueryX(LoginEquipment.class).eq(LoginEquipment::getRobotId, robotId));
if (ObjectUtil.isNotNull(loginEquipment) && ObjectUtil.isNotNull(loginEquipment.getUserId())) {
return loginEquipment;
}
return new LoginEquipment();
}
@Override
public List<WeChatAccountVO> queryByUserId(Long currentUserId) {
return baseMapper.queryByUserId(currentUserId);
}
@Override
public Long countFreeEquipment(Long currentUserId, Integer number) {
return baseMapper.countFreeEquipment(currentUserId, number);
}
@Override
public List<LoginEquipment> findExpiredAccount() {
return baseMapper.selectListByTime(DateUtil.date());
}
}

@ -0,0 +1,29 @@
package com.baiye.modules.distribute.service.impl;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.modules.distribute.entity.PayOrder;
import com.baiye.modules.distribute.mapper.PayOrderMapper;
import com.baiye.modules.distribute.qo.PayOrderQo;
import com.baiye.modules.distribute.service.PayOrderService;
import com.baiye.modules.distribute.vo.PayOrderVO;
import com.baiye.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author Enzo
* @date : 2024/3/28
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class PayOrderServiceImpl extends ExtendServiceImpl<PayOrderMapper, PayOrder> implements PayOrderService {
@Override
public PageResult<PayOrderVO> queryPage(PageParam pageParam, PayOrderQo qo) {
qo.setUserId(SecurityUtils.getCurrentUserId());
return baseMapper.queryPage(pageParam, qo);
}
}

@ -0,0 +1,340 @@
package com.baiye.modules.distribute.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.constant.ResponseConstant;
import com.baiye.constant.WeChatRequestConstants;
import com.baiye.constant.WechatCallbackConstant;
import com.baiye.constant.enums.ResponseCode;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.enums.PackageEnum;
import com.baiye.exception.BadRequestException;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.modules.distribute.dto.*;
import com.baiye.modules.distribute.entity.LoginEquipment;
import com.baiye.modules.distribute.entity.WeChatAccount;
import com.baiye.modules.distribute.entity.WeChatEquipment;
import com.baiye.modules.distribute.mapper.WeChatAccountMapper;
import com.baiye.modules.distribute.mapper.WeChatEquipmentMapper;
import com.baiye.modules.distribute.qo.AccountQo;
import com.baiye.modules.distribute.service.LoginEquipmentService;
import com.baiye.modules.distribute.service.WeChatService;
import com.baiye.modules.distribute.service.WechatFriendService;
import com.baiye.modules.distribute.vo.AccountStatisticsVO;
import com.baiye.modules.distribute.vo.AddFriendVo;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baiye.modules.distribute.vo.WeChatAddFriendVo;
import com.baiye.result.WeChatResponse;
import com.baiye.security.util.SecurityUtils;
import com.baiye.system.properties.WeChatProperties;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author Enzo
* @date 2024-3-27
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WeChatServiceImpl extends ExtendServiceImpl<WeChatAccountMapper, WeChatAccount> implements WeChatService {
@Value("${snowflake.workerId}")
private int workerId;
@Value("${snowflake.datacenterId}")
private int datacenterId;
private final WeChatProperties weChatProperties;
private final WechatFriendService wechatFriendService;
private final LoginEquipmentService loginEquipmentService;
private final WeChatEquipmentMapper weChatEquipmentMapper;
@Override
public String createQrCode(CreateCodeDTO createCodeDTO) {
Map<String, Object> beanToMap = BeanUtil.beanToMap(createCodeDTO);
String getQrCodeResult = HttpUtil.get
(weChatProperties.getGatewayHost().concat(WeChatRequestConstants.GET_QR_CODE)
.concat(weChatProperties.getAppKey()), beanToMap);
log.info("=============== the response as {} =============", getQrCodeResult);
if (StringUtils.isNotBlank(getQrCodeResult)) {
WeChatResponse weChatResponse = JSONUtil.toBean(getQrCodeResult, WeChatResponse.class);
return weChatResponse.getMsg();
}
throw new BadRequestException("创建失败");
}
@Override
public Boolean addFriend(WeChatAddFriendDTO weChatFriendDTO) {
String addedFriendResult = HttpUtil.post(weChatProperties.getGatewayHost().concat
(WeChatRequestConstants.WE_CHAT_ADD_FRIEND).concat(weChatProperties.getAppKey()), JSONUtil.toJsonStr(weChatFriendDTO));
log.info("=============== the response as {} =============", addedFriendResult);
if (addedFriendResult.contains(ResponseCode.SUCCESS.getDesc())) {
WeChatResponse weChatResponse = JSONUtil.toBean(addedFriendResult, WeChatResponse.class);
if (weChatResponse.getStatus() == HttpStatus.HTTP_OK) {
return Boolean.TRUE;
}
throw new BadRequestException(weChatResponse.getMsg());
}
return Boolean.FALSE;
}
@Override
public PageResult<WeChatAccountVO> queryPage(PageParam pageParam, AccountQo qo) {
qo.setUserId(SecurityUtils.getCurrentUserId());
return baseMapper.queryPage(pageParam, qo);
}
@Override
public Boolean createEquipment(Integer num, Integer packageType, Long userId) {
Map<String, Object> map = ImmutableMap.of("num", num);
String createEquipmentResult = HttpUtil.get
(weChatProperties.getGatewayHost().concat(WeChatRequestConstants.CREATE_EQUIPMENT)
.concat(weChatProperties.getAppKey()), map);
log.info("=============== the response as {} =============", createEquipmentResult);
if (StringUtils.isNotBlank(createEquipmentResult)) {
WeChatResponse weChatResponse = JSONUtil.toBean(createEquipmentResult, WeChatResponse.class);
if (weChatResponse.getStatus() == ResponseConstant.SUCCESS) {
Integer dayNum = PackageEnum.find(packageType);
if (dayNum > DefaultNumberConstants.ZERO_NUMBER) {
EquipmentDTO dto = BeanUtil.toBean(weChatResponse.getData(), EquipmentDTO.class);
DateTime dateTime = DateUtil.endOfDay(DateUtil.offsetDay(DateUtil.date(), dayNum));
for (EquipmentDTO.RoBotDTO botDTO : dto.getData()) {
// 创建账号
LoginEquipment equipment = new LoginEquipment();
equipment.setUserId(userId);
equipment.setPackageType(packageType);
equipment.setExpirationTime(dateTime);
equipment.setRobotId(botDTO.getRobotId());
equipment.setPit(botDTO.getRobotAccount());
// equipment.setDeviceNumber(botDTO.getRobotAccount());
loginEquipmentService.save(equipment);
}
}
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
@Override
public String pushCode(PushCodeDTO pushCodeDTO) {
LoginEquipment loginEquipment = loginEquipmentService.queryByRobotId(pushCodeDTO.getRobotId());
if (ObjectUtil.isNotNull(loginEquipment) && ObjectUtil.isNotNull(loginEquipment.getExpirationTime())) {
if (loginEquipment.getExpirationTime().before(DateUtil.date())) {
throw new BadRequestException("当前设备已过期请续费后使用!");
}
}
Map<String, Object> beanToMap = BeanUtil.beanToMap(pushCodeDTO);
String pushQrCodeResult = HttpUtil.get
(weChatProperties.getGatewayHost().concat(WeChatRequestConstants.GET_PUSH_LOGIN)
.concat(weChatProperties.getAppKey()), beanToMap);
log.info("=============== the response as {} =============", pushQrCodeResult);
if (StringUtils.isNotBlank(pushQrCodeResult)) {
WeChatResponse weChatResponse = JSONUtil.toBean(pushQrCodeResult, WeChatResponse.class);
return weChatResponse.getMsg();
}
return CharSequenceUtil.EMPTY;
}
@Override
public String globalSetting(String callbackUrl) {
List<String> strings = Lists.newArrayList(callbackUrl);
Map<String, Object> map = ImmutableMap.of("callbackUrls", strings);
String globalSetting = HttpUtil.post
(weChatProperties.getGatewayHost().concat
(WeChatRequestConstants.GLOBAL_SETTING).concat(weChatProperties.getAppKey()), JSONUtil.toJsonStr(map));
if (StringUtils.isNotBlank(globalSetting)) {
WeChatResponse weChatResponse = JSONUtil.toBean(globalSetting, WeChatResponse.class);
return weChatResponse.getMsg();
}
return CharSequenceUtil.EMPTY;
}
@Override
public Boolean weChatAccountLoginByRespon(WeChatUserLoginDTO userLoginDTO, Integer status, Long userId, Long id) {
WeChatAccount byWxId = this.baseMapper.findByWxId(userLoginDTO.getWxId());
if (ObjectUtil.isNull(byWxId) || ObjectUtil.isNull(byWxId.getId())) {
Long saveId = IdUtil.getSnowflake(workerId, datacenterId).nextId();
WeChatEquipment equipment = new WeChatEquipment();
byWxId = new WeChatAccount();
BeanUtil.copyProperties(userLoginDTO, byWxId);
byWxId.setHeaderUrl(userLoginDTO.getBigHeadImgUrl());
byWxId.setId(saveId);
byWxId.setUserId(userId);
equipment.setUserId(userId);
equipment.setEquipmentId(id);
equipment.setAccountId(saveId);
weChatEquipmentMapper.insert(equipment);
return this.save(byWxId);
}
BeanUtil.copyProperties(userLoginDTO, byWxId);
byWxId.setUserId(userId);
Long counted = weChatEquipmentMapper.countEquipment(byWxId.getId(), id);
if (counted == DefaultNumberConstants.ZERO_NUMBER) {
WeChatEquipment equipment = new WeChatEquipment();
equipment.setEquipmentId(id);
equipment.setUserId(userId);
equipment.setAccountId(byWxId.getId());
weChatEquipmentMapper.insert(equipment);
}
byWxId.setStatus(status == WechatCallbackConstant.LOGIN_SUCCESS ?
DefaultNumberConstants.ONE_NUMBER : DefaultNumberConstants.MINUS_ONE_NUMBER);
return this.updateById(byWxId);
}
@Override
public PageResult<AddFriendVo> queryFirendData(PageParam pageParam, AccountQo qo) {
qo.setUserId(SecurityUtils.getCurrentUserId());
List<AddFriendVo> addFriendVos = Lists.newArrayList();
PageResult<WeChatAccountVO> accountVo = baseMapper.queryPage(pageParam, qo);
for (WeChatAccountVO vo : accountVo.getRecords()) {
AddFriendVo addFriendVo = new AddFriendVo();
BeanUtil.copyProperties(vo, addFriendVo);
// 查询数据天数据
List<WeChatAddFriendVo> weChatAddFriendVos =
loginEquipmentService.queryByDate(DefaultNumberConstants.FIFTEEN_NUMBER, SecurityUtils.getCurrentUserId(), vo.getWxId());
// 转为map
Map<String, List<WeChatAddFriendVo>> map = weChatAddFriendVos.stream().collect
(Collectors.groupingBy(WeChatAddFriendVo::getDayStr));
Integer newFriendsInitiativeNum = DefaultNumberConstants.ZERO_NUMBER;
Integer newPassiveNum = DefaultNumberConstants.ZERO_NUMBER;
List<AddFriendVo.FriendDTO> newArrayList = Lists.newArrayList();
for (int i = 0; i < DefaultNumberConstants.FIFTEEN_NUMBER; i++) {
// 时间格式
String dateTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -i), "MM-dd");
AddFriendVo.FriendDTO dto = new AddFriendVo.FriendDTO();
dto.setDayStr(dateTime);
if (map.containsKey(dateTime)) {
List<WeChatAddFriendVo> voList = map.get(dateTime);
Map<Integer, WeChatAddFriendVo> voMap =
voList.stream().collect(Collectors.toMap
(WeChatAddFriendVo::getAddFriendType, chatAddFriendVo -> chatAddFriendVo));
if (voMap.get(DefaultNumberConstants.ONE_NUMBER) != null) {
WeChatAddFriendVo weChatAddFriendVo = voMap.get(DefaultNumberConstants.ONE_NUMBER);
Integer num = weChatAddFriendVo.getNum();
newFriendsInitiativeNum += num;
dto.setNewDayFriendsInitiativeNum(num);
}
if (voMap.get(DefaultNumberConstants.TWO_NUMBER) != null) {
WeChatAddFriendVo weChatAddFriendVo = voMap.get(DefaultNumberConstants.TWO_NUMBER);
Integer num = weChatAddFriendVo.getNum();
newPassiveNum += num;
dto.setNewDayPassiveNum(num);
}
}
newArrayList.add(dto);
addFriendVo.setList(newArrayList);
}
addFriendVo.setNewFriendsInitiativeNum(newFriendsInitiativeNum);
addFriendVo.setNewPassiveNum(newPassiveNum);
addFriendVos.add(addFriendVo);
}
return new PageResult<>(addFriendVos, accountVo.getTotal());
}
@Override
public Boolean equipmentRenewal(Integer robotId, Integer payType) {
// TODO 设备续费
Integer dayNum = PackageEnum.find(payType);
if (dayNum > DefaultNumberConstants.ZERO_NUMBER) {
LoginEquipment loginEquipment = loginEquipmentService.queryByRobotId(robotId);
if (ObjectUtil.isNotNull(loginEquipment) && ObjectUtil.isNotNull(loginEquipment.getId())) {
DateTime dateTime = DateUtil.endOfDay(DateUtil.offsetDay(loginEquipment.getExpirationTime(), dayNum));
loginEquipment.setExpirationTime(dateTime);
return loginEquipmentService.updateById(loginEquipment);
}
}
return Boolean.FALSE;
}
@Override
public WeChatAccount findByWxId(String robotWxId) {
return baseMapper.findByWxId(robotWxId);
}
@Override
public AccountStatisticsVO statisticsAccountByUserId(Long currentUserId) {
List<String> onlineList = Lists.newArrayList();
AccountStatisticsVO vo = new AccountStatisticsVO();
List<WeChatAccountVO> weChatAccounts = loginEquipmentService.queryByUserId(currentUserId);
Long friendNum = wechatFriendService.queryByUserId(currentUserId);
Integer abnormalNum = DefaultNumberConstants.ZERO_NUMBER;
int onlineNum = DefaultNumberConstants.ZERO_NUMBER;
Map<String, Object> map = Maps.newHashMap();
for (WeChatAccountVO weChatAccount : weChatAccounts) {
map.put("robotId", weChatAccount.getRobotId());
String robotResult = HttpUtil.get
(weChatProperties.getGatewayHost().concat(WeChatRequestConstants.GET_ROBOT_TYPE)
.concat(weChatProperties.getAppKey()), map);
if (JSONUtil.isTypeJSON(robotResult)) {
WeChatResponse weChatResponse = JSONUtil.toBean(robotResult, WeChatResponse.class);
if (weChatResponse.getStatus() == HttpStatus.HTTP_OK) {
WeChatAccountDTO dto = BeanUtil.toBean(weChatResponse.getData(), WeChatAccountDTO.class);
if (ObjectUtil.isNotNull(dto) &&
dto.getStatus() == DefaultNumberConstants.ONE_NUMBER
&& !onlineList.contains(dto.getPit())) {
onlineList.add(dto.getPit());
onlineNum += DefaultNumberConstants.ONE_NUMBER;
}
}
}
}
vo.setFriendNum(friendNum);
vo.setOnlineNum(onlineNum);
vo.setAbnormalNum(abnormalNum);
vo.setAccountNum(weChatAccounts.size());
return vo;
}
@Override
public Boolean updateRemarkByWechatId(String wxId, String remark) {
return this.baseMapper.updateRemark(wxId, remark);
}
@Override
public Boolean logoutByRobotId(Integer robotId) {
List<Integer> arrayList = Lists.newArrayList(robotId);
Map<String, Object> map = Maps.newHashMap();
map.put("robotIds", arrayList);
String result = HttpUtil.post
(weChatProperties.getGatewayHost().concat(WeChatRequestConstants.ROBOT_LOGOUT)
.concat(weChatProperties.getAppKey()), map);
log.info("=============== the response as {} =============", result);
if (StringUtils.isNotBlank(result) && result.contains(ResponseCode.SUCCESS.getDesc())) {
WeChatResponse weChatResponse = JSONUtil.toBean(result, WeChatResponse.class);
if (weChatResponse.getStatus() == HttpStatus.HTTP_OK) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
}

@ -0,0 +1,91 @@
package com.baiye.modules.distribute.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.constant.WechatCallbackConstant;
import com.baiye.modules.distribute.dto.WeChatFriendDTO;
import com.baiye.modules.distribute.dto.WeChatUserLoginDTO;
import com.baiye.modules.distribute.entity.LoginEquipment;
import com.baiye.modules.distribute.entity.WeChatAccount;
import com.baiye.modules.distribute.service.LoginEquipmentService;
import com.baiye.modules.distribute.service.WeChatService;
import com.baiye.modules.distribute.service.WechatCallbackService;
import com.baiye.modules.distribute.service.WechatFriendService;
import com.baiye.notify.event.StationNotifyPushEvent;
import com.baiye.notify.model.domain.AnnouncementNotifyInfo;
import com.baiye.result.WeChatResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Collections;
/**
* @author Enzo
* @date : 2024/4/1
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WechatCallbackServiceImpl implements WechatCallbackService {
private final WeChatService weChatService;
private final ApplicationContext publisher;
private final WechatFriendService wechatFriendService;
private final LoginEquipmentService loginEquipmentService;
@Override
public void analyticalData(WeChatResponse weChatResponse) {
Integer status = weChatResponse.getStatus();
switch (status) {
case WechatCallbackConstant.LOGIN_OUT:
case WechatCallbackConstant.LOGIN_SUCCESS:
wechatLogin(weChatResponse);
break;
case WechatCallbackConstant.LOGIN_FAIL:
// 登录失败接口
break;
case WechatCallbackConstant.THROUGH_FRIENDS:
viaFriendRequest(weChatResponse);
break;
default:
}
}
public void wechatLogin(WeChatResponse weChatResponse) {
WeChatUserLoginDTO userLoginDTO =
JSONUtil.toBean(JSONUtil.toJsonStr(weChatResponse.getData()), WeChatUserLoginDTO.class);
LoginEquipment robot = loginEquipmentService.queryByRobot(userLoginDTO.getPit());
if (ObjectUtil.isNotNull(robot) && ObjectUtil.isNotNull(robot.getUserId())) {
weChatService.weChatAccountLoginByRespon(userLoginDTO, weChatResponse.getStatus(), robot.getUserId(), robot.getId());
AnnouncementNotifyInfo notifyInfo = new AnnouncementNotifyInfo();
notifyInfo.setTitle("新消息通知");
notifyInfo.setMessageKey(String.valueOf(robot.getRobotId()));
notifyInfo.setContent("用户".concat(userLoginDTO.getNickname()).concat("登录成功"));
notifyInfo.setCreateTime(LocalDateTime.now());
notifyInfo.setMessageType(DefaultNumberConstants.ONE_NUMBER);
log.info("============ send message {} ==============", JSONUtil.toJsonStr(notifyInfo));
// 发送消息
publisher.publishEvent(new StationNotifyPushEvent(notifyInfo, Collections.singletonList(robot.getUserId())));
}
}
private void viaFriendRequest(WeChatResponse weChatResponse) {
WeChatFriendDTO weChatFriendDTO =
JSONUtil.toBean(JSONUtil.toJsonStr(weChatResponse.getData()), WeChatFriendDTO.class);
wechatFriendService.addFriendByResponse(weChatFriendDTO);
}
}

@ -0,0 +1,137 @@
package com.baiye.modules.distribute.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.domain.PageResult;
import com.baiye.enums.StatisticsEnum;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.dto.WeChatFriendDTO;
import com.baiye.modules.distribute.dto.WeChatStatisticsDTO;
import com.baiye.modules.distribute.entity.WeChatFriedRecord;
import com.baiye.modules.distribute.mapper.LoginEquipmentMapper;
import com.baiye.modules.distribute.mapper.WeChatFriendMapper;
import com.baiye.modules.distribute.service.WechatFriendService;
import com.baiye.modules.distribute.vo.AddFriendVo;
import com.baiye.modules.distribute.vo.StatisticsFriendVO;
import com.baiye.modules.distribute.vo.WeChatAccountVO;
import com.baiye.modules.distribute.vo.WeChatAddFriendVo;
import com.baiye.security.util.SecurityUtils;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author Enzo
* @date : 2024/3/28
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WechatFriendServiceImpl extends ExtendServiceImpl
<WeChatFriendMapper, WeChatFriedRecord> implements WechatFriendService {
private final LoginEquipmentMapper loginEquipmentMapper;
@Override
public void addFriendByResponse(WeChatFriendDTO weChatFriendDTO) {
if (StringUtils.isNotBlank(weChatFriendDTO.getNickName())) {
List<WeChatAccountVO> voList = loginEquipmentMapper.findEquipmentByAccountId(weChatFriendDTO.getRobotWxId());
if (CollUtil.isNotEmpty(voList)) {
for (WeChatAccountVO vo : voList) {
if (ObjectUtil.isNotNull(vo.getExpirationTime()) && vo.getExpirationTime().after(DateUtil.date())) {
Long count = this.baseMapper.selectCount(WrappersX.lambdaQueryX(WeChatFriedRecord.class).eq
(WeChatFriedRecord::getRobotWxId, weChatFriendDTO.getRobotWxId()).eq
(WeChatFriedRecord::getFriendId, weChatFriendDTO.getFriendId()).eq(WeChatFriedRecord::getUserId, vo.getUserId()));
if (count == DefaultNumberConstants.ZERO_NUMBER &&
vo.getWxId().equals(weChatFriendDTO.getRobotWxId())) {
WeChatFriedRecord weChatFriedRecord = new WeChatFriedRecord();
BeanUtil.copyProperties(weChatFriendDTO, weChatFriedRecord);
weChatFriedRecord.setUserId(vo.getUserId());
this.baseMapper.insert(weChatFriedRecord);
}
}
}
}
}
}
@Override
public List<StatisticsFriendVO> statisticsFriendByType(Integer queryType) {
Integer num = StatisticsEnum.find(queryType);
if (num > DefaultNumberConstants.ZERO_NUMBER) {
DateTime now = DateUtil.date();
DateTime beginOfDay = DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -num));
return baseMapper.queryByDate(beginOfDay, now, SecurityUtils.getCurrentUserId());
}
return Lists.newArrayList();
}
@Override
public PageResult<AddFriendVo> statisticsFriendByUserId(WeChatStatisticsDTO statisticsDTO) {
Date endTime = statisticsDTO.getEndTime();
Date startTime = statisticsDTO.getStartTime();
List<String> weChatIdList = statisticsDTO.getWeChatIdList();
List<AddFriendVo> addFriendVos = Lists.newArrayList();
Long dayNum = DateUtil.betweenDay(startTime, endTime, Boolean.TRUE);
AddFriendVo addFriendVo = new AddFriendVo();
List<WeChatAddFriendVo> weChatAddFriendVos = baseMapper.queryByUserList(weChatIdList, dayNum, SecurityUtils.getCurrentUserId(), startTime, endTime);
// 转为map
Map<String, List<WeChatAddFriendVo>> map = weChatAddFriendVos.stream().collect
(Collectors.groupingBy(WeChatAddFriendVo::getDayStr));
Integer newFriendsInitiativeNum = DefaultNumberConstants.ZERO_NUMBER;
Integer newPassiveNum = DefaultNumberConstants.ZERO_NUMBER;
List<AddFriendVo.FriendDTO> newArrayList = Lists.newArrayList();
for (int i = 0; i <= dayNum; i++) {
// 时间格式
String dateTime = DateUtil.format(DateUtil.offsetDay(startTime, i), "MM-dd");
AddFriendVo.FriendDTO dto = new AddFriendVo.FriendDTO();
dto.setDayStr(dateTime);
if (map.containsKey(dateTime)) {
List<WeChatAddFriendVo> voList = map.get(dateTime);
Map<Integer, WeChatAddFriendVo> voMap =
voList.stream().collect(Collectors.toMap
(WeChatAddFriendVo::getAddFriendType, chatAddFriendVo -> chatAddFriendVo));
if (voMap.get(DefaultNumberConstants.ONE_NUMBER) != null) {
WeChatAddFriendVo weChatAddFriendVo = voMap.get(DefaultNumberConstants.ONE_NUMBER);
Integer num = weChatAddFriendVo.getNum();
newFriendsInitiativeNum += num;
dto.setNewDayFriendsInitiativeNum(num);
}
if (voMap.get(DefaultNumberConstants.TWO_NUMBER) != null) {
WeChatAddFriendVo weChatAddFriendVo = voMap.get(DefaultNumberConstants.TWO_NUMBER);
Integer num = weChatAddFriendVo.getNum();
newPassiveNum += num;
dto.setNewDayPassiveNum(num);
}
}
newArrayList.add(dto);
addFriendVo.setList(newArrayList);
}
addFriendVo.setNewFriendsInitiativeNum(newFriendsInitiativeNum);
addFriendVo.setNewPassiveNum(newPassiveNum);
addFriendVos.add(addFriendVo);
return new PageResult<>(addFriendVos, addFriendVos.size());
}
@Override
public Long queryByUserId(Long currentUserId) {
return this.baseMapper.queryByUserId(currentUserId);
}
}

@ -0,0 +1,22 @@
package com.baiye.modules.distribute.vo;
import lombok.Data;
/**
* @author Enzo
* @date : 2024/4/7
*/
@Data
public class AccountStatisticsVO {
private Integer accountNum;
private Long friendNum;
private Integer onlineNum;
private Integer abnormalNum;
}

@ -0,0 +1,49 @@
package com.baiye.modules.distribute.vo;
import com.baiye.constant.DefaultNumberConstants;
import lombok.*;
import java.util.List;
/**
* @author Enzo
* @date : 2024/4/3
*/
@Data
public class AddFriendVo {
private String wxId;
private Integer robotId;
private String username;
private String nickname;
private String robotWxNick;
private String headerUrl;
private Integer newPassiveNum;
private List<FriendDTO> list;
private Integer newFriendsInitiativeNum;
/**
* list
*/
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Setter
public static class FriendDTO {
private String dayStr;
private Integer newDayFriendsInitiativeNum = DefaultNumberConstants.ZERO_NUMBER;
private Integer newDayPassiveNum = DefaultNumberConstants.ZERO_NUMBER;
}
}

@ -0,0 +1,43 @@
package com.baiye.modules.distribute.vo;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
@Data
public class PayOrderVO {
@Schema(name = "pay_type")
private Integer payType;
@Schema(name = "order_number")
private String orderNumber;
@Schema(name = "status")
private Integer status;
@Schema(name = "purchaser")
private String purchaser;
@Schema(name = "pay_time")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
private Date payTime;
@Schema(name = "amount")
private Double amount;
@Schema(name = "user_id")
private Long userId;
@Schema(title = "创建时间")
private LocalDateTime createTime;
@Schema(title = "修改时间")
private LocalDateTime updateTime;
}

@ -0,0 +1,16 @@
package com.baiye.modules.distribute.vo;
import lombok.Data;
/**
* @author Enzo
* @date : 2024/4/3
*/
@Data
public class StatisticsFriendVO {
private Integer addFriendType;
private Integer count;
}

@ -0,0 +1,86 @@
package com.baiye.modules.distribute.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @author Enzo
* @date : 2024/3/26
*/
@Data
public class WeChatAccountVO {
@Schema(title = "id")
private Long id;
@Schema(title = "用户id")
private Long userId;
@Schema(title = "设备信息")
private String deviceInformation;
@Schema(title = "用户名称")
private String username;
@Schema(title = "用户id")
private String nickname;
@Schema(title = "城市信息")
private String cityInfo;
@Schema(title = "登录类型")
private Integer loginType;
@Schema(name = "登录时间")
private Date loginDate;
@Schema(name = "头像")
private String headerUrl;
@Schema(name = "微信ID")
private String wxId;
@Schema(name = "性别")
private Integer sex;
@Schema(name = "拥有者")
private Long ownerId;
@Schema(title = "创建时间")
private LocalDateTime createTime;
@Schema(title = "修改时间")
private LocalDateTime updateTime;
@Schema(title = "在线状态")
private Integer status;
@Schema(title = "备注")
private String remark;
@Schema(title = "pit")
private String pit;
@Schema(title = "微信号")
private String weChatNo;
@Schema(title = "设备号")
private Integer robotId;
private String deviceNumber;
@Schema(title = "过期时间")
private Date expirationTime;
}

@ -0,0 +1,18 @@
package com.baiye.modules.distribute.vo;
import lombok.Data;
/**
* @author Enzo
* @date : 2024/4/3
*/
@Data
public class WeChatAddFriendVo {
private String dayStr;
private Integer num;
private Integer addFriendType;
}

@ -0,0 +1,40 @@
package com.baiye.properties;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.baiye.system.properties.AliPayProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* @author Enzo
*/
@Component
@Configuration
@EnableConfigurationProperties({AliPayProperties.class})
public class PayConfig {
private final AliPayProperties aliPay;
public PayConfig(AliPayProperties aliPay) {
this.aliPay = aliPay;
Config config = new Config();
config.protocol = aliPay.getProtocol();
config.gatewayHost = aliPay.getGatewayHost();
config.signType = aliPay.getSignType();
config.appId = aliPay.getAppId();
/**
*
*/
config.merchantPrivateKey = aliPay.getMerchantPrivateKey();
config.alipayPublicKey = aliPay.getAliPayPublicKey();
config.notifyUrl = aliPay.getNotifyUrl();
config.encryptKey = aliPay.getEncryptKey();
Factory.setOptions(config);
}
public AliPayProperties getConfig(){
return aliPay;
}
}

@ -0,0 +1,64 @@
package com.baiye.schedule;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.constant.WeChatRequestConstants;
import com.baiye.modules.distribute.entity.LoginEquipment;
import com.baiye.modules.distribute.service.LoginEquipmentService;
import com.baiye.system.properties.WeChatProperties;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @author Enzo
* @date : 2024/4/10
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class AccountTask {
private final WeChatProperties weChatProperties;
private final LoginEquipmentService loginEquipmentService;
/**
* 线
*/
@Scheduled(cron = "0 0 1 * * ? ")
public void updateAccountMassNum() {
List<Integer> arrayList = Lists.newArrayList();
List<LoginEquipment> equipmentList =
loginEquipmentService.findExpiredAccount();
if (CollUtil.isNotEmpty(equipmentList)) {
for (LoginEquipment equipment : equipmentList) {
DateTime dateTime = DateUtil.offsetDay
(equipment.getExpirationTime(), DefaultNumberConstants.FIFTEEN_NUMBER);
if (dateTime.before(DateUtil.date())) {
arrayList.add(equipment.getRobotId());
}
}
if (CollUtil.isNotEmpty(arrayList)) {
Map<String, Object> map = Maps.newHashMap();
map.put("robotIds", arrayList);
String result = HttpUtil.post
(weChatProperties.getGatewayHost().concat(WeChatRequestConstants.ROBOT_LOGOUT)
.concat(weChatProperties.getAppKey()), map);
log.info("========== the response as {} ==========", result);
}
}
}
}

@ -0,0 +1,79 @@
package com.baiye.schedule;
import com.baiye.common.job.handler.ElasticJobHandler;
import com.baiye.result.R;
import com.baiye.schedule.handler.DynamicJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import java.util.Objects;
/**
* @author Enzo
* @date : 2024/5/28
*/
@Slf4j
@RestController
@RequestMapping("/dynamic")
public class DynamicController {
@Autowired
private ElasticJobHandler elasticJobHandler;
/**
*
* jobName
* cron cron 0 * * * * ? *
*
* @param params
* @return
*/
@GetMapping("/createJob")
public R<String> createJob(@RequestBody Map<String, Object> params) {
elasticJobHandler.addJob(params.get("jobName").toString(), params.get("cron").toString(), 1, new DynamicJob(), Objects.isNull(params.get("params")) ? "" : params.get("params").toString(), Objects.isNull(params.get("description")) ? "" : params.get("description").toString());
return R.ok();
}
/**
*
* jobName
* cron cron 0 0/5 * * * ?
*
* @return
*/
@GetMapping("/updateJob")
public R<String> updateJob(@RequestBody Map<String, Object> params) {
if (Objects.isNull(params.get("jobName"))) {
return R.failed("jobName不能为空");
}
if (Objects.isNull(params.get("cron"))) {
return R.failed("cron不能为空");
}
elasticJobHandler.updateJob(params.get("jobName").toString(), params.get("cron").toString());
return R.ok("请求成功");
}
/**
*
* jobName
*
* @return
*/
@GetMapping("/removeJob")
public R<String> removeJob(@RequestBody Map<String, Object> params) {
if (Objects.isNull(params.get("jobName"))) {
return R.failed("jobName不能为空");
}
elasticJobHandler.removeJob(params.get("jobName").toString());
return R.ok("请求成功");
}
}

@ -0,0 +1,46 @@
package com.baiye.schedule.entity;
import com.baiye.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* @author Enzo
* @date : 2024/5/28
*/
@Getter
@Setter
@TableName(value = "tb_job_dynamic_task")
@Schema(title = "定时任务")
public class JobDynamicTask extends BaseEntity implements Serializable {
/**
* ID
*/
@TableId
@Schema(title = "ID")
private Long id;
@Schema(title = "is_delete")
private Integer isDelete;
@Schema(title = "job_name")
private String jobName;
@Schema(title = "cron")
private String cron;
@Schema(title = "description")
private String description;
@Schema(title = "parameters")
private String parameters;
@Schema(title = "status")
private Integer status;
}

@ -0,0 +1,34 @@
package com.baiye.schedule.handler;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
* @author Enzo
* @date : 2024/5/28
*/
@Slf4j
public class DynamicJob implements SimpleJob {
/**
*
*
* @param shardingContext
*/
@Override
public void execute(ShardingContext shardingContext) {
log.info("{}动态定时任务执行逻辑start...", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MS_PATTERN));
String jobName = shardingContext.getJobName();
String jobParameter = shardingContext.getJobParameter();
log.info("---------DynamicJob---------动态定时任务正在执行:jobName = {}, jobParameter = {}", jobName, jobParameter);
//根据参数调用不同的业务接口处理,请远程调用业务模块处理,避免本服务与业务依赖过重...
log.info("{}动态定时任务执行逻辑end...", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MS_PATTERN));
}
}

@ -0,0 +1,41 @@
package com.baiye.schedule.handler;
import com.baiye.common.job.handler.ElasticJobHandler;
import com.baiye.schedule.entity.JobDynamicTask;
import com.baiye.schedule.service.ElasticJobService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author Enzo
* @date : 2024/5/28
*/
@Slf4j
@Service
public class ScanDynamicJobHandler {
@Resource
private ElasticJobHandler elasticJobHandler;
@Resource
private ElasticJobService elasticJobService;
/**
*
* <p>
*
*
* @author songfayuan
* @date 2021/4/26 9:15
*/
public void scanAddJob() {
// 这里为从MySQL数据库读取job_dynamic_task表的数据微服务项目中建议使用feign从业务服务获取避免本服务过度依赖业务的问题然后业务服务新增动态任务也通过feign调取本服务JobOperateController实现从而相对独立本服务模块
List<JobDynamicTask> jobDynamicTaskList = this.elasticJobService.getAllList();
log.info("扫描动态任务列表,并添加任务:本次共扫描到{}条任务。", jobDynamicTaskList.size());
for (JobDynamicTask jobDynamicTask : jobDynamicTaskList) {
// 创建任务
elasticJobHandler.addJob(jobDynamicTask.getJobName(), jobDynamicTask.getCron(), 1, new DynamicJob(), jobDynamicTask.getParameters(), jobDynamicTask.getDescription());
}
}
}

@ -0,0 +1,14 @@
package com.baiye.schedule.mapper;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.schedule.entity.JobDynamicTask;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Enzo
* @date : 2024/5/28
*/
@Mapper
public interface JobDynamicTaskMapper extends ExtendMapper<JobDynamicTask> {
}

@ -0,0 +1,19 @@
package com.baiye.schedule.service;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.schedule.entity.JobDynamicTask;
import java.util.List;
/**
* @author Enzo
* @date : 2024/5/28
*/
public interface ElasticJobService extends ExtendService<JobDynamicTask> {
/**
*
* @return
*/
List<JobDynamicTask> getAllList();
}

@ -0,0 +1,28 @@
package com.baiye.schedule.service.impl;
import com.baiye.schedule.mapper.JobDynamicTaskMapper;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.schedule.entity.JobDynamicTask;
import com.baiye.schedule.service.ElasticJobService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Enzo
* @date : 2024/5/28
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ElasticJobServiceImpl extends ExtendServiceImpl<JobDynamicTaskMapper, JobDynamicTask> implements ElasticJobService {
@Override
public List<JobDynamicTask> getAllList() {
return baseMapper.selectList(WrappersX.lambdaQueryX(JobDynamicTask.class).eq(JobDynamicTask::getStatus, DefaultNumberConstants.ONE_NUMBER));
}
}

@ -0,0 +1,48 @@
spring:
datasource:
url: jdbc:mysql://39.100.77.21:3306/marketing-scrm?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: root
password: y7z7noq2
redis:
host: 39.100.77.21
password: sC33HXphkHBRj4Jb
port: 6379
timeout: 5000
database: 1
alipay:
protocol: https
# 不需要加/gateway.do这是新旧SDK的区别切记
# gatewayHost: openapi.alipaydev.com
gatewayHost: openapi.alipay.com
signType: RSA2
# 填APPID
appId: 2021003125644167
# 填应用私钥注意是应用私钥不要填成公钥了_(:з」∠)_
merchantPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCNIuelR5MHMY3vtl2KEgWUbhHMHuBwxHMVONuUYKlt4grOGJtaPKitgh9MxrvaxmAvH0LilQQKd5T07os9jC2XpNmH0BA6rNVNgBwjWNllqKo+jT8OiKvog9uBuZYfHdkLRhjObrTkSo97jO5Y32591GZHG+cQ/5bgMC0KXlQMOv5piLqUfKYDJ5pWBdS5gqcCkUABZsrW+C8nD7lvOuVglN1AGQiXQzj+Iu3K5xcUg+d3q0nWXhKPpotSolFGSakLEqUja/MnsILVHVw8MYMuq6LxzQ7DQ5fCzMPMIF5kYTynsAV5SoE90ilj1vmmI4aa7dc+9OmG/vXyFuoOEK1bAgMBAAECggEAH0K/9EfqNQmw2ouWJGLhgYLvxjqAk/mvU+AIItFWNdR/eC7TGiWdZvEPZb4PFeIio81Uz0MaZgceozHC/Zry7kfBNufK8HQfus7JbLrdTDsTmk9GzD1RdmreT9l/etztmiWokPDMeFRbe443rM+wdYZ6MP3pLEawcG+7SjSigSKrcpltAJ49NhHyfJxnnCye4mM8PevVGXe4nGv/vKJbAfzl5V8MsSY+SVktj6jOUTSa6nypISvQElyv8jeNH/bTDjg0DOHzL4tUHaVbTqHhtqbNo3n9VuKz4shVAp3I+9PpcTQTueTsM9L0Y+j84bV3VZlTIGGzDUD4qWDhUKPJ4QKBgQDQFNB2vLDJLeGfn+SnCncnr/wQo1xJez+deBqJXoDhDWDuZVcWNaEOWgfDronm8dIedWMYHD//WN0GtA5foAUdlaNq/jeKdJFgzJ/hoOtOveHY1OWqJHiJ/YMRBMuLn/E4Jit7q215JU6Jur1T+70HxrUFTQfY8GWdMvSDFHCKDwKBgQCto24hqgcEDKoR3/sm5sUKqYZTHLeQbniM0D5EcOkBNw7UXGYQSbz7mJ34XQKTfrOL71A+LkjxdMfs5q56yxeOQxR4EBO/Fpz8xPRlud5uIp4eTQVJ8I01meZyvojkF6mO5C4tbcXJOpnpU8ohoeTRu7th0oUYObGUYmn0qzuj9QKBgDCOOtsKSwKXF0hFanjkQ0vakCpdxIJNJVoclayqhc5+bbkTos/G8e9EaP1rtDhVA6Ah6l7M8M4oMWOIDraXw7nUmk60RcekTexVs5VWFLLKMnKDs5gRbKNeqgAFq23Ig+SDW7A/H4uefgY7skRvwPuYjdNP113zMvMM2evgkCZXAoGAP5przvz/EOaqrV2EG93QM3WhdHRCcS9mDP6CsINDdmR6lCM8Z577EJX4128KcIiqsAl7NSuzIG8MhKSDKQuXl07PAqOw+AAKhTSH6XNKHMGldaf01f69WvMCzOkqL5LTUzoWCCH7nxhOJH/CvMsWjBTeMJjyk8seVyIteaf3crkCgYEAmY8OC+Vdo/yop+ooedCnvBC7GVMfcqR6+rIQ+ZnKom7jhByIN6w7eEVAnmNa9dCv/pig7HaYbitWmCNf9tbqFfcdY6e5Svele3amgDM9iqtdJ9Rf1PpDPZw+gmjRIxGs6W8wnl1Sqvpk8pFUA/2xlT6sXpfxra9N09LS0ttU+cU=
# 填支付宝公钥,注意不是生成的应用公钥
aliPayPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyvegkGCrz1i5/K7VzQxvoZm4G73pSPNu9R5ET8YonIuDVoHkHaYvQQizLdRkTyBsYIik8FXsSDmVsw5MLMQ7OAlZ97nQBkz5TxOX6Px766nUpSVoWXoAz6cpIlWnwgir4t1ph88Ph56l+qmqW3gUj/U6MIuzjxBJlijTMHl96its95Nd4cEFx4j+sFuRYob6D0kcemC7xEFuty7bdupda51Z56GYI1YjuUTryTlFOHZbOSThc2ZMzNC1gPG25bn2Lx6sDuPByk4KW4rQ2v7mSfeUuZZRdjtVSC0WV2M2Cv5L8eLFvZRgNYnXrUJYhnRpT+OBAvJZXaWU2nv/bNe/UQIDAQAB
# 回调地址
notifyUrl: http://39.100.77.21:8088/pay/aliPay/pay-notify
# 支付宝成功支付跳转页面
returnUrl: https://count.byffp.top/statePage/success
# 可设置AES密钥调用AES加解密相关接口时需要可选
encryptKey:
springdoc:
swagger-ui:
urls:
- { name: 'admin', url: '/v3/api-docs' }
- { name: 'api', url: 'http://ballcat-api/v3/api-docs' }
#mybatis plus 设置
mybatis-plus:
configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl #关闭sql日志
wechat:
gatewayHost: https://fission-server.scrm-ai.com
appKey: SFkWRAued71GvCeClj8efDhAG6bJ2rzT

@ -0,0 +1,39 @@
spring:
datasource:
url: jdbc:mysql://localhost:3306/marketing-scrm?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: root
password: CK8KyUngFSY
redis:
host: localhost
password:
port: 6379
# 生产环境关闭文档
ballcat:
openapi:
enabled: false
alipay:
protocol: https
# 不需要加/gateway.do这是新旧SDK的区别切记
# gatewayHost: openapi.alipaydev.com
gatewayHost: openapi.alipay.com
signType: RSA2
# 填APPID
appId: 2021003125644167
# 填应用私钥注意是应用私钥不要填成公钥了_(:з」∠)_
merchantPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCNIuelR5MHMY3vtl2KEgWUbhHMHuBwxHMVONuUYKlt4grOGJtaPKitgh9MxrvaxmAvH0LilQQKd5T07os9jC2XpNmH0BA6rNVNgBwjWNllqKo+jT8OiKvog9uBuZYfHdkLRhjObrTkSo97jO5Y32591GZHG+cQ/5bgMC0KXlQMOv5piLqUfKYDJ5pWBdS5gqcCkUABZsrW+C8nD7lvOuVglN1AGQiXQzj+Iu3K5xcUg+d3q0nWXhKPpotSolFGSakLEqUja/MnsILVHVw8MYMuq6LxzQ7DQ5fCzMPMIF5kYTynsAV5SoE90ilj1vmmI4aa7dc+9OmG/vXyFuoOEK1bAgMBAAECggEAH0K/9EfqNQmw2ouWJGLhgYLvxjqAk/mvU+AIItFWNdR/eC7TGiWdZvEPZb4PFeIio81Uz0MaZgceozHC/Zry7kfBNufK8HQfus7JbLrdTDsTmk9GzD1RdmreT9l/etztmiWokPDMeFRbe443rM+wdYZ6MP3pLEawcG+7SjSigSKrcpltAJ49NhHyfJxnnCye4mM8PevVGXe4nGv/vKJbAfzl5V8MsSY+SVktj6jOUTSa6nypISvQElyv8jeNH/bTDjg0DOHzL4tUHaVbTqHhtqbNo3n9VuKz4shVAp3I+9PpcTQTueTsM9L0Y+j84bV3VZlTIGGzDUD4qWDhUKPJ4QKBgQDQFNB2vLDJLeGfn+SnCncnr/wQo1xJez+deBqJXoDhDWDuZVcWNaEOWgfDronm8dIedWMYHD//WN0GtA5foAUdlaNq/jeKdJFgzJ/hoOtOveHY1OWqJHiJ/YMRBMuLn/E4Jit7q215JU6Jur1T+70HxrUFTQfY8GWdMvSDFHCKDwKBgQCto24hqgcEDKoR3/sm5sUKqYZTHLeQbniM0D5EcOkBNw7UXGYQSbz7mJ34XQKTfrOL71A+LkjxdMfs5q56yxeOQxR4EBO/Fpz8xPRlud5uIp4eTQVJ8I01meZyvojkF6mO5C4tbcXJOpnpU8ohoeTRu7th0oUYObGUYmn0qzuj9QKBgDCOOtsKSwKXF0hFanjkQ0vakCpdxIJNJVoclayqhc5+bbkTos/G8e9EaP1rtDhVA6Ah6l7M8M4oMWOIDraXw7nUmk60RcekTexVs5VWFLLKMnKDs5gRbKNeqgAFq23Ig+SDW7A/H4uefgY7skRvwPuYjdNP113zMvMM2evgkCZXAoGAP5przvz/EOaqrV2EG93QM3WhdHRCcS9mDP6CsINDdmR6lCM8Z577EJX4128KcIiqsAl7NSuzIG8MhKSDKQuXl07PAqOw+AAKhTSH6XNKHMGldaf01f69WvMCzOkqL5LTUzoWCCH7nxhOJH/CvMsWjBTeMJjyk8seVyIteaf3crkCgYEAmY8OC+Vdo/yop+ooedCnvBC7GVMfcqR6+rIQ+ZnKom7jhByIN6w7eEVAnmNa9dCv/pig7HaYbitWmCNf9tbqFfcdY6e5Svele3amgDM9iqtdJ9Rf1PpDPZw+gmjRIxGs6W8wnl1Sqvpk8pFUA/2xlT6sXpfxra9N09LS0ttU+cU=
# 填支付宝公钥,注意不是生成的应用公钥
aliPayPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyvegkGCrz1i5/K7VzQxvoZm4G73pSPNu9R5ET8YonIuDVoHkHaYvQQizLdRkTyBsYIik8FXsSDmVsw5MLMQ7OAlZ97nQBkz5TxOX6Px766nUpSVoWXoAz6cpIlWnwgir4t1ph88Ph56l+qmqW3gUj/U6MIuzjxBJlijTMHl96its95Nd4cEFx4j+sFuRYob6D0kcemC7xEFuty7bdupda51Z56GYI1YjuUTryTlFOHZbOSThc2ZMzNC1gPG25bn2Lx6sDuPByk4KW4rQ2v7mSfeUuZZRdjtVSC0WV2M2Cv5L8eLFvZRgNYnXrUJYhnRpT+OBAvJZXaWU2nv/bNe/UQIDAQAB
# 回调地址
notifyUrl: https://count.byffp.top/api/pay/aliPay/pay-notify
# 支付宝成功支付跳转页面
returnUrl: https://count.byffp.top/statePage/success
# 可设置AES密钥调用AES加解密相关接口时需要可选
encryptKey:
wechat:
gatewayHost: https://fission-server.scrm-ai.com
appKey: uNE5DXdjwQa1iE8cBVZJbuvGfr5t9R73

@ -0,0 +1,26 @@
spring:
datasource:
url: jdbc:mysql://39.100.77.21:3306/ad_distribute?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: root
password: y7z7noq2
redis:
host: 39.100.77.21
password: sC33HXphkHBRj4Jb
port: 6379
timeout: 5000
database: 7
#mybatis plus 设置
mybatis-plus:
configuration:
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl #关闭sql日志
springdoc:
swagger-ui:
urls:
- { name: 'admin', url: '/v3/api-docs' }
- { name: 'api', url: 'http://ballcat-api/v3/api-docs' }

@ -0,0 +1,106 @@
server:
port: 8099
spring:
application:
name: @artifactId@
profiles:
active: dev
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# 天爱图形验证码
captcha:
secondary:
enabled: true
# mybatis-plus相关配置
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*Mapper.xml
global-config:
banner: false
db-config:
id-type: auto
insert-strategy: not_empty
update-strategy: not_empty
logic-delete-value: "NOW()" # 逻辑已删除值(使用当前时间标识)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
# BallCat 相关配置
ballcat:
security:
# 前端传输密码的 AES 加密密钥
password-secret-key: '==market-scrm==='
oauth2:
authorizationserver:
# 登陆验证码是否开启
login-captcha-enabled: true
# 内嵌的表单登陆页是否开启
login-page-enabled: false
resourceserver:
## 忽略鉴权的 url 列表
ignore-urls:
- /public/**
- /actuator/**
- /doc.html
- /v2/api-docs/**
- /v3/api-docs/**
- /swagger-resources/**
- /swagger-ui/**
- /webjars/**
- /bycdao-ui/**
- /favicon.ico
- /captcha/**
- /outside/**
- /wechat/global/setting
- /pay/aliPay/pay-notify
# 项目 redis 缓存的 key 前缀
redis:
key-prefix: 'marketing:'
springdoc:
# 开启 oauth2 端点显示
show-oauth2-endpoints: true
swagger-ui:
oauth:
client-id: test
client-secret: test
display-request-duration: true
disable-swagger-default-url: true
persist-authorization: true
# 文件存储路径
file:
mac:
path: ~/file/
avatar: ~/avatar/
clueFilePath: ~/cluefile/
systemSeparator: /
linux:
path: /home/marketing-scrm/file/
avatar: /home/marketing-scrm/avatar/
clueFilePath: /home/marketing-scrm/cluefile/
systemSeparator: /
windows:
path: C:\marketing-scrm\file\
avatar: C:\marketing-scrm\avatar\
clueFilePath: C:\marketing-scrm\cluefile\
systemSeparator: \
# 文件大小 /M
maxSize: 300
avatarMaxSize: 5
elasticjob:
zookeeper:
namespace: springboot-elasticjob
server-list: localhost:2181
snowflake:
workerId: 10
datacenterId: 10

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<contextName>elAdmin</contextName>
<!-- 定义日志格式基础信息 -->
<property name="LOG_DIR" value="./log/" />
<property name="LOG_PATTERN" value="%white(%contextName-) %d{yyyy-MM-dd HH:mm:ss:SS} %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{50}) - %cyan(%msg%n)" />
<property name="LOG_CHARSET" value="utf-8" />
<!--输出到控制台-->
<appender name="stdAppender" class="ch.qos.logback.core.ConsoleAppender">
<!--<withJansi>true</withJansi> &lt;!&ndash; 如果是UTF-8的环境这句要注释掉 &ndash;&gt;-->
<encoder>
<!-- <pattern>%highlight([%-5level]) %cyan(%d{yyyy-MM-dd#HH:mm:ss.SSS}) %yellow([Thread:%thread]) %magenta([Logger:%logger]) -> %msg%n</pattern>-->
<pattern>%highlight([%-5level]) %cyan(%d{yyyy-MM-dd#HH:mm:ss.SSS}) %yellow([Thread:%thread]) %magenta([Logger:%logger]) -> %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 输出到文件,并按天进行归档 -->
<appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/log.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天归档,如果按小时后面加-hh -->
<fileNamePattern>${LOG_DIR}/history/%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<append>true</append>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 不写TRACE DEBUG -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!--普通日志输出到控制台-->
<root level="info">
<appender-ref ref="stdAppender" />
</root>
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO" additivity="false">
<appender-ref ref="stdAppender" />
<appender-ref ref="fileAppender"/>
</logger>
<logger name="jdbc.resultset" level="ERROR" additivity="false">
<appender-ref ref="stdAppender" />
<appender-ref ref="fileAppender"/>
</logger>
<!-- 如想看到表格数据将OFF改为INFO -->
<logger name="jdbc.resultsettable" level="OFF" additivity="false">
<appender-ref ref="stdAppender" />
<appender-ref ref="fileAppender"/>
</logger>
<logger name="jdbc.connection" level="OFF" additivity="false">
<appender-ref ref="stdAppender" />
<appender-ref ref="fileAppender"/>
</logger>
<logger name="jdbc.sqltiming" level="OFF" additivity="false">
<appender-ref ref="stdAppender" />
<appender-ref ref="fileAppender"/>
</logger>
<logger name="jdbc.audit" level="OFF" additivity="false">
<appender-ref ref="stdAppender" />
<appender-ref ref="fileAppender"/>
</logger>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<logger name="springfox.documentation" level="warn" />
<root level="INFO">
<!-- TODO prod 环境去掉std -->
<appender-ref ref="stdAppender"/>
<appender-ref ref="fileAppender"/>
</root>
</configuration>

@ -0,0 +1,80 @@
<?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.modules.distribute.mapper.LoginEquipmentMapper">
<sql id="Base_Alias_Column_List">
wa.username,
wa.nickname,
wa.city_info,
wa.login_type,
wa.header_url,
wa.wx_id,
wa.sex,
wa.status,
wa.we_chat_no,
wa.remark,
wa.create_time,
wa.update_time,
wa.user_id,
le.id,
le.pit,
le.robot_id,
le.device_number,
le.expiration_time
</sql>
<select id="selectByPage" resultType="com.baiye.modules.distribute.vo.WeChatAccountVO">
SELECT
<include refid="Base_Alias_Column_List"/>
FROM
tb_login_equipment le left join
tb_wechat_equipment we on we.equipment_id = le.id
LEFT join tb_wechat_account wa on wa.id = we.account_id
where le.user_id = #{userId}
<if test="username != null">
AND wa.username LIKE concat('%',#{username,jdbcType=VARCHAR},'%')
</if>
<if test="wxId != null">
AND wa.wx_id LIKE concat('%',#{wxId,jdbcType=VARCHAR},'%')
</if>
<if test="startTime != null">
and wa.create_time &gt;= #{startTime,jdbcType=TIMESTAMP}
</if>
<if test="endTime != null">
and wa.create_time &lt;= #{endTime,jdbcType=TIMESTAMP}
</if>
order by le.id desc
</select>
<select id="queryByDate" resultType="com.baiye.modules.distribute.vo.WeChatAddFriendVo">
SELECT DATE_FORMAT(f.create_time, '%m-%d') dayStr
, count(1) as num
, add_friend_type
FROM tb_wechat_friend f
WHERE DATE_SUB(CURDATE(), INTERVAL #{dayNum} DAY) &lt;= date (f.create_time)
and f.robot_wx_id = #{wxId,jdbcType=VARCHAR}
and f.user_id = #{userId}
GROUP BY dayStr, add_friend_type
ORDER BY dayStr
</select>
<select id="queryByUserId" resultType="com.baiye.modules.distribute.vo.WeChatAccountVO">
SELECT
<include refid="Base_Alias_Column_List"/>
FROM
tb_login_equipment le left join
tb_wechat_equipment we on we.equipment_id = le.id
LEFT join tb_wechat_account wa on wa.id = we.account_id
where le.user_id = #{userId}
</select>
<select id="findEquipmentByAccountId" resultType="com.baiye.modules.distribute.vo.WeChatAccountVO">
SELECT
<include refid="Base_Alias_Column_List"/>
FROM
tb_login_equipment le left join
tb_wechat_equipment we on we.equipment_id = le.id
LEFT join tb_wechat_account wa on wa.id = we.account_id
where wa.wx_id = #{wxId}
</select>
</mapper>

@ -0,0 +1,36 @@
<?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.modules.distribute.mapper.WeChatFriendMapper">
<select id="queryByDate" resultType="com.baiye.modules.distribute.vo.StatisticsFriendVO">
SELECT
add_friend_type,
COUNT( 1 ) AS count
FROM
`tb_wechat_friend`
WHERE
`create_time` &gt; #{startTime} AND `create_time` &lt; #{endTime} and user_id = #{userId}
GROUP BY
add_friend_type
</select>
<select id="queryByUserList" resultType="com.baiye.modules.distribute.vo.WeChatAddFriendVo">
SELECT DATE_FORMAT(create_time, '%m-%d') dayStr
, count(1) as num
, add_friend_type
FROM tb_wechat_friend
WHERE DATE_SUB(CURDATE(), INTERVAL #{dayNum} DAY) &lt;= date (create_time)
and create_time &lt;= #{endTime}
and create_time &gt;= #{startTime}
and user_id = #{userId}
<if test="weChatIdList != null and weChatIdList.size() > 0">
and robot_wx_id in
<foreach collection="weChatIdList" open="(" separator="," close=")" item="item">
#{item}
</foreach>
</if>
GROUP BY dayStr, add_friend_type
ORDER BY dayStr
</select>
</mapper>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-admin</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>admin-core</module>
<module>admin-websocket</module>
</modules>
</project>

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-admin</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.baiye</groupId>
<artifactId>admin-core</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-desensitize</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-model</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>security-oauth2-authorization-server</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>system-controller</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-web</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-notify-controller</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>marketing-scrm-admin</artifactId>
<groupId>com.baiye</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>admin-core</artifactId>
<dependencies>
<!--mybatis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- 脱敏工具 -->
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-desensitize</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>common-model</artifactId>
</dependency>
<!-- 基于 spring authorization server 的授权服务器 -->
<dependency>
<groupId>com.baiye</groupId>
<artifactId>security-oauth2-authorization-server</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>system-controller</artifactId>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-web</artifactId>
<version>${revision}</version>
</dependency>
<!-- notify 通知模块 -->
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-notify-controller</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,106 @@
package com.baiye.upms;
//import com.hccake.ballcat.admin.upms.log.LogConfiguration;
import com.baiye.system.authentication.BallcatOAuth2TokenResponseEnhancer;
import com.baiye.system.authentication.DefaultUserInfoCoordinatorImpl;
import com.baiye.system.authentication.SysUserDetailsServiceImpl;
import com.baiye.system.authentication.UserInfoCoordinator;
import com.baiye.system.properties.SystemProperties;
import com.baiye.system.service.SysUserService;
import org.ballcat.security.properties.SecurityProperties;
import org.ballcat.springsecurity.oauth2.server.authorization.web.authentication.OAuth2TokenResponseEnhancer;
import org.ballcat.springsecurity.oauth2.server.resource.introspection.SpringAuthorizationServerSharedStoredOpaqueTokenIntrospector;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
/**
* @author Hccake 2020/5/25 21:01
*/
@EnableAsync
@AutoConfiguration
@MapperScan("com.baiye.**.mapper")
// @ComponentScan({ "com.hccake.ballcat.admin.upms", "com.hccake.ballcat.system",
// "com.hccake.ballcat.log",
// "com.hccake.ballcat.file", "com.hccake.ballcat.notify" })
@ComponentScan({ "com.baiye.upms", "com.baiye.system" })
@EnableConfigurationProperties({ SystemProperties.class, SecurityProperties.class })
public class UpmsAutoConfiguration {
/**
*
*
* @author hccake
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(SysUserService.class)
@ConditionalOnMissingBean(UserDetailsService.class)
static class UserDetailsServiceConfiguration {
/**
*
* @return SysUserDetailsServiceImpl
*/
@Bean
@ConditionalOnMissingBean
public UserDetailsService userDetailsService(SysUserService sysUserService,
UserInfoCoordinator userInfoCoordinator) {
return new SysUserDetailsServiceImpl(sysUserService, userInfoCoordinator);
}
/**
*
* @return UserInfoCoordinator
*/
@Bean
@ConditionalOnMissingBean
public UserInfoCoordinator userInfoCoordinator() {
return new DefaultUserInfoCoordinatorImpl();
}
}
/**
* spring-security-oauth2-authorization-server 使
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OAuth2Authorization.class)
static class SpringOAuth2AuthorizationServerConfiguration {
/**
* token
* @return TokenEnhancer Token
*/
@Bean
@ConditionalOnMissingBean
public OAuth2TokenResponseEnhancer oAuth2TokenResponseEnhancer() {
return new BallcatOAuth2TokenResponseEnhancer();
}
/**
* token 使 OAuth2AuthorizationService token
* @return SpringAuthorizationServerSharedStoredOpaqueTokenIntrospector
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "ballcat.security.oauth2.resourceserver", name = "shared-stored-token",
havingValue = "true", matchIfMissing = true)
public OpaqueTokenIntrospector sharedStoredOpaqueTokenIntrospector(
OAuth2AuthorizationService authorizationService) {
return new SpringAuthorizationServerSharedStoredOpaqueTokenIntrospector(authorizationService);
}
}
}

@ -0,0 +1,42 @@
package com.baiye.upms.config.mybatis;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baiye.constant.GlobalConstants;
import com.baiye.security.userdetails.User;
import com.baiye.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import java.time.LocalDateTime;
/**
* @author Hccake 2019/7/26 14:41
*/
@Slf4j
public class FillMetaObjectHandle implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 逻辑删除标识
this.strictInsertFill(metaObject, "deleted", Long.class, GlobalConstants.NOT_DELETED_FLAG);
// 创建时间
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
// 创建人
User user = SecurityUtils.getUser();
if (user != null) {
this.strictInsertFill(metaObject, "createBy", Long.class, user.getUserId());
}
}
@Override
public void updateFill(MetaObject metaObject) {
// 修改时间
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
// 修改人
User user = SecurityUtils.getUser();
if (user != null) {
this.strictUpdateFill(metaObject, "updateBy", Long.class, user.getUserId());
}
}
}

@ -0,0 +1,62 @@
package com.baiye.upms.config.mybatis;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baiye.extend.mybatis.plus.injector.CustomSqlInjector;
import com.baiye.extend.mybatis.plus.methods.InsertBatchSomeColumnByCollection;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author hccake
* @date 2020/04/19 MybatisPlusconditional
*/
@Configuration
public class MybatisPlusConfig {
/**
* MybatisPlusInterceptor </br>
* MPBean
* @return MybatisPlusInterceptor
*/
@Bean
@ConditionalOnMissingBean(MybatisPlusInterceptor.class)
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
/**
*
* @return FillMetaObjectHandle
*/
@Bean
@ConditionalOnMissingBean(MetaObjectHandler.class)
public MetaObjectHandler fillMetaObjectHandle() {
return new FillMetaObjectHandle();
}
/**
*
* @return ISqlInjector
*/
@Bean
@ConditionalOnMissingBean(ISqlInjector.class)
public ISqlInjector customSqlInjector() {
List<AbstractMethod> list = new ArrayList<>();
// 对于只在更新时进行填充的字段不做插入处理
list.add(new InsertBatchSomeColumnByCollection(t -> t.getFieldFill() != FieldFill.UPDATE));
return new CustomSqlInjector(list);
}
}

@ -0,0 +1,34 @@
package com.baiye.upms.config.task;
import cn.hutool.core.map.MapUtil;
import org.slf4j.MDC;
import org.springframework.core.task.TaskDecorator;
import java.util.Map;
/**
* 使asynctraceId
*
* @author huyuanzhi 2021-11-06 23:14:27
*/
public class MdcTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
final Map<String, String> copyOfContextMap = MDC.getCopyOfContextMap();
return () -> {
if (MapUtil.isNotEmpty(copyOfContextMap)) {
// 现在:@Async线程上下文 恢复Web线程上下文的MDC数据
MDC.setContextMap(copyOfContextMap);
}
try {
runnable.run();
}
finally {
MDC.clear();
}
};
}
}

@ -0,0 +1,35 @@
package com.baiye.upms.config.task;
import org.springframework.boot.task.TaskExecutorCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线线
*
* @see org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
* @author hccake
*/
@Configuration(proxyBeanMethods = false)
public class TaskExecutionConfiguration {
/**
* springboot taskExecutor 使线
* @return TaskExecutorCustomizer
*/
@Bean
public TaskExecutorCustomizer taskExecutorCustomizer() {
// AbortPolicy: 直接抛出java.util.concurrent.RejectedExecutionException异常
// CallerRunsPolicy: 主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度
// DiscardOldestPolicy: 抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行
// DiscardPolicy: 抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行
// 这里使用主线程直接执行该任务
return (taskExecutor -> {
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setTaskDecorator(new MdcTaskDecorator());
});
}
}

@ -0,0 +1,78 @@
// package com.hccake.ballcat.admin.upms.log;
//
// import com.hccake.ballcat.common.log.access.handler.AccessLogHandler;
// import com.hccake.ballcat.common.log.operation.handler.OperationLogHandler;
// import com.hccake.ballcat.log.handler.CustomAccessLogHandler;
// import com.hccake.ballcat.log.handler.CustomOperationLogHandler;
// import com.hccake.ballcat.log.model.entity.AccessLog;
// import com.hccake.ballcat.log.model.entity.OperationLog;
// import com.hccake.ballcat.log.service.AccessLogService;
// import com.hccake.ballcat.log.service.LoginLogService;
// import com.hccake.ballcat.log.service.OperationLogService;
// import com.hccake.ballcat.log.thread.AccessLogSaveThread;
// import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
// import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
// import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
// import org.springframework.context.annotation.Bean;
// import org.springframework.context.annotation.Configuration;
// import
// org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
// import
// org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
//
/// **
// * @author hccake
// */
// @Configuration(proxyBeanMethods = false)
// @ConditionalOnClass(LoginLogService.class)
// public class LogConfiguration {
//
// /**
// * 访问日志保存
// * @param accessLogService 访问日志Service
// * @return CustomAccessLogHandler
// */
// @Bean
// @ConditionalOnBean(AccessLogService.class)
// @ConditionalOnMissingBean(AccessLogHandler.class)
// public AccessLogHandler<AccessLog> customAccessLogHandler(AccessLogService
// accessLogService) {
// return new CustomAccessLogHandler(new AccessLogSaveThread(accessLogService));
// }
//
// /**
// * 操作日志处理器
// * @param operationLogService 操作日志Service
// * @return CustomOperationLogHandler
// */
// @Bean
// @ConditionalOnBean(OperationLogService.class)
// @ConditionalOnMissingBean(OperationLogHandler.class)
// public OperationLogHandler<OperationLog> customOperationLogHandler(OperationLogService
// operationLogService) {
// return new CustomOperationLogHandler(operationLogService);
// }
//
// @ConditionalOnClass(OAuth2AuthorizationServerConfigurer.class)
// @ConditionalOnBean(LoginLogService.class)
// @ConditionalOnMissingBean(LoginLogHandler.class)
// @Configuration(proxyBeanMethods = false)
// static class SpringAuthorizationServerLoginLogConfiguration {
//
// /**
// * Spring Authorization Server 的登录日志处理,监听登录事件记录登录登出
// * @param loginLogService 操作日志Service
// * @param authorizationServerSettings 授权服务器设置
// * @return SpringAuthorizationServerLoginLogHandler
// */
// @Bean
// public LoginLogHandler springAuthorizationServerLoginLogHandler(LoginLogService
// loginLogService,
// AuthorizationServerSettings authorizationServerSettings) {
// return new SpringAuthorizationServerLoginLogHandler(loginLogService,
// authorizationServerSettings);
// }
//
// }
//
// }

@ -0,0 +1,8 @@
package com.baiye.upms.log;
/**
* @author hccake
*/
public interface LoginLogHandler {
}

@ -0,0 +1,140 @@
// package com.hccake.ballcat.admin.upms.log;
//
// import com.hccake.ballcat.common.core.util.WebUtils;
//// import com.hccake.ballcat.common.log.operation.enums.LogStatusEnum;
// import com.hccake.ballcat.common.security.util.SecurityUtils;
//// import com.hccake.ballcat.log.enums.LoginEventTypeEnum;
//// import com.hccake.ballcat.log.model.entity.LoginLog;
//// import com.hccake.ballcat.log.service.LoginLogService;
// import lombok.RequiredArgsConstructor;
// import
// org.ballcat.springsecurity.oauth2.server.authorization.authentication.OAuth2TokenRevocationAuthenticationToken;
// import org.springframework.context.event.EventListener;
// import org.springframework.security.authentication.ProviderNotFoundException;
// import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
// import
// org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
// import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
// import org.springframework.security.authentication.event.LogoutSuccessEvent;
// import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
// import
// org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken;
// import
// org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken;
// import
// org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
//
// import javax.servlet.http.HttpServletRequest;
//
//// import static com.hccake.ballcat.log.handler.LoginLogUtils.prodLoginLog;
//
/// **
// * spring 授权服务器的登录日志处理器
// *
// * @author hccake
// */
// @RequiredArgsConstructor
// public class SpringAuthorizationServerLoginLogHandler implements LoginLogHandler {
//
//// private final LoginLogService loginLogService;
//
// private final AuthorizationServerSettings authorizationServerSettings;
//
// /**
// * 登录成功事件监听 记录用户登录日志
// * @param event 登录成功 event
// */
// @EventListener(AuthenticationSuccessEvent.class)
// public void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) {
// Object source = event.getSource();
// String username = null;
//
// String tokenEndpoint = authorizationServerSettings.getTokenEndpoint();
// HttpServletRequest request = WebUtils.getRequest();
// boolean isOauth2LoginRequest = request.getRequestURI().equals(tokenEndpoint);
//
// // Oauth2登录 和表单登录 处理分开
// if (isOauth2LoginRequest && source instanceof OAuth2AccessTokenAuthenticationToken) {
// username = SecurityUtils.getAuthentication().getName();
// }
// else if (!isOauth2LoginRequest && source instanceof
// UsernamePasswordAuthenticationToken) {
// username = ((UsernamePasswordAuthenticationToken) source).getName();
// }
//
//// if (username != null) {
//// LoginLog loginLog = prodLoginLog(username).setMsg("登录成功")
//// .setStatus(LogStatusEnum.SUCCESS.getValue())
//// .setEventType(LoginEventTypeEnum.LOGIN.getValue());
//// loginLogService.save(loginLog);
//// }
// }
//
// /**
// * 监听鉴权失败事件,记录登录失败日志
// * @param event the event
// */
// @EventListener(AbstractAuthenticationFailureEvent.class)
// public void onAuthenticationFailureEvent(AbstractAuthenticationFailureEvent event) {
// if (event.getException().getClass().isAssignableFrom(ProviderNotFoundException.class))
// {
// return;
// }
//
// Object source = event.getSource();
// String username = null;
//
// String tokenEndpoint = authorizationServerSettings.getTokenEndpoint();
// HttpServletRequest request = WebUtils.getRequest();
// boolean isOauth2LoginRequest = request.getRequestURI().equals(tokenEndpoint);
//
// // Oauth2登录 和表单登录 处理分开
// if (isOauth2LoginRequest && source instanceof
// OAuth2AuthorizationGrantAuthenticationToken) {
// username = ((OAuth2AuthorizationGrantAuthenticationToken) source).getName();
// }
// else if (!isOauth2LoginRequest && source instanceof
// UsernamePasswordAuthenticationToken) {
// username = ((UsernamePasswordAuthenticationToken) source).getName();
// }
//
//// if (username != null) {
//// LoginLog loginLog = prodLoginLog(username).setMsg(event.getException().getMessage())
//// .setEventType(LoginEventTypeEnum.LOGIN.getValue())
//// .setStatus(LogStatusEnum.FAIL.getValue());
//// loginLogService.save(loginLog);
//// }
// }
//
// /**
// * 登出成功事件监听
// * @param event the event
// */
// @EventListener(LogoutSuccessEvent.class)
// public void onLogoutSuccessEvent(LogoutSuccessEvent event) {
// Object source = event.getSource();
// String username = null;
//
// String tokenRevocationEndpoint =
// authorizationServerSettings.getTokenRevocationEndpoint();
// HttpServletRequest request = WebUtils.getRequest();
// boolean isOauth2Login = request.getRequestURI().equals(tokenRevocationEndpoint);
//
// // Oauth2撤销令牌 和表单登出 处理分开
// if (isOauth2Login && source instanceof OAuth2TokenRevocationAuthenticationToken) {
// OAuth2Authorization authorization = ((OAuth2TokenRevocationAuthenticationToken)
// source).getAuthorization();
// username = authorization.getPrincipalName();
// }
// else if (!isOauth2Login && source instanceof UsernamePasswordAuthenticationToken) {
// username = ((UsernamePasswordAuthenticationToken) source).getName();
// }
//
//// if (username != null) {
//// LoginLog loginLog = prodLoginLog(username).setMsg("登出成功")
//// .setEventType(LoginEventTypeEnum.LOGOUT.getValue());
//// loginLogService.save(loginLog);
//// }
// }
//
// }

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.baiye.upms.UpmsAutoConfiguration

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-admin</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.baiye</groupId>
<artifactId>admin-websocket</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>admin-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-websocket</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>distribute-notify-biz</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>marketing-scrm-admin</artifactId>
<groupId>com.baiye</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>admin-websocket</artifactId>
<dependencies>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>admin-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>marketing-scrm-starter-websocket</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.baiye</groupId>
<artifactId>distribute-notify-biz</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save