This commit is contained in:
Jerry
2020-08-13 20:48:34 +08:00
parent cba38ca880
commit cf54acfc38
865 changed files with 38797 additions and 11325 deletions

View File

@@ -1,26 +0,0 @@
/target/
!.mvn/wrapper/maven-wrapper.jar
/.mvn/*
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

View File

@@ -1,5 +0,0 @@
### 服务启动环境依赖
---
在当前工程业务应用服务或Job服务启动前需按如下顺序依次启动下列中间件。
- XXL-Job (可选仅当启动Job服务时使用)

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.orange.admin</groupId>
<artifactId>OrangeAdmin</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>application</artifactId>
<version>1.0.0</version>
<name>application</name>
<packaging>jar</packaging>
<dependencies>
<!-- 业务组件依赖 -->
<dependency>
<groupId>com.orange.admin</groupId>
<artifactId>common-biz</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- tk.mapper 提供的单表自动生成 model/dao/mapper 的插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>${mybatis-generator.version}</version>
<configuration>
<configurationFile>${project.basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,18 +0,0 @@
package com.orange.admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 应用服务启动类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}

View File

@@ -1,56 +0,0 @@
package com.orange.admin.app.controller;
import cn.jimmyshi.beanquery.BeanQuery;
import com.orange.admin.app.model.AreaCode;
import com.orange.admin.app.service.AreaCodeService;
import com.orange.admin.common.core.object.ResponseResult;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 行政区划数据访问接口类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@RestController
@RequestMapping("/admin/app/areaCode")
public class AreaCodeController {
@Autowired
private AreaCodeService areaCodeService;
/**
* 按照字典的形式返回行政区划列表。
*
* @return 字典形式的行政区划列表。
*/
@GetMapping("/listDictAreaCode")
public ResponseResult<List<Map<String, Object>>> listDictAreaCode() {
List<AreaCode> resultList = areaCodeService.getAllList();
return ResponseResult.success(BeanQuery.select(
"parentId as parentId", "areaId as id", "areaName as name").executeFrom(resultList));
}
/**
* 根据上级行政区划Id获取其下级行政区划列表。
*
* @param parentId 上级行政区划Id。
* @return 按照字典的形式返回下级行政区划列表。
*/
@GetMapping("/listDictAreaCodeByParentId")
public ResponseResult<List<Map<String, Object>>> listDictAreaCodeByParentId(@RequestParam(required = false) Long parentId) {
Collection<AreaCode> resultList = areaCodeService.getListByParentId(parentId);
if (CollectionUtils.isEmpty(resultList)) {
return ResponseResult.success(new LinkedList<>());
}
return ResponseResult.success(BeanQuery.select(
"parentId as parentId", "areaId as id", "areaName as name").executeFrom(resultList));
}
}

View File

@@ -1,171 +0,0 @@
package com.orange.admin.app.controller;
import cn.jimmyshi.beanquery.BeanQuery;
import com.github.pagehelper.page.PageMethod;
import com.orange.admin.app.model.*;
import com.orange.admin.app.service.*;
import com.orange.admin.upms.model.*;
import com.orange.admin.common.core.object.*;
import com.orange.admin.common.core.util.*;
import com.orange.admin.common.core.constant.ErrorCodeEnum;
import com.orange.admin.common.core.annotation.MyRequestBody;
import com.orange.admin.common.core.validator.UpdateGroup;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import javax.validation.groups.Default;
/**
* 老师数据源操作控制器类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
@RestController
@RequestMapping("/admin/app/teacher")
public class TeacherController {
@Autowired
private TeacherService teacherService;
/**
* 新增老师数据源数据。
*
* @param teacher 新增对象。
* @return 应答结果对象包含新增对象主键Id。
*/
@PostMapping("/add")
public ResponseResult<JSONObject> add(@MyRequestBody Teacher teacher) {
String errorMessage = MyCommonUtil.getModelValidationError(teacher);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
// 验证关联Id的数据合法性
CallResult callResult = teacherService.verifyRelatedData(teacher, null);
if (!callResult.isSuccess()) {
errorMessage = callResult.getErrorMessage();
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
teacher = teacherService.saveNew(teacher);
JSONObject responseData = new JSONObject();
responseData.put("teacherId", teacher.getTeacherId());
return ResponseResult.success(responseData);
}
/**
* 更新老师数据源数据。
*
* @param teacher 更新对象。
* @return 应答结果对象。
*/
@PostMapping("/update")
public ResponseResult<Void> update(@MyRequestBody Teacher teacher) {
String errorMessage = MyCommonUtil.getModelValidationError(teacher, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
// 验证关联Id的数据合法性
Teacher originalTeacher = teacherService.getById(teacher.getTeacherId());
if (originalTeacher == null) {
//NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
// 验证关联Id的数据合法性
CallResult callResult = teacherService.verifyRelatedData(teacher, originalTeacher);
if (!callResult.isSuccess()) {
errorMessage = callResult.getErrorMessage();
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
if (!teacherService.update(teacher, originalTeacher)) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
/**
* 删除老师数据源数据。
*
* @param teacherId 删除对象主键Id。
* @return 应答结果对象。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long teacherId) {
String errorMessage;
if (MyCommonUtil.existBlankArgument(teacherId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
// 验证关联Id的数据合法性
Teacher originalTeacher = teacherService.getById(teacherId);
if (originalTeacher == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!teacherService.remove(teacherId)) {
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 列出符合过滤条件的老师数据源列表。
*
* @param teacherFilter 过滤对象。
* @param sysDeptFilter 一对一从表过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody Teacher teacherFilter,
@MyRequestBody SysDept sysDeptFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, Teacher.class);
List<Teacher> resultList =
teacherService.getTeacherListWithRelation(teacherFilter, sysDeptFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
}
/**
* 查看指定老师数据源对象详情。
*
* @param teacherId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<Teacher> view(@RequestParam Long teacherId) {
if (MyCommonUtil.existBlankArgument(teacherId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
Teacher teacher = teacherService.getByIdWithRelation(teacherId, MyRelationParam.full());
if (teacher == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success(teacher);
}
/**
* 以字典形式返回全部老师数据源数据集合。字典的键值为[teacherId, teacherName]。
* 白名单接口,登录用户均可访问。
*
* @param filter 过滤对象。
* @return 应答结果对象,包含的数据为 List<Map<String, String>>map中包含两条记录key的值分别是id和namevalue对应具体数据。
*/
@GetMapping("/listDictTeacher")
public ResponseResult<List<Map<String, Object>>> listDictTeacher(Teacher filter) {
List<Teacher> resultList = teacherService.getListByFilter(filter, null);
return ResponseResult.success(BeanQuery.select(
"teacherId as id", "teacherName as name").executeFrom(resultList));
}
}

View File

@@ -1,99 +0,0 @@
package com.orange.admin.app.controller;
import com.github.pagehelper.page.PageMethod;
import com.orange.admin.app.model.*;
import com.orange.admin.app.service.*;
import com.orange.admin.common.core.object.*;
import com.orange.admin.common.core.util.*;
import com.orange.admin.common.core.constant.ErrorCodeEnum;
import com.orange.admin.common.core.annotation.MyRequestBody;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 老师流水统计操作控制器类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
@RestController
@RequestMapping("/admin/app/teacherTransStats")
public class TeacherTransStatsController {
@Autowired
private TeacherTransStatsService teacherTransStatsService;
/**
* 列出符合过滤条件的老师流水统计列表。
*
* @param teacherTransStatsFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody TeacherTransStats teacherTransStatsFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, TeacherTransStats.class);
List<TeacherTransStats> resultList = teacherTransStatsService.getTeacherTransStatsListWithRelation(teacherTransStatsFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
}
/**
* 分组列出符合过滤条件的老师流水统计列表。
*
* @param teacherTransStatsFilter 过滤对象。
* @param groupParam 分组参数。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/listWithGroup")
public ResponseResult<JSONObject> listWithGroup(
@MyRequestBody TeacherTransStats teacherTransStatsFilter,
@MyRequestBody MyGroupParam groupParam,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
String orderBy = MyOrderParam.buildOrderBy(orderParam, TeacherTransStats.class);
groupParam = MyGroupParam.buildGroupBy(groupParam, TeacherTransStats.class);
if (groupParam == null) {
return ResponseResult.error(
ErrorCodeEnum.INVALID_ARGUMENT_FORMAT, "数据参数错误,分组参数不能为空!");
}
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
MyGroupCriteria criteria = groupParam.getGroupCriteria();
List<TeacherTransStats> resultList = teacherTransStatsService.getGroupedTeacherTransStatsListWithRelation(
teacherTransStatsFilter, criteria.getGroupSelect(), criteria.getGroupBy(), orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
}
/**
* 查看指定老师流水统计对象详情。
*
* @param statsId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<TeacherTransStats> view(@RequestParam Long statsId) {
if (MyCommonUtil.existBlankArgument(statsId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
TeacherTransStats teacherTransStats = teacherTransStatsService.getByIdWithRelation(statsId, MyRelationParam.full());
if (teacherTransStats == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success(teacherTransStats);
}
}

View File

@@ -1,13 +0,0 @@
package com.orange.admin.app.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.app.model.AreaCode;
/**
* 行政区划数据操作访问接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface AreaCodeMapper extends BaseDaoMapper<AreaCode> {
}

View File

@@ -1,42 +0,0 @@
package com.orange.admin.app.dao;
import com.orange.admin.common.core.annotation.EnableDataPerm;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.app.model.Teacher;
import com.orange.admin.upms.model.SysDept;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 老师数据源数据操作访问接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@EnableDataPerm
public interface TeacherMapper extends BaseDaoMapper<Teacher> {
/**
* 获取过滤后的对象列表。
*
* @param teacherFilter 主表过滤对象。
* @param orderBy 排序字符串order by从句的参数。
* @return 对象列表。
*/
List<Teacher> getTeacherList(
@Param("teacherFilter") Teacher teacherFilter, @Param("orderBy") String orderBy);
/**
* 获取过滤后的对象列表。同时支持基于一对一从表字段的过滤条件。
*
* @param teacherFilter 主表过滤对象。
* @param sysDeptFilter 一对一从表过滤对象。
* @param orderBy 排序字符串order by从句的参数。
* @return 对象列表。
*/
List<Teacher> getTeacherListEx(
@Param("teacherFilter") Teacher teacherFilter,
@Param("sysDeptFilter") SysDept sysDeptFilter,
@Param("orderBy") String orderBy);
}

View File

@@ -1,43 +0,0 @@
package com.orange.admin.app.dao;
import com.orange.admin.common.core.annotation.EnableDataPerm;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.app.model.TeacherTransStats;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 老师流水统计数据操作访问接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@EnableDataPerm
public interface TeacherTransStatsMapper extends BaseDaoMapper<TeacherTransStats> {
/**
* 获取分组计算后的数据对象列表。
*
* @param teacherTransStatsFilter 主表过滤对象。
* @param groupSelect 分组显示字段列表字符串SELECT从句的参数。
* @param groupBy 分组字段列表字符串GROUP BY从句的参数。
* @param orderBy 排序字符串ORDER BY从句的参数。
* @return 对象列表。
*/
List<TeacherTransStats> getGroupedTeacherTransStatsList(
@Param("teacherTransStatsFilter") TeacherTransStats teacherTransStatsFilter,
@Param("groupSelect") String groupSelect,
@Param("groupBy") String groupBy,
@Param("orderBy") String orderBy);
/**
* 获取过滤后的对象列表。
*
* @param teacherTransStatsFilter 主表过滤对象。
* @param orderBy 排序字符串order by从句的参数。
* @return 对象列表。
*/
List<TeacherTransStats> getTeacherTransStatsList(
@Param("teacherTransStatsFilter") TeacherTransStats teacherTransStatsFilter, @Param("orderBy") String orderBy);
}

View File

@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.app.dao.TeacherMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.app.model.Teacher">
<id column="teacher_id" jdbcType="BIGINT" property="teacherId"/>
<result column="teacher_name" jdbcType="VARCHAR" property="teacherName"/>
<result column="birthday" jdbcType="DATE" property="birthday"/>
<result column="gender" jdbcType="INTEGER" property="gender"/>
<result column="subject_id" jdbcType="INTEGER" property="subjectId"/>
<result column="level" jdbcType="INTEGER" property="level"/>
<result column="flower_count" jdbcType="INTEGER" property="flowerCount"/>
<result column="school_id" jdbcType="BIGINT" property="schoolId"/>
<result column="user_id" jdbcType="BIGINT" property="userId"/>
<result column="register_date" jdbcType="TIMESTAMP" property="registerDate"/>
<result column="available" jdbcType="BIT" property="available"/>
</resultMap>
<sql id="filterRef">
<if test="teacherFilter != null">
<if test="teacherFilter.teacherName != null and teacherFilter.teacherName != ''">
<bind name = "safeTeacherName" value = "'%' + teacherFilter.teacherName + '%'" />
AND zz_teacher.teacher_name LIKE #{safeTeacherName}
</if>
<if test="teacherFilter.birthdayStart != null and teacherFilter.birthdayStart != ''">
AND zz_teacher.birthday &gt;= #{teacherFilter.birthdayStart}
</if>
<if test="teacherFilter.birthdayEnd != null and teacherFilter.birthdayEnd != ''">
AND zz_teacher.birthday &lt;= #{teacherFilter.birthdayEnd}
</if>
<if test="teacherFilter.gender != null">
AND zz_teacher.gender = #{teacherFilter.gender}
</if>
<if test="teacherFilter.subjectId != null">
AND zz_teacher.subject_id = #{teacherFilter.subjectId}
</if>
<if test="teacherFilter.level != null">
AND zz_teacher.level = #{teacherFilter.level}
</if>
<if test="teacherFilter.schoolId != null">
AND zz_teacher.school_id = #{teacherFilter.schoolId}
</if>
<if test="teacherFilter.registerDateStart != null and teacherFilter.registerDateStart != ''">
AND zz_teacher.register_date &gt;= #{teacherFilter.registerDateStart}
</if>
<if test="teacherFilter.registerDateEnd != null and teacherFilter.registerDateEnd != ''">
AND zz_teacher.register_date &lt;= #{teacherFilter.registerDateEnd}
</if>
<if test="teacherFilter.available != null">
AND zz_teacher.available = #{teacherFilter.available}
</if>
</if>
</sql>
<select id="getTeacherList" resultMap="BaseResultMap" parameterType="com.orange.admin.app.model.Teacher">
SELECT * FROM zz_teacher
<where>
<include refid="filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
<!-- 支持基于一对一从表字段过滤的SQL_ID -->
<select id="getTeacherListEx" resultMap="BaseResultMap" >
SELECT
zz_teacher.*
FROM
zz_teacher
LEFT JOIN
zz_sys_dept ON zz_teacher.school_id = zz_sys_dept.dept_id
<where>
<include refid="filterRef"/>
<include refid="com.orange.admin.upms.dao.SysDeptMapper.filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
</mapper>

View File

@@ -1,62 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.app.dao.TeacherTransStatsMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.app.model.TeacherTransStats">
<id column="stats_id" jdbcType="BIGINT" property="statsId"/>
<result column="stats_date" jdbcType="DATE" property="statsDate"/>
<result column="stats_month" jdbcType="DATE" property="statsMonth"/>
<result column="province_id" jdbcType="BIGINT" property="provinceId"/>
<result column="city_id" jdbcType="BIGINT" property="cityId"/>
<result column="school_id" jdbcType="BIGINT" property="schoolId"/>
<result column="school_name" jdbcType="VARCHAR" property="schoolName"/>
<result column="teacher_id" jdbcType="BIGINT" property="teacherId"/>
<result column="teacher_name" jdbcType="VARCHAR" property="teacherName"/>
<result column="video_watch_count" jdbcType="INTEGER" property="videoWatchCount"/>
<result column="flower_count" jdbcType="INTEGER" property="flowerCount"/>
<result column="new_student" jdbcType="INTEGER" property="newStudent"/>
</resultMap>
<sql id="filterRef">
<if test="teacherTransStatsFilter != null">
<if test="teacherTransStatsFilter.statsDateStart != null and teacherTransStatsFilter.statsDateStart != ''">
AND zz_teacher_trans_stats.stats_date &gt;= #{teacherTransStatsFilter.statsDateStart}
</if>
<if test="teacherTransStatsFilter.statsDateEnd != null and teacherTransStatsFilter.statsDateEnd != ''">
AND zz_teacher_trans_stats.stats_date &lt;= #{teacherTransStatsFilter.statsDateEnd}
</if>
<if test="teacherTransStatsFilter.schoolId != null">
AND zz_teacher_trans_stats.school_id = #{teacherTransStatsFilter.schoolId}
</if>
<if test="teacherTransStatsFilter.teacherId != null">
AND zz_teacher_trans_stats.teacher_id = #{teacherTransStatsFilter.teacherId}
</if>
</if>
</sql>
<select id="getGroupedTeacherTransStatsList" resultMap="BaseResultMap" parameterType="com.orange.admin.app.model.TeacherTransStats">
SELECT * FROM
(SELECT
SUM(video_watch_count) video_watch_count,
SUM(flower_count) flower_count,
SUM(new_student) new_student,
${groupSelect}
FROM zz_teacher_trans_stats
<where>
<include refid="filterRef"/>
</where>
GROUP BY ${groupBy}) zz_teacher_trans_stats
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
<select id="getTeacherTransStatsList" resultMap="BaseResultMap" parameterType="com.orange.admin.app.model.TeacherTransStats">
SELECT * FROM zz_teacher_trans_stats
<where>
<include refid="filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
</mapper>

View File

@@ -1,185 +0,0 @@
package com.orange.admin.app.model;
import com.orange.admin.upms.model.SysDept;
import com.orange.admin.upms.model.SysUser;
import com.orange.admin.app.model.constant.Gender;
import com.orange.admin.common.biz.constant.Subject;
import com.orange.admin.app.model.constant.TeacherLevelType;
import com.orange.admin.common.biz.constant.YesNo;
import com.orange.admin.common.core.annotation.RelationDict;
import com.orange.admin.common.core.annotation.RelationConstDict;
import com.orange.admin.common.core.annotation.RelationOneToOne;
import com.orange.admin.common.core.annotation.DeptFilterColumn;
import com.orange.admin.common.core.annotation.UserFilterColumn;
import com.orange.admin.common.core.validator.UpdateGroup;
import com.orange.admin.common.core.validator.ConstDictRef;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Map;
/**
* Teacher实体对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Table(name = "zz_teacher")
public class Teacher {
/**
* 主键Id。
*/
@NotNull(message = "数据验证失败主键Id不能为空", groups = {UpdateGroup.class})
@Id
@UserFilterColumn
@Column(name = "teacher_id")
private Long teacherId;
/**
* 教师名称。
*/
@NotBlank(message = "数据验证失败,教师名称不能为空!")
@Column(name = "teacher_name")
private String teacherName;
/**
* 教师生日。
*/
@NotNull(message = "数据验证失败,出生日期不能为空!")
private Date birthday;
/**
* 教师性别(0: 女 1: 男)。
*/
@NotNull(message = "数据验证失败,性别不能为空!")
@ConstDictRef(constDictClass = Gender.class, message = "数据验证失败,性别为无效值!")
private Integer gender;
/**
* 所教的科目Id。
*/
@NotNull(message = "数据验证失败,所教科目不能为空!")
@ConstDictRef(constDictClass = Subject.class, message = "数据验证失败,所教科目为无效值!")
@Column(name = "subject_id")
private Integer subjectId;
/**
* 教师职级(0: 初级 1: 中级 2: 高级)。
*/
@NotNull(message = "数据验证失败,职级不能为空!")
@ConstDictRef(constDictClass = TeacherLevelType.class, message = "数据验证失败,职级为无效值!")
private Integer level;
/**
* 鲜花数量。
*/
@Column(name = "flower_count")
private Integer flowerCount;
/**
* 校区Id。
*/
@NotNull(message = "数据验证失败,所属校区不能为空!")
@DeptFilterColumn
@Column(name = "school_id")
private Long schoolId;
/**
* 用户Id。
*/
@NotNull(message = "数据验证失败,绑定用户不能为空!")
@Column(name = "user_id")
private Long userId;
/**
* 入职时间。
*/
@Column(name = "register_date")
private Date registerDate;
/**
* 是否在职。
*/
@NotNull(message = "数据验证失败,是否在职不能为空!")
@ConstDictRef(constDictClass = YesNo.class, message = "数据验证失败,是否在职为无效值!")
private Integer available;
/**
* birthday 范围过滤起始值(>=)。
*/
@Transient
private String birthdayStart;
/**
* birthday 范围过滤结束值(<=)。
*/
@Transient
private String birthdayEnd;
/**
* registerDate 范围过滤起始值(>=)。
*/
@Transient
private String registerDateStart;
/**
* registerDate 范围过滤结束值(<=)。
*/
@Transient
private String registerDateEnd;
@RelationOneToOne(
masterIdField = "schoolId",
slaveServiceName = "sysDeptService",
slaveModelClass = SysDept.class,
slaveIdField = "deptId")
@Transient
private SysDept sysDept;
@RelationDict(
masterIdField = "schoolId",
slaveServiceName = "sysDeptService",
equalOneToOneRelationField = "sysDept",
slaveModelClass = SysDept.class,
slaveIdField = "deptId",
slaveNameField = "deptName")
@Transient
private Map<String, Object> schoolIdDictMap;
@RelationDict(
masterIdField = "userId",
slaveServiceName = "sysUserService",
slaveModelClass = SysUser.class,
slaveIdField = "userId",
slaveNameField = "loginName")
@Transient
private Map<String, Object> userIdDictMap;
@RelationConstDict(
masterIdField = "gender",
constantDictClass = Gender.class)
@Transient
private Map<String, Object> genderDictMap;
@RelationConstDict(
masterIdField = "subjectId",
constantDictClass = Subject.class)
@Transient
private Map<String, Object> subjectIdDictMap;
@RelationConstDict(
masterIdField = "level",
constantDictClass = TeacherLevelType.class)
@Transient
private Map<String, Object> levelDictMap;
@RelationConstDict(
masterIdField = "available",
constantDictClass = YesNo.class)
@Transient
private Map<String, Object> availableDictMap;
}

View File

@@ -1,178 +0,0 @@
package com.orange.admin.app.model;
import com.orange.admin.upms.model.SysDept;
import com.orange.admin.common.core.annotation.RelationDict;
import com.orange.admin.common.core.annotation.RelationOneToOne;
import com.orange.admin.common.core.annotation.DeptFilterColumn;
import com.orange.admin.common.core.annotation.UserFilterColumn;
import com.orange.admin.common.core.validator.UpdateGroup;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Map;
/**
* TeacherTransStats实体对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Table(name = "zz_teacher_trans_stats")
public class TeacherTransStats {
/**
* 主键Id。
*/
@NotNull(message = "数据验证失败主键Id不能为空", groups = {UpdateGroup.class})
@Id
@Column(name = "stats_id")
private Long statsId;
/**
* 统计日期。
*/
@NotNull(message = "数据验证失败,统计日期不能为空!")
@Column(name = "stats_date")
private Date statsDate;
/**
* 统计月份。
*/
@NotNull(message = "数据验证失败,统计月份不能为空!")
@Column(name = "stats_month")
private Date statsMonth;
/**
* 省份Id。
*/
@NotNull(message = "数据验证失败,省份不能为空!")
@Column(name = "province_id")
private Long provinceId;
/**
* 城市Id。
*/
@NotNull(message = "数据验证失败,城市不能为空!")
@Column(name = "city_id")
private Long cityId;
/**
* 学校Id。
*/
@NotNull(message = "数据验证失败,校区不能为空!")
@DeptFilterColumn
@Column(name = "school_id")
private Long schoolId;
/**
* 学校名称。
*/
@NotBlank(message = "数据验证失败,学校名称不能为空!")
@Column(name = "school_name")
private String schoolName;
/**
* 老师Id。
*/
@NotNull(message = "数据验证失败,老师不能为空!")
@UserFilterColumn
@Column(name = "teacher_id")
private Long teacherId;
/**
* 老师名称。
*/
@NotBlank(message = "数据验证失败,老师名称不能为空!")
@Column(name = "teacher_name")
private String teacherName;
/**
* 视频观看数量。
*/
@NotNull(message = "数据验证失败,视频观看数量不能为空!")
@Column(name = "video_watch_count")
private Integer videoWatchCount;
/**
* 献花数量。
*/
@NotNull(message = "数据验证失败,献花数量不能为空!")
@Column(name = "flower_count")
private Integer flowerCount;
/**
* 新增学生数量。
*/
@NotNull(message = "数据验证失败,新增学生数量不能为空!")
@Column(name = "new_student")
private Integer newStudent;
/**
* statsDate 范围过滤起始值(>=)。
*/
@Transient
private String statsDateStart;
/**
* statsDate 范围过滤结束值(<=)。
*/
@Transient
private String statsDateEnd;
@RelationOneToOne(
masterIdField = "schoolId",
slaveServiceName = "sysDeptService",
slaveModelClass = SysDept.class,
slaveIdField = "deptId")
@Transient
private SysDept sysDept;
@RelationOneToOne(
masterIdField = "teacherId",
slaveServiceName = "teacherService",
slaveModelClass = Teacher.class,
slaveIdField = "teacherId")
@Transient
private Teacher teacher;
@RelationDict(
masterIdField = "provinceId",
slaveServiceName = "areaCodeService",
slaveModelClass = AreaCode.class,
slaveIdField = "areaId",
slaveNameField = "areaName")
@Transient
private Map<String, Object> provinceIdDictMap;
@RelationDict(
masterIdField = "cityId",
slaveServiceName = "areaCodeService",
slaveModelClass = AreaCode.class,
slaveIdField = "areaId",
slaveNameField = "areaName")
@Transient
private Map<String, Object> cityIdDictMap;
@RelationDict(
masterIdField = "schoolId",
slaveServiceName = "sysDeptService",
equalOneToOneRelationField = "sysDept",
slaveModelClass = SysDept.class,
slaveIdField = "deptId",
slaveNameField = "deptName")
@Transient
private Map<String, Object> schoolIdDictMap;
@RelationDict(
masterIdField = "teacherId",
slaveServiceName = "teacherService",
equalOneToOneRelationField = "teacher",
slaveModelClass = Teacher.class,
slaveIdField = "teacherId",
slaveNameField = "teacherName")
@Transient
private Map<String, Object> teacherIdDictMap;
}

View File

@@ -1,137 +0,0 @@
package com.orange.admin.app.service;
import com.orange.admin.app.dao.*;
import com.orange.admin.app.model.*;
import com.orange.admin.upms.model.*;
import com.orange.admin.upms.service.SysUserService;
import com.orange.admin.upms.service.SysDeptService;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.common.core.object.MyWhereCriteria;
import com.orange.admin.common.core.object.MyRelationParam;
import com.orange.admin.common.core.object.CallResult;
import com.orange.admin.common.biz.base.service.BaseBizService;
import com.orange.admin.common.biz.util.BasicIdGenerator;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 老师数据源数据操作服务类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Service
public class TeacherService extends BaseBizService<Teacher, Long> {
@Autowired
private TeacherMapper teacherMapper;
@Autowired
private SysDeptService sysDeptService;
@Autowired
private SysUserService sysUserService;
@Autowired
private BasicIdGenerator idGenerator;
/**
* 返回当前Service的主表Mapper对象。
*
* @return 主表Mapper对象。
*/
@Override
protected BaseDaoMapper<Teacher> mapper() {
return teacherMapper;
}
/**
* 保存新增对象。
*
* @param teacher 新增对象。
* @return 返回新增对象。
*/
@Transactional(rollbackFor = Exception.class)
public Teacher saveNew(Teacher teacher) {
teacher.setTeacherId(idGenerator.nextLongId());
teacher.setRegisterDate(new Date());
teacherMapper.insert(teacher);
return teacher;
}
/**
* 更新数据对象。
*
* @param teacher 更新的对象。
* @param originalTeacher 原有数据对象。
* @return 成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean update(Teacher teacher, Teacher originalTeacher) {
teacher.setRegisterDate(originalTeacher.getRegisterDate());
return teacherMapper.updateByPrimaryKey(teacher) == 1;
}
/**
* 删除指定数据。
*
* @param teacherId 主键Id。
* @return 成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean remove(Long teacherId) {
return teacherMapper.deleteByPrimaryKey(teacherId) != 0;
// 这里可继续删除关联数据。
}
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getTeacherListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<Teacher> getTeacherList(Teacher filter, String orderBy) {
return teacherMapper.getTeacherList(filter, orderBy);
}
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getTeacherList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param sysDeptFilter 一对一从表过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<Teacher> getTeacherListWithRelation(Teacher filter, SysDept sysDeptFilter, String orderBy) {
List<Teacher> resultList =
teacherMapper.getTeacherListEx(filter, sysDeptFilter, orderBy);
Map<String, List<MyWhereCriteria>> criteriaMap = buildAggregationAdditionalWhereCriteria();
this.buildRelationForDataList(resultList, MyRelationParam.normal(), criteriaMap);
return resultList;
}
/**
* 根据最新对象和原有对象的数据对比,判断关联的字典数据和多对一主表数据是否都是合法数据。
*
* @param teacher 最新数据对象。
* @param originalTeacher 原有数据对象。
* @return 数据全部正确返回true否则false。
*/
public CallResult verifyRelatedData(Teacher teacher, Teacher originalTeacher) {
String errorMessageFormat = "数据验证失败,关联的%s并不存在请刷新后重试";
//这里是基于字典的验证。
if (this.needToVerify(teacher, originalTeacher, Teacher::getSchoolId)
&& !sysDeptService.existId(teacher.getSchoolId())) {
return CallResult.error(String.format(errorMessageFormat, "所属校区"));
}
//这里是基于字典的验证。
if (this.needToVerify(teacher, originalTeacher, Teacher::getUserId)
&& !sysUserService.existId(teacher.getUserId())) {
return CallResult.error(String.format(errorMessageFormat, "绑定用户"));
}
return CallResult.ok();
}
}

View File

@@ -1,88 +0,0 @@
package com.orange.admin.app.service;
import com.orange.admin.app.dao.*;
import com.orange.admin.app.model.*;
import com.orange.admin.upms.service.SysDeptService;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.common.core.object.MyWhereCriteria;
import com.orange.admin.common.core.object.MyRelationParam;
import com.orange.admin.common.biz.base.service.BaseBizService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 老师流水统计数据操作服务类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Service
public class TeacherTransStatsService extends BaseBizService<TeacherTransStats, Long> {
@Autowired
private TeacherTransStatsMapper teacherTransStatsMapper;
@Autowired
private AreaCodeService areaCodeService;
@Autowired
private SysDeptService sysDeptService;
@Autowired
private TeacherService teacherService;
/**
* 返回当前Service的主表Mapper对象。
*
* @return 主表Mapper对象。
*/
@Override
protected BaseDaoMapper<TeacherTransStats> mapper() {
return teacherTransStatsMapper;
}
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getTeacherTransStatsListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<TeacherTransStats> getTeacherTransStatsList(TeacherTransStats filter, String orderBy) {
return teacherTransStatsMapper.getTeacherTransStatsList(filter, orderBy);
}
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getTeacherTransStatsList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<TeacherTransStats> getTeacherTransStatsListWithRelation(TeacherTransStats filter, String orderBy) {
List<TeacherTransStats> resultList = teacherTransStatsMapper.getTeacherTransStatsList(filter, orderBy);
Map<String, List<MyWhereCriteria>> criteriaMap = buildAggregationAdditionalWhereCriteria();
this.buildRelationForDataList(resultList, MyRelationParam.normal(), criteriaMap);
return resultList;
}
/**
* 获取分组过滤后的数据查询结果,以及关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
*
* @param filter 过滤对象。
* @param groupSelect 分组显示列表参数。位于SQL语句SELECT的后面。
* @param groupBy 分组参数。位于SQL语句的GROUP BY后面。
* @param orderBy 排序字符串ORDER BY从句的参数。
* @return 分组过滤结果集。
*/
public List<TeacherTransStats> getGroupedTeacherTransStatsListWithRelation(
TeacherTransStats filter, String groupSelect, String groupBy, String orderBy) {
List<TeacherTransStats> resultList =
teacherTransStatsMapper.getGroupedTeacherTransStatsList(filter, groupSelect, groupBy, orderBy);
// NOTE: 这里只是包含了关联数据,聚合计算数据没有包含。
// 主要原因是由于聚合字段通常被视为普通字段使用不会在group by的从句中出现语义上也不会在此关联。
this.buildRelationForDataList(resultList, MyRelationParam.normal(), null);
return resultList;
}
}

View File

@@ -1,46 +0,0 @@
package com.orange.admin.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 应用程序自定义的程序属性配置文件。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "application")
public class ApplicationConfig {
/**
* token的Http Request Header的key
*/
private String tokenHeaderKey;
/**
* token在过期之前但是已经需要被刷新时response返回的header信息的key。
*/
private String refreshedTokenHeaderKey;
/**
* token 加密用的密钥
*/
private String tokenSigningKey;
/**
* 用户密码加密用的salt值。
*/
private String passwordSalt;
/**
* 用户密码被重置之后的缺省密码
*/
private String defaultUserPassword;
/**
* 上传文件的基础目录
*/
private String uploadFileBaseDir;
/**
* 授信ip列表没有填写表示全部信任。多个ip之间逗号分隔如: http://10.10.10.1:8080,http://10.10.10.2:8080
*/
private String credentialIpList;
}

View File

@@ -1,57 +0,0 @@
package com.orange.admin.config;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import javax.servlet.Filter;
import java.nio.charset.StandardCharsets;
/**
* 这里主要配置Web的各种过滤器和监听器等Servlet容器组件。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Configuration
public class FilterConfig {
/**
* 配置Ajax跨域过滤器。
*/
@Bean
public CorsFilter corsFilterRegistration(ApplicationConfig applicationConfig) {
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
if (StringUtils.isNotBlank(applicationConfig.getCredentialIpList())) {
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
if (credentialIpList.length > 0) {
for (String ip : credentialIpList) {
corsConfiguration.addAllowedOrigin(ip);
}
}
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addExposedHeader(applicationConfig.getRefreshedTokenHeaderKey());
corsConfiguration.setAllowCredentials(true);
configSource.registerCorsConfiguration("/**", corsConfiguration);
}
return new CorsFilter(configSource);
}
@Bean
public FilterRegistrationBean<Filter> characterEncodingFilterRegistration() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>(
new org.springframework.web.filter.CharacterEncodingFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("encoding", StandardCharsets.UTF_8.name());
// forceEncoding强制response也被编码另外即使request中已经设置encodingforceEncoding也会重新设置
filterRegistrationBean.addInitParameter("forceEncoding", "true");
filterRegistrationBean.setAsyncSupported(true);
return filterRegistrationBean;
}
}

