提交 f5d09e69 编写于 作者: 张骞

V0.3版本,将删除修改为逻辑删除,优化了自动填充更新人字段方法,缓存方案更改为Spring Cache,增加Knife4j框架

上级 5b039170
......@@ -4,8 +4,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--SpringBoot集成JSP页面后台工程-->
<!--父工程信息-->
<groupId>com.template</groupId>
<artifactId>Template-back</artifactId>
......@@ -128,64 +126,6 @@
<artifactId>mongodb-driver-sync</artifactId>
<version>3.9.1</version>
</dependency>-->
<!--RocketMQ相关
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.3</version>
</dependency>
&lt;!&ndash;MQ相关依赖&ndash;&gt;
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.6.0</version>
</dependency>-->
<!--zk依赖-->
<!--<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>-->
<!--dubbo的springboot支持-->
<!--<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>-->
<!--dubbo框架-->
<!--<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.4</version>
</dependency>-->
<!--阿里云-->
<!--<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.3</version>
</dependency>-->
<!--<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>-->
<!--fastDFS依赖-->
<!--<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.7</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>-->
<!--阿里云OSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
......
......@@ -111,6 +111,12 @@
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.22</version>
<scope>compile</scope>
</dependency>
</dependencies>
......
......@@ -2,11 +2,13 @@ package com.template.back.common.mapper.school;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.template.back.common.pojo.school.Campus;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 张骞
* @version 1.0.0
* 校区映射接口
*/
@Mapper
public interface CampusMapper extends BaseMapper<Campus> {
}
......@@ -3,6 +3,7 @@ package com.template.back.common.mapper.system;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.pojo.system.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
......@@ -10,8 +11,9 @@ import java.util.List;
/**
* @author 张骞
* @version 1.0
* 管理员用户封装类
* 管理员用户mapper
*/
@Mapper
public interface AdminMapper extends BaseMapper<Admin> {
//中间表查询方法,关联用户和角色之间的关系,根据角色id查询用户
@Select("select admin_id, name,user_name from tb_admin where admin_id IN (SELECT admin_id FROM tb_role_admin WHERE role_id = #{roleId}) ")
......
......@@ -2,7 +2,13 @@ package com.template.back.common.mapper.system;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.template.back.common.pojo.system.Dept;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 张骞
* @version 1.0
* 管理员部门mapper
*/
@Mapper
public interface DeptMapper extends BaseMapper<Dept> {
}
......@@ -2,11 +2,13 @@ package com.template.back.common.mapper.system;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.template.back.common.pojo.Heartbeat;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 张骞
* @version 1.0.0
* 心跳连接映射类
*/
@Mapper
public interface HeartbeatMapper extends BaseMapper<Heartbeat> {
}
......@@ -2,6 +2,7 @@ package com.template.back.common.mapper.system;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.template.back.common.pojo.system.Logger;
import org.apache.ibatis.annotations.Mapper;
/**
......@@ -9,5 +10,6 @@ import com.template.back.common.pojo.system.Logger;
* @version 1.0.0
* @Description logger对应的mapper,使用了mybatisplus
*/
@Mapper
public interface LoggerMapper extends BaseMapper<Logger> {
}
......@@ -2,13 +2,17 @@ package com.template.back.common.mapper.system;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.template.back.common.pojo.system.Module;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 模块映射接口
* @author 张骞
* @version 1.0
* 功能模块mapper
*/
@Mapper
public interface ModuleMapper extends BaseMapper<Module> {
/**
* 根据用户id,查询对应的模块,需要通过中间表查询
......
......@@ -6,14 +6,18 @@ import com.template.back.common.pojo.system.Role;
import com.template.back.common.vo.TreeVo;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
/**
* 角色映射接口
* @author 张骞
* @version 1.0
* 角色mapper
*/
@Mapper
public interface RoleMapper extends BaseMapper<Role> {
/**
* 根据角色查询已经授权的模块
......
......@@ -2,11 +2,13 @@ package com.template.back.common.mapper.system;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.template.back.common.pojo.system.Setting;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 张骞
* @version 1.0
* 自定义设置项保存数据
*/
@Mapper
public interface SettingMapper extends BaseMapper<Setting> {
}
......@@ -2,7 +2,12 @@ package com.template.back.common.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.ibatis.annotations.Delete;
import java.time.LocalDateTime;
import java.util.Date;
......@@ -10,17 +15,39 @@ import java.util.Date;
/**
* @author 张骞
* @version 1.0.0
* @Date 2022年8月14日18:39:33
* @Description 自动填充新增日期和修改日期,需要配合handler
*/
@Data
@ApiModel("公共类") //knife4j框架注解,对类的解释说明
@Data //注解get/set方法
public abstract class BasePojo {
//新增时的保存时间
@ApiModelProperty("新增时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime created;
//新增和修改时的保存时间
@ApiModelProperty("修改时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updated;
//记录当前操作人信息,不进行自动填充,根据需求在业务层自行填充
private String operator;
//记录当前操作用户姓名
@ApiModelProperty("操作用户名称")
@TableField(fill = FieldFill.INSERT_UPDATE)
private String operatorName;
//记录当前操作用户id
@ApiModelProperty("操作用户Id")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long operatorId;
//乐观锁字段
@ApiModelProperty("乐观锁字段")
@Version
private Integer version;
@ApiModelProperty("逻辑删除字段")
@TableLogic
private Integer deleted;
}
package com.template.back.common.pojo;
import java.io.Serializable;
import java.util.List;
/**
......@@ -8,7 +9,9 @@ import java.util.List;
* @param <T>
* element ui 树形控件使用
*/
public interface DataTree<T> {
public interface DataTree<T> extends Serializable {
//定义序列化id
static final Long serialVersionUID = 1L;
public Object getId();
public Object getParentId();
public void setChildren(List<T> children);
......
package com.template.back.common.pojo;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
......@@ -10,12 +12,14 @@ import lombok.NoArgsConstructor;
* @version 1.0.0
* 心跳连接表,用于查询
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("心跳连接模拟数据") //knife4j框架注解,对类的解释说明
@Data //注解get/set方法
public class Heartbeat {
//成员变量
@ApiModelProperty("主键Id")
@TableId //注解为主键
private Long id; //id
@ApiModelProperty("名称")
private String name; //名称
}
......@@ -4,30 +4,47 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import com.template.back.common.pojo.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Date;
/**
* @author 张骞
* @version 1.0.0
* 校区数据实体模型
* @version 2.0.0
* @Date 2022年8月14日17:41:04
* 校区数据实体模型,其他模型可以参考此模型
*/
@ApiModel("校区") //knife4j框架注解,对类的解释说明
@Data //注解get/set方法
@AllArgsConstructor //注解全参数构造方法
@NoArgsConstructor //注解无参构造方法
public class Campus extends BasePojo {
public class Campus extends BasePojo implements Serializable {
//定义序列化id
private static final Long serialVersionUID = 1L;
//成员变量
@ApiModelProperty("主键id")
@TableId(type = IdType.UUID ) //注解为主键,字段开启驼峰命名法
private String campusId; //主键id,使用UUID形式
@ApiModelProperty("学校名称")
private String name; //学校名称
private Date coopTime; //合作时间
@ApiModelProperty("合作时间")
private LocalDate coopTime; //合作时间
@ApiModelProperty("所属销售")
private String sale; //所属销售
@ApiModelProperty("校区备注")
private String remark; //校区备注
//乐观锁字段
@Version
private Integer version;
}
......@@ -4,30 +4,50 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import com.template.back.common.pojo.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 后台管理员数据模型
* @author 张骞
* @version 2.0.0
* @Date 2022年8月14日17:41:04
* 后台用户数据模型
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Admin extends BasePojo {
@ApiModel("后台用户") //knife4j框架注解,对类的解释说明
@Data //注解get/set方法
@AllArgsConstructor //注解全参数构造方法
@NoArgsConstructor //注解无参构造方法
public class Admin extends BasePojo implements Serializable {
//定义序列化id
private static final Long serialVersionUID = 1L;
//成员变量
@ApiModelProperty("主键id")
@TableId //注解为主键
private Long adminId; //主键id
@ApiModelProperty("用户姓名")
private String name; //用户姓名
@ApiModelProperty("用户登录名")
private String userName; //用户登录名
@ApiModelProperty("用户密码")
private String password; //用户密码
@ApiModelProperty("用户状态")
private Long state; //用户状态
@ApiModelProperty("部门id")
private String deptId; //部门id
//关联的部门类型
@ApiModelProperty("关联的部门类型")
@TableField(exist = false) //该字段在数据库中不存在
private Dept dept;
//乐观锁字段
@Version
private Integer version;
}
......@@ -3,23 +3,37 @@ package com.template.back.common.pojo.system;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import com.template.back.common.pojo.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 后台管理员关联部门用户模型
* @author 张骞
* @version 2.0.0
* @Date 2022年8月14日17:41:04
* 后台部门数据模型
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept extends BasePojo {
@ApiModel("部门") //knife4j框架注解,对类的解释说明
@Data //注解get/set方法
@AllArgsConstructor //注解全参数构造方法
@NoArgsConstructor //注解无参构造方法
public class Dept extends BasePojo implements Serializable {
//定义序列化id
private static final Long serialVersionUID = 1L;
//成员变量
@ApiModelProperty("主键id")
@TableId //注解为主键
private Long deptId; //部门id
@ApiModelProperty("部门名称")
private String deptName; //部门名称
@ApiModelProperty("备注")
private String remark; //备注
@Version //乐观锁字段
private Integer version;
}
package com.template.back.common.pojo.system;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.template.back.common.pojo.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author 张骞
* @version 1.0.0
* 记录日志数据模型
* @version 2.0.0
* @Date 2022年8月14日17:44:48
* 自定义错误日志数据模型
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Logger extends BasePojo {
//日志记录的成员变量信息
@ApiModel("自定义错误日志") //knife4j框架注解,对类的解释说明
@Data //注解get/set方法
@AllArgsConstructor //注解全参数构造方法
@NoArgsConstructor //注解无参构造方法
public class Logger implements Serializable {
//定义序列化id
private static final Long serialVersionUID = 1L;
//用户id,在配置文件中设置为自增长
//成员变量
@ApiModelProperty("主键id")
@TableId //注解为主键
private Long id;
//记录异常出现的类
@ApiModelProperty("记录异常出现的类")
private String classes;
//记录异常出现的方法
@ApiModelProperty("记录异常出现的方法")
private String method;
//记录操作时出现异常的用户id
@ApiModelProperty("记录操作时出现异常的用户id")
private String userId;
//出现异常的用户姓名
@ApiModelProperty("出现异常的用户姓名")
private String nickName;
//具体的异常信息
@ApiModelProperty("具体的异常信息")
private String exception;
//开发者备注
@ApiModelProperty("开发者备注")
private String remark;
//本表没有乐观锁字段与逻辑删除字段,这里不继承basePojo,所以添加如下字段
//新增时的保存时间
@ApiModelProperty("新增时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime created;
//新增和修改时的保存时间
@ApiModelProperty("修改时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updated;
//记录当前操作用户姓名
@ApiModelProperty("操作用户名称")
@TableField(fill = FieldFill.INSERT_UPDATE)
private String operator_name;
//记录当前操作用户id
@ApiModelProperty("操作用户Id")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long operator_id;
}
......@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import com.template.back.common.pojo.BasePojo;
import com.template.back.common.pojo.DataTree;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
......@@ -12,34 +14,55 @@ import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author 张骞
* @version 2.0.0
* @Date 2022年8月14日18:21:34
* 功能模块数据模型
*/
@ApiModel("功能模块") //knife4j框架注解,对类的解释说明
@Data //注解生成get/set方法
@AllArgsConstructor //注解生成全参构造
@NoArgsConstructor //注解生成无参构造
public class Module extends BasePojo implements DataTree<Module> {
//成员变量
@ApiModelProperty("主键id")
@TableId(value = "module_id") //注解为主键,指定主键在数据库中的名字
private Long id; //模块id
@ApiModelProperty("排序字段")
private String sort; //排序字段
@ApiModelProperty("父模块id")
private Long parentId; //父模块id
@ApiModelProperty("模块名称")
private String name; //模块名称
@ApiModelProperty("类型0 主菜单/1 左侧菜单/2按钮/3 链接/4 状态")
private Long ctype; //'0 主菜单/1 左侧菜单/2按钮/3 链接/4 状态'
@ApiModelProperty("状态1启用0停用")
private Long state; //'1启用0停用'
@ApiModelProperty("静态页链接地址")
private String curl; //'模块前端静态页链接地址'
@ApiModelProperty("页面请求地址")
private String req; //'模块前端静态页点击按钮或者刷新页面后的请求地址'
@ApiModelProperty("备注")
private String remark; //'备注'
@ApiModelProperty("图标")
private String icon; //'图标 如果是按钮,这里则是按钮的显示状态'
//本类的自关联对象
@ApiModelProperty("本类的自关联对象")
@TableField(exist = false) //该字段在数据库中不存在
private Module module;
@Version //乐观锁字段
private Integer version;
//数据表中不存在,为子模块字段,在树形工具类中使用
@ApiModelProperty("子模块")
@TableField(exist= false)
private List<Module> children;
}
......@@ -4,25 +4,42 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import com.template.back.common.pojo.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 角色模块数据模型
* @author 张骞
* @version 2.0.0
* @Date 2022年8月14日18:25:30
* 后台用户角色数据模型
*/
@ApiModel("后台用户角色") //knife4j框架注解,对类的解释说明
@Data //注解生成get/set方法
@AllArgsConstructor //注解生成全参构造
@NoArgsConstructor //注解生成无参构造
public class Role extends BasePojo {
public class Role extends BasePojo implements Serializable {
//定义序列化id
private static final Long serialVersionUID = 1L;
//创建成员变量
@ApiModelProperty("主键id")
@TableId //注解为主键
private Long roleId;
@ApiModelProperty("角色名称")
private String name; //名称
@ApiModelProperty("描述信息")
private String remark; //描述信息
@ApiModelProperty("用户与角色关联回显数据")
@TableField(exist = false) //该字段在数据库中不存在
private String checked; //用于用户与角色关联回显数据,标记当前用户和角色的关联关系
@Version //乐观锁字段
private Integer version;
}
......@@ -3,28 +3,43 @@ package com.template.back.common.pojo.system;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import com.template.back.common.pojo.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author 张骞
* @version 1.0.0
* @Date 2022年8月14日18:27:11
* 自定义可读取参数数据模型
* 键值对模式
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Setting extends BasePojo {
@ApiModel("后台自定义设置") //knife4j框架注解,对类的解释说明
@Data //注解get/set方法
@AllArgsConstructor //注解全参数构造方法
@NoArgsConstructor //注解无参构造方法
public class Setting extends BasePojo implements Serializable {
//定义序列化id
private static final Long serialVersionUID = 1L;
//成员变量
@ApiModelProperty("主键id")
@TableId //注解为主键
private Long id;
@ApiModelProperty("排序字段")
private String sort; //排序字段
@ApiModelProperty("参数名称")
private String name; //参数名称
@ApiModelProperty("具体参数")
private String param; //具体参数
private String remark; //备注
@Version //乐观锁字段
private Integer version;
@ApiModelProperty("备注")
private String remark; //备注
}
package com.template.back.common.utils;
import java.lang.annotation.*;
/**
* @author 张骞
* @version 1.0.0
* @Description 被标记为Cache的Controller进行缓存,其他情况不进行缓存
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented //标记注解
public @interface CaChe {
/**
* 缓存时间,可以在注解中修改
* @return
*/
String time() default "60";
}
package com.template.back.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
......@@ -12,12 +15,20 @@ import java.util.Map;
* A. 如果业务执行结果为成功, 构建R对象时, 只需要调用 success 方法; 如果需要返回数据传递 object 参数, 如果无需返回, 可以直接传递null。
* B. 如果业务执行结果为失败, 构建R对象时, 只需要调用error 方法, 传递错误提示信息即可。
*/
@ApiModel("web请求返回") //swagger类注解
@Data //注解生成get/set方法
public class R<T> {
public class R<T> implements Serializable {
//返回结果集的成员变量
@ApiModelProperty("响应编码,1-成功,0或者其他数字-失败")
private Integer code; //相应编码,1-成功,0或者其他数字-失败
@ApiModelProperty("错误信息")
private String msg; //错误信息
@ApiModelProperty("响应数据")
private T data; //数据
@ApiModelProperty("响应动态数据")
private Map map = new HashMap(); //相应的动态数据
/**
......
......@@ -12,7 +12,7 @@
<modelVersion>4.0.0</modelVersion>
<!--子项目信息-->
<artifactId>template-back-server</artifactId>
<packaging>war</packaging>
<!--<packaging>war</packaging>-->
<!--版本信息-->
<properties>
<maven.compiler.source>8</maven.compiler.source>
......@@ -20,6 +20,31 @@
</properties>
<!--导入依赖-->
<dependencies>
<!--集成swagger的knife4j框架-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
<!--spring Cache依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--thymeleaf模板-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
<!-- redis起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
......@@ -109,65 +134,44 @@
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
</dependencies>
<!--dubbo的springboot支持
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
dubbo框架
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.4</version>
</dependency>-->
<!--fast依赖,需要父项目支持,否则解析maven依赖会报错-->
<!--<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
</dependency>-->
<!--zk依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
&lt;!&ndash; 去除log4j相关依赖,防止与logback冲突 &ndash;&gt;
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>-->
<!--RocketMQ相关-->
<!--<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
</dependency>-->
<!-- servlet依赖 -->
<!--<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>-->
<build>
<plugins>
<!--maven插件-->
<!--修改maven-resources-plugin版本-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- java编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!--springboot编译插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.5</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
......@@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
......@@ -17,6 +18,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
*/
//开启定时任务
@EnableScheduling
//启用Spring Cache框架注解
@EnableCaching
//由于上传逻辑移动至common工程,所以需要改变扫描把范围才能扫描到
@ComponentScan(basePackages={"com.template"})
//排除mongo的自动配置
......
......@@ -2,17 +2,24 @@ package com.template.back.server.config;
import com.template.back.common.mapper.JacksonObjectMapper;
import com.template.back.server.interceptor.AuthorInterceptor;
import com.template.back.server.interceptor.RedisCacheInterceptor;
import com.template.back.server.interceptor.AdminLoginInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.List;
......@@ -24,16 +31,23 @@ import java.util.List;
@Configuration
@Slf4j
public class WebConfig extends WebMvcConfigurationSupport {
//注入登录拦截器
@Autowired
private AdminLoginInterceptor adminLoginInterceptor;
//注入缓存拦截器
@Autowired
private RedisCacheInterceptor redisCacheInterceptor;
//注入权限拦截器
@Autowired
private AuthorInterceptor authorInterceptor;
/**
* 定义前端资源需要放行的部分
*/
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/backend/", "classpath:/public/" };
/**
* 将自定义方法加入拦截器
* @param registry
......@@ -42,10 +56,9 @@ public class WebConfig extends WebMvcConfigurationSupport {
public void addInterceptors(InterceptorRegistry registry) {
//考虑拦截器的顺序
//登录使用了过滤器,不再使用拦截器
//registry.addInterceptor(this.adminLoginInterceptor).addPathPatterns("/**");
registry.addInterceptor(this.adminLoginInterceptor).addPathPatterns("/**");
//权限拦截器
registry.addInterceptor(this.authorInterceptor).addPathPatterns("/**");
registry.addInterceptor(this.redisCacheInterceptor).addPathPatterns("/**");
}
/**
* 进行静态资源映射的方法
......@@ -55,9 +68,25 @@ public class WebConfig extends WebMvcConfigurationSupport {
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("开始进行静态资源映射……");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
//注册前端资源,避免前端js和css无法被加载
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
//配置本地磁盘的静态资源路径
registry.addResourceHandler("/common/download/**").addResourceLocations("file:E:/001/");
//配置swagger资源(下面两个都是)
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
/**
* 自定义首页地址
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//登录的路径
registry.addViewController("/").setViewName("forward:/backend/pages/login/login.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers(registry);
}
/**
......@@ -73,4 +102,32 @@ public class WebConfig extends WebMvcConfigurationSupport {
//03.将上面的消息转换器对象追加到mvc框架的转换器集合中
converters.add(0,messageConverter);
}
/**
* knife4j框架配置使用
* @return
*/
@Bean
public Docket createRestApi() {
// 文档类型
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.template.back.server.controller"))
.paths(PathSelectors.any())
.build();
}
/**
* knife4j框架配置使用
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Z-Admin")
.version("2.1")
.description("Z-Admin后台管理接口文档")
.build();
}
}
......@@ -7,15 +7,22 @@ import com.template.back.common.pojo.school.Campus;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.service.LoggerService;
import com.template.back.common.utils.AdminThreadLocal;
import com.template.back.common.vo.R;
import com.template.back.server.service.school.CampusService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
/**
......@@ -23,8 +30,9 @@ import java.util.Map;
* @version 1.0.0
* 加盟校控制层代码,本框架单表增删改查标准代码
*/
@Controller //标记为控制层
@RequestMapping("/school/campus") //注解请求映射路径
@Api(tags = "校区管理相关接口")
@RestController //标记为restful风格的控制层
@RequestMapping("/school/campus/") //注解请求映射路径
@Slf4j //注解日志
public class CampusController {
//注入自定义日志业务层
......@@ -35,179 +43,150 @@ public class CampusController {
@Autowired
private CampusService campusService;
/**
* 查询列表
* 查询部门列表
*
* @param page 当前页码
* @param pageSize 每页的数据长度
* @param modelAndView 视图对象
* @param page 当前页码
* @param pageSize 每页的数据长度
* @return
*/
@RequestMapping("list")
public ModelAndView list(@RequestParam(value = "page", defaultValue = "1", required = false) Integer page,
@RequestParam(value = "size", defaultValue = "12", required = false) Integer pageSize,
ModelAndView modelAndView) {
@ApiOperation(value = "查看加盟校列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "page",value = "当前页码",required = true,defaultValue = "1"),
@ApiImplicitParam(name = "pageSize",value = "每页数据长度",required = true,defaultValue = "10"),
@ApiImplicitParam(name = "campusName",value = "根据校区名称查询",required = false),
@ApiImplicitParam(name = "address",value = "根据校区地址查询",required = false),
@ApiImplicitParam(name = "startData",value = "根据开始时间查询,和结束时间共用",required = false),
@ApiImplicitParam(name = "endData",value = "根据结束时间查询,和开始时间共用",required = false),
}) //knife4j注解,用于对接口参数进行说明
@Cacheable(value = "campusCache",key = "#page + '_' + #pageSize+ '_' +#campusName + '_' + #address+ '_' + #startData + '_' + #endData") //spring cache写入缓存
@GetMapping("page")
public R<Page> list(@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(value = "campusName", required = false) String campusName,
@RequestParam(value = "address", required = false) String address,
@RequestParam(value = "startData", required = false)String startData,
@RequestParam(value = "endData", required = false)String endData) {
try {
//调用业务层方法
Page all = this.campusService.findPage(page, pageSize);
Page all = this.campusService.findPage(page, pageSize, campusName, address,startData,endData);
//向前端存入数据
modelAndView.addObject("page", all);
//请求转发
modelAndView.setViewName("WEB-INF/pages/school/campus/list");
return modelAndView;
return R.success(all);
} catch (Exception exception) {
//记录日志
this.loggerService.saveLogAndUser(this.getClass().getName(), //获取当前类名及类数据
this.loggerService.saveLog(this.getClass().getName(), //获取当前类名及类数据
Thread.currentThread().getStackTrace()[1].getMethodName(), //获取当前方法名
this.getAdmin().getName(), //获取当前登录的用户名
exception, "查询校区列表"); //功能中文描述
log.error("后台工程出现异常!异常信息为:" + exception);
exception, "查询加盟校列表");
log.error("后台工程:controller.CampusController出现异常!异常信息为:" + exception);
}
//出现异常,返回错误信息
modelAndView.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
return modelAndView;
return R.error("查询数据列表异常!");
}
/**
* 跳转到新增页面的方法
* 新增数据的方法
* @param campus
* @return
*/
@ApiOperation(value = "新增加盟校数据")
@ApiImplicitParams({@ApiImplicitParam(name = "campus",value = "新增的加盟校数据",required = true)}) //knife4j注解,用于对接口参数进行说明
@CacheEvict(value = "campusCache",allEntries = true) //新增数据后,删除对应的缓存数据
@PostMapping("save")
public R<String> addSave(@RequestBody Campus campus){
//调用业务层的方法进行保存
Boolean insert = this.campusService.save(campus);
if(insert){
return R.success("数据保存成功!");
}else {
return R.error("数据保存失败!");
}
}
/**
* 根据id查询单条数据,用于数据回显
*
* @param id
* @return
*/
@RequestMapping("toAdd")
public ModelAndView toAdd(ModelAndView modelAndView) {
//转发页面,如果自关联、一对多、多对多,可以模仿系统管理部分的方法
modelAndView.setViewName("WEB-INF/pages/school/campus/add");
return modelAndView;
@ApiOperation(value = "根据id查询单条数据")
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "选中的校区id",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("findById")
public R<Campus> findById(@RequestParam(value = "id") String id) {
//如果传入的数据不为空,则开始查询
if (ObjectUtil.isNotEmpty(id)) {
Campus campus = this.campusService.findOne(id);
if (ObjectUtil.isNotEmpty(campus)) {
return R.success(campus);
}
}
return R.error("未查询到要修改的数据!");
}
/**
* 新增保存数据的方法
* @param modelAndView 视图对象
* @param param 前端FROM表单提交数据
* @return 返回视图对象
* 修数据的方法
* @return
*/
@RequestMapping("save")
public ModelAndView insert(ModelAndView modelAndView, @RequestParam Map<String, String> param){
@ApiOperation(value = "修改加盟校数据")
@ApiImplicitParams({@ApiImplicitParam(name = "campus",value = "修改的加盟校数据",required = true)}) //knife4j注解,用于对接口参数进行说明
@CacheEvict(value = "campusCache",allEntries = true)
@PutMapping("edit")
public R<String> edit(@RequestBody Campus campus){
try {
//使用HuTool下的插件,进行map属性注入
Campus campus = BeanUtil.fillBeanWithMap(param, new Campus(), false);
//调用业务层的方法进行数据插入
Boolean insert = this.campusService.insert(campus);
if(!insert){
//写入错误信息
modelAndView.addObject("error","业务层返回数据保存失败!");
//转发页面
modelAndView.setViewName("WEB-INF/pages/school/campus/add");
}else {
//返回页面,请求重定向到列表页
modelAndView.setViewName("redirect:/school/campus/list");
}
return modelAndView;
Boolean update = this.campusService.update(campus);
return R.success("数据修改成功!");
} catch (Exception exception) {
//记录日志
this.loggerService.saveLogAndUser(this.getClass().getName(), //获取当前类名及类数据
this.loggerService.saveLog(this.getClass().getName(), //获取当前类名及类数据
Thread.currentThread().getStackTrace()[1].getMethodName(), //获取当前方法名
this.getAdmin().getName(), //获取当前登录的用户名
exception, "新增校区数据"); //功能中文描述
log.error("后台工程出现异常!异常信息为:" + exception);
exception, "");
log.error("后台工程:controller.CampusController出现异常!异常信息为:" + exception);
}
//出现异常,返回错误信息
//写入错误信息
modelAndView.addObject("error","控制层返回数据保存失败!");
//转发页面继续回到新增页
modelAndView.setViewName("WEB-INF/pages/school/campus/add");
return modelAndView;
return R.error("数据修改失败!");
}
/**
* 根据id删除数据的方法
*
* @param modelAndView
* @param id
* @param ids
* @return
*/
@RequestMapping("delete")
public ModelAndView delete(ModelAndView modelAndView, @RequestParam("id") String id) {
@ApiOperation(value = "根据id删除数据的方法")
@ApiImplicitParams({@ApiImplicitParam(name = "ids",value = "选中的加盟校id集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@CacheEvict(value = "campusCache",allEntries = true)
@PostMapping("delete")
public R<String> delete(@RequestParam("ids") List<String> ids) {
try {
//调用业务层的删除方法
Boolean delete = this.campusService.deleteById(id);
Boolean delete = this.campusService.removeByIds(ids);
//判断业务层返回的状态
if(!delete){
//写入错误数据
modelAndView.addObject("error","数据删除失败!");
}
//返回页面,请求重定向到列表页
modelAndView.setViewName("redirect:/school/campus/list");
return modelAndView;
} catch (Exception exception) {
//记录日志
this.loggerService.saveLogAndUser(this.getClass().getName(), //获取当前类名及类数据
Thread.currentThread().getStackTrace()[1].getMethodName(), //获取当前方法名
this.getAdmin().getName(), //获取当前登录的用户名
exception, "删除校区数据"); //功能中文描述
log.error("后台工程出现异常!异常信息为:" + exception);
}
//出现异常,返回错误信息
modelAndView.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
return modelAndView;
}
/**
* 跳转到修改数据页面的方法
*
* @param modelAndView
* @param id
* @return
*/
@RequestMapping("toEdit")
public ModelAndView toEdit(ModelAndView modelAndView, @RequestParam("id") String id) {
//01.数据回显
if (ObjectUtil.isNotEmpty(id)) {
Campus campus = this.campusService.findOne(id);
if (ObjectUtil.isNotEmpty(campus)) {
//将数据写入
modelAndView.addObject("campus", campus);
return R.error("数据删除失败!");
}
}
//02.请求重定向到修改页面
modelAndView.setViewName("WEB-INF/pages/school/campus/update");
return modelAndView;
}
/**
* 保存修改后数据的方法
*
* @return
*/
@RequestMapping("edit")
public ModelAndView edit(ModelAndView modelAndView, @RequestParam Map<String, Object> param) {
try {
//使用hutool下的插件,进行map属性注入
Campus campus = BeanUtil.fillBeanWithMap(param, new Campus(), false);
//调用业务层的方法进行数据插入
Boolean update = this.campusService.update(campus);
//返回页面,请求重定向到列表页
modelAndView.setViewName("redirect:/school/campus/list");
return modelAndView;
return R.success("数据删除成功!");
} catch (Exception exception) {
//记录日志
this.loggerService.saveLogAndUser(this.getClass().getName(), //获取当前类名及类数据
this.loggerService.saveLog(this.getClass().getName(), //获取当前类名及类数据
Thread.currentThread().getStackTrace()[1].getMethodName(), //获取当前方法名
this.getAdmin().getName(), //获取当前登录的用户名
exception, "保存校区修改"); //功能中文描述
log.error("后台工程出现异常!异常信息为:" + exception);
exception, "");
log.error("后台工程:controller.CampusController出现异常!异常信息为:" + exception);
}
//出现异常,返回错误信息
modelAndView.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
return modelAndView;
return R.error("数据删除失败!");
}
/**
* 获取当前登录用户信息的方法
*
* @return 返回当前登录的用户对象
*/
public Admin getAdmin(){
public Admin getAdmin() {
return AdminThreadLocal.get();
}
}
......@@ -15,6 +15,10 @@ import com.template.back.server.service.system.AdminService;
import com.template.back.server.service.system.DeptService;
import com.template.back.server.service.system.ModuleService;
import com.template.back.server.service.system.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......@@ -28,6 +32,7 @@ import java.util.Map;
* @version 1.0.0
* 管理员控制层代码
*/
@Api(tags = "后台用户相关接口") //knife4j注解,用于自动生成api文档
@RestController //注解为restful风格controller
@RequestMapping("system/user")
@Slf4j
......@@ -56,6 +61,10 @@ public class AdminController {
*
* @return 返回页面重定向地址
*/
@ApiOperation(value = "后台用户登录接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
@ApiImplicitParam(name = "map",value = "用户信息 userName-用户名 password-密码",required = true)
}) //knife4j注解,用于对接口参数进行说明
@NoAuthorization //不需要验证登录
@PostMapping("/login")
public R<Admin> login(@RequestBody Map<String, String> map, HttpServletRequest req) {
......@@ -100,6 +109,9 @@ public class AdminController {
*
* @return
*/
@ApiOperation(value = "加载用户权限菜单接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
}) //knife4j注解,用于对接口参数进行说明
@PostMapping("author")
public R<List<Module>> queryAuthor(HttpServletRequest request) {
//01.获取当前登录的用户信息
......@@ -132,6 +144,9 @@ public class AdminController {
* @param req
* @return
*/
@ApiOperation(value = "后台用户退出接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
}) //knife4j注解,用于对接口参数进行说明
@PostMapping("logout")
public R<String> logout(HttpServletRequest req) {
//删除请求域的数据
......@@ -149,6 +164,12 @@ public class AdminController {
* @param name 查询的条件
* @return
*/
@ApiOperation(value = "查询后台用户列表接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
@ApiImplicitParam(name = "page",value = "当前页码",required = true,defaultValue = "1"),
@ApiImplicitParam(name = "pageSize",value = "每页数据长度",required = true,defaultValue = "10"),
@ApiImplicitParam(name = "name",value = "根据用户姓名查询",required = false)
}) //knife4j注解,用于对接口参数进行说明
@GetMapping("page")
public R<Page> list(@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
......@@ -176,8 +197,10 @@ public class AdminController {
* @param admin
* @return
*/
@ApiOperation(value = "新增后台用户接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "admin",value = "新增的后台用户",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("save")
public R<String> insert(@RequestBody Admin admin) {
public R<String> addSave(@RequestBody Admin admin) {
try {
//1.这里需要验证用户名唯一,根据用户名查询数据
Admin login = this.adminService.login(admin.getUserName());
......@@ -213,6 +236,8 @@ public class AdminController {
* @param ids
* @return
*/
@ApiOperation(value = "删除后台用户接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "ids",value = "选中的课程id集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("delete")
public R<String> delete(@RequestParam("ids") List<Long> ids) {
try {
......@@ -235,14 +260,7 @@ public class AdminController {
return R.error("数据删除失败!");
}
/**
* 获取当前登录用户信息的方法
*
* @return 返回当前登录的用户对象
*/
public Admin getAdmin() {
return AdminThreadLocal.get();
}
/**
* 根据id查询单个的方法
......@@ -250,6 +268,8 @@ public class AdminController {
* @param id
* @return
*/
@ApiOperation(value = "根据id查询单条数据接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "选中的用户id",required = true)}) //knife4j注解,用于对接口参数进行说明
@GetMapping("/findById")
public R<Admin> findById(@RequestParam("id") Long id) {
//01.数据回显
......@@ -269,8 +289,10 @@ public class AdminController {
*
* @return
*/
@ApiOperation(value = "修改后台用户接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "admin",value = "修改的后台用户",required = true)}) //knife4j注解,用于对接口参数进行说明
@PutMapping("edit")
public R<String> edit(@RequestBody Admin admin) {
public R<String> update(@RequestBody Admin admin) {
try {
//调用业务层的方法进行数据插入
Boolean update = this.adminService.update(admin);
......@@ -291,6 +313,8 @@ public class AdminController {
*
* @return
*/
@ApiOperation(value = "根据用户查询角色接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "后台用户id",required = true)}) //knife4j注解,用于对接口参数进行说明
@GetMapping("userRoleList")
public R<List<Role>> userRoleList(@RequestParam("id") Long id) {
//数据回显
......@@ -307,6 +331,8 @@ public class AdminController {
*
* @return
*/
@ApiOperation(value = "根据用户查询角色接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "map",value = "adminId-后台用户id roles-选中的角色集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("/updateRole")
public R<String> updateRole(@RequestBody Map map) {
//调取业务层的方法
......@@ -315,4 +341,13 @@ public class AdminController {
return R.success("用户授权成功!");
}
/**
* 获取当前登录用户信息的方法
*
* @return 返回当前登录的用户对象
*/
public Admin getAdmin() {
return AdminThreadLocal.get();
}
}
......@@ -9,6 +9,10 @@ import com.template.back.common.service.LoggerService;
import com.template.back.common.vo.R;
import com.template.back.server.service.system.AdminService;
import com.template.back.server.service.system.DeptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......@@ -21,6 +25,7 @@ import java.util.List;
* 部门管理控制层程序
* 更新日志:前端更换为html页面,使用json格式数据进行交互,后端进行对应更改
*/
@Api(tags = "后台部门相关接口") //knife4j注解,用于自动生成api文档
@RestController //标记为控制层
@RequestMapping("/system/dept") //定义请求映射路径
@Slf4j //注解日志
......@@ -43,6 +48,12 @@ public class DeptController {
* @param pageSize 每页的数据长度
* @return
*/
@ApiOperation(value = "查询部门列表接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
@ApiImplicitParam(name = "page",value = "当前页码",required = true,defaultValue = "1"),
@ApiImplicitParam(name = "pageSize",value = "每页数据长度",required = true,defaultValue = "10"),
@ApiImplicitParam(name = "deptName",value = "部门名称",required = false)
}) //knife4j注解,用于对接口参数进行说明
@GetMapping("page")
public R<Page> list(@RequestParam(value = "page",defaultValue = "1")Integer page,
@RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
......@@ -68,6 +79,8 @@ public class DeptController {
*
* @return
*/
@ApiOperation(value = "新增部门接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "dept",value = "新增的部门",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("save")
public R<String> addSave(@RequestBody Dept dept) {
try {
......@@ -92,6 +105,8 @@ public class DeptController {
* @param ids
* @return
*/
@ApiOperation(value = "删除部门接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "ids",value = "选中的部门id集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("delete")
public R<String> delete(@RequestParam("ids") List<Long> ids) {
try {
......@@ -127,6 +142,8 @@ public class DeptController {
* @param id
* @return
*/
@ApiOperation(value = "根据id查询单条数据接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "选中的部门id",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("/findById")
public R<Dept> findById(@RequestParam("id") Long id) {
//01.数据回显
......@@ -146,8 +163,10 @@ public class DeptController {
* 保存修改后数据的方法
* @return
*/
@ApiOperation(value = "修改部门接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "dept",value = "修改的部门",required = true)}) //knife4j注解,用于对接口参数进行说明
@PutMapping("edit")
public R<String> edit(@RequestBody Dept dept){
public R<String> update(@RequestBody Dept dept){
try {
//调用业务层的方法进行数据插入
Boolean update = this.deptService.update(dept);
......@@ -168,6 +187,7 @@ public class DeptController {
* 查询列表的方法
* @return
*/
@ApiOperation(value = "查询全部部门接口") //knife4j注解,用于对接口方法进行说明
@GetMapping("/list")
public R<List<Dept>> list(){
//01.调用业务层方法
......
......@@ -3,6 +3,10 @@ package com.template.back.server.controller.system;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.template.back.common.service.LoggerService;
import com.template.back.common.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -14,6 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
* @author 张骞
* 自定义日志控制层
*/
@Api(tags = "后台日志相关接口") //knife4j注解,用于自动生成api文档
@RestController
@RequestMapping("system/logger")
@Slf4j
......@@ -29,6 +34,11 @@ public class LoggerController {
* 查看日志列表的功能
* @return
*/
@ApiOperation(value = "查询日志列表接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
@ApiImplicitParam(name = "page",value = "当前页码",required = true,defaultValue = "1"),
@ApiImplicitParam(name = "pageSize",value = "每页数据长度",required = true,defaultValue = "10")
}) //knife4j注解,用于对接口参数进行说明
@GetMapping("page")
public R<Page> loggerList(@RequestParam(value = "page",defaultValue = "1")Integer page,
@RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize
......
......@@ -11,6 +11,10 @@ import com.template.back.common.utils.AdminThreadLocal;
import com.template.back.common.vo.R;
import com.template.back.server.service.system.ModuleService;
import com.template.back.server.service.system.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......@@ -23,6 +27,7 @@ import java.util.List;
* 模块管理控制层程序
* 更新日志:前端更换为html页面,使用json格式数据进行交互,后端进行对应更改
*/
@Api(tags = "功能模块相关接口") //knife4j注解,用于自动生成api文档
@RestController //标记为控制层
@RequestMapping("/system/module") //定义请求映射路径
@Slf4j //注解日志
......@@ -46,6 +51,12 @@ public class ModuleController {
* @param name
* @return
*/
@ApiOperation(value = "查询模块列表接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
@ApiImplicitParam(name = "page",value = "当前页码",required = true,defaultValue = "1"),
@ApiImplicitParam(name = "pageSize",value = "每页数据长度",required = true,defaultValue = "10"),
@ApiImplicitParam(name = "name",value = "模块名称",required = false)
}) //knife4j注解,用于对接口参数进行说明
@GetMapping("page")
public R<Page> list(@RequestParam(value = "page",defaultValue = "1")Integer page,
@RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
......@@ -71,8 +82,10 @@ public class ModuleController {
* @param module
* @return
*/
@ApiOperation(value = "新增模块接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "module",value = "新增的模块",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("save")
public R<String> insert(@RequestBody Module module){
public R<String> addSave(@RequestBody Module module){
try {
//调用业务层的方法进行数据插入
Boolean insert = this.moduleService.insert(module);
......@@ -95,19 +108,15 @@ public class ModuleController {
return R.error("数据保存失败!");
}
/**
* 获取当前登录用户信息的方法
* @return 返回当前登录的用户对象
*/
public Admin getAdmin(){
return AdminThreadLocal.get();
}
/**
* 根据id集合删除数据的方法
* @param ids
* @return
*/
@ApiOperation(value = "删除模块接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "ids",value = "选中的模块id集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("delete")
public R<String> delete(@RequestParam("ids") List<Long> ids) {
try {
......@@ -151,6 +160,8 @@ public class ModuleController {
* @param id
* @return
*/
@ApiOperation(value = "根据id查询单条数据接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "选中的模块id",required = true)}) //knife4j注解,用于对接口参数进行说明
@GetMapping("/findById")
public R<Module> findById(@RequestParam("id") Long id) {
//01.数据回显
......@@ -169,8 +180,10 @@ public class ModuleController {
* 保存修改后数据的方法
* @return
*/
@ApiOperation(value = "修改后台用户接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "module",value = "修改的模块",required = true)}) //knife4j注解,用于对接口参数进行说明
@PutMapping("edit")
public R<String> edit(@RequestBody Module module){
public R<String> update(@RequestBody Module module){
try {
//调用业务层的方法进行数据插入
Boolean update = this.moduleService.update(module);
......@@ -191,6 +204,7 @@ public class ModuleController {
* 查询列表的方法
* @return
*/
@ApiOperation(value = "查询全部模块接口") //knife4j注解,用于对接口方法进行说明
@GetMapping("/list")
public R<List<Module>> list(){
//01.调用业务层方法
......@@ -199,5 +213,12 @@ public class ModuleController {
return R.success(moduleList);
}
/**
* 获取当前登录用户信息的方法
* @return 返回当前登录的用户对象
*/
public Admin getAdmin(){
return AdminThreadLocal.get();
}
}
......@@ -11,6 +11,10 @@ import com.template.back.common.vo.TreeVo;
import com.template.back.server.service.system.AdminService;
import com.template.back.server.service.system.ModuleService;
import com.template.back.server.service.system.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
......@@ -25,6 +29,7 @@ import java.util.Map;
* 角色管理控制层程序
* 更新日志:前端更换为html页面,使用json格式数据进行交互,后端进行对应更改
*/
@Api(tags = "角色相关接口") //knife4j注解,用于自动生成api文档
@RestController //标记为控制层
@RequestMapping("/system/role") //定义请求映射路径
@Slf4j //注解日志
......@@ -52,6 +57,12 @@ public class RoleController {
* @param name //前端传入的查询条件
* @return
*/
@ApiOperation(value = "查询角色列表接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
@ApiImplicitParam(name = "page",value = "当前页码",required = true,defaultValue = "1"),
@ApiImplicitParam(name = "pageSize",value = "每页数据长度",required = true,defaultValue = "10"),
@ApiImplicitParam(name = "name",value = "角色名称",required = false)
}) //knife4j注解,用于对接口参数进行说明
@GetMapping("page")
public R<Page> list(@RequestParam(value = "page",defaultValue = "1")Integer page,
@RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
......@@ -78,6 +89,8 @@ public class RoleController {
* @param role
* @return
*/
@ApiOperation(value = "新增角色接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "role",value = "新增的角色",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("save")
public R<String> addSave(@RequestBody Role role) {
try {
......@@ -101,6 +114,8 @@ public class RoleController {
* @param ids
* @return
*/
@ApiOperation(value = "删除后台用户接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "ids",value = "选中的角色id集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("delete")
public R<String> delete(@RequestParam("ids") List<Long> ids) {
try {
......@@ -138,6 +153,8 @@ public class RoleController {
* @param id
* @return
*/
@ApiOperation(value = "根据id查询单条数据接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "选中的角色id",required = true)}) //knife4j注解,用于对接口参数进行说明
@GetMapping("/findById")
public R<Role> findById(@RequestParam("id") Long id) {
//01.数据回显
......@@ -156,6 +173,8 @@ public class RoleController {
* 保存修改后数据的方法
* @return
*/
@ApiOperation(value = "修改角色接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "role",value = "修改的角色",required = true)}) //knife4j注解,用于对接口参数进行说明
@PutMapping("edit")
public R<String> edit(@RequestBody Role role) {
try {
......@@ -180,6 +199,8 @@ public class RoleController {
*
* @return
*/
@ApiOperation(value = "查询角色授权接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "选中的角色id",required = true)}) //knife4j注解,用于对接口参数进行说明
@GetMapping("author")
public R<Map> author(@RequestParam("id") Long roleId) {
try {
......@@ -205,6 +226,8 @@ public class RoleController {
* 保存授权数据
* @return
*/
@ApiOperation(value = "保存角色授权接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "map",value = "st-选中的角色id checkedArray-选中的模块集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@PutMapping("updateRoleModule")
public R<String> updateRoleModule(@RequestBody Map map) {
//解析前台传入的数据
......
......@@ -6,6 +6,10 @@ import com.template.back.common.pojo.system.Setting;
import com.template.back.common.service.LoggerService;
import com.template.back.common.vo.R;
import com.template.back.server.service.system.SettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......@@ -17,6 +21,7 @@ import java.util.List;
* @version 1.0
* 自定义设置管理控制层程序,设置内容以键值对的形式存在
*/
@Api(tags = "自定义设置相关接口") //knife4j注解,用于自动生成api文档
@RestController //标记为控制层
@RequestMapping("/system/setting") //定义请求映射路径
@Slf4j //注解日志
......@@ -36,6 +41,12 @@ public class SettingController {
* @param name
* @return
*/
@ApiOperation(value = "查询设置列表接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({
@ApiImplicitParam(name = "page",value = "当前页码",required = true,defaultValue = "1"),
@ApiImplicitParam(name = "pageSize",value = "每页数据长度",required = true,defaultValue = "10"),
@ApiImplicitParam(name = "name",value = "设置名称",required = false)
}) //knife4j注解,用于对接口参数进行说明
@GetMapping("page")
public R<Page> list(@RequestParam(value = "page",defaultValue = "1")Integer page,
@RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
......@@ -63,6 +74,8 @@ public class SettingController {
* @param setting
* @return
*/
@ApiOperation(value = "新增设置接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "setting",value = "新增的设置参数",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("save")
public R<String> addSave(@RequestBody Setting setting) {
try {
......@@ -86,6 +99,8 @@ public class SettingController {
* @param ids
* @return
*/
@ApiOperation(value = "删除后台用户接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "ids",value = "选中的设置id集合",required = true)}) //knife4j注解,用于对接口参数进行说明
@PostMapping("delete")
public R<String> delete(@RequestParam("ids") List<Long> ids) {
try {
......@@ -114,6 +129,8 @@ public class SettingController {
* @param id
* @return
*/
@ApiOperation(value = "根据id查询单条数据接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "选中的设置id",required = true)}) //knife4j注解,用于对接口参数进行说明
@GetMapping("/findById")
public R<Setting> findById(@RequestParam("id") Long id) {
//01.数据回显
......@@ -131,8 +148,10 @@ public class SettingController {
* 保存修改后数据的方法
* @return
*/
@ApiOperation(value = "修改设置接口") //knife4j注解,用于对接口方法进行说明
@ApiImplicitParams({@ApiImplicitParam(name = "setting",value = "修改的设置",required = true)}) //knife4j注解,用于对接口参数进行说明
@PutMapping("edit")
public R<String> edit(@RequestBody Setting setting){
public R<String> update(@RequestBody Setting setting){
try {
//调用业务层的方法进行数据插入
Boolean update = this.settingService.update(setting);
......
package com.template.back.server.controller.system;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.text.DateFormat;
......@@ -13,11 +16,13 @@ import java.util.Date;
* @version 1.0.0
* 测试控制层代码
*/
@Api(tags = "测试相关接口") //knife4j注解,用于自动生成api文档
@Controller
@Slf4j
public class TestController {
@RequestMapping("/hello")
@ApiOperation(value = "测试接口") //knife4j注解,用于对接口方法进行说明
@GetMapping("/hello")
public String hello(Model m){
m.addAttribute("now", DateFormat.getDateTimeInstance().format(new Date()));
return "login"; //视图重定向hello.jsp
......
package com.template.back.server.filter;
import com.alibaba.fastjson.JSON;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.utils.AdminThreadLocal;
import com.template.back.common.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 张骞
* @version 1.0.0
* 用户登录过滤器,拦截器使用有些问题,所以使用过滤器
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//创建路径匹配器对象
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//01.获取本次请求的URI
String url = request.getRequestURI();
//log.info("拦截到请求:{}", url);
//02.判断本次请求, 是否需要登录, 才可以访问
//2.1定义不需要过滤的数组
String[] urls = new String[]{
"/system/user/login",
"/system/user//logout",
"/backend/**",
"/common/**",
"/upload/**",
"/backend/pages/login/login.html"
};
//2.2使用私有方法进行请求匹配
Boolean check = this.check(urls, url);
//03.如果不需要,则直接放行
if (check) {
//log.info("本次请求{}不需要进行登录拦截", url);
filterChain.doFilter(request,response);
return;
}
//04-1.判断后台用户登录状态,如果已登录,则直接放行
Admin admin = (Admin) request.getSession().getAttribute("admin");
if (null != admin) {
log.info("用户已登录,用户id为:{}", request.getSession().getAttribute("admin"));
//将登录的用户id放入ThreadLocal
AdminThreadLocal.set(admin);
//log.info("过滤器层返回数据:后台用户校验成功!");
//放行操作
filterChain.doFilter(request,response);
return;
}
//05.如果未登录, 则返回未登录结果
log.info("当前用户未登录!");
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
//返回false,如果返回true的话,write方法会报错
return;
}
/**
* 路径匹配,检查本次请求是否需要放行
*
* @param urls
* @param uri
* @return
*/
private Boolean check(String[] urls, String uri) {
//01.遍历要放行的请求集合
for (String url : urls) {
//02.调用请求匹配器的方法
boolean match = PATH_MATCHER.match(url, uri);
//03.如果匹配,返回true
if (match) {
return true;
}
}
//04.如果不匹配,返回false
return false;
}
}
package com.template.back.server.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.utils.AdminThreadLocal;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
......@@ -30,6 +32,12 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
//如果字段为空,则填充更新字段
setFieldValByName("updated",LocalDateTime.now(),metaObject);
}
//处理pojo的更新人字段
setFieldValByName("operator_name",getAdmin().getName(),metaObject);
//处理pojo的更新人id字段
setFieldValByName("operator_id",getAdmin().getAdminId(),metaObject);
}
//更新数据时的方法
......@@ -37,5 +45,18 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
public void updateFill(MetaObject metaObject) {
//无论数据是否为空,每次更新,均更新该字段
setFieldValByName("updated",LocalDateTime.now(),metaObject);
//处理pojo的更新人字段
setFieldValByName("operator_name",getAdmin().getName(),metaObject);
//处理pojo的更新人id字段
setFieldValByName("operator_id",getAdmin().getAdminId(),metaObject);
}
/**
* 获取当前登录用户的方法
*/
private Admin getAdmin(){
return AdminThreadLocal.get();
}
}
package com.template.back.server.interceptor;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.utils.AdminThreadLocal;
import com.template.back.common.utils.NoAuthorization;
import com.template.back.common.vo.R;
import com.template.back.server.service.system.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
......@@ -23,14 +27,24 @@ import javax.servlet.http.HttpServletResponse;
@Component //注解加载到spring容器中
@Slf4j //日志注解
public class AdminLoginInterceptor implements HandlerInterceptor {
//knife4j框架的doc文档地址开关
@Value("${doc-interceptor-state}")
private Boolean docState;
//注入业务层对象,用来验证用户登录信息
@Autowired
private AdminService adminService;
//创建路径匹配器对象
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
//注入redis模板类,用于每次验证写入用户登录信息
@Autowired
private RedisTemplate<String,String> redisTemplate;
private static String sessionId = null;
/**
* 请求的前置处理,将User对象写入到ThreadLocal中
*
......@@ -42,6 +56,13 @@ public class AdminLoginInterceptor implements HandlerInterceptor {
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//00.获取sessionId
sessionId = request.getSession().getId();
//01.获取本次请求的URI
String url = request.getRequestURI();
log.info("拦截到请求:{}", url);
//将Admin对象写入到ThreadLocal中
//校验当前的Handler
if (!(handler instanceof HandlerMethod)) {
......@@ -62,6 +83,53 @@ public class AdminLoginInterceptor implements HandlerInterceptor {
}
}
//2-3.对knife4j框架
String[] docUrls = new String[]{
"/doc.html", //从这里开始,是swagger框架过滤使用
"/webjars/**",
"/swagger-resources",
"/v2/api-docs"
};
//2-3-2使用私有方法进行请求匹配
Boolean docCheck = this.check(docUrls, url);
//2-3-3如果不需要,则直接放行
if (docCheck) {
log.info("拦截到knife4j请求{}", url);
//判断配置文件的状态,如果为true,则放行,否则不放行
if(docState){
return true;
}else {
//如果配置文件为false,则始终返回false
return false;
}
}
//2-4.判断本次请求, 是否需要登录, 才可以访问
//2-4-1定义需要过滤的数组
String[] urls = new String[]{
"/system/user/login",
"/system/user/logout",
"/backend/**",
"/common/**",
"/upload/**",
"/backend/pages/login/login.html",
"/",
"error.jsp",
"*.js",
"*.css"
};
//2-4-2使用私有方法进行请求匹配
Boolean check = this.check(urls, url);
//2-4-3如果不需要,则直接放行
if (check) {
log.info("本次请求{}不需要进行登录拦截", url);
return true;
}
//01.从session中拿到当前登录的用户数据
Admin admin = (Admin) request.getSession().getAttribute("admin");
//02.验证数据是否为空,如果不为空,则在数据库中查询用户信息
......@@ -72,7 +140,8 @@ public class AdminLoginInterceptor implements HandlerInterceptor {
if(null != admin1){
//用户验证成功,写入数据
AdminThreadLocal.set(admin1);
//将用户登录的状态数据写入redis
//04-3-2重新写入session,为session延时
request.getSession().setAttribute("admin", admin);
log.info("过滤器层返回数据:后台用户校验成功!");
return true;
}
......@@ -80,7 +149,8 @@ public class AdminLoginInterceptor implements HandlerInterceptor {
}
//03用户状态验证失败,返回到登录页面
response.sendRedirect(request.getContextPath() + "/backend/pages/login/login.html");
// response.sendRedirect(request.getContextPath() + "/backend/pages/login/login.html");
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
log.error("过滤器层返回数据:用户登录验证失败!");
return false;
}
......@@ -99,6 +169,27 @@ public class AdminLoginInterceptor implements HandlerInterceptor {
AdminThreadLocal.remove();
//把登录状态信息从redis中删除
}
/**
* 路径匹配,检查本次请求是否需要放行
*
* @param urls
* @param uri
* @return
*/
private Boolean check(String[] urls, String uri) {
//01.遍历要放行的请求集合
for (String url : urls) {
//02.调用请求匹配器的方法
boolean match = PATH_MATCHER.match(url, uri);
//03.如果匹配,返回true
if (match) {
return true;
}
}
//04.如果不匹配,返回false
return false;
}
}
package com.template.back.server.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.template.back.common.utils.CaChe;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.concurrent.TimeUnit;
/**
* @author 张骞
* @version 1.0
* 缓存响应及写入功能
*/
@ControllerAdvice
@Slf4j
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
@Value("${tanhua.cache.enable}") //注入全局变量的设置值
private Boolean enable;
@Autowired //注入redis模板类
private RedisTemplate<String,String> redisTemplate;
//序列化对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 判断当前全局设置是否支持本操作
* @param methodParameter
* @param aClass
* @return
*/
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
//需要判断三个条件:配置文件中全局开关处于开启状态;是get请求;包含了@Cache注解
//三个条件同时满足,flag为true
boolean flag = enable && methodParameter.hasMethodAnnotation(GetMapping.class) && methodParameter.hasMethodAnnotation(CaChe.class);
return flag;
}
/**
* 输出之前的操作,缓存未命中的话,在这里重新写入缓存
* @param o 返回的数据
* @param methodParameter
* @param mediaType
* @param aClass
* @param serverHttpRequest
* @param serverHttpResponse
* @return
*/
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
//如果传入的数据为空,则不需要处理
if(null == o){
return null;
}
try{
//将数据写入缓存
String redisValue = null;
//判断o的类型是不是String类型
if(o instanceof String){
redisValue = (String) o;
}else {
String string = MAPPER.writeValueAsString(o);
redisValue = string;
}
//调用拦截器的方法,生成redisKey
String redisKey = RedisCacheInterceptor.createRedisKey(((ServletServerHttpRequest)serverHttpRequest).getServletRequest());
//获取超时时间
CaChe caChe = methodParameter.getMethodAnnotation(CaChe.class);
//缓存的时间单位是秒
this.redisTemplate.opsForValue().set(redisKey,redisValue,Long.valueOf(caChe.time()), TimeUnit.SECONDS);
//输出日志
log.info("数据已经写入缓存!");
}catch (Exception exception){
log.error("将数据写入缓存失败!错误详情:"+exception);
}
return o;
}
}
package com.template.back.server.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.template.back.common.utils.CaChe;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 张骞
* @version 1.0
* 缓存过滤功能
*/
@Component //注解为Spring的bean进行管理
@Slf4j
public class RedisCacheInterceptor implements HandlerInterceptor {
@Value("${tanhua.cache.enable}") //注入配置文件中的全局缓存开关数据
private Boolean enable;
@Autowired //注入redis模板类,对缓存进行操作
private RedisTemplate<String, String> redisTemplate;
//对数据进行序列化
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 请求的前置处理,起到拦截并且写入缓存的作用
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//设置缓存全局开关校验
if (!enable) {
return true; //如果开关没有开启,则直接返回true,进行放行
}
//校验当前的Handler
if (!(handler instanceof HandlerMethod)) {
return true;
}
//判断当前请求是否为get
if (!((HandlerMethod) handler).hasMethodAnnotation(GetMapping.class)) {
return true;
}
//判断当前请求是否添加了Cache注解
if (!((HandlerMethod) handler).hasMethodAnnotation(CaChe.class)) {
return true;
}
//缓存命中
//根据方法生成redisKey
String redisKey = createRedisKey(request);
//根据redisKey进行数据查询
String cacheData = this.redisTemplate.opsForValue().get(redisKey);
//如果查询的数据为空,表示缓存没有命中
if(StringUtils.isEmpty(cacheData)){
log.info("当前请求没有命中缓存!");
return true;
}
//如果缓存命中,进行输出
//设置字符集及数据信息
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
//输出查询的数据
response.getWriter().write(cacheData);
log.info("当前请求已经命中缓存!");
return false; //默认返回false,意味着进行拦截
}
/**
* 生成redis中的key,规则:SERVER_CACHE_DATA_MD5(url + param + token)
*
* @param request
* @return
*/
public static String createRedisKey(HttpServletRequest request) throws Exception {
String url = request.getRequestURI(); //请求的url
//Map<String, String[]> parameterMap = request.getParameterMap();
String param = MAPPER.writeValueAsString(request.getParameterMap()); //请求的param
String token = request.getHeader("Authorization"); //从请求头中拿到token数据
String data = url + "_" + param + "_" + token;
return "SERVER_CACHE_DATA_" + DigestUtils.md5Hex(data);
}
}
package com.template.back.server.service.school;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.template.back.common.pojo.school.Campus;
import org.eclipse.jdt.internal.compiler.env.IModule;
/**
* @author 张骞
* @version 1.0.1
* 校区管理业务层约束接口
*/
public interface CampusService {
public interface CampusService extends IService<Campus> {
/**
* 分页查询的方法
* @param page 当前页码,默认1
* @param pageSize 当前页码,默认12
* @return 返回自定义的分页VO数据
*/
Page findPage(Integer page, Integer pageSize);
/**
* 新增数据的方法
* @param campus
* @return
* @param campusName 根据校区名称查询条件
* @param address 根据校区地址查询条件
* @param startData 根据开始日期查询条件
* @param endData 根据结束日期查询条件
* @return 返回自定义的分页VO数据
*/
Boolean insert(Campus campus);
Page findPage(Integer page, Integer pageSize,String campusName,String address, String startData, String endData);
/**
* 根据id删除数据的方法
......
package com.template.back.server.service.school.Impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.template.back.common.mapper.school.CampusMapper;
import com.template.back.common.pojo.school.Campus;
import com.template.back.common.pojo.system.Admin;
......@@ -12,13 +16,17 @@ import com.template.back.server.service.school.CampusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
* @author 张骞
* @version 1.0.1
* 校区管理业务层
*/
@Service //注解为spring管理的业务层
public class CampusServiceImpl implements CampusService {
public class CampusServiceImpl extends ServiceImpl<CampusMapper,Campus> implements CampusService {
//注入mapper接口
@Autowired
private CampusMapper campusMapper;
......@@ -27,44 +35,47 @@ public class CampusServiceImpl implements CampusService {
* 分页查询的方法
* @param page 当前页码,默认1
* @param pageSize 当前页码,默认12
* @return 返回自定义的分页VO数据
* @param campusName 根据校区名称查询条件
* @param address 根据校区地址查询条件
* @param startData 根据开始日期查询条件
* @param endData 根据结束日期查询条件
* @return 返回自定义的分页VO数据
*/
@Override
public Page findPage(Integer page, Integer pageSize) {
public Page findPage(Integer page, Integer pageSize,String campusName,String address, String startData, String endData) {
//01.配置MP的查询条件,根据时间排序
QueryWrapper<Campus> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("created");
LambdaQueryWrapper<Campus> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByDesc(Campus::getCreated);
//1.1根据校区名称查询
if(StrUtil.isNotEmpty(campusName)){
queryWrapper.like(Campus::getName,campusName);
}
//2.4构造根据起止日期开始查询的条件,日期需要转换格式
if (StrUtil.isAllNotEmpty(startData, endData)) {
LocalDate startDate = LocalDate.parse(startData, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate endDate = LocalDate.parse(endData, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
queryWrapper.ge(Campus::getCoopTime,startDate);
queryWrapper.le(Campus::getCoopTime,endDate);
}
//02.配置分页数据
Page<Campus> campusPage = new Page<>(page, pageSize);
Page<Campus> pageCampus = new Page<>(page,pageSize);
//03.查询数据
IPage<Campus> campusIPage = this.campusMapper.selectPage(campusPage, queryWrapper);
//04.封装分页数据并返回
return campusPage;
}
IPage<Campus> campusIPage = this.campusMapper.selectPage(pageCampus, queryWrapper);
/**
* 新增数据的方法
* @param campus
* @return
*/
@Override
public Boolean insert(Campus campus) {
//对数据进行非空验证的方法
Boolean aBoolean = this.dataValidation(campus);
if(aBoolean){
//01.生成UUID(注解自动生成)
//campus.setCampusId(UUID.randomUUID().toString());
//02.获取当前操作的用户信息
Admin admin = AdminThreadLocal.get();
//03.更改当前数据的修改人信息
campus.setOperator(admin.getName());
//04.保存数据
int insert = this.campusMapper.insert(campus);
return insert == 1;
}
return false;
//04.获取数据
List<Campus> campusList = campusIPage.getRecords();
//06.封装分页数据返回
pageCampus.setRecords(campusList);
return pageCampus;
}
/**
* 根据id删除数据的方法
* @param id
......
package com.template.back.server.service.system;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.template.back.common.pojo.system.Admin;
import java.util.List;
......@@ -10,7 +11,7 @@ import java.util.List;
* @version
* 用户业务层封装类
*/
public interface AdminService {
public interface AdminService extends IService<Admin> {
/**
* 后台用户登录的校验方法
* @param username 提交的用户名
......
package com.template.back.server.service.system;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.template.back.common.pojo.system.Dept;
import java.util.List;
......@@ -10,7 +11,7 @@ import java.util.List;
* @version 1.0
* 部门管理业务层接口
*/
public interface DeptService {
public interface DeptService extends IService<Dept> {
/**
* 分页查询的方法
......
......@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.template.back.common.mapper.system.AdminMapper;
import com.template.back.common.mapper.system.DeptMapper;
import com.template.back.common.mapper.system.RoleMapper;
......@@ -28,7 +29,7 @@ import java.util.List;
*/
@Service //业务层注解
@Slf4j //控制台日志注解
public class AdminServiceImpl implements AdminService {
public class AdminServiceImpl extends ServiceImpl<AdminMapper,Admin> implements AdminService {
//TODO 管理员用户密码的保存,没有进行加密,若考虑安全问题,可以使用MD5加密
//注入自定义日志业务层
@Autowired
......@@ -191,9 +192,7 @@ public class AdminServiceImpl implements AdminService {
if (ObjectUtil.isAllNotEmpty(admin.getName(), admin.getUserName(), admin.getPassword(), admin.getState())) {
//01.获取当前操作的用户信息
Admin adminInfo = AdminThreadLocal.get();
//02.更改当前数据的修改人信息
admin.setOperator(adminInfo.getName());
//03.保存数据
//02.保存数据
int insert = this.adminMapper.insert(admin);
return insert == 1;
}
......
......@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.template.back.common.mapper.system.DeptMapper;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.pojo.system.Dept;
......@@ -23,7 +24,7 @@ import java.util.List;
*/
@Service //注解标注为Spring的业务层
@Slf4j //日志注解
public class DeptServiceImpl implements DeptService {
public class DeptServiceImpl extends ServiceImpl<DeptMapper,Dept> implements DeptService {
//注入自定义日志业务层
@Autowired
private LoggerService loggerService;
......@@ -64,9 +65,7 @@ public class DeptServiceImpl implements DeptService {
public Boolean insert(Dept dept){
//01.获取当前操作的用户信息
Admin admin = AdminThreadLocal.get();
//02.更改当前数据的修改人信息
dept.setOperator(admin.getName());
//03.保存数据
//02.保存数据
int insert = this.deptMapper.insert(dept);
return insert == 1;
}
......
......@@ -3,6 +3,7 @@ package com.template.back.server.service.system.Impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.template.back.common.mapper.system.LoggerMapper;
import com.template.back.common.pojo.system.Logger;
import com.template.back.server.service.system.LoggerService;
......@@ -13,7 +14,7 @@ import org.springframework.stereotype.Service;
@Service
@Slf4j
public class LoggerServiceImpl implements LoggerService {
public class LoggerServiceImpl extends ServiceImpl<LoggerMapper,Logger> implements LoggerService {
//注入自定义日志业务层
@Autowired
private LoggerService loggerService;
......
......@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.template.back.common.mapper.system.ModuleMapper;
import com.template.back.common.mapper.system.RoleMapper;
import com.template.back.common.pojo.system.Admin;
......@@ -25,7 +26,7 @@ import java.util.List;
* 模块管理业务层
*/
@Service //标记为SpringBoot管理的业务层
public class ModuleServiceImpl implements ModuleService {
public class ModuleServiceImpl extends ServiceImpl<ModuleMapper,Module> implements ModuleService {
//注入mapper
@Autowired
private ModuleMapper moduleMapper;
......@@ -108,9 +109,7 @@ public class ModuleServiceImpl implements ModuleService {
if(ObjectUtil.isAllNotEmpty(module.getName(),module.getCurl(),module.getCtype(),module.getState())){
//01.获取当前操作的用户信息
Admin admin = AdminThreadLocal.get();
//02.更改当前数据的修改人信息
module.setOperator(admin.getName());
//03.保存数据
//02.保存数据
int insert = this.moduleMapper.insert(module);
return insert == 1;
}
......
......@@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.template.back.common.mapper.system.RoleMapper;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.pojo.system.Role;
......@@ -26,7 +27,7 @@ import java.util.*;
*/
@Service //标记为SpringBoot管理的业务层
@Slf4j //日志注解
public class RoleServiceImpl implements RoleService {
public class RoleServiceImpl extends ServiceImpl<RoleMapper,Role> implements RoleService {
//注入mapper
@Autowired
private RoleMapper roleMapper;
......@@ -65,9 +66,7 @@ public class RoleServiceImpl implements RoleService {
if(ObjectUtil.isAllNotEmpty(role.getName())){
//01.获取当前操作的用户信息
Admin admin = AdminThreadLocal.get();
//02.更改当前数据的修改人信息
role.setOperator(admin.getName());
//03.保存数据
//02.保存数据
int insert = this.roleMapper.insert(role);
return insert == 1;
}
......
......@@ -3,6 +3,7 @@ package com.template.back.server.service.system.Impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.template.back.common.mapper.system.SettingMapper;
import com.template.back.common.pojo.system.Admin;
import com.template.back.common.pojo.system.Setting;
......@@ -21,7 +22,7 @@ import java.util.List;
*/
@Service //标记为SpringBoot管理的业务层
@Slf4j //日志注解
public class SettingServiceImpl implements SettingService {
public class SettingServiceImpl extends ServiceImpl<SettingMapper,Setting> implements SettingService {
//注入mapper对象
@Autowired
private SettingMapper settingMapper;
......@@ -57,9 +58,7 @@ public class SettingServiceImpl implements SettingService {
public Boolean insert(Setting setting) {
//01.获取当前操作的用户信息
Admin admin = AdminThreadLocal.get();
//02.更改当前数据的修改人信息
setting.setOperator(admin.getName());
//03.保存数据
//02.保存数据
int insert = this.settingMapper.insert(setting);
return insert == 1;
}
......
package com.template.back.server.service.system;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.template.back.common.pojo.system.Logger;
/**
* @author 张骞
* @version 1.0.2
* 错误捕获日志业务层接口
*/
public interface LoggerService {
public interface LoggerService extends IService<Logger> {
Page findPage(Integer page, Integer pageSize);
}
package com.template.back.server.service.system;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.template.back.common.pojo.system.Module;
import com.template.back.common.vo.TreeVo;
......@@ -9,7 +10,7 @@ import java.util.List;
/**
* 模块管理业务层约束接口
*/
public interface ModuleService {
public interface ModuleService extends IService<Module> {
/**
* 分页查询
......
package com.template.back.server.service.system;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.template.back.common.pojo.system.Role;
import com.template.back.common.vo.TreeVo;
......@@ -10,7 +11,7 @@ import java.util.Map;
/**
* 角色管理业务层约束接口
*/
public interface RoleService {
public interface RoleService extends IService<Role> {
/**
* 分页查询
......
package com.template.back.server.service.system;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.template.back.common.pojo.system.Setting;
import java.util.List;
......@@ -10,7 +11,7 @@ import java.util.List;
* @version
* 设置类业务层
*/
public interface SettingService {
public interface SettingService extends IService<Setting> {
/**
* 分页查询的方法
* @param page
......
spring.application.name = template-back
server.port = 18078
#权限过滤器开关
author-interceptor-state=true
#并发设置
# 服务器最大连接数,默认8192
server.tomcat.max-connections=100
# 等待队列长度,默认100。
server.tomcat.accept-count=100
# 最大工作线程数,默认200。(4核8g内存,线程数经验值800。)
server.tomcat.threads.max=200
# 最小工作空闲线程数,默认10。(适当增大一些,以便应对突然增长的访问量)
server.tomcat.threads.min-spare=20
#mybatisplus配置在控制台输出sql语句和结果
loggoing.level.com.template.back.common.mapper.system =debug
# 权限过滤器开关
author-interceptor-state=false
# knife4j文档过滤器开关,生产环境下需要关闭
doc-interceptor-state=true
#配置上传文件的大小参数
# 配置上传文件的大小参数
spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB
# 配置mysql数据库
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/spring_db?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
spring.datasource.url=jdbc:mysql://58.56.31.21:3306/spring_db?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
spring.datasource.username=spring_db
spring.datasource.password=123456
# 逻辑删除配置
# 逻辑已删除值 1
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值 0
mybatis-plus.global-config.db-config.logic-not-delete-value=0
# mybatisplus配置在控制台输出sql语句和结果
loggoing.level.com.template.back.common.mapper.system =debug
# Redis相关配置
spring.redis.jedis.pool.max-wait = 5000ms
spring.redis.jedis.pool.max-Idle = 100
spring.redis.jedis.pool.min-Idle = 10
spring.redis.timeout = 10s
# 配置mapper扫描的位置
mybatis-plus.mapper-locations=classpath*:com/template/back/mapper/*/*.xml
# 配置枚举包扫描位置
mybatis-plus.type-enums-package=com.template.back.common.enums
# 表名前缀
mybatis-plus.global-config.db-config.table-prefix=tb_
# id策略为自增长
mybatis-plus.global-config.db-config.id-type=auto
#reids集群连接信息
#spring.redis.cluster.nodes = 192.168.31.81:6379,192.168.31.81:6380,192.168.31.81:6381
#spring.redis.cluster.max-redirects=5
......@@ -29,18 +58,17 @@ spring.redis.timeout = 10s
#单节点redis的配置,密码不适用可以放开
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
#spring.redis.password=123456
# 配置枚举包扫描位置
mybatis-plus.type-enums-package=com.template.back.common.enums
# 表名前缀
mybatis-plus.global-config.db-config.table-prefix=tb_
# id策略为自增长
mybatis-plus.global-config.db-config.id-type=auto
# 设置缓存过期时间,单位:毫秒
spring.cache.redis.time-to-live=1800000
# 日志配置
logging.config = classpath:logback-spring.xml
#定时任务配置
scheduled-thread-pool: 2
#dubbo服务中心,如果使用分布式,则放开
#dubbo.application.name = itcast-tanhua-server
#dubbo.registry.address = zookeeper://192.168.31.81:2181
......@@ -48,13 +76,8 @@ logging.config = classpath:logback-spring.xml
#dubbo.registry.timeout = 10000
#调用服务的超时时间
dubbo.consumer.timeout = 10000
#dubbo.consumer.timeout = 10000
#是否开启数据缓存
tanhua.cache.enable=false
#定时任务配置
scheduled-thread-pool: 2
# ===================================================================
# 分布式文件系统FDFS配置
......
......@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 浏览器title -->
<title>张骞|后台管理系统</title>
<title>Z-Admin|后台管理系统</title>
<!-- 自定义图标 -->
<link rel="shortcut icon" href="images/cloud_logo_2.png" />
<!-- 引入vue开发环境 -->
......@@ -21,6 +21,7 @@
<link rel="stylesheet" href="plugins/element-ui/lib/theme-chalk/index.css">
<!-- 自定义css样式 -->
<link href="styles/css/index.css" rel="stylesheet" type="text/css">
<!-- css样式,样式和本页相关,没有抽出 -->
<style>
/* 左侧菜单进度条样式1 */
......@@ -180,7 +181,7 @@
<span class="el-dropdown-link" id="name">
<i class="el-icon-user-solid" id="user"></i>
<!-- 这里动态显示登录用户名 -->
{{ userInfo.name }},您好<i class="el-icon-arrow-down el-icon--right"></i>
{{ userInfo.name }}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<!-- 用户登录鼠标划过弹出按钮 -->
<el-dropdown-menu slot="dropdown">
......@@ -204,8 +205,8 @@
<!-- 主区域部分Iframe模块start -->
<el-main style="padding:0px;" scrollbar="yes">
<!-- 可关闭标签选项卡start -->
<el-tabs v-model="tabindex" type="card" @tab-remove="removetabs" @tab-click="clicktabs" closable
text-align='middle'>
<el-tabs v-model="tabindex" type="card" @tab-remove="removetabs" @tab-click="clicktabs"
:closable="closable" text-align='middle'>
<el-tab-pane v-for="(item, index) in tabvals" :label="item.title" :name="item.name"
width="100%">
<!-- 正文iframe嵌套div start -->
......@@ -238,16 +239,17 @@
<!-- 主区域部分end -->
</el-container>
</el-container>
<!-- 页面整体容器end -->
<!--弹窗部分start-->
<!--修改密码弹窗start-->
<el-dialog title="方未云账户密码修改" :visible.sync="dialogVisiblePassword" width="40%" :before-close="handleClose">
<el-dialog title="账户密码修改" :visible.sync="dialogVisiblePassword" width="40%" :before-close="handleClose">
<!-- 当前登录用户名提示,不允许修改 -->
<span id="userInfo">
<strong>当前登录账户:</strong>{{ userInfo.name }}
<span>(用户名请联系方未工作人员更改)</span>
<span>(用户名请联系主管理员更改)</span>
</span>
<!-- 密码提交表单start -->
<el-form :model="password" :rules="rules" ref="ruleForm" label-width="80px" style="margin-top: 25px;">
......@@ -274,7 +276,8 @@
<!--修改密码弹窗end-->
<!--新增修改公用弹窗start :弹窗宽度和弹窗高度可以从子页面传输-->
<el-dialog :title=dislogName :visible.sync="dialogVisible" :width=big :before-close="handleClose">
<el-dialog :title=dislogName :visible.sync="dialogVisible" :width=big :before-close="handleClose"
:close-on-click-modal="false" :close-on-press-escape="false">
<iframe :src="dialogUrl" width=100% :height=height frameborder="0" id="iframeUpdate"></iframe>
</el-dialog>
<!--新增修改公用弹窗end-->
......@@ -298,16 +301,18 @@
//数据集合
data() {
return {
//标签页是否可以关闭的值
closable: false,
// 顶部菜单指使默认值
headTitle: '系统日志管理',
headTitle: '首页',
// 默认打开的页面(iframe)
iframeUrl: 'pages/system/logger/list.html',
iframeUrl: 'pages/home/home_page.html',
// 默认打开的页面(tabs首页,需要和iframeUrl一致)
tabindex: 'pages/system/logger/list.html',
tabindex: 'pages/home/home_page.html',
// tabs标签页使用
tabvals: [{ title: '系统运行日志', name: 'pages/system/logger/list.html', value: '' }],
tabvals: [{ title: '首页', name: 'pages/home/home_page.html', value: '', closable: false }],
//页面底部版权信息,具体内容在这里修改
pageInfo: '©2022-方未云后台管理系统-方未教育技术支持中心',
pageInfo: 'Copyright © 2022 Z-Admin-轻量化后台管理系统',
// 当前菜单默认收起状态
isopen: false,
// 收起菜单图标的默认状态
......@@ -339,127 +344,7 @@
// 标签页使用
active: '',
// 菜单动态数据,可以后台传入进行菜单权限控制
menus: [
{
id: 1, name: '系统功能管理', parentId: null, url: '', icon: 'el-icon-s-tools', children: [
{
id: 1,
name: '部门管理',
parentId: 1,
icon: 'el-icon-tickets',
curl: 'pages/system/dept/list.html',
children: [{
"created": null,
"updated": null,
"operator": null,
"id": "10",
"parentId": "9",
"name": "部门新增按钮",
"ctype": "2",
"state": "1",
"curl": "add1",
"remark": "",
"icon": "add",
"module": null,
"version": null,
"children": null
}, {
"created": null,
"updated": null,
"operator": null,
"id": "11",
"parentId": "9",
"name": "部门删除按钮",
"ctype": "2",
"state": "1",
"curl": "del",
"remark": "",
"icon": "del",
"module": null,
"version": null,
"children": null
}, {
"created": null,
"updated": null,
"operator": null,
"id": "12",
"parentId": "9",
"name": "部门修改按钮",
"ctype": "2",
"state": "1",
"curl": "updata",
"remark": "",
"icon": "updata",
"module": null,
"version": null,
"children": null
}]
},
{
id: 2,
name: '用户管理',
pid: 1,
icon: 'el-icon-user',
curl: 'pages/system/admin/list.html'
},
{
id: 3,
name: '角色管理',
pid: 1,
icon: 'el-icon-coordinate',
curl: 'pages/system/role/list.html'
},
{
id: 4,
name: '模块管理',
pid: 1,
icon: 'el-icon-box',
curl: 'pages/system/module/list.html'
},
{
id: 5,
name: '参数设置',
pid: 1,
icon: 'el-icon-setting',
curl: 'pages/system/setting/list.html'
},
{
id: 6,
name: '系统运行日志',
pid: 1,
icon: 'el-icon-printer',
curl: 'pages/system/logger/list.html'
}
]
},
{
id: 2, name: '校区会员管理', pid: null, url: '8', icon: 'el-icon-s-order', children: [
{
id: 21,
name: '校区管理',
pid: 2,
icon: 'el-icon-school',
curl: '6'
},
{
id: 22,
name: '会员管理',
pid: 2,
icon: 'el-icon-user',
curl: '7'
},
{
index: 23,
id: 23,
name: '在线状态',
pid: 2,
icon: 'el-icon-monitor',
curl: '8'
}
]
}
],
menus: [{ id: 1, name: '菜单正在加载中' }],
// 获取屏幕高度
screenHeight: document.documentElement.clientHeight + "px",
// 获取iframe页面高度
......@@ -546,6 +431,8 @@
// 为权限集合赋值
this.buttomList = isok[0].buttom;
}
//为关闭按钮赋值
this.closable = true;
},
//点击顶部标签页被点击的方法
clicktabs(tab) {
......@@ -558,10 +445,16 @@
// 为权限赋值:因为上面tabvals的属性buttom无法赋值给tab,这里再次从集合中取值
let isok = this.tabvals.filter(tabNew => tabNew.name == tab.name);
this.buttomList = isok[0].buttom;
//为关闭按钮赋值
if (tab.name != 'pages/home/home_page.html') {
this.closable = true
} else {
this.closable = false
}
},
//关闭标签页的方法
removetabs(tabname) {
if (tabname != 'home') {
if (tabname != 'pages/home/home_page.html') {
let index = this.tabvals.findIndex(tab => tab.name == tabname);
this.tabvals.splice(index, 1)
//刷新标签页
......@@ -569,6 +462,12 @@
this.iframeUrl = this.tabvals[index - 1].name
// 为权限赋值
this.buttomList = this.tabvals[index - 1].buttom;
//为关闭按钮赋值
if (this.tabvals[index - 1].name != 'pages/home/home_page.html') {
this.closable = true
} else {
this.closable = false
}
}
},
// 等待加载页面关闭,可以设置显示时间,单位:毫秒
......@@ -605,23 +504,22 @@
//let storage = window.localStorage;
//alert("id:"+storage.id);
//发送请求,根据当前id去服务器中查找对应的数据
axios.post('/member/changePassword', this.password).then(function (response) {
//alert(storage.id);
//获取响应数据
let res = response.data;
//判定根据旧密码是否可以查询到数据
if (res.data === undefined) {
//如果没有用户名信息,当第一次输入的密码不正确,给出提示
_this.passwordTips02();
changePassword(this.password).then(res => {
if (String(res.code) === '1') {
//给出提示
parent.index.$message.success(res.data)
//强制退出,重新登录(为了提示,进行延时操作)
this.timer = null
this.timer = setTimeout(() => {
this.logout()
}, 1000)
} else {
//如果后台查出相关的数据,修改成功,给出提示,并让用户退出重新登录
_this.tips('密码修改成功,下次请使用新密码登录!');
//关闭窗口
_this.dialogVisiblePassword = false;
this.$message.error(res.msg)
}
}).catch(function (err) {
console.log(err)
}).catch(err => {
this.$message.error("请求异常!")
})
} else {
//如果两次输入的密码不一致,给出提示
this.tips('两次新密码输入不一致!');
......@@ -677,10 +575,13 @@
if (userInfo) {
this.userInfo = JSON.parse(userInfo)
//获取当前用户权限下的菜单
}
// 关闭等加载页面
this.closeLoading()
//延时加载css页面效果
this.timer = setTimeout(() => {
document.getElementById('iframeWindow').contentWindow.location.reload(true)
}, 300)
},
//钩子函数:页面销毁前执行
beforeDestroy() {
......
<!DOCTYPE html>
<html>
<!-- 页面版式02:菜单无法收回-->
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>方未云|后台管理系统</title>
<!-- 引入Element必要的依赖文件 -->
<link rel="stylesheet" href="plugins/element-ui/lib/theme-chalk/index.css">
<script src="plugins/vue/vue.js"></script>
<script src="plugins/element-ui/lib/index.js"></script>
<script src="plugins/axios/axios-0.18.0.js" type="text/javascript"></script>
<!-- 引入本页自定义css样式 -->
<!-- 自定义图标 -->
<link rel="shortcut icon" href="images/cloud_logo_2.png" />
<!-- css样式 -->
<style>
.box {
width: 208px;
height: 100%;
/* background: #212431dc; */
white-space: nowrap;
}
.el-scrollbar {
height: 100%;
}
.el-scrollbar__wrap {
overflow: scroll;
width: 110%;
height: 103%;
}
html,
body,
#app,
.el-container {
/*设置内部填充为0,几个布局元素之间没有间距*/
padding: 0px;
/*外部间距也是如此设置*/
margin: 0px;
/*统一设置高度为100%*/
height: 100%;
}
</style>
<body>
<!-- div关联Vue依赖 -->
<div id="div">
<!-- 头部外层容器 start -->
<el-container style="box-shadow: 5px 5px 3px #000000; background-color: rgba(189, 189, 189, 0.295);">
<!-- 头部模块 start -->
<el-header class="header" style="height: 60px;">
<el-container>
<div>
<a herf="index.html">
<el-image src="images/logo_new_xiao.png" class="logo_img" herf="index.html"
style="height: 30px;margin-top:6%;" @click="userPage"></el-image>
</a>
</div>
<!-- 头部_导航部分start -->
<el-menu :default-active="activeIndex2" mode="horizontal" @select="handleSelect"
text-color="#050518" active-text-color="#409EFF" style="margin-left: auto;">
</el-menu>
<!-- 头部_导航部分end -->
<el-dropdown style="float: left;margin-top: 0.7%">
<span class="el-dropdown-link" id="name" style="margin-top: 5%;margin-left:30px;float: left">
<i class="el-icon-user-solid" style="font-size: 15px;color: rgb(64, 158,255);"></i>
{{nickname}},您好<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item>修改密码</el-dropdown-item> -->
<el-dropdown-item>
<el-button type="text" @click="dialogVisiblePassword = true">修改密码</el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button type="text" @click="logout">退出登录</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-container>
</el-header>
<!-- 头部模块 end -->
</el-container>
<!-- 头部外层容器 end -->
<el-container style="line-height: 20px;cursor: pointer;height: calc(100vh - 60px);">
<!-- 左侧导航栏start style="background-color: #383c4d;"-->
<el-aside width="210px" style="background-color: #383c4d">
<div class="box">
<el-scrollbar>
<!-- 功能菜单提示 -->
<div style="text-align: center;margin-top: 15px;margin-left: -15px;margin-bottom: 10px;">
<!-- <el-tag type="info">&nbsp;&nbsp;&nbsp;模板-后台功能菜单&nbsp;&nbsp;&nbsp;</el-tag> -->
</div>
<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen"
@close="handleClose" background-color="#383c4d" text-color="#fff"
active-text-color="rgb(64, 158,255)" style="width:210px;">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-s-tools"></i>
<span>系统功能管理</span>
</template>
<el-menu-item index="1-1"><i class="el-icon-tickets"></i>部门管理</el-menu-item>
<el-menu-item index="1-2"><i class="el-icon-user"></i>用户管理</el-menu-item>
<el-menu-item index="1-3"><i class="el-icon-coordinate"></i>角色管理</el-menu-item>
<el-menu-item index="1-4"><i class="el-icon-box"></i>模块管理</el-menu-item>
<el-menu-item index="1-5"><i class="el-icon-setting"></i>参数设置</el-menu-item>
<el-menu-item index="1-6"><i class="el-icon-printer"></i>系统运行日志</el-menu-item>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-s-order"></i>
<span>校区会员管理</span>
</template>
<el-menu-item index="2-1"><i class="el-icon-school"></i>校区管理</el-menu-item>
<el-menu-item index="2-2"><i class="el-icon-user"></i>会员管理</el-menu-item>
<el-menu-item index="2-3"><i class="el-icon-monitor"></i>在线状态</el-menu-item>
</el-submenu>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-s-comment"></i>
<span>口才课程管理</span>
</template>
<el-menu-item index="3-1"><i class="el-icon-files"></i>口才级别管理</el-menu-item>
<el-menu-item index="3-2"><i class="el-icon-notebook-2"></i>口才教案管理</el-menu-item>
<el-menu-item index="3-3"><i class="el-icon-data-analysis"></i>口才课件管理</el-menu-item>
</el-submenu>
<el-submenu index="4">
<template slot="title">
<i class="el-icon-s-order"></i>
<span>书法课程管理</span>
</template>
<el-menu-item index="4-1"><i class="el-icon-files"></i>口才级别管理</el-menu-item>
<el-menu-item index="4-2"><i class="el-icon-notebook-2"></i>口才教案管理</el-menu-item>
<el-menu-item index="4-3"><i class="el-icon-data-analysis"></i>口才课件管理</el-menu-item>
</el-submenu>
<!-- 加载一级菜单
<el-submenu v-for="level in levels" :index="level.sort" style="width: 228px">
<template slot="title">
<i class="el-icon-collection"></i>
<span>{{level.name}}</span>
</template>
加载二级菜单
<el-menu-item v-for="(item,index) in level.eloPdfList" :index="level.sort+'-'+item.sort"
@click="operation(item)">
<i class="el-icon-data-board"></i>
{{item.name}}
</el-menu-item>
</el-submenu> -->
</el-menu>
</el-scrollbar>
</div>
</el-aside>
<!-- 主区域部分start -->
<el-container style="background-color: #f7f7f7e7;scrollbar-width: none;">
<!-- 主区域部分嵌套 -->
<el-main style="scrollbar-width: none;">
<div style="padding-top:0px;height: 88vh;">
<iframe src="pages\system\dept\list.html" id="pdf" frameborder="0" scrolling="no"
id="external-frame" onload="setIframeHeight(this) " target=_parent
style="text-align: center;margin-top: 0px;width:100%;height: 88vh;"></iframe>
</div>
</el-main>
<!-- 页面底部 -->
<el-footer style="background-color: #383c4d8c;height: 40px;text-align: center;">
<span> </span>
<p style="font-size: 10px;margin-top: 8px;color: rgb(255, 255, 255);">©2022-方未云后台管理系统-方未教育技术支持中心
</p>
</el-footer>
</el-container>
<!-- 主区域部分end -->
</el-container>
<!-- 左侧导航栏end -->
<!-- 修改密码弹窗start -->
<el-dialog title="方未云账户密码修改" :visible.sync="dialogVisiblePassword" width="40%" :before-close="handleClose">
<span style="margin-bottom: 20px;margin-top: 0px;margin-left:25px;padding-top: 0px">
<strong>当前登录账户:</strong>{{nickname}}
<span>(用户名请联系方未工作人员更改)</span>
</span>
<el-form :model="password" :rules="rules" ref="ruleForm" label-width="80px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input placeholder="请输入旧密码" v-model="password.oldPassword" maxlength="20" show-word-limit>
</el-input>
</el-form-item>
<el-form-item label="新密码">
<el-input placeholder="请输入新密码" v-model="password.newPassword01" show-password maxlength="20"
show-word-limit></el-input>
</el-form-item>
<el-form-item label="确认密码">
<el-input placeholder="请再次输入新密码" v-model="password.newPassword02" show-password maxlength="20"
show-word-limit></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisiblePassword = false">取 消</el-button>
<el-button type="primary" @click="changePassword">提 交</el-button>
</div>
</el-dialog>
<!--修改密码弹窗end-->
</div>
</body>
<script>
// Vue核心对象
new Vue({
el: "#div",
data() {
return {
name: '',
nickname: '',
levels: [],
results: [],
checked: [],
pdfPath: '',
vectorPdfPath: '',
dialogVisiblePassword: false,
password: {
id: window.localStorage.id,
oldPassword: '',
newPassword01: '',
newPassword02: '',
},
tableData: [{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-08',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-06',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-07',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
multipleSelection: []
}
},
methods: {
//登录气泡及弹窗关闭使用的方法
handleClose(done) {
{
done();
}
},
//跳转用户中心的方法
userPage() {
window.open('/user.html', '_self');
},
//退出登录的方法
logout() {
//alert("退出方法被执行了");
//1.获取localStorage
let storage = window.localStorage;
//2.发送请求,清除登录状态
axios.post('/member/logout', '{"id":"' + storage.id + '"}').then(function (response) {
//1.获取响应数据
let data = response.data;
//2.提示
//alert("您已成功退出系统!");
}).catch(function (err) {
console.log(err)
});
//3.清理localStorage
window.localStorage.clear();
//4.通过调用checkLogin方法重置主页面的右上角显示区域
this.checkLogin();
},
//点击按钮,验证登录状态,并且组合配置路径
operation(eloPdf) {
let _this = this;
//加载路径配置文件
//加载路径配置文件,请求向量加密
//_this.vector(eloPdf);
//4.发送post请求,获取配置文件信息
axios.post('/eloPdf/vector', '{"pdf":"' + eloPdf.pdf + '"}').then(function (response) {
//5.得到响应数据
var res = response.data;
//alert(JSON.stringify(res));
//this.vectorPdfPath = res.data;
//alert(vectorPptPath);
//更改iframe的属性
//alert(pdfPath+vectorPdfPath);
document.querySelector("iframe").src = pdfPath + res.data;
//重新刷新iframe页面
document.querySelector('iframe').contentWindow.location.reload();
}).catch(function (err) {
console.log(err)
});
/*
//不使用向量加密的方法
//更改iframe的属性
//alert(pdfPath);
document.querySelector("iframe").src = pdfPath + eloPdf.pdf;
//重新刷新iframe页面
document.querySelector('iframe').contentWindow.location.reload();*/
},
//获取虚拟路径的方法
path() {
//4.发送post请求,获取配置文件信息
axios.post('/eloPdf/path').then(function (response) {
//5.得到响应数据
var res = response.data;
this.pdfPath = res.data.para;
//alert(pdfPath);
}).catch(function (err) {
console.log(err)
});
},
//加载数据的方法
findPdf() {
let _this = this;
//alert("加载数据测试");
//4.发送post请求,获取题目信息
axios.post('/eloPdf/list').then(function (response) {
//5.得到响应数据
var res = response.data;
//alert(JSON.stringify(res));
_this.levels = res.data;
}).catch(function (err) {
console.log(err)
});
},
},
//页面刷新时启动的方法
created() {
//获取当前的pdf对象数据
this.findPdf();
//验证当前的登录信息
this.checkLogin();
//获取相对路径的配置参数
this.path();
},
});
</script>
</html>
\ No newline at end of file
var canvas;
var context;
var width;
var height;
var quads = [];
var displacementVec;
window.onload = function()
{
canvas = document.getElementById('canvas');
// canvas.style.width = window.innerWidth + "px";
canvas.style.width = (window.innerWidth - 380) + "px";
setTimeout(function() {
// canvas.style.height = window.innerHeight + "px";
canvas.style.height = "400px";
}, 0);
context = canvas.getContext('2d');
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
displacementVec = vec2d.create(0.02, 0.02);
generateTriangles();
loop();
};
function generateTriangles()
{
var length = 32 - 1;
var i = length;
for(i; i > -1; --i)
{
var obj = quad.create(width >> 1, (i / length) * (height >> 1) + (height >> 2), Math.sin((i / length) * (Math.PI)) * (width >> 3));
quads.push(obj);
}
}
function loop()
{
updateTriangles();
renderTriangles();
requestAnimationFrame(loop);
}
function updateTriangles()
{
var i = quads.length - 1;
for(i; i > -1; --i)
{
var quad = quads[i];
quad.update();
}
}
function renderTriangles()
{
context.lineWidth = 1;
context.fillStyle = '#383c4d'; // 背景颜色
context.strokeStyle = '#409eff'; // 图形颜色
context.globalAlpha = 0.15;
context.fillRect(0, 0, canvas.width, canvas.height);
context.globalAlpha = 1;
context.fillStyle = '#ffffff'; // 影子颜色
var i = quads.length - 1;
var j;
for(i; i > -1; --i)
{
var quad = quads[i];
j = quad.getPoints().length - 1;
for(j; j > -1; --j)
{
var p1 = quad.getPoints()[j];
var p2 = (j > 0) ? quad.getPoints()[j - 1] : quad.getPoints()[quad.getPoints().length - 1];
context.beginPath();
context.moveTo(quad.getPos().getX() + Math.cos(p1.getAngle().getX()) * p1.getSize(), quad.getPos().getY() + Math.sin(p1.getAngle().getY()) * p1.getSize());
context.lineTo(quad.getPos().getX() + Math.cos(p2.getAngle().getX()) * p2.getSize(), quad.getPos().getY() + Math.sin(p2.getAngle().getY()) * p2.getSize());
context.arc(quad.getPos().getX() + Math.cos(p1.getAngle().getX()) * p1.getSize(), quad.getPos().getY() + Math.sin(p1.getAngle().getY()) * p1.getSize(), 4, 0, Math.PI * 2);
context.fill();
context.stroke();
context.closePath();
}
}
}
//vec2d definition:
var vec2d =
{
_x: 1,
_y: 0,
create: function(x, y)
{
var obj = Object.create(this);
obj.setX(x);
obj.setY(y);
return obj;
},
getX: function()
{
return this._x;
},
setX: function(value)
{
this._x = value;
},
getY: function()
{
return this._y;
},
setY: function(value)
{
this._y = value;
},
setXY: function(x, y)
{
this._x = x;
this._y = y;
},
getLength: function()
{
return Math.sqrt(this._x * this._x + this._y * this._y);
},
setLength: function(length)
{
var angle = this.getAngle();
this._x = Math.cos(angle) * length;
this._y = Math.sin(angle) * length;
},
getAngle: function()
{
return Math.atan2(this._y, this._x);
},
setAngle: function(angle)
{
var length = this.getLength();
this._x = Math.cos(angle) * length;
this._y = Math.sin(angle) * length;
},
add: function(vector)
{
this._x += vector.getX();
this._y += vector.getY();
},
substract: function(vector)
{
this._x -= vector.getX();
this._y -= vector.getY();
},
multiply: function(value)
{
this._x *= value;
this._y *= value;
},
divide: function(value)
{
this._x *= value;
this._y *= value;
}
};
//quad definition:
var quad =
{
_pos: null,
_size: null,
_points: null,
create: function(x, y, size)
{
var obj = Object.create(this);
obj.setPos(vec2d.create(x, y));
obj.setSize(size);
obj.setPoints
(
[
point.create(size, 0, 0),
point.create(size, Math.PI / 2, Math.PI / 2),
point.create(size, Math.PI, Math.PI),
point.create(size, Math.PI * 1.5, Math.PI * 1.5)
]
);
return obj;
},
update: function()
{
var i = this._points.length - 1;
for(i; i > -1; --i)
{
var point = this._points[i];
point.update();
}
},
getPos: function()
{
return this._pos;
},
setPos: function(vector)
{
this._pos = vector;
},
getSize: function()
{
return this._size;
},
setSize: function(size)
{
this._size = size;
},
getPoints: function()
{
return this._points;
},
setPoints: function(points)
{
this._points = points;
}
};
//point definition:
var point =
{
_pos: null,
_size: null,
_angle: null,
create: function(size, angleX, angleY)
{
var obj = Object.create(this);
obj.setPos(vec2d.create(0, 0));
obj.setSize(size);
obj.setAngle(vec2d.create(angleX, angleY));
obj.getAngle().add(vec2d.create(size / 200, size / 200));
return obj;
},
update: function()
{
this.getAngle().add(displacementVec);
},
getPos: function()
{
return this._pos;
},
setPos: function(vector)
{
this._pos = vector;
},
getSize: function()
{
return this._size;
},
setSize: function(size)
{
this._size = size;
},
getAngle: function()
{
return this._angle;
},
setAngle: function(angle)
{
this._angle = angle;
},
};
\ No newline at end of file
<!DOCTYPE html>
<html>
<!-- 页面版式03:菜单可以收回,顶部带标签 -->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 浏览器title -->
<title>Z-Admin|系统中心</title>
<!-- 自定义图标 -->
<link rel="shortcut icon" href="../../images/cloud_logo_2.png" />
<!-- 引入vue开发环境 -->
<script src="../../plugins/vue/vue.js"></script>
<!-- 引入组件库,包含自定义请求方法 -->
<script src="../../plugins/axios/axios.min.js"></script>
<script src="../../plugins/element-ui/lib/index.js"></script>
<script src="../../js/request.js"></script>
<!-- 引入element样式 -->
<link rel="stylesheet" href="../../plugins/element-ui/lib/theme-chalk/index.css">
<!-- 引入画图样式 -->
<script src="../../js/home_page/home_page.js"></script>
<link rel="stylesheet" href="../../styles/css/home_page/home_page.css">
<!-- 引入css -->
<!-- <link rel="stylesheet" href="../../styles/css/home_page/page.css"> -->
</head>
<body>
<div id="app">
<!-- 服务器状态start -->
<div
style="margin-left: 22px;width: 300px;height:470px;border-radius: 10px;background-color: #e6e6e6;text-align: center;box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.1);float: left;">
<!-- 提示文字 -->
<div style="padding-top: 20px;text-align: left;padding-bottom: 10px;padding-left: 20px;">
<i class="el-icon-receiving"></i>
<span style="color: rgb(78, 78, 78);text-align: left;font-size: 16px;">Z-Admin自检系统</span>
</div>
<hr>
<!-- 具体信息 -->
<div style="margin: 20px;text-align: left;">
<div style="padding-left: 10px;padding: 10px;">
<i class="el-icon-loading" style="color:#1a7cfc;font-size: 18px;"></i>
<span style="padding-left: 10px;">自动检测执行中...</span>
</div>
<div style="padding-left: 10px;padding: 10px;">
<i class="el-icon-success" style="color:#1a7cfc;font-size: 18px;"></i>
<span style="padding-left: 10px;">服务器状态:{{state}}</span>
</div>
<div style="padding-left: 10px;padding: 10px;">
<i class="el-icon-s-platform" style="color:#1a7cfc;font-size: 18px;"></i>
<span style="padding-left: 10px;">当前连接:{{server}}</span>
</div>
<div style="padding-left: 10px;padding: 10px;">
<i class="el-icon-files" style="color:#1a7cfc;font-size: 18px;"></i>
<span style="padding-left: 10px;">系统日期:{{date | formatDate}}</span>
</div>
<div style="padding-left: 10px;padding: 10px;">
<i class="el-icon-time" style="color:#1a7cfc;font-size: 18px;"></i>
<span style="padding-left: 10px;">系统时间:{{date | formatTime}}</span>
</div>
</div>
</div>
<!-- 服务器状态end -->
<!-- 服务器运算中效果start -->
<div
style="width: calc(100vw - 365px);height:470px;margin-left:345px;background-color: #383c4d;border-radius: 10px;text-align: center;box-shadow: 0px 0px 4px 1px rgba(0,0,0,0.1);">
<!-- 提示文字 -->
<div style="padding-top: 20px;padding-bottom: 10px;padding-left: 20px;text-align: left;">
<i class="el-icon-cloudy" style="color: #e6e6e6;"></i>
<span
style="color: rgb(248, 248, 248);text-align: left;font-size: 16px;">Z-Admin持续计算中,提供服务端支持[GPU算法视觉呈现]</span>
</div>
<hr>
<!-- 运算图画板 -->
<div style="text-align: center;float: left;">
<canvas id="canvas" style="text-align: center;padding-left: 10px;"></canvas>
</div>
</div>
<!-- 服务器运算中效果end -->
</div>
<!-- vue部分 -->
<script>
new Vue({
el: '#app',
data() {
return {
//当前校区的数据
campus: { number: '1' },
//当前连接
server: '华北区集群',
//授权天数
ofDay: '1',
// 当前授权科目
subject: 0,
surpass: "20%",
// 服务器状态
state: "正常",
date: new Date(),
}
},
// 方法集合
methods: {
// echarts方法集合
// 更改上方异常检测模块数据
error() {
this.state = "检测中..."
this.server = "检测中..."
this.timer = null
// 关闭自检效果
this.timer = setTimeout(() => {
this.state = "异常"
this.server = "暂无连接"
}, 1500)
},
// 获取当前课程的权限
async init() {
// 测试当前服务器状态
axios.post('/system/user/test').then(function (response) {
// alert(response.$message)
}, error => {
this.error()
})
},
},
// 过滤器
filters: {
// 时间格式化
formatDate(value) {
let date = new Date(value);
let y = date.getFullYear();
let MM = date.getMonth() + 1;
MM = MM < 10 ? "0" + MM : MM;
let d = date.getDate();
d = d < 10 ? "0" + d : d;
return y + "-" + MM + "-" + d;
},
// 时间格式化
formatTime(value) {
let date = new Date(value);
let h = date.getHours();
h = h < 10 ? "0" + h : h;
let m = date.getMinutes();
m = m < 10 ? "0" + m : m;
let s = date.getSeconds();
s = s < 10 ? "0" + s : s;
// return y + "-" + MM + "-" + d + " " + h + ":" + m + ":" + s;
return h + ":" + m + ":" + s;
}
},
// 钩子函数,加载完成时调用
mounted() {
var that = this;
this.timer = setInterval(() => {
that.date = new Date(); //修改数据date
}, 1000);
},
created() {
// 请求课程列表数据
Promise.all([
this.init(),
]).then(res => {
// 默认选中课程
this.defaultCourse(this.course)
})
},
// 钩子函数,销毁前执行
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer); //在Vue实例销毁前,清除我们的定时器
}
},
})
</script>
</body>
</html>
\ No newline at end of file
......@@ -33,7 +33,7 @@
<!-- 顶部LOGO部分end -->
<!-- 登录中间部分 -->
<div class="login-box" style="margin: top 47.934px;">
<div class="login-box">
<h1>登 录</h1>
<h2>请先登录以管理后台数据</h2>
<el-form :model="member" :rules="loginRules" ref="ruleForm" label-width="100px" id="ruleForm">
......@@ -110,7 +110,7 @@
let res = await loginApi(this.member)
if (String(res.code) === '1') {
localStorage.setItem('userInfo', JSON.stringify(res.data))
window.location.href = '/backend/index_tabs.html'
window.location.href = '/backend/index.html'
} else {
this.$message.error(res.msg)
this.loading = false
......
......@@ -66,7 +66,7 @@
<el-table-column prop="updated" label="最后编辑时间" width="220">
</el-table-column>
<!-- 编辑人 -->
<el-table-column prop="operator" label="编辑人" show-overflow-tooltip>
<el-table-column prop="operatorName" label="编辑人" show-overflow-tooltip>
</el-table-column>
<!-- 操作按钮 -->
<el-table-column label="操作" width="220" fixed="right">
......
......@@ -62,7 +62,7 @@
<el-table-column prop="updated" label="最后编辑时间" width="220">
</el-table-column>
<!-- 编辑人 -->
<el-table-column prop="operator" label="编辑人" show-overflow-tooltip>
<el-table-column prop="operatorName" label="编辑人" show-overflow-tooltip>
</el-table-column>
<!-- 操作按钮 -->
<el-table-column label="操作">
......
......@@ -74,7 +74,7 @@
<el-table-column prop="icon" label="图标" width="200">
</el-table-column>
<!-- 最后编辑时间 -->
<el-table-column prop="updated" label="最后编辑时间" show-overflow-tooltip>
<el-table-column prop="updatedName" label="最后编辑时间" show-overflow-tooltip>
</el-table-column>
<!-- 编辑人 -->
<el-table-column prop="operator" label="编辑人" show-overflow-tooltip>
......
......@@ -60,7 +60,7 @@
<el-table-column prop="updated" label="最后编辑时间" width="220">
</el-table-column>
<!-- 编辑人 -->
<el-table-column prop="operator" label="编辑人" show-overflow-tooltip>
<el-table-column prop="operatorName" label="编辑人" show-overflow-tooltip>
</el-table-column>
<!-- 操作按钮 -->
<el-table-column label="操作" width="220px">
......
......@@ -67,7 +67,7 @@
<el-table-column prop="updated" label="最后编辑时间" width="220">
</el-table-column>
<!-- 编辑人 -->
<el-table-column prop="operator" label="编辑人" show-overflow-tooltip>
<el-table-column prop="operatorName" label="编辑人" show-overflow-tooltip>
</el-table-column>
<!-- 操作按钮 -->
<el-table-column label="操作" width="100" fixed="right">
......
* {
margin: 0px;
}
canvas {
display: block;
}
/* 顶部四个色块的样式 */
.user-info-wrapper .bottom-wrapper .item-wapper.buy-course {
background-image: linear-gradient( 123deg ,#6bc0ff 0,#3a8cf6 100%);
-webkit-box-shadow: 4px 8px 38px 0 rgb(0 177 255 / 60%);
box-shadow: 4px 8px 38px 0 rgb(0 177 255 / 60%);
}
.user-info-wrapper .bottom-wrapper .item-wapper.course-complate {
background-image: linear-gradient( 123deg ,#acf057 0,#88d838 100%);
-webkit-box-shadow: 4px 8px 38px 0 rgb(182 247 43 / 60%);
box-shadow: 4px 8px 38px 0 rgb(182 247 43 / 60%);
margin-left: 40px;
}
.user-info-wrapper .bottom-wrapper .item-wapper.week-study {
background-image: linear-gradient( 123deg ,#ffc443 0,#ff8a28 100%);
-webkit-box-shadow: 4px 8px 38px 0 rgb(252 178 70 / 60%);
box-shadow: 4px 8px 38px 0 rgb(252 178 70 / 60%);
margin-left: 40px;
}
.user-info-wrapper .bottom-wrapper .item-wapper.beyond-partter {
background-image: linear-gradient( 123deg ,#ff6b7d 0,#ff4c55 100%);
-webkit-box-shadow: 4px 8px 38px 0 rgb(255 76 85 / 60%);
box-shadow: 4px 8px 38px 0 rgb(255 76 85 / 60%);
margin-left: 40px;
}
/* 顶部四个色块关联的其他样式 */
.user-info-wrapper .bottom-wrapper {
padding: 40px 20px 40px 20px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.user-info-wrapper .bottom-wrapper {
padding: 40px 20px 40px 20px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.user-info-wrapper .bottom-wrapper .item-wapper {
width: 242px;
height: 105px;
border-radius: 8px;
padding: 20px 22px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.user-info-wrapper .bottom-wrapper .item-wapper .info .text {
font-family: PingFangSC-Regular;
font-size: 33px;
color: #fff;
letter-spacing: 0;
line-height: 22px;
margin-top: 20px;
margin-left: 10px;
}
.user-info-wrapper .bottom-wrapper .item-wapper .info p {
font-family: PingFangSC-Regular;
font-size: 14px;
color: #fff;
letter-spacing: 0;
line-height: 22px;
margin-top: 11px;
margin-left: 10px;
font-weight: 100;
}
/* 图片大小 */
.user-info-wrapper .bottom-wrapper .item-wapper .img img {
width: 80px;
height: 80px;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册