提交最终文件

master
LWJ 1 year ago
commit 88ca2b015e

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

@ -0,0 +1,161 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.zwz</groupId>
<artifactId>s006</artifactId>
<description>校园失物招领管理系统</description>
<version>3.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 实体类字段验证-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- HTTP请求-->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
<!-- 热更新 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<!-- MybatisPlus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- Redis扩展-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.21.3</version>
</dependency>
<!-- XML转换-->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.20</version>
</dependency>
<!-- JSON-->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.33</version>
</dependency>
<!-- Mysql -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- Swagger因为SpringBoot3.0不支持,所以只是为了注释而用 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<!-- Hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.19</version>
</dependency>
<!-- Excel 请勿更新 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.10-FINAL</version>
</dependency>
<!-- 代码生成 请勿更新 -->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>2.9.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<jvmArguments>
-Dfile.encoding=UTF-8 -Ddruid.mysql.usePingMethod=false
</jvmArguments>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,21 @@
package cn.zwz;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableJpaAuditing
@EnableCaching
@EnableAsync
@EnableScheduling
public class ZwzApplication {
public static void main(String[] args) {
SpringApplication.run(ZwzApplication.class, args);
}
}

@ -0,0 +1,44 @@
package cn.zwz.basics.baseClass;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
@Configuration
@Slf4j
@ApiOperation(value = "SpringBoot启动配置类")
@Import(cn.hutool.extra.spring.SpringUtil.class)
public class BeansConfiguration {
@Bean
@ApiOperation(value = "初始化PathMatcher")
public PathMatcher pathMatcher(){
log.info("初始化PathMatcher成功");
return new AntPathMatcher();
}
@Primary
@Bean
@ApiOperation(value = "初始化线程池")
public TaskExecutor primaryTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
log.info("初始化线程池成功");
return executor;
}
@Bean
@ApiOperation(value = "初始化Redis锁")
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "zwz-lock");
}
}

@ -0,0 +1,37 @@
package cn.zwz.basics.baseClass;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.data.entity.User;
import cn.zwz.data.service.IUserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@ApiOperation(value = "启动执行类")
public class StartBean implements ApplicationRunner {
@Autowired
private IUserService iUserService;
@Autowired
private RedisTemplateHelper redisTemplate;
private static final String REDIS_USER_PRE = "USER:";
@Override
@ApiOperation(value = "启动执行方法",notes = "用于日志记录用户姓名")
public void run(ApplicationArguments args) {
List<User> userList = iUserService.list();
for (User user : userList) {
if(user.getNickname() != null && user.getUsername() != null) {
redisTemplate.set(REDIS_USER_PRE + user.getUsername(), user.getNickname());
}
}
}
}

@ -0,0 +1,80 @@
package cn.zwz.basics.baseClass;
import cn.zwz.basics.utils.PageUtil;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.baseVo.PageVo;
import cn.zwz.basics.baseVo.Result;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.List;
@ApiOperation(value = "模板控制器层")
public abstract class ZwzBaseController<E, ID extends Serializable> {
@Autowired
public abstract ZwzBaseService<E,ID> getZwzService();
@RequestMapping(value = "/getOne", name = "查询单个数据", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "查询单个数据")
public Result<E> getOne(@RequestParam ID id){
return new ResultUtil<E>().setData(getZwzService().get(id));
}
@RequestMapping(value = "/getAll", name = "查询全部数据", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "查询全部数据")
public Result<List<E>> getAll(){
return new ResultUtil<List<E>>().setData(getZwzService().getAll());
}
@RequestMapping(value = "/getByPage", name = "查询数据", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "查询数据")
public Result<Page<E>> getByPage(PageVo page){
return new ResultUtil<Page<E>>().setData(getZwzService().findAll(PageUtil.initPage(page)));
}
@RequestMapping(value = "/save", name = "新增数据", method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "新增数据")
public Result<E> save(E entity){
return new ResultUtil<E>().setData(getZwzService().save(entity));
}
@RequestMapping(value = "/update", name = "编辑数据", method = RequestMethod.PUT)
@ResponseBody
@ApiOperation(value = "编辑数据")
public Result<E> update(E entity){
return new ResultUtil<E>().setData(getZwzService().update(entity));
}
@RequestMapping(value = "/count", name = "查询数据条数", method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "查询数据条数")
public Result<Long> count(){
return new ResultUtil<Long>().setData(getZwzService().count());
}
@RequestMapping(value = "/delOne", name = "删除数据", method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "删除数据")
public Result<Object> delByIds(@RequestParam ID id){
getZwzService().delete(id);
return new ResultUtil<Object>().setSuccessMsg("OK");
}
@RequestMapping(value = "/delByIds", name = "删除数据", method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "删除数据")
public Result<Object> delByIds(@RequestParam ID[] ids){
for(ID id:ids){
getZwzService().delete(id);
}
return new ResultUtil<Object>().setSuccessMsg("OK");
}
}

@ -0,0 +1,16 @@
package cn.zwz.basics.baseClass;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import java.io.Serializable;
@ApiOperation(value = "模板数据链路层")
@NoRepositoryBean
public interface ZwzBaseDao<E, ID extends Serializable> extends JpaRepository<E, ID>, JpaSpecificationExecutor<E> {
@Override
E getById(ID id);
}

@ -0,0 +1,68 @@
package cn.zwz.basics.baseClass;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Date;
@ApiOperation(value = "模板实体类")
@Data
@AllArgsConstructor
@NoArgsConstructor
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
public abstract class ZwzBaseEntity implements Serializable{
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID")
@Id
@TableId
private String id = IdUtil.getSnowflake(1, 1).nextId() + "";
@LastModifiedBy
@TableField(fill = FieldFill.UPDATE)
@ApiModelProperty(value = "最后更新人")
private String updateBy;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.UPDATE)
@LastModifiedDate
@ApiModelProperty(value = "更新时间")
private Date updateTime;
@CreatedBy
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建者")
private String createBy;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
@CreatedDate
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "逻辑删除")
private int delFlag;
}

@ -0,0 +1,66 @@
package cn.zwz.basics.baseClass;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.io.Serializable;
import java.util.List;
@ApiOperation(value = "模板服务层")
@FunctionalInterface
public interface ZwzBaseService<E, ID extends Serializable> {
ZwzBaseDao<E, ID> getRepository();
@ApiOperation(value = "查询")
default E get(ID id) {
return getRepository().findById(id).orElse(null);
}
@ApiOperation(value = "查询")
default List<E> getAll() {
return getRepository().findAll();
}
@ApiOperation(value = "新增")
default E save(E entity) {
return getRepository().save(entity);
}
@ApiOperation(value = "编辑")
default E update(E entity) {
return getRepository().saveAndFlush(entity);
}
@ApiOperation(value = "批量保存")
default Iterable<E> saveOrUpdateAll(Iterable<E> entities) {
return getRepository().saveAll(entities);
}
@ApiOperation(value = "计数")
default Long count() {
return getRepository().count();
}
@ApiOperation(value = "删除")
default void delete(E entity) {
getRepository().delete(entity);
}
@ApiOperation(value = "删除")
default void delete(ID id) {
getRepository().deleteById(id);
}
@ApiOperation(value = "删除")
default void delete(Iterable<E> entities) {
getRepository().deleteAllInBatch(entities);
}
@ApiOperation(value = "查询")
default Page<E> findAll(Pageable pageable){
return getRepository().findAll(pageable);
}
}

@ -0,0 +1,31 @@
package cn.zwz.basics.baseVo;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@ApiOperation(value = "分页VO类")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "排序名称", notes = "排序的字段名")
private String sort;
@ApiModelProperty(value = "页码编号", notes = "即展示第几页")
private int pageNumber;
@ApiModelProperty(value = "排序类型", notes = "升序asc,降序desc")
private String order;
@ApiModelProperty(value = "每页个数", notes = "建议设置为15")
private int pageSize;
}

@ -0,0 +1,34 @@
package cn.zwz.basics.baseVo;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@ApiOperation(value = "返回数据VO类")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> implements Serializable{
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "返回主数据",notes = "泛型")
private T result;
@ApiModelProperty(value = "是否请求成功",notes = "true为请求成功,false为请求失败")
private boolean success;
@ApiModelProperty(value = "返回状态代码",notes = "默认200为成功")
private Integer code;
@ApiModelProperty(value = "时间戳",notes = "当前系统的时间戳")
private long timestamp = System.currentTimeMillis();
@ApiModelProperty(value = "提示信息",notes = "额外的提示信息")
private String message;
}

@ -0,0 +1,29 @@
package cn.zwz.basics.baseVo;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@ApiOperation(value = "临时用户类")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TokenUser implements Serializable{
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "拥有的菜单权限")
private List<String> permissions;
@ApiModelProperty(value = "是否自动登录")
private Boolean saveLogin;
}

@ -0,0 +1,29 @@
package cn.zwz.basics.code;
import cn.zwz.basics.code.vue.MyBatisPlusUtils;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ApiOperation(value = "后端代码生成器执行类")
public class MyBatisPlusCodeUtils {
@ApiOperation(value = "一键产生增删改查代码")
public static void main(String[] args) throws Exception {
new MyBatisPlusUtils(CLASS_NAME,DESCRIPTION,CLASS_PATH,REMOVE_FLAG).work();
}
@ApiModelProperty(value = "类名")
private static final String CLASS_NAME = "DynamicTableData";
@ApiModelProperty(value = "类备注")
private static final String DESCRIPTION = "动态表格值";
@ApiModelProperty(value = "生成路径")
private static final String CLASS_PATH = "cn.zwz.test";
@ApiModelProperty(value = "是否删除代码")
private static final Boolean REMOVE_FLAG = false;
}

@ -0,0 +1,54 @@
package cn.zwz.basics.code.bean;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ApiOperation(value = "代码生成器基础类")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Entity {
@ApiModelProperty(value = "控制器层包")
private String controllerPackage;
@ApiModelProperty(value = "服务层实现包")
private String serviceImplPackage;
@ApiModelProperty(value = "服务层接口包")
private String servicePackage;
@ApiModelProperty(value = "数据链路层包")
private String daoPackage;
@ApiModelProperty(value = "实体VO包")
private String entityPackage;
@ApiModelProperty(value = "类名")
private String className;
@ApiModelProperty(value = "类名小写")
private String classNameLowerCase;
@ApiModelProperty(value = "备注")
private String description;
@ApiModelProperty(value = "作者")
private String author;
@ApiModelProperty(value = "表名")
private String tableName;
@ApiModelProperty(value = "主键数据类型")
private String primaryKeyType;
@ApiModelProperty(value = "是否树状")
private Boolean isTree;
@ApiModelProperty(value = "是否流程")
private Boolean activiti;
}

@ -0,0 +1,55 @@
package cn.zwz.basics.code.bean;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import java.math.BigDecimal;
@ApiOperation(value = "代码生成器基础类")
@Data
public class Field {
@ApiModelProperty(value = "字段名称")
private String name;
@ApiModelProperty(value = "字段标识")
private String field;
@ApiModelProperty(value = "字段层级")
private String level;
@ApiModelProperty(value = "是否在表格显示")
private Boolean tableShow;
@ApiModelProperty(value = "排序值")
private BigDecimal sortOrder;
@ApiModelProperty(value = "是否可搜索")
private Boolean searchable;
@ApiModelProperty(value = "是否可添加编辑")
private Boolean editable;
@ApiModelProperty(value = "字段类型")
private String type;
@ApiModelProperty(value = "搜索层级")
private String searchLevel;
@ApiModelProperty(value = "搜索栏类型")
private String searchType;
@ApiModelProperty(value = "默认排序规则")
private String defaultSortType;
@ApiModelProperty(value = "字段")
private Boolean validate;
@ApiModelProperty(value = "是否为默认排序")
private Boolean defaultSort;
@ApiModelProperty(value = "是否可排序")
private Boolean sortable;
}

@ -0,0 +1,30 @@
package cn.zwz.basics.code.bean;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ApiOperation(value = "代码生成器基础类")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Item {
@ApiModelProperty(value = "子项标题")
private String title;
@ApiModelProperty(value = "子项类别")
private String type;
@ApiModelProperty(value = "子项大写")
private String upperName;
@ApiModelProperty(value = "子项小写")
private String lowerName;
@ApiModelProperty(value = "子项行名")
private String lineName;
}

@ -0,0 +1,286 @@
package cn.zwz.basics.code.vue;
import cn.hutool.core.date.DateUtil;
import cn.zwz.basics.code.bean.Entity;
import cn.zwz.basics.exception.ZwzException;
import cn.zwz.data.utils.ZwzNullUtils;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;
/**
* @author
* CSDN: Designer
*/
@Slf4j
@ApiOperation(value = "后端代码生成器")
public class MyBatisPlusUtils {
public MyBatisPlusUtils(String className,String description,String path,Boolean removeFlag) {
this.className = className;
this.description = description;
this.entityPackage = path + ".entity";
this.daoPackage = path + ".mapper";
this.servicePackage = path + ".service";
this.serviceImplPackage = path + ".serviceimpl";
this.controllerPackage = path + ".controller";
this.removeFlag = removeFlag;
}
public void work() throws IOException {
ClasspathResourceLoader crl = new ClasspathResourceLoader("/template/");
GroupTemplate gt = new GroupTemplate(crl, Configuration.defaultConfiguration());
// 一键产生增删改查代码
this.createNewCode(gt);
if(this.removeFlag) {
// 一键移除生成的代码
removeNewCode(this.className);
}
}
@ApiModelProperty(value = "是否删除代码")
private Boolean removeFlag = false;
@ApiModelProperty(value = "类名")
private String className = "";
@ApiModelProperty(value = "类备注")
private String description = "";
@ApiModelProperty(value = "作者")
private static final String author = "郑为中";
@ApiModelProperty(value = "数据库表前缀")
private static final String tablePre = "a_";
@ApiModelProperty(value = "主键类型")
private static final String primaryKeyType = "String";
@ApiModelProperty(value = "实体类对应包")
private String entityPackage = "";
@ApiModelProperty(value = "dao对应包")
private String daoPackage = "";
@ApiModelProperty(value = "service对应包")
private String servicePackage = "";
@ApiModelProperty(value = "serviceImpl对应包")
private String serviceImplPackage = "";
@ApiModelProperty(value = "controller对应包")
private String controllerPackage = "";
@ApiOperation(value = "生成代码")
private void createNewCode(GroupTemplate gt) throws IOException {
Template entityTemplate = gt.getTemplate("entity.btl");
Template daoTemplate = gt.getTemplate("mapper.btl");
Template serviceTemplate = gt.getTemplate("mpService.btl");
Template serviceImplTemplate = gt.getTemplate("mpServiceImpl.btl");
Template controllerTemplate = gt.getTemplate("mpController.btl");
Template mapperXmlTemplate = gt.getTemplate("mapperXml.btl");
Entity entity = new Entity();
entity.setEntityPackage(entityPackage);
entity.setDaoPackage(daoPackage);
entity.setServicePackage(servicePackage);
entity.setServiceImplPackage(serviceImplPackage);
entity.setControllerPackage(controllerPackage);
entity.setAuthor(author);
entity.setClassName(name(className, true));
entity.setTableName(tablePre+camel2Underline(className));
entity.setClassNameLowerCase(name(className, false));
entity.setDescription(description);
entity.setPrimaryKeyType(primaryKeyType);
entity.setActiviti(false);
entity.setIsTree(false);
OutputStream out = null;
/**
*
*/
entityTemplate.binding("entity", entity);
String entityRrender = entityTemplate.render();
String entityFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(entityPackage) + "/" + className + ".java";
File entityFile = new File(entityFileUrl);
File entityDir = entityFile.getParentFile();
if (!entityDir.exists()) {
entityDir.mkdirs();
}
if(!entityFile.exists()){
// 若文件存在则不重新生成
entityFile.createNewFile();
out = new FileOutputStream(entityFile);
entityTemplate.renderTo(out);
}
/**
* Dao
*/
daoTemplate.binding("entity",entity);
String daoResult = daoTemplate.render();
String daoFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(daoPackage) + "/" +className + "Mapper.java";
File daoFile = new File(daoFileUrl);
File daoDir = daoFile.getParentFile();
if (!daoDir.exists()) {
daoDir.mkdirs();
}
if(!daoFile.exists()) {
daoFile.createNewFile();
out = new FileOutputStream(daoFile);
daoTemplate.renderTo(out);
}
/**
* Service
*/
serviceTemplate.binding("entity",entity);
String serviceResult = serviceTemplate.render();
String serviceFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(servicePackage) + "/I" + className + "Service.java";
File serviceFile = new File(serviceFileUrl);
File serviceDir = serviceFile.getParentFile();
if (!serviceDir.exists()) {
serviceDir.mkdirs();
}
if(!serviceFile.exists()) {
serviceFile.createNewFile();
out = new FileOutputStream(serviceFile);
serviceTemplate.renderTo(out);
}
/**
* serviceImpl
*/
serviceImplTemplate.binding("entity",entity);
String serviceImplResult = serviceImplTemplate.render();
String serviceImplFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(serviceImplPackage) + "/I" + className + "ServiceImpl.java";
File serviceImplFile = new File(serviceImplFileUrl);
File serviceImplDir = serviceImplFile.getParentFile();
if (!serviceImplDir.exists()) {
serviceImplDir.mkdirs();
}
if(!serviceImplFile.exists()) {
serviceImplFile.createNewFile();
out = new FileOutputStream(serviceImplFile);
serviceImplTemplate.renderTo(out);
}
/**
* controller
*/
controllerTemplate.binding("entity",entity);
String controllerResult = controllerTemplate.render();
String controllerFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(controllerPackage) + "/" + className + "Controller.java";
File controllerFile = new File(controllerFileUrl);
File controllerDir = controllerFile.getParentFile();
if (!controllerDir.exists()) {
controllerDir.mkdirs();
}
if(!controllerFile.exists()) {
controllerFile.createNewFile();
out = new FileOutputStream(controllerFile);
controllerTemplate.renderTo(out);
}
/**
* mapperXml
*/
mapperXmlTemplate.binding("entity",entity);
String mapperXmlResult = mapperXmlTemplate.render();
String mapperXmlFileUrl = System.getProperty("user.dir")+"/src/main/resources/mapper/" + className + "Mapper.xml";
File mapperXmlFile = new File(mapperXmlFileUrl);
File mapperXmlDir = mapperXmlFile.getParentFile();
if (!mapperXmlDir.exists()) {
mapperXmlDir.mkdirs();
}
if(!mapperXmlFile.exists()) {
mapperXmlFile.createNewFile();
out = new FileOutputStream(mapperXmlFile);
mapperXmlTemplate.renderTo(out);
}
// 关闭流
if(out!=null){
out.close();
}
log.info("【生成代码成功】" + DateUtil.now());
}
@ApiOperation(value = "删除代码")
private void removeNewCode(String className) {
String entityFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(entityPackage) + "/" +className+".java";
File entityFile = new File(entityFileUrl);
if(entityFile.exists()){
entityFile.delete();
}
String daoFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(daoPackage) + "/" +className+"Mapper.java";
File daoFile = new File(daoFileUrl);
if(daoFile.exists()){
daoFile.delete();
}
String serviceFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(servicePackage) + "/I" +className+"Service.java";
File serviceFile = new File(serviceFileUrl);
if(serviceFile.exists()){
serviceFile.delete();
}
String serviceImplFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(serviceImplPackage) + "/I" +className+"ServiceImpl.java";
File serviceImplFile = new File(serviceImplFileUrl);
if(serviceImplFile.exists()){
serviceImplFile.delete();
}
String controllerFileUrl = System.getProperty("user.dir")+"/src/main/java/"+ dotToLine(controllerPackage) + "/" +className+"Controller.java";
File controllerFile = new File(controllerFileUrl);
if(controllerFile.exists()){
controllerFile.delete();
}
String mapperXmlFileUrl = System.getProperty("user.dir")+"/src/main/resources/mapper/" + className + "Mapper.xml";
File mapperXmlFile = new File(mapperXmlFileUrl);
if(mapperXmlFile.exists()){
mapperXmlFile.delete();
}
log.info("【删除代码成功】" + DateUtil.now());
}
@ApiOperation(value = "点转斜线")
public static String dotToLine(String dotContext){
return dotContext.replace(".", "/");
}
@ApiOperation(value = "驼峰法转下划线")
public static String camel2Underline(String camelContext) {
if (ZwzNullUtils.isNull(camelContext)) {
return "";
}
if(Objects.equals(1,camelContext.length())){
return camelContext.toLowerCase();
}
StringBuffer stringBuffer = new StringBuffer();
for(int i = 1; i < camelContext.length(); i ++){
if(Character.isUpperCase(camelContext.charAt(i))){
stringBuffer.append("_" + Character.toLowerCase(camelContext.charAt(i)));
}else{
stringBuffer.append(camelContext.charAt(i));
}
}
return (camelContext.charAt(0) + stringBuffer.toString()).toLowerCase();
}
@ApiOperation(value = "首字母是否大小写")
public static String name(String classTitle, boolean isFirstUpper){
if(ZwzNullUtils.isNull(classTitle)){
throw new ZwzException("类名的长度必须是正数");
}
if(Objects.equals(1,classTitle.length())){
return isFirstUpper ? classTitle.toUpperCase() : classTitle.toLowerCase();
}
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(isFirstUpper ? Character.toUpperCase(classTitle.charAt(0)) : Character.toLowerCase(classTitle.charAt(0)));
stringBuffer.append(classTitle.substring(1));
return stringBuffer.toString();
}
}