View File

@@ -1,53 +0,0 @@
package com.orange.admin.config;
import com.orange.admin.interceptor.AuthenticationInterceptor;
import com.orange.admin.common.biz.interceptor.AccessInterceptor;
import com.orange.admin.common.biz.interceptor.MyRequestArgumentResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* 所有的项目拦截器都在这里集中配置。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/**");
registry.addInterceptor(new AccessInterceptor()).addPathPatterns("/**");
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
// 添加MyRequestBody参数解析器
argumentResolvers.add(new MyRequestArgumentResolver());
}
@Bean
public HttpMessageConverter<String> responseBodyConverter() {
return new StringHttpMessageConverter(StandardCharsets.UTF_8);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(responseBodyConverter());
}
}

View File

@@ -1,137 +0,0 @@
package com.orange.admin.interceptor;
import com.orange.admin.config.CacheConfig;
import com.orange.admin.config.ApplicationConfig;
import com.orange.admin.upms.model.SysPermWhitelist;
import com.orange.admin.upms.service.SysPermWhitelistService;
import com.orange.admin.upms.service.SysPermService;
import com.orange.admin.common.core.annotation.NoAuthInterface;
import com.orange.admin.common.core.constant.ErrorCodeEnum;
import com.orange.admin.common.core.object.ResponseResult;
import com.orange.admin.common.core.object.TokenData;
import com.orange.admin.common.core.util.ApplicationContextHolder;
import com.orange.admin.common.core.util.JwtUtil;
import com.alibaba.fastjson.JSONObject;
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 org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
import java.util.List;
import java.util.stream.Collectors;
/**
* 登录用户Token验证、生成和权限验证的拦截器。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {
private ApplicationConfig applicationConfig =
ApplicationContextHolder.getBean("applicationConfig");
private CacheManager cacheManager =
ApplicationContextHolder.getBean("cacheManager");
private SysPermService sysPermService =
ApplicationContextHolder.getBean("sysPermService");
private static SysPermWhitelistService sysPermWhilelistService =
ApplicationContextHolder.getBean("sysPermWhitelistService");
private static Set<String> whitelistPermSet;
static {
List<SysPermWhitelist> sysPermWhitelistList = sysPermWhilelistService.getAllList();
whitelistPermSet = sysPermWhitelistList.stream()
.map(SysPermWhitelist::getPermUrl).collect(Collectors.toSet());
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String url = request.getRequestURI();
// 如果接口方法标记NoAuthInterface注解可以直接跳过Token鉴权验证这里主要为了测试接口方便
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler;
if (hm.getBeanType().getAnnotation(NoAuthInterface.class) != null
|| hm.getMethodAnnotation(NoAuthInterface.class) != null) {
return true;
}
}
String token = request.getHeader(applicationConfig.getTokenHeaderKey());
if (StringUtils.isBlank(token)) {
token = request.getParameter(applicationConfig.getTokenHeaderKey());
}
Claims c = JwtUtil.parseToken(token, applicationConfig.getTokenSigningKey());
if (JwtUtil.isNullOrExpired(c)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
this.outputResponseMessage(response,
ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN, "用户会话已过期,请重新登录!"));
return false;
}
String sessionId = (String) c.get("sessionId");
Cache cache = cacheManager.getCache(CacheConfig.CacheEnum.GLOBAL_CACHE.name());
TokenData tokenData = cache.get(sessionId, TokenData.class);
if (tokenData == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
this.outputResponseMessage(response,
ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN, "用户会话已失效,请重新登录!"));
return false;
}
TokenData.addToRequest(tokenData);
// 如果url在权限资源白名单中则不需要进行鉴权操作
if (!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;
}
}
if (JwtUtil.needToRefresh(c)) {
String refreshedToken = JwtUtil.generateToken(c, applicationConfig.getTokenSigningKey());
response.addHeader(applicationConfig.getRefreshedTokenHeaderKey(), refreshedToken);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 这里需要空注解否则sonar会不happy。
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 这里需要空注解否则sonar会不happy。
}
private void outputResponseMessage(HttpServletResponse response, ResponseResult<Object> respObj) {
PrintWriter out;
try {
out = response.getWriter();
} catch (IOException e) {
log.error("Failed to call OutputResponseMessage.", e);
return;
}
response.setContentType("application/json; charset=utf-8");
out.print(JSONObject.toJSONString(respObj));
out.flush();
out.close();
}
}

View File

@@ -1,292 +0,0 @@
package com.orange.admin.interceptor;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import com.orange.admin.common.core.constant.DataPermRuleType;
import com.orange.admin.common.core.annotation.DeptFilterColumn;
import com.orange.admin.common.core.annotation.UserFilterColumn;
import com.orange.admin.common.core.annotation.EnableDataPerm;
import com.orange.admin.common.core.exception.NoDataPermException;
import com.orange.admin.common.core.object.GlobalThreadLocal;
import com.orange.admin.common.core.object.TokenData;
import com.orange.admin.common.core.util.ApplicationContextHolder;
import com.orange.admin.common.core.util.ContextUtil;
import com.orange.admin.common.core.util.MyModelUtil;
import com.orange.admin.config.CacheConfig;
import com.orange.admin.upms.dao.SysDataPermMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SubSelect;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.common.Mapper;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.util.*;
/**
* Mybatis拦截器。目前用于数据权限的统一拦截和注入处理。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
@Slf4j
@Component
public class MybatisDataPermInterceptor implements Interceptor {
@Autowired
private CacheManager cacheManager;
/**
* HTTP Head或HTTP Request Parameter中菜单Id数据的KEY名称。
*/
private static final String MENU_ID_HEADER_KEY = "MenuId";
/**
* 对象缓存。由于Set是排序后的因为在查找排除方法名称时效率更高。
* 在应用服务启动的监听器中(LoadDataPermMapperListener),会调用当前对象的(loadMappersWithDataPerm)方法,加载缓存。
*/
private Map<String, ModelDataPermInfo> cacheMap = new HashMap<>();
/**
* 预先加载需要数据权限过滤的Mapper到缓存该函数会在(LoadDataPermMapperListener)监听器中调用。
*/
public void loadMappersWithDataPerm() {
@SuppressWarnings("all")
Map<String, Mapper> mapperMap =
ApplicationContextHolder.getApplicationContext().getBeansOfType(Mapper.class);
for (Mapper<?> mapperProxy : mapperMap.values()) {
// 优先处理jdk的代理
Object proxy = ReflectUtil.getFieldValue(mapperProxy, "h");
// 如果不是jdk的代理再看看cjlib的代理。
if (proxy == null) {
proxy = ReflectUtil.getFieldValue(mapperProxy, "CGLIB$CALLBACK_0");
}
Class<?> mapperClass =
(Class<?>) ReflectUtil.getFieldValue(proxy, "mapperInterface");
EnableDataPerm rule = mapperClass.getAnnotation(EnableDataPerm.class);
if (rule != null) {
loadRules(mapperClass, rule);
}
}
}
private void loadRules(Class<?> mapperClass, EnableDataPerm rule) {
// 由于给数据权限Mapper添加@EnableDataPerm将会导致无限递归因此这里检测到之后
// 会在系统启动加载监听器的时候,及时抛出异常。
if (mapperClass.equals(SysDataPermMapper.class)) {
throw new IllegalStateException("Add @EnableDataPerm annotation to SysDataPermMapper is ILLEGAL!");
}
// 这里开始获取当前Mapper已经声明的的SqlId中有哪些是需要排除在外的。
// 排除在外的将不进行数据过滤。
Set<String> excludeMethodNameSet = null;
String[] excludes = rule.excluseMethodName();
if (excludes.length > 0) {
excludeMethodNameSet = new HashSet<>();
for (String excludeName : excludes) {
excludeMethodNameSet.add(excludeName);
// 这里是给tk.mapper和pagehelper中分页查询先获取数据总量的查询。
excludeMethodNameSet.add(excludeName + "_COUNT");
}
}
// 获取Mapper关联的主表信息包括表名user过滤字段名和dept过滤字段名。
Class<?> modelClazz = (Class<?>)
((ParameterizedType) mapperClass.getGenericInterfaces()[0]).getActualTypeArguments()[0];
Field[] fields = ReflectUtil.getFields(modelClazz);
Field userFilterField = null;
Field deptFilterField = null;
for (Field field : fields) {
if (null != field.getAnnotation(UserFilterColumn.class)) {
userFilterField = field;
}
if (null != field.getAnnotation(DeptFilterColumn.class)) {
deptFilterField = field;
}
if (userFilterField != null && deptFilterField != null) {
break;
}
}
// 通过注解解析与Mapper关联的Model并获取与数据权限关联的信息并将结果缓存。
ModelDataPermInfo info = new ModelDataPermInfo();
info.setMainTableName(MyModelUtil.mapToTableName(modelClazz));
info.setExcludeMethodNameSet(excludeMethodNameSet);
if (userFilterField != null) {
info.setUserFilterColumn(MyModelUtil.mapToColumnName(userFilterField, modelClazz));
}
if (deptFilterField != null) {
info.setDeptFilterColumn(MyModelUtil.mapToColumnName(deptFilterField, modelClazz));
}
cacheMap.put(mapperClass.getName(), info);
}
@SuppressWarnings("unchecked")
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 只有在HttpServletRequest场景下该拦截器才起作用对于系统级别的预加载数据不会应用数据权限。
if (!ContextUtil.hasRequestContext()) {
return invocation.proceed();
}
// 判断当前线程本地存储中,业务操作是否禁用了数据权限过滤,如果禁用,则不进行后续的数据过滤处理了。
if (!GlobalThreadLocal.enabledDataPerm()) {
return invocation.proceed();
}
RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
StatementHandler delegate =
(StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");
//通过反射获取delegate父类BaseStatementHandler的mappedStatement属性
MappedStatement mappedStatement =
(MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
SqlCommandType commandType = mappedStatement.getSqlCommandType();
TokenData tokenData = TokenData.takeFromRequest();
// 数据过滤权限中只是过滤SELECT语句。如果是管理员则不参与数据权限的数据过滤显示全部数据。
if (commandType != SqlCommandType.SELECT || tokenData == null || Boolean.TRUE.equals(tokenData.getIsAdmin())) {
return invocation.proceed();
}
String sqlId = mappedStatement.getId();
int pos = StringUtils.lastIndexOf(sqlId, ".");
String className = StringUtils.substring(sqlId, 0, pos);
String methodName = StringUtils.substring(sqlId, pos + 1);
// 先从缓存中查找当前Mapper是否存在。
ModelDataPermInfo info = cacheMap.get(className);
// 再次查找当前方法是否为排除方法,如果不是,就参与数据权限注入过滤。
if (info != null && !CollUtil.contains(info.getExcludeMethodNameSet(), methodName)) {
String menuId = ContextUtil.getHttpRequest().getHeader(MENU_ID_HEADER_KEY);
if (StringUtils.isBlank(menuId)) {
menuId = ContextUtil.getHttpRequest().getParameter(MENU_ID_HEADER_KEY);
if (StringUtils.isBlank(menuId)) {
throw new IllegalStateException(
"No [ MENU_ID ] key found in Http Header for SQL_ID [ " + sqlId + " ].");
}
}
Cache cache = cacheManager.getCache(CacheConfig.CacheEnum.DATA_PERMISSION_CACHE.name());
Map<Object, Map<Integer, String>> menuIdAndDataPermMap =
(Map<Object, Map<Integer, String>>) cache.get(tokenData.getSessionId(), Map.class);
if (menuIdAndDataPermMap == null) {
throw new NoDataPermException(
"No Related DataPerm found with SESSION_ID [ " + tokenData.getSessionId() + " ].");
}
Map<Integer, String> dataPermMap = menuIdAndDataPermMap.get(Long.valueOf(menuId));
if (MapUtils.isEmpty(dataPermMap)) {
throw new NoDataPermException(
"No Related DataPerm found with MENU_ID [ " + menuId + " ] for SQL_ID [ " + sqlId + " ].");
}
processDataPerm(info, dataPermMap, delegate.getBoundSql());
}
return invocation.proceed();
}
private void processDataPerm(ModelDataPermInfo info, Map<Integer, String> dataPermMap, BoundSql boundSql)
throws JSQLParserException {
if (dataPermMap.containsKey(DataPermRuleType.TYPE_ALL)) {
return;
}
String sql = boundSql.getSql();
Select select = (Select) CCJSqlParserUtil.parse(sql);
PlainSelect selectBody = (PlainSelect) select.getSelectBody();
FromItem fromItem = selectBody.getFromItem();
PlainSelect subSelect = null;
if (fromItem instanceof SubSelect) {
subSelect = (PlainSelect) ((SubSelect) fromItem).getSelectBody();
}
List<String> criteriaList = new LinkedList<>();
for (Map.Entry<Integer, String> entry : dataPermMap.entrySet()) {
String filterClause = processDataPermRule(info, entry.getKey(), entry.getValue());
if (StringUtils.isNotBlank(filterClause)) {
criteriaList.add(filterClause);
}
}
if (CollectionUtils.isNotEmpty(criteriaList)) {
StringBuilder filterBuilder = new StringBuilder(128);
filterBuilder.append("(");
filterBuilder.append(StringUtils.join(criteriaList, " OR "));
filterBuilder.append(")");
String dataFilter = filterBuilder.toString();
if (subSelect != null) {
buildWhereClause(subSelect, dataFilter);
} else {
buildWhereClause(selectBody, dataFilter);
}
}
sql = select.toString();
ReflectUtil.setFieldValue(boundSql, "sql", sql);
}
private String processDataPermRule(ModelDataPermInfo info, Integer ruleType, String deptIds) {
TokenData tokenData = TokenData.takeFromRequest();
StringBuilder filter = new StringBuilder(128);
if (ruleType == DataPermRuleType.TYPE_USER_ONLY) {
if (StringUtils.isNotBlank(info.getUserFilterColumn())) {
filter.append(info.getMainTableName())
.append(".")
.append(info.getUserFilterColumn())
.append(" = ")
.append(tokenData.getUserId());
}
} else {
if (StringUtils.isNotBlank(info.getDeptFilterColumn())) {
if (ruleType == DataPermRuleType.TYPE_DEPT_ONLY) {
filter.append(info.getMainTableName())
.append(".")
.append(info.getDeptFilterColumn())
.append(" = ")
.append(tokenData.getDeptId());
} else if (ruleType == DataPermRuleType.TYPE_CUSTOM_DETP_LIST) {
filter.append(info.getMainTableName())
.append(".")
.append(info.getDeptFilterColumn())
.append(" IN (")
.append(deptIds)
.append(") ");
}
}
}
return filter.toString();
}
private void buildWhereClause(PlainSelect select, String dataFilter) throws JSQLParserException {
if (select.getWhere() == null) {
select.setWhere(CCJSqlParserUtil.parseCondExpression(dataFilter));
} else {
AndExpression and = new AndExpression(
CCJSqlParserUtil.parseCondExpression(dataFilter), select.getWhere());
select.setWhere(and);
}
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 这里需要空注解否则sonar会不happy。
}
@Data
private static final class ModelDataPermInfo {
private Set<String> excludeMethodNameSet;
private String userFilterColumn;
private String deptFilterColumn;
private String mainTableName;
}
}

View File

@@ -1,25 +0,0 @@
package com.orange.admin.listener;
import com.orange.admin.interceptor.MybatisDataPermInterceptor;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 应用服务启动监听器。
* 目前主要功能是调用DataPermInterceptor中的loadMappersWithEnableDataPerm方法
* 将标记有数据权限规则注解的Mapper对象加载到缓存以提升系统运行时效率。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Component
public class LoadDataPermMapperListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
MybatisDataPermInterceptor interceptor =
applicationReadyEvent.getApplicationContext().getBean(MybatisDataPermInterceptor.class);
interceptor.loadMappersWithDataPerm();
}
}

View File

