mirror of
https://gitee.com/orangeform/orange-admin.git
synced 2026-01-17 18:46:36 +08:00
commit:同步1.4版本
This commit is contained in:
BIN
orange-demo-single-service/.DS_Store
vendored
Normal file
BIN
orange-demo-single-service/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -1,10 +1,15 @@
|
||||
### 服务接口文档
|
||||
---
|
||||
- Knife4j
|
||||
- 服务启动后,Knife4j的文档入口地址 [http://localhost:8082/doc.html#/plus](http://localhost:8082/doc.html#/plus)
|
||||
- Postman
|
||||
- 无需启动服务,即可将当前工程的接口导出成Postman格式。在工程的common/common-tools/模块下,找到ExportApiApp文件,并执行main函数。
|
||||
|
||||
### 服务启动环境依赖
|
||||
---
|
||||
|
||||
执行docker-compose up -d 命令启动下面依赖的服务。
|
||||
执行docker-compose down 命令停止下面服务。
|
||||
|
||||
- Redis
|
||||
- 版本:4
|
||||
- 端口: 6379
|
||||
- 推荐客户端工具 [AnotherRedisDesktopManager](https://github.com/qishibo/AnotherRedisDesktopManager)
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
<artifactId>common-core</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orange.demo</groupId>
|
||||
<artifactId>common-redis</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orange.demo</groupId>
|
||||
<artifactId>common-sequence</artifactId>
|
||||
@@ -30,11 +35,6 @@
|
||||
<artifactId>application-common</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orange.demo</groupId>
|
||||
<artifactId>common-swagger</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.app.controller;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import cn.jimmyshi.beanquery.BeanQuery;
|
||||
import com.orange.demo.app.model.AreaCode;
|
||||
import com.orange.demo.app.service.AreaCodeService;
|
||||
@@ -20,7 +19,6 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "行政区划数据访问接口")
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/areaCode")
|
||||
public class AreaCodeController {
|
||||
|
||||
@@ -16,10 +16,8 @@ import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.constant.*;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.orange.demo.common.core.cache.SessionCacheHelper;
|
||||
import com.orange.demo.common.redis.cache.SessionCacheHelper;
|
||||
import com.orange.demo.config.ApplicationConfig;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -35,7 +33,6 @@ import javax.validation.groups.Default;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "课程数据管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/course")
|
||||
@@ -56,14 +53,6 @@ public class CourseController {
|
||||
* @param courseDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"course.courseId",
|
||||
"course.priceStart",
|
||||
"course.priceEnd",
|
||||
"course.classHourStart",
|
||||
"course.classHourEnd",
|
||||
"course.createTimeStart",
|
||||
"course.createTimeEnd"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody("course") CourseDto courseDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(courseDto);
|
||||
@@ -87,13 +76,6 @@ public class CourseController {
|
||||
* @param courseDto 更新对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"course.priceStart",
|
||||
"course.priceEnd",
|
||||
"course.classHourStart",
|
||||
"course.classHourEnd",
|
||||
"course.createTimeStart",
|
||||
"course.createTimeEnd"})
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(@MyRequestBody("course") CourseDto courseDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(courseDto, Default.class, UpdateGroup.class);
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.orange.demo.common.core.object.*;
|
||||
import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.constant.*;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -22,7 +21,6 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "课程统计管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/courseTransStats")
|
||||
|
||||
@@ -12,8 +12,6 @@ import com.orange.demo.common.core.object.ResponseResult;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -27,7 +25,6 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "年级管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/grade")
|
||||
@@ -42,7 +39,6 @@ public class GradeController {
|
||||
* @param gradeDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"grade.gradeId"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Integer> add(@MyRequestBody("grade") GradeDto gradeDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(gradeDto);
|
||||
|
||||
@@ -11,8 +11,6 @@ import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.constant.*;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -26,7 +24,6 @@ import javax.validation.groups.Default;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "校区数据管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/schoolInfo")
|
||||
@@ -41,7 +38,6 @@ public class SchoolInfoController {
|
||||
* @param schoolInfoDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"schoolInfo.schoolId"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody("schoolInfo") SchoolInfoDto schoolInfoDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(schoolInfoDto);
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.orange.demo.common.core.object.*;
|
||||
import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.constant.*;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -22,7 +21,6 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "学生行为统计管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/studentActionStats")
|
||||
|
||||
@@ -10,8 +10,6 @@ import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.constant.*;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -25,7 +23,6 @@ import javax.validation.groups.Default;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "学生行为流水管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/studentActionTrans")
|
||||
@@ -40,10 +37,6 @@ public class StudentActionTransController {
|
||||
* @param studentActionTransDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"studentActionTrans.transId",
|
||||
"studentActionTrans.createTimeStart",
|
||||
"studentActionTrans.createTimeEnd"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody("studentActionTrans") StudentActionTransDto studentActionTransDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(studentActionTransDto);
|
||||
@@ -67,9 +60,6 @@ public class StudentActionTransController {
|
||||
* @param studentActionTransDto 更新对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"studentActionTrans.createTimeStart",
|
||||
"studentActionTrans.createTimeEnd"})
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(@MyRequestBody("studentActionTrans") StudentActionTransDto studentActionTransDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(studentActionTransDto, Default.class, UpdateGroup.class);
|
||||
|
||||
@@ -10,8 +10,6 @@ import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.constant.*;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -26,7 +24,6 @@ import java.util.stream.Collectors;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "班级数据管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/studentClass")
|
||||
@@ -45,7 +42,6 @@ public class StudentClassController {
|
||||
* @param studentClassDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"studentClass.classId"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody("studentClass") StudentClassDto studentClassDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(studentClassDto);
|
||||
|
||||
@@ -11,8 +11,6 @@ import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.constant.*;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -26,7 +24,6 @@ import javax.validation.groups.Default;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "学生数据管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/app/student")
|
||||
@@ -41,13 +38,6 @@ public class StudentController {
|
||||
* @param studentDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"student.studentId",
|
||||
"student.searchString",
|
||||
"student.birthdayStart",
|
||||
"student.birthdayEnd",
|
||||
"student.registerTimeStart",
|
||||
"student.registerTimeEnd"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody("student") StudentDto studentDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(studentDto);
|
||||
@@ -71,12 +61,6 @@ public class StudentController {
|
||||
* @param studentDto 更新对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"student.searchString",
|
||||
"student.birthdayStart",
|
||||
"student.birthdayEnd",
|
||||
"student.registerTimeStart",
|
||||
"student.registerTimeEnd"})
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(@MyRequestBody("student") StudentDto studentDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(studentDto, Default.class, UpdateGroup.class);
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.orange.demo.app.dto;
|
||||
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -14,28 +12,24 @@ import javax.validation.constraints.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("ClassCourseDto对象")
|
||||
@Data
|
||||
public class ClassCourseDto {
|
||||
|
||||
/**
|
||||
* 班级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,班级Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long classId;
|
||||
|
||||
/**
|
||||
* 课程Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程Id", required = true)
|
||||
@NotNull(message = "数据验证失败,课程Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 课程顺序(数值越小越靠前)。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程顺序(数值越小越靠前)", required = true)
|
||||
@NotNull(message = "数据验证失败,课程顺序(数值越小越靠前)不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer courseOrder;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.orange.demo.app.dto;
|
||||
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -14,21 +12,18 @@ import javax.validation.constraints.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("ClassStudentDto对象")
|
||||
@Data
|
||||
public class ClassStudentDto {
|
||||
|
||||
/**
|
||||
* 班级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,班级Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long classId;
|
||||
|
||||
/**
|
||||
* 学生Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生Id", required = true)
|
||||
@NotNull(message = "数据验证失败,学生Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long studentId;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.app.model.constant.CourseDifficult;
|
||||
import com.orange.demo.application.common.constant.Subject;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -19,41 +17,35 @@ import java.math.BigDecimal;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("CourseDto对象")
|
||||
@Data
|
||||
public class CourseDto {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id", required = true)
|
||||
@NotNull(message = "数据验证失败,主键Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 课程名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程名称", required = true)
|
||||
@NotBlank(message = "数据验证失败,课程名称不能为空!")
|
||||
private String courseName;
|
||||
|
||||
/**
|
||||
* 课程价格。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程价格", required = true)
|
||||
@NotNull(message = "数据验证失败,课程价格不能为空!")
|
||||
private BigDecimal price;
|
||||
|
||||
/**
|
||||
* 课程描述。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 课程难度(0: 容易 1: 普通 2: 很难)。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程难度(0: 容易 1: 普通 2: 很难)", required = true)
|
||||
@NotNull(message = "数据验证失败,课程难度不能为空!")
|
||||
@ConstDictRef(constDictClass = CourseDifficult.class, message = "数据验证失败,课程难度为无效值!")
|
||||
private Integer difficulty;
|
||||
@@ -61,14 +53,12 @@ public class CourseDto {
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所属年级不能为空!")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 学科Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学科Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所属学科不能为空!")
|
||||
@ConstDictRef(constDictClass = Subject.class, message = "数据验证失败,所属学科为无效值!")
|
||||
private Integer subjectId;
|
||||
@@ -76,50 +66,42 @@ public class CourseDto {
|
||||
/**
|
||||
* 课时数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "课时数量", required = true)
|
||||
@NotNull(message = "数据验证失败,课时数量不能为空!")
|
||||
private Integer classHour;
|
||||
|
||||
/**
|
||||
* 多张课程图片地址。
|
||||
*/
|
||||
@ApiModelProperty(value = "多张课程图片地址", required = true)
|
||||
@NotBlank(message = "数据验证失败,课程图片不能为空!")
|
||||
private String pictureUrl;
|
||||
|
||||
/**
|
||||
* price 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "price 范围过滤起始值(>=)")
|
||||
private BigDecimal priceStart;
|
||||
|
||||
/**
|
||||
* price 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "price 范围过滤结束值(<=)")
|
||||
private BigDecimal priceEnd;
|
||||
|
||||
/**
|
||||
* classHour 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "classHour 范围过滤起始值(>=)")
|
||||
private Integer classHourStart;
|
||||
|
||||
/**
|
||||
* classHour 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "classHour 范围过滤结束值(<=)")
|
||||
private Integer classHourEnd;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "createTime 范围过滤起始值(>=)")
|
||||
private String createTimeStart;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "createTime 范围过滤结束值(<=)")
|
||||
private String createTimeEnd;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.application.common.constant.Subject;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -18,28 +16,24 @@ import java.util.Date;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("CourseTransStatsDto对象")
|
||||
@Data
|
||||
public class CourseTransStatsDto {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id", required = true)
|
||||
@NotNull(message = "数据验证失败,主键Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long statsId;
|
||||
|
||||
/**
|
||||
* 统计日期。
|
||||
*/
|
||||
@ApiModelProperty(value = "统计日期", required = true)
|
||||
@NotNull(message = "数据验证失败,统计日期不能为空!")
|
||||
private Date statsDate;
|
||||
|
||||
/**
|
||||
* 科目Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "科目Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所属科目不能为空!")
|
||||
@ConstDictRef(constDictClass = Subject.class, message = "数据验证失败,所属科目为无效值!")
|
||||
private Integer subjectId;
|
||||
@@ -47,59 +41,50 @@ public class CourseTransStatsDto {
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所属年级不能为空!")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 年级名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级名称")
|
||||
private String gradeName;
|
||||
|
||||
/**
|
||||
* 课程Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程Id", required = true)
|
||||
@NotNull(message = "数据验证失败,课程Id不能为空!")
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 课程名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程名称")
|
||||
private String courseName;
|
||||
|
||||
/**
|
||||
* 学生上课次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生上课次数", required = true)
|
||||
@NotNull(message = "数据验证失败,上课次数不能为空!")
|
||||
private Integer studentAttendCount;
|
||||
|
||||
/**
|
||||
* 学生献花数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生献花数量", required = true)
|
||||
@NotNull(message = "数据验证失败,献花数量不能为空!")
|
||||
private Integer studentFlowerAmount;
|
||||
|
||||
/**
|
||||
* 学生献花次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生献花次数", required = true)
|
||||
@NotNull(message = "数据验证失败,献花次数不能为空!")
|
||||
private Integer studentFlowerCount;
|
||||
|
||||
/**
|
||||
* statsDate 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "statsDate 范围过滤起始值(>=)")
|
||||
private String statsDateStart;
|
||||
|
||||
/**
|
||||
* statsDate 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "statsDate 范围过滤结束值(<=)")
|
||||
private String statsDateEnd;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.orange.demo.app.dto;
|
||||
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -14,21 +12,18 @@ import javax.validation.constraints.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("GradeDto对象")
|
||||
@Data
|
||||
public class GradeDto {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id", required = true)
|
||||
@NotNull(message = "数据验证失败,主键Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 年级名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级名称", required = true)
|
||||
@NotBlank(message = "数据验证失败,年级名称不能为空!")
|
||||
private String gradeName;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.orange.demo.app.dto;
|
||||
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -14,35 +12,30 @@ import javax.validation.constraints.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("SchoolInfoDto对象")
|
||||
@Data
|
||||
public class SchoolInfoDto {
|
||||
|
||||
/**
|
||||
* 学校Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学校Id", required = true)
|
||||
@NotNull(message = "数据验证失败,学校Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 学校名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "学校名称", required = true)
|
||||
@NotBlank(message = "数据验证失败,学校名称不能为空!")
|
||||
private String schoolName;
|
||||
|
||||
/**
|
||||
* 所在省Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在省Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所在省份不能为空!")
|
||||
private Long provinceId;
|
||||
|
||||
/**
|
||||
* 所在城市Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在城市Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所在城市不能为空!")
|
||||
private Long cityId;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.orange.demo.app.dto;
|
||||
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -16,165 +14,141 @@ import java.util.Date;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentActionStatsDto对象")
|
||||
@Data
|
||||
public class StudentActionStatsDto {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id", required = true)
|
||||
@NotNull(message = "数据验证失败,主键Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long statsId;
|
||||
|
||||
/**
|
||||
* 统计日期。
|
||||
*/
|
||||
@ApiModelProperty(value = "统计日期", required = true)
|
||||
@NotNull(message = "数据验证失败,统计日期不能为空!")
|
||||
private Date statsDate;
|
||||
|
||||
/**
|
||||
* 统计小时。
|
||||
*/
|
||||
@ApiModelProperty(value = "统计小时")
|
||||
private Date statsMonth;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所属年级不能为空!")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 学生所在省Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生所在省Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所在省份不能为空!")
|
||||
private Long provinceId;
|
||||
|
||||
/**
|
||||
* 学生所在城市Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生所在城市Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所在城市不能为空!", groups = {UpdateGroup.class})
|
||||
private Long cityId;
|
||||
|
||||
/**
|
||||
* 购课学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购课学币数量", required = true)
|
||||
@NotNull(message = "数据验证失败,购课学币数量不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyCourseAmount;
|
||||
|
||||
/**
|
||||
* 购买课程次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买课程次数", required = true)
|
||||
@NotNull(message = "数据验证失败,购买课程次数不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyCourseCount;
|
||||
|
||||
/**
|
||||
* 购买视频学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买视频学币数量", required = true)
|
||||
@NotNull(message = "数据验证失败,购买视频学币数量不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyVideoAmount;
|
||||
|
||||
/**
|
||||
* 购买视频次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买视频次数", required = true)
|
||||
@NotNull(message = "数据验证失败,购买视频次数不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyVideoCount;
|
||||
|
||||
/**
|
||||
* 购买作业学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买作业学币数量", required = true)
|
||||
@NotNull(message = "数据验证失败,购买作业学币数量不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyPaperAmount;
|
||||
|
||||
/**
|
||||
* 购买作业次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买作业次数", required = true)
|
||||
@NotNull(message = "数据验证失败,购买作业次数不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyPaperCount;
|
||||
|
||||
/**
|
||||
* 购买献花数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花数量", required = true)
|
||||
@NotNull(message = "数据验证失败,购买献花数量不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyFlowerAmount;
|
||||
|
||||
/**
|
||||
* 购买献花次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花次数", required = true)
|
||||
@NotNull(message = "数据验证失败,购买献花次数不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer buyFlowerCount;
|
||||
|
||||
/**
|
||||
* 充值学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "充值学币数量", required = true)
|
||||
@NotNull(message = "数据验证失败,充值学币数量不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer rechargeCoinAmount;
|
||||
|
||||
/**
|
||||
* 充值学币次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "充值学币次数", required = true)
|
||||
@NotNull(message = "数据验证失败,充值学币次数不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer rechargeCoinCount;
|
||||
|
||||
/**
|
||||
* 线下课程上课次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "线下课程上课次数", required = true)
|
||||
@NotNull(message = "数据验证失败,线下课程上课次数不能为空!")
|
||||
private Integer doCourseCount;
|
||||
|
||||
/**
|
||||
* 观看视频次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "观看视频次数", required = true)
|
||||
@NotNull(message = "数据验证失败,观看视频次数不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer watchVideoCount;
|
||||
|
||||
/**
|
||||
* 购买献花消费学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花消费学币数量", required = true)
|
||||
@NotNull(message = "数据验证失败,购买献花消费学币数量不能为空!")
|
||||
private Integer watchVideoTotalSecond;
|
||||
|
||||
/**
|
||||
* 做题数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "做题数量", required = true)
|
||||
@NotNull(message = "数据验证失败,做题数量不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer doExerciseCount;
|
||||
|
||||
/**
|
||||
* 做题正确的数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "做题正确的数量", required = true)
|
||||
@NotNull(message = "数据验证失败,做题正确的数量不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer doExerciseCorrectCount;
|
||||
|
||||
/**
|
||||
* statsDate 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "statsDate 范围过滤起始值(>=)")
|
||||
private String statsDateStart;
|
||||
|
||||
/**
|
||||
* statsDate 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "statsDate 范围过滤结束值(<=)")
|
||||
private String statsDateEnd;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.application.common.constant.StudentActionType;
|
||||
import com.orange.demo.application.common.constant.DeviceType;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -19,49 +17,42 @@ import java.util.Date;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentActionTransDto对象")
|
||||
@Data
|
||||
public class StudentActionTransDto {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id", required = true)
|
||||
@NotNull(message = "数据验证失败,主键Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long transId;
|
||||
|
||||
/**
|
||||
* 学生Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生Id", required = true)
|
||||
@NotNull(message = "数据验证失败,学生Id不能为空!")
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 学生名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生名称", required = true)
|
||||
@NotBlank(message = "数据验证失败,学生名称不能为空!")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 学生校区。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生校区", required = true)
|
||||
@NotNull(message = "数据验证失败,学生校区不能为空!")
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,学生年级不能为空!")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 行为类型(0: 充值 1: 购课 2: 上课签到 3: 上课签退 4: 看视频课 5: 做作业 6: 刷题 7: 献花)。
|
||||
*/
|
||||
@ApiModelProperty(value = "行为类型(0: 充值 1: 购课 2: 上课签到 3: 上课签退 4: 看视频课 5: 做作业 6: 刷题 7: 献花)", required = true)
|
||||
@NotNull(message = "数据验证失败,行为类型不能为空!")
|
||||
@ConstDictRef(constDictClass = StudentActionType.class, message = "数据验证失败,行为类型为无效值!")
|
||||
private Integer actionType;
|
||||
@@ -69,7 +60,6 @@ public class StudentActionTransDto {
|
||||
/**
|
||||
* 设备类型(0: iOS 1: Android 2: PC)。
|
||||
*/
|
||||
@ApiModelProperty(value = "设备类型(0: iOS 1: Android 2: PC)", required = true)
|
||||
@NotNull(message = "数据验证失败,设备类型不能为空!")
|
||||
@ConstDictRef(constDictClass = DeviceType.class, message = "数据验证失败,设备类型为无效值!")
|
||||
private Integer deviceType;
|
||||
@@ -77,61 +67,51 @@ public class StudentActionTransDto {
|
||||
/**
|
||||
* 看视频秒数。
|
||||
*/
|
||||
@ApiModelProperty(value = "看视频秒数")
|
||||
private Integer watchVideoSeconds;
|
||||
|
||||
/**
|
||||
* 购买献花数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花数量")
|
||||
private Integer flowerCount;
|
||||
|
||||
/**
|
||||
* 购买作业数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买作业数量")
|
||||
private Integer paperCount;
|
||||
|
||||
/**
|
||||
* 购买视频数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买视频数量")
|
||||
private Integer videoCount;
|
||||
|
||||
/**
|
||||
* 购买课程数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买课程数量")
|
||||
private Integer courseCount;
|
||||
|
||||
/**
|
||||
* 充值学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "充值学币数量")
|
||||
private Integer coinCount;
|
||||
|
||||
/**
|
||||
* 做题是否正确标记。
|
||||
*/
|
||||
@ApiModelProperty(value = "做题是否正确标记")
|
||||
private Integer exerciseCorrectFlag;
|
||||
|
||||
/**
|
||||
* 发生时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "发生时间", required = true)
|
||||
@NotNull(message = "数据验证失败,发生时间不能为空!")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "createTime 范围过滤起始值(>=)")
|
||||
private String createTimeStart;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "createTime 范围过滤结束值(<=)")
|
||||
private String createTimeEnd;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.app.model.constant.ClassLevel;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -16,49 +14,42 @@ import javax.validation.constraints.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentClassDto对象")
|
||||
@Data
|
||||
public class StudentClassDto {
|
||||
|
||||
/**
|
||||
* 班级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,班级Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long classId;
|
||||
|
||||
/**
|
||||
* 班级名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级名称", required = true)
|
||||
@NotBlank(message = "数据验证失败,班级名称不能为空!")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 学校Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学校Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所属校区不能为空!")
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 学生班长Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生班长Id", required = true)
|
||||
@NotNull(message = "数据验证失败,学生班长不能为空!")
|
||||
private Long leaderId;
|
||||
|
||||
/**
|
||||
* 已完成课时数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "已完成课时数量", required = true)
|
||||
@NotNull(message = "数据验证失败,已完成课时不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer finishClassHour;
|
||||
|
||||
/**
|
||||
* 班级级别(0: 初级班 1: 培优班 2: 冲刺提分班 3: 竞赛班)。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级级别(0: 初级班 1: 培优班 2: 冲刺提分班 3: 竞赛班)", required = true)
|
||||
@NotNull(message = "数据验证失败,班级级别不能为空!")
|
||||
@ConstDictRef(constDictClass = ClassLevel.class, message = "数据验证失败,班级级别为无效值!")
|
||||
private Integer classLevel;
|
||||
|
||||
@@ -6,8 +6,6 @@ import com.orange.demo.application.common.constant.Gender;
|
||||
import com.orange.demo.application.common.constant.ExpLevel;
|
||||
import com.orange.demo.application.common.constant.StudentStatus;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -20,56 +18,48 @@ import java.util.Date;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentDto对象")
|
||||
@Data
|
||||
public class StudentDto {
|
||||
|
||||
/**
|
||||
* 学生Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生Id", required = true)
|
||||
@NotNull(message = "数据验证失败,学生Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 登录手机。
|
||||
*/
|
||||
@ApiModelProperty(value = "登录手机", required = true)
|
||||
@NotBlank(message = "数据验证失败,手机号码不能为空!")
|
||||
private String loginMobile;
|
||||
|
||||
/**
|
||||
* 学生姓名。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生姓名", required = true)
|
||||
@NotBlank(message = "数据验证失败,学生姓名不能为空!")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 所在省份Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在省份Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所在省份不能为空!")
|
||||
private Long provinceId;
|
||||
|
||||
/**
|
||||
* 所在城市Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在城市Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所在城市不能为空!")
|
||||
private Long cityId;
|
||||
|
||||
/**
|
||||
* 区县Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "区县Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所在区县不能为空!")
|
||||
private Long districtId;
|
||||
|
||||
/**
|
||||
* 学生性别 (0: 女生 1: 男生)。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生性别 (0: 女生 1: 男生)", required = true)
|
||||
@NotNull(message = "数据验证失败,学生性别不能为空!")
|
||||
@ConstDictRef(constDictClass = Gender.class, message = "数据验证失败,学生性别为无效值!")
|
||||
private Integer gender;
|
||||
@@ -77,14 +67,12 @@ public class StudentDto {
|
||||
/**
|
||||
* 生日。
|
||||
*/
|
||||
@ApiModelProperty(value = "生日", required = true)
|
||||
@NotNull(message = "数据验证失败,出生日期不能为空!")
|
||||
private Date birthday;
|
||||
|
||||
/**
|
||||
* 经验等级 (0: 初级 1: 中级 2: 高级 3: 资深)。
|
||||
*/
|
||||
@ApiModelProperty(value = "经验等级 (0: 初级 1: 中级 2: 高级 3: 资深)", required = true)
|
||||
@NotNull(message = "数据验证失败,经验等级不能为空!")
|
||||
@ConstDictRef(constDictClass = ExpLevel.class, message = "数据验证失败,经验等级为无效值!")
|
||||
private Integer experienceLevel;
|
||||
@@ -92,35 +80,30 @@ public class StudentDto {
|
||||
/**
|
||||
* 总共充值学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "总共充值学币数量", required = true)
|
||||
@NotNull(message = "数据验证失败,充值学币不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer totalCoin;
|
||||
|
||||
/**
|
||||
* 可用学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "可用学币数量", required = true)
|
||||
@NotNull(message = "数据验证失败,剩余学币不能为空!", groups = {UpdateGroup.class})
|
||||
private Integer leftCoin;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id", required = true)
|
||||
@NotNull(message = "数据验证失败,年级不能为空!")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 校区Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "校区Id", required = true)
|
||||
@NotNull(message = "数据验证失败,所属校区不能为空!")
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 学生状态 (0: 正常 1: 锁定 2: 注销)。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生状态 (0: 正常 1: 锁定 2: 注销)", required = true)
|
||||
@NotNull(message = "数据验证失败,学生状态不能为空!", groups = {UpdateGroup.class})
|
||||
@ConstDictRef(constDictClass = StudentStatus.class, message = "数据验证失败,学生状态为无效值!")
|
||||
private Integer status;
|
||||
@@ -128,30 +111,25 @@ public class StudentDto {
|
||||
/**
|
||||
* birthday 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "birthday 范围过滤起始值(>=)")
|
||||
private String birthdayStart;
|
||||
|
||||
/**
|
||||
* birthday 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "birthday 范围过滤结束值(<=)")
|
||||
private String birthdayEnd;
|
||||
|
||||
/**
|
||||
* registerTime 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "registerTime 范围过滤起始值(>=)")
|
||||
private String registerTimeStart;
|
||||
|
||||
/**
|
||||
* registerTime 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "registerTime 范围过滤结束值(<=)")
|
||||
private String registerTimeEnd;
|
||||
|
||||
/**
|
||||
* login_mobile / student_name LIKE搜索字符串。
|
||||
*/
|
||||
@ApiModelProperty(value = "LIKE模糊搜索字符串")
|
||||
private String searchString;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.app.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.common.core.annotation.DeletedFlagColumn;
|
||||
import lombok.Data;
|
||||
import javax.persistence.*;
|
||||
@@ -32,7 +31,6 @@ public class Grade {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
private Integer status;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.app.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.app.model.constant.ClassLevel;
|
||||
import com.orange.demo.common.core.annotation.RelationDict;
|
||||
import com.orange.demo.common.core.annotation.RelationConstDict;
|
||||
@@ -77,7 +76,6 @@ public class StudentClass {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
private Integer status;
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@ package com.orange.demo.app.service.impl;
|
||||
|
||||
import com.orange.demo.common.core.base.service.BaseDictService;
|
||||
import com.orange.demo.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orange.demo.common.core.cache.MapDictionaryCache;
|
||||
import com.orange.demo.common.redis.cache.RedisDictionaryCache;
|
||||
import com.orange.demo.app.service.GradeService;
|
||||
import com.orange.demo.app.dao.GradeMapper;
|
||||
import com.orange.demo.app.model.Grade;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* 年级字典数据操作服务类。
|
||||
@@ -20,10 +22,17 @@ public class GradeServiceImpl extends BaseDictService<Grade, Integer> implements
|
||||
|
||||
@Autowired
|
||||
private GradeMapper gradeMapper;
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
public GradeServiceImpl() {
|
||||
super();
|
||||
this.dictionaryCache = MapDictionaryCache.create(Grade::getGradeId);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.dictionaryCache = RedisDictionaryCache.create(
|
||||
redissonClient, "Grade", Grade.class, Grade::getGradeId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -10,31 +8,26 @@ import lombok.Data;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("行政区划实体对象")
|
||||
@Data
|
||||
public class AreaCodeVo {
|
||||
|
||||
/**
|
||||
* 行政区划主键Id
|
||||
*/
|
||||
@ApiModelProperty(value = "行政区划主键Id", required = true)
|
||||
private Long areaId;
|
||||
|
||||
/**
|
||||
* 行政区划名称
|
||||
*/
|
||||
@ApiModelProperty(value = "行政区划名称")
|
||||
private String areaName;
|
||||
|
||||
/**
|
||||
* 行政区划级别 (1: 省级别 2: 市级别 3: 区级别)
|
||||
*/
|
||||
@ApiModelProperty(value = "行政区划级别")
|
||||
private Integer areaLevel;
|
||||
|
||||
/**
|
||||
* 父级行政区划Id
|
||||
*/
|
||||
@ApiModelProperty(value = "父级行政区划Id")
|
||||
private Long parentId;
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -10,25 +8,21 @@ import lombok.Data;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("ClassCourseVO实体对象")
|
||||
@Data
|
||||
public class ClassCourseVo {
|
||||
|
||||
/**
|
||||
* 班级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级Id")
|
||||
private Long classId;
|
||||
|
||||
/**
|
||||
* 课程Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程Id")
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 课程顺序(数值越小越靠前)。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程顺序(数值越小越靠前)")
|
||||
private Integer courseOrder;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -10,19 +8,16 @@ import lombok.Data;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("ClassStudentVO实体对象")
|
||||
@Data
|
||||
public class ClassStudentVo {
|
||||
|
||||
/**
|
||||
* 班级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级Id")
|
||||
private Long classId;
|
||||
|
||||
/**
|
||||
* 学生Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生Id")
|
||||
private Long studentId;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -13,79 +11,66 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("CourseTransStatsVO实体对象")
|
||||
@Data
|
||||
public class CourseTransStatsVo {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id")
|
||||
private Long statsId;
|
||||
|
||||
/**
|
||||
* 统计日期。
|
||||
*/
|
||||
@ApiModelProperty(value = "统计日期")
|
||||
private Date statsDate;
|
||||
|
||||
/**
|
||||
* 科目Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "科目Id")
|
||||
private Integer subjectId;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 年级名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级名称")
|
||||
private String gradeName;
|
||||
|
||||
/**
|
||||
* 课程Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程Id")
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 课程名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程名称")
|
||||
private String courseName;
|
||||
|
||||
/**
|
||||
* 学生上课次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生上课次数")
|
||||
private Integer studentAttendCount;
|
||||
|
||||
/**
|
||||
* 学生献花数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生献花数量")
|
||||
private Integer studentFlowerAmount;
|
||||
|
||||
/**
|
||||
* 学生献花次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生献花次数")
|
||||
private Integer studentFlowerCount;
|
||||
|
||||
/**
|
||||
* gradeId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "gradeId 字典关联数据")
|
||||
private Map<String, Object> gradeIdDictMap;
|
||||
|
||||
/**
|
||||
* subjectId 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "subjectId 常量字典关联数据")
|
||||
private Map<String, Object> subjectIdDictMap;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -14,103 +12,86 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("CourseVO实体对象")
|
||||
@Data
|
||||
public class CourseVo {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id")
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 课程名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程名称")
|
||||
private String courseName;
|
||||
|
||||
/**
|
||||
* 课程价格。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程价格")
|
||||
private BigDecimal price;
|
||||
|
||||
/**
|
||||
* 课程描述。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 课程难度(0: 容易 1: 普通 2: 很难)。
|
||||
*/
|
||||
@ApiModelProperty(value = "课程难度(0: 容易 1: 普通 2: 很难)")
|
||||
private Integer difficulty;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 学科Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学科Id")
|
||||
private Integer subjectId;
|
||||
|
||||
/**
|
||||
* 课时数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "课时数量")
|
||||
private Integer classHour;
|
||||
|
||||
/**
|
||||
* 多张课程图片地址。
|
||||
*/
|
||||
@ApiModelProperty(value = "多张课程图片地址")
|
||||
private String pictureUrl;
|
||||
|
||||
/**
|
||||
* 创建用户Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建用户Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 最后修改时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "最后修改时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* courseId 的多对多关联表数据对象,数据对应类型为ClassCourseVo。
|
||||
*/
|
||||
@ApiModelProperty(value = "courseId 的多对多关联表数据对象,数据对应类型为ClassCourseVo")
|
||||
private Map<String, Object> classCourse;
|
||||
|
||||
/**
|
||||
* gradeId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "gradeId 字典关联数据")
|
||||
private Map<String, Object> gradeIdDictMap;
|
||||
|
||||
/**
|
||||
* difficulty 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "difficulty 常量字典关联数据")
|
||||
private Map<String, Object> difficultyDictMap;
|
||||
|
||||
/**
|
||||
* subjectId 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "subjectId 常量字典关联数据")
|
||||
private Map<String, Object> subjectIdDictMap;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -10,19 +8,16 @@ import lombok.Data;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("GradeVO实体对象")
|
||||
@Data
|
||||
public class GradeVo {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 年级名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级名称")
|
||||
private String gradeName;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -12,43 +10,36 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("SchoolInfoVO实体对象")
|
||||
@Data
|
||||
public class SchoolInfoVo {
|
||||
|
||||
/**
|
||||
* 学校Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学校Id")
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 学校名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "学校名称")
|
||||
private String schoolName;
|
||||
|
||||
/**
|
||||
* 所在省Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在省Id")
|
||||
private Long provinceId;
|
||||
|
||||
/**
|
||||
* 所在城市Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在城市Id")
|
||||
private Long cityId;
|
||||
|
||||
/**
|
||||
* provinceId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "provinceId 字典关联数据")
|
||||
private Map<String, Object> provinceIdDictMap;
|
||||
|
||||
/**
|
||||
* cityId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "cityId 字典关联数据")
|
||||
private Map<String, Object> cityIdDictMap;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -13,151 +11,126 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentActionStatsVO实体对象")
|
||||
@Data
|
||||
public class StudentActionStatsVo {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id")
|
||||
private Long statsId;
|
||||
|
||||
/**
|
||||
* 统计日期。
|
||||
*/
|
||||
@ApiModelProperty(value = "统计日期")
|
||||
private Date statsDate;
|
||||
|
||||
/**
|
||||
* 统计小时。
|
||||
*/
|
||||
@ApiModelProperty(value = "统计小时")
|
||||
private Date statsMonth;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 学生所在省Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生所在省Id")
|
||||
private Long provinceId;
|
||||
|
||||
/**
|
||||
* 学生所在城市Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生所在城市Id")
|
||||
private Long cityId;
|
||||
|
||||
/**
|
||||
* 购课学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购课学币数量")
|
||||
private Integer buyCourseAmount;
|
||||
|
||||
/**
|
||||
* 购买课程次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买课程次数")
|
||||
private Integer buyCourseCount;
|
||||
|
||||
/**
|
||||
* 购买视频学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买视频学币数量")
|
||||
private Integer buyVideoAmount;
|
||||
|
||||
/**
|
||||
* 购买视频次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买视频次数")
|
||||
private Integer buyVideoCount;
|
||||
|
||||
/**
|
||||
* 购买作业学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买作业学币数量")
|
||||
private Integer buyPaperAmount;
|
||||
|
||||
/**
|
||||
* 购买作业次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买作业次数")
|
||||
private Integer buyPaperCount;
|
||||
|
||||
/**
|
||||
* 购买献花数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花数量")
|
||||
private Integer buyFlowerAmount;
|
||||
|
||||
/**
|
||||
* 购买献花次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花次数")
|
||||
private Integer buyFlowerCount;
|
||||
|
||||
/**
|
||||
* 充值学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "充值学币数量")
|
||||
private Integer rechargeCoinAmount;
|
||||
|
||||
/**
|
||||
* 充值学币次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "充值学币次数")
|
||||
private Integer rechargeCoinCount;
|
||||
|
||||
/**
|
||||
* 线下课程上课次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "线下课程上课次数")
|
||||
private Integer doCourseCount;
|
||||
|
||||
/**
|
||||
* 观看视频次数。
|
||||
*/
|
||||
@ApiModelProperty(value = "观看视频次数")
|
||||
private Integer watchVideoCount;
|
||||
|
||||
/**
|
||||
* 购买献花消费学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花消费学币数量")
|
||||
private Integer watchVideoTotalSecond;
|
||||
|
||||
/**
|
||||
* 做题数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "做题数量")
|
||||
private Integer doExerciseCount;
|
||||
|
||||
/**
|
||||
* 做题正确的数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "做题正确的数量")
|
||||
private Integer doExerciseCorrectCount;
|
||||
|
||||
/**
|
||||
* gradeId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "gradeId 字典关联数据")
|
||||
private Map<String, Object> gradeIdDictMap;
|
||||
|
||||
/**
|
||||
* provinceId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "provinceId 字典关联数据")
|
||||
private Map<String, Object> provinceIdDictMap;
|
||||
|
||||
/**
|
||||
* cityId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "cityId 字典关联数据")
|
||||
private Map<String, Object> cityIdDictMap;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -13,121 +11,101 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentActionTransVO实体对象")
|
||||
@Data
|
||||
public class StudentActionTransVo {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "主键Id")
|
||||
private Long transId;
|
||||
|
||||
/**
|
||||
* 学生Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生Id")
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 学生名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生名称")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 学生校区。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生校区")
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 行为类型(0: 充值 1: 购课 2: 上课签到 3: 上课签退 4: 看视频课 5: 做作业 6: 刷题 7: 献花)。
|
||||
*/
|
||||
@ApiModelProperty(value = "行为类型(0: 充值 1: 购课 2: 上课签到 3: 上课签退 4: 看视频课 5: 做作业 6: 刷题 7: 献花)")
|
||||
private Integer actionType;
|
||||
|
||||
/**
|
||||
* 设备类型(0: iOS 1: Android 2: PC)。
|
||||
*/
|
||||
@ApiModelProperty(value = "设备类型(0: iOS 1: Android 2: PC)")
|
||||
private Integer deviceType;
|
||||
|
||||
/**
|
||||
* 看视频秒数。
|
||||
*/
|
||||
@ApiModelProperty(value = "看视频秒数")
|
||||
private Integer watchVideoSeconds;
|
||||
|
||||
/**
|
||||
* 购买献花数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买献花数量")
|
||||
private Integer flowerCount;
|
||||
|
||||
/**
|
||||
* 购买作业数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买作业数量")
|
||||
private Integer paperCount;
|
||||
|
||||
/**
|
||||
* 购买视频数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买视频数量")
|
||||
private Integer videoCount;
|
||||
|
||||
/**
|
||||
* 购买课程数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "购买课程数量")
|
||||
private Integer courseCount;
|
||||
|
||||
/**
|
||||
* 充值学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "充值学币数量")
|
||||
private Integer coinCount;
|
||||
|
||||
/**
|
||||
* 做题是否正确标记。
|
||||
*/
|
||||
@ApiModelProperty(value = "做题是否正确标记")
|
||||
private Integer exerciseCorrectFlag;
|
||||
|
||||
/**
|
||||
* 发生时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "发生时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* schoolId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "schoolId 字典关联数据")
|
||||
private Map<String, Object> schoolIdDictMap;
|
||||
|
||||
/**
|
||||
* gradeId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "gradeId 字典关联数据")
|
||||
private Map<String, Object> gradeIdDictMap;
|
||||
|
||||
/**
|
||||
* actionType 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "actionType 常量字典关联数据")
|
||||
private Map<String, Object> actionTypeDictMap;
|
||||
|
||||
/**
|
||||
* deviceType 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "deviceType 常量字典关联数据")
|
||||
private Map<String, Object> deviceTypeDictMap;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -13,73 +11,61 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentClassVO实体对象")
|
||||
@Data
|
||||
public class StudentClassVo {
|
||||
|
||||
/**
|
||||
* 班级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级Id")
|
||||
private Long classId;
|
||||
|
||||
/**
|
||||
* 班级名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级名称")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 学校Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学校Id")
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 学生班长Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生班长Id")
|
||||
private Long leaderId;
|
||||
|
||||
/**
|
||||
* 已完成课时数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "已完成课时数量")
|
||||
private Integer finishClassHour;
|
||||
|
||||
/**
|
||||
* 班级级别(0: 初级班 1: 培优班 2: 冲刺提分班 3: 竞赛班)。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级级别(0: 初级班 1: 培优班 2: 冲刺提分班 3: 竞赛班)")
|
||||
private Integer classLevel;
|
||||
|
||||
/**
|
||||
* 创建用户。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建用户")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 班级创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "班级创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* schoolId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "schoolId 字典关联数据")
|
||||
private Map<String, Object> schoolIdDictMap;
|
||||
|
||||
/**
|
||||
* leaderId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "leaderId 字典关联数据")
|
||||
private Map<String, Object> leaderIdDictMap;
|
||||
|
||||
/**
|
||||
* classLevel 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "classLevel 常量字典关联数据")
|
||||
private Map<String, Object> classLevelDictMap;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -13,145 +11,121 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("StudentVO实体对象")
|
||||
@Data
|
||||
public class StudentVo {
|
||||
|
||||
/**
|
||||
* 学生Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生Id")
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 登录手机。
|
||||
*/
|
||||
@ApiModelProperty(value = "登录手机")
|
||||
private String loginMobile;
|
||||
|
||||
/**
|
||||
* 学生姓名。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生姓名")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 所在省份Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在省份Id")
|
||||
private Long provinceId;
|
||||
|
||||
/**
|
||||
* 所在城市Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "所在城市Id")
|
||||
private Long cityId;
|
||||
|
||||
/**
|
||||
* 区县Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "区县Id")
|
||||
private Long districtId;
|
||||
|
||||
/**
|
||||
* 学生性别 (0: 女生 1: 男生)。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生性别 (0: 女生 1: 男生)")
|
||||
private Integer gender;
|
||||
|
||||
/**
|
||||
* 生日。
|
||||
*/
|
||||
@ApiModelProperty(value = "生日")
|
||||
private Date birthday;
|
||||
|
||||
/**
|
||||
* 经验等级 (0: 初级 1: 中级 2: 高级 3: 资深)。
|
||||
*/
|
||||
@ApiModelProperty(value = "经验等级 (0: 初级 1: 中级 2: 高级 3: 资深)")
|
||||
private Integer experienceLevel;
|
||||
|
||||
/**
|
||||
* 总共充值学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "总共充值学币数量")
|
||||
private Integer totalCoin;
|
||||
|
||||
/**
|
||||
* 可用学币数量。
|
||||
*/
|
||||
@ApiModelProperty(value = "可用学币数量")
|
||||
private Integer leftCoin;
|
||||
|
||||
/**
|
||||
* 年级Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "年级Id")
|
||||
private Integer gradeId;
|
||||
|
||||
/**
|
||||
* 校区Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "校区Id")
|
||||
private Long schoolId;
|
||||
|
||||
/**
|
||||
* 注册时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "注册时间")
|
||||
private Date registerTime;
|
||||
|
||||
/**
|
||||
* 学生状态 (0: 正常 1: 锁定 2: 注销)。
|
||||
*/
|
||||
@ApiModelProperty(value = "学生状态 (0: 正常 1: 锁定 2: 注销)")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* provinceId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "provinceId 字典关联数据")
|
||||
private Map<String, Object> provinceIdDictMap;
|
||||
|
||||
/**
|
||||
* cityId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "cityId 字典关联数据")
|
||||
private Map<String, Object> cityIdDictMap;
|
||||
|
||||
/**
|
||||
* districtId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "districtId 字典关联数据")
|
||||
private Map<String, Object> districtIdDictMap;
|
||||
|
||||
/**
|
||||
* gradeId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "gradeId 字典关联数据")
|
||||
private Map<String, Object> gradeIdDictMap;
|
||||
|
||||
/**
|
||||
* schoolId 字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "schoolId 字典关联数据")
|
||||
private Map<String, Object> schoolIdDictMap;
|
||||
|
||||
/**
|
||||
* gender 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "gender 常量字典关联数据")
|
||||
private Map<String, Object> genderDictMap;
|
||||
|
||||
/**
|
||||
* experienceLevel 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "experienceLevel 常量字典关联数据")
|
||||
private Map<String, Object> experienceLevelDictMap;
|
||||
|
||||
/**
|
||||
* status 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "status 常量字典关联数据")
|
||||
private Map<String, Object> statusDictMap;
|
||||
}
|
||||
|
||||
@@ -43,4 +43,9 @@ public class ApplicationConfig {
|
||||
* 授信ip列表,没有填写表示全部信任。多个ip之间逗号分隔,如: http://10.10.10.1:8080,http://10.10.10.2:8080
|
||||
*/
|
||||
private String credentialIpList;
|
||||
/**
|
||||
* Session的用户权限在Redis中的过期时间(秒)。
|
||||
* 缺省值是 one day
|
||||
*/
|
||||
private int permRedisExpiredSeconds = 86400;
|
||||
}
|
||||
|
||||
@@ -11,13 +11,16 @@ import com.orange.demo.common.core.object.ResponseResult;
|
||||
import com.orange.demo.common.core.object.TokenData;
|
||||
import com.orange.demo.common.core.util.ApplicationContextHolder;
|
||||
import com.orange.demo.common.core.util.JwtUtil;
|
||||
import com.orange.demo.common.core.cache.SessionCacheHelper;
|
||||
import com.orange.demo.common.core.util.RedisKeyUtil;
|
||||
import com.orange.demo.common.redis.cache.SessionCacheHelper;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -36,13 +39,15 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class AuthenticationInterceptor implements HandlerInterceptor {
|
||||
|
||||
private ApplicationConfig appConfig =
|
||||
private final ApplicationConfig appConfig =
|
||||
ApplicationContextHolder.getBean("applicationConfig");
|
||||
|
||||
private SessionCacheHelper cacheHelper =
|
||||
private final JedisPool jedisPool = ApplicationContextHolder.getBean(JedisPool.class);
|
||||
|
||||
private final SessionCacheHelper cacheHelper =
|
||||
ApplicationContextHolder.getBean("sessionCacheHelper");
|
||||
|
||||
private SysPermService sysPermService =
|
||||
private final SysPermService sysPermService =
|
||||
ApplicationContextHolder.getBean(SysPermService.class);
|
||||
|
||||
private static SysPermWhitelistService sysPermWhitelistService =
|
||||
@@ -90,13 +95,13 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
|
||||
TokenData.addToRequest(tokenData);
|
||||
// 如果url在权限资源白名单中,则不需要进行鉴权操作
|
||||
if (Boolean.FALSE.equals(tokenData.getIsAdmin()) && !whitelistPermSet.contains(url)) {
|
||||
Set<String> urlSet = sysPermService.getCacheableSysPermSetByUserId(
|
||||
tokenData.getSessionId(), tokenData.getUserId());
|
||||
if (!urlSet.contains(url)) {
|
||||
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
this.outputResponseMessage(response,
|
||||
ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
|
||||
return false;
|
||||
try (Jedis jedis = jedisPool.getResource()) {
|
||||
if (!jedis.sismember(RedisKeyUtil.makeSessionPermIdKeyForRedis(tokenData.getSessionId()), url)) {
|
||||
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
this.outputResponseMessage(response,
|
||||
ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (JwtUtil.needToRefresh(c)) {
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package com.orange.demo.upms.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orange.demo.config.ApplicationConfig;
|
||||
import com.orange.demo.upms.service.*;
|
||||
@@ -19,7 +15,7 @@ import com.orange.demo.common.core.constant.ErrorCodeEnum;
|
||||
import com.orange.demo.common.core.object.ResponseResult;
|
||||
import com.orange.demo.common.core.object.TokenData;
|
||||
import com.orange.demo.common.core.util.*;
|
||||
import com.orange.demo.common.core.cache.SessionCacheHelper;
|
||||
import com.orange.demo.common.redis.cache.SessionCacheHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -34,8 +30,6 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiSupport(order = 1)
|
||||
@Api(tags = "用户登录接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/login")
|
||||
@@ -63,12 +57,6 @@ public class LoginController {
|
||||
* @param password 密码。
|
||||
* @return 应答结果对象,其中包括JWT的Token数据,以及菜单列表。
|
||||
*/
|
||||
@ApiImplicitParams({
|
||||
// 这里包含密码密文,仅用于方便开发期间的接口测试,集成测试和发布阶段,需要将当前注解去掉。
|
||||
// 如果您重新生成了公钥和私钥,请替换password的缺省值。
|
||||
@ApiImplicitParam(name = "loginName", defaultValue = "admin"),
|
||||
@ApiImplicitParam(name = "password", defaultValue = "IP3ccke3GhH45iGHB5qP9p7iZw6xUyj28Ju10rnBiPKOI35sc%2BjI7%2FdsjOkHWMfUwGYGfz8ik31HC2Ruk%2Fhkd9f6RPULTHj7VpFdNdde2P9M4mQQnFBAiPM7VT9iW3RyCtPlJexQ3nAiA09OqG%2F0sIf1kcyveSrulxembARDbDo%3D")
|
||||
})
|
||||
@NoAuthInterface
|
||||
@PostMapping("/doLogin")
|
||||
public ResponseResult<JSONObject> doLogin(
|
||||
@@ -104,18 +92,20 @@ public class LoginController {
|
||||
tokenData.setShowName(user.getShowName());
|
||||
tokenData.setIsAdmin(isAdmin);
|
||||
cacheHelper.putTokenData(sessionId, tokenData);
|
||||
List<SysMenu> menuList;
|
||||
Collection<SysMenu> menuList;
|
||||
Collection<String> permCodeList;
|
||||
if (isAdmin) {
|
||||
menuList = sysMenuService.getAllMenuList();
|
||||
permCodeList = sysPermCodeService.getAllPermCodeList();
|
||||
} else {
|
||||
menuList = sysMenuService.getMenuListByUserId(user.getUserId());
|
||||
List<String> permCodeList = sysPermCodeService.getPermCodeListByUserId(user.getUserId());
|
||||
jsonData.put("permCodeList", permCodeList);
|
||||
permCodeList = sysPermCodeService.getPermCodeListByUserId(user.getUserId());
|
||||
}
|
||||
jsonData.put("menuList", menuList);
|
||||
jsonData.put("permCodeList", permCodeList);
|
||||
if (user.getUserType() != SysUserType.TYPE_ADMIN) {
|
||||
// 缓存用户的权限资源
|
||||
sysPermService.putUserSysPermCache(sessionId, user.getUserId(), isAdmin);
|
||||
sysPermService.putUserSysPermCache(sessionId, user.getUserId());
|
||||
}
|
||||
return ResponseResult.success(jsonData);
|
||||
}
|
||||
@@ -128,6 +118,7 @@ public class LoginController {
|
||||
@PostMapping("/doLogout")
|
||||
public ResponseResult<Void> doLogout() {
|
||||
TokenData tokenData = TokenData.takeFromRequest();
|
||||
sysPermService.removeUserSysPermCache(tokenData.getSessionId());
|
||||
cacheHelper.removeAllSessionCache(tokenData.getSessionId());
|
||||
return ResponseResult.success();
|
||||
}
|
||||
@@ -148,15 +139,17 @@ public class LoginController {
|
||||
JSONObject jsonData = new JSONObject();
|
||||
jsonData.put("showName", tokenData.getShowName());
|
||||
jsonData.put("isAdmin", tokenData.getIsAdmin());
|
||||
List<SysMenu> menuList;
|
||||
Collection<SysMenu> menuList;
|
||||
Collection<String> permCodeList;
|
||||
if (tokenData.getIsAdmin()) {
|
||||
menuList = sysMenuService.getAllMenuList();
|
||||
permCodeList = sysPermCodeService.getAllPermCodeList();
|
||||
} else {
|
||||
menuList = sysMenuService.getMenuListByUserId(tokenData.getUserId());
|
||||
List<String> permCodeList = sysPermCodeService.getPermCodeListByUserId(tokenData.getUserId());
|
||||
jsonData.put("permCodeList", permCodeList);
|
||||
permCodeList = sysPermCodeService.getPermCodeListByUserId(tokenData.getUserId());
|
||||
}
|
||||
jsonData.put("menuList", menuList);
|
||||
jsonData.put("permCodeList", permCodeList);
|
||||
return ResponseResult.success(jsonData);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orange.demo.upms.dto.SysMenuDto;
|
||||
import com.orange.demo.upms.vo.SysMenuVo;
|
||||
@@ -24,7 +22,6 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "菜单管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysMenu")
|
||||
@@ -41,7 +38,6 @@ public class SysMenuController {
|
||||
* @return 应答结果对象,包含新增菜单的主键Id。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ApiOperationSupport(ignoreParameters = {"sysMenu.menuId"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(
|
||||
@MyRequestBody("sysMenu") SysMenuDto sysMenuDto, @MyRequestBody String permCodeIdListString) {
|
||||
@@ -126,9 +122,9 @@ public class SysMenuController {
|
||||
*
|
||||
* @return 应答结果对象,包含全部菜单数据列表。
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<List<SysMenuVo>> list() {
|
||||
List<SysMenu> sysMenuList = sysMenuService.getAllListByOrder("menuType", "showOrder");
|
||||
List<SysMenu> sysMenuList = sysMenuService.getAllListByOrder("showOrder");
|
||||
return ResponseResult.success(MyModelUtil.copyCollectionTo(sysMenuList, SysMenuVo.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orange.demo.upms.dto.SysPermCodeDto;
|
||||
import com.orange.demo.upms.vo.SysPermCodeVo;
|
||||
@@ -25,7 +23,6 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "权限字管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysPermCode")
|
||||
@@ -42,7 +39,6 @@ public class SysPermCodeController {
|
||||
* @return 应答结果对象,包含新增权限字的主键Id。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ApiOperationSupport(ignoreParameters = {"sysPermCode.permCodeId"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(
|
||||
@MyRequestBody("sysPermCode") SysPermCodeDto sysPermCodeDto, @MyRequestBody String permIdListString) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -27,7 +25,6 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "权限资源管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysPerm")
|
||||
@@ -42,7 +39,6 @@ public class SysPermController {
|
||||
* @param sysPermDto 新增权限资源对象。
|
||||
* @return 应答结果对象,包含新增权限资源的主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"sysPerm.permId"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody("sysPerm") SysPermDto sysPermDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysPermDto);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orange.demo.upms.dto.SysPermModuleDto;
|
||||
import com.orange.demo.upms.vo.SysPermModuleVo;
|
||||
@@ -29,7 +27,6 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "权限资源模块管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysPermModule")
|
||||
@@ -44,7 +41,6 @@ public class SysPermModuleController {
|
||||
* @param sysPermModuleDto 新增权限资源模块对象。
|
||||
* @return 应答结果对象,包含新增权限资源模块的主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"sysPermModule.moduleId"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody("sysPermModule") SysPermModuleDto sysPermModuleDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysPermModuleDto);
|
||||
@@ -121,7 +117,7 @@ public class SysPermModuleController {
|
||||
*
|
||||
* @return 应答结果对象,包含权限资源模块列表。
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<List<SysPermModuleVo>> list() {
|
||||
List<SysPermModule> permModuleList = sysPermModuleService.getAllListByOrder("showOrder");
|
||||
return ResponseResult.success(MyModelUtil.copyCollectionTo(permModuleList, SysPermModuleVo.class));
|
||||
@@ -132,7 +128,7 @@ public class SysPermModuleController {
|
||||
*
|
||||
* @return 应答结果对象,包含树状列表,结构为权限资源模块和权限资源之间的树状关系。
|
||||
*/
|
||||
@GetMapping("/listAll")
|
||||
@PostMapping("/listAll")
|
||||
public ResponseResult<List<Map<String, Object>>> listAll() {
|
||||
List<SysPermModule> sysPermModuleList = sysPermModuleService.getPermModuleAndPermList();
|
||||
List<Map<String, Object>> resultList = new LinkedList<>();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -32,7 +30,6 @@ import java.util.stream.Collectors;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "角色管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysRole")
|
||||
@@ -51,7 +48,6 @@ public class SysRoleController {
|
||||
* @return 应答结果对象,包含新增角色的主键Id。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ApiOperationSupport(ignoreParameters = {"sysRole.roleId", "sysRole.createTimeStart", "sysRole.createTimeEnd"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(
|
||||
@MyRequestBody("sysRole") SysRoleDto sysRoleDto, @MyRequestBody String menuIdListString) {
|
||||
@@ -80,7 +76,6 @@ public class SysRoleController {
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ApiOperationSupport(ignoreParameters = {"sysRole.createTimeStart", "sysRole.createTimeEnd"})
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(
|
||||
@MyRequestBody("sysRole") SysRoleDto sysRoleDto, @MyRequestBody String menuIdListString) {
|
||||
|
||||
@@ -12,8 +12,6 @@ import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.orange.demo.common.core.validator.AddGroup;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.orange.demo.config.ApplicationConfig;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -28,7 +26,6 @@ import javax.validation.groups.Default;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Api(tags = "用户管理管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysUser")
|
||||
@@ -49,10 +46,6 @@ public class SysUserController {
|
||||
* @return 应答结果对象,包含新增用户的主键Id。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"sysUser.userId",
|
||||
"sysUser.createTimeStart",
|
||||
"sysUser.createTimeEnd"})
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(
|
||||
@MyRequestBody("sysUser") SysUserDto sysUserDto, @MyRequestBody String roleIdListString) {
|
||||
@@ -78,9 +71,6 @@ public class SysUserController {
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"sysUser.createTimeStart",
|
||||
"sysUser.createTimeEnd"})
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(
|
||||
@MyRequestBody("sysUser") SysUserDto sysUserDto, @MyRequestBody String roleIdListString) {
|
||||
|
||||
@@ -20,7 +20,7 @@ public interface SysPermMapper extends BaseDaoMapper<SysPerm> {
|
||||
* @param userId 用户Id。
|
||||
* @return 该用户的权限标识列表。
|
||||
*/
|
||||
List<SysPerm> getPermListByUserId(@Param("userId") Long userId);
|
||||
List<String> getPermListByUserId(@Param("userId") Long userId);
|
||||
|
||||
/**
|
||||
* 查询权限资源地址的用户列表。同时返回详细的分配路径。
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<select id="getMenuListByUserId" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
DISTINCT m.*
|
||||
m.*
|
||||
FROM
|
||||
zz_sys_user_role ur,
|
||||
zz_sys_role_menu rm,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.orange.demo.upms.dao.SysMenuPermCodeMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orange.demo.upms.model.SysMenuPermCode">
|
||||
<result column="menu_id" jdbcType="BIGINT" property="menuId"/>
|
||||
<result column="perm_code_id" jdbcType="BIGINT" property="permCodeId"/>
|
||||
<id column="menu_id" jdbcType="BIGINT" property="menuId"/>
|
||||
<id column="perm_code_id" jdbcType="BIGINT" property="permCodeId"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<select id="getPermCodeListByUserId" resultType="java.lang.String">
|
||||
SELECT
|
||||
DISTINCT pc.perm_code
|
||||
pc.perm_code
|
||||
FROM
|
||||
zz_sys_user_role ur,
|
||||
zz_sys_role_menu rm,
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
<result column="deleted_flag" jdbcType="INTEGER" property="deletedFlag"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getPermListByUserId" resultMap="BaseResultMap">
|
||||
<select id="getPermListByUserId" resultType="java.lang.String">
|
||||
SELECT
|
||||
p.*
|
||||
p.url
|
||||
FROM
|
||||
zz_sys_user_role ur,
|
||||
zz_sys_role_menu rm,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.orange.demo.upms.dao.SysPermModuleMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orange.demo.upms.model.SysPermModule">
|
||||
<result column="module_id" jdbcType="BIGINT" property="moduleId"/>
|
||||
<id column="module_id" jdbcType="BIGINT" property="moduleId"/>
|
||||
<result column="parent_id" jdbcType="BIGINT" property="parentId"/>
|
||||
<result column="module_name" jdbcType="VARCHAR" property="moduleName"/>
|
||||
<result column="module_type" jdbcType="INTEGER" property="moduleType"/>
|
||||
@@ -34,9 +34,8 @@
|
||||
FROM
|
||||
zz_sys_perm_module pm
|
||||
LEFT JOIN
|
||||
zz_sys_perm p ON pm.module_id = p.module_id
|
||||
zz_sys_perm p ON pm.module_id = p.module_id AND p.deleted_flag = ${@com.orange.demo.common.core.constant.GlobalDeletedFlag@NORMAL}
|
||||
<where>
|
||||
AND p.deleted_flag = ${@com.orange.demo.common.core.constant.GlobalDeletedFlag@NORMAL}
|
||||
AND pm.deleted_flag = ${@com.orange.demo.common.core.constant.GlobalDeletedFlag@NORMAL}
|
||||
</where>
|
||||
ORDER BY
|
||||
|
||||
@@ -3,8 +3,6 @@ package com.orange.demo.upms.dto;
|
||||
import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.orange.demo.upms.model.constant.SysMenuType;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@@ -16,34 +14,29 @@ import javax.validation.constraints.NotNull;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("菜单Dto")
|
||||
@Data
|
||||
public class SysMenuDto {
|
||||
|
||||
/**
|
||||
* 菜单Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单Id", required = true)
|
||||
@NotNull(message = "菜单Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 父菜单Id,目录菜单的父菜单为null
|
||||
*/
|
||||
@ApiModelProperty(value = "父菜单Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单显示名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单显示名称", required = true)
|
||||
@NotBlank(message = "菜单显示名称不能为空!")
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单类型 (0: 目录 1: 菜单 2: 按钮 3: UI片段)。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单类型", required = true)
|
||||
@NotNull(message = "菜单类型不能为空!")
|
||||
@ConstDictRef(constDictClass = SysMenuType.class, message = "数据验证失败,菜单类型为无效值!")
|
||||
private Integer menuType;
|
||||
@@ -51,19 +44,16 @@ public class SysMenuDto {
|
||||
/**
|
||||
* 前端表单路由名称,仅用于menu_type为1的菜单类型。
|
||||
*/
|
||||
@ApiModelProperty(value = "前端表单路由名称")
|
||||
private String formRouterName;
|
||||
|
||||
/**
|
||||
* 菜单显示顺序 (值越小,排序越靠前)。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单显示顺序", required = true)
|
||||
@NotNull(message = "菜单显示顺序不能为空!")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 菜单图标。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单显示顺序")
|
||||
private String icon;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ package com.orange.demo.upms.dto;
|
||||
import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.orange.demo.upms.model.constant.SysPermCodeType;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@@ -16,34 +14,29 @@ import javax.validation.constraints.NotNull;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("权限字Dto")
|
||||
@Data
|
||||
public class SysPermCodeDto {
|
||||
|
||||
/**
|
||||
* 权限字Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字Id", required = true)
|
||||
@NotNull(message = "权限字Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long permCodeId;
|
||||
|
||||
/**
|
||||
* 权限字标识(一般为有含义的英文字符串)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字标识", required = true)
|
||||
@NotBlank(message = "权限字编码不能为空!")
|
||||
private String permCode;
|
||||
|
||||
/**
|
||||
* 上级权限字Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "上级权限字Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 权限字类型(0: 表单 1: UI片段 2: 操作)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字类型", required = true)
|
||||
@NotNull(message = "权限字类型不能为空!")
|
||||
@ConstDictRef(constDictClass = SysPermCodeType.class, message = "数据验证失败,权限类型为无效值!")
|
||||
private Integer permCodeType;
|
||||
@@ -51,14 +44,12 @@ public class SysPermCodeDto {
|
||||
/**
|
||||
* 显示名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示名称", required = true)
|
||||
@NotBlank(message = "权限字显示名称不能为空!")
|
||||
private String showName;
|
||||
|
||||
/**
|
||||
* 显示顺序(数值越小,越靠前)。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序", required = true)
|
||||
@NotNull(message = "权限字显示顺序不能为空!")
|
||||
private Integer showOrder;
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.orange.demo.upms.dto;
|
||||
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@@ -14,48 +12,41 @@ import javax.validation.constraints.NotNull;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("权限资源Dto")
|
||||
@Data
|
||||
public class SysPermDto {
|
||||
|
||||
/**
|
||||
* 权限资源Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限资源Id", required = true)
|
||||
@NotNull(message = "权限Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long permId;
|
||||
|
||||
/**
|
||||
* 权限资源名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限资源名称", required = true)
|
||||
@NotBlank(message = "权限资源名称不能为空!")
|
||||
private String permName;
|
||||
|
||||
/**
|
||||
* shiro格式的权限字,如(upms:sysUser:add)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字")
|
||||
private String permCode;
|
||||
|
||||
/**
|
||||
* 权限所在的权限模块Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限所在的权限模块Id")
|
||||
@NotNull(message = "权限模块Id不能为空!")
|
||||
private Long moduleId;
|
||||
|
||||
/**
|
||||
* 关联的URL。
|
||||
*/
|
||||
@ApiModelProperty(value = "关联的URL", required = true)
|
||||
@NotBlank(message = "权限关联的url不能为空!")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 权限在当前模块下的顺序,由小到大。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序", required = true)
|
||||
@NotNull(message = "权限显示顺序不能为空!")
|
||||
private Integer showOrder;
|
||||
}
|
||||
@@ -3,8 +3,6 @@ package com.orange.demo.upms.dto;
|
||||
import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import com.orange.demo.upms.model.constant.SysPermModuleType;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@@ -16,34 +14,29 @@ import javax.validation.constraints.NotNull;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("权限资源模块Dto")
|
||||
@Data
|
||||
public class SysPermModuleDto {
|
||||
|
||||
/**
|
||||
* 权限模块Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限模块Id", required = true)
|
||||
@NotNull(message = "权限模块Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long moduleId;
|
||||
|
||||
/**
|
||||
* 权限模块名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限模块名称", required = true)
|
||||
@NotBlank(message = "权限模块名称不能为空!")
|
||||
private String moduleName;
|
||||
|
||||
/**
|
||||
* 上级权限模块Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "上级权限模块Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 权限模块类型(0: 普通模块 1: Controller模块)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限模块类型", required = true)
|
||||
@NotNull(message = "模块类型不能为空!")
|
||||
@ConstDictRef(constDictClass = SysPermModuleType.class, message = "数据验证失败,权限模块类型为无效值!")
|
||||
private Integer moduleType;
|
||||
@@ -51,7 +44,6 @@ public class SysPermModuleDto {
|
||||
/**
|
||||
* 权限模块在当前层级下的顺序,由小到大。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序", required = true)
|
||||
@NotNull(message = "权限模块显示顺序不能为空!")
|
||||
private Integer showOrder;
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.orange.demo.upms.dto;
|
||||
|
||||
import com.orange.demo.common.core.validator.UpdateGroup;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -13,21 +11,18 @@ import javax.validation.constraints.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("角色Dto")
|
||||
@Data
|
||||
public class SysRoleDto {
|
||||
|
||||
/**
|
||||
* 角色Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "角色Id", required = true)
|
||||
@NotNull(message = "角色Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 角色名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "角色名称", required = true)
|
||||
@NotBlank(message = "角色名称不能为空!")
|
||||
private String roleName;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ import com.orange.demo.common.core.validator.ConstDictRef;
|
||||
import com.orange.demo.upms.model.constant.SysUserType;
|
||||
import com.orange.demo.upms.model.constant.SysUserStatus;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
@@ -18,42 +16,36 @@ import javax.validation.constraints.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("SysUserDto对象")
|
||||
@Data
|
||||
public class SysUserDto {
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户Id", required = true)
|
||||
@NotNull(message = "数据验证失败,用户Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 登录用户名。
|
||||
*/
|
||||
@ApiModelProperty(value = "登录用户名", required = true)
|
||||
@NotBlank(message = "数据验证失败,登录用户名不能为空!")
|
||||
private String loginName;
|
||||
|
||||
/**
|
||||
* 用户密码。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户密码", required = true)
|
||||
@NotBlank(message = "数据验证失败,用户密码不能为空!", groups = {AddGroup.class})
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 用户显示名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户显示名称", required = true)
|
||||
@NotBlank(message = "数据验证失败,用户显示名称不能为空!")
|
||||
private String showName;
|
||||
|
||||
/**
|
||||
* 用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)", required = true)
|
||||
@NotNull(message = "数据验证失败,用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)不能为空!")
|
||||
@ConstDictRef(constDictClass = SysUserType.class, message = "数据验证失败,用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)为无效值!")
|
||||
private Integer userType;
|
||||
@@ -61,13 +53,11 @@ public class SysUserDto {
|
||||
/**
|
||||
* 用户头像的Url。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户头像的Url")
|
||||
private String headImageUrl;
|
||||
|
||||
/**
|
||||
* 用户状态(0: 正常 1: 锁定)。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户状态(0: 正常 1: 锁定)", required = true)
|
||||
@NotNull(message = "数据验证失败,用户状态(0: 正常 1: 锁定)不能为空!")
|
||||
@ConstDictRef(constDictClass = SysUserStatus.class, message = "数据验证失败,用户状态(0: 正常 1: 锁定)为无效值!")
|
||||
private Integer userStatus;
|
||||
@@ -75,12 +65,10 @@ public class SysUserDto {
|
||||
/**
|
||||
* createTime 范围过滤起始值(>=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "createTime 范围过滤起始值(>=)")
|
||||
private String createTimeStart;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤结束值(<=)。
|
||||
*/
|
||||
@ApiModelProperty(value = "createTime 范围过滤结束值(<=)")
|
||||
private String createTimeEnd;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.upms.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.common.core.annotation.DeletedFlagColumn;
|
||||
import com.orange.demo.common.core.annotation.RelationManyToMany;
|
||||
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
|
||||
@@ -92,7 +91,6 @@ public class SysMenu {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
@Column(name = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.upms.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.common.core.annotation.DeletedFlagColumn;
|
||||
import com.orange.demo.common.core.annotation.RelationDict;
|
||||
import lombok.Data;
|
||||
@@ -75,7 +74,6 @@ public class SysPerm {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
@Column(name = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.upms.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.common.core.annotation.DeletedFlagColumn;
|
||||
import com.orange.demo.common.core.annotation.RelationManyToMany;
|
||||
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
|
||||
@@ -87,7 +86,6 @@ public class SysPermCode {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
@Column(name = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.upms.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.common.core.annotation.DeletedFlagColumn;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -75,7 +74,6 @@ public class SysPermModule {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
@Column(name = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.upms.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.common.core.annotation.DeletedFlagColumn;
|
||||
import com.orange.demo.common.core.annotation.RelationManyToMany;
|
||||
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
|
||||
@@ -63,7 +62,6 @@ public class SysRole {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
@Column(name = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.upms.model;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.orange.demo.upms.model.constant.SysUserType;
|
||||
import com.orange.demo.upms.model.constant.SysUserStatus;
|
||||
import com.orange.demo.common.core.annotation.RelationConstDict;
|
||||
@@ -72,7 +71,6 @@ public class SysUser {
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@DeletedFlagColumn
|
||||
@Column(name = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
@@ -46,15 +46,15 @@ public interface SysMenuService extends IBaseService<SysMenu, Long> {
|
||||
*
|
||||
* @return 全部菜单列表。
|
||||
*/
|
||||
List<SysMenu> getAllMenuList();
|
||||
Collection<SysMenu> getAllMenuList();
|
||||
|
||||
/**
|
||||
* 获取指定用户Id的菜单列表。
|
||||
* 获取指定用户Id的菜单列表,已去重。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @return 用户关联的菜单列表。
|
||||
*/
|
||||
List<SysMenu> getMenuListByUserId(Long userId);
|
||||
Collection<SysMenu> getMenuListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 判断当前菜单是否存在子菜单。
|
||||
|
||||
@@ -15,12 +15,19 @@ import java.util.*;
|
||||
public interface SysPermCodeService extends IBaseService<SysPermCode, Long> {
|
||||
|
||||
/**
|
||||
* 获取指定用户的权限字列表。
|
||||
* 获取指定用户的权限字列表,已去重。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @return 用户关联的权限字列表。
|
||||
*/
|
||||
List<String> getPermCodeListByUserId(Long userId);
|
||||
Collection<String> getPermCodeListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 获取所有权限字数据列表,已去重。
|
||||
*
|
||||
* @return 全部权限字列表。
|
||||
*/
|
||||
Collection<String> getAllPermCodeList();
|
||||
|
||||
/**
|
||||
* 保存新增的权限字对象。
|
||||
|
||||
@@ -47,24 +47,14 @@ public interface SysPermService extends IBaseService<SysPerm, Long> {
|
||||
*/
|
||||
List<SysPerm> getPermListWithRelation(SysPerm sysPermFilter);
|
||||
|
||||
/**
|
||||
* 获取指定用户的权限资源集合,并存储于缓存,从而提升后续读取效率。
|
||||
*
|
||||
* @param sessionId 用户会话Id。
|
||||
* @param userId 用户主键Id。
|
||||
* @return 当前用户权限集合。
|
||||
*/
|
||||
Set<String> getCacheableSysPermSetByUserId(String sessionId, Long userId);
|
||||
|
||||
/**
|
||||
* 将指定用户的指定会话的权限集合存入缓存。
|
||||
*
|
||||
* @param sessionId 会话Id。
|
||||
* @param userId 用户主键Id。
|
||||
* @param isAdmin 是否是管理员。
|
||||
* @return 查询并缓存后的权限集合。
|
||||
*/
|
||||
Set<String> putUserSysPermCache(String sessionId, Long userId, boolean isAdmin);
|
||||
Collection<String> putUserSysPermCache(String sessionId, Long userId);
|
||||
|
||||
/**
|
||||
* 将指定会话的权限集合从缓存中移除。
|
||||
@@ -74,20 +64,12 @@ public interface SysPermService extends IBaseService<SysPerm, Long> {
|
||||
void removeUserSysPermCache(String sessionId);
|
||||
|
||||
/**
|
||||
* 获取指定用户的权限集合,这里之所以为公有方法,因为spring cache的技术要求,私有方法数据不能缓存。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @return 用户权限集合。
|
||||
*/
|
||||
Set<String> getSysPermSetByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 获取与指定用户关联的权限资源列表。
|
||||
* 获取与指定用户关联的权限资源列表,已去重。
|
||||
*
|
||||
* @param userId 关联的用户主键Id。
|
||||
* @return 与指定用户Id关联的权限资源列表。
|
||||
*/
|
||||
List<SysPerm> getPermListByUserId(Long userId);
|
||||
Collection<String> getPermListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 验证权限资源对象关联的数据是否都合法。
|
||||
|
||||
@@ -142,7 +142,7 @@ public class SysMenuServiceImpl extends BaseService<SysMenu, Long> implements Sy
|
||||
* @return 全部菜单列表。
|
||||
*/
|
||||
@Override
|
||||
public List<SysMenu> getAllMenuList() {
|
||||
public Collection<SysMenu> getAllMenuList() {
|
||||
Example e = new Example(SysMenu.class);
|
||||
e.orderBy("showOrder");
|
||||
Example.Criteria c = e.createCriteria();
|
||||
@@ -152,14 +152,19 @@ public class SysMenuServiceImpl extends BaseService<SysMenu, Long> implements Sy
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户Id的菜单列表。
|
||||
* 获取指定用户Id的菜单列表,已去重。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @return 用户关联的菜单列表。
|
||||
*/
|
||||
@Override
|
||||
public List<SysMenu> getMenuListByUserId(Long userId) {
|
||||
return sysMenuMapper.getMenuListByUserId(userId);
|
||||
public Collection<SysMenu> getMenuListByUserId(Long userId) {
|
||||
List<SysMenu> menuList = sysMenuMapper.getMenuListByUserId(userId);
|
||||
LinkedHashMap<Long, SysMenu> menuMap = new LinkedHashMap<>();
|
||||
for (SysMenu menu : menuList) {
|
||||
menuMap.put(menu.getMenuId(), menu);
|
||||
}
|
||||
return menuMap.values();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,14 +54,26 @@ public class SysPermCodeServiceImpl extends BaseService<SysPermCode, Long> imple
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户的权限字列表。
|
||||
* 获取指定用户的权限字列表,已去重。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @return 用户关联的权限字列表。
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPermCodeListByUserId(Long userId) {
|
||||
return sysPermCodeMapper.getPermCodeListByUserId(userId);
|
||||
public Collection<String> getPermCodeListByUserId(Long userId) {
|
||||
List<String> permCodeList = sysPermCodeMapper.getPermCodeListByUserId(userId);
|
||||
return new HashSet<>(permCodeList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有权限字数据列表,已去重。
|
||||
*
|
||||
* @return 全部权限字列表。
|
||||
*/
|
||||
@Override
|
||||
public Collection<String> getAllPermCodeList() {
|
||||
List<SysPermCode> permCodeList = this.getAllList();
|
||||
return permCodeList.stream().map(SysPermCode::getPermCode).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,24 +8,24 @@ import com.orange.demo.common.core.object.MyRelationParam;
|
||||
import com.orange.demo.common.core.constant.GlobalDeletedFlag;
|
||||
import com.orange.demo.common.core.object.CallResult;
|
||||
import com.orange.demo.common.core.util.MyModelUtil;
|
||||
import com.orange.demo.common.core.util.RedisKeyUtil;
|
||||
import com.orange.demo.config.ApplicationConfig;
|
||||
import com.orange.demo.upms.service.*;
|
||||
import com.orange.demo.upms.dao.SysPermCodePermMapper;
|
||||
import com.orange.demo.upms.dao.SysPermMapper;
|
||||
import com.orange.demo.upms.model.SysPerm;
|
||||
import com.orange.demo.upms.model.SysPermCodePerm;
|
||||
import com.orange.demo.upms.model.SysPermModule;
|
||||
import com.orange.demo.upms.model.SysUser;
|
||||
import com.orange.demo.upms.model.constant.SysUserType;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Transaction;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 权限资源数据服务类。
|
||||
@@ -46,6 +46,10 @@ public class SysPermServiceImpl extends BaseService<SysPerm, Long> implements Sy
|
||||
private SysUserService sysUserService;
|
||||
@Autowired
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
@Autowired
|
||||
private JedisPool jedisPool;
|
||||
@Autowired
|
||||
private ApplicationConfig applicationConfig;
|
||||
|
||||
/**
|
||||
* 返回主对象的Mapper对象。
|
||||
@@ -83,8 +87,8 @@ public class SysPermServiceImpl extends BaseService<SysPerm, Long> implements Sy
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(SysPerm perm, SysPerm originalPerm) {
|
||||
MyModelUtil.fillCommonsForUpdate(perm, originalPerm);
|
||||
perm.setDeletedFlag(GlobalDeletedFlag.NORMAL);
|
||||
MyModelUtil.fillCommonsForUpdate(perm, originalPerm);
|
||||
return sysPermMapper.updateByPrimaryKeySelective(perm) != 0;
|
||||
}
|
||||
|
||||
@@ -130,39 +134,31 @@ public class SysPermServiceImpl extends BaseService<SysPerm, Long> implements Sy
|
||||
return permList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户的权限资源集合,并存储于缓存,从而提升后续读取效率。
|
||||
*
|
||||
* @param sessionId 用户会话Id。
|
||||
* @param userId 用户主键Id。
|
||||
* @return 当前用户权限集合。
|
||||
*/
|
||||
@Cacheable(value = "USER_PERMISSION_CACHE", key = "#sessionId", unless = "#result == null")
|
||||
@Override
|
||||
public Set<String> getCacheableSysPermSetByUserId(String sessionId, Long userId) {
|
||||
// 这里可以防止非法的userId直接访问权限受限的url
|
||||
SysUser user = sysUserService.getById(userId);
|
||||
if (user == null) {
|
||||
return new HashSet<>(1);
|
||||
}
|
||||
// 管理员账户返回空对象,便于缓存的统一处理。
|
||||
return user.getUserType() == SysUserType.TYPE_ADMIN
|
||||
? new HashSet<>(1) : this.getSysPermSetByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定用户的指定会话的权限集合存入缓存。
|
||||
*
|
||||
* @param sessionId 会话Id。
|
||||
* @param userId 用户主键Id。
|
||||
* @param isAdmin 是否是管理员。
|
||||
* @return 查询并缓存后的权限集合。
|
||||
*/
|
||||
@CachePut(value = "USER_PERMISSION_CACHE", key = "#sessionId")
|
||||
@Override
|
||||
public Set<String> putUserSysPermCache(String sessionId, Long userId, boolean isAdmin) {
|
||||
// 管理员账户返回空对象,便于缓存的统一处理。
|
||||
return isAdmin ? new HashSet<>(1) : this.getSysPermSetByUserId(userId);
|
||||
public Collection<String> putUserSysPermCache(String sessionId, Long userId) {
|
||||
Collection<String> permList = this.getPermListByUserId(userId);
|
||||
if (CollectionUtils.isEmpty(permList)) {
|
||||
return permList;
|
||||
}
|
||||
String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId);
|
||||
try (Jedis jedis = jedisPool.getResource()) {
|
||||
Transaction t = jedis.multi();
|
||||
if (permList != null) {
|
||||
for (String perm : permList) {
|
||||
t.sadd(sessionPermKey, perm);
|
||||
}
|
||||
t.expire(sessionPermKey, applicationConfig.getPermRedisExpiredSeconds());
|
||||
}
|
||||
t.exec();
|
||||
}
|
||||
return permList;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,33 +166,24 @@ public class SysPermServiceImpl extends BaseService<SysPerm, Long> implements Sy
|
||||
*
|
||||
* @param sessionId 会话Id。
|
||||
*/
|
||||
@CacheEvict(value = "USER_PERMISSION_CACHE", key = "#sessionId")
|
||||
@Override
|
||||
public void removeUserSysPermCache(String sessionId) {
|
||||
// 空实现即可,只是通过注解将当前sessionId从cache中删除。
|
||||
try (Jedis jedis = jedisPool.getResource()) {
|
||||
String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId);
|
||||
jedis.del(sessionPermKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户的权限集合,这里之所以为公有方法,因为spring cache的技术要求,私有方法数据不能缓存。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @return 用户权限集合。
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getSysPermSetByUserId(Long userId) {
|
||||
List<SysPerm> permList = this.getPermListByUserId(userId);
|
||||
return permList.stream().map(SysPerm::getUrl).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取与指定用户关联的权限资源列表。
|
||||
* 获取与指定用户关联的权限资源列表,已去重。
|
||||
*
|
||||
* @param userId 关联的用户主键Id。
|
||||
* @return 与指定用户Id关联的权限资源列表。
|
||||
*/
|
||||
@Override
|
||||
public List<SysPerm> getPermListByUserId(Long userId) {
|
||||
return sysPermMapper.getPermListByUserId(userId);
|
||||
public Collection<String> getPermListByUserId(Long userId) {
|
||||
List<String> urlList = sysPermMapper.getPermListByUserId(userId);
|
||||
return new HashSet<>(urlList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,8 +91,8 @@ public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements Sy
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(SysRole role, SysRole originalRole, Set<Long> menuIdSet) {
|
||||
MyModelUtil.fillCommonsForUpdate(role, originalRole);
|
||||
role.setDeletedFlag(GlobalDeletedFlag.NORMAL);
|
||||
MyModelUtil.fillCommonsForUpdate(role, originalRole);
|
||||
if (sysRoleMapper.updateByPrimaryKey(role) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,11 +61,10 @@ public class SysUserServiceImpl extends BaseService<SysUser, Long> implements Sy
|
||||
*/
|
||||
@Override
|
||||
public SysUser getSysUserByLoginName(String loginName) {
|
||||
Example e = new Example(SysUser.class);
|
||||
Example.Criteria c = e.createCriteria();
|
||||
c.andEqualTo("loginName", loginName);
|
||||
c.andEqualTo("deletedFlag", GlobalDeletedFlag.NORMAL);
|
||||
return sysUserMapper.selectOneByExample(e);
|
||||
SysUser filter = new SysUser();
|
||||
filter.setLoginName(loginName);
|
||||
filter.setDeletedFlag(GlobalDeletedFlag.NORMAL);
|
||||
return sysUserMapper.selectOne(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
@@ -12,79 +10,66 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("菜单VO")
|
||||
@Data
|
||||
public class SysMenuVo {
|
||||
|
||||
/**
|
||||
* 菜单Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单Id")
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 父菜单Id,目录菜单的父菜单为null
|
||||
*/
|
||||
@ApiModelProperty(value = "父菜单Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单显示名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单显示名称")
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单类型 (0: 目录 1: 菜单 2: 按钮 3: UI片段)。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单类型")
|
||||
private Integer menuType;
|
||||
|
||||
/**
|
||||
* 前端表单路由名称,仅用于menu_type为1的菜单类型。
|
||||
*/
|
||||
@ApiModelProperty(value = "前端表单路由名称")
|
||||
private String formRouterName;
|
||||
|
||||
/**
|
||||
* 菜单显示顺序 (值越小,排序越靠前)。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单显示顺序")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 菜单图标。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单显示顺序")
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建者Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新者Id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 菜单与权限字关联对象列表。
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单与权限字关联对象列表")
|
||||
private List<Map<String, Object>> sysMenuPermCodeList;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
@@ -12,73 +10,61 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("权限字VO")
|
||||
@Data
|
||||
public class SysPermCodeVo {
|
||||
|
||||
/**
|
||||
* 权限字Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字Id")
|
||||
private Long permCodeId;
|
||||
|
||||
/**
|
||||
* 权限字标识(一般为有含义的英文字符串)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字标识")
|
||||
private String permCode;
|
||||
|
||||
/**
|
||||
* 上级权限字Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "上级权限字Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 权限字类型(0: 表单 1: UI片段 2: 操作)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字类型")
|
||||
private Integer permCodeType;
|
||||
|
||||
/**
|
||||
* 显示名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示名称")
|
||||
private String showName;
|
||||
|
||||
/**
|
||||
* 显示顺序(数值越小,越靠前)。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建者Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新者Id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 权限字与权限资源关联对象列表。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字与权限资源关联对象列表")
|
||||
private List<Map<String, Object>> sysPermCodePermList;
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
@@ -12,67 +10,56 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("权限资源模块VO")
|
||||
@Data
|
||||
public class SysPermModuleVo {
|
||||
|
||||
/**
|
||||
* 权限模块Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限模块Id")
|
||||
private Long moduleId;
|
||||
|
||||
/**
|
||||
* 权限模块名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限模块名称")
|
||||
private String moduleName;
|
||||
|
||||
/**
|
||||
* 上级权限模块Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "上级权限模块Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 权限模块类型(0: 普通模块 1: Controller模块)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限模块类型")
|
||||
private Integer moduleType;
|
||||
|
||||
/**
|
||||
* 权限模块在当前层级下的顺序,由小到大。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建者Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新者Id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 权限资源对象列表。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限资源对象列表")
|
||||
private List<SysPermVo> sysPermList;
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
@@ -12,73 +10,61 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("权限资源VO")
|
||||
@Data
|
||||
public class SysPermVo {
|
||||
|
||||
/**
|
||||
* 权限资源Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限资源Id")
|
||||
private Long permId;
|
||||
|
||||
/**
|
||||
* 权限资源名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限资源名称")
|
||||
private String permName;
|
||||
|
||||
/**
|
||||
* shiro格式的权限字,如(upms:sysUser:add)。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限字")
|
||||
private String permCode;
|
||||
|
||||
/**
|
||||
* 权限所在的权限模块Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "权限所在的权限模块Id")
|
||||
private Long moduleId;
|
||||
|
||||
/**
|
||||
* 关联的URL。
|
||||
*/
|
||||
@ApiModelProperty(value = "关联的URL")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 权限在当前模块下的顺序,由小到大。
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建者Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新者Id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 模块Id的字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "模块Id的字典关联数据")
|
||||
private Map<String, Object> moduleIdDictMap;
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
@@ -12,49 +10,41 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("角色VO")
|
||||
@Data
|
||||
public class SysRoleVo {
|
||||
|
||||
/**
|
||||
* 角色Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "角色Id")
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 角色名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "角色名称")
|
||||
private String roleName;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建者Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新者Id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 角色与菜单关联对象列表。
|
||||
*/
|
||||
@ApiModelProperty(value = "角色与菜单关联对象列表")
|
||||
private List<Map<String, Object>> sysRoleMenuList;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.orange.demo.upms.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -14,91 +12,71 @@ import java.util.List;
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ApiModel("SysUserVO实体对象")
|
||||
@Data
|
||||
public class SysUserVo {
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户Id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 登录用户名。
|
||||
*/
|
||||
@ApiModelProperty(value = "登录用户名")
|
||||
private String loginName;
|
||||
|
||||
/**
|
||||
* 用户密码。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户密码")
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 用户显示名称。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户显示名称")
|
||||
private String showName;
|
||||
|
||||
/**
|
||||
* 用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)")
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 用户头像的Url。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户头像的Url")
|
||||
private String headImageUrl;
|
||||
|
||||
/**
|
||||
* 用户状态(0: 正常 1: 锁定)。
|
||||
*/
|
||||
@ApiModelProperty(value = "用户状态(0: 正常 1: 锁定)")
|
||||
private Integer userStatus;
|
||||
|
||||
/**
|
||||
* 创建用户Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建用户Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新者Id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 多对多用户角色数据集合。
|
||||
*/
|
||||
@ApiModelProperty(value = "多对多用户角色数据集合")
|
||||
private List<Map<String, Object>> sysUserRoleList;
|
||||
|
||||
/**
|
||||
* userType 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "userType 常量字典关联数据")
|
||||
private Map<String, Object> userTypeDictMap;
|
||||
|
||||
/**
|
||||
* userStatus 常量字典关联数据。
|
||||
*/
|
||||
@ApiModelProperty(value = "userStatus 常量字典关联数据")
|
||||
private Map<String, Object> userStatusDictMap;
|
||||
}
|
||||
|
||||
@@ -56,14 +56,35 @@ pagehelper:
|
||||
supportMethodsArguments: false
|
||||
params: count=countSql
|
||||
|
||||
swagger:
|
||||
# 当enabled为false的时候,则可禁用swagger。
|
||||
enabled: true
|
||||
# 工程的基础包名。
|
||||
basePackage: com.orange.demo
|
||||
title: 橙单单体服务工程
|
||||
description: 橙单单体服务工程详情
|
||||
version: 1.0
|
||||
# 存储session数据的Redis,所有服务均需要,因此放到公共配置中。
|
||||
# 根据实际情况,该Redis也可以用于存储其他数据。
|
||||
redis:
|
||||
jedis:
|
||||
enabled: true
|
||||
host: localhost
|
||||
port: 6379
|
||||
timeout: 60000
|
||||
pool:
|
||||
maxTotal: 20
|
||||
maxIdle: 8
|
||||
minIdle: 0
|
||||
maxWait: 2000
|
||||
# redisson的配置。每个服务可以自己的配置文件中覆盖此选项。
|
||||
redisson:
|
||||
# 如果该值为false,系统将不会创建RedissionClient的bean。
|
||||
enabled: true
|
||||
# redis地址,多个地址之间逗号分隔。如果是从主机制,第一个为master,其余为slave。
|
||||
address: localhost:6379
|
||||
# 链接超时,单位毫秒。
|
||||
timeout: 6000
|
||||
# 单位毫秒。分布式锁的超时检测时长。
|
||||
# 如果一次锁内操作超该毫秒数,或在释放锁之前异常退出,Redis会在该时长之后主动删除该锁使用的key。
|
||||
lockWatchdogTimeout: 60000
|
||||
pool:
|
||||
# 连接池数量。
|
||||
poolSize: 20
|
||||
# 连接池中最小空闲数量。
|
||||
minIdle: 5
|
||||
|
||||
# 暴露监控端点
|
||||
management:
|
||||
@@ -139,6 +160,8 @@ application:
|
||||
uploadFileBaseDir: ./zz-resource/upload-files/app
|
||||
# 跨域的IP白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
|
||||
credentialIpList: "*"
|
||||
# Session的用户和数据权限在Redis中的过期时间(秒)。
|
||||
permRedisExpiredSeconds: 86400
|
||||
|
||||
sequence:
|
||||
# Snowflake 分布式Id生成算法所需的WorkNode参数值。
|
||||
@@ -196,6 +219,8 @@ application:
|
||||
uploadFileBaseDir: ./zz-resource/upload-files/app
|
||||
# 跨域的IP白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
|
||||
credentialIpList: "*"
|
||||
# Session的用户和数据权限在Redis中的过期时间(秒)。
|
||||
permRedisExpiredSeconds: 86400
|
||||
|
||||
sequence:
|
||||
# Snowflake 分布式Id生成算法所需的WorkNode参数值。
|
||||
|
||||
@@ -53,9 +53,6 @@
|
||||
<root level="${OUTPUT_LOG_LEVEL}">
|
||||
<AppenderRef ref="console"/>
|
||||
</root>
|
||||
<Logger name="springfox.documentation" additivity="false" level="error">
|
||||
<AppenderRef ref="console"/>
|
||||
</Logger>
|
||||
<Logger name="com.orange.demo" additivity="false" level="info">
|
||||
<AppenderRef ref="console"/>
|
||||
<AppenderRef ref="file_log"/>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.orange.demo.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 主要用于标记数据权限中基于DeptId进行过滤的字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DeptFilterColumn {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.orange.demo.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 作为DisableDataFilterAspect的切点。
|
||||
* 该注解仅能标记在方法上,方法内所有的查询语句,均不会被Mybatis拦截器过滤数据。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DisableDataFilter {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.orange.demo.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 仅用于微服务的多租户项目。
|
||||
* 用于注解DAO层Mapper对象的租户过滤规则。被包含的方法将不会进行租户Id的过滤。
|
||||
* 对于tk mapper和mybatis plus中的内置方法,可以直接指定方法名即可,如:selectOne。
|
||||
* 需要说明的是,在大多数场景下,只要在实体对象中指定了租户Id字段,基于该主表的绝大部分增删改操作,
|
||||
* 都需要经过租户Id过滤,仅当查询非常复杂,或者主表不在SQL语句之中的时候,可以通过该注解禁用该SQL,
|
||||
* 并根据需求通过手动的方式实现租户过滤。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DisableTenantFilter {
|
||||
|
||||
/**
|
||||
* 包含的方法名称数组。该值不能为空,因为如想取消所有方法的租户过滤,
|
||||
* 可以通过在实体对象中不指定租户Id字段注解的方式实现。
|
||||
*
|
||||
* @return 被包括的方法名称数组。
|
||||
*/
|
||||
String[] includeMethodName();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orange.demo.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 用于注解DAO层Mapper对象的数据权限规则。
|
||||
* 由于框架使用了tk.mapper,所以并非所有的Mapper接口均在当前Mapper对象中定义,有一部分被tk.mapper封装,如selectAll等。
|
||||
* 如果需要排除tk.mapper中的方法,可以直接使用tk.mapper基类所声明的方法名称即可。
|
||||
* 另外,比较特殊的场景是,因为tk.mapper是通用框架,所以同样的selectAll方法,可以获取不同的数据集合,因此在service中如果
|
||||
* 出现两个不同的方法调用Mapper的selectAll方法,但是一个需要参与过滤,另外一个不需要参与,那么就需要修改当前类的Mapper方法,
|
||||
* 将其中一个方法重新定义一个具体的接口方法,并重新设定其是否参与数据过滤。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EnableDataPerm {
|
||||
|
||||
/**
|
||||
* 排除的方法名称数组。如果为空,所有的方法均会被Mybaits拦截注入权限过滤条件。
|
||||
*
|
||||
* @return 被排序的方法名称数据。
|
||||
*/
|
||||
String[] excluseMethodName() default {};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.orange.demo.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 主要用于标记通过租户Id进行过滤的字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface TenantFilterColumn {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.orange.demo.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 主要用于标记数据权限中基于UserId进行过滤的字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface UserFilterColumn {
|
||||
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package com.orange.demo.common.core.cache;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.caffeine.CaffeineCache;
|
||||
import org.springframework.cache.support.SimpleCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 使用Caffeine作为本地缓存库
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class CacheConfig {
|
||||
|
||||
private static final int DEFAULT_MAXSIZE = 10000;
|
||||
private static final int DEFAULT_TTL = 3600;
|
||||
|
||||
/**
|
||||
* 定义cache名称、超时时长秒、最大个数
|
||||
* 每个cache缺省3600秒过期,最大个数1000
|
||||
*/
|
||||
public enum CacheEnum {
|
||||
/**
|
||||
* 专门存储用户权限的缓存。
|
||||
*/
|
||||
USER_PERMISSION_CACHE(1800, 10000),
|
||||
/**
|
||||
* session下上传文件名的缓存(时间是24小时)。
|
||||
*/
|
||||
UPLOAD_FILENAME_CACHE(86400, 20000),
|
||||
/**
|
||||
* 缺省全局缓存(时间是24小时)。
|
||||
*/
|
||||
GLOBAL_CACHE(86400, 20000);
|
||||
|
||||
CacheEnum() {
|
||||
}
|
||||
|
||||
CacheEnum(int ttl, int maxSize) {
|
||||
this.ttl = ttl;
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存的最大数量。
|
||||
*/
|
||||
private int maxSize = DEFAULT_MAXSIZE;
|
||||
/**
|
||||
* 缓存的时长(单位:秒)
|
||||
*/
|
||||
private int ttl = DEFAULT_TTL;
|
||||
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
public int getTtl() {
|
||||
return ttl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化缓存配置。
|
||||
*/
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
SimpleCacheManager manager = new SimpleCacheManager();
|
||||
// 把各个cache注册到cacheManager中,CaffeineCache实现了org.springframework.cache.Cache接口
|
||||
ArrayList<CaffeineCache> caches = new ArrayList<>();
|
||||
for (CacheEnum c : CacheEnum.values()) {
|
||||
caches.add(new CaffeineCache(c.name(),
|
||||
Caffeine.newBuilder().recordStats()
|
||||
.expireAfterAccess(c.getTtl(), TimeUnit.SECONDS)
|
||||
.maximumSize(c.getMaxSize())
|
||||
.build())
|
||||
);
|
||||
}
|
||||
manager.setCaches(caches);
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,7 @@ public class MyRequestArgumentResolver implements HandlerMethodArgumentResolver
|
||||
}
|
||||
}
|
||||
} else if (parameterType == Boolean.class) {
|
||||
return value.toString();
|
||||
return value;
|
||||
} else if (parameterType == Character.class) {
|
||||
return value.toString().charAt(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.orange.demo.common.core.object;
|
||||
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
|
||||
/**
|
||||
* 线程本地化数据管理的工具类。可根据需求自行添加更多的线程本地化变量及其操作方法。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class GlobalThreadLocal {
|
||||
|
||||
/**
|
||||
* 存储数据权限过滤是否启用的线程本地化对象。
|
||||
* 目前的过滤条件,包括数据权限和租户过滤。
|
||||
*/
|
||||
private static final ThreadLocal<Boolean> DATA_FILTER_ENABLE = ThreadLocal.withInitial(() -> Boolean.TRUE);
|
||||
|
||||
/**
|
||||
* 设置数据过滤是否打开。如果打开,当前Servlet线程所执行的SQL操作,均会进行数据过滤。
|
||||
*
|
||||
* @param enable 打开为true,否则false。
|
||||
* @return 返回之前的状态,便于恢复。
|
||||
*/
|
||||
public static boolean setDataFilter(boolean enable) {
|
||||
boolean oldValue = DATA_FILTER_ENABLE.get();
|
||||
DATA_FILTER_ENABLE.set(enable);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前Servlet线程所执行的SQL操作,是否进行数据过滤。
|
||||
*
|
||||
* @return true 进行数据权限过滤,否则false。
|
||||
*/
|
||||
public static boolean enabledDataFilter() {
|
||||
return BooleanUtil.isTrue(DATA_FILTER_ENABLE.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空该存储数据,主动释放线程本地化存储资源。
|
||||
*/
|
||||
public static void clearDataFilter() {
|
||||
DATA_FILTER_ENABLE.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private GlobalThreadLocal() {
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,16 @@ public class TokenData {
|
||||
* 用户Id。
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户所在部门Id。
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
*/
|
||||
private Long deptId;
|
||||
/**
|
||||
* 租户Id。
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
*/
|
||||
private Long tenantId;
|
||||
/**
|
||||
* 是否为超级管理员。
|
||||
*/
|
||||
@@ -36,6 +46,11 @@ public class TokenData {
|
||||
* 标识不同登录的会话Id。
|
||||
*/
|
||||
private String sessionId;
|
||||
/**
|
||||
* 访问uaa的授权token。
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
*/
|
||||
private String uaaAccessToken;
|
||||
|
||||
/**
|
||||
* 将令牌对象添加到Http请求对象。
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.orange.demo.common.core.util;
|
||||
|
||||
/**
|
||||
* Redis 键生成工具类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class RedisKeyUtil {
|
||||
|
||||
/**
|
||||
* 计算SessionId关联的权限数据存储于Redis中的键。
|
||||
*
|
||||
* @param sessionId 会话Id。
|
||||
* @return 会话关联的权限数据存储于Redis中的键值。
|
||||
*/
|
||||
public static String makeSessionPermIdKeyForRedis(String sessionId) {
|
||||
return "PERM__" + sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算SessionId关联的数据权限数据存储于Redis中的键。
|
||||
*
|
||||
* @param sessionId 会话Id。
|
||||
* @return 会话关联的数据权限数据存储于Redis中的键值。
|
||||
*/
|
||||
public static String makeSessionDataPermIdKeyForRedis(String sessionId) {
|
||||
return "DATA_PERM__" + sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private RedisKeyUtil() {
|
||||
}
|
||||
}
|
||||
@@ -9,21 +9,26 @@
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>common-swagger</artifactId>
|
||||
<artifactId>common-redis</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>common-swagger</name>
|
||||
<name>common-redis</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orange.demo</groupId>
|
||||
<artifactId>common-core</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>${jedis.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>${redisson.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,412 @@
|
||||
package com.orange.demo.common.redis.cache;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.orange.demo.common.core.cache.DictionaryCache;
|
||||
import com.orange.demo.common.core.constant.ApplicationConstant;
|
||||
import com.orange.demo.common.core.exception.RedisCacheAccessException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.redisson.api.RMap;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 字典数据Redis缓存对象。
|
||||
*
|
||||
* @param <K> 字典表主键类型。
|
||||
* @param <V> 字典表对象类型。
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class RedisDictionaryCache<K, V> implements DictionaryCache<K, V> {
|
||||
|
||||
/**
|
||||
* redisson客户端。
|
||||
*/
|
||||
protected final RedissonClient redissonClient;
|
||||
/**
|
||||
* 数据存储对象。
|
||||
*/
|
||||
protected final RMap<K, String> dataMap;
|
||||
/**
|
||||
* 字典值对象类型。
|
||||
*/
|
||||
protected final Class<V> valueClazz;
|
||||
/**
|
||||
* 由于大部分场景是读取操作,所以使用读写锁提高并发的伸缩性。
|
||||
*/
|
||||
protected final ReadWriteLock lock;
|
||||
/**
|
||||
* 获取字典主键数据的函数对象。
|
||||
*/
|
||||
protected final Function<V, K> idGetter;
|
||||
/**
|
||||
* 超时时长。单位毫秒。
|
||||
*/
|
||||
protected static final long TIMEOUT = 2000L;
|
||||
|
||||
/**
|
||||
* 当前对象的构造器函数。
|
||||
*
|
||||
* @param redissonClient Redisson的客户端对象。
|
||||
* @param dictionaryName 字典表的名称。等同于redis hash对象的key。
|
||||
* @param valueClazz 值对象的Class对象。
|
||||
* @param idGetter 获取当前类主键字段值的函数对象。
|
||||
* @param <K> 字典主键类型。
|
||||
* @param <V> 字典对象类型
|
||||
* @return 实例化后的字典内存缓存对象。
|
||||
*/
|
||||
public static <K, V> RedisDictionaryCache<K, V> create(
|
||||
RedissonClient redissonClient,
|
||||
String dictionaryName,
|
||||
Class<V> valueClazz,
|
||||
Function<V, K> idGetter) {
|
||||
if (idGetter == null) {
|
||||
throw new IllegalArgumentException("IdGetter can't be NULL.");
|
||||
}
|
||||
return new RedisDictionaryCache<>(redissonClient, dictionaryName, valueClazz, idGetter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数。
|
||||
*
|
||||
* @param redissonClient Redisson的客户端对象。
|
||||
* @param dictionaryName 字典表的名称。等同于redis hash对象的key。确保全局唯一。
|
||||
* @param valueClazz 值对象的Class对象。
|
||||
* @param idGetter 获取当前类主键字段值的函数对象。
|
||||
*/
|
||||
public RedisDictionaryCache(
|
||||
RedissonClient redissonClient,
|
||||
String dictionaryName,
|
||||
Class<V> valueClazz,
|
||||
Function<V, K> idGetter) {
|
||||
this.redissonClient = redissonClient;
|
||||
this.dataMap = redissonClient.getMap(dictionaryName + ApplicationConstant.DICT_CACHE_NAME_SUFFIX);
|
||||
this.lock = new ReentrantReadWriteLock();
|
||||
this.valueClazz = valueClazz;
|
||||
this.idGetter = idGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照数据插入的顺序返回全部字典对象的列表。
|
||||
*
|
||||
* @return 全部字段数据列表。
|
||||
*/
|
||||
@Override
|
||||
public List<V> getAll() {
|
||||
Collection<String> dataList;
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.readLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataList = dataMap.readAllValues();
|
||||
} finally {
|
||||
// 如果上面的操作时间超过redisson.lockWatchdogTimeout的时长,
|
||||
// redis会将与该锁关联的键删除,此后调用unlock的时候,就会抛出运行时异常。
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::getAll] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
return dataList.stream()
|
||||
.map(data -> JSON.parseObject(data, valueClazz))
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中与键列表对应的对象列表。
|
||||
*
|
||||
* @param keys 主键集合。
|
||||
* @return 对象列表。
|
||||
*/
|
||||
@Override
|
||||
public List<V> getInList(Set<K> keys) {
|
||||
if (CollectionUtils.isEmpty(keys)) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
Collection<String> dataList;
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.readLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataList = dataMap.getAll(keys).values();
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::getInList] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
if (dataList == null) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
return dataList.stream()
|
||||
.map(data -> JSON.parseObject(data, valueClazz))
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中获取指定的数据。
|
||||
*
|
||||
* @param id 数据的key。
|
||||
* @return 获取到的数据,如果没有返回null。
|
||||
*/
|
||||
@Override
|
||||
public V get(K id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
String data;
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.readLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
data = dataMap.get(id);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::get] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(data, valueClazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中数据条目的数量。
|
||||
*
|
||||
* @return 返回缓存的数据数量。
|
||||
*/
|
||||
@Override
|
||||
public int getCount() {
|
||||
return dataMap.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将参数List中的数据保存到缓存中,同时保证getAll返回的数据列表,与参数列表中数据项的顺序保持一致。
|
||||
*
|
||||
* @param dataList 待缓存的数据列表。
|
||||
*/
|
||||
@Override
|
||||
public void putAll(List<V> dataList) {
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return;
|
||||
}
|
||||
Map<K, String> map = dataList.stream()
|
||||
.collect(Collectors.toMap(idGetter, JSON::toJSONString));
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataMap.putAll(map, 1000);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::putAll] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据存入缓存。
|
||||
*
|
||||
* @param id 通常为字典数据的主键。
|
||||
* @param data 字典数据对象。
|
||||
*/
|
||||
@Override
|
||||
public void put(K id, V data) {
|
||||
if (id == null || data == null) {
|
||||
return;
|
||||
}
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataMap.fastPut(id, JSON.toJSONString(data));
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::put] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载,先清空原有数据,在执行putAll的操作。
|
||||
*
|
||||
* @param dataList 待缓存的数据列表。
|
||||
* @param force true则强制刷新,如果false,当缓存中存在数据时不刷新。
|
||||
*/
|
||||
@Override
|
||||
public void reload(List<V> dataList, boolean force) {
|
||||
Map<K, String> map = null;
|
||||
if (CollectionUtils.isNotEmpty(dataList)) {
|
||||
map = dataList.stream().collect(Collectors.toMap(idGetter, JSON::toJSONString));
|
||||
}
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
// 如果不强制刷新,需要先判断缓存中是否存在数据。
|
||||
if (!force && this.getCount() > 0) {
|
||||
return;
|
||||
}
|
||||
dataMap.clear();
|
||||
if (map != null) {
|
||||
dataMap.putAll(map, 1000);
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::reload] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存中指定的键。
|
||||
*
|
||||
* @param id 待删除数据的主键。
|
||||
* @return 返回被删除的对象,如果主键不存在,返回null。
|
||||
*/
|
||||
@Override
|
||||
public V invalidate(K id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
String data;
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
data = dataMap.remove(id);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::invalidate] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(data, valueClazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存中,参数列表中包含的键。
|
||||
*
|
||||
* @param keys 待删除数据的主键集合。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void invalidateSet(Set<K> keys) {
|
||||
if (CollectionUtils.isEmpty(keys)) {
|
||||
return;
|
||||
}
|
||||
Object[] keyArray = keys.toArray(new Object[]{});
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataMap.fastRemove((K[]) keyArray);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::invalidateSet] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存。
|
||||
*/
|
||||
@Override
|
||||
public void invalidateAll() {
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataMap.clear();
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::invalidateAll] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
package com.orange.demo.common.redis.cache;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orange.demo.common.core.exception.RedisCacheAccessException;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.redisson.api.RListMultimap;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 树形字典数据Redis缓存对象。
|
||||
*
|
||||
* @param <K> 字典表主键类型。
|
||||
* @param <V> 字典表对象类型。
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class RedisTreeDictionaryCache<K, V> extends RedisDictionaryCache<K, V> {
|
||||
|
||||
/**
|
||||
* 树形数据存储对象。
|
||||
*/
|
||||
private final RListMultimap<K, String> allTreeMap;
|
||||
/**
|
||||
* 获取字典父主键数据的函数对象。
|
||||
*/
|
||||
protected final Function<V, K> parentIdGetter;
|
||||
|
||||
/**
|
||||
* 当前对象的构造器函数。
|
||||
*
|
||||
* @param redissonClient Redisson的客户端对象。
|
||||
* @param dictionaryName 字典表的名称。等同于redis hash对象的key。
|
||||
* @param valueClazz 值对象的Class对象。
|
||||
* @param idGetter 获取当前类主键字段值的函数对象。
|
||||
* @param parentIdGetter 获取当前类父主键字段值的函数对象。
|
||||
* @param <K> 字典主键类型。
|
||||
* @param <V> 字典对象类型
|
||||
* @return 实例化后的树形字典内存缓存对象。
|
||||
*/
|
||||
public static <K, V> RedisTreeDictionaryCache<K, V> create(
|
||||
RedissonClient redissonClient,
|
||||
String dictionaryName,
|
||||
Class<V> valueClazz,
|
||||
Function<V, K> idGetter,
|
||||
Function<V, K> parentIdGetter) {
|
||||
if (idGetter == null) {
|
||||
throw new IllegalArgumentException("IdGetter can't be NULL.");
|
||||
}
|
||||
if (parentIdGetter == null) {
|
||||
throw new IllegalArgumentException("ParentIdGetter can't be NULL.");
|
||||
}
|
||||
return new RedisTreeDictionaryCache<>(
|
||||
redissonClient, dictionaryName, valueClazz, idGetter, parentIdGetter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数。
|
||||
*
|
||||
* @param redissonClient Redisson的客户端对象。
|
||||
* @param dictionaryName 字典表的名称。等同于redis hash对象的key。
|
||||
* @param valueClazz 值对象的Class对象。
|
||||
* @param idGetter 获取当前类主键字段值的函数对象。
|
||||
* @param parentIdGetter 获取当前类父主键字段值的函数对象。
|
||||
*/
|
||||
public RedisTreeDictionaryCache(
|
||||
RedissonClient redissonClient,
|
||||
String dictionaryName,
|
||||
Class<V> valueClazz,
|
||||
Function<V, K> idGetter,
|
||||
Function<V, K> parentIdGetter) {
|
||||
super(redissonClient, dictionaryName, valueClazz, idGetter);
|
||||
this.allTreeMap = redissonClient.getListMultimap(dictionaryName + "-TREE-DICT");
|
||||
this.parentIdGetter = parentIdGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该父主键的子数据列表。
|
||||
*
|
||||
* @param parentId 父主键Id。如果parentId为null,则返回所有一级节点数据。
|
||||
* @return 子数据列表。
|
||||
*/
|
||||
public List<V> getListByParentId(K parentId) {
|
||||
List<String> dataList;
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.readLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataList = allTreeMap.get(parentId);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisTreeDictionaryCache::getListByParentId] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
List<V> resultList = new LinkedList<>();
|
||||
dataList.forEach(data -> resultList.add(JSON.parseObject(data, valueClazz)));
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将参数List中的数据保存到缓存中,同时保证getAll返回的数据列表,与参数列表中数据项的顺序保持一致。
|
||||
*
|
||||
* @param dataList 待缓存的数据列表。
|
||||
*/
|
||||
@Override
|
||||
public void putAll(List<V> dataList) {
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return;
|
||||
}
|
||||
// 锁外执行数据结构组装,降低锁的粒度,提高并发性。
|
||||
Map<K, String> map = dataList.stream()
|
||||
.collect(Collectors.toMap(idGetter, JSON::toJSONString));
|
||||
Multimap<K, String> treeMap = LinkedListMultimap.create();
|
||||
for (V data : dataList) {
|
||||
treeMap.put(parentIdGetter.apply(data), JSON.toJSONString(data));
|
||||
}
|
||||
Set<Map.Entry<K, Collection<String>>> entries = treeMap.asMap().entrySet();
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (this.lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataMap.putAll(map, 1000);
|
||||
for (Map.Entry<K, Collection<String>> entry : entries) {
|
||||
allTreeMap.removeAll(entry.getKey());
|
||||
allTreeMap.putAll(entry.getKey(), entry.getValue());
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisTreeDictionaryCache::putAll] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据存入缓存。
|
||||
*
|
||||
* @param id 通常为字典数据的主键。
|
||||
* @param data 字典数据对象。
|
||||
*/
|
||||
@Override
|
||||
public void put(K id, V data) {
|
||||
if (id == null || data == null) {
|
||||
return;
|
||||
}
|
||||
String stringData = JSON.toJSONString(data);
|
||||
K parentId = parentIdGetter.apply(data);
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (this.lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
String oldData = dataMap.put(id, stringData);
|
||||
if (oldData != null) {
|
||||
allTreeMap.remove(parentId, oldData);
|
||||
}
|
||||
allTreeMap.put(parentId, stringData);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisTreeDictionaryCache::put] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 行为等同于接口中的描述。这里之所以重写,是因为不确定redisson的读写锁,
|
||||
* 是否为可重入锁。
|
||||
*
|
||||
* @param dataList 待缓存的数据列表。
|
||||
* @param force true则强制刷新,如果false,当缓存中存在数据时不刷新。
|
||||
*/
|
||||
@Override
|
||||
public void reload(List<V> dataList, boolean force) {
|
||||
// 锁外执行数据结构组装,降低锁的粒度,提高并发性。
|
||||
Map<K, String> map = null;
|
||||
Set<Map.Entry<K, Collection<String>>> entries = null;
|
||||
if (CollectionUtils.isNotEmpty(dataList)) {
|
||||
map = dataList.stream().collect(Collectors.toMap(idGetter, JSON::toJSONString));
|
||||
Multimap<K, String> treeMap = LinkedListMultimap.create();
|
||||
for (V data : dataList) {
|
||||
treeMap.put(parentIdGetter.apply(data), JSON.toJSONString(data));
|
||||
}
|
||||
entries = treeMap.asMap().entrySet();
|
||||
}
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
// 如果不强制刷新,需要先判断缓存中是否存在数据。
|
||||
if (!force && this.getCount() > 0) {
|
||||
return;
|
||||
}
|
||||
dataMap.clear();
|
||||
allTreeMap.clear();
|
||||
if (map != null) {
|
||||
dataMap.putAll(map, 1000);
|
||||
for (Map.Entry<K, Collection<String>> entry : entries) {
|
||||
allTreeMap.removeAll(entry.getKey());
|
||||
allTreeMap.putAll(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisDictionaryCache::reload] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存中指定的键。
|
||||
*
|
||||
* @param id 待删除数据的主键。
|
||||
* @return 返回被删除的对象,如果主键不存在,返回null。
|
||||
*/
|
||||
@Override
|
||||
public V invalidate(K id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
V data = null;
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (this.lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
String stringData = dataMap.remove(id);
|
||||
if (stringData != null) {
|
||||
data = JSON.parseObject(stringData, valueClazz);
|
||||
K parentId = parentIdGetter.apply(data);
|
||||
allTreeMap.remove(parentId, stringData);
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisTreeDictionaryCache::invalidate] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存中,参数列表中包含的键。
|
||||
*
|
||||
* @param keys 待删除数据的主键集合。
|
||||
*/
|
||||
@Override
|
||||
public void invalidateSet(Set<K> keys) {
|
||||
if (CollectionUtils.isEmpty(keys)) {
|
||||
return;
|
||||
}
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
keys.forEach(id -> {
|
||||
if (id != null) {
|
||||
String stringData = dataMap.remove(id);
|
||||
if (stringData != null) {
|
||||
K parentId = parentIdGetter.apply(JSON.parseObject(stringData, valueClazz));
|
||||
allTreeMap.remove(parentId, stringData);
|
||||
}
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisTreeDictionaryCache::invalidateSet] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存。
|
||||
*/
|
||||
@Override
|
||||
public void invalidateAll() {
|
||||
String exceptionMessage;
|
||||
try {
|
||||
if (lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
dataMap.clear();
|
||||
allTreeMap.clear();
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionMessage = String.format(
|
||||
"LOCK Operation of [RedisTreeDictionaryCache::invalidateAll] encountered EXCEPTION [%s] for DICT [%s].",
|
||||
e.getClass().getSimpleName(), valueClazz.getSimpleName());
|
||||
log.warn(exceptionMessage);
|
||||
throw new RedisCacheAccessException(exceptionMessage, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.orange.demo.common.redis.cache;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.spring.cache.CacheConfig;
|
||||
import org.redisson.spring.cache.RedissonSpringCacheManager;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 使用Redisson作为Redis的分布式缓存库。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class RedissonCacheConfig {
|
||||
|
||||
private static final int DEFAULT_TTL = 3600000;
|
||||
|
||||
/**
|
||||
* 定义cache名称、超时时长(毫秒)。
|
||||
*/
|
||||
public enum CacheEnum {
|
||||
/**
|
||||
* session下上传文件名的缓存(时间是24小时)。
|
||||
*/
|
||||
UPLOAD_FILENAME_CACHE(86400000),
|
||||
/**
|
||||
* 缺省全局缓存(时间是24小时)。
|
||||
*/
|
||||
GLOBAL_CACHE(86400000);
|
||||
|
||||
/**
|
||||
* 缓存的时长(单位:毫秒)
|
||||
*/
|
||||
private int ttl = DEFAULT_TTL;
|
||||
|
||||
CacheEnum() {
|
||||
}
|
||||
|
||||
CacheEnum(int ttl) {
|
||||
this.ttl = ttl;
|
||||
}
|
||||
|
||||
public int getTtl() {
|
||||
return ttl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化缓存配置。
|
||||
*/
|
||||
@Bean
|
||||
CacheManager cacheManager(RedissonClient redissonClient) {
|
||||
Map<String, CacheConfig> config = Maps.newHashMap();
|
||||
for (CacheEnum c : CacheEnum.values()) {
|
||||
config.put(c.name(), new CacheConfig(c.getTtl(), 0));
|
||||
}
|
||||
return new RedissonSpringCacheManager(redissonClient, config);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.orange.demo.common.core.cache;
|
||||
package com.orange.demo.common.redis.cache;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orange.demo.common.core.object.TokenData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.Cache;
|
||||
@@ -30,7 +32,7 @@ public class SessionCacheHelper {
|
||||
public void putSessionUploadFile(String filename) {
|
||||
if (filename != null) {
|
||||
Set<String> sessionUploadFileSet = null;
|
||||
Cache cache = cacheManager.getCache(CacheConfig.CacheEnum.UPLOAD_FILENAME_CACHE.name());
|
||||
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.UPLOAD_FILENAME_CACHE.name());
|
||||
Cache.ValueWrapper valueWrapper = cache.get(TokenData.takeFromRequest().getSessionId());
|
||||
if (valueWrapper != null) {
|
||||
sessionUploadFileSet = (Set<String>) valueWrapper.get();
|
||||
@@ -53,7 +55,7 @@ public class SessionCacheHelper {
|
||||
if (filename == null) {
|
||||
return false;
|
||||
}
|
||||
Cache cache = cacheManager.getCache(CacheConfig.CacheEnum.UPLOAD_FILENAME_CACHE.name());
|
||||
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.UPLOAD_FILENAME_CACHE.name());
|
||||
Cache.ValueWrapper valueWrapper = cache.get(TokenData.takeFromRequest().getSessionId());
|
||||
if (valueWrapper == null) {
|
||||
return false;
|
||||
@@ -71,8 +73,8 @@ public class SessionCacheHelper {
|
||||
if (sessionId == null || tokenData == null) {
|
||||
return;
|
||||
}
|
||||
Cache cache = cacheManager.getCache(CacheConfig.CacheEnum.GLOBAL_CACHE.name());
|
||||
cache.put(sessionId, tokenData);
|
||||
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
|
||||
cache.put(sessionId, JSON.toJSONString(tokenData));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,8 +84,9 @@ public class SessionCacheHelper {
|
||||
* @return 当前会话的JWT Token对象。
|
||||
*/
|
||||
public TokenData getTokenData(String sessionId) {
|
||||
Cache cache = cacheManager.getCache(CacheConfig.CacheEnum.GLOBAL_CACHE.name());
|
||||
return cache.get(sessionId, TokenData.class);
|
||||
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
|
||||
String tokenString = cache.get(sessionId, String.class);
|
||||
return JSONObject.parseObject(tokenString, TokenData.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +95,7 @@ public class SessionCacheHelper {
|
||||
* @param sessionId 当前会话的SessionId。
|
||||
*/
|
||||
public void removeAllSessionCache(String sessionId) {
|
||||
for (CacheConfig.CacheEnum c : CacheConfig.CacheEnum.values()) {
|
||||
for (RedissonCacheConfig.CacheEnum c : RedissonCacheConfig.CacheEnum.values()) {
|
||||
cacheManager.getCache(c.name()).evict(sessionId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.orange.demo.common.redis.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
/**
|
||||
* Redis配置类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "redis.jedis.enabled", havingValue = "true")
|
||||
public class JedisConfig {
|
||||
|
||||
@Value("${redis.jedis.port}")
|
||||
private Integer port;
|
||||
|
||||
@Value("${redis.jedis.host}")
|
||||
private String redisHost;
|
||||
|
||||
@Value("${redis.jedis.timeout}")
|
||||
private int timeout;
|
||||
|
||||
@Value("${redis.jedis.pool.maxTotal}")
|
||||
private Integer maxTotal;
|
||||
|
||||
@Value("${redis.jedis.pool.maxIdle}")
|
||||
private Integer maxIdle;
|
||||
|
||||
@Value("${redis.jedis.pool.minIdle}")
|
||||
private Integer minIdle;
|
||||
|
||||
@Value("${redis.jedis.pool.maxWait}")
|
||||
private Integer maxWait;
|
||||
|
||||
@Bean
|
||||
public JedisPool getJedisPool() {
|
||||
// Jedis配置信息
|
||||
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
|
||||
jedisPoolConfig.setMaxTotal(maxTotal);
|
||||
jedisPoolConfig.setMaxIdle(maxIdle);
|
||||
jedisPoolConfig.setMinIdle(minIdle);
|
||||
jedisPoolConfig.setMaxWaitMillis(maxWait);
|
||||
jedisPoolConfig.setEvictorShutdownTimeoutMillis(2000);
|
||||
return new JedisPool(jedisPoolConfig, redisHost, port);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.orange.demo.common.redis.config;
|
||||
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.Config;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Redisson配置类。和Jedis一样都是Redis客户端,但是Redisson提供了更多的数据结构抽象。
|
||||
* 这里我们只是使用了Redisson的分布式锁,以及map等数据结构作为字典缓存使用。更多用法请参考其文档。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "redis.redisson.enabled", havingValue = "true")
|
||||
public class RedissonConfig {
|
||||
|
||||
@Value("${redis.redisson.lockWatchdogTimeout}")
|
||||
private Integer lockWatchdogTimeout;
|
||||
|
||||
@Value("${redis.redisson.address}")
|
||||
private String address;
|
||||
|
||||
@Value("${redis.redisson.timeout}")
|
||||
private Integer timeout;
|
||||
|
||||
@Value("${redis.redisson.pool.poolSize}")
|
||||
private Integer poolSize;
|
||||
|
||||
@Value("${redis.redisson.pool.minIdle}")
|
||||
private Integer minIdle;
|
||||
|
||||
@Bean
|
||||
public RedissonClient redissonClient() {
|
||||
Config config = new Config();
|
||||
// 这里config还支持其他redis集群模式,可根据实际需求更换。
|
||||
// 比如useClusterServers()/useMasterSlaveServers()等。
|
||||
config.setLockWatchdogTimeout(lockWatchdogTimeout)
|
||||
.useSingleServer()
|
||||
.setAddress("redis://" + address)
|
||||
.setConnectionPoolSize(poolSize)
|
||||
.setConnectionMinimumIdleSize(minIdle)
|
||||
.setConnectTimeout(timeout);
|
||||
return Redisson.create(config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.orange.demo.common.redis.config.JedisConfig,\
|
||||
com.orange.demo.common.redis.config.RedissonConfig
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.orange.demo.common.swagger.config;
|
||||
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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 springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
/**
|
||||
* 自动加载bean的配置对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@EnableSwagger2
|
||||
@EnableKnife4j
|
||||
@EnableConfigurationProperties(SwaggerProperties.class)
|
||||
@ConditionalOnProperty(prefix = "swagger", name = "enabled")
|
||||
public class SwaggerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public Docket upmsDocket(SwaggerProperties properties) {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.groupName("1. 用户权限分组接口")
|
||||
.ignoredParameterTypes(MyRequestBody.class)
|
||||
.apiInfo(apiInfo(properties))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage(properties.getBasePackage() + ".upms.controller"))
|
||||
.paths(PathSelectors.any()).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket bizDocket(SwaggerProperties properties) {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.groupName("2. 业务应用分组接口")
|
||||
.ignoredParameterTypes(MyRequestBody.class)
|
||||
.apiInfo(apiInfo(properties))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage(properties.getBasePackage() + ".app.controller"))
|
||||
.paths(PathSelectors.any()).build();
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo(SwaggerProperties properties) {
|
||||
return new ApiInfoBuilder()
|
||||
.title(properties.getTitle())
|
||||
.description(properties.getDescription())
|
||||
.version(properties.getVersion()).build();
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.orange.demo.common.swagger.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* 配置参数对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("swagger")
|
||||
public class SwaggerProperties {
|
||||
|
||||
/**
|
||||
* 是否开启Swagger。
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* Swagger解析的基础包路径。
|
||||
**/
|
||||
private String basePackage = "";
|
||||
|
||||
/**
|
||||
* ApiInfo中的标题。
|
||||
**/
|
||||
private String title = "";
|
||||
|
||||
/**
|
||||
* ApiInfo中的描述信息。
|
||||
**/
|
||||
private String description = "";
|
||||
|
||||
/**
|
||||
* ApiInfo中的版本信息。
|
||||
**/
|
||||
private String version = "";
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user