@ -0,0 +1,297 @@
package cn.zwz.basics.code.vue;
import cn.hutool.core.util.StrUtil;
import cn.zwz.basics.exception.ZwzException;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.basics.code.bean.Field;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.*;
/**
* @author
* CSDN: Designer
*/
@ApiOperation(value = "前端代码生成器")
@RestController
@Api(tags = "Vue代码生成")
@RequestMapping(value = "/zwz/generate")
public class ZwzVueGenerator {
@RequestMapping(value = "/table/{vueName}/{rowNum}", method = RequestMethod.POST)
@ApiOperation(value = "生成前端Vue表格代码")
public Result<Object> createTable(@PathVariable String vueName,@PathVariable Integer rowNum,@RequestBody List<Field> fields) throws IOException {
Map<String, String> map = new HashMap<>();
map.put("component", generate("tableIndex.btl", false, vueName, rowNum, fields));
map.put("componentApi", generate("tableIndex.btl", true, vueName, rowNum, fields));
map.put("add", generate("add.btl", false, vueName, rowNum, fields));
map.put("addApi", generate("add.btl", true, vueName, rowNum, fields));
map.put("edit", generate("edit.btl", false, vueName, rowNum, fields));
map.put("editApi", generate("edit.btl", true, vueName, rowNum, fields));
map.put("single", generate("table.btl", false, vueName, rowNum, fields));
map.put("singleApi", generate("table.btl", true, vueName, rowNum, fields));
map.put("api", generate("api.btl", true, vueName, rowNum, fields));
return ResultUtil.data(map);
}
@RequestMapping(value = "/tree/{vueName}/{rowNum}", method = RequestMethod.POST)
@ApiOperation(value = "生成前端Vue树形代码")
public Result<Object> createTree(@PathVariable String vueName,@PathVariable Integer rowNum,@RequestBody List<Field> fields) throws IOException {
Map<String, String> map = new HashMap<>();
map.put("result", generate("tree.btl", false, vueName, rowNum, fields));
map.put("resultApi", generate("tree.btl", true, vueName, rowNum, fields));
map.put("api", generate("treeApi.btl", true, vueName, rowNum, fields));
return ResultUtil.data(map);
}
@RequestMapping(value = "/getEntityData/{path}", method = RequestMethod.GET)
@ApiOperation(value = "生成实体类的前端代码")
public Result<Object> getEntityData(@PathVariable String path) {
String result = null;
try {
result = generateEntityData(path);
} catch (Exception e) {
return ResultUtil.error("实体类已被删除");
}
return ResultUtil.data(result);
}
public String generateEntityData(String path) throws Exception {
Class c = Class.forName(path);
Object obj = c.getDeclaredConstructor().newInstance();
String start = "{\n" +" \"data\": [";
String end = "\n ]\n" + "}";
String fieldAll = "";
java.lang.reflect.Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
java.lang.reflect.Field field = fields[i];
field.setAccessible(true);
// 字段名
String fieldName = field.getName();
String fieldType = field.getType().getName();
// 白名单
if("serialVersionUID".equals(fieldName)||"actBusinessId".equals(fieldName)||"applyUser".equals(fieldName)||"routeName".equals(fieldName)||"procInstId".equals(fieldName)||"applyTime".equals(fieldName)){
continue;
}
// 注解
ApiModelProperty myFieldAnnotation = field.getAnnotation(ApiModelProperty.class);
String fieldNameCN = fieldName;
if (myFieldAnnotation != null) {
fieldNameCN = myFieldAnnotation.value();
}
fieldNameCN = (fieldNameCN == null || fieldNameCN == "") ? fieldName : fieldNameCN;
String type = "text";
String searchType = "text";
if (fieldType.contains("Date")) {
type = "date";
searchType = "daterange";
} else if (fieldType.contains("BigDecimal")) {
type = "number";
}
String fieldJson = "\n {\n" +
" \"sortOrder\": " + i + ",\n" +
" \"field\": \"" + fieldName + "\",\n" +
" \"name\": \"" + fieldNameCN + "\",\n" +
" \"level\": \"2\",\n" +
" \"tableShow\": true,\n" +
" \"editable\": true,\n" +
" \"type\": \"" + type + "\",\n" +
" \"searchType\": \"" + searchType + "\",\n" +
" \"searchLevel\": \"2\",\n" +
" \"validate\": false,\n" +
" \"searchable\": true,\n" +
" \"sortable\": false,\n" +
" \"defaultSort\": false,\n" +
" \"defaultSortType\": \"desc\"\n" +
" }";
String splitChar = fieldAll == "" ? "" : ",";
fieldAll = fieldAll + splitChar + fieldJson;
}
return start + fieldAll + end;
}
public String generate(String template, boolean api, String vueName, Integer rowNum, List<Field> fields) throws IOException {
ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("/template/vue/");
Configuration cfg = Configuration.defaultConfiguration();
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
Template tableTemplate = gt.getTemplate(template);
Collections.sort(fields, Comparator.comparing(Field::getSortOrder));
tableTemplate.binding("api", api);
tableTemplate.binding("vueName", name(vueName, false));
tableTemplate.binding("apiName", name(vueName, true));
tableTemplate.binding("fields", fields);
Boolean upload = false, uploadThumb = false, wangEditor = false, quill = false, password = false;
for(Field f:fields){
if(Objects.equals("wangEditor",f.getType())){
wangEditor = true;
}
if(Objects.equals("uploadThumb",f.getType())){
uploadThumb = true;
}
if(Objects.equals("upload",f.getType())){
upload = true;
}
if(Objects.equals("password",f.getType())){
password = true;
}
if(Objects.equals("quill",f.getType())){
quill = true;
}
}
tableTemplate.binding("wangEditor", wangEditor);
tableTemplate.binding("uploadThumb", uploadThumb);
tableTemplate.binding("upload", upload);
tableTemplate.binding("password", password);
tableTemplate.binding("quill", quill);
if(Objects.equals("table.btl",template) || Objects.equals("tableIndex.btl",template)){
Boolean daterangeSearch = false;
for(Field f:fields){
if(f.getSearchable() && Objects.equals("daterange",f.getSearchType())){
daterangeSearch = true;
}
}
tableTemplate.binding("daterangeSearch", daterangeSearch);
// 是否隐藏搜索
Boolean hideSearchFlag = false;
List<Field> firstTwo = new ArrayList<>();
List<Field> rest = new ArrayList<>();
Integer count = 0;
for(Field field : fields){
if(field.getSearchable()){
count++;
if(count < 3){
firstTwo.add(field);
}else{
rest.add(field);
}
}
}
if(count > 5){
hideSearchFlag = true;
tableTemplate.binding("firstTwo", firstTwo);
tableTemplate.binding("rest", rest);
}
tableTemplate.binding("searchSize", count);
tableTemplate.binding("hideSearch", hideSearchFlag);
// 默认排序
String defaultSort = "";
String defaultSortType = "";
for(Field field : fields){
if(field.getDefaultSort()){
defaultSort = field.getField();
defaultSortType = field.getDefaultSortType();
break;
}
}
tableTemplate.binding("defaultSort", defaultSort);
tableTemplate.binding("defaultSortType", defaultSortType);
}
tableTemplate.binding("wangEditorWidth", "100%");
tableTemplate.binding("quillWidth", "100%");
tableTemplate.binding("toQuill", false);
tableTemplate.binding("rowNum", rowNum);
if(rowNum == 1){
// 一行一列
tableTemplate.binding("modalWidth", 500);
tableTemplate.binding("width", "100%");
tableTemplate.binding("editWidth", "100%");
tableTemplate.binding("itemWidth", "");
tableTemplate.binding("span", "9");
if(Objects.equals(template,"table.btl") || Objects.equals(template,"tree.btl")) {
tableTemplate.binding("toQuill", true);
}
if(Objects.equals(template,"add.btl") || Objects.equals(template,"edit.btl")) {
tableTemplate.binding("width", "570px");
tableTemplate.binding("rowNum", 1);
}
} else if(rowNum == 2){
// 一行二列
tableTemplate.binding("modalWidth", 770);
tableTemplate.binding("width", "250px");
tableTemplate.binding("editWidth", "250px");
tableTemplate.binding("itemWidth", "350px");
tableTemplate.binding("span", "17");
if(Objects.equals(template,"table.btl") || Objects.equals(template,"tree.btl")) {
tableTemplate.binding("toQuill", true);
tableTemplate.binding("quillWidth", "610px");
}
if(Objects.equals(template,"add.btl") || Objects.equals(template,"edit.btl")) {
tableTemplate.binding("width", "570px");
tableTemplate.binding("rowNum", 1);
}
} else if(rowNum == 3){
// 一行三列
tableTemplate.binding("modalWidth", 980);
tableTemplate.binding("width", "200px");
tableTemplate.binding("editWidth", "200px");
tableTemplate.binding("itemWidth", "300px");
tableTemplate.binding("span", "17");
if(Objects.equals(template,"table.btl") || Objects.equals(template,"tree.btl")) {
tableTemplate.binding("quillWidth", "820px");
tableTemplate.binding("wangEditorWidth", "820px");
}
if(Objects.equals(template,"add.btl") || Objects.equals(template,"edit.btl")) {
tableTemplate.binding("width", "570px");
tableTemplate.binding("rowNum", 1);
}
} else if(rowNum == 4) {
// 一行四列
tableTemplate.binding("modalWidth", 1130);
tableTemplate.binding("width", "160px");
tableTemplate.binding("editWidth", "160px");
tableTemplate.binding("itemWidth", "260px");
tableTemplate.binding("span", "17");
if(Objects.equals(template,"table.btl") || Objects.equals(template,"tree.btl")) {
tableTemplate.binding("quillWidth", "970px");
tableTemplate.binding("wangEditorWidth", "970px");
}
if(Objects.equals(template,"add.btl") || Objects.equals(template,"edit.btl")) {
tableTemplate.binding("width", "570px");
tableTemplate.binding("rowNum", 1);
}
} else{
// 不满足的情况
throw new ZwzException("一行的输入栏只能为1到4列");
}
return tableTemplate.render();
}
/**
*
* @param name
* @param isFirstUpper
* @return
*/
public static String name(String name, boolean isFirstUpper){
if(StrUtil.isBlank(name)){
throw new ZwzException("name不能为空");
}
if(name.length()==1){
if(isFirstUpper){
return name.toUpperCase();
} else {
return name.toLowerCase();
}
}
StringBuffer sb = new StringBuffer();
if(isFirstUpper){
sb.append(Character.toUpperCase(name.charAt(0)));
} else {
sb.append(Character.toLowerCase(name.charAt(0)));
}
sb.append(name.substring(1));
return sb.toString();
}
}

@ -0,0 +1,40 @@
package cn.zwz.basics.exception;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
@ApiOperation(value = "自定义异常")
public class ZwzAuthException extends InternalAuthenticationServiceException {
private static final long serialVersionUID = 1L;
private static final String DEFAULT_MSG = "系统鉴权失败";
@ApiModelProperty(value = "异常消息内容")
private String msg;
public ZwzAuthException(String msg){
super(msg);
this.msg = msg;
}
public ZwzAuthException(){
super(DEFAULT_MSG);
this.msg = DEFAULT_MSG;
}
public ZwzAuthException(String msg, Throwable t) {
super(msg, t);
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

@ -0,0 +1,28 @@
package cn.zwz.basics.exception;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
@ApiOperation(value = "自定义异常")
@Data
public class ZwzException extends RuntimeException {
private static final long serialVersionUID = 1L;
private static final String DEFAULT_MSG = "系统出现错误";
@ApiModelProperty(value = "异常消息内容")
private String msg;
public ZwzException(){
super(DEFAULT_MSG);
this.msg = DEFAULT_MSG;
}
public ZwzException(String msg){
super(msg);
this.msg = msg;
}
}

@ -0,0 +1,33 @@
package cn.zwz.basics.log;
import io.swagger.annotations.ApiOperation;
@ApiOperation(value = "日志枚举类")
public enum LogType {
/**
* 1
*/
DEFAULT_OPERATION,
/**
* 2
*/
LOGIN,
/**
* 3
*/
DATA_CENTER,
/**
* 4
*/
MORE_MOUDLE,
/**
* 5
*/
CHART
}

@ -0,0 +1,23 @@
package cn.zwz.basics.log;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import java.lang.annotation.*;
@ApiOperation(value = "日志实体类")
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
@ApiModelProperty(value = "日志名称")
public String about() default "系统日志";
@ApiModelProperty(value = "日志类型")
public LogType type() default LogType.DEFAULT_OPERATION;
@ApiModelProperty(value = "操作代码")
String doType() default "";
}

@ -0,0 +1,158 @@
package cn.zwz.basics.log;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.utils.IpInfoUtil;
import cn.zwz.basics.utils.ThreadPoolUtil;
import cn.zwz.data.entity.Log;
import cn.zwz.data.service.LogService;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NamedThreadLocal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@ApiOperation(value = "日志实现类")
@Aspect
@Component
@Slf4j
public class SystemLogAspect {
private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<Date>("ThreadLocal beginTime");
@Autowired
private LogService logService;
@Autowired(required = false)
private HttpServletRequest request;
@Autowired
private IpInfoUtil ipInfoUtil;
@Autowired
private RedisTemplateHelper redisTemplate;
private static final String REDIS_USER_PRE = "USER:";
private static final String LOG_DES_PRE = "description";
private static final String LOG_TYPE_PRE = "type";
private static final String LOG_DO_PRE = "doType";
@ApiOperation(value = "控制层切点")
@Pointcut("@annotation(cn.zwz.basics.log.SystemLog)")
public void controllerAspect() {
}
@ApiOperation(value = "前置通知")
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint){
Date beginTime = new Date();
beginTimeThreadLocal.set(beginTime);
}
@ApiOperation(value = "后置通知")
@AfterReturning("controllerAspect()")
public void after(JoinPoint joinPoint){
try {
String username = "";
String description = getControllerMethodInfo(joinPoint).get("description").toString();
int type = (int)getControllerMethodInfo(joinPoint).get("type");
String doType = getControllerMethodInfo(joinPoint).get("doType").toString();
Map<String, String[]> logParams = request.getParameterMap();
JSONObject logJo = new JSONObject();
for (Map.Entry<String, String[]> keyInMap : logParams.entrySet()) {
String keyItemInMap = keyInMap.getKey();
String paramValue = (keyInMap.getValue() != null && keyInMap.getValue().length > 0 ? keyInMap.getValue()[0] : "");
logJo.put(keyItemInMap,StrUtil.endWithIgnoreCase(keyInMap.getKey(), "password") ? "" : paramValue);
}
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(Objects.equals("anonymousUser",principal.toString())){
return;
}
String device = "", isMobile = "PC端";
UserAgent ua = UserAgentUtil.parse(request.getHeader("user-agent"));
if (ua != null) {
if (ua.isMobile()) {
isMobile = "移动端";
}
device = isMobile + " | " + ua.getBrowser().toString() + " " + ua.getVersion() + " | " + ua.getPlatform().toString() + " " + ua.getOs().toString();
}
UserDetails user = (UserDetails) principal;
String str = redisTemplate.get(REDIS_USER_PRE + user.getUsername());
if(str != null) {
username = str;
} else {
username = user.getUsername();
}
Log log = new Log();
log.setUsername(username);
log.setName(description);
log.setLogType(type);
log.setCode(doType);
log.setRequestUrl(request.getRequestURI());
log.setRequestType(request.getMethod());
log.setRequestParam(logJo.toJSONString());
log.setIp(ipInfoUtil.getRequestIpAddress(request));
log.setDevice(device);
log.setIpInfo(ipInfoUtil.getIpCity(request));
Long logElapsedTime = System.currentTimeMillis() - beginTimeThreadLocal.get().getTime();
log.setCostTime(logElapsedTime.intValue());
ThreadPoolUtil.getPool().execute(new SaveSystemLogThread(log, logService));
} catch (Exception e) {
log.error("日志异常", e);
}
}
@ApiOperation(value = "保存日志")
private static class SaveSystemLogThread implements Runnable {
private Log log;
private LogService logService;
public SaveSystemLogThread(Log esLog, LogService logService) {
this.log = esLog;
this.logService = logService;
}
@Override
public void run() {
logService.save(log);
}
}
public static Map<String, Object> getControllerMethodInfo(JoinPoint aopLogPoint) throws Exception{
Map<String, Object> map = new HashMap<String, Object>(16);
Method[] methods = Class.forName(aopLogPoint.getTarget().getClass().getName()).getMethods();
for(Method method : methods) {
if(!Objects.equals(aopLogPoint.getSignature().getName(),method.getName())) {
continue;
}
Class[] aopLogClass = method.getParameterTypes();
if(aopLogClass.length != aopLogPoint.getArgs().length) {
continue;
}
map.put(LOG_DO_PRE, method.getAnnotation(SystemLog.class).doType());
map.put(LOG_DES_PRE, method.getAnnotation(SystemLog.class).about());
map.put(LOG_TYPE_PRE, method.getAnnotation(SystemLog.class).type().ordinal());
}
return map;
}
}

@ -0,0 +1,84 @@
package cn.zwz.basics.mybatisplus;
import cn.zwz.basics.redis.RedisTemplateHelper;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;
@ApiOperation(value = "MybatisPlus字段填充")
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Autowired
private RedisTemplateHelper redisTemplate;
private static final String ANONYMOUS_USER = "anonymousUser";
private static final String REDIS_PRE = "OAUSER:";
private static final String CREATE_BY = "createBy";
private static final String CREATE_TIME = "createTime";
private static final String UPDATE_BY = "updateBy";
private static final String UPDATE_TIME = "updateTime";
private static final String DEFALUT_STR = "API接口";
@Override
@ApiOperation(value = "新增方法填充")
public void insertFill(MetaObject metaObject) {
try {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(!Objects.equals(ANONYMOUS_USER,principal.toString())){
UserDetails user = (UserDetails) principal;
String str = redisTemplate.get(REDIS_PRE + user.getUsername());
if(str != null) {
this.setFieldValByName(CREATE_BY, str, metaObject);
} else {
this.setFieldValByName(CREATE_BY, user.getUsername(), metaObject);
}
}
this.setFieldValByName(CREATE_TIME, new Date(), metaObject);
}
catch (NullPointerException e) {
this.setFieldValByName(CREATE_BY, DEFALUT_STR, metaObject);
this.setFieldValByName(CREATE_TIME, new Date(), metaObject);
}
}
@Override
@ApiOperation(value = "编辑方法填充")
public void updateFill(MetaObject metaObject) {
try {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(!Objects.equals(ANONYMOUS_USER,principal.toString())){
UserDetails user = (UserDetails) principal;
this.setFieldValByName(UPDATE_BY, user.getUsername(), metaObject);
String str = redisTemplate.get(REDIS_PRE + user.getUsername());
if(str != null) {
this.setFieldValByName(UPDATE_BY, str, metaObject);
} else {
this.setFieldValByName(UPDATE_BY, user.getUsername(), metaObject);
}
}
this.setFieldValByName(UPDATE_TIME, new Date(), metaObject);
}
catch (NullPointerException e) {
this.setFieldValByName(UPDATE_BY, DEFALUT_STR, metaObject);
this.setFieldValByName(UPDATE_TIME, new Date(), metaObject);
}
}
}

@ -0,0 +1,23 @@
package cn.zwz.basics.mybatisplus;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import io.swagger.annotations.ApiOperation;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ApiOperation(value = "MybatisPlus配置类")
@Configuration
@MapperScan({"cn.zwz.*.mapper", "cn.zwz.*.*.mapper"})
public class MybatisPlusConfig {
@Bean
@ApiOperation(value = "初始化MybatisPlus配置")
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

@ -0,0 +1,26 @@
package cn.zwz.basics.parameter;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@ApiOperation(value = "验证码接口配置")
@Data
@Configuration
@ConfigurationProperties(prefix = "intercept")
public class CaptchaProperties {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "需要图片验证码验证的接口")
private List<String> verification = new ArrayList<>();
@ApiModelProperty(value = "需要企微验证码验证的接口")
private List<String> wechat = new ArrayList<>();
}

@ -0,0 +1,42 @@
package cn.zwz.basics.parameter;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
@ApiOperation(value = "系统基础常量")
public interface CommonConstant {
@ApiModelProperty(value = "正常")
Integer USER_STATUS_NORMAL = 0;
@ApiModelProperty(value = "禁用")
Integer USER_STATUS_LOCK = -1;
@ApiModelProperty(value = "顶级菜单")
Integer PERMISSION_NAV = -1;
@ApiModelProperty(value = "普通菜单")
Integer PERMISSION_PAGE = 0;
@ApiModelProperty(value = "按钮菜单")
Integer PERMISSION_OPERATION = 1;
@ApiModelProperty(value = "顶级菜单")
Integer LEVEL_ZERO = 0;
@ApiModelProperty(value = "1级菜单")
Integer LEVEL_ONE = 1;
@ApiModelProperty(value = "2级菜单")
Integer LEVEL_TWO = 2;
@ApiModelProperty(value = "3级菜单")
Integer LEVEL_THREE = 3;
@ApiModelProperty(value = "总部门ID")
String PARENT_ID = "0";
@ApiModelProperty(value = "头像URL")
String USER_DEFAULT_AVATAR = "https://asoa-1305425069.cos.ap-shanghai.myqcloud.com/1669635627773202432.png";
}

@ -0,0 +1,59 @@
package cn.zwz.basics.parameter;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.context.annotation.Configuration;
@ApiOperation(value = "登录常量类")
@Data
@Configuration
public class ZwzLoginProperties {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "是否单点登录")
private Boolean ssoFlag = true;
@ApiModelProperty(value = "是否保存权限")
private Boolean saveRoleFlag = true;
@ApiModelProperty(value = "用户Token过期天数", notes = "保存Token的时间,Token没了也不能自动登录")
private Integer userTokenInvalidDays = 30;
@ApiModelProperty(value = "用户保存登录天数", notes = "选择了自动登录,记录保存的时间")
private Integer userSaveLoginTokenDays = 7;
@ApiModelProperty(value = "最大登录失败次数")
private Integer maxLoginFailTimes = 10;
@ApiModelProperty(value = "登录失败超限后锁定分钟")
private Integer loginFailMaxThenLockTimes = 10;
@ApiModelProperty(value = "全局限流")
private Boolean allLimiting = false;
@ApiModelProperty(value = "全局限流个数")
private Integer allLimitingSize = 100;
@ApiModelProperty(value = "全局限流单位时长")
private Long allLimitingTime = 1000L;
@ApiModelProperty(value = "单IP限流")
private Boolean oneLimiting = false;
@ApiModelProperty(value = "单IP限流个数")
private Integer oneLimitingSize = 100;
@ApiModelProperty(value = "单IP限流单位时长")
private Long oneLimitingTime = 1000L;
public static final String HTTP_HEADER = "accessToken";
public static final String SAVE_LOGIN_PRE = "saveLogin";
public static final String HTTP_TOKEN_PRE = "ZWZ_TOKEN_PRE:";
public static final String USER_TOKEN_PRE = "ZWZ_USER_TOKEN:";
}

@ -0,0 +1,91 @@
package cn.zwz.basics.redis;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.Objects;
@ApiOperation(value = "Redis异常处理")
@Configuration
@Slf4j
public class RedisExceptionThrowsConfig extends CachingConfigurerSupport {
@ApiModelProperty(value = "时长类型")
private String unit = "day";
@ApiModelProperty(value = "时长值", notes = "-1为不限制")
private Integer time = 30;
@Override
@ApiOperation(value = "Redis序列化异常")
public CacheErrorHandler errorHandler() {
CacheErrorHandler ceh = new CacheErrorHandler() {
@Override
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
log.warn("Redis序列化出现了查询异常");
log.warn(key.toString());
}
@Override
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
log.warn("Redis序列化出现了插入异常");
log.warn(key.toString());
}
@Override
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
log.warn("Redis序列化出现了Evict异常");
log.warn(key.toString());
}
@Override
public void handleCacheClearError(RuntimeException e, Cache cache) {
log.warn("Redis序列化出现了删除异常");
}
};
return ceh;
}
@Bean
@ApiOperation(value = "Redis序列化")
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
// 判断缓存格式化错误
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
PolymorphicTypeValidator ptv = new ObjectMapper().getPolymorphicTypeValidator();
objectMapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(objectMapper);
// 判断乱码错误
RedisCacheConfiguration rc = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))
.disableCachingNullValues();
// 处理缓存时长
Duration expireTime = Duration.ofDays(time);
if(Objects.equals(unit,"hour")) {
expireTime = Duration.ofHours(time);
} else if(Objects.equals(unit,"minute")) {
expireTime = Duration.ofMinutes(time);
}
return RedisCacheManager.builder(factory).cacheDefaults(rc.entryTtl(expireTime)).build();
}
}