@@ -1,129 +0,0 @@
package com.orange.admin.upms.controller;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import com.orange.admin.config.ApplicationConfig;
import com.orange.admin.config.CacheConfig;
import com.orange.admin.upms.service.*;
import com.orange.admin.upms.model.SysMenu;
import com.orange.admin.upms.model.SysUser;
import com.orange.admin.upms.model.constant.SysUserStatus;
import com.orange.admin.upms.model.constant.SysUserType;
import com.orange.admin.common.core.annotation.NoAuthInterface;
import com.orange.admin.common.core.constant.ErrorCodeEnum;
import com.orange.admin.common.core.object.ResponseResult;
import com.orange.admin.common.core.object.TokenData;
import com.orange.admin.common.core.util.JwtUtil;
import com.orange.admin.common.core.util.MyCommonUtil;
import com.orange.admin.common.core.util.RsaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* 登录接口控制器类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
@RestController
@RequestMapping("/admin/login")
public class LoginController {
@Autowired
private SysUserService sysUserService;
@Autowired
private SysMenuService sysMenuService;
@Autowired
private SysPermCodeService sysPermCodeService;
@Autowired
private SysPermService sysPermService;
@Autowired
private SysDataPermService sysDataPermService;
@Autowired
private ApplicationConfig appConfig;
@Autowired
private CacheManager cacheManager;
/**
* 登录接口。
*
* @param loginName 登录名。
* @param password 密码。
* @return 应答结果对象其中包括JWT的Token数据以及菜单列表。
*/
@NoAuthInterface
@GetMapping("/doLogin")
public ResponseResult<JSONObject> doLogin(
@RequestParam String loginName, @RequestParam String password) throws Exception {
if (MyCommonUtil.existBlankArgument(loginName, password)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
//NOTE: 执行RsaUtil工具类中的main函数可以生成新的公钥和私钥。
String privateKey =
"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKkLhAydtOtA4WuIkkIIUVaGWu4ElOEAQF9GTulHHWOwCHI1UvcKolvS1G+mdsKcmGtEAQ92AUde/kDRGu8Wn7kLDtCgUfo72soHz7Qfv5pVB4ohMxQd/9cxeKjKbDoirhB9Z3xGF20zUozp4ZPLxpTtI7azr0xzUtd5+D/HfLDrAgMBAAECgYEApESZhDz4YyeAJiPnpJ06lS8oS2VOWzsIUs0av5uoloeoHXtt7Lx7u2kroHeNrl3Hy2yg7ypH4dgQkGHin3VHrVAgjG3TxhgBXIqqntzzk2AGJKBeIIkRX86uTvtKZyp3flUgcwcGmpepAHS1V1DPY3aVYvbcqAmoL6DX6VYN0NECQQDQUitMdC76lEtAr5/ywS0nrZJDo6U7eQ7ywx/eiJ+YmrSye8oorlAj1VBWG+Cl6jdHOHtTQyYv/tu71fjzQiJTAkEAz7wb47/vcSUpNWQxItFpXz0o6rbJh71xmShn1AKP7XptOVZGlW9QRYEzHabV9m/DHqI00cMGhHrWZAhCiTkUCQJAFsJjaJ7o4weAkTieyO7B+CvGZw1h5/V55Jvcx3s1tH5yb22G0Jr6tm9/r2isSnQkReutzZLwgR3e886UvD7lcQJAAUcD2OOuQkDbPwPNtYwaHMbQgJj9JkOI9kskUE5vuiMdltOr/XFAyhygRtdmy2wmhAK1VnDfkmL6/IR8fEGImQJABOB0KCalb0M8CPnqqHzozrD8gPObnIIr4aVvLIPATN2g7MM2N6F7JbI4RZFiKa92LV6bhQCY8OvHi5K2cgFpbw==";
SysUser user = sysUserService.getSysUserByLoginName(loginName);
password = URLDecoder.decode(password, StandardCharsets.UTF_8.name());
password = RsaUtil.decrypt(password, privateKey);
if (user == null
|| !user.getPassword().equals(MyCommonUtil.encrptedPassword(password, appConfig.getPasswordSalt()))) {
return ResponseResult.error(ErrorCodeEnum.INVALID_USERNAME_PASSWORD);
}
String errorMessage;
if (user.getUserStatus() == SysUserStatus.STATUS_LOCKED) {
errorMessage = "登录失败,用户账号被锁定!";
return ResponseResult.error(ErrorCodeEnum.INVALID_USER_STATUS, errorMessage);
}
boolean isAdmin = user.getUserType() == SysUserType.TYPE_ADMIN;
Map<String, Object> claims = new HashMap<>(3);
String sessionId = MyCommonUtil.generateUuid();
claims.put("sessionId", sessionId);
String token = JwtUtil.generateToken(claims, appConfig.getTokenSigningKey());
JSONObject jsonData = new JSONObject();
jsonData.put(TokenData.REQUEST_ATTRIBUTE_NAME, token);
jsonData.put("showName", user.getShowName());
jsonData.put("isAdmin", isAdmin);
TokenData tokenData = new TokenData();
tokenData.setSessionId(sessionId);
tokenData.setUserId(user.getUserId());
tokenData.setDeptId(user.getDeptId());
tokenData.setShowName(user.getShowName());
tokenData.setIsAdmin(isAdmin);
Cache sessionCache = cacheManager.getCache(CacheConfig.CacheEnum.GLOBAL_CACHE.name());
sessionCache.put(sessionId, tokenData);
List<SysMenu> menuList;
if (isAdmin) {
menuList = sysMenuService.getAllMenuList();
} else {
menuList = sysMenuService.getMenuListByUserId(user.getUserId());
List<String> permCodeList = sysPermCodeService.getPermCodeListByUserId(user.getUserId());
jsonData.put("permCodeList", permCodeList);
}
jsonData.put("menuList", menuList);
if (user.getUserType() != SysUserType.TYPE_ADMIN) {
// 缓存用户的权限资源
sysPermService.putUserSysPermCache(sessionId, user.getUserId(), isAdmin);
sysDataPermService.putDataPermCache(sessionId, user.getUserId(), user.getDeptId(), isAdmin);
}
return ResponseResult.success(jsonData);
}
/**
* 登出操作。同时将Session相关的信息从缓存中删除。
*
* @return 应答结果对象。
*/
@PostMapping("/doLogout")
public ResponseResult<Void> doLogout() {
TokenData tokenData = TokenData.takeFromRequest();
sysPermService.removeUserSysPermCache(tokenData.getSessionId());
sysDataPermService.removeDataPermCache(tokenData.getSessionId());
return ResponseResult.success();
}
}

View File

@@ -1,291 +0,0 @@
package com.orange.admin.upms.controller;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import com.orange.admin.upms.model.SysDataPermMenu;
import com.orange.admin.upms.model.SysDataPerm;
import com.orange.admin.upms.model.SysUser;
import com.orange.admin.upms.service.SysDataPermService;
import com.orange.admin.upms.service.SysUserService;
import com.orange.admin.common.core.validator.UpdateGroup;
import com.orange.admin.common.core.constant.ErrorCodeEnum;
import com.orange.admin.common.core.object.CallResult;
import com.orange.admin.common.core.object.MyOrderParam;
import com.orange.admin.common.core.object.MyPageParam;
import com.orange.admin.common.core.object.ResponseResult;
import com.orange.admin.common.core.object.MyRelationParam;
import com.orange.admin.common.core.util.MyCommonUtil;
import com.orange.admin.common.core.util.MyPageUtil;
import com.orange.admin.common.core.annotation.MyRequestBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.groups.Default;
import java.util.*;
import java.util.stream.Collectors;
/**
* 数据权限接口控制器对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysDataPerm")
public class SysDataPermController {
@Autowired
private SysDataPermService sysDataPermService;
@Autowired
private SysUserService sysUserService;
/**
* 添加新数据权限操作。
*
* @param sysDataPerm 新增对象。
* @param deptIdListString 数据权限关联的部门Id列表多个之间逗号分隔。
* @param menuIdListString 数据权限关联的菜单Id列表多个之间逗号分隔。
* @return 应答结果对象。包含新增数据权限对象的主键Id。
*/
@SuppressWarnings("unchecked")
@PostMapping("/add")
public ResponseResult<JSONObject> add(
@MyRequestBody SysDataPerm sysDataPerm,
@MyRequestBody String deptIdListString,
@MyRequestBody String menuIdListString) {
if (MyCommonUtil.existBlankArgument(menuIdListString)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
String errorMessage = MyCommonUtil.getModelValidationError(sysDataPerm);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
CallResult result = sysDataPermService.verifyRelatedData(sysDataPerm, deptIdListString, menuIdListString);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, result.getErrorMessage());
}
List<SysDataPermMenu> dataPermMenuList = null;
Set<Long> deptIdSet = null;
if (result.getData() != null) {
dataPermMenuList = (List<SysDataPermMenu>) result.getData().get("dataPermMenuList");
deptIdSet = (Set<Long>) result.getData().get("deptIdSet");
}
sysDataPermService.saveNew(sysDataPerm, deptIdSet, dataPermMenuList);
JSONObject responseData = new JSONObject();
responseData.put("dataPermId", sysDataPerm.getDataPermId());
return ResponseResult.success(responseData);
}
/**
* 更新数据权限操作。
*
* @param sysDataPerm 更新的数据权限对象。
* @param deptIdListString 数据权限关联的部门Id列表多个之间逗号分隔。
* @param menuIdListString 数据权限关联的菜单Id列表多个之间逗号分隔
* @return 应答结果对象。
*/
@SuppressWarnings("unchecked")
@PostMapping("/update")
public ResponseResult<Void> update(
@MyRequestBody SysDataPerm sysDataPerm,
@MyRequestBody String deptIdListString,
@MyRequestBody String menuIdListString) {
if (MyCommonUtil.existBlankArgument(menuIdListString)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
String errorMessage = MyCommonUtil.getModelValidationError(sysDataPerm, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
SysDataPerm originalSysDataPerm = sysDataPermService.getById(sysDataPerm.getDataPermId());
if (originalSysDataPerm == null) {
errorMessage = "数据验证失败,当前数据权限并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
CallResult result = sysDataPermService.verifyRelatedData(sysDataPerm, deptIdListString, menuIdListString);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, result.getErrorMessage());
}
List<SysDataPermMenu> dataPermMenuList = null;
Set<Long> deptIdSet = null;
if (result.getData() != null) {
dataPermMenuList = (List<SysDataPermMenu>) result.getData().get("dataPermMenuList");
deptIdSet = (Set<Long>) result.getData().get("deptIdSet");
}
if (!sysDataPermService.update(sysDataPerm, originalSysDataPerm, deptIdSet, dataPermMenuList)) {
errorMessage = "更新失败,数据不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 删除数据权限操作。
*
* @param dataPermId 待删除数据权限主键Id。
* @return 应答数据结果。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long dataPermId) {
if (MyCommonUtil.existBlankArgument(dataPermId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
if (!sysDataPermService.remove(dataPermId)) {
String errorMessage = "数据操作失败,数据权限不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 查看数据权限列表。
*
* @param sysDataPermFilter 数据权限查询过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象。包含数据权限列表。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody SysDataPerm sysDataPermFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysDataPerm.class);
List<SysDataPerm> resultList = sysDataPermService.getSysDataPermList(sysDataPermFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
}
/**
* 查看单条数据权限详情。
*
* @param dataPermId 数据权限的主键Id。
* @return 应答结果对象,包含数据权限的详情。
*/
@GetMapping("/view")
public ResponseResult<SysDataPerm> view(@RequestParam Long dataPermId) {
if (MyCommonUtil.existBlankArgument(dataPermId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
SysDataPerm dataPerm = sysDataPermService.getByIdWithRelation(dataPermId, MyRelationParam.full());
if (dataPerm == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success(dataPerm);
}
/**
* 获取不包含指定数据权限Id的用户列表。
* 用户和数据权限是多对多关系当前接口将返回没有赋值指定DataPermId的用户列表。可用于给数据权限添加新用户。
*
* @param dataPermId 数据权限主键Id。
* @param sysUserFilter 用户数据的过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含用户列表数据。
*/
@PostMapping("/listNotInDataPermUser")
public ResponseResult<JSONObject> listNotInDataPermUser(
@MyRequestBody Long dataPermId,
@MyRequestBody SysUser sysUserFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
ResponseResult<Void> verifyResult = this.doDataPermUserVerify(dataPermId);
if (!verifyResult.isSuccess()) {
return ResponseResult.errorFrom(verifyResult);
}
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
List<SysUser> resultList =
sysUserService.getNotInSysUserListByDataPermId(dataPermId, sysUserFilter, orderBy);
JSONObject responseData = MyPageUtil.makeResponseData(resultList);
return ResponseResult.success(responseData);
}
/**
* 拥有指定数据权限的用户列表。
*
* @param dataPermId 数据权限主键Id。
* @param sysUserFilter 用户过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含用户列表数据。
*/
@PostMapping("/listDataPermUser")
public ResponseResult<JSONObject> listDataPermUser(
@MyRequestBody Long dataPermId,
@MyRequestBody SysUser sysUserFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
ResponseResult<Void> verifyResult = this.doDataPermUserVerify(dataPermId);
if (!verifyResult.isSuccess()) {
return ResponseResult.errorFrom(verifyResult);
}
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
List<SysUser> resultList =
sysUserService.getSysUserListByDataPermId(dataPermId, sysUserFilter, orderBy);
JSONObject responseData = MyPageUtil.makeResponseData(resultList);
return ResponseResult.success(responseData);
}
private ResponseResult<Void> doDataPermUserVerify(Long dataPermId) {
if (MyCommonUtil.existBlankArgument(dataPermId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
if (!sysDataPermService.existId(dataPermId)) {
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
}
return ResponseResult.success();
}
/**
* 为指定数据权限添加用户列表。该操作可同时给一批用户赋值数据权限,并在同一事务内完成。
*
* @param dataPermId 数据权限主键Id。
* @param userIdListString 逗号分隔的用户Id列表。
* @return 应答结果对象。
*/
@PostMapping("/addDataPermUser")
public ResponseResult<Void> addDataPermUser(
@MyRequestBody Long dataPermId, @MyRequestBody String userIdListString) {
if (MyCommonUtil.existBlankArgument(dataPermId, userIdListString)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
Set<Long> userIdSet =
Arrays.stream(userIdListString.split(",")).map(Long::valueOf).collect(Collectors.toSet());
if (!sysDataPermService.existId(dataPermId)
|| !sysUserService.existUniqueKeyList("userId", userIdSet)) {
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
}
sysDataPermService.addDataPermUserList(dataPermId, userIdSet);
return ResponseResult.success();
}
/**
* 为指定用户移除指定数据权限。
*
* @param dataPermId 指定数据权限主键Id。
* @param userId 指定用户主键Id。
* @return 应答数据结果。
*/
@PostMapping("/deleteDataPermUser")
public ResponseResult<Void> deleteDataPermUser(
@MyRequestBody Long dataPermId, @MyRequestBody Long userId) {
if (MyCommonUtil.existBlankArgument(dataPermId, userId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
if (!sysDataPermService.removeDataPermUser(dataPermId, userId)) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
}

View File

@@ -1,155 +0,0 @@
package com.orange.admin.upms.controller;
import cn.jimmyshi.beanquery.BeanQuery;
import com.github.pagehelper.page.PageMethod;
import com.orange.admin.upms.model.*;
import com.orange.admin.upms.service.*;
import com.orange.admin.common.core.object.*;
import com.orange.admin.common.core.util.*;
import com.orange.admin.common.core.constant.ErrorCodeEnum;
import com.orange.admin.common.core.annotation.MyRequestBody;
import com.orange.admin.common.core.validator.UpdateGroup;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import javax.validation.groups.Default;
/**
* 部门管理操作控制器类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysDept")
public class SysDeptController {
@Autowired
private SysDeptService sysDeptService;
/**
* 新增部门管理数据。
*
* @param sysDept 新增对象。
* @return 应答结果对象包含新增对象主键Id。
*/
@PostMapping("/add")
public ResponseResult<JSONObject> add(@MyRequestBody SysDept sysDept) {
String errorMessage = MyCommonUtil.getModelValidationError(sysDept);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
sysDept = sysDeptService.saveNew(sysDept);
JSONObject responseData = new JSONObject();
responseData.put("deptId", sysDept.getDeptId());
return ResponseResult.success(responseData);
}
/**
* 更新部门管理数据。
*
* @param sysDept 更新对象。
* @return 应答结果对象。
*/
@PostMapping("/update")
public ResponseResult<Void> update(@MyRequestBody SysDept sysDept) {
String errorMessage = MyCommonUtil.getModelValidationError(sysDept, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
// 验证关联Id的数据合法性
SysDept originalSysDept = sysDeptService.getById(sysDept.getDeptId());
if (originalSysDept == null) {
//NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!sysDeptService.update(sysDept, originalSysDept)) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
/**
* 删除部门管理数据。
*
* @param deptId 删除对象主键Id。
* @return 应答结果对象。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long deptId) {
String errorMessage;
if (MyCommonUtil.existBlankArgument(deptId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
// 验证关联Id的数据合法性
SysDept originalSysDept = sysDeptService.getById(deptId);
if (originalSysDept == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!sysDeptService.remove(deptId)) {
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 列出符合过滤条件的部门管理列表。
*
* @param sysDeptFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody SysDept sysDeptFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysDept.class);
List<SysDept> resultList = sysDeptService.getSysDeptListWithRelation(sysDeptFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
}
/**
* 查看指定部门管理对象详情。
*
* @param deptId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<SysDept> view(@RequestParam Long deptId) {
if (MyCommonUtil.existBlankArgument(deptId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
SysDept sysDept = sysDeptService.getByIdWithRelation(deptId, MyRelationParam.full());
if (sysDept == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success(sysDept);
}
/**
* 以字典形式返回全部部门管理数据集合。字典的键值为[deptId, deptName]。
* 白名单接口,登录用户均可访问。
*
* @param filter 过滤对象。
* @return 应答结果对象,包含的数据为 List<Map<String, String>>map中包含两条记录key的值分别是id和namevalue对应具体数据。
*/
@GetMapping("/listDictSysDept")
public ResponseResult<List<Map<String, Object>>> listDictSysDept(SysDept filter) {
List<SysDept> resultList = sysDeptService.getListByFilter(filter, null);
return ResponseResult.success(BeanQuery.select(
"deptId as id", "deptName as name").executeFrom(resultList));
}
}

View File

@@ -1,200 +0,0 @@
package com.orange.admin.upms.controller;
import cn.jimmyshi.beanquery.BeanQuery;
import com.github.pagehelper.page.PageMethod;
import com.orange.admin.upms.model.*;
import com.orange.admin.upms.service.*;
import com.orange.admin.common.core.object.*;
import com.orange.admin.common.core.util.*;
import com.orange.admin.common.core.constant.ErrorCodeEnum;
import com.orange.admin.common.core.annotation.MyRequestBody;
import com.orange.admin.common.core.validator.UpdateGroup;
import com.orange.admin.config.ApplicationConfig;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import javax.validation.groups.Default;
/**
* 用户管理操作控制器类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysUser")
public class SysUserController {
@Autowired
private SysUserService sysUserService;
@Autowired
private ApplicationConfig applicationConfig;
/**
* 新增用户操作。
*
* @param sysUser 新增用户对象。
* @param roleIdListString 逗号分隔的角色Id列表。
* @param dataPermIdListString 逗号分隔的数据权限Id列表。
* @return 应答结果对象包含新增用户的主键Id。
*/
@SuppressWarnings("unchecked")
@PostMapping("/add")
public ResponseResult<JSONObject> add(
@MyRequestBody SysUser sysUser,
@MyRequestBody String roleIdListString,
@MyRequestBody String dataPermIdListString) {
String errorMessage = MyCommonUtil.getModelValidationError(sysUser);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
CallResult result = sysUserService.verifyRelatedData(
sysUser, null, roleIdListString, dataPermIdListString);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, result.getErrorMessage());
}
Set<Long> roleIdSet = (Set<Long>) result.getData().get("roleIdSet");
Set<Long> dataPermIdSet = (Set<Long>) result.getData().get("dataPermIdSet");
sysUserService.saveNew(sysUser, roleIdSet, dataPermIdSet, applicationConfig.getPasswordSalt());
JSONObject responseData = new JSONObject();
responseData.put("userId", sysUser.getUserId());
return ResponseResult.success(responseData);
}
/**
* 更新用户操作。
*
* @param sysUser 更新用户对象。
* @param roleIdListString 逗号分隔的角色Id列表。
* @param dataPermIdListString 逗号分隔的数据权限Id列表。
* @return 应答结果对象。
*/
@SuppressWarnings("unchecked")
@PostMapping("/update")
public ResponseResult<Void> update(
@MyRequestBody SysUser sysUser,
@MyRequestBody String roleIdListString,
@MyRequestBody String dataPermIdListString) {
String errorMessage = MyCommonUtil.getModelValidationError(sysUser, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
SysUser originalUser = sysUserService.getById(sysUser.getUserId());
if (originalUser == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
CallResult result = sysUserService.verifyRelatedData(
sysUser, originalUser, roleIdListString, dataPermIdListString);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, result.getErrorMessage());
}
Set<Long> roleIdSet = (Set<Long>) result.getData().get("roleIdSet");
Set<Long> dataPermIdSet = (Set<Long>) result.getData().get("dataPermIdSet");
if (!sysUserService.update(sysUser, originalUser, roleIdSet, dataPermIdSet)) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
/**
* 重置密码操作。
*
* @param userId 指定用户主键Id。
* @return 应答结果对象。
*/
@PostMapping("/resetPassword")
public ResponseResult<Void> resetPassword(@MyRequestBody Long userId) {
if (MyCommonUtil.existBlankArgument(userId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
if (!sysUserService.resetPassword(
userId, applicationConfig.getDefaultUserPassword(), applicationConfig.getPasswordSalt())) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
/**
* 删除用户管理数据。
*
* @param userId 删除对象主键Id。
* @return 应答结果对象。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long userId) {
String errorMessage;
if (MyCommonUtil.existBlankArgument(userId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
// 验证关联Id的数据合法性
SysUser originalSysUser = sysUserService.getById(userId);
if (originalSysUser == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!sysUserService.remove(userId)) {
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 列出符合过滤条件的用户管理列表。
*
* @param sysUserFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody SysUser sysUserFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
List<SysUser> resultList = sysUserService.getSysUserListWithRelation(sysUserFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
}
/**
* 查看指定用户管理对象详情。
*
* @param userId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<SysUser> view(@RequestParam Long userId) {
if (MyCommonUtil.existBlankArgument(userId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
// 这里查看用户数据时候需要把用户多对多关联的角色和数据权限Id一并查出。
SysUser sysUser = sysUserService.getByIdWithRelation(userId, MyRelationParam.full());
if (sysUser == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success(sysUser);
}
/**
* 以字典形式返回全部用户管理数据集合。字典的键值为[userId, loginName]。
* 白名单接口,登录用户均可访问。
*
* @param filter 过滤对象。
* @return 应答结果对象,包含的数据为 List<Map<String, String>>map中包含两条记录key的值分别是id和namevalue对应具体数据。
*/
@GetMapping("/listDictSysUser")
public ResponseResult<List<Map<String, Object>>> listDictSysUser(SysUser filter) {
List<SysUser> resultList = sysUserService.getListByFilter(filter, null);
return ResponseResult.success(BeanQuery.select(
"userId as id", "loginName as name").executeFrom(resultList));
}
}

View File

@@ -1,13 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysDataPermDept;
/**
* 数据权限与部门关系数据访问操作接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysDataPermDeptMapper extends BaseDaoMapper<SysDataPermDept> {
}

View File

@@ -1,27 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysDataPerm;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 数据权限数据访问操作接口。
* NOTE: 该对象一定不能被 @EnableDataPerm 注解标注,否则会导致无限递归。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysDataPermMapper extends BaseDaoMapper<SysDataPerm> {
/**
* 获取数据权限列表。
*
* @param sysDataPermFilter 过滤对象。
* @param orderBy 排序字符串。
* @return 过滤后的数据权限列表。
*/
List<SysDataPerm> getSysDataPermList(
@Param("sysDataPermFilter") SysDataPerm sysDataPermFilter, @Param("orderBy") String orderBy);
}

View File

@@ -1,24 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysDataPermMenu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 数据权限与菜单关系数据访问操作接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysDataPermMenuMapper extends BaseDaoMapper<SysDataPermMenu> {
/**
* 获取指定用户Id的数据权限列表。
*
* @param userId 指定的用户Id。
* @return 数据权限列表。
*/
List<SysDataPermMenu> getSysDataPermMenuListByUserId(@Param("userId") Long userId);
}

View File

@@ -1,22 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysDataPermUser;
import java.util.List;
/**
* 数据权限与用户关系数据访问操作接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysDataPermUserMapper extends BaseDaoMapper<SysDataPermUser> {
/**
* 批量添加数据权限和用户关系的列表。
*
* @param dataPermUserList 数据权限用户关系列表。
*/
void addDataPermUserList(List<SysDataPermUser> dataPermUserList);
}

View File

@@ -1,26 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysDept;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 部门管理数据操作访问接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysDeptMapper extends BaseDaoMapper<SysDept> {
/**
* 获取过滤后的对象列表。
*
* @param sysDeptFilter 主表过滤对象。
* @param orderBy 排序字符串order by从句的参数。
* @return 对象列表。
*/
List<SysDept> getSysDeptList(
@Param("sysDeptFilter") SysDept sysDeptFilter, @Param("orderBy") String orderBy);
}

View File

@@ -1,13 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysMenuPermCode;
/**
* 菜单与权限字关系数据访问操作接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysMenuPermCodeMapper extends BaseDaoMapper<SysMenuPermCode> {
}

View File

@@ -1,13 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysPermCodePerm;
/**
* 权限字与权限资源关系数据访问操作接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysPermCodePermMapper extends BaseDaoMapper<SysPermCodePerm> {
}

View File

@@ -1,13 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysPermWhitelist;
/**
* 权限资源白名单数据访问操作接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysPermWhitelistMapper extends BaseDaoMapper<SysPermWhitelist> {
}

View File

@@ -1,13 +0,0 @@
package com.orange.admin.upms.dao;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.model.SysRoleMenu;
/**
* 角色与菜单操作关联关系数据访问操作接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public interface SysRoleMenuMapper extends BaseDaoMapper<SysRoleMenu> {
}

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.upms.dao.SysDataPermDeptMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.upms.model.SysDataPermDept">
<result column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
<result column="dept_id" jdbcType="BIGINT" property="deptId"/>
</resultMap>
</mapper>

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.upms.dao.SysDataPermMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.upms.model.SysDataPerm">
<id column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
<result column="data_perm_name" jdbcType="VARCHAR" property="dataPermName"/>
<result column="rule_type" jdbcType="INTEGER" property="ruleType"/>
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
<result column="create_username" jdbcType="VARCHAR" property="createUsername"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
<result column="deleted_flag" jdbcType="INTEGER" property="deletedFlag"/>
</resultMap>
<resultMap id="BaseResultMapEx" type="com.orange.admin.upms.model.SysDataPerm" extends="BaseResultMap">
<collection property="dataPermDeptList" column="data_perm_id" javaType="ArrayList"
ofType="com.orange.admin.upms.model.SysDataPermDept" notNullColumn="dept_id"
resultMap="com.orange.admin.upms.dao.SysDataPermDeptMapper.BaseResultMap">
</collection>
</resultMap>
<sql id="filterRef">
<if test="sysDataPermFilter != null">
<if test="sysDataPermFilter.ruleType != null">
AND zz_sys_data_perm.rule_type = #{sysDataPermFilter.ruleType}
</if>
<if test="sysDataPermFilter.searchString != null and sysDataPermFilter.searchString != ''">
<bind name= "safeSearchString" value= "'%' + sysDataPermFilter.searchString + '%'" />
AND IFNULL(zz_sys_data_perm.data_perm_name, '') LIKE #{safeSearchString}
</if>
</if>
AND zz_sys_data_perm.deleted_flag = ${@com.orange.admin.common.core.constant.GlobalDeletedFlag@NORMAL}
</sql>
<select id="getSysDataPermList" resultMap="BaseResultMap" parameterType="com.orange.admin.upms.model.SysDataPerm">
SELECT
zz_sys_data_perm.*
FROM
zz_sys_data_perm
<where>
<include refid="filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
</mapper>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.upms.dao.SysDataPermMenuMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.upms.model.SysDataPermMenu">
<result column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
<result column="menu_id" jdbcType="BIGINT" property="menuId"/>
</resultMap>
<resultMap id="BaseResultMapEx" type="com.orange.admin.upms.model.SysDataPermMenu" extends="BaseResultMap">
<result column="rule_type" jdbcType="INTEGER" property="ruleType"/>
</resultMap>
<select id="getSysDataPermMenuListByUserId" resultMap="BaseResultMapEx" >
SELECT
dpm.*, dp.rule_type
FROM
zz_sys_data_perm_user dpu
INNER JOIN
zz_sys_data_perm dp ON dpu.data_perm_id = dp.data_perm_id
LEFT JOIN
zz_sys_data_perm_menu dpm ON dpu.data_perm_id = dpm.data_perm_id
<where>
AND dpu.user_id = #{userId}
AND dp.deleted_flag = ${@com.orange.admin.common.core.constant.GlobalDeletedFlag@NORMAL}
</where>
</select>
</mapper>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.upms.dao.SysDataPermUserMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.upms.model.SysDataPermUser">
<result column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
<result column="user_id" jdbcType="BIGINT" property="userId"/>
</resultMap>
<insert id="addDataPermUserList">
REPLACE INTO zz_sys_data_perm_user(data_perm_id, user_id) VALUES
<foreach collection="list" index="index" item="item" separator=",">
(#{item.dataPermId}, #{item.userId})
</foreach>
</insert>
</mapper>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.upms.dao.SysDeptMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.upms.model.SysDept">
<id column="dept_id" jdbcType="BIGINT" property="deptId"/>
<result column="dept_name" jdbcType="VARCHAR" property="deptName"/>
<result column="show_order" jdbcType="INTEGER" property="showOrder"/>
<result column="deleted_flag" jdbcType="INTEGER" property="deletedFlag"/>
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
<result column="create_username" jdbcType="VARCHAR" property="createUsername"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
</resultMap>
<sql id="filterRef">
<if test="sysDeptFilter != null">
<if test="sysDeptFilter.deptName != null and sysDeptFilter.deptName != ''">
<bind name = "safeDeptName" value = "'%' + sysDeptFilter.deptName + '%'" />
AND zz_sys_dept.dept_name LIKE #{safeDeptName}
</if>
</if>
AND zz_sys_dept.deleted_flag = ${@com.orange.admin.common.core.constant.GlobalDeletedFlag@NORMAL}
</sql>
<select id="getSysDeptList" resultMap="BaseResultMap" parameterType="com.orange.admin.upms.model.SysDept">
SELECT * FROM zz_sys_dept
<where>
<include refid="filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
</mapper>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.orange.admin.upms.dao.SysMenuPermCodeMapper">
<resultMap id="BaseResultMap" type="com.orange.admin.upms.model.SysMenuPermCode">
<result column="menu_id" jdbcType="BIGINT" property="menuId"/>
<result column="perm_cod_id" jdbcType="BIGINT" property="permCodeId"/>
</resultMap>
</mapper>

View File

@@ -1,104 +0,0 @@
package com.orange.admin.upms.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.orange.admin.common.core.annotation.DeletedFlagColumn;
import com.orange.admin.common.core.annotation.JobUpdateTimeColumn;
import com.orange.admin.common.core.annotation.RelationManyToMany;
import com.orange.admin.common.core.validator.ConstDictRef;
import com.orange.admin.common.core.validator.UpdateGroup;
import com.orange.admin.common.core.constant.DataPermRuleType;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.*;
/**
* 数据权限实体对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Table(name = "zz_sys_data_perm")
public class SysDataPerm {
/**
* 主键Id。
*/
@NotNull(message = "数据权限Id不能为空", groups = {UpdateGroup.class})
@Id
@Column(name = "data_perm_id")
private Long dataPermId;
/**
* 显示名称。
*/
@NotBlank(message = "数据权限名称不能为空!")
@Column(name = "data_perm_name")
private String dataPermName;
/**
* 数据权限规则类型(0: 全部可见 1: 只看自己 2: 只看本部门 3: 本部门及子部门 4: 多部门及子部门 5: 自定义部门列表)。
*/
@NotNull(message = "数据权限规则类型不能为空!")
@ConstDictRef(constDictClass = DataPermRuleType.class)
@Column(name = "rule_type")
private Integer ruleType;
/**
* 创建者。
*/
@Column(name = "create_user_id")
private Long createUserId;
/**
* 创建者显示名称。
*/
@Column(name = "create_username")
private String createUsername;
/**
* 创建时间。
*/
@Column(name = "create_time")
private Date createTime;
/**
* 更新时间。
*/
@JobUpdateTimeColumn
@Column(name = "update_time")
private Date updateTime;
/**
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
*/
@JSONField(serialize = false)
@DeletedFlagColumn
@Column(name = "deleted_flag")
private Integer deletedFlag;
@RelationManyToMany(
relationMapperName = "sysDataPermDeptMapper",
relationMasterIdField = "dataPermId",
relationModelClass = SysDataPermDept.class)
@Transient
private List<SysDataPermDept> dataPermDeptList;
@RelationManyToMany(
relationMapperName = "sysDataPermMenuMapper",
relationMasterIdField = "dataPermId",
relationModelClass = SysDataPermMenu.class)
@Transient
private List<SysDataPermMenu> dataPermMenuList;
@Transient
private String createTimeStart;
@Transient
private String createTimeEnd;
@Transient
private String searchString;
}

View File

@@ -1,34 +0,0 @@
package com.orange.admin.upms.model;
import lombok.Data;
import lombok.ToString;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 数据权限与部门关联实体对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@ToString(of = {"deptId"})
@Table(name = "zz_sys_data_perm_dept")
public class SysDataPermDept {
/**
* 数据权限Id。
*/
@Id
@Column(name = "data_perm_id")
private Long dataPermId;
/**
* 关联部门Id。
*/
@Id
@Column(name = "dept_id")
private Long deptId;
}

View File

@@ -1,36 +0,0 @@
package com.orange.admin.upms.model;
import lombok.Data;
import javax.persistence.*;
/**
* 数据权限与菜单关联实体对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Table(name = "zz_sys_data_perm_menu")
public class SysDataPermMenu {
/**
* 数据权限Id。
*/
@Id
@Column(name = "data_perm_id")
private Long dataPermId;
/**
* 关联菜单Id。
*/
@Id
@Column(name = "menu_id")
private Long menuId;
@Transient
private Integer ruleType;
@Transient
private String deptIdListString;
}

View File

@@ -1,30 +0,0 @@
package com.orange.admin.upms.model;
import lombok.Data;
import javax.persistence.*;
/**
* 数据权限与用户关联实体对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Table(name = "zz_sys_data_perm_user")
public class SysDataPermUser {
/**
* 数据权限Id。
*/
@Id
@Column(name = "data_perm_id")
private Long dataPermId;
/**
* 用户Id。
*/
@Id
@Column(name = "user_id")
private Long userId;
}

View File

@@ -1,77 +0,0 @@
package com.orange.admin.upms.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.orange.admin.common.core.annotation.DeletedFlagColumn;
import com.orange.admin.common.core.annotation.JobUpdateTimeColumn;
import com.orange.admin.common.core.validator.UpdateGroup;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.Date;
/**
* SysDept实体对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Table(name = "zz_sys_dept")
public class SysDept {
/**
* 部门Id。
*/
@NotNull(message = "数据验证失败部门Id不能为空", groups = {UpdateGroup.class})
@Id
@Column(name = "dept_id")
private Long deptId;
/**
* 部门名称。
*/
@NotBlank(message = "数据验证失败,部门名称不能为空!")
@Column(name = "dept_name")
private String deptName;
/**
* 显示顺序。
*/
@NotNull(message = "数据验证失败,显示顺序不能为空!")
@Column(name = "show_order")
private Integer showOrder;
/**
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
*/
@JSONField(serialize = false)
@DeletedFlagColumn
@Column(name = "deleted_flag")
private Integer deletedFlag;
/**
* 创建用户Id。
*/
@Column(name = "create_user_id")
private Long createUserId;
/**
* 创建用户名。
*/
@Column(name = "create_username")
private String createUsername;
/**
* 创建时间。
*/
@Column(name = "create_time")
private Date createTime;
/**
* 更新时间。
*/
@JobUpdateTimeColumn
@Column(name = "update_time")
private Date updateTime;
}

View File

@@ -1,352 +0,0 @@
package com.orange.admin.upms.service;
import com.alibaba.fastjson.JSONObject;
import com.orange.admin.common.biz.base.service.BaseBizService;
import com.orange.admin.common.biz.util.BasicIdGenerator;
import com.orange.admin.common.core.constant.DataPermRuleType;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.common.core.constant.GlobalDeletedFlag;
import com.orange.admin.common.core.object.TokenData;
import com.orange.admin.common.core.object.CallResult;
import com.orange.admin.upms.dao.SysDataPermDeptMapper;
import com.orange.admin.upms.dao.SysDataPermMapper;
import com.orange.admin.upms.dao.SysDataPermUserMapper;
import com.orange.admin.upms.dao.SysDataPermMenuMapper;
import com.orange.admin.upms.model.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import java.util.*;
import java.util.stream.Collectors;
/**
* 数据权限数据服务类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Service
public class SysDataPermService extends BaseBizService<SysDataPerm, Long> {
@Autowired
private SysDataPermMapper sysDataPermMapper;
@Autowired
private SysDataPermDeptMapper sysDataPermDeptMapper;
@Autowired
private SysDataPermMenuMapper sysDataPermMenuMapper;
@Autowired
private SysMenuService sysMenuService;
@Autowired
private SysDataPermUserMapper sysDataPermUserMapper;
@Autowired
private SysDeptService sysDeptService;
@Autowired
private BasicIdGenerator idGenerator;
/**
* 返回主对象的Mapper对象。
*
* @return 主对象的Mapper对象。
*/
@Override
protected BaseDaoMapper<SysDataPerm> mapper() {
return sysDataPermMapper;
}
/**
* 保存新增的数据权限对象。
*
* @param dataPerm 新增的数据权限对象。
* @param deptIdSet 关联的部门Id列表。
* @param dataPermMenuList 关联的菜单对象列表。
* @return 新增后的数据权限对象。
*/
@Transactional(rollbackFor = Exception.class)
public SysDataPerm saveNew(SysDataPerm dataPerm, Set<Long> deptIdSet, List<SysDataPermMenu> dataPermMenuList) {
dataPerm.setDataPermId(idGenerator.nextLongId());
TokenData tokenData = TokenData.takeFromRequest();
dataPerm.setCreateUserId(tokenData.getUserId());
dataPerm.setCreateUsername(tokenData.getShowName());
dataPerm.setDeletedFlag(GlobalDeletedFlag.NORMAL);
Date now = new Date();
dataPerm.setCreateTime(now);
dataPerm.setUpdateTime(now);
sysDataPermMapper.insert(dataPerm);
this.insertRelationData(dataPerm, deptIdSet, dataPermMenuList);
return dataPerm;
}
/**
* 更新数据权限对象。
*
* @param dataPerm 更新的数据权限对象。
* @param originalDataPerm 原有的数据权限对象。
* @param deptIdSet 关联的部门Id列表。
* @param dataPermMenuList 关联的菜单对象列表。
* @return 更新成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean update(
SysDataPerm dataPerm,
SysDataPerm originalDataPerm,
Set<Long> deptIdSet,
List<SysDataPermMenu> dataPermMenuList) {
dataPerm.setUpdateTime(new Date());
dataPerm.setCreateTime(originalDataPerm.getCreateTime());
dataPerm.setCreateUserId(originalDataPerm.getCreateUserId());
dataPerm.setCreateUsername(originalDataPerm.getCreateUsername());
dataPerm.setDeletedFlag(GlobalDeletedFlag.NORMAL);
if (sysDataPermMapper.updateByPrimaryKey(dataPerm) != 1) {
return false;
}
SysDataPermMenu dataPermMenu = new SysDataPermMenu();
dataPermMenu.setDataPermId(dataPerm.getDataPermId());
sysDataPermMenuMapper.delete(dataPermMenu);
SysDataPermDept dataPermDept = new SysDataPermDept();
dataPermDept.setDataPermId(dataPerm.getDataPermId());
sysDataPermDeptMapper.delete(dataPermDept);
this.insertRelationData(dataPerm, deptIdSet, dataPermMenuList);
return true;
}
/**
* 删除指定数据权限。
*
* @param dataPermId 数据权限主键Id。
* @return 删除成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean remove(Long dataPermId) {
SysDataPerm dataPerm = new SysDataPerm();
dataPerm.setDataPermId(dataPermId);
dataPerm.setDeletedFlag(GlobalDeletedFlag.DELETED);
if (sysDataPermMapper.updateByPrimaryKeySelective(dataPerm) != 1) {
return false;
}
SysDataPermMenu dataPermMenu = new SysDataPermMenu();
dataPermMenu.setDataPermId(dataPermId);
sysDataPermMenuMapper.delete(dataPermMenu);
SysDataPermDept dataPermDept = new SysDataPermDept();
dataPermDept.setDataPermId(dataPermId);
sysDataPermDeptMapper.delete(dataPermDept);
SysDataPermUser dataPermUser = new SysDataPermUser();
dataPermUser.setDataPermId(dataPermId);
sysDataPermUserMapper.delete(dataPermUser);
return true;
}
/**
* 获取数据权限列表。
*
* @param filter 数据权限过滤对象。
* @param orderBy 排序参数。
* @return 数据权限查询列表。
*/
public List<SysDataPerm> getSysDataPermList(SysDataPerm filter, String orderBy) {
return sysDataPermMapper.getSysDataPermList(filter, orderBy);
}
/**
* 将指定用户的指定会话的数据权限集合存入缓存。
*
* @param sessionId 会话Id。
* @param userId 用户主键Id。
* @param deptId 用户所属部门主键Id。
* @param isAdmin 是否是管理员。
* @return 查询并缓存后的数据权限集合。返回格式为Map<MenuId, Map<RuleType, DeptIdString>>。
*/
@CachePut(value = "DATA_PERMISSION_CACHE", key = "#sessionId")
public Map<Object, Map<Integer, String>> putDataPermCache(
String sessionId, Long userId, Long deptId, boolean isAdmin) {
// 管理员账户返回空对象,便于缓存的统一处理。
return isAdmin ? new HashMap<>(1) : this.getSysDataPermMenuListByUserId(userId, deptId);
}
/**
* 将指定会话的数据权限集合从缓存中移除。
*
* @param sessionId 会话Id。
*/
@CacheEvict(value = "DATA_PERMISSION_CACHE", key = "#sessionId")
public void removeDataPermCache(String sessionId) {
// 空实现即可只是通过注解将当前sessionId从cache中删除。
}
/**
* 获取指定用户Id的数据权限列表。并基于菜单Id和权限规则类型进行了一级和二级的分组。
*
* @param userId 指定的用户Id。
* @param deptId 用户所属部门主键Id。
* @return 合并优化后的数据权限列表。返回格式为Map<MenuId, Map<RuleType, DeptIdString>>。
*/
public Map<Object, Map<Integer, String>> getSysDataPermMenuListByUserId(Long userId, Long deptId) {
List<SysDataPermMenu> dataPermMenuList = sysDataPermMenuMapper.getSysDataPermMenuListByUserId(userId);
if (dataPermMenuList.isEmpty()) {
return new HashMap<>(1);
}
// 这里用代码的方式把deptId组装到SysDataPermMenu中。
Set<Long> dataPermIdSet = dataPermMenuList.stream()
.map(SysDataPermMenu::getDataPermId).collect(Collectors.toSet());
Example e = new Example(SysDataPermDept.class);
e.createCriteria().andIn("dataPermId", dataPermIdSet);
List<SysDataPermDept> dataPermDeptList = sysDataPermDeptMapper.selectByExample(e);
Map<Long, List<SysDataPermDept>> deptMap =
dataPermDeptList.stream().collect(Collectors.groupingBy(SysDataPermDept::getDataPermId));
for (SysDataPermMenu dataPermMenu : dataPermMenuList) {
List<SysDataPermDept> deptList = deptMap.get(dataPermMenu.getDataPermId());
if (CollectionUtils.isNotEmpty(deptList)) {
Set<Long> deptIdSet = deptList.stream().map(SysDataPermDept::getDeptId).collect(Collectors.toSet());
dataPermMenu.setDeptIdListString(StringUtils.join(deptIdSet, ","));
}
}
// 由于同一用户可能属于多个数据权限所以需要进行基于menuId的权限合并。
return mergeDataPermMenuList(dataPermMenuList, deptId);
}
private Map<Object, Map<Integer, String>> mergeDataPermMenuList(
List<SysDataPermMenu> dataPermMenuList, Long deptId) {
Map<Object, List<SysDataPermMenu>> menuMap =
dataPermMenuList.stream().collect(Collectors.groupingBy(SysDataPermMenu::getMenuId));
Map<Object, Map<Integer, String>> resultMap = new HashMap<>(menuMap.size());
// 这里menuMap的key是menuId
for (Map.Entry<Object, List<SysDataPermMenu>> entry : menuMap.entrySet()) {
Object menuId = entry.getKey();
// 为了更方便进行后续的合并优化处理这里再基于规则类型进行分组。ruleMap的key是规则类型。
Map<Integer, List<SysDataPermMenu>> ruleMap =
entry.getValue().stream().collect(Collectors.groupingBy(SysDataPermMenu::getRuleType));
Map<Integer, String> m = new HashMap<>(1);
// 如有有ALL存在就可以直接退出了没有必要在处理后续的规则了。
if (ruleMap.containsKey(DataPermRuleType.TYPE_ALL)) {
m.put(DataPermRuleType.TYPE_ALL, "null");
resultMap.put(menuId, m);
continue;
}
// 合并自定义部门了。
String deptIds = processMultiDept(ruleMap, deptId);
if (deptIds != null) {
m.put(DataPermRuleType.TYPE_CUSTOM_DETP_LIST, deptIds);
}
// 最后处理当前部门和当前用户。
if (ruleMap.get(DataPermRuleType.TYPE_DEPT_ONLY) != null) {
m.put(DataPermRuleType.TYPE_DEPT_ONLY, "null");
}
if (ruleMap.get(DataPermRuleType.TYPE_USER_ONLY) != null) {
m.put(DataPermRuleType.TYPE_USER_ONLY, "null");
}
resultMap.put(menuId, m);
}
return resultMap;
}
private String processMultiDept(Map<Integer, List<SysDataPermMenu>> ruleMap, Long deptId) {
List<SysDataPermMenu> customDeptList = ruleMap.get(DataPermRuleType.TYPE_CUSTOM_DETP_LIST);
if (customDeptList == null) {
return null;
}
Set<Long> deptIdSet = new HashSet<>();
for (SysDataPermMenu customDept : customDeptList) {
deptIdSet.addAll(Arrays.stream(StringUtils.split(
customDept.getDeptIdListString(), ",")).map(Long::valueOf).collect(Collectors.toSet()));
}
if (ruleMap.containsKey(DataPermRuleType.TYPE_DEPT_ONLY)) {
deptIdSet.add(deptId);
ruleMap.remove(DataPermRuleType.TYPE_DEPT_ONLY);
}
return StringUtils.join(deptIdSet, ',');
}
/**
* 添加用户和数据权限之间的多对多关联关系。
*
* @param dataPermId 数据权限Id。
* @param userIdSet 关联的用户Id列表。
*/
@Transactional(rollbackFor = Exception.class)
public void addDataPermUserList(Long dataPermId, Set<Long> userIdSet) {
List<SysDataPermUser> dataPermUserList = new LinkedList<>();
for (Long userId : userIdSet) {
SysDataPermUser dataPermUser = new SysDataPermUser();
dataPermUser.setDataPermId(dataPermId);
dataPermUser.setUserId(userId);
dataPermUserList.add(dataPermUser);
}
sysDataPermUserMapper.addDataPermUserList(dataPermUserList);
}
/**
* 移除用户和数据权限之间的多对多关联关系。
*
* @param dataPermId 数据权限主键Id。
* @param userId 用户主键Id。
*/
@Transactional(rollbackFor = Exception.class)
public boolean removeDataPermUser(Long dataPermId, Long userId) {
SysDataPermUser dataPermUser = new SysDataPermUser();
dataPermUser.setDataPermId(dataPermId);
dataPermUser.setUserId(userId);
return sysDataPermUserMapper.delete(dataPermUser) == 1;
}
/**
* 验证数据权限对象关联菜单数据是否都合法。
*
* @param dataPerm 数据权限关对象。
* @param deptIdListString 与数据权限关联的部门Id列表。
* @param menuIdListString 与数据权限关联的菜单Id列表。
* @return 验证结果。
*/
public CallResult verifyRelatedData(SysDataPerm dataPerm, String deptIdListString, String menuIdListString) {
JSONObject jsonObject = new JSONObject();
if (dataPerm.getRuleType() == DataPermRuleType.TYPE_CUSTOM_DETP_LIST) {
if (StringUtils.isBlank(deptIdListString)) {
return CallResult.error("数据验证失败,部门列表不能为空!");
}
Set<Long> deptIdSet = Arrays.stream(StringUtils.split(
deptIdListString, ",")).map(Long::valueOf).collect(Collectors.toSet());
if (!sysDeptService.existAllPrimaryKeys(deptIdSet)) {
return CallResult.error("数据验证失败,存在不合法的部门数据,请刷新后重试!");
}
jsonObject.put("deptIdSet", deptIdSet);
}
String[] menuIdArray = StringUtils.split(menuIdListString, ",");
Set<Long> menuIdSet = Arrays.stream(menuIdArray).map(Long::valueOf).collect(Collectors.toSet());
// 验证菜单Id的合法性
if (!sysMenuService.existAllPrimaryKeys(menuIdSet)) {
return CallResult.error("数据验证失败,存在不合法的菜单,请刷新后重试!");
}
List<SysDataPermMenu> dataPermMenuList = new LinkedList<>();
for (Long menuId : menuIdSet) {
SysDataPermMenu dataPermMenu = new SysDataPermMenu();
dataPermMenu.setMenuId(menuId);
dataPermMenuList.add(dataPermMenu);
}
jsonObject.put("dataPermMenuList", dataPermMenuList);
return CallResult.ok(jsonObject);
}
private void insertRelationData(
SysDataPerm dataPerm, Set<Long> deptIdSet, List<SysDataPermMenu> dataPermMenuList) {
if (CollectionUtils.isNotEmpty(deptIdSet)) {
List<SysDataPermDept> dataPermDeptList = new LinkedList<>();
for (Long deptId : deptIdSet) {
SysDataPermDept dataPermDept = new SysDataPermDept();
dataPermDept.setDataPermId(dataPerm.getDataPermId());
dataPermDept.setDeptId(deptId);
dataPermDeptList.add(dataPermDept);
}
sysDataPermDeptMapper.insertList(dataPermDeptList);
}
if (CollectionUtils.isNotEmpty(dataPermMenuList)) {
for (SysDataPermMenu dataPermMenu : dataPermMenuList) {
dataPermMenu.setDataPermId(dataPerm.getDataPermId());
}
sysDataPermMenuMapper.insertList(dataPermMenuList);
}
}
}

View File

@@ -1,133 +0,0 @@
package com.orange.admin.upms.service;
import com.orange.admin.upms.dao.*;
import com.orange.admin.upms.model.*;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.common.core.constant.GlobalDeletedFlag;
import com.orange.admin.common.core.object.TokenData;
import com.orange.admin.common.core.object.MyWhereCriteria;
import com.orange.admin.common.core.object.MyRelationParam;
import com.orange.admin.common.biz.base.service.BaseBizService;
import com.orange.admin.common.biz.util.BasicIdGenerator;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import java.util.*;
/**
* 部门管理数据操作服务类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Service
public class SysDeptService extends BaseBizService<SysDept, Long> {
@Autowired
private SysDeptMapper sysDeptMapper;
@Autowired
private SysDataPermDeptMapper sysDataPermDeptMapper;
@Autowired
private BasicIdGenerator idGenerator;
/**
* 返回当前Service的主表Mapper对象。
*
* @return 主表Mapper对象。
*/
@Override
protected BaseDaoMapper<SysDept> mapper() {
return sysDeptMapper;
}
/**
* 保存新增的部门对象。
*
* @param sysDept 新增的部门对象。
* @return 新增后的部门对象。
*/
@Transactional(rollbackFor = Exception.class)
public SysDept saveNew(SysDept sysDept) {
sysDept.setDeptId(idGenerator.nextLongId());
sysDept.setDeletedFlag(GlobalDeletedFlag.NORMAL);
TokenData tokenData = TokenData.takeFromRequest();
sysDept.setCreateUserId(tokenData.getUserId());
sysDept.setCreateUsername(tokenData.getShowName());
Date now = new Date();
sysDept.setCreateTime(now);
sysDept.setUpdateTime(now);
sysDeptMapper.insert(sysDept);
return sysDept;
}
/**
* 更新部门对象。
*
* @param sysDept 更新的部门对象。
* @param originalSysDept 原有的部门对象。
* @return 更新成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean update(SysDept sysDept, SysDept originalSysDept) {
sysDept.setCreateUserId(originalSysDept.getCreateUserId());
sysDept.setCreateUsername(originalSysDept.getCreateUsername());
sysDept.setCreateTime(originalSysDept.getCreateTime());
sysDept.setUpdateTime(new Date());
sysDept.setDeletedFlag(GlobalDeletedFlag.NORMAL);
return sysDeptMapper.updateByPrimaryKey(sysDept) != 0;
}
/**
* 删除指定数据。
*
* @param deptId 主键Id。
* @return 成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean remove(Long deptId) {
Example sysDeptExample = new Example(SysDept.class);
Example.Criteria c = sysDeptExample.createCriteria();
c.andEqualTo(super.idFieldName, deptId);
c.andEqualTo(super.deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
// 这里先删除主数据
SysDept deletedObject = new SysDept();
deletedObject.setDeletedFlag(GlobalDeletedFlag.DELETED);
if (sysDeptMapper.updateByExampleSelective(deletedObject, sysDeptExample) == 0) {
return false;
}
// 这里可继续删除关联数据。
SysDataPermDept dataPermDept = new SysDataPermDept();
dataPermDept.setDeptId(deptId);
sysDataPermDeptMapper.delete(dataPermDept);
return true;
}
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getSysDeptListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<SysDept> getSysDeptList(SysDept filter, String orderBy) {
return sysDeptMapper.getSysDeptList(filter, orderBy);
}
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getSysDeptList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<SysDept> getSysDeptListWithRelation(SysDept filter, String orderBy) {
List<SysDept> resultList = sysDeptMapper.getSysDeptList(filter, orderBy);
Map<String, List<MyWhereCriteria>> criteriaMap = buildAggregationAdditionalWhereCriteria();
this.buildRelationForDataList(resultList, MyRelationParam.normal(), criteriaMap);
return resultList;
}
}

View File

@@ -1,32 +0,0 @@
package com.orange.admin.upms.service;
import com.orange.admin.common.biz.base.service.BaseBizService;
import com.orange.admin.common.core.base.dao.BaseDaoMapper;
import com.orange.admin.upms.dao.SysPermWhitelistMapper;
import com.orange.admin.upms.model.SysPermWhitelist;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 权限资源白名单数据服务类。
* 白名单中的权限资源,可以不受权限控制,任何用户皆可访问,一般用于常用的字典数据列表接口。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Service
public class SysPermWhitelistService extends BaseBizService<SysPermWhitelist, String> {
@Autowired
private SysPermWhitelistMapper sysPermWhitelistMapper;
/**
* 返回主对象的Mapper对象。
*
* @return 主对象的Mapper对象。
*/
@Override
protected BaseDaoMapper<SysPermWhitelist> mapper() {
return sysPermWhitelistMapper;
}
}

View File

@@ -1,193 +0,0 @@
logging:
level:
# 这里设置的日志级别优先于log4j2.xml文件Loggers中的日志级别。
com.orange.admin: info
server:
tomcat:
uri-encoding: UTF-8
max-threads: 100
min-spare-threads: 10
port: 8082
# spring相关配置
spring:
application:
name: app
profiles:
active: dev
servlet:
multipart:
max-file-size: 50MB
max-request-size: 50MB
http:
converters:
preferred-json-mapper: fastjson
encoding:
force: true
charset: UTF-8
enabled: true
freemarker:
template-loader-path: classpath:/template/
cache: false
charset: UTF-8
check-template-location: true
content-type: text/html
expose-request-attributes: false
expose-session-attributes: false
request-context-attribute: request
suffix: .ftl
# mybatis的基本配置
mybatis:
mapperLocations: classpath:com/orange/admin/*/dao/mapper/*Mapper.xml
typeAliasesPackage: com.orange.admin.*.model
# mybatis的通用mapper的配置
mapper:
mappers: tk.mybatis.mapper.common.Mapper,tk.mybatis.mapper.additional.insert.InsertListMapper
not-empty: false
identity: MYSQL
# 自动分页的配置
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: false
params: count=countSql
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: '*'
jmx:
exposure:
include: '*'
endpoint:
# 与中间件相关的健康详情也会被展示
health:
show-details: always
configprops:
# 在/actuator/configprops中所有包含password的配置将用 * 隐藏。
# 如果不想隐藏任何配置项的值,可以直接使用如下被注释的空值。
# keys-to-sanitize:
keys-to-sanitize: password
server:
servlet:
context-path: "/"
# 开发数据库相关配置
---
spring:
profiles: dev
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://localhost:3306/zz-orange-admin?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
name: app
initialSize: 10
minIdle: 10
maxActive: 50
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
maxOpenPreparedStatements: 20
validationQuery: SELECT 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
filters: stat,wall
useGlobalDataSourceStat: true
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*,/actuator/*"
stat-view-servlet:
enabled: true
urlPattern: /druid/*
resetEnable: true
application:
# common-biz 主要包含通用配置项由common-biz包的CommonBizConfig读取。
common-biz:
# Snowflake 分布式Id生成算法所需的WorkNode参数值。
snowflakeWorkNode: 1
# Jwt令牌加密的签名值。
tokenSigningKey: OrangeAdmin
# Jwt令牌在Http Header中的键名称。
tokenHeaderKey: Authorization
# Jwt令牌刷新后在Http Header中的键名称。
refreshedTokenHeaderKey: RefreshedToken
# 密码加密的盐值。
passwordSalt: OrangeAdmin-passwd-salt
# 初始化密码。
defaultUserPassword: 123456
# 缺省的文件上传根目录。
uploadFileBaseDir: ./upload-files/app
# 跨域的IP白名单列表多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
credentialIpList: "*"
# 发布数据库相关配置
---
spring:
profiles: product
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://localhost:3306/zz-orange-admin?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
name: app
initialSize: 10
minIdle: 10
maxActive: 50
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
maxOpenPreparedStatements: 20
validationQuery: SELECT 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
filters: stat,wall
useGlobalDataSourceStat: true
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*,/actuator/*"
stat-view-servlet:
enabled: true
urlPattern: /druid/*
resetEnable: true
application:
# common-biz 主要包含通用配置项由common-biz包的CommonBizConfig读取。
common-biz:
# Snowflake 分布式Id生成算法所需的WorkNode参数值。
snowflakeWorkNode: 1
# Jwt令牌加密的签名值。
tokenSigningKey: OrangeAdmin
# Jwt令牌在Http Header中的键名称。
tokenHeaderKey: Authorization
# Jwt令牌刷新后在Http Header中的键名称。
refreshedTokenHeaderKey: RefreshedToken
# 密码加密的盐值。
passwordSalt: OrangeAdmin-passwd-salt
# 初始化密码。
defaultUserPassword: 123456
# 缺省的文件上传根目录。
uploadFileBaseDir: ./upload-files/app
# 跨域的IP白名单列表多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
credentialIpList: "*"

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="javaFileEncoding" value="UTF-8"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
</plugin>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/zz-orange-admin?useSSL=true&serverTimezone=Asia/Shanghai"
userId="root"
password="123456">
</jdbcConnection>
<javaModelGenerator targetPackage="com.orange.admin.app.model" targetProject="src/main/java"/>
<sqlMapGenerator targetPackage="com.orange.admin.app.dao.mapper" targetProject="src/main/java"/>
<javaClientGenerator targetPackage="com.orange.admin.app.dao" targetProject="src/main/java" type="XMLMAPPER"/>
<!--<table tableName="bbc_system_role_user" domainObjectName="SystemRoleUser">-->
<!--</table>-->
<!-- 执行 mvn mybatis-generator:generate 即可生成 -->
</context>
</generatorConfiguration>

View File

@@ -1,41 +0,0 @@
package com.orange.admin.common.biz.aop;
import com.orange.admin.common.core.object.GlobalThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 禁用数据权限过滤的AOP处理类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Aspect
@Component
@Order(1)
@Slf4j
public class DisableDataPermAspect {
/**
* 所有标记了DisableDataPerm注解的方法。
*/
@Pointcut("@annotation(com.orange.admin.common.core.annotation.DisableDataPerm)")
public void disableDataPermPointCut() {
// 空注释避免sonar警告
}
@Around("disableDataPermPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
boolean dataPermEnabled = GlobalThreadLocal.setDataPerm(false);
try {
return point.proceed();
} finally {
GlobalThreadLocal.setDataPerm(dataPermEnabled);
}
}
}

View File

@@ -1,19 +0,0 @@
package com.orange.admin.common.biz.base.service;
import com.orange.admin.common.core.base.service.BaseService;
import lombok.extern.slf4j.Slf4j;
/**
* 所有业务Service的共同基类。由于BaseService位于common-core模块内该模块很少涉及spring bean的集成
* 因此该类位于业务服务类和BaseService之间主要提供一些通用方法特别是与spring bean相关的业务代码。
* NOTE: 目前该类实现为空,主要是为了便于用户自行扩展,同时也能方便今后向微服务的升级,
*
* @param <M> Model对象的类型。
* @param <K> Model对象主键的类型。
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
public abstract class BaseBizService<M, K> extends BaseService<M, K> {
}

View File

@@ -1,22 +0,0 @@
package com.orange.admin.common.biz.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 应用程序自定义的通用属性配置文件。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "application.common-biz")
public class CommonBizConfig {
/**
* Snowflake计算主键Id时所需的WorkNode参数值。
*/
private Integer snowflakeWorkNode;
}

View File

@@ -1,39 +0,0 @@
package com.orange.admin.common.biz.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import java.util.ArrayList;
import java.util.List;
/**
* 对象数据格式转换器这里集成了alibaba的fastjson作为消息格式转换工具
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Configuration
public class FastjsonConfig {
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
fastConverter.setSupportedMediaTypes(supportedMediaTypes);
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.PrettyFormat,
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.IgnoreNonFieldGetter);
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
fastConverter.setFastJsonConfig(fastJsonConfig);
return new HttpMessageConverters(fastConverter);
}
}

View File

@@ -1,60 +0,0 @@
package com.orange.admin.common.biz.interceptor;
import com.orange.admin.common.core.object.GlobalThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 服务访问日志的拦截器,主要完成记录接口调用时长。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Slf4j
public class AccessInterceptor implements HandlerInterceptor {
private static final ThreadLocal<Long> STARTTIME_THREADLOCAL = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
STARTTIME_THREADLOCAL.set(System.currentTimeMillis());
// 每次进入Controller接口之前均主动打开数据权限验证。
// 可以避免该Servlet线程在处理之前的请求时异常退出从而导致该状态数据没有被正常清除。
GlobalThreadLocal.setDataPerm(true);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 这里需要加注释否则sonar不happy。
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
long startTime = STARTTIME_THREADLOCAL.get();
long elapse = System.currentTimeMillis() - startTime;
String urlPath = request.getRequestURI();
String controllerMethod = "Unknown";
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler;
String controllerName = hm.getBean().getClass().getName();
// 这里将cglib织入的部分去掉提升日志的可读性
int index = controllerName.indexOf("$$");
if (index > 0) {
controllerName = controllerName.substring(0, index);
}
controllerMethod = controllerName + "." + hm.getMethod().getName();
}
log.info("access: {} -- elapse {} ms -- {}.", controllerMethod, elapse, urlPath);
STARTTIME_THREADLOCAL.remove();
GlobalThreadLocal.clearDataPerm();
}
}

View File

@@ -1,51 +0,0 @@
package com.orange.admin.common.biz.util;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.orange.admin.common.biz.config.CommonBizConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* 全局共享的snowflake计算工具类。
* 基于Hutool中的对应工具类实现同时读取系统的配置参数并初始化该对象。如果今后
* 升级为基于分布式Id生成服务的实现时仅需修改内部实现外部业务方法不会受到任何影响。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Component
public class BasicIdGenerator {
@Autowired
private CommonBizConfig config;
private Snowflake snowflake;
@PostConstruct
private void init() {
snowflake = IdUtil.createSnowflake(config.getSnowflakeWorkNode(), 0);
}
/**
* 获取基于Snowflake算法的数值型Id。
* 由于底层实现为synchronized方法因此计算过程串行化且线程安全。
*
* @return 计算后的全局唯一Id。
*/
public long nextLongId() {
return this.snowflake.nextId();
}
/**
* 获取基于Snowflake算法的字符串Id。
* 由于底层实现为synchronized方法因此计算过程串行化且线程安全。
*
* @return 计算后的全局唯一Id。
*/
public String nextStringId() {
return this.snowflake.nextIdStr();
}
}

View File

@@ -1,16 +0,0 @@
package com.orange.admin.common.core.annotation;
import java.lang.annotation.*;
/**
* 主要用于标记数据权限中基于DeptId进行过滤的字段。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DeptFilterColumn {
}

View File

@@ -1,17 +0,0 @@
package com.orange.admin.common.core.annotation;
import java.lang.annotation.*;
/**
* 作为DisableDataPermAspect的切点。
* 该注解仅能标记在方法上,方法内所有的查询语句,均不会被数据权限过滤。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DisableDataPerm {
}

View File

@@ -1,27 +0,0 @@
package com.orange.admin.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 Stephen.Liu
* @date 2020-05-24
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableDataPerm {
/**
* 排除的方法名称数组。如果为空所有的方法均会被Mybaits拦截注入权限过滤条件。
*
* @return 被排序的方法名称数据。
*/
String[] excluseMethodName() default {};
}

View File

@@ -1,16 +0,0 @@
package com.orange.admin.common.core.annotation;
import java.lang.annotation.*;
/**
* 主要用于标记数据权限中基于UserId进行过滤的字段。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserFilterColumn {
}

View File

@@ -1,44 +0,0 @@
package com.orange.admin.common.core.constant;
/**
* 应用程序的常量声明对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public final class ApplicationConstant {
/**
* 图片文件上传的父目录。
*/
public static final String UPLOAD_IMAGE_PARENT_PATH = "image";
/**
* 附件文件上传的父目录。
*/
public static final String UPLOAD_ATTACHMENT_PARENT_PATH = "attachment";
/**
* CSV文件扩展名。
*/
public static final String CSV_EXT = "csv";
/**
* XLSX文件扩展名。
*/
public static final String XLSX_EXT = "xlsx";
/**
* 统计分类计算时,按天聚合计算的常量值。(前端在MyOrderParam和MyGroupParam中传给后台)
*/
public static final String DAY_AGGREGATION = "day";
/**
* 统计分类计算时,按月聚合计算的常量值。(前端在MyOrderParam和MyGroupParam中传给后台)
*/
public static final String MONTH_AGGREGATION = "month";
/**
* 统计分类计算时,按年聚合计算的常量值。(前端在MyOrderParam和MyGroupParam中传给后台)
*/
public static final String YEAR_AGGREGATION = "year";
/**
* 私有构造函数,明确标识该常量类的作用。
*/
private ApplicationConstant() {
}
}

View File

@@ -1,57 +0,0 @@
package com.orange.admin.common.core.constant;
import java.util.HashMap;
import java.util.Map;
/**
* 数据权限规则类型常量类。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public final class DataPermRuleType {
/**
* 查看全部。
*/
public static final int TYPE_ALL = 0;
/**
* 仅查看当前用户
*/
public static final int TYPE_USER_ONLY = 1;
/**
* 仅查看当前部门
*/
public static final int TYPE_DEPT_ONLY = 2;
/**
* 自定义部门列表
*/
public static final int TYPE_CUSTOM_DETP_LIST = 5;
private static final Map<Object, String> DICT_MAP = new HashMap<>(4);
static {
DICT_MAP.put(0, "查看全部");
DICT_MAP.put(1, "仅查看当前用户");
DICT_MAP.put(2, "仅查看所在部门");
DICT_MAP.put(5, "自定义部门列表");
}
/**
* 判断参数是否为当前常量字典的合法取值范围。
*
* @param value 待验证的参数值。
* @return 合法返回true否则false。
*/
public static boolean isValid(Integer value) {
return value != null && DICT_MAP.containsKey(value);
}
/**
* 私有构造函数,明确标识该常量类的作用。
*/
private DataPermRuleType() {
}
}

View File

@@ -1,51 +0,0 @@
package com.orange.admin.common.core.object;
import cn.hutool.core.util.BooleanUtil;
/**
* 线程本地化数据管理的工具类。可根据需求自行添加更多的线程本地化变量及其操作方法。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
public class GlobalThreadLocal {
/**
* 存储数据权限过滤是否启用的线程本地化对象。
*/
private static final ThreadLocal<Boolean> DATA_PERM_ENABLE = ThreadLocal.withInitial(() -> Boolean.TRUE);
/**
* 设置数据权限过滤是否打开。如果打开当前Servlet线程所执行的SQL操作均会进行数据权限过滤。
*
* @param enable 打开为true否则false。
* @return 返回之前的状态,便于恢复。
*/
public static boolean setDataPerm(boolean enable) {
boolean oldValue = DATA_PERM_ENABLE.get();
DATA_PERM_ENABLE.set(enable);
return oldValue;
}
/**
* 判断当前Servlet线程所执行的SQL操作是否进行数据权限过滤。
*
* @return true 进行数据权限过滤否则false。
*/
public static boolean enabledDataPerm() {
return BooleanUtil.isTrue(DATA_PERM_ENABLE.get());
}
/**
* 清空该存储数据,主动释放线程本地化存储资源。
*/
public static void clearDataPerm() {
DATA_PERM_ENABLE.remove();
}
/**
* 私有构造函数,明确标识该常量类的作用。
*/
private GlobalThreadLocal() {
}
}

View File

@@ -1,63 +0,0 @@
package com.orange.admin.common.core.object;
import com.orange.admin.common.core.util.ContextUtil;
import lombok.Data;
import lombok.ToString;
import javax.servlet.http.HttpServletRequest;
/**
* 基于Jwt用于前后端传递的令牌对象。
*
* @author Stephen.Liu
* @date 2020-05-24
*/
@Data
@ToString
public class TokenData {
/**
* 在HTTP Request对象中的属性键。
*/
public static final String REQUEST_ATTRIBUTE_NAME = "tokenData";
/**
* 用户Id。
*/
private Long userId;
/**
* 用户所在部门Id。
*/
private Long deptId;
/**
* 是否为超级管理员。
*/
private Boolean isAdmin;
/**
* 用户显示名称。
*/
private String showName;
/**
* 标识不同登录的会话Id。
*/
private String sessionId;
/**
* 将令牌对象添加到Http请求对象。
*
* @param tokenData 令牌对象。
*/
public static void addToRequest(TokenData tokenData) {
HttpServletRequest request = ContextUtil.getHttpRequest();
request.setAttribute(TokenData.REQUEST_ATTRIBUTE_NAME, tokenData);
}
/**
* 从Http Request对象中获取令牌对象。
*
* @return 令牌对象。
*/
public static TokenData takeFromRequest() {
HttpServletRequest request = ContextUtil.getHttpRequest();
return (TokenData) request.getAttribute(REQUEST_ATTRIBUTE_NAME);
}
}

View File

@@ -1,143 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.orange.admin</groupId>
<artifactId>OrangeAdmin</artifactId>
<version>1.0.0</version>
<name>OrangeAdmin</name>
<packaging>pom</packaging>
<properties>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
<spring-platform.version>Cairo-SR8</spring-platform.version>
<spring-boot-admin.version>2.2.2</spring-boot-admin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<application.name>OrangeAdmin</application.name>
<!-- 工具库版本 -->
<commons-collections4.version>4.4</commons-collections4.version>
<common-csv.version>1.8</common-csv.version>
<poi-ooxml.version>4.1.2</poi-ooxml.version>
<hutool.version>5.1.5</hutool.version>
<jjwt.version>0.9.1</jjwt.version>
<fastjson.version>1.2.66</fastjson.version>
<bean.query.version>1.1.5</bean.query.version>
<caffeine.version>2.8.1</caffeine.version>
<mapstruct.version>1.3.1.Final</mapstruct.version>
<!-- 数据库工具版本 -->
<druid.version>1.1.21</druid.version>
<mybatis-mapper.version>2.1.5</mybatis-mapper.version>
<mybatis-generator.version>1.4.0</mybatis-generator.version>
<pagehelper.version>1.2.13</pagehelper.version>
</properties>
<modules>
<module>common</module>
<module>application</module>
</modules>
<dependencies>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- freemarker 模板引擎模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--server-api-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- 日志模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- aop模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 缓存模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--配置文件处理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--监控客户端-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin.version}</version>
</dependency>
<!-- mapstruct 对象映射 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
<scope>provided</scope>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>${spring-platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@@ -1,10 +0,0 @@
[INFO ] 时间[2020-05-24 22:35:48] 线程[main] ==> Starting MyApplication on stephendembp with PID 2363 (/Users/stephen-liu/Desktop/OrangeAdmin/application/target/classes started by stephen-liu in /Users/stephen-liu/Desktop/OrangeAdmin)
[INFO ] 时间[2020-05-24 22:35:48] 线程[main] ==> The following profiles are active: dev
[INFO ] 时间[2020-05-24 22:36:53] 线程[main] ==> Starting MyApplication on stephendembp with PID 2366 (/Users/stephen-liu/Desktop/OrangeAdmin/application/target/classes started by stephen-liu in /Users/stephen-liu/Desktop/OrangeAdmin)
[INFO ] 时间[2020-05-24 22:36:53] 线程[main] ==> The following profiles are active: dev
[INFO ] 时间[2020-05-24 22:37:00] 线程[main] ==> Started MyApplication in 7.554 seconds (JVM running for 8.747)
[INFO ] 时间[2020-05-24 22:37:39] 线程[http-nio-8082-exec-1] ==> access: com.orange.admin.upms.controller.LoginController.doLogin -- elapse 173 ms -- /admin/login/doLogin.
[INFO ] 时间[2020-05-24 22:38:34] 线程[main] ==> Starting MyApplication on stephendembp with PID 2385 (/Users/stephen-liu/Desktop/OrangeAdmin/application/target/classes started by stephen-liu in /Users/stephen-liu/Desktop/OrangeAdmin)
[INFO ] 时间[2020-05-24 22:38:34] 线程[main] ==> The following profiles are active: dev
[INFO ] 时间[2020-05-24 22:38:41] 线程[main] ==> Started MyApplication in 7.343 seconds (JVM running for 8.439)
[INFO ] 时间[2020-05-24 22:39:22] 线程[http-nio-8082-exec-2] ==> access: com.orange.admin.upms.controller.LoginController.doLogin -- elapse 126 ms -- /admin/login/doLogin.

View File

@@ -1,109 +0,0 @@
import * as staticDict from '@/staticDict'
export default class DictionaryController {
static dictAreaCode (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/app/areaCode/listDictAreaCode', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictAreaCodeByParentId (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/app/areaCode/listDictAreaCodeByParentId', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictAddAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('', 'post', params, axiosOption, httpOption);
}
static dictDeleteAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('', 'post', params, axiosOption, httpOption);
}
static dictBatchDeleteAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('', 'post', params, axiosOption, httpOption);
}
static dictUpdateAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('', 'post', params, axiosOption, httpOption);
}
static dictReloadAreaCodeCachedData (sender, params, axiosOption, httpOption) {
return sender.doUrl('', 'get', params, axiosOption, httpOption);
}
static dictGender () {
return new Promise((resolve) => {
resolve(staticDict.Gender);
});
}
static dictSubject () {
return new Promise((resolve) => {
resolve(staticDict.Subject);
});
}
static dictSysDept (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/upms/sysDept/listDictSysDept', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictSysUser (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/upms/sysUser/listDictSysUser', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictSysUserStatus () {
return new Promise((resolve) => {
resolve(staticDict.SysUserStatus);
});
}
static dictSysUserType () {
return new Promise((resolve) => {
resolve(staticDict.SysUserType);
});
}
static dictTeacher (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/app/teacher/listDictTeacher', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictTeacherLevelType () {
return new Promise((resolve) => {
resolve(staticDict.TeacherLevelType);
});
}
static dictYesNo () {
return new Promise((resolve) => {
resolve(staticDict.YesNo);
});
}
static dictSysDataPermType () {
return new Promise((resolve) => {
resolve(staticDict.SysDataPermType);
});
}
}

