commit
88ca2b015e
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 4.9 MiB |
@ -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,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,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,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";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Markdown消息B类
|
||||||
|
*/
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Markdown消息A类
|
||||||
|
*/
|
||||||
|
@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…
Reference in new issue