@ -0,0 +1,647 @@
package cn.zwz.basics.redis;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@ApiOperation(value = "Redis工具类")
@Component
public class RedisTemplateHelper {
@Autowired
private StringRedisTemplate redisTemplate;
@ApiOperation(value = "scan实现")
private void scan(String wayForScan, Consumer<byte[]> consumableList) {
redisTemplate.execute((RedisConnection connection) -> {
try (Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().count(Long.MAX_VALUE).match(wayForScan).build())) {
cursor.forEachRemaining(consumableList);
return null;
} catch (Exception exception) {
throw new RuntimeException(exception);
}
});
}
@ApiOperation(value = "scan获取符合条件的key")
public Set<String> scan(String pattern) {
Set<String> keys = new HashSet<>();
this.scan(pattern, item -> {
String key = new String(item, StandardCharsets.UTF_8);
keys.add(key);
});
return keys;
}
@ApiOperation(value = "通过通配符表达式删除所有")
public void deleteByPattern(String pattern) {
Set<String> keys = this.scan(pattern);
redisTemplate.delete(keys);
}
@ApiOperation(value = "删除key")
public void delete(String key) {
redisTemplate.delete(key);
}
@ApiOperation(value = "批量删除key")
public void delete(Collection<String> keys) {
redisTemplate.delete(keys);
}
@ApiOperation(value = "序列化key")
public byte[] dump(String key) {
return redisTemplate.dump(key);
}
@ApiOperation(value = "是否存在key")
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
@ApiOperation(value = "设置过期时间")
public Boolean expire(String key, long timeout, TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
@ApiOperation(value = "设置过期时间")
public Boolean expireAt(String key, Date date) {
return redisTemplate.expireAt(key, date);
}
@ApiOperation(value = "查找匹配的key")
public Set<String> keys(String pattern) {
return redisTemplate.keys(pattern);
}
@ApiOperation(value = "将当前数据库的 key 移动到给定的数据库 db 当中")
public Boolean move(String key, int dbIndex) {
return redisTemplate.move(key, dbIndex);
}
@ApiOperation(value = "移除 key 的过期时间key 将持久保持")
public Boolean persist(String key) {
return redisTemplate.persist(key);
}
@ApiOperation(value = "返回 key 的剩余的过期时间")
public Long getExpire(String key, TimeUnit unit) {
return redisTemplate.getExpire(key, unit);
}
@ApiOperation(value = "返回 key 的剩余的过期时间")
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
@ApiOperation(value = "从当前数据库中随机返回一个 key")
public String randomKey() {
return redisTemplate.randomKey();
}
@ApiOperation(value = "修改 key 的名称")
public void rename(String oldKey, String newKey) {
redisTemplate.rename(oldKey, newKey);
}
@ApiOperation(value = "仅当 newkey 不存在时,将 oldKey 改名为 newkey")
public Boolean renameIfAbsent(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
@ApiOperation(value = "返回 key 所储存的值的类型")
public DataType type(String key) {
return redisTemplate.type(key);
}
/** -------------------string相关操作--------------------- */
@ApiOperation(value = "设置指定 key 的值")
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
@ApiOperation(value = "将值 value 关联到 key ,并将 key 的过期时间设为 timeout")
public void set(String key, String value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
@ApiOperation(value = "获取指定 key 的值")
public String get(String key) {
return redisTemplate.opsForValue().get(key);
}
@ApiOperation(value = "返回 key 中字符串值的子字符")
public String getRange(String key, long start, long end) {
return redisTemplate.opsForValue().get(key, start, end);
}
@ApiOperation(value = "将给定 key 的值设为 value ,并返回 key 的旧值(old value)")
public String getAndSet(String key, String value) {
return redisTemplate.opsForValue().getAndSet(key, value);
}
@ApiOperation(value = "对 key 所储存的字符串值,获取指定偏移量上的位(bit)")
public Boolean getBit(String key, long offset) {
return redisTemplate.opsForValue().getBit(key, offset);
}
@ApiOperation(value = "批量获取")
public List<String> multiGet(Collection<String> keys) {
return redisTemplate.opsForValue().multiGet(keys);
}
@ApiOperation(value = "设置ASCII码, 字符串'a'的ASCII码是97, 转为二进制是'01100001', 此方法是将二进制第offset位值变为value",notes = "offset 位置, value: 值,true为1, false为0")
public boolean setBit(String key, long offset, boolean value) {
return redisTemplate.opsForValue().setBit(key, offset, value);
}
@ApiOperation(value = "只有在 key 不存在时设置 key 的值",notes = "之前已经存在返回false, 不存在返回true")
public boolean setIfAbsent(String key, String value) {
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
@ApiOperation(value = "用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始",notes = "offset:从指定位置开始覆写")
public void setRange(String key, String value, long offset) {
redisTemplate.opsForValue().set(key, value, offset);
}
@ApiOperation(value = "获取字符串的长度")
public Long size(String key) {
return redisTemplate.opsForValue().size(key);
}
@ApiOperation(value = "批量添加")
public void multiSet(Map<String, String> maps) {
redisTemplate.opsForValue().multiSet(maps);
}
@ApiOperation(value = "同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在")
public boolean multiSetIfAbsent(Map<String, String> maps) {
return redisTemplate.opsForValue().multiSetIfAbsent(maps);
}
@ApiOperation(value = "增加(自增长), 负数则为自减")
public Long incrBy(String key, long increment) {
return redisTemplate.opsForValue().increment(key, increment);
}
@ApiOperation(value = "增加(自增长)")
public Double incrByFloat(String key, double increment) {
return redisTemplate.opsForValue().increment(key, increment);
}
@ApiOperation(value = "追加到末尾")
public Integer append(String key, String value) {
return redisTemplate.opsForValue().append(key, value);
}
// hash表
@ApiOperation(value = "获取存储在哈希表中指定字段的值")
public Object hGet(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
@ApiOperation(value = "获取所有给定字段的值")
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
@ApiOperation(value = "获取所有给定字段的值")
public List<Object> hMultiGet(String key, Collection<Object> fields) {
return redisTemplate.opsForHash().multiGet(key, fields);
}
@ApiOperation(value = "添加单个")
public void hPut(String key, String hashKey, String value) {
redisTemplate.opsForHash().put(key, hashKey, value);
}
@ApiOperation(value = "添加集合")
public void hPutAll(String key, Map<String, String> maps) {
redisTemplate.opsForHash().putAll(key, maps);
}
@ApiOperation(value = "仅当hashKey不存在时才设置")
public Boolean hPutIfAbsent(String key, String hashKey, String value) {
return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value);
}
@ApiOperation(value = "删除一个或多个哈希表字段")
public Long hDelete(String key, Object... fields) {
return redisTemplate.opsForHash().delete(key, fields);
}
@ApiOperation(value = "查看哈希表 key 中,指定的字段是否存在")
public boolean hExists(String key, String field) {
return redisTemplate.opsForHash().hasKey(key, field);
}
@ApiOperation(value = "为哈希表 key 中的指定字段的整数值加上增量 increment")
public Long hIncrBy(String key, Object field, long increment) {
return redisTemplate.opsForHash().increment(key, field, increment);
}
@ApiOperation(value = "为哈希表 key 中的指定字段的整数值加上增量 increment")
public Double hIncrByFloat(String key, Object field, double delta) {
return redisTemplate.opsForHash().increment(key, field, delta);
}
@ApiOperation(value = "获取所有哈希表中的字段")
public Set<Object> hKeys(String key) {
return redisTemplate.opsForHash().keys(key);
}
@ApiOperation(value = "获取哈希表中字段的数量")
public Long hSize(String key) {
return redisTemplate.opsForHash().size(key);
}
@ApiOperation(value = "获取哈希表中所有值")
public List<Object> hValues(String key) {
return redisTemplate.opsForHash().values(key);
}
@ApiOperation(value = "迭代哈希表中的键值对")
public Cursor<Map.Entry<Object, Object>> hScan(String key, ScanOptions options) {
return redisTemplate.opsForHash().scan(key, options);
}
// list
@ApiOperation(value = "通过索引获取列表中的元素")
public String lIndex(String key, long index) {
return redisTemplate.opsForList().index(key, index);
}
@ApiOperation(value = "获取列表指定范围内的元素")
public List<String> lRange(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
@ApiOperation(value = "存储在list头部")
public Long lLeftPush(String key, String value) {
return redisTemplate.opsForList().leftPush(key, value);
}
public Long lLeftPushAll(String key, String... value) {
return redisTemplate.opsForList().leftPushAll(key, value);
}
public Long lLeftPushAll(String key, Collection<String> value) {
return redisTemplate.opsForList().leftPushAll(key, value);
}
@ApiOperation(value = "当list存在的时候才加入")
public Long lLeftPushIfPresent(String key, String value) {
return redisTemplate.opsForList().leftPushIfPresent(key, value);
}
@ApiOperation(value = "如果pivot存在,再pivot前面添加")
public Long lLeftPush(String key, String pivot, String value) {
return redisTemplate.opsForList().leftPush(key, pivot, value);
}
public Long lRightPush(String key, String value) {
return redisTemplate.opsForList().rightPush(key, value);
}
public Long lRightPushAll(String key, String... value) {
return redisTemplate.opsForList().rightPushAll(key, value);
}
public Long lRightPushAll(String key, Collection<String> value) {
return redisTemplate.opsForList().rightPushAll(key, value);
}
@ApiOperation(value = "为已存在的列表添加值")
public Long lRightPushIfPresent(String key, String value) {
return redisTemplate.opsForList().rightPushIfPresent(key, value);
}
@ApiOperation(value = "在pivot元素的右边添加值")
public Long lRightPush(String key, String pivot, String value) {
return redisTemplate.opsForList().rightPush(key, pivot, value);
}
@ApiOperation(value = "通过索引设置列表元素的值")
public void lSet(String key, long index, String value) {
redisTemplate.opsForList().set(key, index, value);
}
@ApiOperation(value = "移出并获取列表的第一个元素")
public String lLeftPop(String key) {
return redisTemplate.opsForList().leftPop(key);
}
@ApiOperation(value = "移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止")
public String lBLeftPop(String key, long timeout, TimeUnit unit) {
return redisTemplate.opsForList().leftPop(key, timeout, unit);
}
@ApiOperation(value = "移除并获取列表最后一个元素")
public String lRightPop(String key) {
return redisTemplate.opsForList().rightPop(key);
}
@ApiOperation(value = "移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止")
public String lBRightPop(String key, long timeout, TimeUnit unit) {
return redisTemplate.opsForList().rightPop(key, timeout, unit);
}
@ApiOperation(value = "移除列表的最后一个元素,并将该元素添加到另一个列表并返回")
public String lRightPopAndLeftPush(String sourceKey, String destinationKey) {
return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
destinationKey);
}
@ApiOperation(value = "从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止")
public String lBRightPopAndLeftPush(String sourceKey, String destinationKey,long timeout, TimeUnit unit) {
return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey,destinationKey, timeout, unit);
}
@ApiOperation(value = "删除集合中值等于value的元素",notes = "index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素;index<0, 从尾部开始删除第一个值等于value的元素")
public Long lRemove(String key, long index, String value) {
return redisTemplate.opsForList().remove(key, index, value);
}
@ApiOperation(value = "裁剪list")
public void lTrim(String key, long start, long end) {
redisTemplate.opsForList().trim(key, start, end);
}
@ApiOperation(value = "获取列表长度")
public Long lLen(String key) {
return redisTemplate.opsForList().size(key);
}
// set
@ApiOperation(value = "set添加元素")
public Long sAdd(String key, String... values) {
return redisTemplate.opsForSet().add(key, values);
}
@ApiOperation(value = "set移除元素")
public Long sRemove(String key, Object... values) {
return redisTemplate.opsForSet().remove(key, values);
}
@ApiOperation(value = "移除并返回集合的一个随机元素")
public String sPop(String key) {
return redisTemplate.opsForSet().pop(key);
}
@ApiOperation(value = "将元素value从一个集合移到另一个集合")
public Boolean sMove(String key, String value, String destKey) {
return redisTemplate.opsForSet().move(key, value, destKey);
}
@ApiOperation(value = "获取集合的大小")
public Long sSize(String key) {
return redisTemplate.opsForSet().size(key);
}
@ApiOperation(value = "判断集合是否包含value")
public Boolean sIsMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
@ApiOperation(value = "获取两个集合的交集")
public Set<String> sIntersect(String key, String otherKey) {
return redisTemplate.opsForSet().intersect(key, otherKey);
}
@ApiOperation(value = "获取key集合与多个集合的交集")
public Set<String> sIntersect(String key, Collection<String> otherKeys) {
return redisTemplate.opsForSet().intersect(key, otherKeys);
}
@ApiOperation(value = "key集合与otherKey集合的交集存储到destKey集合中")
public Long sIntersectAndStore(String key, String otherKey, String destKey) {
return redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey);
}
@ApiOperation(value = "key集合与多个集合的交集存储到destKey集合中")
public Long sIntersectAndStore(String key, Collection<String> otherKeys,String destKey) {
return redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey);
}
@ApiOperation(value = "获取两个集合的并集")
public Set<String> sUnion(String key, String otherKeys) {
return redisTemplate.opsForSet().union(key, otherKeys);
}
@ApiOperation(value = "获取key集合与多个集合的并集")
public Set<String> sUnion(String key, Collection<String> otherKeys) {
return redisTemplate.opsForSet().union(key, otherKeys);
}
@ApiOperation(value = "key集合与otherKey集合的并集存储到destKey中")
public Long sUnionAndStore(String key, String otherKey, String destKey) {
return redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey);
}
@ApiOperation(value = "key集合与多个集合的并集存储到destKey中")
public Long sUnionAndStore(String key, Collection<String> otherKeys,String destKey) {
return redisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey);
}
@ApiOperation(value = "获取两个集合的差集")
public Set<String> sDifference(String key, String otherKey) {
return redisTemplate.opsForSet().difference(key, otherKey);
}
@ApiOperation(value = "获取key集合与多个集合的差集")
public Set<String> sDifference(String key, Collection<String> otherKeys) {
return redisTemplate.opsForSet().difference(key, otherKeys);
}
@ApiOperation(value = "key集合与otherKey集合的差集存储到destKey中")
public Long sDifference(String key, String otherKey, String destKey) {
return redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey);
}
@ApiOperation(value = "key集合与多个集合的差集存储到destKey中")
public Long sDifference(String key, Collection<String> otherKeys,String destKey) {
return redisTemplate.opsForSet().differenceAndStore(key, otherKeys,destKey);
}
@ApiOperation(value = "返回集合指定元素")
public Set<String> setMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
@ApiOperation(value = "随机获取集合中的一个元素")
public String sRandomMember(String key) {
return redisTemplate.opsForSet().randomMember(key);
}
@ApiOperation(value = "随机获取集合中count个元素")
public List<String> sRandomMembers(String key, long count) {
return redisTemplate.opsForSet().randomMembers(key, count);
}
@ApiOperation(value = "随机获取集合中count个元素并且去除重复的")
public Set<String> sDistinctRandomMembers(String key, long count) {
return redisTemplate.opsForSet().distinctRandomMembers(key, count);
}
@ApiOperation(value = "scan扫描返回指定key")
public Cursor<String> sScan(String key, ScanOptions options) {
return redisTemplate.opsForSet().scan(key, options);
}
// zSet
@ApiOperation(value = "添加元素,有序集合是按照元素的score值由小到大排列")
public Boolean zAdd(String key, String value, double score) {
return redisTemplate.opsForZSet().add(key, value, score);
}
@ApiOperation(value = "添加集合")
public Long zAdd(String key, Set<ZSetOperations.TypedTuple<String>> values) {
return redisTemplate.opsForZSet().add(key, values);
}
@ApiOperation(value = "移除")
public Long zRemove(String key, Object... values) {
return redisTemplate.opsForZSet().remove(key, values);
}
@ApiOperation(value = "增加元素的score值并返回增加后的值")
public Double zIncrementScore(String key, String value, double delta) {
return redisTemplate.opsForZSet().incrementScore(key, value, delta);
}
@ApiOperation(value = "返回元素在集合的排名,有序集合是按照元素的score值由小到大排列")
public Long zRank(String key, Object value) {
return redisTemplate.opsForZSet().rank(key, value);
}
@ApiOperation(value = "返回元素在集合的排名,按元素的score值由大到小排列")
public Long zReverseRank(String key, Object value) {
return redisTemplate.opsForZSet().reverseRank(key, value);
}
@ApiOperation(value = "获取集合的元素, 从小到大排序")
public Set<String> zRange(String key, long start, long end) {
return redisTemplate.opsForZSet().range(key, start, end);
}
@ApiOperation(value = "获取集合元素, 并且把score值也获取")
public Set<ZSetOperations.TypedTuple<String>> zRangeWithScores(String key, long start,long end) {
return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
}
@ApiOperation(value = "根据Score值查询集合元素")
public Set<String> zRangeByScore(String key, double min, double max) {
return redisTemplate.opsForZSet().rangeByScore(key, min, max);
}
@ApiOperation(value = "根据Score值查询集合元素, 从小到大排序")
public Set<ZSetOperations.TypedTuple<String>> zRangeByScoreWithScores(String key,double min, double max) {
return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
}
@ApiOperation(value = "根据Score值和指定位置查询集合元素, 从小到大排序")
public Set<ZSetOperations.TypedTuple<String>> zRangeByScoreWithScores(String key,double min, double max, long start, long end) {
return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, start, end);
}
@ApiOperation(value = "获取集合的元素, 从大到小排序")
public Set<String> zReverseRange(String key, long start, long end) {
return redisTemplate.opsForZSet().reverseRange(key, start, end);
}
@ApiOperation(value = "获取集合的元素, 从大到小排序, 并返回score值")
public Set<ZSetOperations.TypedTuple<String>> zReverseRangeWithScores(String key,long start, long end) {
return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
}
@ApiOperation(value = "根据Score值查询集合元素, 从大到小排序")
public Set<String> zReverseRangeByScore(String key, double min, double max) {
return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
}
@ApiOperation(value = "根据Score值查询集合元素, 从大到小排序")
public Set<ZSetOperations.TypedTuple<String>> zReverseRangeByScoreWithScores(String key, double min, double max) {
return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max);
}
@ApiOperation(value = "根据Score值和指定位置查询集合元素, 从大到小排序")
public Set<String> zReverseRangeByScore(String key, double min, double max, long start, long end) {
return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end);
}
@ApiOperation(value = "根据score值获取集合元素数量")
public Long zCount(String key, double min, double max) {
return redisTemplate.opsForZSet().count(key, min, max);
}
@ApiOperation(value = "获取集合大小")
public Long zSize(String key) {
return redisTemplate.opsForZSet().size(key);
}
@ApiOperation(value = "获取集合大小")
public Long zZCard(String key) {
return redisTemplate.opsForZSet().zCard(key);
}
@ApiOperation(value = "获取集合中value元素的score值")
public Double zScore(String key, Object value) {
return redisTemplate.opsForZSet().score(key, value);
}
@ApiOperation(value = "移除指定索引位置的成员")
public Long zRemoveRange(String key, long start, long end) {
return redisTemplate.opsForZSet().removeRange(key, start, end);
}
@ApiOperation(value = "根据指定的score值的范围来移除成员")
public Long zRemoveRangeByScore(String key, double min, double max) {
return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
}
@ApiOperation(value = "获取key和otherKey的并集并存储在destKey中")
public Long zUnionAndStore(String key, String otherKey, String destKey) {
return redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey);
}
@ApiOperation(value = "获取key和otherKey的并集并存储在destKey中")
public Long zUnionAndStore(String key, Collection<String> otherKeys, String destKey) {
return redisTemplate.opsForZSet().unionAndStore(key, otherKeys, destKey);
}
@ApiOperation(value = "交集")
public Long zIntersectAndStore(String key, String otherKey, String destKey) {
return redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey);
}
@ApiOperation(value = "交集")
public Long zIntersectAndStore(String key, Collection<String> otherKeys, String destKey) {
return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey);
}
@ApiOperation(value = "scan扫描指定key")
public Cursor<ZSetOperations.TypedTuple<String>> zScan(String key, ScanOptions options) {
return redisTemplate.opsForZSet().scan(key, options);
}
@ApiOperation(value = "获得连接工厂")
public RedisConnectionFactory getConnectionFactory() {
return redisTemplate.getConnectionFactory();
}
}

@ -0,0 +1,88 @@
package cn.zwz.basics.security;
import cn.zwz.basics.parameter.CommonConstant;
import cn.zwz.data.entity.User;
import cn.zwz.data.utils.ZwzNullUtils;
import cn.zwz.data.vo.PermissionDTO;
import cn.zwz.data.vo.RoleDTO;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
@ApiOperation(value = "查询用户的角色和菜单权限")
public class SecurityUserDetails extends User implements UserDetails {
private static final long serialVersionUID = 1L;
private List<RoleDTO> roles;
private List<PermissionDTO> permissions;
@Override
@ApiOperation(value = "查询用户的角色和菜单权限")
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
// 菜单权限
if(permissions!=null && permissions.size() > 0){
for (PermissionDTO dto : permissions) {
if(!ZwzNullUtils.isNull(dto.getTitle()) && !ZwzNullUtils.isNull(dto.getPath())) {
grantedAuthorityList.add(new SimpleGrantedAuthority(dto.getTitle()));
}
}
}
// 角色
if(roles != null && roles.size() > 0){
roles.forEach(role -> {
if(!ZwzNullUtils.isNull(role.getName())){
grantedAuthorityList.add(new SimpleGrantedAuthority(role.getName()));
}
});
}
return grantedAuthorityList;
}
@Override
@ApiOperation(value = "账号是否启用")
public boolean isEnabled() {
return Objects.equals(CommonConstant.USER_STATUS_NORMAL,this.getStatus());
}
@ApiOperation(value = "账号是否过期")
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
@ApiOperation(value = "账号密码是否过期")
public boolean isCredentialsNonExpired() {
return true;
}
@Override
@ApiOperation(value = "账号是否禁用")
public boolean isAccountNonLocked() {
return !Objects.equals(CommonConstant.USER_STATUS_LOCK, this.getStatus());
}
/**
*
* @param user
*/
public SecurityUserDetails(User user) {
if(user != null) {
this.setUsername(user.getUsername());
this.setPassword(user.getPassword());
this.setStatus(user.getStatus());
this.permissions = user.getPermissions();
this.roles = user.getRoles();
}
}
}

@ -0,0 +1,49 @@
package cn.zwz.basics.security;
import cn.zwz.data.entity.User;
import cn.zwz.data.service.IUserService;
import cn.zwz.data.utils.ZwzNullUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@ApiOperation(value = "登录判断类")
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private IUserService iUserService;
private static final String LOGIN_FAIL_DISABLED_PRE = "userLoginDisableFlag:";
@Override
@ApiOperation(value = "根据账号/手机号查询用户所有信息")
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
String loginFailFlag = LOGIN_FAIL_DISABLED_PRE + username;
String value = redisTemplate.opsForValue().get(loginFailFlag);
Long timeRest = redisTemplate.getExpire(loginFailFlag, TimeUnit.MINUTES);
if(!ZwzNullUtils.isNull(value)){
throw new UsernameNotFoundException("试错超限,请您在" + timeRest + "分钟后再登");
}
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.and(wrapper -> wrapper.eq("username", username).or().eq("mobile",username));
userQw.orderByDesc("create_time");
userQw.last("limit 1");
User superUser = iUserService.getOne(userQw);
if(superUser == null) {
throw new UsernameNotFoundException(username + "不存在");
}
return new SecurityUserDetails(superUser);
}
}