View File

@@ -1,25 +0,0 @@
export default class TeacherController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacher/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacher/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/app/teacher/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacher/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacher/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacher/delete', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -1,17 +0,0 @@
export default class TeacherTransStatsController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacherTransStats/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacherTransStats/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/app/teacherTransStats/export', params, fileName);
}
static listWithGroup (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/teacherTransStats/listWithGroup', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -1,17 +0,0 @@
import SystemController from './Controller/SystemController'
import SysDataPermController from './Controller/SysDataPermController'
import DictionaryController from './Controller/DictionaryController'
import SysDeptController from './Controller/SysDeptController.js'
import SysUserController from './Controller/SysUserController.js'
import TeacherController from './Controller/TeacherController.js'
import TeacherTransStatsController from './Controller/TeacherTransStatsController.js'
export {
SystemController,
SysDataPermController,
DictionaryController,
SysDeptController,
SysUserController,
TeacherController,
TeacherTransStatsController
}

View File

@@ -1,41 +0,0 @@
// 开发环境不使用懒加载, 因为懒加载页面太多的话会造成webpack热更新太慢, 所以只有开发环境使用懒加载
const _import = require('./import-' + process.env.NODE_ENV)
function getProps (route) {
return route.query;
}
// 系统生成路由
const routers = [
{ path: '/login', component: _import('login/index'), name: 'login', props: getProps, desc: '登录' },
{
path: '/',
component: _import('layout/index'),
name: 'main',
props: getProps,
redirect: {
name: 'welcome'
},
meta: {
title: '主页',
showOnly: true
},
children: [
{path: 'welcome', component: _import('welcome/index'), name: 'welcome', meta: {title: '欢迎'}},
{path: 'formSysUser', component: _import('upms/formSysUser/index'), name: 'formSysUser', meta: {title: '用户管理'}},
{path: 'formSysDept', component: _import('upms/formSysDept/index'), name: 'formSysDept', meta: {title: '部门管理'}},
{path: 'formSysRole', component: _import('upms/formSysRole/index'), name: 'formSysRole', meta: {title: '角色管理'}},
{path: 'formSysDataPerm', component: _import('upms/formSysDataPerm/index'), name: 'formSysDataPerm', meta: {title: '数据权限管理'}},
{path: 'formSysMenu', component: _import('upms/formSysMenu/index'), name: 'formSysMenu', meta: {title: '菜单列表'}},
{path: 'formSysDict', component: _import('upms/formDictManagement/index'), name: 'formSysDict', meta: {title: '字典管理'}},
{path: 'formSysPermCode', component: _import('upms/formSysPermCode/index'), name: 'formSysPermCode', meta: {title: '权限字管理'}},
{path: 'formSysPerm', component: _import('upms/formSysPerm/index'), name: 'formSysPerm', meta: {title: '权限资源管理'}},
{path: 'formTeacher', component: _import('generated/formTeacher/index'), name: 'formTeacher', props: getProps, meta: {title: '老师管理'}},
{path: 'formCreateTeacher', component: _import('generated/formCreateTeacher/index'), name: 'formCreateTeacher', props: getProps, meta: {title: '新建老师'}},
{path: 'formEditTeacher', component: _import('generated/formEditTeacher/index'), name: 'formEditTeacher', props: getProps, meta: {title: '编辑老师'}},
{path: 'formTeacherTransStats', component: _import('generated/formTeacherTransStats/index'), name: 'formTeacherTransStats', props: getProps, meta: {title: '老师个人统计'}}
]
}
];
export default routers;

View File

@@ -1,370 +0,0 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formCreateTeacher" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="教师名称" prop="Teacher.teacherName">
<el-input class="input-item" v-model="formData.Teacher.teacherName"
:clearable="true" placeholder="教师名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出生日期" prop="Teacher.birthday">
<el-date-picker class="input-item" v-model="formData.Teacher.birthday" :clearable="true"
placeholder="出生日期" type="date" align="left"
format="yyyy-MM-dd" value-format="yyyy-MM-dd hh:mm:ss" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别" prop="Teacher.gender">
<el-select class="input-item" v-model="formData.Teacher.gender" :clearable="true" filterable
placeholder="性别" :loading="formCreateTeacher.gender.impl.loading"
@visible-change="formCreateTeacher.gender.impl.onVisibleChange"
@change="onGenderValueChange">
<el-option v-for="item in formCreateTeacher.gender.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所教科目" prop="Teacher.subjectId">
<el-select class="input-item" v-model="formData.Teacher.subjectId" :clearable="true" filterable
placeholder="所教科目" :loading="formCreateTeacher.subjectId.impl.loading"
@visible-change="formCreateTeacher.subjectId.impl.onVisibleChange"
@change="onSubjectIdValueChange">
<el-option v-for="item in formCreateTeacher.subjectId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职级" prop="Teacher.level">
<el-select class="input-item" v-model="formData.Teacher.level" :clearable="true" filterable
placeholder="职级" :loading="formCreateTeacher.level.impl.loading"
@visible-change="formCreateTeacher.level.impl.onVisibleChange"
@change="onLevelValueChange">
<el-option v-for="item in formCreateTeacher.level.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="鲜花数量" prop="Teacher.flowerCount">
<el-input-number class="input-item" v-model="formData.Teacher.flowerCount"
:clearable="true" controls-position="right" placeholder="鲜花数量" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属校区" prop="Teacher.schoolId">
<el-select class="input-item" v-model="formData.Teacher.schoolId" :clearable="true" filterable
placeholder="所属校区" :loading="formCreateTeacher.schoolId.impl.loading"
@visible-change="formCreateTeacher.schoolId.impl.onVisibleChange"
@change="onSchoolIdValueChange">
<el-option v-for="item in formCreateTeacher.schoolId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="绑定用户" prop="Teacher.userId">
<el-select class="input-item" v-model="formData.Teacher.userId" :clearable="true" filterable
placeholder="绑定用户" :loading="formCreateTeacher.userId.impl.loading"
@visible-change="formCreateTeacher.userId.impl.onVisibleChange"
@change="onUserIdValueChange">
<el-option v-for="item in formCreateTeacher.userId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否在职" prop="Teacher.available">
<el-select class="input-item" v-model="formData.Teacher.available" :clearable="true" filterable
placeholder="是否在职" :loading="formCreateTeacher.available.impl.loading"
@visible-change="formCreateTeacher.available.impl.onVisibleChange"
@change="onAvailableValueChange">
<el-option v-for="item in formCreateTeacher.available.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formCreateTeacher:formCreateTeacher:add')"
@click="onAddClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { TeacherController, DictionaryController } from '@/api';
export default {
name: 'formCreateTeacher',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
Teacher: {
teacherId: undefined,
teacherName: undefined,
birthday: undefined,
gender: undefined,
subjectId: undefined,
level: undefined,
flowerCount: undefined,
schoolId: undefined,
userId: undefined,
registerDate: undefined,
available: undefined,
sysDept: {
deptId: undefined,
deptName: undefined,
showOrder: undefined,
deletedFlag: undefined,
createUserId: undefined,
createUsername: undefined,
createTime: undefined,
updateTime: undefined
},
isDatasourceInit: false
}
},
rules: {
'Teacher.teacherName': [
{required: true, message: '请输入教师名称', trigger: 'blur'}
],
'Teacher.birthday': [
{required: true, message: '请输入出生日期', trigger: 'blur'}
],
'Teacher.gender': [
{required: true, message: '请输入性别', trigger: 'blur'}
],
'Teacher.subjectId': [
{required: true, message: '请输入所教科目', trigger: 'blur'}
],
'Teacher.level': [
{required: true, message: '请输入职级', trigger: 'blur'}
],
'Teacher.flowerCount': [
{type: 'integer', message: '鲜花数量只允许输入整数', trigger: 'blur', transform: (value) => Number(value)},
{type: 'number', min: 0, message: '鲜花数量必须大于0', trigger: 'blur', transform: (value) => Number(value)}
],
'Teacher.schoolId': [
{required: true, message: '请输入所属校区', trigger: 'blur'}
],
'Teacher.userId': [
{required: true, message: '请输入绑定用户', trigger: 'blur'}
],
'Teacher.available': [
{required: true, message: '请输入是否在职', trigger: 'blur'}
]
},
formCreateTeacher: {
formFilter: {
},
formFilterCopy: {
},
gender: {
impl: new DropdownWidget(this.loadGenderDropdownList)
},
subjectId: {
impl: new DropdownWidget(this.loadSubjectIdDropdownList)
},
level: {
impl: new DropdownWidget(this.loadLevelDropdownList)
},
schoolId: {
impl: new DropdownWidget(this.loadSchoolIdDropdownList)
},
userId: {
impl: new DropdownWidget(this.loadUserIdDropdownList)
},
available: {
impl: new DropdownWidget(this.loadAvailableDropdownList)
},
menu: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 性别下拉数据获取函数
*/
loadGenderDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictGender(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 性别选中值改变
*/
onGenderValueChange (value) {
},
/**
* 所教科目下拉数据获取函数
*/
loadSubjectIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSubject(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所教科目选中值改变
*/
onSubjectIdValueChange (value) {
},
/**
* 职级下拉数据获取函数
*/
loadLevelDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictTeacherLevelType(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 职级选中值改变
*/
onLevelValueChange (value) {
},
/**
* 所属校区下拉数据获取函数
*/
loadSchoolIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDept(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属校区选中值改变
*/
onSchoolIdValueChange (value) {
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.Teacher.userId = undefined;
this.formCreateTeacher.userId.impl.dirty = true;
this.onUserIdValueChange(this.formData.Teacher.userId);
},
/**
* 绑定用户下拉数据获取函数
*/
loadUserIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {
deptId: this.formData.Teacher.schoolId
};
DictionaryController.dictSysUser(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 绑定用户选中值改变
*/
onUserIdValueChange (value) {
},
/**
* 是否在职下拉数据获取函数
*/
loadAvailableDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictYesNo(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 是否在职选中值改变
*/
onAvailableValueChange (value) {
},
/**
* 更新新建老师
*/
refreshFormCreateTeacher (reloadData = false) {
if (!this.formCreateTeacher.isInit) {
// 初始化下拉数据
}
this.formCreateTeacher.isInit = true;
},
/**
* 保存
*/
onAddClick () {
this.$refs.formCreateTeacher.validate((valid) => {
if (!valid) return;
let params = {
teacher: {
teacherName: this.formData.Teacher.teacherName,
birthday: this.formData.Teacher.birthday,
gender: this.formData.Teacher.gender,
subjectId: this.formData.Teacher.subjectId,
level: this.formData.Teacher.level,
flowerCount: this.formData.Teacher.flowerCount,
schoolId: this.formData.Teacher.schoolId,
userId: this.formData.Teacher.userId,
available: this.formData.Teacher.available
}
};
TeacherController.add(this, params).then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
initFormData () {
},
formInit () {
this.refreshFormCreateTeacher();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

View File

@@ -1,402 +0,0 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditTeacher" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="教师名称" prop="Teacher.teacherName">
<el-input class="input-item" v-model="formData.Teacher.teacherName"
:clearable="true" placeholder="教师名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出生日期" prop="Teacher.birthday">
<el-date-picker class="input-item" v-model="formData.Teacher.birthday" :clearable="true"
placeholder="出生日期" type="date" align="left"
format="yyyy-MM-dd" value-format="yyyy-MM-dd hh:mm:ss" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别" prop="Teacher.gender">
<el-select class="input-item" v-model="formData.Teacher.gender" :clearable="true" filterable
placeholder="性别" :loading="formEditTeacher.gender.impl.loading"
@visible-change="formEditTeacher.gender.impl.onVisibleChange"
@change="onGenderValueChange">
<el-option v-for="item in formEditTeacher.gender.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所教科目" prop="Teacher.subjectId">
<el-select class="input-item" v-model="formData.Teacher.subjectId" :clearable="true" filterable
placeholder="所教科目" :loading="formEditTeacher.subjectId.impl.loading"
@visible-change="formEditTeacher.subjectId.impl.onVisibleChange"
@change="onSubjectIdValueChange">
<el-option v-for="item in formEditTeacher.subjectId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职级" prop="Teacher.level">
<el-select class="input-item" v-model="formData.Teacher.level" :clearable="true" filterable
placeholder="职级" :loading="formEditTeacher.level.impl.loading"
@visible-change="formEditTeacher.level.impl.onVisibleChange"
@change="onLevelValueChange">
<el-option v-for="item in formEditTeacher.level.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="鲜花数量" prop="Teacher.flowerCount">
<el-input-number class="input-item" v-model="formData.Teacher.flowerCount"
:clearable="true" controls-position="right" placeholder="鲜花数量" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属校区" prop="Teacher.schoolId">
<el-select class="input-item" v-model="formData.Teacher.schoolId" :clearable="true" filterable
placeholder="所属校区" :loading="formEditTeacher.schoolId.impl.loading"
@visible-change="formEditTeacher.schoolId.impl.onVisibleChange"
@change="onSchoolIdValueChange">
<el-option v-for="item in formEditTeacher.schoolId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="绑定用户" prop="Teacher.userId">
<el-select class="input-item" v-model="formData.Teacher.userId" :clearable="true" filterable
placeholder="绑定用户" :loading="formEditTeacher.userId.impl.loading"
@visible-change="formEditTeacher.userId.impl.onVisibleChange"
@change="onUserIdValueChange">
<el-option v-for="item in formEditTeacher.userId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否在职" prop="Teacher.available">
<el-select class="input-item" v-model="formData.Teacher.available" :clearable="true" filterable
placeholder="是否在职" :loading="formEditTeacher.available.impl.loading"
@visible-change="formEditTeacher.available.impl.onVisibleChange"
@change="onAvailableValueChange">
<el-option v-for="item in formEditTeacher.available.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formEditTeacher:formEditTeacher:update')"
@click="onUpdateClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { TeacherController, DictionaryController } from '@/api';
export default {
name: 'formEditTeacher',
props: {
teacherId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
Teacher: {
teacherId: undefined,
teacherName: undefined,
birthday: undefined,
gender: undefined,
subjectId: undefined,
level: undefined,
flowerCount: undefined,
schoolId: undefined,
userId: undefined,
registerDate: undefined,
available: undefined,
sysDept: {
deptId: undefined,
deptName: undefined,
showOrder: undefined,
deletedFlag: undefined,
createUserId: undefined,
createUsername: undefined,
createTime: undefined,
updateTime: undefined
},
isDatasourceInit: false
}
},
rules: {
'Teacher.teacherName': [
{required: true, message: '请输入教师名称', trigger: 'blur'}
],
'Teacher.birthday': [
{required: true, message: '请输入出生日期', trigger: 'blur'}
],
'Teacher.gender': [
{required: true, message: '请输入性别', trigger: 'blur'}
],
'Teacher.subjectId': [
{required: true, message: '请输入所教科目', trigger: 'blur'}
],
'Teacher.level': [
{required: true, message: '请输入职级', trigger: 'blur'}
],
'Teacher.flowerCount': [
{type: 'integer', message: '鲜花数量只允许输入整数', trigger: 'blur', transform: (value) => Number(value)},
{type: 'number', min: 0, message: '鲜花数量必须大于0', trigger: 'blur', transform: (value) => Number(value)}
],
'Teacher.schoolId': [
{required: true, message: '请输入所属校区', trigger: 'blur'}
],
'Teacher.userId': [
{required: true, message: '请输入绑定用户', trigger: 'blur'}
],
'Teacher.available': [
{required: true, message: '请输入是否在职', trigger: 'blur'}
]
},
formEditTeacher: {
formFilter: {
},
formFilterCopy: {
},
gender: {
impl: new DropdownWidget(this.loadGenderDropdownList)
},
subjectId: {
impl: new DropdownWidget(this.loadSubjectIdDropdownList)
},
level: {
impl: new DropdownWidget(this.loadLevelDropdownList)
},
schoolId: {
impl: new DropdownWidget(this.loadSchoolIdDropdownList)
},
userId: {
impl: new DropdownWidget(this.loadUserIdDropdownList)
},
available: {
impl: new DropdownWidget(this.loadAvailableDropdownList)
},
menu: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 性别下拉数据获取函数
*/
loadGenderDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictGender(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 性别选中值改变
*/
onGenderValueChange (value) {
},
/**
* 所教科目下拉数据获取函数
*/
loadSubjectIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSubject(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所教科目选中值改变
*/
onSubjectIdValueChange (value) {
},
/**
* 职级下拉数据获取函数
*/
loadLevelDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictTeacherLevelType(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 职级选中值改变
*/
onLevelValueChange (value) {
},
/**
* 所属校区下拉数据获取函数
*/
loadSchoolIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDept(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属校区选中值改变
*/
onSchoolIdValueChange (value) {
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.Teacher.userId = undefined;
this.formEditTeacher.userId.impl.dirty = true;
this.onUserIdValueChange(this.formData.Teacher.userId);
},
/**
* 绑定用户下拉数据获取函数
*/
loadUserIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {
deptId: this.formData.Teacher.schoolId
};
DictionaryController.dictSysUser(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 绑定用户选中值改变
*/
onUserIdValueChange (value) {
},
/**
* 是否在职下拉数据获取函数
*/
loadAvailableDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictYesNo(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 是否在职选中值改变
*/
onAvailableValueChange (value) {
},
/**
* 更新编辑老师
*/
refreshFormEditTeacher (reloadData = false) {
this.loadTeacherData().then(res => {
if (!this.formEditTeacher.isInit) {
// 初始化下拉数据
}
this.formEditTeacher.isInit = true;
}).catch(e => {});
},
/**
* 保存
*/
onUpdateClick () {
this.$refs.formEditTeacher.validate((valid) => {
if (!valid) return;
let params = {
teacher: {
teacherId: this.teacherId,
teacherName: this.formData.Teacher.teacherName,
birthday: this.formData.Teacher.birthday,
gender: this.formData.Teacher.gender,
subjectId: this.formData.Teacher.subjectId,
level: this.formData.Teacher.level,
flowerCount: this.formData.Teacher.flowerCount,
schoolId: this.formData.Teacher.schoolId,
userId: this.formData.Teacher.userId,
available: this.formData.Teacher.available
}
};
TeacherController.update(this, params).then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
/**
* 获取老师数据源详细信息
*/
loadTeacherData () {
return new Promise((resolve, reject) => {
if (!this.formData.Teacher.isDatasourceInit) {
let params = {
teacherId: this.teacherId
};
TeacherController.view(this, params).then(res => {
this.formData.Teacher = {...res.data, isDatasourceInit: true};
if (this.formData.Teacher.genderDictMap) this.formEditTeacher.gender.impl.dropdownList = [this.formData.Teacher.genderDictMap];
if (this.formData.Teacher.subjectIdDictMap) this.formEditTeacher.subjectId.impl.dropdownList = [this.formData.Teacher.subjectIdDictMap];
if (this.formData.Teacher.levelDictMap) this.formEditTeacher.level.impl.dropdownList = [this.formData.Teacher.levelDictMap];
if (this.formData.Teacher.schoolIdDictMap) this.formEditTeacher.schoolId.impl.dropdownList = [this.formData.Teacher.schoolIdDictMap];
if (this.formData.Teacher.userIdDictMap) this.formEditTeacher.userId.impl.dropdownList = [this.formData.Teacher.userIdDictMap];
if (this.formData.Teacher.availableDictMap) this.formEditTeacher.available.impl.dropdownList = [this.formData.Teacher.availableDictMap];
resolve();
}).catch(e => {
reject();
});
} else {
resolve();
}
});
},
initFormData () {
},
formInit () {
this.refreshFormEditTeacher();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

View File

@@ -1,304 +0,0 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="教师职级">
<el-select class="filter-item" v-model="formTeacher.formFilter.level" :clearable="true" filterable
placeholder="教师职级" :loading="formTeacher.level.impl.loading"
@visible-change="formTeacher.level.impl.onVisibleChange"
@change="onLevelValueChange">
<el-option v-for="item in formTeacher.level.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="所教科目">
<el-select class="filter-item" v-model="formTeacher.formFilter.subjectId" :clearable="true" filterable
placeholder="所教科目" :loading="formTeacher.subjectId.impl.loading"
@visible-change="formTeacher.subjectId.impl.onVisibleChange"
@change="onSubjectIdValueChange">
<el-option v-for="item in formTeacher.subjectId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="注册日期">
<date-range class="filter-item" v-model="formTeacher.formFilter.registerDate" :clearable="true" :allowTypes="['day']" align="left"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
format="yyyy-MM-dd" value-format="yyyy-MM-dd hh:mm:ss" />
</el-form-item>
<el-form-item label="校区名称">
<el-input class="filter-item" v-model="formTeacher.formFilter.schoolName"
:clearable="true" placeholder="校区名称" />
</el-form-item>
<el-form-item label="老师名称">
<el-input class="filter-item" v-model="formTeacher.formFilter.teacherName"
:clearable="true" placeholder="老师名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormTeacher(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formTeacher:formTeacher:formCreateTeacher')"
@click="onFormCreateTeacherClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formTeacher.Teacher.impl.dataList" size="mini" @sort-change="formTeacher.Teacher.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formTeacher.Teacher.impl.getTableIndex" />
<el-table-column label="教师名称" prop="teacherName">
</el-table-column>
<el-table-column label="教师职级" prop="levelDictMap.name" sortable="custom">
</el-table-column>
<el-table-column label="所教科目" prop="subjectIdDictMap.name">
</el-table-column>
<el-table-column label="出生日期" prop="birthday">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.birthday, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="所属校区" prop="schoolIdDictMap.name">
</el-table-column>
<el-table-column label="鲜花数量" prop="flowerCount" sortable="custom">
</el-table-column>
<el-table-column label="入职时间" prop="registerDate">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.registerDate, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button @click="onFormEditTeacherClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formTeacher:formTeacher:formEditTeacher')">
编辑
</el-button>
<el-button @click="onFormTeacherTransStatsClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formTeacher:formTeacher:formTeacherTransStats')">
统计
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formTeacher:formTeacher:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formTeacher.Teacher.impl.totalCount"
:current-page="formTeacher.Teacher.impl.currentPage"
:page-size="formTeacher.Teacher.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formTeacher.Teacher.impl.onCurrentPageChange"
@size-change="formTeacher.Teacher.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { TeacherController, DictionaryController } from '@/api';
import formCreateTeacher from '@/views/generated/formCreateTeacher';
import formTeacherTransStats from '@/views/generated/formTeacherTransStats';
import formEditTeacher from '@/views/generated/formEditTeacher';
export default {
name: 'formTeacher',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formTeacher: {
formFilter: {
level: undefined,
subjectId: undefined,
registerDate: [],
schoolName: undefined,
teacherName: undefined
},
formFilterCopy: {
level: undefined,
subjectId: undefined,
registerDate: [],
schoolName: undefined,
teacherName: undefined
},
level: {
impl: new DropdownWidget(this.loadLevelDropdownList)
},
subjectId: {
impl: new DropdownWidget(this.loadSubjectIdDropdownList)
},
Teacher: {
impl: new TableWidget(this.loadTeacherData, this.loadTeacherVerify, true, 'registerDate', 1)
},
isInit: false
}
}
},
methods: {
/**
* 老师列表数据获取函数返回Primise
*/
loadTeacherData (params) {
if (params == null) params = {};
params = {
...params,
sysDeptFilter: {
deptName: this.formTeacher.formFilterCopy.schoolName
},
teacherFilter: {
teacherName: this.formTeacher.formFilterCopy.teacherName,
subjectId: this.formTeacher.formFilterCopy.subjectId,
level: this.formTeacher.formFilterCopy.level,
registerDateStart: Array.isArray(this.formTeacher.formFilterCopy.registerDate) ? this.formTeacher.formFilterCopy.registerDate[0] : undefined,
registerDateEnd: Array.isArray(this.formTeacher.formFilterCopy.registerDate) ? this.formTeacher.formFilterCopy.registerDate[1] : undefined
}
}
return new Promise((resolve, reject) => {
TeacherController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 老师列表数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadTeacherVerify () {
this.formTeacher.formFilterCopy.schoolName = this.formTeacher.formFilter.schoolName;
this.formTeacher.formFilterCopy.teacherName = this.formTeacher.formFilter.teacherName;
this.formTeacher.formFilterCopy.subjectId = this.formTeacher.formFilter.subjectId;
this.formTeacher.formFilterCopy.level = this.formTeacher.formFilter.level;
this.formTeacher.formFilterCopy.registerDate = this.formTeacher.formFilter.registerDate;
return true;
},
/**
* 教师职级下拉数据获取函数
*/
loadLevelDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictTeacherLevelType(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 教师职级选中值改变
*/
onLevelValueChange (value) {
},
/**
* 所教科目下拉数据获取函数
*/
loadSubjectIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSubject(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所教科目选中值改变
*/
onSubjectIdValueChange (value) {
},
/**
* 更新老师管理
*/
refreshFormTeacher (reloadData = false) {
if (reloadData) {
this.formTeacher.Teacher.impl.refreshTable(true, 1);
} else {
this.formTeacher.Teacher.impl.refreshTable();
}
if (!this.formTeacher.isInit) {
// 初始化下拉数据
}
this.formTeacher.isInit = true;
},
/**
* 新建
*/
onFormCreateTeacherClick () {
let params = {};
this.$dialog.show('新建', formCreateTeacher, {
area: ['800px']
}, params).then(res => {
this.refreshFormTeacher();
}).catch(e => {});
},
/**
* 编辑
*/
onFormEditTeacherClick (row) {
let params = {
teacherId: row.teacherId
};
this.$dialog.show('编辑', formEditTeacher, {
area: ['800px']
}, params).then(res => {
this.formTeacher.Teacher.impl.refreshTable();
}).catch(e => {});
},
/**
* 统计
*/
onFormTeacherTransStatsClick (row) {
let params = {
teacherId: row.teacherId
};
this.$dialog.show('统计', formTeacherTransStats, {
area: ['800px']
}, params).then(res => {
this.formTeacher.Teacher.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
teacherId: row.teacherId
};
this.$confirm('是否删除此老师?').then(res => {
TeacherController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.formTeacher.Teacher.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormTeacher();
},
initFormData () {
},
formInit () {
this.refreshFormTeacher();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -1,186 +0,0 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="统计日期">
<date-range class="filter-item" v-model="formTeacherTransStats.formFilter.statsDate" :clearable="true" :allowTypes="['day']" align="left"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
format="yyyy-MM-dd" value-format="yyyy-MM-dd hh:mm:ss" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormTeacherTransStats(true)">查询</el-button>
</filter-box>
</el-form>
<el-form ref="formTeacherTransStats" :model="formData" class="full-width-input" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col class="table-box" :span="24">
<ve-line height="300px"
:extend="formTeacherTransStats.TeacherTransStats.chartOption"
:data="formTeacherTransStats.TeacherTransStats.impl.chartData"
:settings="formTeacherTransStats.TeacherTransStats.chartSetting"
:loading="formTeacherTransStats.TeacherTransStats.impl.loading"
:data-empty="formTeacherTransStats.TeacherTransStats.impl.dataEmpty"
:after-set-option-once="onTeacherTransStatsOptionSet"/>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { defaultLineChartOption, defaultBarChartOption, defaultPieChartOption } from '@/utils/chartOption.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { TeacherTransStatsController, DictionaryController } from '@/api';
export default {
name: 'formTeacherTransStats',
props: {
teacherId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
TeacherTransStats: {
statsId: undefined,
statsDate: undefined,
statsMonth: undefined,
provinceId: undefined,
cityId: undefined,
schoolId: undefined,
schoolName: undefined,
teacherId: undefined,
teacherName: undefined,
videoWatchCount: undefined,
flowerCount: undefined,
newStudent: undefined,
sysDept: {
deptId: undefined,
deptName: undefined,
showOrder: undefined,
deletedFlag: undefined,
createUserId: undefined,
createUsername: undefined,
createTime: undefined,
updateTime: undefined
},
teacher: {
teacherId: undefined,
teacherName: undefined,
birthday: undefined,
gender: undefined,
subjectId: undefined,
level: undefined,
flowerCount: undefined,
schoolId: undefined,
userId: undefined,
registerDate: undefined,
available: undefined
},
isDatasourceInit: false
}
},
formTeacherTransStats: {
formFilter: {
statsDate: []
},
formFilterCopy: {
statsDate: []
},
TeacherTransStats: {
impl: new ChartWidget(this.loadTeacherTransStatsData, this.loadTeacherTransStatsVerify,
['statsDateShowName', 'videoWatchCount', 'newStudent', 'flowerCount']),
chartOption: defaultLineChartOption,
chartSetting: {
dimension: ['statsDateShowName'],
metrics: ['videoWatchCount', 'newStudent', 'flowerCount'],
labelMap: {
'videoWatchCount': '视频观看数量',
'newStudent': '新增学生数量',
'flowerCount': '献花数量'
}
}
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 老师流水统计数据获取函数返回Primise
*/
loadTeacherTransStatsData () {
let params = {
groupParam: [
{
fieldName: 'statsDate'
}
],
teacherTransStatsFilter: {
statsDateStart: Array.isArray(this.formTeacherTransStats.formFilterCopy.statsDate) ? this.formTeacherTransStats.formFilterCopy.statsDate[0] : undefined,
statsDateEnd: Array.isArray(this.formTeacherTransStats.formFilterCopy.statsDate) ? this.formTeacherTransStats.formFilterCopy.statsDate[1] : undefined,
teacherId: this.teacherId
}
}
return new Promise((resolve, reject) => {
TeacherTransStatsController.listWithGroup(this, params).then(res => {
resolve({
dataList: res.data.dataList.map((item) => {
return {...item, statsDateShowName: this.formatDateByStatsType(item.statsDate, this.formTeacherTransStats.TeacherTransStats.statsType)};
}),
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 老师流水统计数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadTeacherTransStatsVerify () {
this.formTeacherTransStats.formFilterCopy.statsDate = this.formTeacherTransStats.formFilter.statsDate;
return true;
},
/**
* 获取老师流水统计的echarts实例
*/
onTeacherTransStatsOptionSet (echarts) {
echarts.resize();
this.formTeacherTransStats.TeacherTransStats.impl.chartObject = echarts;
},
/**
* 更新老师个人统计
*/
refreshFormTeacherTransStats (reloadData = false) {
this.formTeacherTransStats.TeacherTransStats.impl.refreshChart(reloadData);
if (!this.formTeacherTransStats.isInit) {
// 初始化下拉数据
}
this.formTeacherTransStats.isInit = true;
},
initFormData () {
},
formInit () {
this.refreshFormTeacherTransStats();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

View File

@@ -1,308 +0,0 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditSysDataPerm" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="120px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="数据权限名称" prop="SysDataPerm.dataPermName">
<el-input class="input-item" v-model="formData.SysDataPerm.dataPermName"
:clearable="true" placeholder="显示名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="过滤规则" prop="SysDataPerm.ruleType">
<el-select class="input-item" v-model="formData.SysDataPerm.ruleType" :clearable="true"
placeholder="过滤规则" :loading="formEditSysDataPerm.ruleType.impl.loading"
@visible-change="onRuleTypeVisibleChange"
@change="onRuleTypeValueChange">
<el-option v-for="item in formEditSysDataPerm.ruleType.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-card shadow="never">
<div slot="header" class="card-header">
<span>部门列表</span>
<el-input size="mini" v-model="deptNameFilter" placeholder="输入部门名称过滤" style="width: 250px;" clearable suffix-icon="el-icon-search" />
</div>
<el-scrollbar style="height: 250px;" wrap-class="scrollbar_dropdown__wrap">
<el-tree ref="deptTree" :data="deptTree" show-checkbox node-key="id" default-expand-all
:check-strictly="true" :props="{...deptProps, disabled: () => {return (formData.SysDataPerm.ruleType !== SysDataPermType.CUSTOM_DEPT_AND_CHILD && formData.SysDataPerm.ruleType !== SysDataPermType.CUSTOM_DEPT)}}" :filter-node-method="filterDeptNode" />
</el-scrollbar>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="never">
<div slot="header" class="card-header">
<span>菜单列表</span>
<el-input size="mini" v-model="menuNameFilter" placeholder="输入菜单名称过滤" style="width: 250px;" clearable suffix-icon="el-icon-search" />
</div>
<el-scrollbar style="height: 250px;" wrap-class="scrollbar_dropdown__wrap">
<el-tree ref="menuTree" :data="menuTree" show-checkbox node-key="menuId" default-expand-all
:props="menuProps" :filter-node-method="filterMneuNode" />
</el-scrollbar>
</el-card>
</el-col>
</el-row>
<el-col :span="24" style="margin-top: 20px;">
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true" @click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onUpdateClick()"
:disabled="!(checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:add') || checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:update'))">
保存
</el-button>
</el-row>
</el-col>
</el-form>
</div>
</template>
<script>
import { treeDataTranslate } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController, SysDataPermController } from '@/api';
export default {
name: 'formEditSysDataPerm',
props: {
dataPermId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachedPageChildMixin],
data () {
return {
deptTree: [],
deptNameFilter: undefined,
menuTree: [],
menuNameFilter: undefined,
allowParentList: [],
menuProps: {
label: 'menuName'
},
deptProps: {
label: 'name'
},
formData: {
SysDataPerm: {
dataPermId: undefined,
dataPermName: undefined,
ruleType: undefined,
deptIdListString: undefined,
createUserId: undefined,
createUsername: undefined,
createTime: undefined,
updateTime: undefined
}
},
rules: {
'SysDataPerm.dataPermName': [
{required: true, message: '请输入数据权限名称', trigger: 'blur'}
],
'SysDataPerm.ruleType': [
{required: true, message: '请选择过滤规则', trigger: 'blur'}
]
},
formEditSysDataPerm: {
formFilter: {
},
formFilterCopy: {
},
ruleType: {
impl: new DropdownWidget(this.loadRuleTypeDropdownList)
},
isInit: false
}
}
},
methods: {
filterDeptNode (value, data) {
if (!value) return true;
return data.deptName ? data.deptName.indexOf(value) !== -1 : true;
},
filterMneuNode (value, data) {
if (!value) return true;
if (data.menuName.indexOf(value) !== -1) {
this.allowParentList.push(data.menuId);
return true;
} else {
return this.allowParentList.indexOf(data.parentId) !== -1;
}
},
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 过滤规则下拉数据获取函数
*/
loadRuleTypeDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDataPermType(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 过滤规则下拉框显隐
*/
onRuleTypeVisibleChange (show) {
this.formEditSysDataPerm.ruleType.impl.onVisibleChange(show).catch(e => {});
},
/**
* 过滤规则选中值改变
*/
onRuleTypeValueChange (value) {
},
/**
* 部门列表数据获取函数
*/
loadDeptList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDept(this, params).then(res => {
this.deptTree = treeDataTranslate(res.getList(), 'id');
if (Array.isArray(this.formData.SysDataPerm.dataPermDeptList)) {
this.$refs.deptTree.setCheckedKeys(this.formData.SysDataPerm.dataPermDeptList.map((item) => {
return item.deptId;
}));
}
}).catch(e => {
reject(e);
});
});
},
/**
* 菜单列表数据获取函数
*/
loadMenuList () {
return new Promise((resolve, reject) => {
let params = {};
SystemController.getMenuPermList(this, params).then(res => {
this.menuTree = treeDataTranslate(res.data.map((item) => {
if (item.menuType === this.SysMenuType.DIRECTORY || item.menuType === this.SysMenuType.MENU) {
return {...item};
}
}).filter(item => {
return item != null;
}), 'menuId');
if (Array.isArray(this.formData.SysDataPerm.dataPermMenuList)) {
let selectList = this.formData.SysDataPerm.dataPermMenuList.map((item) => {
return item.menuId;
});
this.$refs.menuTree.setCheckedKeys(selectList);
}
}).catch(e => {
reject(e);
});
});
},
/**
* 更新编辑数据权限
*/
refreshFormEditSysDataPerm (reloadData = false) {
this.formEditSysDataPerm.ruleType.impl.onVisibleChange(true).catch(e => {});
this.formEditSysDataPerm.isInit = true;
},
/**
* 编辑
*/
onUpdateClick () {
this.$refs.formEditSysDataPerm.validate((valid) => {
if (!valid) return;
let params = {
sysDataPerm: {
dataPermId: this.dataPermId,
ruleType: this.formData.SysDataPerm.ruleType,
dataPermName: this.formData.SysDataPerm.dataPermName
}
};
if (this.formData.SysDataPerm.ruleType === this.SysDataPermType.CUSTOM_DEPT_AND_CHILD ||
this.formData.SysDataPerm.ruleType === this.SysDataPermType.CUSTOM_DEPT) {
let deptList = this.$refs.deptTree.getCheckedKeys();
if (deptList.length <= 0) {
this.$message.error('请选择数据权限部门');
return;
}
params.deptIdListString = Array.isArray(deptList) ? deptList.join(',') : undefined;
}
let menuList = this.$refs.menuTree.getCheckedKeys();
if (menuList.length <= 0) {
this.$message.error('请选择数据权限生效的菜单');
return;
}
params.menuIdListString = Array.isArray(menuList) ? menuList.join(',') : undefined;
if (this.dataPermId == null) {
SysDataPermController.add(this, params).then(res => {
this.$message.success('添加成功');
this.onCancel(true);
}).catch(e => {});
} else {
SysDataPermController.update(this, params).then(res => {
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {});
}
});
},
/**
* 获取数据权限详细信息
*/
loadSysDataPermData () {
return new Promise((resolve, reject) => {
if (this.dataPermId == null) {
resolve();
} else {
let params = {
dataPermId: this.dataPermId
};
SysDataPermController.view(this, params).then(res => {
this.formData.SysDataPerm = {...res.data};
resolve();
}).catch(e => {
reject();
});
}
});
},
initFormData () {
},
formInit () {
let loadAllDatasource = [
this.loadSysDataPermData()
];
Promise.all(loadAllDatasource).then(res => {
this.initFormData();
this.refreshFormEditSysDataPerm();
this.loadMenuList();
this.loadDeptList();
}).catch(e => {});
}
},
mounted () {
this.formInit();
},
watch: {
menuNameFilter (val) {
this.allowParentList = [];
this.$refs.menuTree.filter(val);
},
deptNameFilter (val) {
this.$refs.deptTree.filter(val);
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,205 +0,0 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditSysDept" :model="formData" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="所属部门" prop="SysDept.parentId">
<el-cascader class="input-item" v-model="formEditSysDept.parentId.value" :clearable="true"
placeholder="所属部门" :loading="formEditSysDept.parentId.impl.loading" :props="{value: 'id', label: 'name', checkStrictly: true}"
@visible-change="onParentIdVisibleChange" :options="formEditSysDept.parentId.impl.dropdownList"
@change="onParentIdValueChange">
</el-cascader>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="部门名称" prop="SysDept.deptName">
<el-input class="input-item" v-model="formData.SysDept.deptName"
:clearable="true" placeholder="部门名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="显示顺序" prop="SysDept.showOrder">
<el-input-number class="input-item" v-model="formData.SysDept.showOrder"
:clearable="true" controls-position="right" placeholder="显示顺序" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onUpdateClick()"
:disabled="!(checkPermCodeExist('formSysDept:fragmentSysDept:update') || checkPermCodeExist('formSysDept:fragmentSysDept:add'))">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findTreeNodePath } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDeptController, DictionaryController } from '@/api';
export default {
name: 'formEditSysDept',
props: {
deptId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachedPageChildMixin],
data () {
return {
formData: {
SysDept: {
deptId: undefined,
deptName: undefined,
showOrder: undefined,
parentId: undefined,
deletedFlag: undefined,
createUserId: undefined,
createUsername: undefined,
createTime: undefined,
updateTime: undefined
}
},
rules: {
'SysDept.deptName': [
{required: true, message: '请输入部门名称', trigger: 'blur'}
],
'SysDept.showOrder': [
{required: true, message: '请输入显示顺序', trigger: 'blur'}
]
},
formEditSysDept: {
formFilter: {
},
formFilterCopy: {
},
parentId: {
impl: new DropdownWidget(this.loadParentIdDropdownList, true, 'id'),
value: []
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 所属部门下拉数据获取函数
*/
loadParentIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDept(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属部门下拉框显隐
*/
onParentIdVisibleChange (show) {
this.formEditSysDept.parentId.impl.onVisibleChange(show).catch(e => {});
},
/**
* 所属部门选中值改变
*/
onParentIdValueChange (value) {
},
/**
* 更新编辑用户
*/
refreshFormEditSysDept (reloadData = false) {
this.formEditSysDept.parentId.impl.onVisibleChange(true).then(res => {
if (!this.formEditSysDept.isInit) {
this.formEditSysDept.parentId.value = findTreeNodePath(
this.formEditSysDept.parentId.impl.dropdownList, this.formData.SysDept.parentId, 'id');
}
this.formEditSysDept.isInit = true;
});
},
/**
* 编辑
*/
onUpdateClick () {
this.$refs.formEditSysDept.validate((valid) => {
if (!valid) return;
let params = {
sysDept: {
deptName: this.formData.SysDept.deptName,
showOrder: this.formData.SysDept.showOrder,
parentId: Array.isArray(this.formEditSysDept.parentId.value) ? this.formEditSysDept.parentId.value[this.formEditSysDept.parentId.value.length - 1] : undefined,
deptId: this.deptId
}
};
if (this.isEdit) {
SysDeptController.update(this, params).then(res => {
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {});
} else {
SysDeptController.add(this, params).then(res => {
this.$message.success('新建成功');
this.onCancel(true);
}).catch(e => {});
}
});
},
/**
* 获取部门管理详细信息
*/
loadSysDeptData () {
if (!this.isEdit) return;
let params = {
deptId: this.deptId
};
return new Promise((resolve, reject) => {
SysDeptController.view(this, params).then(res => {
this.formData.SysDept = {...res.data};
resolve();
}).catch(e => {
reject();
});
});
},
initFormData () {
},
formInit () {
let loadAllDatasource = [
this.loadSysDeptData()
];
Promise.all(loadAllDatasource).then(res => {
this.initFormData();
this.refreshFormEditSysDept();
}).catch(e => {});
}
},
computed: {
isEdit () {
return this.deptId != null;
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -1,216 +0,0 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="325">
<el-form-item label="用户状态">
<el-select class="filter-item" v-model="formSysUser.formFilter.sysUserStatus" :clearable="true"
placeholder="用户状态" :loading="formSysUser.sysUserStatus.impl.loading"
@visible-change="onSysUserStatusVisibleChange">
<el-option v-for="item in formSysUser.sysUserStatus.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="用户名">
<el-input class="filter-item" v-model="formSysUser.formFilter.sysUserLoginName"
:clearable="true" placeholder="用户名" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysUser(true)">查询</el-button>
<el-button slot="operator" size="mini" type="primary" :plain="false" @click="onSetUser"
:disabled="selectUsers == null || selectUsers.length <= 0">授权人员</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSysUser.SysUser.impl.dataList" size="mini" row-key="userId" ref="userTable"
header-cell-class-name="table-header-gray" height="395px" @selection-change="onTableSelectionChange">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px" :index="formSysUser.SysUser.impl.getTableIndex" />
<el-table-column header-align="center" align="center" type="selection" width="50px" :reserve-selection="true" />
<el-table-column label="用户名" prop="loginName">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型">
<template slot-scope="scope">
<span>{{SysUserType.getValue(scope.row.userType)}}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysUser.SysUser.impl.totalCount"
:current-page="formSysUser.SysUser.impl.currentPage"
:page-size="formSysUser.SysUser.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysUser.SysUser.impl.onCurrentPageChange"
@size-change="formSysUser.SysUser.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDataPermController, DictionaryController } from '@/api';
export default {
props: {
dataPermId: {
type: [String, Number],
required: true
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysUser: {
formFilter: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
formFilterCopy: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
sysUserStatus: {
impl: new DropdownWidget(this.loadSysUserStatusDropdownList)
},
SysUser: {
impl: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, true, 'createTime', 1)
},
isInit: false
},
selectUsers: []
}
},
methods: {
/**
* 用户状态下拉数据获取函数
*/
loadSysUserStatusDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysUserStatus(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 用户状态下拉框显隐
*/
onSysUserStatusVisibleChange (show) {
this.formSysUser.sysUserStatus.impl.onVisibleChange(show).catch(e => {});
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
onTableSelectionChange (values) {
this.selectUsers = values;
},
onSetUser () {
let params = {
dataPermId: this.dataPermId,
userIdListString: this.selectUsers.map((item) => {
return item.userId
}).join(',')
}
SysDataPermController.addDataPermUser(this, params).then(res => {
this.$message.success('授权成功');
this.refreshFormSysUser(true);
this.$refs.userTable.clearSelection();
this.selectUsers = [];
}).catch(e => {});
},
onCancel () {
this.$router.go(-1);
},
loadSysUserData (params) {
params.dataPermId = this.dataPermId;
params.sysUserFilter = {
loginName: this.formSysUser.formFilterCopy.sysUserLoginName,
userStatus: this.formSysUser.formFilterCopy.sysUserStatus
}
this.$refs.userTable.clearSelection();
return new Promise((resolve, reject) => {
SysDataPermController.listNotInDataPermUser(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
this.formSysUser.formFilterCopy.sysUserLoginName = this.formSysUser.formFilter.sysUserLoginName;
this.formSysUser.formFilterCopy.sysUserStatus = this.formSysUser.formFilter.sysUserStatus;
return true;
},
refreshFormSysUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysUser.SysUser.impl.refreshTable(true, 1);
} else {
this.formSysUser.SysUser.impl.refreshTable();
}
this.formSysUser.sysUserStatus.impl.onVisibleChange(true).catch(e => {});
this.formSysUser.isInit = true;
},
initData () {
this.refreshFormSysUser();
}
},
mounted () {
this.initData();
},
computed: {
getContextHeightStyle () {
return [
{'height': (this.getClientHeight - 142) + 'px'}
]
},
...mapGetters(['getClientHeight'])
},
watch: {
currentPage: function (value, oldValue) {
this.loadDatasource(false).catch(e => {
this.currentPage = oldValue;
})
}
}
}
</script>
<style>
</style>

View File

@@ -1,483 +0,0 @@
<template>
<div class="tab-dialog-box" style="position: relative;">
<el-tabs v-model="activeFragmentId" :before-leave="onFragmentChange">
<el-tab-pane label="数据权限管理" name="fragmentSysDataPerm" style="width: 100%;"
v-if="checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm')">
<el-scrollbar class="custom-scroll" :style="{height: getTabPaneHeight + 'px'}">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="过滤规则">
<el-select class="filter-item" v-model="fragmentSysDataPerm.formFilter.sysDatapermType" :clearable="true"
placeholder="过滤规则" :loading="fragmentSysDataPerm.sysDatapermType.impl.loading"
@visible-change="onSysDatapermTypeVisibleChange"
@change="onSysDatapermTypeValueChange">
<el-option v-for="item in fragmentSysDataPerm.sysDatapermType.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="数据权限名称">
<el-input class="filter-item" v-model="fragmentSysDataPerm.formFilter.sysDataPermName"
:clearable="true" placeholder="数据权限名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysDataPerm(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:add')"
@click="onAddDataPermClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysDataPerm.SysDataPerm.impl.dataList" size="mini"
@sort-change="fragmentSysDataPerm.SysDataPerm.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysDataPerm.SysDataPerm.impl.getTableIndex" />
<el-table-column label="权限名称" prop="dataPermName">
</el-table-column>
<el-table-column label="过滤规则">
<template slot-scope="scope">
<span>{{SysDataPermType.getValue(scope.row.ruleType)}}</span>
</template>
</el-table-column>
<el-table-column label="创建人" prop="createUsername">
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button @click="onEditDataPermClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:update')">
编辑
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="fragmentSysDataPerm.SysDataPerm.impl.totalCount"
:current-page="fragmentSysDataPerm.SysDataPerm.impl.currentPage"
:page-size="fragmentSysDataPerm.SysDataPerm.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="fragmentSysDataPerm.SysDataPerm.impl.onCurrentPageChange"
@size-change="fragmentSysDataPerm.SysDataPerm.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane label="用户授权" name="fragmentSysDataPermUser" style="width: 100%;"
v-if="checkPermCodeExist('formSysDataPerm:fragmentSysDataPermUser')">
<el-scrollbar class="custom-scroll" :style="{height: getTabPaneHeight + 'px'}">
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="数据权限">
<el-select class="filter-item" v-model="fragmentSysDataPermUser.formFilter.dataPermId" clearable
placeholder="数据权限" :loading="fragmentSysDataPermUser.dataPermId.impl.loading"
@visible-change="fragmentSysDataPermUser.dataPermId.impl.onVisibleChange"
@change="onDataPermChange">
<el-option v-for="item in fragmentSysDataPermUser.dataPermId.impl.dropdownList" :key="item.dataPermId"
:value="item.dataPermId" :label="item.dataPermName" />
</el-select>
</el-form-item>
<el-form-item label="用户名">
<el-input class="filter-item" v-model="fragmentSysDataPermUser.formFilter.searchString"
:clearable="true" placeholder="输入用户名 / 昵称查询" @change="refreshFragmentSysDataPermUser(true)" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysDataPermUser(true)">
查询
</el-button>
<el-button slot="operator" type="primary" size="mini" @click="onAddDataPermUserClick()"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPermUser:addDataPermUser') ||
fragmentSysDataPermUser.formFilter.dataPermId == null || fragmentSysDataPermUser.formFilter.dataPermId === ''">
添加用户
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysDataPermUser.SysDataPermUserList.impl.dataList" size="mini"
@sort-change="fragmentSysDataPermUser.SysDataPermUserList.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysDataPermUser.SysDataPermUserList.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型">
<template slot-scope="scope">
<span>{{SysUserType.getValue(scope.row.userType)}}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="80px">
<template slot-scope="scope">
<el-button class="btn-table-delete" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPermUser:deleteDataPermUser')"
@click="onDeleteRow(scope.row)">移除</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="fragmentSysDataPermUser.SysDataPermUserList.impl.totalCount"
:current-page="fragmentSysDataPermUser.SysDataPermUserList.impl.currentPage"
:page-size="fragmentSysDataPermUser.SysDataPermUserList.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="fragmentSysDataPermUser.SysDataPermUserList.impl.onCurrentPageChange"
@size-change="fragmentSysDataPermUser.SysDataPermUserList.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</el-scrollbar>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDataPermController, DictionaryController } from '@/api';
import formEditSysDataPerm from '@/views/upms/formEditSysDataPerm';
import formSetSysDataPermUser from '@/views/upms/formSetSysDataPermUser';
export default {
name: 'formSysDataPerm',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
activeFragmentId: undefined,
fragmentSysDataPerm: {
formFilter: {
sysDatapermType: undefined,
sysDataPermName: undefined
},
formFilterCopy: {
sysDatapermType: undefined,
sysDataPermName: undefined
},
sysDatapermType: {
impl: new DropdownWidget(this.loadSysDatapermTypeDropdownList)
},
SysDataPerm: {
impl: new TableWidget(this.loadSysDataPermData, this.loadSysDataPermVerify, true, 'createTime', 1)
},
isInit: false
},
fragmentSysDataPermUser: {
formFilter: {
dataPermId: undefined,
searchString: undefined
},
dataPermId: {
impl: new DropdownWidget(this.loadDataPermDropdownList)
},
SysDataPermUserList: {
impl: new TableWidget(this.loadSysDataPermUserListData, this.loadSysDataPermUserListVerify, true, 'createTime', 1)
},
isInit: false
}
}
},
methods: {
/**
* 数据权限数据获取函数返回Primise
*/
loadSysDataPermData (params) {
params.sysDataPermFilter = {
searchString: this.fragmentSysDataPerm.formFilterCopy.sysDataPermName,
ruleType: this.fragmentSysDataPerm.formFilterCopy.sysDatapermType
};
return new Promise((resolve, reject) => {
SysDataPermController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 数据权限数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysDataPermVerify () {
this.fragmentSysDataPerm.formFilterCopy.sysDataPermName = this.fragmentSysDataPerm.formFilter.sysDataPermName;
this.fragmentSysDataPerm.formFilterCopy.sysDatapermType = this.fragmentSysDataPerm.formFilter.sysDatapermType;
return true;
},
/**
* 过滤规则下拉数据获取函数
*/
loadSysDatapermTypeDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDataPermType(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 过滤规则下拉框显隐
*/
onSysDatapermTypeVisibleChange (show) {
this.fragmentSysDataPerm.sysDatapermType.impl.onVisibleChange(show).catch(e => {});
},
/**
* 过滤规则选中值改变
*/
onSysDatapermTypeValueChange (value) {
},
/**
* 更新数据权限管理
*/
refreshFragmentSysDataPerm (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable(true, 1);
} else {
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable();
}
this.fragmentSysDataPerm.sysDatapermType.impl.onVisibleChange(true).catch(e => {});
this.fragmentSysDataPerm.isInit = true;
},
/**
* 新建
*/
onAddDataPermClick () {
let params = {};
this.$dialog.show('新建数据权限', formEditSysDataPerm, {
area: ['800px', '520px']
}, params).then(res => {
this.refreshFragmentSysDataPerm();
}).catch(e => {});
},
/**
* 编辑
*/
onEditDataPermClick (row) {
let params = {
dataPermId: row.dataPermId
};
this.$dialog.show('编辑数据权限', formEditSysDataPerm, {
area: ['800px', '520px']
}, params).then(res => {
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
dataPermId: row.dataPermId
};
this.$confirm('是否删除此数据权限?').then(res => {
SysDataPermController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
// AAAAAAAAAAA
onDataPermChange (value) {
this.refreshFragmentSysDataPermUser(true);
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
loadDataPermDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
SysDataPermController.list(this, params).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
/**
* 用户列表数据获取函数返回Primise
*/
loadSysDataPermUserListData (params) {
return new Promise((resolve, reject) => {
if (this.fragmentSysDataPermUser.formFilter.dataPermId == null || this.fragmentSysDataPermUser.formFilter.dataPermId === '') {
this.$message.error('请选择数据权限');
resolve({
dataList: [],
totalCount: 0
});
return;
}
params.dataPermId = this.fragmentSysDataPermUser.formFilter.dataPermId;
params.searchString = this.fragmentSysDataPermUser.formFilter.searchString;
SysDataPermController.listDataPermUser(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户列表数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysDataPermUserListVerify () {
return true;
},
onDeleteRow (row) {
this.$confirm('是否移除此用户?').then(res => {
let params = {
dataPermId: this.fragmentSysDataPermUser.formFilter.dataPermId,
userId: row.userId
}
SysDataPermController.deleteDataPermUser(this, params).then(res => {
this.refreshFragmentSysDataPermUser(true);
this.$message.success('移除成功');
}).catch(e => {});
}).catch(e => {});
},
/**
* 更新数据权限授权
*/
refreshFragmentSysDataPermUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysDataPermUser.SysDataPermUserList.impl.refreshTable(true, 1);
} else {
this.fragmentSysDataPermUser.SysDataPermUserList.impl.refreshTable();
}
this.fragmentSysDataPermUser.isInit = true;
},
/**
* 授权用户
*/
onAddDataPermUserClick () {
let params = {
dataPermId: this.fragmentSysDataPermUser.formFilter.dataPermId
};
this.$dialog.show('授权用户', formSetSysDataPermUser, {
area: ['1100px', '580px']
}, params).then(res => {
this.refreshFragmentSysDataPermUser(true);
}).catch(e => {
this.refreshFragmentSysDataPermUser(true);
});
},
buildFragmentPermCodeMap () {
this.permCodeList = [
{
key: 'fragmentSysDataPerm',
permCode: 'formSysDataPerm:fragmentSysDataPerm',
refresh: this.refreshFragmentSysDataPerm
},
{
key: 'fragmentSysDataPermUser',
permCode: 'formSysDataPerm:fragmentSysDataPermUser',
refresh: this.refreshFragmentSysDataPermUser
}
];
},
onFragmentChange (fragmentId) {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.permCodeList[i].key === fragmentId) {
this.activeFragmentId = fragmentId;
// if (this.permCodeList[i].refresh) this.permCodeList[i].refresh();
return true;
}
}
return false;
},
getActiveFragment () {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.permCodeList[i].key === this.activeFragmentId) {
return this.permCodeList[i];
}
}
},
/**
* 根据权限获取默认显示的fragment
*/
getDefaultFragment () {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.checkPermCodeExist(this.permCodeList[i].permCode)) {
this.activeFragmentId = this.permCodeList[i].key;
return this.permCodeList[i];
}
}
return undefined;
},
onResume () {
this.refreshFragmentSysDataPerm();
},
initFormData () {
},
formInit () {
this.buildFragmentPermCodeMap();
let defaultFragment = this.getDefaultFragment();
if (defaultFragment == null) {
this.$message.error('您没有访问这个页面的权限,请与系统管理员联系!');
} else {
if (defaultFragment.refresh) defaultFragment.refresh();
}
}
},
computed: {
getTabPaneHeight () {
return (this.getClientHeight - 192);
},
...mapGetters(['getClientHeight'])
},
created () {
this.formInit();
}
}
</script>

View File

@@ -1,218 +0,0 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="数据权限">
<el-select class="filter-item" v-model="formDataPermUser.formFilter.dataPermId" clearable
placeholder="数据权限" :loading="formDataPermUser.dataPermId.impl.loading"
@visible-change="formDataPermUser.dataPermId.impl.onVisibleChange"
@change="onDataPermChange">
<el-option v-for="item in formDataPermUser.dataPermId.impl.dropdownList" :key="item.dataPermId"
:value="item.dataPermId" :label="item.dataPermName" />
</el-select>
</el-form-item>
<el-form-item label="用户名">
<el-input class="filter-item" v-model="formDataPermUser.formFilter.searchString"
:clearable="true" placeholder="输入用户名 / 昵称查询" @change="refreshFormDataPermUser(true)" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormDataPermUser(true)">
查询
</el-button>
<el-button slot="operator" type="primary" size="mini" @click="onAddDataPermUserClick()"
:disabled="!checkPermCodeExist('sysDataPermUserManagement:addDataPermUser') || formDataPermUser.formFilter.dataPermId == null || formDataPermUser.formFilter.dataPermId === ''">
授权用户
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formDataPermUser.SysDataPermUserList.impl.dataList" size="mini"
@sort-change="formDataPermUser.SysDataPermUserList.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="formDataPermUser.SysDataPermUserList.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型">
<template slot-scope="scope">
<span>{{SysUserType.getValue(scope.row.userType)}}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="80px">
<template slot-scope="scope">
<el-button class="btn-table-delete" type="text" size="mini" @click="onDeleteRow(scope.row)">移除</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formDataPermUser.SysDataPermUserList.impl.totalCount"
:current-page="formDataPermUser.SysDataPermUserList.impl.currentPage"
:page-size="formDataPermUser.SysDataPermUserList.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formDataPermUser.SysDataPermUserList.impl.onCurrentPageChange"
@size-change="formDataPermUser.SysDataPermUserList.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDataPermController, DictionaryController } from '@/api';
import formSetSysDataPermUser from '@/views/upms/formSetSysDataPermUser';
export default {
name: 'formDataPermUser',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formDataPermUser: {
formFilter: {
dataPermId: undefined,
searchString: undefined
},
dataPermId: {
impl: new DropdownWidget(this.loadDataPermDropdownList)
},
SysDataPermUserList: {
impl: new TableWidget(this.loadSysDataPermUserListData, this.loadSysDataPermUserListVerify, true, 'createTime', 1)
},
isInit: false
}
}
},
methods: {
onDataPermChange (value) {
this.refreshFormDataPermUser(true);
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
loadDataPermDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
SysDataPermController.list(this, params).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
/**
* 用户列表数据获取函数返回Primise
*/
loadSysDataPermUserListData (params) {
return new Promise((resolve, reject) => {
if (this.formDataPermUser.formFilter.dataPermId == null || this.formDataPermUser.formFilter.dataPermId === '') {
this.$message.error('请选择数据权限');
resolve({
dataList: [],
totalCount: 0
});
return;
}
params.dataPermId = this.formDataPermUser.formFilter.dataPermId;
params.searchString = this.formDataPermUser.formFilter.searchString;
SysDataPermController.listDataPermUser(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户列表数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysDataPermUserListVerify () {
return true;
},
onDeleteRow (row) {
this.$confirm('是否移除此用户?').then(res => {
let params = {
dataPermId: this.formDataPermUser.formFilter.dataPermId,
userId: row.userId
}
SysDataPermController.deleteDataPermUser(this, params).then(res => {
this.refreshFormDataPermUser(true);
this.$message.success('移除成功');
}).catch(e => {});
}).catch(e => {});
},
/**
* 更新数据权限授权
*/
refreshFormDataPermUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formDataPermUser.SysDataPermUserList.impl.refreshTable(true, 1);
} else {
this.formDataPermUser.SysDataPermUserList.impl.refreshTable();
}
this.formDataPermUser.isInit = true;
},
/**
* 授权用户
*/
onAddDataPermUserClick () {
let params = {
dataPermId: this.formDataPermUser.formFilter.dataPermId
};
this.$dialog.show('授权用户', formSetSysDataPermUser, {
area: ['1100px', '580px']
}, params).then(res => {
this.refreshFormDataPermUser(true);
}).catch(e => {
this.refreshFormDataPermUser(true);
});
},
onResume () {
this.refreshFormDataPermUser();
},
initFormData () {
},
formInit () {
this.initFormData();
// this.refreshFormDataPermUser();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -1,189 +0,0 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="部门名称">
<el-input class="filter-item" v-model="formSysDept.formFilter.deptName"
:clearable="true" placeholder="部门名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysDept(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:add')"
@click="onCreateSysDeptClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSysDept.SysDeptList.impl.dataList" size="mini" row-key="deptId"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px">
</el-table-column>
<el-table-column label="部门名称" prop="deptName">
</el-table-column>
<el-table-column label="所在省份" prop="cityIdDictMap.name">
</el-table-column>
<el-table-column label="所在城市" prop="provinceIdDictMap.name">
</el-table-column>
<el-table-column label="创建人" prop="createUsername">
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="150px">
<template slot-scope="scope">
<el-button @click="onEditSysDeptClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:update')">
编辑
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { treeDataTranslate } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDeptController, DictionaryController } from '@/api';
import formEditSysDept from '../formEditSysDept';
export default {
name: 'formSysDept',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysDept: {
formFilter: {
deptName: undefined
},
formFilterCopy: {
deptName: undefined
},
SysDeptList: {
impl: new TableWidget(this.loadSysDeptListData, this.loadSysDeptListVerify, false)
},
isInit: false
}
}
},
methods: {
/**
* 部门列表数据获取函数返回Primise
*/
loadSysDeptListData (params) {
params.sysDeptFilter = {
deptName: this.formSysDept.formFilterCopy.deptName
};
return new Promise((resolve, reject) => {
SysDeptController.list(this, params).then(res => {
resolve({
dataList: treeDataTranslate(res.data.dataList, 'deptId', 'parentId'),
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 部门列表数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysDeptListVerify () {
this.formSysDept.formFilterCopy.deptName = this.formSysDept.formFilter.deptName;
return true;
},
/**
* 部门列表当前页变化函数
*/
onSysDeptListCurrentPageChange (newPage) {
this.formSysDept.SysDeptList.impl.onCurrentPageChange(newPage);
},
/**
* 部门列表每页显示数量变化函数(跳转回第一页)
*/
onSysDeptListPageSizeChange (newPage) {
this.formSysDept.SysDeptList.impl.onPageSizeChange(newPage);
},
/**
* 更新部门管理
*/
refreshFormSysDept (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysDept.SysDeptList.impl.refreshTable(true, 1);
} else {
this.formSysDept.SysDeptList.impl.refreshTable();
}
this.formSysDept.isInit = true;
},
/**
* 新建
*/
onCreateSysDeptClick () {
let params = {};
this.$dialog.show('新建部门', formEditSysDept, {
area: ['500px']
}, params).then(res => {
this.refreshFormSysDept();
}).catch(e => {});
},
/**
* 编辑部门
*/
onEditSysDeptClick (row) {
let params = {
deptId: row.deptId
};
this.$dialog.show('编辑部门', formEditSysDept, {
area: ['500px']
}, params).then(res => {
this.formSysDept.SysDeptList.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
deptId: row.deptId
};
this.$confirm('是否删除部门?').then(res => {
SysDeptController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.formSysDept.SysDeptList.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormSysDept();
},
initFormData () {
},
formInit () {
this.initFormData();
this.refreshFormSysDept();
}
},
created () {
this.formInit();
}
}
</script>

19
orange-demo-service/.idea/$CACHE_FILE$ generated Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State>
<id />
</State>
</expanded-state>
<selected-state>
<State>
<id>Ali-Check</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
</project>

View File

@@ -0,0 +1,11 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="Scala">
<indentOptions>
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

45
orange-demo-service/.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="admin-monitor" />
<module name="gateway" />
<module name="common-core" />
<module name="stats-service" />
<module name="application-common" />
<module name="upms-interface" />
<module name="common-redis" />
<module name="course-class-service" />
<module name="common-sequence" />
<module name="upms-service" />
<module name="course-class-interface" />
<module name="stats-interface" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="admin-monitor" target="1.8" />
<module name="application" target="1.8" />
<module name="application-common" target="1.8" />
<module name="common" target="1.8" />
<module name="common-core" target="1.8" />
<module name="common-redis" target="1.8" />
<module name="common-sequence" target="1.8" />
<module name="course-class" target="1.8" />
<module name="course-class-interface" target="1.8" />
<module name="course-class-service" target="1.8" />
<module name="gateway" target="1.8" />
<module name="OrangeDemo" target="1.8" />
<module name="stats" target="1.8" />
<module name="stats-interface" target="1.8" />
<module name="stats-service" target="1.8" />
<module name="upms" target="1.8" />
<module name="upms-interface" target="1.8" />
<module name="upms-service" target="1.8" />
</bytecodeTargetLevel>
</component>
</project>

24
orange-demo-service/.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/admin-monitor/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/admin-monitor/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/application-common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/course-class/course-class-interface/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/course-class/course-class-service/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/course-class/course-class-service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/gateway/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/gateway/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/stats/stats-interface/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/stats/stats-service/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/stats/stats-service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/upms/upms-interface/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/upms/upms-service/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/upms/upms-service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-core/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-redis/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-redis/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-sequence/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-sequence/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@@ -0,0 +1,176 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AbstractBeanReferencesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AlibabaClassMustHaveAuthor" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="AlibabaEnumConstantsMustHaveComment" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="AlibabaMethodTooLong" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="AlibabaThreadPoolCreation" enabled="false" level="BLOCKER" enabled_by_default="false" />
<inspection_tool class="AlibabaTransactionMustHaveRollback" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="AlibabaUndefineMagicConstant" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="AsyncMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AutowiredDependenciesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BooleanMethodIsAlwaysInverted" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckDtdRefs" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CheckTagEmptyBody" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckXmlFileWithXercesValidator" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="ConstantConditions" enabled="false" level="WARNING" enabled_by_default="false">
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />
</inspection_tool>
<inspection_tool class="ContextComponentScanInconsistencyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ContextJavaBeanUnresolvedMethodsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DeprecatedClassUsageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicatedBeanNamesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicatedCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="Duplicates" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="FieldCanBeLocal" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FlowRequiredBeanTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IgnoreResultOfCall" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_reportAllNonLibraryCalls" value="false" />
<option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.math.BigInteger,.*,java.math.BigDecimal,.*,java.net.InetAddress,.*,java.net.URI,.*,java.util.List,of,java.util.Set,of,java.util.Map,of|ofEntries|entry,java.util.Collections,unmodifiable.*|singleton.*|checked.*|min|max|stream,java.util.UUID,.*,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*" />
</inspection_tool>
<inspection_tool class="InjectionValueTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
<inspection_tool class="JdkProxiedBeanTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LoopStatementsThatDontLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MVCPathVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MissingAspectjAutoproxyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantThrows" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RequiredBeanTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ScheduledMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
<inspection_tool class="SpringAopErrorsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringAopWarningsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringAutowiredFieldsWarningInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBatchModel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBeanAttributesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBeanAutowiringInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBeanConstructorArgInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBeanDepedencyCheckInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBeanInstantiationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBeanLookupMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBeanNameConventionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBootAdditionalConfig" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringBootApplicationProperties" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringCacheAnnotationsOnInterfaceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringCacheNamesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringCacheableAndCachePutInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringCacheableComponentsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringComponentScan" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringContextConfigurationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringDataMethodInconsistencyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringDataRepositoryMethodParametersInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringDataRepositoryMethodReturnTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringElInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringElStaticFieldInjectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringEventListenerInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringFacetCodeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringFacetInspection" enabled="false" level="WARNING" enabled_by_default="false">
<option name="checkTestFiles" value="false" />
</inspection_tool>
<inspection_tool class="SpringFacetProgrammaticInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringFactoryMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringHandlersSchemasHighlighting" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringInactiveProfileHighlightingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringIncorrectResourceTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringInjectionValueConsistencyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringInjectionValueStyleInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringIntegrationDeprecations21" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringIntegrationModel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringJavaAutowiredFieldsWarningInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringJavaAutowiredMembersInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringJavaAutowiringInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringJavaConfigExternalBeansErrorInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringJavaConfigInconsistencyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringJavaConstructorAutowiringInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="SpringJavaInjectionPointsAutowiringInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="SpringLookupInjectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringMVCInitBinder" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringMVCViewInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringMessageDispatcherWebXmlInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringModelInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringOsgiElementsInconsistencyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringOsgiListenerInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringOsgiServiceCommonInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringPlaceholdersInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringPublicFactoryMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringRequiredAnnotationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringRequiredPropertyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringScopesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringSecurityAnnotationBeanPointersResolveInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringSecurityDebugActivatedInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringSecurityFiltersConfiguredInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringSecurityModelInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringStaticMembersAutowiringInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringTestingDirtiesContextInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringTestingTransactionalInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringTransactionalComponentInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringWebServiceAnnotationsInconsistencyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringWebServicesConfigurationsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpringWebSocketConfigurationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringBufferReplaceableByString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryReturn" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnparsedCustomBeanInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnresolvedMessageChannel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UtilSchemaInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WebflowConfigModelInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WebflowModelInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WebflowSetupInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlDefaultAttributeValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlDuplicatedId" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlHighlighting" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlInvalidId" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlPathReference" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlUnboundNsPrefix" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlUnusedNamespaceDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlWrongRootElement" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="unused" enabled="false" level="WARNING" enabled_by_default="false">
<option name="LOCAL_VARIABLE" value="true" />
<option name="FIELD" value="true" />
<option name="METHOD" value="true" />
<option name="CLASS" value="true" />
<option name="PARAMETER" value="true" />
<option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
<option name="ADD_MAINS_TO_ENTRIES" value="true" />
<option name="ADD_APPLET_TO_ENTRIES" value="true" />
<option name="ADD_SERVLET_TO_ENTRIES" value="true" />
<option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
</inspection_tool>
</profile>
</component>

View File

@@ -0,0 +1,5 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" />
</settings>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: ch.qos.logback:logback-classic:1.2.3">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: ch.qos.logback:logback-core:1.2.3">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: cn.hutool:hutool-all:5.1.5">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.1.5/hutool-all-5.1.5.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.1.5/hutool-all-5.1.5-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/cn/hutool/hutool-all/5.1.5/hutool-all-5.1.5-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: cn.jimmyshi:bean-query:1.1.5">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/cn/jimmyshi/bean-query/1.1.5/bean-query-1.1.5.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/cn/jimmyshi/bean-query/1.1.5/bean-query-1.1.5-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/cn/jimmyshi/bean-query/1.1.5/bean-query-1.1.5-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.alibaba.cloud:spring-cloud-alibaba-sentinel-datasource:2.2.1.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-alibaba-sentinel-datasource/2.2.1.RELEASE/spring-cloud-alibaba-sentinel-datasource-2.2.1.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-alibaba-sentinel-datasource/2.2.1.RELEASE/spring-cloud-alibaba-sentinel-datasource-2.2.1.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-alibaba-sentinel-datasource/2.2.1.RELEASE/spring-cloud-alibaba-sentinel-datasource-2.2.1.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.alibaba.cloud:spring-cloud-circuitbreaker-sentinel:2.2.1.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-circuitbreaker-sentinel/2.2.1.RELEASE/spring-cloud-circuitbreaker-sentinel-2.2.1.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-circuitbreaker-sentinel/2.2.1.RELEASE/spring-cloud-circuitbreaker-sentinel-2.2.1.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-circuitbreaker-sentinel/2.2.1.RELEASE/spring-cloud-circuitbreaker-sentinel-2.2.1.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2.2.1.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-nacos-config/2.2.1.RELEASE/spring-cloud-starter-alibaba-nacos-config-2.2.1.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-nacos-config/2.2.1.RELEASE/spring-cloud-starter-alibaba-nacos-config-2.2.1.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-nacos-config/2.2.1.RELEASE/spring-cloud-starter-alibaba-nacos-config-2.2.1.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2.2.1.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-nacos-discovery/2.2.1.RELEASE/spring-cloud-starter-alibaba-nacos-discovery-2.2.1.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-nacos-discovery/2.2.1.RELEASE/spring-cloud-starter-alibaba-nacos-discovery-2.2.1.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-nacos-discovery/2.2.1.RELEASE/spring-cloud-starter-alibaba-nacos-discovery-2.2.1.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel:2.2.1.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-sentinel/2.2.1.RELEASE/spring-cloud-starter-alibaba-sentinel-2.2.1.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-sentinel/2.2.1.RELEASE/spring-cloud-starter-alibaba-sentinel-2.2.1.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/alibaba/cloud/spring-cloud-starter-alibaba-sentinel/2.2.1.RELEASE/spring-cloud-starter-alibaba-sentinel-2.2.1.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

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