@ -0,0 +1,108 @@
package cn.zwz.basics.security;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.security.jwt.*;
import cn.zwz.basics.utils.SecurityUtil;
import cn.zwz.basics.parameter.ZwzLoginProperties;
import cn.zwz.basics.security.validate.ImageValidateFilter;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@ApiOperation(value = "SpringSecurity配置类")
@Configuration
@EnableMethodSecurity
public class WebSecurityConfig {
@Autowired
private ZwzLoginProperties zwzLoginProperties;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private AuthenticationFailHandler authenticationFailHandler;
@Autowired
private ZwzAccessDeniedHandler zwzAccessDeniedHandler;
@Autowired
private ImageValidateFilter imageValidateFilter;
@Autowired
private RedisTemplateHelper redisTemplate;
@Autowired
private SecurityUtil securityUtil;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().requestMatchers("/zwz/dictData/getByType/**","/zwz/file/view/**","/zwz/user/regist","/zwz/common/**","/*/*.js","/*/*.css","/*/*.png","/*/*.ico", "/swagger-ui.html").permitAll()
.and().formLogin().loginPage("/zwz/common/needLogin").loginProcessingUrl("/zwz/login").permitAll()
.successHandler(authenticationSuccessHandler).failureHandler(authenticationFailHandler).and()
.headers().frameOptions().disable().and()
.logout()
.permitAll()
.and()
.authorizeHttpRequests()
.anyRequest()
.authenticated()
.and()
.cors().and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling().accessDeniedHandler(zwzAccessDeniedHandler)
.and()
.authenticationProvider(authenticationProvider())
.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(imageValidateFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
return username -> userDetailsService.loadUserByUsername(username);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
@Bean
public JwtTokenOncePerRequestFilter authenticationJwtTokenFilter() throws Exception {
return new JwtTokenOncePerRequestFilter(redisTemplate, securityUtil, zwzLoginProperties);
}
}

@ -0,0 +1,88 @@
package cn.zwz.basics.security.controller;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.security.SecurityUserDetails;
import cn.zwz.basics.security.utils.WeiChatUtils;
import cn.zwz.basics.security.utils.ZwzWxNoticeUtils;
import cn.zwz.basics.utils.CommonUtil;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.utils.SecurityUtil;
import cn.zwz.data.entity.User;
import cn.zwz.data.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@RestController
@Api(tags = "企业微信验证码登录接口")
@RequestMapping("/zwz/qwVerificationCode")
@Transactional
public class QwVerificationCodeController {
@Autowired
private IUserService iUserService;
@Autowired
private RedisTemplateHelper redisTemplate;
@Autowired
private SecurityUtil securityUtil;
@ApiOperation(value = "发送企微验证码")
@RequestMapping(value = "/sendVerificationCode", method = RequestMethod.GET)
public Result<Object> sendVerificationCode(@RequestParam String jobNumber) {
if(!Objects.equals("zwz",jobNumber)) {
return ResultUtil.error("请联系管理员配置您的工号");
}
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.eq("status", 0);
userQw.eq("username",jobNumber);
Long userCount = iUserService.count(userQw);
if(userCount < 1L) {
return new ResultUtil<Object>().setErrorMsg("无权限登入");
}
String verificationCode = CommonUtil.getRandomTwoNum();
/**
*
*/
ZwzWxNoticeUtils.sendTuWenMessage("zwz", "OA登录验证","验证码 " + verificationCode + "1分钟后失效","https://gitee.com/yyzwz","https://bkimg.cdn.bcebos.com/pic/37d12f2eb9389b503a80d4b38b35e5dde6116ed7", WeiChatUtils.getToken());
redisTemplate.set("qwsms:" + jobNumber,verificationCode,60, TimeUnit.SECONDS);
return ResultUtil.success();
}
@SystemLog(about = "企微验证码登入", type = LogType.LOGIN)
@ApiOperation(value = "企微验证码登入")
@RequestMapping(value = "/verificationCodeLogin", method = RequestMethod.GET)
public Result<Object> verificationCodeLogin(@RequestParam String jobNumber,@RequestParam String code){
String codeAns = redisTemplate.get("qwsms:" + jobNumber);
if(codeAns == null) {
return ResultUtil.error("验证码已过期");
}
if(codeAns.equals(code)) {
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.eq("username",jobNumber);
List<User> users = iUserService.list(userQw);
if(users.size() == 0) {
return ResultUtil.error(jobNumber + "账户不存在");
}
String accessToken = securityUtil.getToken(jobNumber, false);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(new SecurityUserDetails(users.get(0)), null, null);
SecurityContextHolder.getContext().setAuthentication(authentication);
return ResultUtil.data(accessToken);
}
return ResultUtil.error("验证码错误");
}
}

@ -0,0 +1,85 @@
package cn.zwz.basics.security.jwt;
import cn.zwz.basics.utils.ResponseUtil;
import cn.zwz.basics.exception.ZwzAuthException;
import cn.zwz.basics.parameter.ZwzLoginProperties;
import cn.zwz.data.utils.ZwzNullUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;
@ApiOperation(value = "登录失败回调")
@Slf4j
@Component
public class AuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {
@Autowired
private ZwzLoginProperties tokenProperties;
@Autowired
private StringRedisTemplate stringRedisTemplate;
private static final String LOGIN_FAIL_TIMES_PRE = "LOGIN_FAIL_TIMES_PRE:";
private static final String REQUEST_PARAMETER_USERNAME = "username:";
private static final boolean RESPONSE_FAIL_FLAG = false;
private static final int RESPONSE_FAIL_CODE = 500;
@ApiOperation(value = "查询登录失败的次数")
public boolean recordLoginTime(String username) {
String loginFailTimeStr = stringRedisTemplate.opsForValue().get(LOGIN_FAIL_TIMES_PRE + username);
int loginFailTime = 0;
// 已错误次数
if(!ZwzNullUtils.isNull(loginFailTimeStr)){
loginFailTime = Integer.parseInt(loginFailTimeStr) + 1;
}
stringRedisTemplate.opsForValue().set(LOGIN_FAIL_TIMES_PRE + username, loginFailTime + "", tokenProperties.getLoginFailMaxThenLockTimes(), TimeUnit.MINUTES);
if(loginFailTime >= tokenProperties.getMaxLoginFailTimes()){
stringRedisTemplate.opsForValue().set("userLoginDisableFlag:"+username, "fail", tokenProperties.getLoginFailMaxThenLockTimes(), TimeUnit.MINUTES);
return false;
}
return true;
}
@Override
@ApiOperation(value = "登录失败回调")
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) {
if (exception instanceof BadCredentialsException || exception instanceof UsernameNotFoundException) {
recordLoginTime(request.getParameter(REQUEST_PARAMETER_USERNAME));
String failTimesStr = stringRedisTemplate.opsForValue().get(LOGIN_FAIL_TIMES_PRE + request.getParameter(REQUEST_PARAMETER_USERNAME));
//已错误的次数
int userFailTimes = 0;
if(!ZwzNullUtils.isNull(failTimesStr)){
userFailTimes = Integer.parseInt(failTimesStr);
}
int restLoginTime = tokenProperties.getMaxLoginFailTimes() - userFailTimes;
if(restLoginTime < 5 && restLoginTime > 0){
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_FAIL_CODE,"账号密码不正确,还能尝试登录" + restLoginTime + "次"));
} else if(restLoginTime < 1) {
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_FAIL_CODE,"重试超限,请您" + tokenProperties.getLoginFailMaxThenLockTimes() + "分后再登录"));
} else {
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_FAIL_CODE,"账号密码不正确"));
}
} else if (exception instanceof ZwzAuthException){
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_FAIL_CODE,((ZwzAuthException) exception).getMsg()));
} else if (exception instanceof DisabledException) {
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_FAIL_CODE,"账户处于禁用状态,无法登录"));
} else {
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_FAIL_CODE,"系统当前不能登录,请稍后再试"));
}
}
}

@ -0,0 +1,88 @@
package cn.zwz.basics.security.jwt;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.utils.ResponseUtil;
import cn.zwz.basics.baseVo.TokenUser;
import cn.zwz.basics.parameter.ZwzLoginProperties;
import cn.hutool.core.util.StrUtil;
import cn.zwz.data.utils.ZwzNullUtils;
import com.alibaba.fastjson2.JSON;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ApiOperation(value = "登录成功回调")
@Slf4j
@Component
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
private ZwzLoginProperties tokenProperties;
@Autowired
private StringRedisTemplate redisTemplate;
private static final boolean RESPONSE_SUCCESS_FLAG = true;
private static final int RESPONSE_SUCCESS_CODE = 200;
private static final String TOKEN_REPLACE_STR_FRONT = "-";
private static final String TOKEN_REPLACE_STR_BACK = "";
@Override
@ApiOperation(value = "登录成功回调")
@SystemLog(about = "登录系统", type = LogType.LOGIN)
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication ac) throws IOException, ServletException {
String saveLogin = request.getParameter(ZwzLoginProperties.SAVE_LOGIN_PRE);
Boolean saveLoginFlag = false;
if(!ZwzNullUtils.isNull(saveLogin) && Objects.equals(saveLogin,"true")){
saveLoginFlag = true;
}
List<String> permissionsList = new ArrayList<>();
List<GrantedAuthority> authorities = (List<GrantedAuthority>) ((UserDetails)ac.getPrincipal()).getAuthorities();
for(GrantedAuthority g : authorities){
permissionsList.add(g.getAuthority());
}
String token = UUID.randomUUID().toString().replace(TOKEN_REPLACE_STR_FRONT, TOKEN_REPLACE_STR_BACK);
String username = ((UserDetails)ac.getPrincipal()).getUsername();
TokenUser user = new TokenUser(username, permissionsList, saveLoginFlag);
// 判断是否存储菜单权限
if(!tokenProperties.getSaveRoleFlag()){
user.setPermissions(null);
}
// 单点登录判断
if(tokenProperties.getSsoFlag()){
String oldToken = redisTemplate.opsForValue().get(ZwzLoginProperties.USER_TOKEN_PRE + username);
if(StrUtil.isNotBlank(oldToken)){
redisTemplate.delete(ZwzLoginProperties.HTTP_TOKEN_PRE + oldToken);
}
}
if(saveLoginFlag){
redisTemplate.opsForValue().set(ZwzLoginProperties.USER_TOKEN_PRE + username, token, tokenProperties.getUserSaveLoginTokenDays(), TimeUnit.DAYS);
redisTemplate.opsForValue().set(ZwzLoginProperties.HTTP_TOKEN_PRE + token, JSON.toJSONString(user), tokenProperties.getUserSaveLoginTokenDays(), TimeUnit.DAYS);
}else{
redisTemplate.opsForValue().set(ZwzLoginProperties.USER_TOKEN_PRE + username, token, tokenProperties.getUserTokenInvalidDays(), TimeUnit.MINUTES);
redisTemplate.opsForValue().set(ZwzLoginProperties.HTTP_TOKEN_PRE + token, JSON.toJSONString(user), tokenProperties.getUserTokenInvalidDays(), TimeUnit.MINUTES);
}
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_SUCCESS_FLAG,RESPONSE_SUCCESS_CODE,"登录成功", token));
}
}

@ -0,0 +1,100 @@
package cn.zwz.basics.security.jwt;
import cn.zwz.basics.baseVo.TokenUser;
import cn.zwz.basics.parameter.ZwzLoginProperties;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.utils.ResponseUtil;
import cn.zwz.basics.utils.SecurityUtil;
import cn.zwz.data.utils.ZwzNullUtils;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.ApiOperation;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ApiOperation(value = "自定义权限过滤")
@Slf4j
public class JwtTokenOncePerRequestFilter extends OncePerRequestFilter {
private SecurityUtil securityUtil;
@Autowired
private RedisTemplateHelper redisTemplate;
private ZwzLoginProperties zwzLoginProperties;
private static final boolean RESPONSE_FAIL_FLAG = false;
private static final int RESPONSE_NO_ROLE_CODE = 401;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String tokenHeader = request.getHeader(ZwzLoginProperties.HTTP_HEADER);
if(ZwzNullUtils.isNull(tokenHeader)){
tokenHeader = request.getParameter(ZwzLoginProperties.HTTP_HEADER);
}
if (ZwzNullUtils.isNull(tokenHeader)) {
filterChain.doFilter(request, response);
return;
}
try {
UsernamePasswordAuthenticationToken token = getUsernamePasswordAuthenticationToken(tokenHeader, response);
SecurityContextHolder.getContext().setAuthentication(token);
}catch (Exception e){
log.warn("自定义权限过滤失败" + e);
}
filterChain.doFilter(request, response);
}
@ApiOperation(value = "判断登录是否失效")
private UsernamePasswordAuthenticationToken getUsernamePasswordAuthenticationToken(String header, HttpServletResponse response) {
String userName = null;
String tokenInRedis = redisTemplate.get(ZwzLoginProperties.HTTP_TOKEN_PRE + header);
if(ZwzNullUtils.isNull(tokenInRedis)){
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_NO_ROLE_CODE,"登录状态失效,需要重登!"));
return null;
}
TokenUser tokenUser = JSONObject.parseObject(tokenInRedis,TokenUser.class);
userName = tokenUser.getUsername();
List<GrantedAuthority> permissionList = new ArrayList<>();
if(zwzLoginProperties.getSaveRoleFlag()){
for(String permission : tokenUser.getPermissions()){
permissionList.add(new SimpleGrantedAuthority(permission));
}
} else{
permissionList = securityUtil.getCurrUserPerms(userName);
}
if(!tokenUser.getSaveLogin()){
redisTemplate.set(ZwzLoginProperties.USER_TOKEN_PRE + userName, header, zwzLoginProperties.getUserTokenInvalidDays(), TimeUnit.MINUTES);
redisTemplate.set(ZwzLoginProperties.HTTP_TOKEN_PRE + header, tokenInRedis, zwzLoginProperties.getUserTokenInvalidDays(), TimeUnit.MINUTES);
}
if(!ZwzNullUtils.isNull(userName)) {
User user = new User(userName, "", permissionList);
return new UsernamePasswordAuthenticationToken(user, null, permissionList);
}
return null;
}
public JwtTokenOncePerRequestFilter(RedisTemplateHelper redis, SecurityUtil securityUtil,ZwzLoginProperties zwzLoginProperties) {
this.redisTemplate = redis;
this.securityUtil = securityUtil;
this.zwzLoginProperties = zwzLoginProperties;
}
}

@ -0,0 +1,26 @@
package cn.zwz.basics.security.jwt;
import cn.zwz.basics.utils.ResponseUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@ApiOperation(value = "自定义权限文案")
@Component
public class ZwzAccessDeniedHandler implements AccessDeniedHandler {
private static final boolean RESPONSE_FAIL_FLAG = false;
private static final int RESPONSE_NO_SELF_ROLE_CODE = 403;
@Override
@ApiOperation(value = "重写自定义权限拒绝方法")
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exception) {
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_NO_SELF_ROLE_CODE,"您无权访问该菜单,谢谢!"));
}
}

@ -0,0 +1,98 @@
package cn.zwz.basics.security.utils;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.ApiOperation;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.URL;
@ApiOperation(value = "日志枚举类")
public class WeChatUploadMeidaUtils {
/**
*
*
* @param fileType
* @param filePath
* @return
* @throws Exception
*/
public static JSONObject UploadMeida(String fileType, String filePath, String token) throws Exception {
// 返回结果
String result = null;
File file = new File(filePath);
if (!file.exists() || !file.isFile()) {
throw new IOException("文件不存在");
}
String uploadTempMaterial_url="https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
uploadTempMaterial_url = uploadTempMaterial_url.replace("ACCESS_TOKEN", token).replace("TYPE", fileType);
URL url = new URL(uploadTempMaterial_url);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");// 以POST方式提交表单
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);// POST方式不能使用缓存
// 设置请求头信息
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
// 设置边界
String BOUNDARY = "----------" + System.currentTimeMillis();
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
// 请求正文信息
// 第一部分
StringBuilder sb = new StringBuilder();
sb.append("--");// 必须多两条道
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data;name=\"media\"; filename=\"" + file.getName() + "\"\r\n");
sb.append("Content-Type:application/octet-stream\r\n\r\n");
// 获得输出流
OutputStream out = new DataOutputStream(conn.getOutputStream());
// 输出表头
out.write(sb.toString().getBytes("UTF-8"));
// 文件正文部分
// 把文件以流的方式 推送道URL中
DataInputStream din = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] buffer = new byte[1024];
while ((bytes = din.read(buffer)) != -1) {
out.write(buffer, 0, bytes);
}
din.close();
// 结尾部分
byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");// 定义数据最后分割线
out.write(foot);
out.flush();
out.close();
if (HttpsURLConnection.HTTP_OK == conn.getResponseCode()) {
StringBuffer strbuffer = null;
BufferedReader reader = null;
try {
strbuffer = new StringBuffer();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String lineString = null;
while ((lineString = reader.readLine()) != null) {
strbuffer.append(lineString);
}
if (result == null) {
result = strbuffer.toString();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
}
}
JSONObject jsonObject = JSONObject.parseObject(result);
return jsonObject;
}
}

@ -0,0 +1,192 @@
package cn.zwz.basics.security.utils;
import java.io.*;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import javax.net.ssl.*;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ApiOperation(value = "HTTP工具类")
public class WeiChatUtils implements X509TrustManager {
@ApiModelProperty(value = "企业ID")
public static final String CORPID = "";
@ApiModelProperty(value = "企业微信密匙")
public static final String CORPSECRET = "";
/**
* Token
* @return
*/
public static String getToken(){
String s= httpsRequest("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + CORPID + "&corpsecret=" + CORPSECRET,"GET",null);
JSONObject err = JSON.parseObject(s);
if(err.getString("errmsg").equals("ok")){
return err.getString("access_token");
}
return null;
}
public static String getCustomerName(String wxid,String inToken,String outToken) {
if(wxid.startsWith("wo") || wxid.startsWith("wm")) {
String s= httpsRequest("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=" + outToken + "&external_userid=" + wxid,"GET",null);
JSONObject jsonObject = JSON.parseObject(s);
if(jsonObject.getString("errcode").equals("0")) {
JSONObject externalContact = jsonObject.getJSONObject("external_contact");
return externalContact.getString("name");
}else {
return "未知";
}
}
if(wxid.startsWith("wb")) {
return "机器人";
}
String s= httpsRequest("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=" + inToken + "&userid=" + wxid,"GET",null);
JSONObject jsonObject = JSON.parseObject(s);
if(jsonObject.getString("errcode").equals("0")) {
return jsonObject.getString("name");
}else {
return "未知";
}
}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
/*
* https GET/POST
*
* */
public static String httpsRequest(String requestUrl,String requestMethod,String outputStr){
StringBuffer buffer=null;
try{
//创建SSLContext
SSLContext sslContext=SSLContext.getInstance("SSL");
TrustManager[] tm={new WeiChatUtils()};
//初始化
sslContext.init(null, tm, new java.security.SecureRandom());;
//获取SSLSocketFactory对象
SSLSocketFactory ssf=sslContext.getSocketFactory();
URL url=new URL(requestUrl);
HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod(requestMethod);
//设置当前实例使用的SSLSoctetFactory
conn.setSSLSocketFactory(ssf);
conn.connect();
//往服务器端写内容
if(null!=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
//读取服务器端返回的内容
InputStream is=conn.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
buffer=new StringBuffer();
String line=null;
while((line=br.readLine())!=null){
buffer.append(line);
}
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
@Data
@AllArgsConstructor
@NoArgsConstructor
private static class Wechatdepartment {
// 部门名称
private String name;
// 英文名称
private String name_en;
// 父部门id
private int parentid;
// 在父部门中的次序值
private int order;
// 部门id
private int id;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
private static class WeChatUser {
// 成员名称。长度为1~64个utf8字符
private String name;
// 成员别名。长度1~32个utf8字符
private String alias;
// 手机号码。企业内必须唯一mobile/email二者不能同时为空
private String mobile;
// 用户id
private String userid;
// 成员所属部门id列表,不超过100个
private String[] department;
// 部门内的排序值默认为0
private String[] order;
// 职务信息
private String position;
// 性别。1表示男性2表示女性
private String gender;
// 邮箱
private String email;
// 个数必须和参数department的个数一致
// 表示在所在的部门内是否为上级。1表示为上级0表示非上级。
private String is_leader_in_dept;
// 主部门
private String main_department;
// 批量删除id列表
private List<String> useridlist;
// 座机
private String telephone;
private ExternalProfile external_profile;
}
@Data
private static class ExternalProfile {
private ExternalAttr[] external_attr;
}
@Data
private static class ExternalAttr {
private String type;
private ExternalText text;
private String name;
}
@Data
private static class ExternalText {
private String value;
}
}

@ -0,0 +1,333 @@
package cn.zwz.basics.security.utils;
import cn.zwz.data.utils.ZwzNullUtils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@ApiOperation(value = "企微消息发送消息工具类")
public class ZwzWxNoticeUtils {
private static final String BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";
private static final String USER_ID_ERR = "81013";
@ApiModelProperty(value = "朗世企业ID")
public static final String YH_CORPID = "wwf94bb44e76e308f8";
@ApiOperation(value = "发送文本消息")
public static String sendInputMessage(int company,String userId,String content,String token){
if(content == null || ZwzNullUtils.isNull(content)) {
return "NULL";
}
String json = JSON.toJSONString(new ZwzWeChatNoticeInput(userId,"text",YH_CORPID,new ZwzWeChatNoticeInputItem(content),0,1));
String s= WeiChatUtils.httpsRequest(BASE_URL + token,"POST",json);
System.out.println(s);
JSONObject ans1 = JSONObject.parseObject(s);
String jsonStr2 = ans1.getString("errcode");
if(jsonStr2.equals("0")){
return ans1.getString("msgid");
} else if(jsonStr2.equals("81013")) {
return USER_ID_ERR;
}
return "FAIL";
}
@ApiOperation(value = "企微上传文件")
public static String uploadWeChatFile(String path, String fileType,String token) {
try {
JSONObject jsonObject = WeChatUploadMeidaUtils.UploadMeida(fileType,path,token);
System.out.println(jsonObject.toJSONString());
String errcode = jsonObject.getString("errcode");
if(errcode.equals("0")) {
System.out.println("文件上传成功");
System.out.println(jsonObject.getString("media_id"));
return jsonObject.getString("media_id");
}
return "文件上传失败";
} catch (Exception e) {
return "文件上传失败";
}
}
@ApiOperation(value = "发送图片消息")
public static String sendImageMessage(int company,String userId,String mediaId,String token) {
ZwzWeiChatNoticeImage image = new ZwzWeiChatNoticeImage(userId,"image",YH_CORPID,new ZwzWeChatNoticeImageItem(mediaId),0,1);
String json = JSON.toJSONString(image);
String s= WeiChatUtils.httpsRequest(BASE_URL + token,"POST",json);
JSONObject ans1 = JSONObject.parseObject(s);
String errcode = ans1.getString("errcode");
if(errcode.equals("0")){
return ans1.getString("msgid");
} else if(errcode.equals("81013")) {
return USER_ID_ERR;
}
return "FAIL";
}
@ApiOperation(value = "发送视频消息")
public static String sendVideoMessage(int company,String userId,String mediaId,String title,String description,String token) {
ZwzWeiChatNoticeVideo video = new ZwzWeiChatNoticeVideo(userId,"video",YH_CORPID,new ZwzWeChatNoticeVideoItem(mediaId,title,description),0,1);
String json = JSON.toJSONString(video);
String s= WeiChatUtils.httpsRequest(BASE_URL + token,"POST",json);
JSONObject ans1 = JSONObject.parseObject(s);
String errcode = ans1.getString("errcode");
if(errcode.equals("0")){
return ans1.getString("msgid");
} else if(errcode.equals("81013")) {
return USER_ID_ERR;
}
return "FAIL";
}
@ApiOperation(value = "发送文件消息")
public static String sendFileMessage(int company,String userId,String mediaId,String token) {
ZwzWeiChatNoticeFile file = new ZwzWeiChatNoticeFile(userId,"file",YH_CORPID,new ZwzWeChatNoticeFileItem(mediaId),0,1);
String json = JSON.toJSONString(file);
String s= WeiChatUtils.httpsRequest(BASE_URL + token,"POST",json);
JSONObject ans1 = JSONObject.parseObject(s);
String errcode = ans1.getString("errcode");
if(errcode.equals("0")){
return ans1.getString("msgid");
} else if(errcode.equals("81013")) {
return USER_ID_ERR;
}
return "FAIL";
}
@ApiOperation(value = "发送文本卡片消息")
public static String sendTextCardMessage(int company,String userId,String title,String description,String url,String btntxt,String token) {
ZwzWeiChatNoticeTextCard file = new ZwzWeiChatNoticeTextCard(userId,"textcard",YH_CORPID,new ZwzWeChatNoticeTextCardItem(title,description,url,btntxt),0,1);
String json = JSON.toJSONString(file);
String s= WeiChatUtils.httpsRequest(BASE_URL + token,"POST",json);
JSONObject ans1 = JSONObject.parseObject(s);
String errcode = ans1.getString("errcode");
if(errcode.equals("0")){
return ans1.getString("msgid");
} else if(errcode.equals("81013")) {
return USER_ID_ERR;
}
return "FAIL";
}
@ApiOperation(value = "发送图文消息")
public static String sendTuWenMessage(String userId,String title,String description,String url,String picUrl,String token) {
List<ZwzWeChatNoticeTuWenItemValue> tuWenList = new ArrayList<>();
tuWenList.add(new ZwzWeChatNoticeTuWenItemValue(title, description, url, picUrl));
ZwzWeChatNoticeTuWen file = new ZwzWeChatNoticeTuWen(userId,"news","1000002",new ZwzWeChatNoticeTuWenItem(tuWenList),0,1);
String json = JSON.toJSONString(file);
String s= WeiChatUtils.httpsRequest(BASE_URL + token,"POST",json);
JSONObject ans1 = JSONObject.parseObject(s);
String errcode = ans1.getString("errcode");
if(errcode.equals("0")){
return ans1.getString("msgid");
} else if(errcode.equals("81013")) {
return USER_ID_ERR;
}
return "FAIL";
}
@ApiOperation(value = "发送Markdown消息")
public static String sendMarkdownMessage(int company,String userId,String content,String token){
if(content == null || ZwzNullUtils.isNull(content)) {
return "NULL";
}
String json = JSON.toJSONString(new ZwzWeChatNoticeMarkdown(userId,"markdown",YH_CORPID,new ZwzWeChatNoticeMarkdownItem(content),0,1));
String s= WeiChatUtils.httpsRequest(BASE_URL + token,"POST",json);
System.out.println(s);
JSONObject ans1 = JSONObject.parseObject(s);
String jsonStr2 = ans1.getString("errcode");
if(jsonStr2.equals("0")){
return ans1.getString("msgid");
} else if(jsonStr2.equals("81013")) {
return USER_ID_ERR;
}
return "FAIL";
}
/**
* MarkdownB
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeMarkdown {
private String touser;
private String msgtype;
private String agentid;
private ZwzWeChatNoticeMarkdownItem markdown;
private int safe;
private int enable_duplicate_check;
}
/**
* MarkdownA
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeMarkdownItem {
private String content;
}
/**
* B
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeTuWen {
private String touser;
private String msgtype;
private String agentid;
private ZwzWeChatNoticeTuWenItem news;
private int safe;
private int enable_duplicate_check;
}
/**
* A
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeTuWenItem {
private List<ZwzWeChatNoticeTuWenItemValue> articles;
}
/**
* A
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeTuWenItemValue {
private String title;
private String description;
private String url;
private String picurl;
}
/**
* B
*/
@Data
@AllArgsConstructor
private static class ZwzWeiChatNoticeTextCard {
private String touser;
private String msgtype;
private String agentid;
private ZwzWeChatNoticeTextCardItem textcard;
private int safe;
private int enable_duplicate_check;
}
/**
* A
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeTextCardItem {
private String title;
private String description;
private String url;
private String btntxt;
}
/**
* B
*/
@Data
@AllArgsConstructor
private static class ZwzWeiChatNoticeFile {
private String touser;
private String msgtype;
private String agentid;
private ZwzWeChatNoticeFileItem file;
private int safe;
private int enable_duplicate_check;
}
/**
* A
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeFileItem {
private String media_id;
}
/**
* B
*/
@Data
@AllArgsConstructor
private static class ZwzWeiChatNoticeVideo {
private String touser;
private String msgtype;
private String agentid;
private ZwzWeChatNoticeVideoItem video;
private int safe;
private int enable_duplicate_check;
}
/**
* A
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeVideoItem {
private String media_id;
private String title;
private String description;
}
/**
* B
*/
@Data
@AllArgsConstructor
private static class ZwzWeiChatNoticeImage {
private String touser;
private String msgtype;
private String agentid;
private ZwzWeChatNoticeImageItem image;
private int safe;
private int enable_duplicate_check;
}
/**
* A
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeImageItem {
private String media_id;
}
/**
* B
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeInput {
private String touser;
private String msgtype;
private String agentid;
private ZwzWeChatNoticeInputItem text;
private int safe;
private int enable_duplicate_check;
}
/**
* A
*/
@Data
@AllArgsConstructor
private static class ZwzWeChatNoticeInputItem {
private String content;
}
}

@ -0,0 +1,73 @@
package cn.zwz.basics.security.validate;
import cn.zwz.basics.utils.ResponseUtil;
import cn.zwz.basics.parameter.CaptchaProperties;
import cn.zwz.data.utils.ZwzNullUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
/**
* @author
* CSDN: Designer
*/
@ApiOperation(value = "验证码过滤类")
@Configuration
public class ImageValidateFilter extends OncePerRequestFilter {
@Autowired
private CaptchaProperties captchaProperties;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private PathMatcher pathMatcher;
private static final boolean RESPONSE_FAIL_FLAG = false;
private static final int RESPONSE_CODE_FAIL_CODE = 500;
@Override
@ApiOperation(value = "验证码过滤")
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Boolean filterFlag = false;
for(String requestURI : captchaProperties.getVerification()){
if(pathMatcher.match(requestURI, request.getRequestURI())){
filterFlag = true;
break;
}
}
if(!filterFlag) {
filterChain.doFilter(request, response);
return;
}
String verificationCodeId = request.getParameter("captchaId");
String userInputCode = request.getParameter("code");
if(ZwzNullUtils.isNull(userInputCode) || ZwzNullUtils.isNull(verificationCodeId)){
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_CODE_FAIL_CODE,"验证码为空"));
return;
}
String codeAnsInRedis = redisTemplate.opsForValue().get(verificationCodeId);
if(ZwzNullUtils.isNull(codeAnsInRedis)){
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_CODE_FAIL_CODE,"已过期的验证码,需要重新填写"));
return;
}
if(!Objects.equals(codeAnsInRedis.toLowerCase(),userInputCode.toLowerCase())) {
ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_CODE_FAIL_CODE,"验证码不正确"));
return;
}
redisTemplate.delete(verificationCodeId);
filterChain.doFilter(request, response);
}
}

@ -0,0 +1,95 @@
package cn.zwz.basics.utils;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.multipart.MultipartFile;
import java.util.Base64;
import java.io.*;
@ApiOperation(value = "文件工具类")
public class Base64DecodeMultipartFile implements MultipartFile {
@ApiModelProperty(value = "图片内容")
private final byte[] imgContent;
@ApiModelProperty(value = "图片抬头")
private final String header;
private static final String IMAGE_PATH_STEP_STR = ".";
private static final String IMAGE_PATH_SPLIT_STR = ";";
private static final String IMAGE_HEADER_SPLIT_STR = "/";
private static final String IMAGE_TYPE_SPLIT_STR = ":";
private static final String IMAGE_BASE_SPLIT_STR = ",";
public Base64DecodeMultipartFile(byte[] imgContent, String header) {
this.imgContent = imgContent;
this.header = header.split(IMAGE_PATH_SPLIT_STR)[0];
}
@Override
@ApiOperation(value = "获取图片的大小")
public long getSize() {
return imgContent.length;
}
@Override
@ApiOperation(value = "获取图片的输入流")
public InputStream getInputStream() {
return new ByteArrayInputStream(imgContent);
}
@Override
@ApiOperation(value = "获取图片的字节流")
public byte[] getBytes() {
return imgContent;
}
@Override
@ApiOperation(value = "获取图片名称")
public String getName() {
return System.currentTimeMillis() + Math.random() + IMAGE_PATH_STEP_STR + header.split(IMAGE_HEADER_SPLIT_STR)[1];
}
@Override
@ApiOperation(value = "图片转换")
public void transferTo(File dest) throws IOException, IllegalStateException {
new FileOutputStream(dest).write(imgContent);
}
@Override
@ApiOperation(value = "判断图片是否为空")
public boolean isEmpty() {
return imgContent == null || imgContent.length == 0;
}
@Override
@ApiOperation(value = "获取图片完整路径")
public String getOriginalFilename() {
return System.currentTimeMillis() + (int)Math.random() * 10000 + IMAGE_PATH_STEP_STR + header.split(IMAGE_HEADER_SPLIT_STR)[1];
}
@Override
@ApiOperation(value = "获取图片类型")
public String getContentType() {
return header.split(IMAGE_TYPE_SPLIT_STR)[1];
}
public static MultipartFile base64Convert(String base64) {
String[] baseStrs = base64.split(IMAGE_BASE_SPLIT_STR);
byte[] b = Base64.getDecoder().decode(baseStrs[1]);
for (int i = 0; i < b.length; i++) {
if (b[i] < 0) {
b[i] += 256;
}
}
return new Base64DecodeMultipartFile(b, baseStrs[0]);
}
}

@ -0,0 +1,47 @@
package cn.zwz.basics.utils;
import io.swagger.annotations.ApiOperation;
import java.security.SecureRandom;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;
@ApiOperation(value = "公共工具类")
public class CommonUtil {
private static SecureRandom random = new SecureRandom();
@ApiOperation(value = "生成随机文件名称")
public static String renamePic(String fileName) {
return UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
}
@ApiOperation(value = "生成随机企微验证码")
public static String getRandomTwoNum() {
int num = random.nextInt(99);
// 不足六位前面补0
String str = String.format("%02d", num);
return str;
}
@ApiOperation(value = "避免删除 DFS 死循环")
public static Boolean judgeIds(String tempString, String[] list){
boolean flag = true;
for(String id : list){
if(Objects.equals(tempString,id)){
flag = false;
break;
}
}
return !flag;
}
@ApiOperation(value = "生成随机6位验证码")
public static String getRandomNum() {
Random random = new Random();
int num = random.nextInt(999999);
return String.format("%06d", num);
}
}

@ -0,0 +1,237 @@
package cn.zwz.basics.utils;
import cn.zwz.basics.exception.ZwzException;
import cn.zwz.data.utils.ZwzNullUtils;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
@ApiOperation(value = "验证码工具类")
public class CreateVerifyCode {
@ApiModelProperty(value = "验证码")
private String code = null;
@ApiModelProperty(value = "验证码字符个数")
private int charactersNumber = 4;
@ApiModelProperty(value = "图片高度")
private int imagePeripheralHeight = 40;
@ApiModelProperty(value = "图片宽度")
private int imagePeripheralWidth = 160;
@ApiModelProperty(value = "干扰线数")
private int lineCount = 20;
@ApiModelProperty(value = "图片Buffer")
private BufferedImage buffImg = null;
Random random = new Random();
public CreateVerifyCode() {
creatImage();
}
public CreateVerifyCode(int imageWidth, int imageHeight) {
this.imagePeripheralWidth = imageWidth;
this.imagePeripheralHeight = imageHeight;
creatImage();
}
public CreateVerifyCode(int imageWidth, int imageHeight, int codeCount) {
this.imagePeripheralWidth = imageWidth;
this.imagePeripheralHeight = imageHeight;
this.charactersNumber = codeCount;
creatImage();
}
public CreateVerifyCode(int imageWidth, int imageHeight, int codeCount, int lineCount) {
this.imagePeripheralWidth = imageWidth;
this.imagePeripheralHeight = imageHeight;
this.charactersNumber = codeCount;
this.lineCount = lineCount;
creatImage();
}
public CreateVerifyCode(int imageWidth, int imageHeight, int codeCount, int lineCount, String code) {
this.imagePeripheralWidth = imageWidth;
this.imagePeripheralHeight = imageHeight;
this.charactersNumber = codeCount;
this.lineCount = lineCount;
creatImage(code);
}
/**
*
*/
private void creatImage() {
// 字体的宽度
int fontWidth = imagePeripheralWidth / charactersNumber;
// 字体的高度
int fontHeight = imagePeripheralHeight - 5;
int codeY = imagePeripheralHeight - 8;
// 图像buffer
buffImg = new BufferedImage(imagePeripheralWidth, imagePeripheralHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = buffImg.getGraphics();
//Graphics2D g = buffImg.createGraphics();
// 设置背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, imagePeripheralWidth, imagePeripheralHeight);
// 设置字体
//Font font1 = getFont(fontHeight);
Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
g.setFont(font);
// 设置干扰线
for (int i = 0; i < lineCount; i++) {
int xs = random.nextInt(imagePeripheralWidth);
int ys = random.nextInt(imagePeripheralHeight);
int xe = xs + random.nextInt(imagePeripheralWidth);
int ye = ys + random.nextInt(imagePeripheralHeight);
g.setColor(getRandColor(1, 255));
g.drawLine(xs, ys, xe, ye);
}
// 添加噪点 噪声率
float yawpRate = 0.01f;
int area = (int) (yawpRate * imagePeripheralWidth * imagePeripheralHeight);
for (int i = 0; i < area; i++) {
int x = random.nextInt(imagePeripheralWidth);
int y = random.nextInt(imagePeripheralHeight);
buffImg.setRGB(x, y, random.nextInt(255));
}
// 得到随机字符
String str1 = randomStr(charactersNumber);
this.code = str1;
for (int i = 0; i < charactersNumber; i++) {
String strRand = str1.substring(i, i + 1);
g.setColor(getRandColor(1, 255));
g.drawString(strRand, i*fontWidth+3, codeY);
}
}
@ApiOperation(value = "图片生成工具类")
private void creatImage(String code) {
if(ZwzNullUtils.isNull(code)){
throw new ZwzException("图形验证码过期了,再生成个新的哦!");
}
this.code = code;
buffImg = new BufferedImage(imagePeripheralWidth, imagePeripheralHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = buffImg.getGraphics();
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, imagePeripheralWidth, imagePeripheralHeight);
Font font = new Font("Fixedsys", Font.BOLD, imagePeripheralHeight - 5);
g.setFont(font);
float yawpRate = 0.01f;
int area = (int) (yawpRate * imagePeripheralWidth * imagePeripheralHeight);
for (int i = 0; i < area; i++) {
buffImg.setRGB(random.nextInt(imagePeripheralWidth), random.nextInt(imagePeripheralHeight), random.nextInt(255));
}
for (int i = 0; i < lineCount; i++) {
int xs = random.nextInt(imagePeripheralWidth);
int ys = random.nextInt(imagePeripheralHeight);
int xe = xs + random.nextInt(imagePeripheralWidth);
int ye = ys + random.nextInt(imagePeripheralHeight);
g.setColor(getRandColor(2, 254));
g.drawLine(xs, ys, xe, ye);
}
for (int i = 0; i < code.length(); i++) {
String strRand = code.substring(i, i + 1);
g.setColor(getRandColor(2, 254));
g.drawString(strRand, i * (imagePeripheralWidth / charactersNumber) + 3, imagePeripheralHeight - 8);
}
}
@ApiOperation(value = "随机生成验证码")
public String randomStr(int size) {
String str1 = "0123456789";
String str2 = "";
for (int i = 0; i < size; i++) {
double randomIndex = Math.random();
double randomNumber = randomIndex * (str1.length() - 1);
str2 += str1.charAt((int) randomNumber);
}
return str2;
}
@ApiOperation(value = "随机生成验证码颜色")
private Color getRandColor(int color1, int color2) {
color1 = color1 > 255 ? 255 : color1;
color2 = color2 > 255 ? 255 : color2;
return new Color(color1 + random.nextInt(color2 - color1), color1 + random.nextInt(color2 - color1), color1 + random.nextInt(color2 - color1));
}
/**
*
*/
private Font getFont(int size) {
Random random = new Random();
Font[] font = new Font[5];
font[0] = new Font("Ravie", Font.PLAIN, size);
font[1] = new Font("Antique Olive Compact", Font.PLAIN, size);
font[2] = new Font("Fixedsys", Font.PLAIN, size);
font[3] = new Font("Wide Latin", Font.PLAIN, size);
font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, size);
return font[random.nextInt(5)];
}
// 扭曲方法
private void shear(Graphics g, int w1, int h1, Color color) {
shearX(g, w1, h1, color);
shearY(g, w1, h1, color);
}
private void shearX(Graphics g, int imageWidth, int imageHeight, Color color) {
int period = random.nextInt(2);
for (int i = 0; i < imageHeight; i ++) {
double doubleValue = (double) (period >> 1) * Math.sin((double) i / (double) period + (2.0 * Math.PI * (double) random.nextInt(2)));
g.copyArea(0, i, imageWidth, 1, doubleToInteger(doubleValue), 0);
// 加边框
g.setColor(color);
g.drawLine(doubleToInteger(doubleValue), i, 0, i);
g.drawLine(doubleToInteger(doubleValue) + imageWidth, i, imageWidth, i);
}
}
private Integer doubleToInteger(double number) {
return (int) number;
}
private void shearY(Graphics g, int w1, int h1, Color color) {
int period = random.nextInt(40) + 10;
for (int i = 0; i < w1; i++) {
double doubleValue = (double) (period >> 1) * Math.sin((double) i / (double) period + (2.0 * Math.PI * 7.0) / 20.0);
g.copyArea(i, 0, 1, h1, 0, doubleToInteger(doubleValue));
// 加边框
g.setColor(color);
g.drawLine(i, doubleToInteger(doubleValue), i, 0);
g.drawLine(i, doubleToInteger(doubleValue) + h1, i, h1);
}
}
public void write(OutputStream sos) throws IOException {
ImageIO.write(buffImg, "png", sos);
sos.close();
}
public BufferedImage getBuffImg() {
return buffImg;
}
public String getCode() {
return code.toLowerCase();
}
}

@ -0,0 +1,100 @@
package cn.zwz.basics.utils;
import cn.hutool.http.HttpUtil;
import cn.zwz.data.utils.ZwzNullUtils;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Objects;
@ApiOperation(value = "IP定位工具类")
@Slf4j
@Component
public class IpInfoUtil {
@ApiModelProperty(value = "腾讯地图的KEY值")
private String key = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX";
private static final String IP_HEADER_PRE_ONE = "x-forwarded-for";
private static final String IP_HEADER_PRE_TWO = "Proxy-Client-IP";
private static final String IP_HEADER_PRE_THREE = "WL-Proxy-Client-IP";
private static final String IP_HEADER_NONE = "unknown";
private static final String IP_HEADER_LOCAL_HOST = "127.0.0.1";
private static final String IP_HEADER_LOCAL_LONG_HOST = "0:0:0:0:0:0:0:1";
private static final String TXDT_URL_PRE = "https://apis.map.qq.com/ws/location/v1/ip?key=";
@ApiOperation(value = "查询IP地址的区县")
public String getIpCity(HttpServletRequest request){
String url = TXDT_URL_PRE + key + "&ip=" + getRequestIpAddress(request);
String resultStr = "本地测试";
try {
JSONObject objectResult = JSONObject.parseObject(HttpUtil.get(url, 3000));
if(Objects.equals(objectResult.get("status"),"0")) {
JSONObject adInfo = objectResult.getJSONObject("result").getJSONObject("ad_info");
String nationStr = adInfo.getString("nation");
String provinceStr = adInfo.getString("province");
String cityStr = adInfo.getString("city");
String districtStr = adInfo.getString("district");
if(!ZwzNullUtils.isNull(nationStr) && ZwzNullUtils.isNull(provinceStr)){
resultStr = nationStr;
} else {
resultStr = provinceStr;
if(!ZwzNullUtils.isNull(cityStr)){
resultStr += "-" + cityStr;
}
if(!ZwzNullUtils.isNull(districtStr)){
resultStr += "-" + districtStr;
}
}
}
} catch (Exception e) {
log.warn("区县查询失败");
}
return resultStr;
}
@ApiOperation(value = "查询请求的IP地址")
public String getRequestIpAddress(HttpServletRequest request) {
String ipAddress = request.getHeader(IP_HEADER_PRE_ONE);
if (ipAddress == null || ipAddress.length() < 1 || IP_HEADER_NONE.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader(IP_HEADER_PRE_TWO);
}
if (ipAddress == null || ipAddress.length() < 1 || IP_HEADER_NONE.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader(IP_HEADER_PRE_THREE);
}
if (ipAddress == null || ipAddress.length() < 1 || IP_HEADER_NONE.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (Objects.equals(IP_HEADER_LOCAL_HOST,ipAddress)) {
InetAddress inetAddress = null;
try {
inetAddress = InetAddress.getLocalHost();
} catch (UnknownHostException exception) {
exception.printStackTrace();
}
ipAddress = inetAddress.getHostAddress();
}
}
if (ipAddress != null && ipAddress.length() > 15) {
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
if(Objects.equals(IP_HEADER_LOCAL_LONG_HOST,ipAddress)){
ipAddress = IP_HEADER_LOCAL_HOST;
}
return ipAddress;
}
}

@ -0,0 +1,128 @@
package cn.zwz.basics.utils;
import cn.zwz.basics.exception.ZwzException;
import cn.zwz.basics.baseVo.PageVo;
import cn.zwz.data.utils.ZwzNullUtils;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ApiOperation(value = "分页工具类")
public class PageUtil {
private final static String[] NO_CAN_USE_WORDS = {"drop","select","master","insert","truncate","declare","delete","sleep","update","alter"};
private static final String SORT_BY_ASC = "asc";
private static final String SORT_BY_DESC = "desc";
private static final String CAMEL_STEP_STR = "_";
private static final String NULL_STR = "";
@ApiModelProperty(value = "JPA分页方法")
public static Pageable initPage(PageVo page){
Pageable able = null;
int pageNumber = page.getPageNumber();
int pageSize = page.getPageSize();
String sort = page.getSort();
String order = page.getOrder();
pageNumber = pageNumber < 1 ? 1 : pageNumber;
pageSize = pageSize < 1 ? 1 : pageSize;
pageSize = pageSize > 100 ? 100 : pageSize;
if(!ZwzNullUtils.isNull(sort)) {
Sort.Direction direction = ZwzNullUtils.isNull(order) ? Sort.Direction.DESC : Sort.Direction.valueOf(order.toUpperCase());
Sort sortBy = Sort.by(direction, sort);
able = PageRequest.of(pageNumber - 1, pageSize, sortBy);
} else {
able = PageRequest.of(pageNumber - 1, pageSize);
}
return able;
}
@ApiModelProperty(value = "MybatisPlus分页方法")
public static Page initMpPage(PageVo page){
Page newPage = null;
int pageNumber = page.getPageNumber();
int pageSize = page.getPageSize();
String sort = page.getSort();
String order = page.getOrder();
SQLInject(sort);
pageNumber = pageNumber < 1 ? 1 : pageNumber;
pageSize = pageSize < 1 ? 1 : pageSize;
pageSize = pageSize > 100 ? 100 : pageSize;
if(!ZwzNullUtils.isNull(sort)) {
Boolean isAsc = false;
if(ZwzNullUtils.isNull(order)) {
isAsc = false;
} else {
if(Objects.equals(order.toLowerCase(),SORT_BY_DESC)){
isAsc = false;
} else if(Objects.equals(order.toLowerCase(),SORT_BY_ASC)){
isAsc = true;
}
}
newPage = new Page(pageNumber, pageSize);
newPage.addOrder(isAsc ? OrderItem.asc(camel2Underline(sort)) : OrderItem.desc(camel2Underline(sort)));
} else {
newPage = new Page(pageNumber, pageSize);
}
return newPage;
}
@ApiModelProperty(value = "自定义分页方法")
public static List listToPage(PageVo page, List list) {
int pageNumber = page.getPageNumber() - 1;
int pageSize = page.getPageSize();
pageNumber = pageNumber < 1 ? 1 : pageNumber;
pageSize = pageSize < 1 ? 1 : pageSize;
pageSize = pageSize > 100 ? 100 : pageSize;
int startIndex = pageNumber * pageSize;
int endIndex = pageNumber * pageSize + pageSize;
if(startIndex > list.size()){
return new ArrayList();
} else if(endIndex > list.size() - 1) {
return list.subList(startIndex, list.size());
} else {
return list.subList(startIndex, endIndex);
}
}
@ApiModelProperty(value = "防 Mybatis Plus 的 SQL 注入攻击")
public static void SQLInject(String sqlStr){
if (ZwzNullUtils.isNull(sqlStr)) {
return;
}
sqlStr = sqlStr.toLowerCase();
for(int i = 0; i < NO_CAN_USE_WORDS.length; i ++) {
if (sqlStr.contains(NO_CAN_USE_WORDS[i])) {
throw new ZwzException(sqlStr + " 单词不合法");
}
}
}
@ApiModelProperty(value = "驼峰转下划线")
public static String camel2Underline(String underlineContent) {
if (ZwzNullUtils.isNull(underlineContent)) {
return NULL_STR;
}
if(underlineContent.length() < 2){
return underlineContent.toLowerCase();
}
StringBuffer camelUnderlineTempBuf = new StringBuffer();
for(int i = 1; i < underlineContent.length(); i ++){
camelUnderlineTempBuf.append(Character.isUpperCase(underlineContent.charAt(i)) ? CAMEL_STEP_STR + Character.toLowerCase(underlineContent.charAt(i)) : underlineContent.charAt(i));
}
String ans = underlineContent.charAt(0) + camelUnderlineTempBuf.toString();
return ans.toLowerCase();
}
}

@ -0,0 +1,66 @@
package cn.zwz.basics.utils;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ApiOperation(value = "API接口回调工具类")
@Slf4j
public class ResponseUtil {
private static final String CHARACTER_ENCODING = "UTF-8";
private static final String CONTENT_TYPE = "application/json;charset=UTF-8";
@ApiModelProperty(value = "输出JSON")
public static void out(HttpServletResponse httpServletResponse, Map<String, Object> responseMap){
ServletOutputStream outputStream = null;
try {
httpServletResponse.setCharacterEncoding(CHARACTER_ENCODING);
httpServletResponse.setContentType(CONTENT_TYPE);
outputStream = httpServletResponse.getOutputStream();
outputStream.write(JSONObject.toJSONString(responseMap).getBytes());
} catch (Exception exception) {
log.warn(exception + "Response转换JSON错误");
} finally{
if(outputStream != null){
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static Map<String, Object> resultMap(boolean flag, Integer responseCode, String message, Object data){
Map<String, Object> responseMap = new HashMap<String, Object>(16);
responseMap.put("result", data == null ? null : data);
responseMap.put("timestamp", System.currentTimeMillis() / 1000L);
responseMap.put("success", flag);
responseMap.put("code", responseCode);
responseMap.put("message", message);
return responseMap;
}
public static Map<String, Object> resultSuccessMap(String msg){
return resultMap(true, 200, msg, null);
}
public static Map<String, Object> resultMap(boolean successFlag, Integer code, String msg){
return resultMap(successFlag, code, msg, null);
}
public static Map<String, Object> resultSuccessMap(){
return resultMap(true, 200, "操作成功", null);
}
}

@ -0,0 +1,103 @@
package cn.zwz.basics.utils;
import cn.zwz.basics.baseVo.Result;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
@ApiOperation(value = "API接口回调工具类")
public class ResultUtil<T> {
private Result<T> result;
private static final String DEFAULR_SUCCESS_STR = "OK";
private static final String DEFAULR_FAIL_STR = "操作失败";
public ResultUtil(){
result = new Result<>();
result.setSuccess(true);
result.setMessage(DEFAULR_SUCCESS_STR);
result.setCode(200);
}
@ApiModelProperty(value = "成功返回数据")
public Result<T> setData(T t){
this.result.setResult(t);
this.result.setCode(200);
return this.result;
}
@ApiModelProperty(value = "成功返回数据和备注")
public Result<T> setDataAndMessage(T t, String msg){
this.result.setResult(t);
this.result.setCode(200);
this.result.setMessage(msg);
return this.result;
}
@ApiModelProperty(value = "成功返回备注")
public Result<T> setSuccessMsg(String msg){
this.result.setSuccess(true);
this.result.setMessage(msg);
this.result.setCode(200);
this.result.setResult(null);
return this.result;
}
@ApiModelProperty(value = "成功返回数据和备注")
public Result<T> setData(T t, String msg){
this.result.setResult(t);
this.result.setCode(200);
this.result.setMessage(msg);
return this.result;
}
@ApiModelProperty(value = "错误返回备注")
public Result<T> setErrorMsg(String msg){
this.result.setSuccess(false);
this.result.setMessage(msg);
this.result.setCode(500);
return this.result;
}
@ApiModelProperty(value = "错误返回状态码备注")
public Result<T> setErrorMsg(Integer code, String msg){
this.result.setSuccess(false);
this.result.setMessage(msg);
this.result.setCode(code);
return this.result;
}
public static <T> Result<T> data(T t){
return new ResultUtil<T>().setData(t);
}
public static <T> Result<T> data(){
return new ResultUtil<T>().setData(null);
}
public static <T> Result<T> data(T t, String msg){
return new ResultUtil<T>().setData(t, msg);
}
public static <T> Result<T> error(String msg){
return new ResultUtil<T>().setErrorMsg(msg);
}
public static <T> Result<T> error(){
return new ResultUtil<T>().setErrorMsg(DEFAULR_FAIL_STR);
}
public static <T> Result<T> error(Integer code, String msg){
return new ResultUtil<T>().setErrorMsg(code, msg);
}
public static <T> Result<T> success(String msg){
return new ResultUtil<T>().setSuccessMsg(msg);
}
public static <T> Result<T> success(){
return new ResultUtil<T>().setSuccessMsg(DEFAULR_SUCCESS_STR);
}
}

@ -0,0 +1,154 @@
package cn.zwz.basics.utils;
import cn.zwz.basics.exception.ZwzException;
import cn.zwz.basics.baseVo.TokenUser;
import cn.zwz.basics.parameter.ZwzLoginProperties;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.data.entity.*;
import cn.zwz.data.service.IPermissionService;
import cn.zwz.data.service.IRoleService;
import cn.zwz.data.service.IUserService;
import cn.zwz.data.utils.ZwzNullUtils;
import cn.zwz.data.vo.PermissionDTO;
import cn.zwz.data.vo.RoleDTO;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
@ApiOperation(value = "鉴权工具类")
@Component
public class SecurityUtil {
@Autowired
private ZwzLoginProperties tokenProperties;
@Autowired
private RedisTemplateHelper redisTemplate;
@Autowired
private IUserService iUserService;
@Autowired
private IRoleService iRoleService;
@Autowired
private IPermissionService iPermissionService;
private static final String TOKEN_REPLACE_FRONT_STR = "-";
private static final String TOKEN_REPLACE_BACK_STR = "";
private User selectByUserName(String title) {
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.eq("username",title);
User user = iUserService.getOne(userQw);
if(user == null) {
return null;
}
/**
*
*/
QueryWrapper<Role> roleQw = new QueryWrapper<>();
roleQw.inSql("id","SELECT role_id FROM a_user_role WHERE del_flag = 0 AND user_id = '" + user.getId() + "'");
List<Role> roleList = iRoleService.list(roleQw);
List<RoleDTO> roles = new ArrayList<>();
for (Role role : roleList) {
roles.add(new RoleDTO(role.getName(),role.getId(),role.getDescription()));
}
user.setRoles(roles);
/**
*
*/
QueryWrapper<Permission> permissionQw = new QueryWrapper<>();
permissionQw.inSql("id","SELECT role_id FROM a_role_permission WHERE del_flag = 0 AND permission_id = '" + user.getId() + "'");
List<Permission> permissionList = iPermissionService.list(permissionQw);
List<PermissionDTO> permissions = new ArrayList<>();
for (Permission permission : permissionList) {
if(!Objects.equals(1,permission.getType())) {
permissions.add(new PermissionDTO(permission.getPath(),permission.getTitle()));
}
}
user.setPermissions(permissions);
return user;
}
@ApiOperation(value = "获取新的用户Token")
public String getToken(String username, Boolean saveLogin){
if(ZwzNullUtils.isNull(username)){
throw new ZwzException("username不能为空");
}
boolean saved = false;
if(saveLogin == null || saveLogin){
saved = true;
}
User selectUser = selectByUserName(username);
// 菜单和角色的数组
List<String> permissionTitleList = new ArrayList<>();
if(tokenProperties.getSaveRoleFlag()){
for(PermissionDTO p : selectUser.getPermissions()){
if(!ZwzNullUtils.isNull(p.getTitle()) && !ZwzNullUtils.isNull(p.getPath())) {
permissionTitleList.add(p.getTitle());
}
}
for(RoleDTO r : selectUser.getRoles()){
permissionTitleList.add(r.getName());
}
}
String ansUserToken = UUID.randomUUID().toString().replace(TOKEN_REPLACE_FRONT_STR, TOKEN_REPLACE_BACK_STR);
TokenUser tokenUser = new TokenUser(selectUser.getUsername(), permissionTitleList, saved);
// 单点登录删除旧Token
if(tokenProperties.getSsoFlag()) {
String oldToken = redisTemplate.get(ZwzLoginProperties.USER_TOKEN_PRE + selectUser.getUsername());
if (StrUtil.isNotBlank(oldToken)) {
redisTemplate.delete(ZwzLoginProperties.HTTP_TOKEN_PRE + oldToken);
}
}
// 保存至Redis备查
if(saved){
redisTemplate.set(ZwzLoginProperties.USER_TOKEN_PRE + selectUser.getUsername(), ansUserToken, tokenProperties.getUserSaveLoginTokenDays(), TimeUnit.DAYS);
redisTemplate.set(ZwzLoginProperties.HTTP_TOKEN_PRE + ansUserToken, JSON.toJSONString(tokenUser), tokenProperties.getUserSaveLoginTokenDays(), TimeUnit.DAYS);
}else{
redisTemplate.set(ZwzLoginProperties.USER_TOKEN_PRE + selectUser.getUsername(), ansUserToken, tokenProperties.getUserTokenInvalidDays(), TimeUnit.MINUTES);
redisTemplate.set(ZwzLoginProperties.HTTP_TOKEN_PRE + ansUserToken, JSON.toJSONString(tokenUser), tokenProperties.getUserTokenInvalidDays(), TimeUnit.MINUTES);
}
return ansUserToken;
}
@ApiOperation(value = "查询指定用户的权限列表")
public List<GrantedAuthority> getCurrUserPerms(String userName){
List<GrantedAuthority> ans = new ArrayList<>();
User selectUser = selectByUserName(userName);
if(selectUser == null){
return ans;
}
List<PermissionDTO> perList = selectUser.getPermissions();
if(perList.size() < 1) {
return ans;
}
for(PermissionDTO vo : perList){
ans.add(new SimpleGrantedAuthority(vo.getTitle()));
}
return ans;
}
@ApiOperation(value = "查询当前Token的用户对象")
public User getCurrUser(){
Object selectUser = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(Objects.equals("anonymousUser",selectUser.toString())){
throw new ZwzException("登录失效");
}
UserDetails user = (UserDetails) selectUser;
return selectByUserName(user.getUsername());
}
}

@ -0,0 +1,34 @@
package cn.zwz.basics.utils;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import java.util.concurrent.*;
@ApiOperation(value = "线程池配置实体类")
public class ThreadPoolUtil {
@ApiModelProperty(value = "线程的缓冲队列")
private static BlockingQueue<Runnable> bqueue = new ArrayBlockingQueue<Runnable>(100);
@ApiModelProperty(value = "核心线程数")
private static final int SIZE_CORE_POOL = 5;
@ApiModelProperty(value = "最大线程数量")
private static final int SIZE_MAX_POOL = 10;
@ApiModelProperty(value = "空闲线程存活时间")
private static final long ALIVE_TIME = 2000;
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(SIZE_CORE_POOL, SIZE_MAX_POOL, ALIVE_TIME, TimeUnit.MILLISECONDS, bqueue, new ThreadPoolExecutor.CallerRunsPolicy());
static {
pool.prestartAllCoreThreads();
}
@ApiOperation(value = "获取可用线程")
public static ThreadPoolExecutor getPool() {
return pool;
}
}

@ -0,0 +1,140 @@
package cn.zwz.data.controller;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.utils.SecurityUtil;
import cn.zwz.data.entity.Permission;
import cn.zwz.data.entity.User;
import cn.zwz.data.service.IPermissionService;
import cn.zwz.data.service.IUserService;
import cn.zwz.data.utils.ZwzNullUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author
* CSDN: Designer
*/
@RestController
@Api(tags = "个人门户接口")
@RequestMapping("/zwz/myDoor")
@Transactional
public class MyDoorController {
@Autowired
private SecurityUtil securityUtil;
@Autowired
private IPermissionService iPermissionService;
@Autowired
private IUserService iUserService;
@SystemLog(about = "查询个人门户菜单A", type = LogType.DATA_CENTER,doType = "MY-DOOR-01")
@ApiOperation(value = "查询个人门户菜单A")
@RequestMapping(value = "/getMyDoorList", method = RequestMethod.POST)
public Result<List<MyDoorMenuClass>> getMyDoorList(){
User user = securityUtil.getCurrUser();
user = iUserService.getById(user.getId());
List<MyDoorMenuClass> ans = new ArrayList<>();
String myDoor = user.getMyDoor();
if(ZwzNullUtils.isNull(myDoor)) {
return new ResultUtil().setData(ans);
}
String[] zwz666s = myDoor.split("ZWZ666");
List<Permission> all = iPermissionService.list();
for (String zwz666 : zwz666s) {
for (Permission permission : all) {
if(Objects.equals(permission.getName(),zwz666)) {
MyDoorMenuClass menu = new MyDoorMenuClass();
menu.setName(permission.getName());
menu.setTitle(permission.getTitle());
ans.add(menu);
break;
}
}
}
return new ResultUtil().setData(ans);
}
@SystemLog(about = "查询个人门户菜单B", type = LogType.DATA_CENTER,doType = "MY-DOOR-02")
@ApiOperation(value = "获取个人门户菜单B")
@RequestMapping(value = "/getMyDoorList6", method = RequestMethod.POST)
public Result<List<MyDoorMenuClass>> getMyDoorList6(){
User user = securityUtil.getCurrUser();
user = iUserService.getById(user.getId());
List<MyDoorMenuClass> ans = new ArrayList<>();
String myDoor = user.getMyDoor();
if(ZwzNullUtils.isNull(myDoor)) {
ans.add(getNullMenu());ans.add(getNullMenu());ans.add(getNullMenu());
ans.add(getNullMenu());ans.add(getNullMenu());ans.add(getNullMenu());
return new ResultUtil().setData(ans);
}
String[] zwz666s = myDoor.split("ZWZ666");
List<Permission> all = iPermissionService.list();
for (String zwz666 : zwz666s) {
for (Permission permission : all) {
if(Objects.equals(permission.getName(),zwz666)) {
MyDoorMenuClass menu = new MyDoorMenuClass();
menu.setName(permission.getName());
menu.setTitle(permission.getTitle());
ans.add(menu);
break;
}
}
}
int size = ans.size();
if(size < 6) {
int time = 6 - size;
for(int i = 0 ; i < time; i ++) {
ans.add(getNullMenu());
}
}
return new ResultUtil().setData(ans);
}
@SystemLog(about = "修改个人门户菜单", type = LogType.DATA_CENTER,doType = "MY-DOOR-03")
@ApiOperation(value = "修改个人门户菜单")
@RequestMapping(value = "/setMyDoorList", method = RequestMethod.POST)
public Result<Object> setMyDoorList(@RequestParam String str){
User user = securityUtil.getCurrUser();
user = iUserService.getById(user.getId());
if(user != null) {
if(ZwzNullUtils.isNull(str)) {
user.setMyDoor("");
iUserService.saveOrUpdate(user);
} else {
user.setMyDoor(str);
iUserService.saveOrUpdate(user);
}
return ResultUtil.success("OK");
}
return ResultUtil.error("ROSTER IS NULL");
}
private MyDoorMenuClass getNullMenu() {
MyDoorMenuClass menu = new MyDoorMenuClass();
menu.setName("null");
menu.setTitle("尚未添加");
return menu;
}
@Data
private class MyDoorMenuClass {
private String name;
private String title;
}
}

@ -0,0 +1,49 @@
package cn.zwz.data.controller;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.utils.PageUtil;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.baseVo.PageVo;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.data.entity.User;
import cn.zwz.data.service.IUserService;
import cn.zwz.data.utils.ZwzNullUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
/**
* @author
* CSDN: Designer
*/
@Slf4j
@RestController
@Api(tags = "新用户接口")
@RequestMapping("/zwz/myUser")
@Transactional
public class MyUserController {
@Autowired
private IUserService iUserService;
@SystemLog(about = "查询用户", type = LogType.DATA_CENTER,doType = "USER-01")
@RequestMapping(value = "/getByPage", method = RequestMethod.GET)
@ApiOperation(value = "查询用户")
public Result<IPage<User>> getByPage(@ModelAttribute User user,@ModelAttribute PageVo page){
QueryWrapper<User> qw = new QueryWrapper<>();
if(user.getDepartmentId() != null && !ZwzNullUtils.isNull(user.getDepartmentId())) {
qw.like("department_id",user.getDepartmentId());
}
if(user.getNickname() != null && !ZwzNullUtils.isNull(user.getNickname())) {
qw.like("nickname",user.getNickname());
}
IPage<User> data = iUserService.page(PageUtil.initMpPage(page),qw);
return new ResultUtil<IPage<User>>().setData(data);
}
}

@ -0,0 +1,337 @@
package cn.zwz.data.controller;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.parameter.CommonConstant;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.utils.SecurityUtil;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.data.entity.*;
import cn.zwz.data.service.*;
import cn.zwz.data.utils.VoUtil;
import cn.zwz.data.utils.ZwzNullUtils;
import cn.zwz.data.vo.MenuVo;
import cn.zwz.data.vo.UserByPermissionVo;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @author
* CSDN: Designer
*/
@RestController
@Api(tags = "菜单管理接口")
@RequestMapping("/zwz/permission")
@CacheConfig(cacheNames = "permission")
@Transactional
public class PermissionController {
@Autowired
private SecurityUtil securityUtil;
@Autowired
private IRolePermissionService iRolePermissionService;
@Autowired
private IPermissionService iPermissionService;
@Autowired
private IUserRoleService iUserRoleService;
@Autowired
private RedisTemplateHelper redisTemplateHelper;
@Autowired
private IRoleService iRoleService;
@Autowired
private IUserService iUserService;
@SystemLog(about = "查询菜单权限拥有者", type = LogType.DATA_CENTER,doType = "PERMISSION-01")
@ApiOperation(value = "查询菜单权限拥有者")
@RequestMapping(value = "/getUserByPermission", method = RequestMethod.GET)
public Result<List<UserByPermissionVo>> getUserByPermission(@RequestParam String permissionId){
Permission permission = iPermissionService.getById(permissionId);
if(permission == null) {
return ResultUtil.error("该菜单已被删除");
}
List<UserByPermissionVo> ansList = new ArrayList<>();
// 查询用户
QueryWrapper<RolePermission> qw = new QueryWrapper<>();
qw.eq("permission_id",permissionId);
List<RolePermission> rolePermissionList = iRolePermissionService.list(qw);
for (RolePermission rp : rolePermissionList) {
Role role = iRoleService.getById(rp.getRoleId());
if(role != null) {
QueryWrapper<UserRole> urQw = new QueryWrapper<>();
urQw.eq("role_id",role.getId());
List<UserRole> userRoleList = iUserRoleService.list(urQw);
for (UserRole ur : userRoleList) {
User user = iUserService.getById(ur.getUserId());
if(user != null) {
boolean flag = false;
for (UserByPermissionVo vo : ansList) {
if(Objects.equals(vo.getUserId(),user.getId())) {
flag = true;
vo.setRoleStr(vo.getRoleStr() + role.getName() + "(" + role.getDescription() + ") ");
break;
}
}
if(!flag) {
UserByPermissionVo vo = new UserByPermissionVo();
vo.setUserId(user.getId());
vo.setUserName(user.getNickname());
vo.setRoleStr(role.getName());
vo.setCode(user.getUsername());
vo.setMobile(user.getMobile());
ansList.add(vo);
}
}
}
}
}
return new ResultUtil<List<UserByPermissionVo>>().setData(ansList);
}
@ApiOperation(value = "根据层级查询菜单")
private List<Permission> getPermissionListByLevel(int level) {
QueryWrapper<Permission> qw = new QueryWrapper<>();
qw.eq("level",level);
qw.orderByAsc("sort_order");
return iPermissionService.list(qw);
}
@SystemLog(about = "查询菜单", type = LogType.DATA_CENTER,doType = "PERMISSION-02")
@RequestMapping(value = "/getMenuList", method = RequestMethod.GET)
@ApiOperation(value = "查询菜单")
public Result<List<MenuVo>> getMenuList(){
List<MenuVo> menuList = new ArrayList<>();
User currUser = securityUtil.getCurrUser();
String keyInRedis = "permission::userMenuList:" + currUser.getId();
String valueInRedis = redisTemplateHelper.get(keyInRedis);
if(!ZwzNullUtils.isNull(valueInRedis)){
return new ResultUtil<List<MenuVo>>().setData(JSON.parseArray(valueInRedis,MenuVo.class));
}
// 拥有的菜单列表
List<Permission> list = getPermissionByUserId(currUser.getId());
// 顶级菜单
for(Permission permission : list){
if(CommonConstant.PERMISSION_NAV.equals(permission.getType())&&CommonConstant.LEVEL_ZERO.equals(permission.getLevel())) {
menuList.add(VoUtil.permissionToMenuVo(permission));
}
}
// 一级菜单
List<MenuVo> firstMenuList = new ArrayList<>();
for(Permission permission : list){
if(Objects.equals(CommonConstant.PERMISSION_PAGE,permission.getType()) && Objects.equals(CommonConstant.LEVEL_ONE,permission.getLevel())) {
firstMenuList.add(VoUtil.permissionToMenuVo(permission));
}
}
// 二级菜单
List<MenuVo> secondMenuList = new ArrayList<>();
for(Permission permission : list){
if(Objects.equals(CommonConstant.PERMISSION_PAGE,permission.getType()) && Objects.equals(CommonConstant.LEVEL_TWO,permission.getLevel())) {
secondMenuList.add(VoUtil.permissionToMenuVo(permission));
}
}
// 按钮
List<MenuVo> buttonPermissions = new ArrayList<>();
for(Permission permission : list){
if(Objects.equals(CommonConstant.PERMISSION_OPERATION,permission.getType()) && Objects.equals(CommonConstant.LEVEL_THREE,permission.getLevel())) {
buttonPermissions.add(VoUtil.permissionToMenuVo(permission));
}
}
// 有权限的二级菜单
for(MenuVo vo : secondMenuList){
List<String> permTypes = new ArrayList<>();
for(MenuVo menuVo : buttonPermissions){
if(Objects.equals(vo.getId(),menuVo.getParentId())){
permTypes.add(menuVo.getButtonType());
}
}
vo.setPermTypes(permTypes);
}
// 二连一
for(MenuVo vo : firstMenuList) {
List<MenuVo> secondMenu = new ArrayList<>();
for(MenuVo menuVo : secondMenuList){
if(Objects.equals(vo.getId(),menuVo.getParentId())) {
secondMenu.add(menuVo);
}
}
vo.setChildren(secondMenu);
}
// 一连顶
for(MenuVo vo : menuList) {
List<MenuVo> firstMenu = new ArrayList<>();
for(MenuVo menuVo : firstMenuList){
if(Objects.equals(vo.getId(),menuVo.getParentId())) {
firstMenu.add(menuVo);
}
}
vo.setChildren(firstMenu);
}
redisTemplateHelper.set(keyInRedis, JSONObject.toJSONString(menuList), 10L, TimeUnit.DAYS);
return new ResultUtil<List<MenuVo>>().setData(menuList);
}
@SystemLog(about = "搜索菜单", type = LogType.DATA_CENTER,doType = "PERMISSION-03")
@RequestMapping(value = "/search", method = RequestMethod.GET)
@ApiOperation(value = "搜索菜单")
public Result<List<Permission>> searchPermissionList(@RequestParam String title){
QueryWrapper<Permission> qw = new QueryWrapper<>();
qw.like("title",title);
qw.orderByAsc("sort_order");
return new ResultUtil<List<Permission>>().setData(iPermissionService.list(qw));
}
@ApiOperation(value = "根据父ID查询菜单")
private List<Permission> getPermissionListByParentId(String parentId) {
QueryWrapper<Permission> qw = new QueryWrapper<>();
qw.eq("parent_id",parentId);
qw.orderByAsc("sort_order");
return iPermissionService.list(qw);
}
@SystemLog(about = "查询全部菜单", type = LogType.DATA_CENTER,doType = "PERMISSION-04")
@RequestMapping(value = "/getAllList", method = RequestMethod.GET)
@ApiOperation(value = "查询全部菜单")
@Cacheable(key = "'allList'")
public Result<List<Permission>> getAllList(){
// 顶级菜单列表
List<Permission> list0 = getPermissionListByLevel(0);
for(Permission p0 : list0){
// 一级
List<Permission> list1 = getPermissionListByParentId(p0.getId());
p0.setChildren(list1);
// 二级
for(Permission p1 : list1){
List<Permission> children1 = getPermissionListByParentId(p1.getId());
p1.setChildren(children1);
// 三级
for(Permission p2 : children1){
List<Permission> children2 = getPermissionListByParentId(p2.getId());
p2.setChildren(children2);
}
}
}
return new ResultUtil<List<Permission>>().setData(list0);
}
@SystemLog(about = "删除菜单", type = LogType.DATA_CENTER,doType = "PERMISSION-05")
@RequestMapping(value = "/delByIds", method = RequestMethod.POST)
@ApiOperation(value = "删除菜单")
@CacheEvict(key = "'menuList'")
public Result<Object> delByIds(@RequestParam String[] ids){
for(String id : ids){
QueryWrapper<RolePermission> qw = new QueryWrapper<>();
qw.like("permission_id",id);
long rolePermissionCount = iRolePermissionService.count(qw);
if(rolePermissionCount > 0L) {
Permission permission = iPermissionService.getById(id);
if(permission == null) {
return ResultUtil.error("菜单不存在");
}
return ResultUtil.error(permission.getTitle() + "菜单正在被角色使用,不能删除");
}
}
for(String id:ids){
iPermissionService.removeById(id);
}
redisTemplateHelper.delete("permission::allList");
return ResultUtil.success();
}
@SystemLog(about = "添加菜单", type = LogType.DATA_CENTER,doType = "PERMISSION-06")
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ApiOperation(value = "添加菜单")
@CacheEvict(key = "'menuList'")
public Result<Permission> add(Permission permission){
if(Objects.equals(CommonConstant.PERMISSION_OPERATION,permission.getType())) {
QueryWrapper<Permission> perQw = new QueryWrapper<>();
perQw.eq("title",permission.getTitle());
long permissionByTitleCount = iPermissionService.count(perQw);
if(permissionByTitleCount > 0L){
return new ResultUtil<Permission>().setErrorMsg("名称已存在");
}
}
if(Objects.equals(CommonConstant.PERMISSION_NAV,permission.getType())) {
// 顶级菜单添加标识
permission.setParentId("0");
if(ZwzNullUtils.isNull(permission.getPath())) {
permission.setPath(permission.getName());
}
permission.setDescription("");
permission.setComponent("");
}
iPermissionService.saveOrUpdate(permission);
redisTemplateHelper.delete("permission::allList");
return new ResultUtil<Permission>().setData(permission);
}
@SystemLog(about = "编辑菜单", type = LogType.DATA_CENTER,doType = "PERMISSION-07")
@RequestMapping(value = "/edit", method = RequestMethod.POST)
@ApiOperation(value = "编辑菜单")
public Result<Permission> edit(Permission permission){
if(Objects.equals(CommonConstant.PERMISSION_OPERATION,permission.getType())) {
Permission p = iPermissionService.getById(permission.getId());
if(!Objects.equals(p.getTitle(),permission.getTitle())) {
QueryWrapper<Permission> perQw = new QueryWrapper<>();
perQw.eq("title",permission.getTitle());
long permissionCount = iPermissionService.count(perQw);
if(permissionCount > 0L){
return new ResultUtil<Permission>().setErrorMsg("名称已存在");
}
}
}
iPermissionService.saveOrUpdate(permission);
Set<String> keysUser = redisTemplateHelper.keys("user:" + "*");
redisTemplateHelper.delete(keysUser);
Set<String> keysUserMenu = redisTemplateHelper.keys("permission::userMenuList:*");
redisTemplateHelper.delete(keysUserMenu);
redisTemplateHelper.delete("permission::allList");
return new ResultUtil<Permission>().setData(permission);
}
private List<Permission> getPermissionByUserId(String userId) {
QueryWrapper<UserRole> urQw = new QueryWrapper<>();
urQw.eq("user_id",userId);
List<UserRole> userRoleList = iUserRoleService.list(urQw);
List<Permission> permissionList = new ArrayList<>();
for (UserRole userRole : userRoleList) {
QueryWrapper<RolePermission> rpQw = new QueryWrapper<>();
rpQw.eq("role_id",userRole.getRoleId());
List<RolePermission> rolePermissionList = iRolePermissionService.list(rpQw);
for (RolePermission rolePermission : rolePermissionList) {
boolean flag = true;
for (Permission permission : permissionList) {
if(Objects.equals(permission.getId(),rolePermission.getPermissionId())) {
flag = false;
break;
}
}
if(flag) {
permissionList.add(iPermissionService.getById(rolePermission.getPermissionId()));
}
}
}
return permissionList;
}
}

@ -0,0 +1,146 @@
package cn.zwz.data.controller;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.utils.PageUtil;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.baseVo.PageVo;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.data.utils.ZwzNullUtils;
import cn.zwz.data.vo.RedisVo;
import cn.hutool.core.date.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @author
* CSDN: Designer
*/
@RestController
@Api(tags = "缓存管理接口")
@RequestMapping("/zwz/redis")
@Transactional
public class RedisController {
@ApiModelProperty(value = "最大键值数")
private static final int maxSize = 100000;
private static final String DATE_FORMAT_IN_REDIS = "HH:mm:ss";
private static final String STEP_STR_IN_REDIS = "*";
private static final Integer INIT_SIZE_IN_REDIS = 16;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RedisTemplateHelper redisTemplateHelper;
@RequestMapping(value = "/save", method = RequestMethod.POST)
@ApiOperation(value = "新增")
public Result<Object> save(@RequestParam String key,@RequestParam String value,@RequestParam Long expireTime){
if(expireTime == 0L) {
return ResultUtil.success();
}
if(expireTime < 0){
redisTemplate.opsForValue().set(key ,value);
}
redisTemplate.opsForValue().set(key ,value, expireTime, TimeUnit.SECONDS);
return ResultUtil.success();
}
@RequestMapping(value = "/delByKeys", method = RequestMethod.POST)
@ApiOperation(value = "删除")
public Result<Object> delByKeys(@RequestParam String[] keys){
for(String redisKey : keys){
redisTemplate.delete(redisKey);
}
return ResultUtil.success();
}
@RequestMapping(value = "/delAll", method = RequestMethod.POST)
@ApiOperation(value = "全部删除")
public Result<Object> delAll(){
redisTemplate.delete(redisTemplateHelper.keys(STEP_STR_IN_REDIS));
return ResultUtil.success();
}
@RequestMapping(value = "/getKeySize", method = RequestMethod.GET)
@ApiOperation(value = "获取实时key大小")
public Result<Object> getKeySize(){
Map<String, Object> map = new HashMap<>(INIT_SIZE_IN_REDIS);
map.put("keySize", redisTemplate.getConnectionFactory().getConnection().dbSize());
map.put("time", DateUtil.format(new Date(), DATE_FORMAT_IN_REDIS));
return ResultUtil.data(map);
}
@RequestMapping(value = "/getMemory", method = RequestMethod.GET)
@ApiOperation(value = "获取实时内存大小")
public Result<Object> getMemory(){
Map<String, Object> hashMap = new HashMap<>(INIT_SIZE_IN_REDIS);
Properties properties = redisTemplate.getConnectionFactory().getConnection().info("memory");
hashMap.put("memory", properties.get("used_memory"));
hashMap.put("time", DateUtil.format(new Date(), DATE_FORMAT_IN_REDIS));
return ResultUtil.data(hashMap);
}
@RequestMapping(value = "/getAllByPage", method = RequestMethod.GET)
@ApiOperation(value = "查询Redis数据")
public Result<Page<RedisVo>> getAllByPage(@RequestParam(required = false) String key,PageVo pageVo){
List<RedisVo> list = new ArrayList<>();
if(!ZwzNullUtils.isNull(key)){
key = STEP_STR_IN_REDIS + key + STEP_STR_IN_REDIS;
} else{
key = STEP_STR_IN_REDIS;
}
Set<String> keyListInSet = redisTemplateHelper.keys(key);
int keyListInSetSize = keyListInSet.size();
if(keyListInSetSize > maxSize){
keyListInSetSize = maxSize;
}
int i = 0;
for (String keyInSet : keyListInSet) {
if(i > keyListInSetSize) {
break;
}
RedisVo redisVo = new RedisVo(keyInSet, "", redisTemplate.getExpire(keyInSet, TimeUnit.SECONDS));
list.add(redisVo);
i++;
}
Page<RedisVo> page = new PageImpl<RedisVo>(PageUtil.listToPage(pageVo, list), PageUtil.initPage(pageVo), keyListInSetSize);
for (RedisVo vo : page.getContent()) {
String ansValue = null;
try {
ansValue = redisTemplate.opsForValue().get(vo.getKey());
if(ansValue.length() > 100){
ansValue = ansValue.substring(0, 100) + "..";
}
vo.setValue(ansValue);
} catch (Exception ex){
vo.setValue("二进制内容");
}
}
return new ResultUtil<Page<RedisVo>>().setData(page);
}
@RequestMapping(value = "/getByKey/{key}", method = RequestMethod.GET)
@ApiOperation(value = "通过key获取")
public Result<Object> getByKey(@PathVariable String key){
Map<String, Object> map = new HashMap<>();
String redisValue = redisTemplate.opsForValue().get(key);
Long expireTimeUnit = redisTemplate.getExpire(key, TimeUnit.SECONDS);
map.put("value", redisValue);
map.put("expireTime", expireTimeUnit);
return ResultUtil.data(map);
}
}

@ -0,0 +1,187 @@
package cn.zwz.data.controller;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.utils.PageUtil;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.baseVo.PageVo;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.data.entity.*;
import cn.zwz.data.service.IRolePermissionService;
import cn.zwz.data.service.IRoleService;
import cn.zwz.data.service.IUserRoleService;
import cn.zwz.data.utils.ZwzNullUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* @author
* CSDN: Designer
*/
@RestController
@Api(tags = "角色管理接口")
@RequestMapping("/zwz/role")
@Transactional
public class RoleController {
@Autowired
private IRoleService iRoleService;
@Autowired
private IUserRoleService iUserRoleService;
@Autowired
private IRolePermissionService iRolePermissionService;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RedisTemplateHelper redisTemplateHelper;
@SystemLog(about = "查询全部角色", type = LogType.DATA_CENTER,doType = "ROLE-01")
@RequestMapping(value = "/getAllList", method = RequestMethod.GET)
@ApiOperation(value = "查询全部角色")
public Result<Object> getAllList(){
return ResultUtil.data(iRoleService.list());
}
@SystemLog(about = "查询角色", type = LogType.DATA_CENTER,doType = "ROLE-02")
@RequestMapping(value = "/getAllByPage", method = RequestMethod.GET)
@ApiOperation(value = "查询角色")
public Result<IPage<Role>> getRoleByPage(@ModelAttribute Role role,@ModelAttribute PageVo page) {
QueryWrapper<Role> qw = new QueryWrapper<>();
if(!ZwzNullUtils.isNull(role.getName())) {
qw.like("name",role.getName());
}
if(!ZwzNullUtils.isNull(role.getDescription())) {
qw.like("description",role.getDescription());
}
IPage<Role> roleList = iRoleService.page(PageUtil.initMpPage(page),qw);
for(Role r : roleList.getRecords()){
QueryWrapper<RolePermission> rpQw = new QueryWrapper<>();
rpQw.eq("role_id",r.getId());
r.setPermissions(iRolePermissionService.list(rpQw));
}
return new ResultUtil<IPage<Role>>().setData(roleList);
}
@SystemLog(about = "配置默认角色", type = LogType.DATA_CENTER,doType = "ROLE-03")
@RequestMapping(value = "/setDefault", method = RequestMethod.POST)
@ApiOperation(value = "配置默认角色")
public Result<Object> setDefault(@RequestParam String id,@RequestParam Boolean isDefault){
Role role = iRoleService.getById(id);
if(role != null) {
if(!Objects.equals(role.getDefaultRole(),isDefault)) {
role.setDefaultRole(isDefault);
iRoleService.saveOrUpdate(role);
}
return ResultUtil.success();
}
return ResultUtil.error("不存在");
}
@SystemLog(about = "修改菜单权限", type = LogType.DATA_CENTER,doType = "ROLE-04")
@RequestMapping(value = "/editRolePerm", method = RequestMethod.POST)
@ApiOperation(value = "修改菜单权限")
public Result<Object> editRolePerm(@RequestParam String roleId,@RequestParam(required = false) String[] permIds){
Role role = iRoleService.getById(roleId);
if(role == null) {
return ResultUtil.error("角色已被删除");
}
if(permIds == null) {
permIds = new String[0];
}
QueryWrapper<RolePermission> oldQw = new QueryWrapper<>();
oldQw.eq("role_id",role.getId());
List<RolePermission> oldPermissionList = iRolePermissionService.list(oldQw);
// 判断新增 = oldPermissionList没有 permIds有
for (String permId : permIds) {
boolean flag = true;
for (RolePermission rp : oldPermissionList) {
if(Objects.equals(permId,rp.getPermissionId())) {
flag = false;
break;
}
}
if(flag) {
RolePermission rp = new RolePermission();
rp.setRoleId(role.getId());
rp.setPermissionId(permId);
iRolePermissionService.saveOrUpdate(rp);
}
}
// 判断删除 = oldPermissionList有 permIds没有
for (RolePermission rp : oldPermissionList) {
boolean flag = true;
for (String permId : permIds) {
if(Objects.equals(permId,rp.getPermissionId())) {
flag = false;
break;
}
}
if(flag) {
iRolePermissionService.removeById(rp.getId());
}
}
Set<String> keysUser = redisTemplateHelper.keys("user:" + "*");
redisTemplate.delete(keysUser);
Set<String> keysUserRole = redisTemplateHelper.keys("userRole:" + "*");
redisTemplate.delete(keysUserRole);
Set<String> keysUserMenu = redisTemplateHelper.keys("permission::userMenuList:*");
redisTemplate.delete(keysUserMenu);
return ResultUtil.data();
}
@SystemLog(about = "新增角色", type = LogType.DATA_CENTER,doType = "ROLE-05")
@RequestMapping(value = "/save", method = RequestMethod.POST)
@ApiOperation(value = "新增角色")
public Result<Role> save(Role role){
iRoleService.saveOrUpdate(role);
return new ResultUtil<Role>().setData(role);
}
@SystemLog(about = "编辑角色", type = LogType.DATA_CENTER,doType = "ROLE-06")
@RequestMapping(value = "/edit", method = RequestMethod.POST)
@ApiOperation(value = "编辑角色")
public Result<Role> edit(Role role){
iRoleService.saveOrUpdate(role);
Set<String> keysUser = redisTemplateHelper.keys("user:" + "*");
redisTemplate.delete(keysUser);
Set<String> keysUserRole = redisTemplateHelper.keys("userRole:" + "*");
redisTemplate.delete(keysUserRole);
return new ResultUtil<Role>().setData(role);
}
@SystemLog(about = "删除角色", type = LogType.DATA_CENTER,doType = "ROLE-07")
@RequestMapping(value = "/delByIds", method = RequestMethod.POST)
@ApiOperation(value = "删除角色")
public Result<Object> delByIds(@RequestParam String[] ids){
for(String id : ids) {
QueryWrapper<UserRole> urQw = new QueryWrapper<>();
urQw.eq("role_id", id);
long urCount = iUserRoleService.count(urQw);
if(urCount > 0L){
return ResultUtil.error("不能删除正在使用的角色");
}
}
for(String id:ids){
iRoleService.removeById(id);
QueryWrapper<RolePermission> rpQw = new QueryWrapper<>();
rpQw.eq("role_id",id);
iRolePermissionService.remove(rpQw);
}
return ResultUtil.success();
}
}

@ -0,0 +1,67 @@
package cn.zwz.data.controller;
import cn.zwz.basics.utils.CreateVerifyCode;
import cn.zwz.basics.utils.IpInfoUtil;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.basics.baseVo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @author
* CSDN: Designer
*/
@RestController
@RequestMapping("/zwz/common")
@Api(tags = "公共接口")
@Transactional
public class SecurityController {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private IpInfoUtil ipInfoUtil;
@RequestMapping(value = "/ip/info", method = RequestMethod.GET)
@ApiOperation(value = "IP信息")
public Result<Object> upload(HttpServletRequest request) {
return ResultUtil.data(ipInfoUtil.getIpCity(request));
}
@RequestMapping(value = "/draw/{captchaId}", method = RequestMethod.GET)
@ApiOperation(value = "根据验证码ID获取图片")
public void draw(@PathVariable("captchaId") String captchaId, HttpServletResponse response) throws IOException {
String codeStr = redisTemplate.opsForValue().get(captchaId);
CreateVerifyCode createVerifyCode = new CreateVerifyCode(116,36,4,10, codeStr);
response.setContentType("image/png");
createVerifyCode.write(response.getOutputStream());
}
@RequestMapping(value = "/init", method = RequestMethod.GET)
@ApiOperation(value = "初始化验证码")
public Result<Object> init() {
String codeId = UUID.randomUUID().toString().replace("-","");
redisTemplate.opsForValue().set(codeId, new CreateVerifyCode().randomStr(4),2L, TimeUnit.MINUTES);
return ResultUtil.data(codeId);
}
@RequestMapping(value = "/needLogin", method = RequestMethod.GET)
@ApiOperation(value = "未登录返回的数据")
public Result<Object> needLogin(){
return ResultUtil.error(401, "登录失效");
}
}

@ -0,0 +1,49 @@
package cn.zwz.data.controller;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.utils.ResultUtil;
import cn.zwz.data.entity.Setting;
import cn.zwz.data.service.ISettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
/**
* @author
* CSDN: Designer
*/
@RestController
@Api(tags = "全局设置接口")
@RequestMapping("/zwz/setting")
public class SettingController {
@Autowired
private ISettingService iSettingService;
@SystemLog(about = "查看单个配置", type = LogType.DATA_CENTER,doType = "SETTING-01")
@RequestMapping(value = "/getOne", method = RequestMethod.GET)
@ApiOperation(value = "查看单个配置")
public Result<Setting> getOne(@RequestParam String id) {
return new ResultUtil<Setting>().setData(iSettingService.getById(id));
}
@SystemLog(about = "修改单个配置", type = LogType.DATA_CENTER,doType = "SETTING-02")
@RequestMapping(value = "/setOne", method = RequestMethod.GET)
@ApiOperation(value = "修改单个配置")
public Result<Object> setOne(@RequestParam String id,@RequestParam String value) {
Setting setting = iSettingService.getById(id);
if(setting == null) {
return ResultUtil.error("不存在");
}
if(!Objects.equals(value,setting.getValue())) {
setting.setValue(value);
iSettingService.saveOrUpdate(setting);
}
return ResultUtil.success();
}
}

@ -0,0 +1,479 @@
package cn.zwz.data.controller;
import cn.zwz.basics.log.SystemLog;
import cn.zwz.basics.redis.RedisTemplateHelper;
import cn.zwz.basics.utils.*;
import cn.zwz.basics.parameter.CommonConstant;
import cn.zwz.basics.log.LogType;
import cn.zwz.basics.baseVo.PageVo;
import cn.zwz.basics.baseVo.Result;
import cn.zwz.data.entity.*;
import cn.zwz.data.service.*;
import cn.zwz.data.utils.ZwzNullUtils;
import cn.zwz.data.vo.PermissionDTO;
import cn.zwz.data.vo.RoleDTO;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author
* CSDN: Designer
*/
@RestController
@Api(tags = "用户接口")
@RequestMapping("/zwz/user")
@CacheConfig(cacheNames = "user")
@Transactional
public class UserController {
@Autowired
private IUserService iUserService;
@Autowired
private IDepartmentService iDepartmentService;
@Autowired
private IRoleService iRoleService;
@Autowired
private IUserRoleService iUserRoleService;
@Autowired
private IDepartmentHeaderService iDepartmentHeaderService;
@Autowired
private IRolePermissionService iRolePermissionService;
@Autowired
private RedisTemplateHelper redisTemplateHelper;
@Autowired
private IPermissionService iPermissionService;
@PersistenceContext
private EntityManager entityManager;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private StringRedisTemplate redisTemplate;
private static final String REDIS_PRE_1 = "userRole::";
private static final String REDIS_PRE_2 = "userRole::depIds:";
private static final String REDIS_PRE_3 = "permission::userMenuList:";
private static final String REDIS_PRE_4 = "user::";
@SystemLog(about = "获取当前登录用户", type = LogType.DATA_CENTER,doType = "USER-02")
@RequestMapping(value = "/info", method = RequestMethod.GET)
@ApiOperation(value = "获取当前登录用户")
public Result<User> getUserInfo(){
User u = securityUtil.getCurrUser();
entityManager.clear();
u.setPassword(null);
return new ResultUtil<User>().setData(u);
}
@RequestMapping(value = "/regist", method = RequestMethod.POST)
@ApiOperation(value = "注册用户")
public Result<Object> regist(@Valid User u){
u.setEmail(u.getMobile() + "@qq.com");
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.and(wrapper -> wrapper.eq("username", u.getUsername()).or().eq("mobile",u.getMobile()));
if(iUserService.count(userQw) > 0L) {
return ResultUtil.error("登录账号/手机号重复");
}
String encryptPass = new BCryptPasswordEncoder().encode(u.getPassword());
u.setPassword(encryptPass).setType(0);
iUserService.saveOrUpdate(u);
QueryWrapper<Role> roleQw = new QueryWrapper<>();
roleQw.eq("default_role",true);
List<Role> roleList = iRoleService.list(roleQw);
if(roleList.size() > 0){
for(Role role : roleList) {
iUserRoleService.saveOrUpdate(new UserRole().setUserId(u.getId()).setRoleId(role.getId()));
}
}
return ResultUtil.data(u);
}
@SystemLog(about = "解锁验证密码", type = LogType.DATA_CENTER,doType = "USER-03")
@RequestMapping(value = "/unlock", method = RequestMethod.POST)
@ApiOperation(value = "解锁验证密码")
public Result<Object> unLock(@RequestParam String password){
User u = securityUtil.getCurrUser();
if(!new BCryptPasswordEncoder().matches(password, u.getPassword())){
return ResultUtil.error("密码不正确");
}
return ResultUtil.data(null);
}
@SystemLog(about = "重置密码", type = LogType.DATA_CENTER,doType = "USER-04")
@RequestMapping(value = "/resetPass", method = RequestMethod.POST)
@ApiOperation(value = "重置密码")
public Result<Object> resetPass(@RequestParam String[] ids){
for(String id : ids){
User userForReset = iUserService.getById(id);
if(userForReset == null) {
return ResultUtil.error("不存在");
}
userForReset.setPassword(new BCryptPasswordEncoder().encode("123456"));
iUserService.saveOrUpdate(userForReset);
redisTemplate.delete(REDIS_PRE_4 + userForReset.getUsername());
}
return ResultUtil.success();
}
@SystemLog(about = "修改用户资料", type = LogType.DATA_CENTER,doType = "USER-05")
@RequestMapping(value = "/edit", method = RequestMethod.POST)
@ApiOperation(value = "修改用户资料",notes = "用户名密码不会修改 需要username更新缓存")
@CacheEvict(key = "#u.username")
public Result<Object> editOwn(User u){
User old = securityUtil.getCurrUser();
u.setUsername(old.getUsername());
u.setPassword(old.getPassword());
iUserService.saveOrUpdate(u);
return ResultUtil.success("修改成功");
}
@SystemLog(about = "修改密码", type = LogType.DATA_CENTER,doType = "USER-06")
@RequestMapping(value = "/modifyPass", method = RequestMethod.POST)
@ApiOperation(value = "修改密码")
public Result<Object> modifyPass(@RequestParam String password,@RequestParam String newPass,@RequestParam String passStrength){
User user = securityUtil.getCurrUser();
if(!new BCryptPasswordEncoder().matches(password, user.getPassword())){
return ResultUtil.error("原密码不正确");
}
String newEncryptPass= new BCryptPasswordEncoder().encode(newPass);
user.setPassword(newEncryptPass);
user.setPassStrength(passStrength);
iUserService.saveOrUpdate(user);
redisTemplate.delete(REDIS_PRE_4 + user.getUsername());
return ResultUtil.success();
}
@SystemLog(about = "查询用户", type = LogType.DATA_CENTER,doType = "USER-07")
@RequestMapping(value = "/getUserList", method = RequestMethod.GET)
@ApiOperation(value = "查询用户")
public Result<IPage<User>> getUserList(@ModelAttribute User user, @ModelAttribute PageVo page) {
QueryWrapper<User> userQw = new QueryWrapper<>();
if(!ZwzNullUtils.isNull(user.getNickname())) {
userQw.like("nickname",user.getNickname());
}
if(!ZwzNullUtils.isNull(user.getDepartmentId())) {
userQw.eq("department_id",user.getDepartmentId());
}
IPage<User> userData = iUserService.page(PageUtil.initMpPage(page),userQw);
for(User u: userData.getRecords()) {
QueryWrapper<Role> roleQw = new QueryWrapper<>();
roleQw.inSql("id","SELECT role_id FROM a_user_role WHERE user_id = '" + u.getId() + "'");
List<Role> list = iRoleService.list(roleQw);
List<RoleDTO> roleDTOList = list.stream().map(e->{
return new RoleDTO().setId(e.getId()).setName(e.getName()).setDescription(e.getDescription());
}).collect(Collectors.toList());
u.setRoles(roleDTOList);
entityManager.detach(u);
u.setPassword(null);
}
return new ResultUtil<IPage<User>>().setData(userData);
}
@SystemLog(about = "根据部门查询用户", type = LogType.DATA_CENTER,doType = "USER-08")
@RequestMapping(value = "/getByDepartmentId", method = RequestMethod.GET)
@ApiOperation(value = "根据部门查询用户")
public Result<List<User>> getByCondition(@RequestParam String departmentId){
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.eq("department_id", departmentId);
List<User> list = iUserService.list(userQw);
entityManager.clear();
list.forEach(u -> {
u.setPassword(null);
});
return new ResultUtil<List<User>>().setData(list);
}
@SystemLog(about = "模拟搜索用户", type = LogType.DATA_CENTER,doType = "USER-09")
@RequestMapping(value = "/searchByName/{username}", method = RequestMethod.GET)
@ApiOperation(value = "模拟搜索用户")
public Result<List<User>> searchByName(@PathVariable String username) throws UnsupportedEncodingException {
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.eq("username", URLDecoder.decode(username, "utf-8"));
userQw.eq("status", 0);
List<User> list = iUserService.list(userQw);
entityManager.clear();
list.forEach(u -> {
u.setPassword(null);
});
return new ResultUtil<List<User>>().setData(list);
}
@SystemLog(about = "查询全部用户", type = LogType.DATA_CENTER,doType = "USER-10")
@RequestMapping(value = "/getAll", method = RequestMethod.GET)
@ApiOperation(value = "查询全部用户")
public Result<List<User>> getAll(){
List<User> userList = iUserService.list();
for(User user: userList){
entityManager.clear();
user.setPassword(null);
}
return new ResultUtil<List<User>>().setData(userList);
}
@SystemLog(about = "管理员修改资料", type = LogType.DATA_CENTER,doType = "USER-11")
@RequestMapping(value = "/admin/edit", method = RequestMethod.POST)
@ApiOperation(value = "管理员修改资料")
@CacheEvict(key = "#u.username")
public Result<Object> edit(User u,@RequestParam(required = false) String[] roleIds){
User customaryUser = iUserService.getById(u.getId());
// 登录账号和密码不能发生变更
u.setUsername(customaryUser.getUsername());
u.setPassword(customaryUser.getPassword());
if(!Objects.equals(customaryUser.getMobile(),u.getMobile())) {
QueryWrapper<User> customaryUserQw = new QueryWrapper<>();
customaryUserQw.ne("id",customaryUser.getId());
customaryUserQw.eq("mobile",u.getMobile());
long customaryUserCount = iUserService.count(customaryUserQw);
if(customaryUserCount > 0) {
return ResultUtil.error("手机号重复");
}
}
if(!ZwzNullUtils.isNull(u.getDepartmentId())) {
Department department = iDepartmentService.getById(u.getDepartmentId());
if(department != null) {
u.setDepartmentTitle(department.getTitle());
}
} else {
u.setDepartmentId("");
u.setDepartmentTitle("");
}
// 吃哦就花
iUserService.saveOrUpdate(u);
QueryWrapper<UserRole> userRoleQw = new QueryWrapper<>();
userRoleQw.eq("user_id",u.getId());
iUserRoleService.remove(userRoleQw);
if(roleIds != null && roleIds.length > 0) {
for (String roleId : roleIds) {
UserRole ur = new UserRole();
ur.setUserId(u.getId());
ur.setRoleId(roleId);
iUserRoleService.saveOrUpdate(ur);
}
}
redisTemplate.delete(REDIS_PRE_1 + u.getId());
redisTemplate.delete(REDIS_PRE_2 + u.getId());
redisTemplate.delete(REDIS_PRE_3 + u.getId());
return ResultUtil.success();
}
@SystemLog(about = "添加用户", type = LogType.DATA_CENTER,doType = "USER-12")
@RequestMapping(value = "/admin/add", method = RequestMethod.POST)
@ApiOperation(value = "添加用户")
public Result<Object> add(@Valid User u,@RequestParam(required = false) String[] roleIds) {
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.and(wrapper -> wrapper.eq("username", u.getUsername()).or().eq("mobile",u.getMobile()));
if(iUserService.count(userQw) > 0L) {
return ResultUtil.error("登录账号/手机号重复");
}
if(!ZwzNullUtils.isNull(u.getDepartmentId())){
Department department = iDepartmentService.getById(u.getDepartmentId());
if(department != null){
u.setDepartmentTitle(department.getTitle());
}
}else{
u.setDepartmentId("");
u.setDepartmentTitle("");
}
u.setPassword(new BCryptPasswordEncoder().encode(u.getPassword()));
iUserService.saveOrUpdate(u);
if(roleIds != null && roleIds.length > 0) {
for (String roleId : roleIds) {
UserRole userRole = new UserRole();
userRole.setUserId(u.getId());
userRole.setRoleId(roleId);
iUserRoleService.saveOrUpdate(userRole);
}
}
return ResultUtil.success();
}
@SystemLog(about = "禁用用户", type = LogType.DATA_CENTER,doType = "USER-13")
@RequestMapping(value = "/disable", method = RequestMethod.POST)
@ApiOperation(value = "禁用用户")
public Result<Object> disable( @RequestParam String id){
User user = iUserService.getById(id);
if(user == null){
return ResultUtil.error("用户不存在");
}
user.setStatus(CommonConstant.USER_STATUS_LOCK);
iUserService.saveOrUpdate(user);
redisTemplate.delete("user::"+user.getUsername());
return ResultUtil.success();
}
@SystemLog(about = "启用用户", type = LogType.DATA_CENTER,doType = "USER-14")
@RequestMapping(value = "/enable", method = RequestMethod.POST)
@ApiOperation(value = "启用用户")
public Result<Object> enable(@RequestParam String id){
User user = iUserService.getById(id);
if(user==null){
return ResultUtil.error("用户不存在");
}
user.setStatus(CommonConstant.USER_STATUS_NORMAL);
iUserService.saveOrUpdate(user);
redisTemplate.delete("user::"+user.getUsername());
return ResultUtil.success();
}
@SystemLog(about = "删除用户", type = LogType.DATA_CENTER,doType = "USER-15")
@RequestMapping(value = "/delByIds", method = RequestMethod.POST)
@ApiOperation(value = "删除用户")
public Result<Object> delByIds(@RequestParam String[] ids) {
for(String id:ids){
User u = iUserService.getById(id);
redisTemplate.delete("user::" + u.getUsername());
redisTemplate.delete("userRole::" + u.getId());
redisTemplate.delete("userRole::depIds:" + u.getId());
redisTemplate.delete("permission::userMenuList:" + u.getId());
Set<String> keys = redisTemplateHelper.keys("department::*");
redisTemplate.delete(keys);
iUserService.removeById(id);
QueryWrapper<UserRole> urQw = new QueryWrapper<>();
urQw.eq("user_id",id);
iUserRoleService.remove(urQw);
QueryWrapper<DepartmentHeader> dhQw = new QueryWrapper<>();
dhQw.eq("user_id",id);
iDepartmentHeaderService.remove(dhQw);
}
return ResultUtil.success();
}
@SystemLog(about = "导入用户", type = LogType.DATA_CENTER,doType = "USER-16")
@RequestMapping(value = "/importData", method = RequestMethod.POST)
@ApiOperation(value = "导入用户")
public Result<Object> importData(@RequestBody List<User> users){
List<Integer> errors = new ArrayList<>();
List<String> reasons = new ArrayList<>();
int count = 0;
for(User u: users){
count++;
if(StrUtil.isBlank(u.getUsername())||StrUtil.isBlank(u.getPassword())){
errors.add(count);
reasons.add("账号密码为空");
continue;
}
QueryWrapper<User> userQw = new QueryWrapper<>();
userQw.eq("username",u.getUsername());
if(iUserService.count(userQw) > 0L) {
errors.add(count);
reasons.add("用户名已存在");
continue;
}
u.setPassword(new BCryptPasswordEncoder().encode(u.getPassword()));
if(StrUtil.isNotBlank(u.getDepartmentId())){
Department department = iDepartmentService.getById(u.getDepartmentId());
if(department == null) {
errors.add(count);
reasons.add("部门不存在");
continue;
}
}
if(u.getStatus()==null){
u.setStatus(CommonConstant.USER_STATUS_NORMAL);
}
iUserService.saveOrUpdate(u);
if(u.getDefaultRole() != null && u.getDefaultRole()==1) {
QueryWrapper<Role> roleQw = new QueryWrapper<>();
roleQw.eq("default_role",true);
List<Role> roleList = iRoleService.list(roleQw);
if(roleList!=null&&roleList.size()>0){
for(Role role : roleList){
UserRole ur = new UserRole().setUserId(u.getId()).setRoleId(role.getId());
iUserRoleService.saveOrUpdate(ur);
}
}
}
}
int successCount = users.size() - errors.size();
String successMessage = "成功导入 " + successCount + " 位用户";
String failMessage = "成功导入 " + successCount + " 位用户,失败 " + errors.size() + " 位用户。<br>" +"第 " + errors.toString() + " 行数据导入出错,错误原因是为 <br>" + reasons.toString();
String message = null;
if(errors.size() == 0){
message = successMessage;
}else{
message = failMessage;
}
return ResultUtil.success(message);
}
@ApiOperation(value = "添加用户的角色和菜单信息")
public User userToDTO(User user) {
if(user == null) {
return null;
}
// 角色
QueryWrapper<UserRole> urQw = new QueryWrapper<>();
urQw.eq("user_id", user.getId());
List<UserRole> roleList = iUserRoleService.list(urQw);
List<RoleDTO> roleDTOList = new ArrayList<>();
for (UserRole userRole : roleList) {
Role role = iRoleService.getById(userRole.getRoleId());
if(role != null) {
roleDTOList.add(new RoleDTO().setId(role.getId()).setName(role.getName()));
}
}
user.setRoles(roleDTOList);
// 菜单
List<String> permissionIdList = new ArrayList<>();
for (RoleDTO dto : roleDTOList) {
QueryWrapper<RolePermission> rpQw = new QueryWrapper<>();
rpQw.eq("role_id",dto.getId());
List<RolePermission> list = iRolePermissionService.list(rpQw);
for (RolePermission rp : list) {
boolean flag = true;
for (String id : permissionIdList) {
if(Objects.equals(id,rp.getPermissionId())) {
flag = false;
break;
}
}
if(flag) {
permissionIdList.add(rp.getPermissionId());
}
}
}
List<PermissionDTO> permissionDTOList = new ArrayList<>();
for (String id : permissionIdList) {
Permission permission = iPermissionService.getById(id);
if(permission != null) {
if(Objects.equals(permission.getType(),CommonConstant.PERMISSION_OPERATION)) {
continue;
}
permissionDTOList.add(new PermissionDTO().setTitle(permission.getTitle()).setPath(permission.getPath()));
}
}
user.setPermissions(permissionDTOList);
return user;
}
}

@ -0,0 +1,12 @@
package cn.zwz.data.dao;
import cn.zwz.basics.baseClass.ZwzBaseDao;
import cn.zwz.data.entity.Log;
/**
* @author
* CSDN: Designer
*/
public interface LogDao extends ZwzBaseDao<Log,String> {
}

@ -0,0 +1,14 @@
package cn.zwz.data.dao.mapper;
import cn.zwz.data.entity.Permission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author
* CSDN: Designer
*/
public interface PermissionMapper extends BaseMapper<Permission> {
}

@ -0,0 +1,11 @@
package cn.zwz.data.dao.mapper;
import cn.zwz.data.entity.Role;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author
* CSDN: Designer
*/
public interface RoleMapper extends BaseMapper<Role> {
}

@ -0,0 +1,11 @@
package cn.zwz.data.dao.mapper;
import cn.zwz.data.entity.RolePermission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author
* CSDN: Designer
*/
public interface RolePermissionMapper extends BaseMapper<RolePermission> {
}

@ -0,0 +1,11 @@
package cn.zwz.data.dao.mapper;
import cn.zwz.data.entity.Setting;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author
* CSDN: Designer
*/
public interface SettingMapper extends BaseMapper<Setting> {
}

@ -0,0 +1,11 @@
package cn.zwz.data.dao.mapper;
import cn.zwz.data.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author
* CSDN: Designer
*/
public interface UserMapper extends BaseMapper<User> {
}

@ -0,0 +1,15 @@
package cn.zwz.data.dao.mapper;
import cn.zwz.data.entity.Role;
import cn.zwz.data.entity.UserRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author
* CSDN: Designer
*/
public interface UserRoleMapper extends BaseMapper<UserRole> {
}

@ -0,0 +1,95 @@
package cn.zwz.data.entity;
import cn.zwz.basics.baseClass.ZwzBaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import java.math.BigDecimal;
import java.util.List;
/**
* @author
* CSDN: Designer
*/
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "a_permission")
@TableName("a_permission")
@ApiModel(value = "菜单权限")
public class Permission extends ZwzBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "菜单名称")
private String name;
@ApiModelProperty(value = "菜单标题")
private String title;
@ApiModelProperty(value = "菜单层级")
private Integer level;
@ApiModelProperty(value = "启用状态")
private Integer status = 0;
@ApiModelProperty(value = "菜单按钮类型")
private Integer type;
@ApiModelProperty(value = "前端组件名称")
private String component;
@ApiModelProperty(value = "页面路径")
private String path;
@ApiModelProperty(value = "PC端图标")
private String icon;
@ApiModelProperty(value = "父节点ID")
private String parentId;
@ApiModelProperty(value = "按钮类型")
private String buttonType;
@ApiModelProperty(value = "备注")
private String description;
@ApiModelProperty(value = "菜单排序值")
@Column(precision = 10, scale = 2)
private BigDecimal sortOrder;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "节点展开状态")
private Boolean expand = true;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "结点选中状态")
private Boolean selected = false;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "结点勾选状态")
private Boolean checked = false;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "子菜单列表")
private List<Permission> children;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "菜单子权限列表")
private List<String> permTypes;
}

@ -0,0 +1,48 @@
package cn.zwz.data.entity;
import cn.zwz.basics.baseClass.ZwzBaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import java.util.List;
/**
* @author
* CSDN: Designer
*/
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "a_role")
@TableName("a_role")
@ApiModel(value = "角色")
public class Role extends ZwzBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "角色名称")
private String name;
@ApiModelProperty(value = "数据权限")
private int dataType;
@ApiModelProperty(value = "是否默认")
private Boolean defaultRole;
@ApiModelProperty(value = "角色备注")
private String description;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "角色拥有菜单列表")
private List<RolePermission> permissions;
}

@ -0,0 +1,36 @@
package cn.zwz.data.entity;
import cn.zwz.basics.baseClass.ZwzBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
/**
* @author
* CSDN: Designer
*/
@Data
@Accessors(chain = true)
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "a_role_permission")
@TableName("a_role_permission")
@ApiModel(value = "角色权限")
public class RolePermission extends ZwzBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "权限ID")
private String permissionId;
@ApiModelProperty(value = "角色ID")
private String roleId;
}

@ -0,0 +1,37 @@
package cn.zwz.data.entity;
import cn.zwz.basics.baseClass.ZwzBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
/**
* @author
* CSDN: Designer
*/
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "a_setting")
@TableName("a_setting")
@ApiModel(value = "配置")
@NoArgsConstructor
public class Setting extends ZwzBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "设置内容")
private String value;
public Setting(String id){
super.setId(id);
}
}

@ -0,0 +1,105 @@
package cn.zwz.data.entity;
import cn.zwz.basics.baseClass.ZwzBaseEntity;
import cn.zwz.basics.parameter.CommonConstant;
import cn.zwz.data.vo.PermissionDTO;
import cn.zwz.data.vo.RoleDTO;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import java.util.List;
/**
* @author
* CSDN: Designer
*/
@Data
@Accessors(chain = true)
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "a_user")
@TableName("a_user")
@ApiModel(value = "用户")
public class User extends ZwzBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "姓名")
@NotNull(message = "姓名不能为空")
@Size(max = 20, message = "姓名长度不能超过20")
private String nickname;
@ApiModelProperty(value = "账号")
@Column(unique = true, nullable = false)
@Pattern(regexp = "^[a-zA-Z0-9_\\u4e00-\\u9fa5]{4,16}$", message = "账号长度不合法")
private String username;
@ApiModelProperty(value = "密码")
@NotNull(message = "密码不能为空")
private String password;
@ApiModelProperty(value = "密码强度")
@Column(length = 2)
private String passStrength;
@ApiModelProperty(value = "手机号")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式错误")
private String mobile;
@ApiModelProperty(value = "部门ID")
private String departmentId;
@ApiModelProperty(value = "部门")
private String departmentTitle;
@ApiModelProperty(value = "邮箱")
@Pattern(regexp = "^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$", message = "邮箱格式错误")
private String email;
@ApiModelProperty(value = "性别")
private String sex;
@ApiModelProperty(value = "区县")
private String address;
@ApiModelProperty(value = "用户类型")
private Integer type;
@ApiModelProperty(value = "个人门户")
private String myDoor;
@ApiModelProperty(value = "启用状态")
private Integer status = CommonConstant.USER_STATUS_NORMAL;
@ApiModelProperty(value = "头像")
private String avatar = CommonConstant.USER_DEFAULT_AVATAR;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "是否默认角色")
private Integer defaultRole;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "用户拥有的菜单列表")
private List<PermissionDTO> permissions;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "用户拥有的角色列表")
private List<RoleDTO> roles;
}

@ -0,0 +1,48 @@
package cn.zwz.data.entity;
import cn.zwz.basics.baseClass.ZwzBaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
/**
* @author
* CSDN: Designer
*/
@Data
@Accessors(chain = true)
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "a_user_role")
@TableName("a_user_role")
@ApiModel(value = "用户角色")
public class UserRole extends ZwzBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "角色ID")
private String roleId;
@ApiModelProperty(value = "用户ID")
private String userId;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "用户名")
private String userName;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "角色名")
private String roleName;
}

@ -0,0 +1,13 @@
package cn.zwz.data.service;
import cn.zwz.data.entity.Permission;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author
* CSDN: Designer
*/
public interface IPermissionService extends IService<Permission> {
}

@ -0,0 +1,12 @@
package cn.zwz.data.service;
import cn.zwz.data.entity.RolePermission;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author
* CSDN: Designer
*/
public interface IRolePermissionService extends IService<RolePermission> {
}

@ -0,0 +1,12 @@
package cn.zwz.data.service;
import cn.zwz.data.entity.Role;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author
* CSDN: Designer
*/
public interface IRoleService extends IService<Role> {
}

@ -0,0 +1,12 @@
package cn.zwz.data.service;
import cn.zwz.data.entity.Setting;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author
* CSDN: Designer
*/
public interface ISettingService extends IService<Setting> {
}

@ -0,0 +1,11 @@
package cn.zwz.data.service;
import cn.zwz.data.entity.UserRole;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author
* CSDN: Designer
*/
public interface IUserRoleService extends IService<UserRole> {
}

@ -0,0 +1,12 @@
package cn.zwz.data.service;
import cn.zwz.data.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author
* CSDN: Designer
*/
public interface IUserService extends IService<User> {
}

@ -0,0 +1,16 @@
package cn.zwz.data.serviceimpl;
import cn.zwz.data.dao.mapper.PermissionMapper;
import cn.zwz.data.entity.Permission;
import cn.zwz.data.service.IPermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author
* CSDN: Designer
*/
@Service
public class IPermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
}

@ -0,0 +1,16 @@
package cn.zwz.data.serviceimpl;
import cn.zwz.data.dao.mapper.RolePermissionMapper;
import cn.zwz.data.entity.RolePermission;
import cn.zwz.data.service.IRolePermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author
* CSDN: Designer
*/
@Service
public class IRolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> implements IRolePermissionService {
}

@ -0,0 +1,16 @@
package cn.zwz.data.serviceimpl;
import cn.zwz.data.dao.mapper.RoleMapper;
import cn.zwz.data.entity.Role;
import cn.zwz.data.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author
* CSDN: Designer
*/
@Service
public class IRoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
}

@ -0,0 +1,16 @@
package cn.zwz.data.serviceimpl;
import cn.zwz.data.dao.mapper.SettingMapper;
import cn.zwz.data.entity.Setting;
import cn.zwz.data.service.ISettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author
* CSDN: Designer
*/
@Service
public class ISettingServiceImpl extends ServiceImpl<SettingMapper, Setting> implements ISettingService {
}

@ -0,0 +1,16 @@
package cn.zwz.data.serviceimpl;
import cn.zwz.data.dao.mapper.UserRoleMapper;
import cn.zwz.data.entity.UserRole;
import cn.zwz.data.service.IUserRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author
* CSDN: Designer
*/
@Service
public class IUserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements IUserRoleService {
}

@ -0,0 +1,16 @@
package cn.zwz.data.serviceimpl;
import cn.zwz.data.dao.mapper.UserMapper;
import cn.zwz.data.entity.User;
import cn.zwz.data.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author
* CSDN: Designer
*/
@Service
public class IUserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}

@ -0,0 +1,31 @@
package cn.zwz.data.utils;
import cn.zwz.data.vo.OssSettingVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
/**
* @author
* CSDN: Designer
*/
@Api(tags = "文件配置接口类")
public interface FileManage {
@ApiOperation(value = "删除文件")
void deleteFile(String key);
@ApiOperation(value = "重命名文件")
String renameFile(String fromKey, String toKey);
@ApiOperation(value = "获取配置")
OssSettingVo getOssSetting();
@ApiOperation(value = "拷贝文件")
String copyFile(String fromKey, String toKey);
@ApiOperation(value = "文件流上传")
String inputStreamUpload(InputStream inputStream, String key, MultipartFile file);
}

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

Loading…
Cancel
Save