commit e643ea15144c3328d36befc935b9bb23ef338c63 Author: rong.liu Date: Tue Jun 4 16:50:36 2024 +0800 initialSubmission 职站商场 diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee5b008 --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +<<<<<<< HEAD +# IASF + +粒子研究院网站 +======= +#IASF 粒子研究院网站 + +## 代码结构 +``` +├─main +│ ├─java +│ │ └─com +│ │ └─company +│ │ └─project +│ │ ├─CompanyProjectApplication.java 项目启动类 +│ │ ├─common 公共资源,如注解、切面、定时、全局异常处理、shiro集成、通用工具类等 +│ │ ├─controller Controler层 +│ │ ├─entity 实体类 +│ │ ├─mapper DAO层 +│ │ ├─service Service层 +│ │ │ └─impl Service层实现 +│ └─resources +│ ├── application-dev.yml 开发环境配置文件 +│ ├── application-test.yml 测试环境配置文件 +│ ├── application-prod.yml 生产环境配置文件 +│ ├── application.yml 通用配置文件 +│ ├── logback-spring.xml 日志配置文件 +│ └──mapper Mybatis XML文件 +└─test + └─java + └─com + └─company + └─project + ├── CompanyFrameApplicationTests.java 单元测试 +``` + +## 开发建议 +- Model内成员变量建议与表字段数量对应,如需扩展成员变量(比如连表查询)建议创建VO,否则需在扩展的成员变量上加@TableField(exist = false) +- 建议业务失败直接使用throw new BusinessException("ErrorMessage")抛出,由统一异常处理器来封装业务失败的响应结果,会直接被封装为{"code":500002,"message":"ErrorMessage"}返回,尽情抛出; +- token支持header跟query传参形式,如: + - ajax中设置header:```beforeSend: function(request) {request.setRequestHeader("authorization", "有效的token");}``` + - query:```?authorization=有效的token ``` +- 数据库基础字段:id(bigint)、remark(varchar)、unable_flag(tinyint)、deleted(tinyint)、create_id(bigint)、update_id(bigint)、create_time(datetime)、update_time(datetime) + +## 使用说明 +- 使用IDE导入本项目,IDE需要安装lombok插件 +- 下载redis 启动redis +- 创建数据库, 导入***.sql +- 配置application-dev.yml中的redis以及数据库连接 +- 运行项目 + 1. 直接运行CompanyProjectApplication.java + 2. 项目根目录下执行mvn -X clean package -Dmaven.test.skip=true编译打包,然后执行java -jar manager.jar +- 登录地址 http://localhost:8080/index/login 用户名密码:admin/123456 +- 代码生成使用 + 1. 逻辑删除字段,请统一用deleted字段: 1未删 0已删; 主键请统一格式: `id` varchar(50) 类型; 列名请勿使用数据库关键字 + 2. application.yml中配置: 使用代码生成模块时 指定要生成的表存在于哪种数据库。project.database=mysql + 3. 点击[代码生成]菜单,生成一个或多个表的代码,下载到本地 + 4. 解压下载的代码,直接复制main文件夹到本地项目的src目录下 + 5. 数据库执行sql,生成菜单 + 6. 点击[角色管理]菜单,修改角色所绑定的菜单的权限,刷新页面查看 + +- 数据权限配置及使用 示例:文章管理列表 + 1. 需要数据权限所控制的表(如sys_content), 需要有创建人字段 + 2. 配置角色的数据范围(本部门,其他部门等), 以及绑定的部门 + 3. 在列表加个注解@DataScope(用来查询当前等路人的多个角色(并集), 根据角色数据范围, 获取绑定的部门id, 查关联的用户id) + 4. 在查某个模块的list或page的时候,手动queryWrapper.in(createId, 关联的用户id) + + +## 技术文档 +* 核心框架:[Spring Boot](https://spring.io/projects/spring-boot) +* 持久层框架:[MyBatis-Plus](https://mybatis.plus) +* 分页:[Page](https://mybatis.plus/guide/page.html) +* 数据库连接池:[Alibaba Druid](https://github.com/alibaba/druid/) +* 安全框架:[Apache Shiro](http://shiro.apache.org/) +* 缓存框架:[Redis](https://redis.io/) +* 接口文档:[Knife4j](https://doc.xiaominfo.com/) +* 阿里巴巴Java开发手册[最新版下载](https://github.com/alibaba/p3c) +>>>>>>> 粒子研究院网站提交 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8f3f0a2 --- /dev/null +++ b/pom.xml @@ -0,0 +1,324 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.6.RELEASE + + + + com.huoran + iasf + 1.0.0 + IASF + jar + 粒子研究院网站 + + + 1.8 + 3.4.0 + 2.5.5 + 2.6 + 2.5 + 1.10 + 1.7 + 2.3.2 + 1.4.0 + 1.1.10 + 1.2.74 + 2.0.2 + 1.6.2 + 4.0.1 + 4.0.1 + 4.1.3 + 4.1.3 + 4.1.3 + + + + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + 2.1.0.RELEASE + pom + import + + + + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + org.apache.commons + commons-email + 1.3.3 + + + + + com.aliyun + aliyun-java-sdk-core + + + + org.springframework.boot + spring-boot-starter-cache + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-aop + + + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + + org.projectlombok + lombok + + + + com.alibaba + fastjson + ${fastjson.version} + + + + com.baomidou + dynamic-datasource-spring-boot-starter + ${mybatis-plus-dynamic.version} + + + com.baomidou + mybatis-plus + ${mybatis-plus.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.baomidou + mybatis-plus-generator + ${mybatis-plus.version} + + + mysql + mysql-connector-java + runtime + + + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j.version} + + + commons-lang + commons-lang + ${commons.lang.version} + + + commons-io + commons-io + ${commons.io.version} + + + commons-configuration + commons-configuration + ${commons.configuration.version} + + + velocity + org.apache.velocity + ${velocity.version} + + + org.quartz-scheduler + quartz + ${quartz.version} + + + com.mchange + c3p0 + + + com.zaxxer + HikariCP-java6 + + + + + com.github.whvcse + easy-captcha + ${easy-captcha.version} + + + commons-codec + commons-codec + 1.13 + + + io.jsonwebtoken + jjwt + 0.9.0 + + + + com.squareup.okhttp3 + okhttp + 3.14.9 + + + + cn.hutool + hutool-core + 5.3.6 + + + + + + + cn.afterturn + easypoi-base + ${easypoi-base.version} + + + guava + com.google.guava + + + guava + com.google.guava + + + poi-ooxml-schemas + org.apache.poi + + + + + cn.afterturn + easypoi-web + ${easypoi-web.version} + + + cn.afterturn + easypoi-annotation + ${easypoi-annotation.version} + + + + org.apache.poi + poi-ooxml + ${poi-ooxml.version} + + + org.apache.poi + poi + ${poi.version} + + + + + + iasf + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + true + + + + + + + + src/main/java + + **/*.xml + + + + src/main/resources + + **/* + + true + + + + + + + aliyun-repos + http://maven.aliyun.com/nexus/content/groups/public/ + + false + + + + + + + aliyun-plugin + http://maven.aliyun.com/nexus/content/groups/public/ + + false + + + + diff --git a/src/main/java/com/huoran/iasf/IASFApplication.java b/src/main/java/com/huoran/iasf/IASFApplication.java new file mode 100644 index 0000000..333e112 --- /dev/null +++ b/src/main/java/com/huoran/iasf/IASFApplication.java @@ -0,0 +1,32 @@ +package com.huoran.iasf; + +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +import java.net.InetAddress; + +@SpringBootApplication +@MapperScan("com.huoran.iasf.mapper") +@Slf4j +@ServletComponentScan(basePackages = {"com.huoran.iasf.common.filter"}) //这一句完成了配置,Springboot的”懒理念“真的厉害。 +public class IASFApplication { + + public static void main(String[] args) throws Exception { + ConfigurableApplicationContext application = SpringApplication.run(IASFApplication.class, args); + + Environment env = application.getEnvironment(); + log.info("\n----------------------------------------------------------\n\t" + + "Application '{}' is running! Access URLs:\n\t" + + "Doc: \thttp://{}:{}/iasf/doc.html\n" + + "----------------------------------------------------------", + env.getProperty("spring.application.name"), + InetAddress.getLocalHost().getHostAddress(), + env.getProperty("server.port")); + } + +} diff --git a/src/main/java/com/huoran/iasf/common/aop/annotation/DataScope.java b/src/main/java/com/huoran/iasf/common/aop/annotation/DataScope.java new file mode 100644 index 0000000..5b3f4d6 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/aop/annotation/DataScope.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.common.aop.annotation; + +import java.lang.annotation.*; + +/** + * LogAnnotation + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope { +} diff --git a/src/main/java/com/huoran/iasf/common/aop/annotation/LogAnnotation.java b/src/main/java/com/huoran/iasf/common/aop/annotation/LogAnnotation.java new file mode 100644 index 0000000..14eb5c0 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/aop/annotation/LogAnnotation.java @@ -0,0 +1,23 @@ +package com.huoran.iasf.common.aop.annotation; + +/** + * LogAnnotation + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +// @Target(ElementType.METHOD) +// @Retention(RetentionPolicy.RUNTIME) +// @Documented +public @interface LogAnnotation { + /** + * 模块 + */ + String title() default ""; + + /** + * 功能 + */ + String action() default ""; +} diff --git a/src/main/java/com/huoran/iasf/common/aop/annotation/NoRepeatSubmit.java b/src/main/java/com/huoran/iasf/common/aop/annotation/NoRepeatSubmit.java new file mode 100644 index 0000000..8bc1f07 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/aop/annotation/NoRepeatSubmit.java @@ -0,0 +1,17 @@ +package com.huoran.iasf.common.aop.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @Description 不重复提交注解 + */ + +@Target(ElementType.METHOD) // 作用到方法上 +@Retention(RetentionPolicy.RUNTIME) // 运行时有效 +public @interface NoRepeatSubmit { + + String name() default "name:"; +} diff --git a/src/main/java/com/huoran/iasf/common/aop/aspect/DataScopeAspect.java b/src/main/java/com/huoran/iasf/common/aop/aspect/DataScopeAspect.java new file mode 100644 index 0000000..04e21d6 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/aop/aspect/DataScopeAspect.java @@ -0,0 +1,133 @@ +package com.huoran.iasf.common.aop.aspect; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.entity.SysRole; +import com.huoran.iasf.entity.SysUser; +import com.huoran.iasf.service.HttpSessionService; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 概念:最终控制列表中显示哪些 部门/人 创建的数据 + * 1、需要数据权限控制的列表, 需要有创建人字段, 示例:文章管理 + * 2、配置角色的数据范围(本部门,其他部门等), 以及绑定的部门 + * 3、加个注解,用来查询当前等路人的多个角色(并集), 根据角色数据范围, 获取绑定的部门id, 查关联的用户id + * 4、在查某个模块的list或page的时候,手动queryWrapper.in(createId, 关联的用户id) + * + * @author cheney + */ +@Aspect +@Component +public class DataScopeAspect { + + @Resource + HttpSessionService sessionService; + @Resource + com.huoran.iasf.service.RoleService roleService; + @Resource + com.huoran.iasf.service.DeptService deptService; + @Resource + com.huoran.iasf.service.UserService userService; + + + @Pointcut("@annotation(com.huoran.iasf.common.aop.annotation.DataScope)") + public void dataScopePointCut() { + } + + @Before("dataScopePointCut()") + public void doBefore(JoinPoint point) { + handleDataScope(point); + } + + protected void handleDataScope(final JoinPoint joinPoint) { + //获取当前登陆人 + Integer id = sessionService.getCurrentUserId(); + //获取当前登陆人角色, 如果无角色, 那么不限制 + List sysRoles = roleService.getRoleInfoByUserId(id); + if (CollectionUtils.isEmpty(sysRoles) || sysRoles.size() == 0) { + return; + } + //角色未配置数据权限范围, 那么不限制 + List list = sysRoles.parallelStream().filter(one -> null != one.getDataScope()).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(list) || list.size() == 0) { + return; + } + //如果存在某角色配置了全部范围, 那么不限制 + if (list.stream().anyMatch(sysRole -> Constant.DATA_SCOPE_ALL.equals(sysRole.getDataScope()))) { + return; + } + //获取绑定的人 + List userIds = this.getUserIdsByRoles(list, id); + Object params = joinPoint.getArgs()[0]; + if (params instanceof com.huoran.iasf.entity.BaseEntity) { + com.huoran.iasf.entity.BaseEntity baseEntity = (com.huoran.iasf.entity.BaseEntity) params; + baseEntity.setCreateIds(userIds); + } + + } + + /** + * 获取最终的用户id + * + * @param sysRoles 角色 + * @param userId 当前用户id + * @return 用户id集合 + */ + private List getUserIdsByRoles(List sysRoles, Integer userId) { + //本人 + SysUser sysUser = userService.getById(userId); + //本部门 + // SysDept sysDept = deptService.getById(sysUser.getDeptId()); + //部门ids, 定义哪些部门最终拥有权限查看 + LinkedList deptList = new LinkedList<>(); + //用户ids,定义列表中哪些人创建的可查看 + LinkedList userIdList = new LinkedList<>(); + //根据数据权限范围分组, 不同的数据范围不同的逻辑处理 + /*Map> dataScopeMap = sysRoles.parallelStream().collect(Collectors.groupingBy(com.huoran.iasf.entity.SysRole::getDataScope)); + dataScopeMap.forEach((k, v) -> { + if (Constant.DATA_SCOPE_CUSTOM.equals(k)) { + //自定义 + //根据角色id,获取所有自定义关联的部门id + QueryWrapper queryWrapper = Wrappers.query().select("dept_id").in("role_id", v.parallelStream().map(com.huoran.iasf.entity.SysRole::getId).collect(Collectors.toList())); + deptList.addAll(sysRoleDeptService.listObjs(queryWrapper)); + } else if (Constant.DATA_SCOPE_DEPT_AND_CHILD.equals(k)) { + //本部门及以下 + if (sysDept != null && StringUtils.isNotBlank(sysDept.getDeptNo())) { + //获取本部门以下所有关联的部门 + QueryWrapper queryWrapper = Wrappers.query().select("id").like("relation_code", sysDept.getDeptNo()); + deptList.addAll(deptService.listObjs(queryWrapper)); + } + } else if (Constant.DATA_SCOPE_DEPT.equals(k)) { + //本部门 + if (sysDept != null && StringUtils.isNotBlank(sysDept.getId())) { + deptList.add(sysDept.getId()); + } + } else if (Constant.DATA_SCOPE_DEPT_SELF.equals(k)) { + //自己 + userIdList.add(userId); + } + });*/ + if (!CollectionUtils.isEmpty(deptList)) { + QueryWrapper queryWrapper = Wrappers.query().select("id").in("dept_id", deptList); + userIdList.addAll(userService.listObjs(queryWrapper)); + } + //如果配置了角色数据范围, 最终没有查到userId, 那么返回无数据 + if (CollectionUtils.isEmpty(userIdList)) { + throw new BusinessException(BaseResponseCode.NOT_ACCOUNT); + } + return userIdList.parallelStream().map(Object::toString).collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java b/src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java new file mode 100644 index 0000000..aa6ed45 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java @@ -0,0 +1,95 @@ +package com.huoran.iasf.common.aop.aspect; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.common.utils.R; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import lombok.Synchronized; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import java.util.concurrent.TimeUnit; + +import static com.huoran.iasf.service.HttpApiSessionService.APP_SECRET; + + +/** + * @Description aop解析注解 + */ + +@Aspect +@Component +public class NoRepeatSubmitAop { + + private Log logger = LogFactory.getLog(getClass()); + + @Autowired + private RedisServiceAop redisService; + + @Synchronized + @Around("execution(* com.huoran.*.controller.*.*(..)) && @annotation(noRepeatSubmit)") + public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable { + + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + HttpServletResponse response = attributes.getResponse(); + String token = request.getHeader(Constant.ACCESS_TOKEN); + //如果header中不存在token,则从参数中获取token + if (StringUtils.isEmpty(token)) { + token = request.getParameter(Constant.ACCESS_TOKEN); + } + if (StringUtils.isEmpty(token)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + } + // 校验并解析token,如果token过期或者篡改,则会返回null + Claims claims = checkJWT(token); + if (null == claims) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + } + String key = token + "-" + request.getServletPath(); + if ( !redisService.haskey(key) ) {// 如果缓存中有这个url视为重复提交 + Object o = pjp.proceed(); + redisService.setCacheObject(key, 0, 1, TimeUnit.SECONDS); + return o; + } else { + redisService.setCacheObject(key, 0, 1, TimeUnit.SECONDS);//点了同样的URL继续限制,直到2次点击中间间隔超过了限制 + return R.fail("请勿重复提交或者操作过于频繁!"); + } + + } + + /** + * 校验token + */ + public Claims checkJWT(String token) { + + try { + final Claims claims = Jwts.parser().setSigningKey(APP_SECRET). + parseClaimsJws(token).getBody(); + return claims; + } catch (Exception e) { + return null; + } + } + +} diff --git a/src/main/java/com/huoran/iasf/common/aop/aspect/RedisServiceAop.java b/src/main/java/com/huoran/iasf/common/aop/aspect/RedisServiceAop.java new file mode 100644 index 0000000..a4ba31c --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/aop/aspect/RedisServiceAop.java @@ -0,0 +1,228 @@ +package com.huoran.iasf.common.aop.aspect; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @Description RedisService + */ +@Component +@SuppressWarnings(value = {"unchecked", "rawtypes"}) +public class RedisServiceAop { + + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @return 缓存的对象 + */ + public ValueOperations setCacheObject(String key, T value) { + ValueOperations operation = redisTemplate.opsForValue(); + operation.set(key, value); + return operation; + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + * @return 缓存的对象 + */ + public ValueOperations setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) { + ValueOperations operation = redisTemplate.opsForValue(); + operation.set(key, value, timeout, timeUnit); + return operation; + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(String key) { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public void deleteObject(String key) { + redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection + */ + public void deleteObject(Collection collection) { + redisTemplate.delete(collection); + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public ListOperations setCacheList(String key, List dataList) { + ListOperations listOperation = redisTemplate.opsForList(); + if (null != dataList) { + int size = dataList.size(); + for (int i = 0; i < size; i++) { + listOperation.leftPush(key, dataList.get(i)); + } + } + return listOperation; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(String key) { + List dataList = new ArrayList(); + ListOperations listOperation = redisTemplate.opsForList(); + Long size = listOperation.size(key); + + for (int i = 0; i < size; i++) { + dataList.add(listOperation.index(key, i)); + } + return dataList; + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(String key, Set dataSet) { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(String key) { + Set dataSet = new HashSet(); + BoundSetOperations operation = redisTemplate.boundSetOps(key); + dataSet = operation.members(); + return dataSet; + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + * @return + */ + public HashOperations setCacheMap(String key, Map dataMap) { + HashOperations hashOperations = redisTemplate.opsForHash(); + if (null != dataMap) { + for (Map.Entry entry : dataMap.entrySet()) { + hashOperations.put(key, entry.getKey(), entry.getValue()); + } + } + return hashOperations; + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(String key) { + Map map = redisTemplate.opsForHash().entries(key); + return map; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(String pattern) { + return redisTemplate.keys(pattern); + } + + /** + * + * @param key + * @return + */ + public boolean haskey(String key){ + return redisTemplate.hasKey(key); + } + + public Long getExpire(String key){ + return redisTemplate.getExpire(key); + } + + + public ValueOperations setBillObject(String key, List> value) { + ValueOperations operation = redisTemplate.opsForValue(); + operation.set(key, (T) value); + return operation; + } + /** + * 缓存list> + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + * @return 缓存的对象 + */ + public ValueOperations setBillObject(String key, List> value, Integer timeout, TimeUnit timeUnit) { + ValueOperations operation = redisTemplate.opsForValue(); + operation.set(key,(T)value, timeout, timeUnit); + return operation; + } + /** + * 缓存Map + * + * @param key + * @param dataMap + * @return + */ + public HashOperations setCKdBillMap(String key, Map dataMap) { + HashOperations hashOperations = redisTemplate.opsForHash(); + if (null != dataMap) { + for (Map.Entry entry : dataMap.entrySet()) { + hashOperations.put(key, entry.getKey(), entry.getValue()); + } + } + return hashOperations; + } +} diff --git a/src/main/java/com/huoran/iasf/common/aop/aspect/SysLogAspect.java b/src/main/java/com/huoran/iasf/common/aop/aspect/SysLogAspect.java new file mode 100644 index 0000000..14d8cbb --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/aop/aspect/SysLogAspect.java @@ -0,0 +1,116 @@ +package com.huoran.iasf.common.aop.aspect; + +import com.alibaba.fastjson.JSON; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.utils.HttpContextUtils; +import com.huoran.iasf.common.utils.IPUtils; +import com.huoran.iasf.entity.SysLog; +import com.huoran.iasf.mapper.SysLogMapper; +import com.huoran.iasf.service.HttpSessionService; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.context.annotation.Lazy; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * 日志切面 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +// @Aspect +// @Component +@Slf4j +public class SysLogAspect { + @Lazy + @Resource + private SysLogMapper sysLogMapper; + + @Lazy + @Resource + private HttpSessionService httpSessionService; + + /** + * 此处的切点是注解的方式 + * 只要出现 @LogAnnotation注解都会进入 + */ + @Pointcut("@annotation(com.huoran.iasf.common.aop.annotation.LogAnnotation)") + public void logPointCut() { + + } + + /** + * 环绕增强,相当于MethodInterceptor + */ + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + //执行方法 + Object result = point.proceed(); + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + + //保存日志 + try { + saveSysLog(point, time); + } catch (Exception e) { + log.error("sysLog,exception:{}", e, e); + } + + return result; + } + + /** + * 把日志保存 + */ + private void saveSysLog(ProceedingJoinPoint joinPoint, long time) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + SysLog sysLog = new SysLog(); + LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class); + if (logAnnotation != null) { + //注解上的描述 + sysLog.setOperation(logAnnotation.title() + "-" + logAnnotation.action()); + } + + //请求的方法名 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = signature.getName(); + sysLog.setMethod(className + "." + methodName + "()"); + log.info("请求{}.{}耗时{}毫秒", className, methodName, time); + try { + //请求的参数 + Object[] args = joinPoint.getArgs(); + String params = null; + if (args.length != 0) { + params = JSON.toJSONString(args); + } + + sysLog.setParams(params); + } catch (Exception e) { + log.error("sysLog,exception:{}", e, e); + } + //获取request + HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); + //设置IP地址 + sysLog.setIp(IPUtils.getIpAddr(request)); + log.info("Ip{},接口地址{},请求方式{},入参:{}", sysLog.getIp(), request.getRequestURL(), request.getMethod(), sysLog.getParams()); + //用户名 + Integer userId = httpSessionService.getCurrentUserId(); + String username = httpSessionService.getCurrentUsername(); + sysLog.setUsername(username); + sysLog.setUserId(userId.toString()); + sysLog.setTime((int) time); + log.info(sysLog.toString()); + sysLogMapper.insert(sysLog); + + } +} diff --git a/src/main/java/com/huoran/iasf/common/config/FileUploadProperties.java b/src/main/java/com/huoran/iasf/common/config/FileUploadProperties.java new file mode 100644 index 0000000..c128439 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/FileUploadProperties.java @@ -0,0 +1,59 @@ +package com.huoran.iasf.common.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +/** + * 文件上传参数配置类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Component +@ConfigurationProperties(prefix = "file") +public class FileUploadProperties { + + private String path; + private String ip; + private String url; + private String accessUrl; + + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + + //set accessUrl + if (StringUtils.isEmpty(url)) { + this.accessUrl = null; + } + this.accessUrl = url.substring(url.lastIndexOf("/")) + "/**"; + System.out.println("accessUrl=" + accessUrl); + } + + public String getAccessUrl() { + return accessUrl; + } + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/config/MetaObjectHandlerConfig.java b/src/main/java/com/huoran/iasf/common/config/MetaObjectHandlerConfig.java new file mode 100644 index 0000000..cf45de5 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/MetaObjectHandlerConfig.java @@ -0,0 +1,85 @@ +package com.huoran.iasf.common.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.service.HttpSessionService; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; + + +/** + * mybatis plus 默认值配置 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Component +public class MetaObjectHandlerConfig implements MetaObjectHandler { + + @Lazy + @Resource + HttpSessionService httpSessionService; + + @Override + public void insertFill(MetaObject metaObject) { + Date currentDate = new Date(); + String[] setterNames = metaObject.getSetterNames(); + HashSet setterNameSet = new HashSet<>(Arrays.asList(setterNames)); + if (setterNameSet.contains("deleted")) { + //默认未删除 + setFieldValByName("deleted", Constant.DATA_NOT_DELETED, metaObject); + } + if (setterNameSet.contains("createTime")) { + //创建时间默认当前时间 + setFieldValByName("createTime", currentDate, metaObject); + } + if (setterNameSet.contains("createDate")) { + //创建时间默认当前时间 + setFieldValByName("createDate", currentDate, metaObject); + } +// if (setterNameSet.contains("createId")) { +// //创建时间默认当前时间 +// setFieldValByName("createId", httpSessionService.getCurrentUserId(), metaObject); +// } +// if (setterNameSet.contains("updateId")) { +// //创建时间默认当前时间 +// setFieldValByName("updateId", httpSessionService.getCurrentUserId(), metaObject); +// } + if (setterNameSet.contains("updateTime")) { + //创建时间默认当前时间 + setFieldValByName("updateTime", currentDate, metaObject); + } + if (setterNameSet.contains("updateDate")) { + //创建时间默认当前时间 + setFieldValByName("updateDate", currentDate, metaObject); + } + + + } + + @Override + public void updateFill(MetaObject metaObject) { + Date currentDate = new Date(); + String[] setterNames = metaObject.getSetterNames(); + HashSet setterNameSet = new HashSet<>(Arrays.asList(setterNames)); + if (setterNameSet.contains("updateTime")) { + //创建时间默认当前时间 + setFieldValByName("updateTime", currentDate, metaObject); + } + if (setterNameSet.contains("updateDate")) { + //创建时间默认当前时间 + setFieldValByName("updateDate", currentDate, metaObject); + } +// if (setterNameSet.contains("updateId")) { +// //创建时间默认当前时间 +// setFieldValByName("updateId", httpSessionService.getCurrentUserId(), metaObject); +// } + } +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/config/MyBatisPlusConfig.java b/src/main/java/com/huoran/iasf/common/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..8ee5f4b --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/MyBatisPlusConfig.java @@ -0,0 +1,25 @@ +package com.huoran.iasf.common.config; + +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mybatis plus config + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Configuration +public class MyBatisPlusConfig { + /** + * 配置mybatis-plus 分页查件 + */ + @Bean + public PaginationInterceptor paginationInterceptor() { + PaginationInterceptor page = new PaginationInterceptor(); + page.setDialectType("mysql"); + return page; + } +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/config/MyCacheConfig.java b/src/main/java/com/huoran/iasf/common/config/MyCacheConfig.java new file mode 100644 index 0000000..42a0ce8 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/MyCacheConfig.java @@ -0,0 +1,48 @@ +package com.huoran.iasf.common.config; + +import org.springframework.boot.autoconfigure.cache.CacheProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * @Author chen + * @DATE 2021/12/28 10:42 + * @Version 1.0 + */ +@EnableConfigurationProperties(CacheProperties.class) +@Configuration +@EnableCaching +public class MyCacheConfig { + + @Bean + RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){ + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); + //修改缓存key、value的序列化机制,返回json数据格式 + config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); + config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); + //读取redis配置文件 + CacheProperties.Redis redisProperties = cacheProperties.getRedis(); + if (redisProperties.getTimeToLive() != null) { + config = config.entryTtl(redisProperties.getTimeToLive()); + } + + if (redisProperties.getKeyPrefix() != null) { + config = config.prefixKeysWith(redisProperties.getKeyPrefix()); + } + + if (!redisProperties.isCacheNullValues()) { + config = config.disableCachingNullValues(); + } + + if (!redisProperties.isUseKeyPrefix()) { + config = config.disableKeyPrefix(); + } + return config; + } +} diff --git a/src/main/java/com/huoran/iasf/common/config/MyThreadConfig.java b/src/main/java/com/huoran/iasf/common/config/MyThreadConfig.java new file mode 100644 index 0000000..a68425b --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/MyThreadConfig.java @@ -0,0 +1,29 @@ +package com.huoran.iasf.common.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * @Author chen + * @DATE 2021/12/28 17:48 + * @Version 1.0 + */ +@Configuration +public class MyThreadConfig { + + @Bean + public ThreadPoolExecutor threadPoolExecutor(){ + return new ThreadPoolExecutor(20, + 300, + 10, + TimeUnit.SECONDS, + new LinkedBlockingDeque<>(), + Executors.defaultThreadFactory(), + new ThreadPoolExecutor.AbortPolicy()); + } +} diff --git a/src/main/java/com/huoran/iasf/common/config/NonStaticResourceHttpRequestConfig.java b/src/main/java/com/huoran/iasf/common/config/NonStaticResourceHttpRequestConfig.java new file mode 100644 index 0000000..aeca4ee --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/NonStaticResourceHttpRequestConfig.java @@ -0,0 +1,22 @@ +package com.huoran.iasf.common.config; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; + +import javax.servlet.http.HttpServletRequest; +import java.nio.file.Path; + +@Component +public class NonStaticResourceHttpRequestConfig extends ResourceHttpRequestHandler { + + public final static String ATTR_FILE = "NON-STATIC-FILE"; + + @Override + protected Resource getResource(HttpServletRequest request) { + final Path filePath = (Path) request.getAttribute(ATTR_FILE); + return new FileSystemResource(filePath); + } + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/config/SwaggerConfiguration.java b/src/main/java/com/huoran/iasf/common/config/SwaggerConfiguration.java new file mode 100644 index 0000000..42345a9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/SwaggerConfiguration.java @@ -0,0 +1,48 @@ +package com.huoran.iasf.common.config; + +import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + + +/** + * SwaggerConfiguration + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Configuration +@EnableSwagger2 +@EnableKnife4j +@Import(BeanValidatorPluginsConfiguration.class) +public class SwaggerConfiguration { + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage("com.huoran.iasf.controller")) + .paths(PathSelectors.any()) + .build(); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("IASF APIs") + .description("粒子研究院 APIs") + .termsOfServiceUrl("http://localhost:10000/") + .version("V1.0") + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/config/WebMvcConfigurer.java b/src/main/java/com/huoran/iasf/common/config/WebMvcConfigurer.java new file mode 100644 index 0000000..a5e4615 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/config/WebMvcConfigurer.java @@ -0,0 +1,160 @@ +package com.huoran.iasf.common.config; + +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.serializer.ToStringSerializer; +import com.alibaba.fastjson.serializer.ValueFilter; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.ResourceHttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; + +import javax.annotation.Resource; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * spring mvc 配置 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Configuration +@EnableConfigurationProperties(FileUploadProperties.class) +public class WebMvcConfigurer extends WebMvcConfigurationSupport { + + @Resource + private FileUploadProperties fileUploadProperties; + + + private CorsConfiguration buildConfig() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.addAllowedHeader("*"); // 允许任何头 + corsConfiguration.addAllowedOrigin("*"); // 允许任何头 + corsConfiguration.addAllowedMethod("*"); // 允许任何方法(post、get等) + return corsConfiguration; + } + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", buildConfig()); // 对接口配置跨域设置 + return new CorsFilter(source); + } + + + /** + * 使用阿里 FastJson 作为JSON MessageConverter + */ + @Override + public void configureMessageConverters(List> converters) { + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));// @ResponseBody 解决乱码 + converters.add(new ResourceHttpMessageConverter()); + converters.add(new AllEncompassingFormHttpMessageConverter()); + converters.add(fastJsonHttpMessageConverter()); + } + + @Bean + public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() { + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + FastJsonConfig config = new FastJsonConfig(); + //Long类型转String类型 + SerializeConfig serializeConfig = SerializeConfig.globalInstance; + // ToStringSerializer 是这个包 com.alibaba.fastjson.serializer.ToStringSerializer + serializeConfig.put(BigInteger.class, ToStringSerializer.instance); + serializeConfig.put(Long.class, ToStringSerializer.instance); + serializeConfig.put(Long.TYPE, ToStringSerializer.instance); + config.setSerializeConfig(serializeConfig); + config.setSerializerFeatures( + SerializerFeature.WriteMapNullValue, // 保留map空的字段 + SerializerFeature.WriteNullStringAsEmpty, // 将String类型的null转成"" + SerializerFeature.WriteNullNumberAsZero, // 将Number类型的null转成0 + SerializerFeature.WriteNullListAsEmpty, // 将List类型的null转成[] + SerializerFeature.WriteNullBooleanAsFalse, // 将Boolean类型的null转成false + SerializerFeature.WriteDateUseDateFormat, //日期格式转换 + SerializerFeature.DisableCircularReferenceDetect // 避免循环引用 + ); + config.setSerializeFilters(valueFilter); + converter.setFastJsonConfig(config); + converter.setDefaultCharset(StandardCharsets.UTF_8); + // 解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json" + List mediaTypeList = new ArrayList<>(); + mediaTypeList.add(MediaType.APPLICATION_JSON); + converter.setSupportedMediaTypes(mediaTypeList); + return converter; + } + + + /** + * FastJson过滤器将null值转换为字符串 + * obj 是class + * s 是key值 + * o1 是value值 + */ + public static final ValueFilter valueFilter = (obj, s, v) -> { + if (v == null) { + return ""; + } + return v; + }; + + /** + * 页面跨域访问Controller过滤 + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + WebMvcConfigurer.super.addCorsMappings(registry); + registry.addMapping("/**") + .allowedHeaders("*") + .allowCredentials(true) + .allowedMethods("*") + .allowedOrigins("*"); + } + + + /** + * 发现如果继承了WebMvcConfigurationSupport,则在yml中配置的相关内容会失效。 需要重新指定静态资源 + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/**").addResourceLocations( + "classpath:/static/"); + registry.addResourceHandler("doc.html").addResourceLocations( + "classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations( + "classpath:/META-INF/resources/webjars/"); + registry.addResourceHandler(fileUploadProperties.getAccessUrl()) + .addResourceLocations("file:" + fileUploadProperties.getPath()); + } + + + /** + * 配置servlet处理 + */ + @Override + public void configureDefaultServletHandling( + DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + +} + diff --git a/src/main/java/com/huoran/iasf/common/exception/BusinessException.java b/src/main/java/com/huoran/iasf/common/exception/BusinessException.java new file mode 100644 index 0000000..1b62c57 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/exception/BusinessException.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.common.exception; + +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * BusinessException + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class BusinessException extends RuntimeException { + private BaseResponseCode baseResponseCode; +} diff --git a/src/main/java/com/huoran/iasf/common/exception/NotFoundException.java b/src/main/java/com/huoran/iasf/common/exception/NotFoundException.java new file mode 100644 index 0000000..84c2ebd --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/exception/NotFoundException.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.common.exception; + +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * BusinessException + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class NotFoundException extends RuntimeException { + private BaseResponseCode baseResponseCode; +} diff --git a/src/main/java/com/huoran/iasf/common/exception/UnauthorizedException.java b/src/main/java/com/huoran/iasf/common/exception/UnauthorizedException.java new file mode 100644 index 0000000..50d03a4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/exception/UnauthorizedException.java @@ -0,0 +1,13 @@ +package com.huoran.iasf.common.exception; + +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class UnauthorizedException extends RuntimeException { + private BaseResponseCode baseResponseCode; +} diff --git a/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java b/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java new file mode 100644 index 0000000..b41faea --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java @@ -0,0 +1,69 @@ +package com.huoran.iasf.common.exception.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * 错误码 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Getter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public enum BaseResponseCode implements ResponseCodeInterface { + /** + * 错误码 + */ + USERNAME_EXISTS(10008, "用户名已存在!"), + KEY_OR_TOMEUNIT(10009, "key or TomeUnit 不能为空!"), + DICTIONARY_DATA_FAILED(10010, "获取字典数据失败"), + UPLOAD_EMPTY(10011, "上传内容为空"), + UPLOAD_FAILED(10012, "上传失败"), + VERIFICATION_CODE_ERROR(10007, "验证码错误!"), + VERIFICATION_CODE_EXPIRED(10006, "验证码已过期!"), + CANNOT_SAME(10005, "新密码不能与旧密码相同!"), + EXCEL_FILE_INVALID(10004, "上传excel文件错误!"), + VALID_EXCEPTION(10003, "参数格式校验异常!"), + OPERATION_ERROR(10002, "操作失败"), + SYSTEM_BUSY(500, "系统繁忙,请稍候再试"), + SUCCESS(200, "success"), + + EXCEL_FILE_FORMAT_ERROR(40007, "请根据模板使用说明录入正确的用户信息!"), + TOKEN_ERROR(401, "登录凭证已过期,请重新登录"), + DATA_ERROR(401003, "传入数据异常"), + NOT_ACCOUNT(401004, "该用户不存在,请先注册"), + USER_LOCK(401005, "该用户已被锁定,请联系运营人员"), + PASSWORD_ERROR(401006, "用户名或密码错误"), + METHOD_ARGUMENT_NOT_VALID_EXCEPTION(400, "请求参数有误"), + UNAUTHORIZED_ERROR(401008, "权鉴校验不通过"), + ROLE_PERMISSION_RELATION(401009, "该菜单权限存在子集关联,不允许删除"), + OLD_PASSWORD_ERROR(401010, "旧密码不正确"), + NOT_PERMISSION_DELETED_DEPT(401011, "该组织机构下还关联着用户,不允许删除"), + DELETE_SUB_DEPARTMENTS_FIRST(401018, "请先删除子级部门!"), + OPERATION_MENU_PERMISSION_CATALOG_ERROR(401012, "操作后的菜单类型是目录,所属菜单必须为默认顶级菜单或者目录"), + OPERATION_MENU_PERMISSION_MENU_ERROR(401013, "操作后的菜单类型是菜单,所属菜单必须为目录类型"), + OPERATION_MENU_PERMISSION_BTN_ERROR(401013, "操作后的菜单类型是按钮,所属菜单必须为菜单类型"), + OPERATION_MENU_PERMISSION_URL_NOT_NULL(401015, "菜单权限的url不能为空"), + OPERATION_MENU_PERMISSION_URL_PERMS_NULL(401016, "菜单权限的标识符不能为空"), + ROLE_ERROR(401017, "账号角色被删,请联系管理员添加角色后再试"), + EXCEL_FILE_NULL(40006, "导入失败,导入数据为空!"), + + DATA_DOES_NOT_EXIST(500, "当前数据不存在"), + ; + + /** + * 错误码 + */ + private int code; + /** + * 错误消息 + */ + private String msg; + +} diff --git a/src/main/java/com/huoran/iasf/common/exception/code/ResponseCodeInterface.java b/src/main/java/com/huoran/iasf/common/exception/code/ResponseCodeInterface.java new file mode 100644 index 0000000..b1b18cb --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/exception/code/ResponseCodeInterface.java @@ -0,0 +1,24 @@ +package com.huoran.iasf.common.exception.code; + +/** + * ResponseCodeInterface + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface ResponseCodeInterface { + /** + * 获取code + * + * @return code + */ + int getCode(); + + /** + * 获取信息 + * + * @return msg + */ + String getMsg(); +} diff --git a/src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java b/src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java new file mode 100644 index 0000000..d7e437b --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java @@ -0,0 +1,145 @@ +package com.huoran.iasf.common.exception.handler; + +import com.google.common.collect.Maps; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.NotFoundException; +import com.huoran.iasf.common.exception.UnauthorizedException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.R; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authz.AuthorizationException; +import org.springframework.http.HttpStatus; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.ValidationException; +import java.util.HashMap; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +/** + * RestExceptionHandler + * 全局异常拦截器 + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Slf4j +@RestControllerAdvice +public class RestExceptionHandler { + + /** + * 系统繁忙,请稍候再试" + */ + @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public R handleException(Exception e) { + log.error("Exception,exception:{}", e, e); + return R.getResult(BaseResponseCode.SYSTEM_BUSY); + } + + @ExceptionHandler(IllegalArgumentException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R illegalArgumentException(IllegalArgumentException e) { + log.error("Exception,exception:{}", e, e); + return R.getResult(BaseResponseCode.METHOD_ARGUMENT_NOT_VALID_EXCEPTION); + } + + @ExceptionHandler(AuthenticationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public R authenticationException(AuthenticationException e) { + log.error("Exception,exception:{}", e, e); +// throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + return new R(BaseResponseCode.TOKEN_ERROR.getCode(), BaseResponseCode.TOKEN_ERROR.getMsg()); + } + + /** + * 自定义全局异常处理 + */ + @ExceptionHandler(value = BusinessException.class) + @ResponseStatus(HttpStatus.OK) + public R businessExceptionHandler(BusinessException e) { + log.error("Exception,exception:{}", e, e); + BaseResponseCode em = e.getBaseResponseCode(); + return new R(em.getCode(), em.getMsg()); + } + + /** + * 权限全局异常处理 + */ + @ExceptionHandler(value = UnauthorizedException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public R businessExceptionHandler(UnauthorizedException e) { + log.error("Exception,exception:{}", e, e); + BaseResponseCode em = e.getBaseResponseCode(); + return new R(em.getCode(), em.getMsg()); + } + + @ExceptionHandler(value = NotFoundException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public R businessExceptionHandler(NotFoundException e) { + log.error("Exception,exception:{}", e, e); + BaseResponseCode em = e.getBaseResponseCode(); + return new R(em.getCode(), em.getMsg()); + } + + /** + * 没有权限 返回403视图 + */ + @ExceptionHandler(value = AuthorizationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public R errorPermission(AuthorizationException e) { + log.error("Exception,exception:{}", e, e); + return new R(BaseResponseCode.UNAUTHORIZED_ERROR); + + } + + /** + * 处理参数格式校验异常 + */ + @ExceptionHandler(value = MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) + public R handleValidException(MethodArgumentNotValidException e){ + log.error("参数格式校验异常"); + BindingResult bindingResult = e.getBindingResult(); + HashMap errorMap = Maps.newHashMap(); + AtomicReference errorMsg = new AtomicReference<>(""); + bindingResult.getFieldErrors().forEach(fieldError -> { + errorMsg.set(fieldError.getDefaultMessage()); + errorMap.put(fieldError.getField(),fieldError.getDefaultMessage()); + }); + return R.fail(errorMsg); + } + + /** + * 校验List类型, 需要controller添加@Validated注解 + * 处理Validated List 异常 + */ + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handle(ConstraintViolationException exception) { + log.error("methodArgumentNotValidExceptionHandler bindingResult.allErrors():{},exception:{}", exception, exception); + Set> violations = exception.getConstraintViolations(); + StringBuilder builder = new StringBuilder(); + for (ConstraintViolation violation : violations) { + builder.append(violation.getMessage()); + break; + } + return R.getResult(BaseResponseCode.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getCode(), builder.toString()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public R handle(ValidationException e) { + log.error("Exception,exception:{}", e, e); + return new R(404, e.getMessage()); + } + +} diff --git a/src/main/java/com/huoran/iasf/common/filter/AuthFilter.java b/src/main/java/com/huoran/iasf/common/filter/AuthFilter.java new file mode 100644 index 0000000..78795f4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/filter/AuthFilter.java @@ -0,0 +1,110 @@ +package com.huoran.iasf.common.filter; + + +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.UnauthorizedException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.Constant; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.apache.shiro.subject.Subject; +import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; + +import static com.huoran.iasf.service.HttpApiSessionService.*; + +/** + * shiro过滤器 登录用户权限认证授权 + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Slf4j +@WebFilter(filterName = "tokenFilter", urlPatterns = "/**") +@Order(1) +//@Component +public class AuthFilter implements Filter { + /** + * 白名单 + */ + private static final String[] whiteList = + {"/iasf/sys/user/login", + "/iasf/sys/exportFailure","/iasf/sys/getVerify","/iasf/doc.html"}; + + //需要拦截的地址,验证token是否存在及有效 + @Override + @SneakyThrows + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + //每一次的请求先校验cookie + + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin")); + resp.setHeader("Access-Control-Allow-Methods", req.getMethod()); + resp.setHeader("Access-Control-Max-Age", "3600"); + resp.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers")); + String url = req.getRequestURI(); + log.info("url:{}", url); + + if (Arrays.asList(whiteList).contains(url)) { + chain.doFilter(request, response); + } else { + //拦截接口 + //从header中获取token + String token = req.getHeader("token"); + //如果header中不存在token,则从参数中获取token + if (StringUtils.isBlank(token)) { + token = request.getParameter("token"); + } + //token为空返回 + if (StringUtils.isBlank(token)) { + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + resp.setCharacterEncoding("utf-8"); + resp.setContentType(MediaType.APPLICATION_JSON_VALUE); + request.setAttribute("filterError", new UnauthorizedException(BaseResponseCode.TOKEN_ERROR)); + // 指定处理该请求的处理器 + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, resp); + } + // 校验并解析token,如果token过期或者篡改,则会返回null + Claims claims = checkJWT(token); + if (null == claims) { + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + resp.setCharacterEncoding("utf-8"); + resp.setContentType(MediaType.APPLICATION_JSON_VALUE); + request.setAttribute("filterError", new UnauthorizedException(BaseResponseCode.TOKEN_ERROR)); + // 指定处理该请求的处理器 + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, resp); + }else { + // 校验通过后,设置用户信息到request里,在Controller中从Request域中获取用户信息 + request.setAttribute(USER_ID_KEY, claims.get(USER_ID_KEY)); + request.setAttribute(USER_USERNAME_KEY, claims.get(USER_USERNAME_KEY)); + } + chain.doFilter(request, response); + } + + } + + /** + * 校验token + */ + public Claims checkJWT(String token) { + + try { + final Claims claims = Jwts.parser().setSigningKey(APP_SECRET). + parseClaimsJws(token).getBody(); + return claims; + } catch (Exception e) { + return null; + } + } + +} diff --git a/src/main/java/com/huoran/iasf/common/job/task/TestTask.java b/src/main/java/com/huoran/iasf/common/job/task/TestTask.java new file mode 100644 index 0000000..893bab2 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/job/task/TestTask.java @@ -0,0 +1,21 @@ +package com.huoran.iasf.common.job.task; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 测试定时任务(演示Demo,可删除) + * testTask为spring bean的名称, 方法名称必须是run + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +// @Component("testTask") +public class TestTask { + private Logger logger = LoggerFactory.getLogger(getClass()); + + public void run(String params){ + logger.debug("TestTask定时任务正在执行,参数为:{}", params); + } +} diff --git a/src/main/java/com/huoran/iasf/common/job/utils/ScheduleJob.java b/src/main/java/com/huoran/iasf/common/job/utils/ScheduleJob.java new file mode 100644 index 0000000..e533785 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/job/utils/ScheduleJob.java @@ -0,0 +1,117 @@ +/* +package com.huoran.iasf.common.job.utils; + +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.common.utils.SpringContextUtils; +import com.huoran.iasf.entity.SysJobEntity; +import com.huoran.iasf.entity.SysJobLogEntity; +import com.huoran.iasf.service.SysJobLogService; +import org.apache.commons.lang.StringUtils; +import org.quartz.JobExecutionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import java.lang.reflect.Method; + + +*/ +/** + * 定时任务 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +public class ScheduleJob extends QuartzJobBean { + private Logger logger = LoggerFactory.getLogger(getClass()); + + final SysJobLogService sysJobLogService; + + public ScheduleJob(SysJobLogService sysJobLogService) { + this.sysJobLogService = sysJobLogService; + } + + + @Override + protected void executeInternal(JobExecutionContext context) { + SysJobEntity scheduleJob = (SysJobEntity) context.getMergedJobDataMap() + .get(SysJobEntity.JOB_PARAM_KEY); + + //获取spring bean + SysJobLogService scheduleJobLogService = (SysJobLogService) SpringContextUtils.getBean("sysJobLogService"); + + //数据库保存执行记录 + SysJobLogEntity log = new SysJobLogEntity(); + log.setJobId(scheduleJob.getId()); + log.setBeanName(scheduleJob.getBeanName()); + log.setParams(scheduleJob.getParams()); + + //任务开始时间 + long startTime = System.currentTimeMillis(); + + try { + //执行任务 + logger.debug("任务准备执行,任务ID:" + scheduleJob.getId()); + + Object target = SpringContextUtils.getBean(scheduleJob.getBeanName()); + assert target != null; + Method method = target.getClass().getDeclaredMethod("run", String.class); + method.invoke(target, scheduleJob.getParams()); + + //任务执行总时长 + long times = System.currentTimeMillis() - startTime; + log.setTimes((int) times); + //任务状态 0:成功 1:失败 + log.setStatus(0); + + logger.debug("任务执行完毕,任务ID:" + scheduleJob.getId() + " 总共耗时:" + times + "毫秒"); + } catch (Exception e) { + logger.error("任务执行失败,任务ID:" + scheduleJob.getId(), e); + + //任务执行总时长 + long times = System.currentTimeMillis() - startTime; + log.setTimes((int) times); + + //任务状态 0:成功 1:失败 + log.setStatus(1); + log.setError(StringUtils.substring(e.toString(), 0, 2000)); + } finally { + assert scheduleJobLogService != null; + scheduleJobLogService.save(log); + } + } + + */ +/** + * 判断bean是否有效 + * + * @param beanName beanName + * @return 返回信息 + *//* + + public static R judgeBean(String beanName) { + + if (org.springframework.util.StringUtils.isEmpty(beanName)) { + return R.fail("spring bean名称不能为空"); + } + + Object target = SpringContextUtils.getBean(beanName); + if (target == null) { + return R.fail("spring bean不存在,请检查"); + } + Method method; + try { + method = target.getClass().getDeclaredMethod("run", String.class); + } catch (Exception e) { + return R.fail("spring bean中的run方法不存在,请检查"); + } + if (method == null) { + return R.fail("spring bean中的run方法不存在,请检查"); + } + + return R.success(); + } +} +*/ diff --git a/src/main/java/com/huoran/iasf/common/job/utils/ScheduleUtils.java b/src/main/java/com/huoran/iasf/common/job/utils/ScheduleUtils.java new file mode 100644 index 0000000..646d56c --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/job/utils/ScheduleUtils.java @@ -0,0 +1,172 @@ +/* +package com.huoran.iasf.common.job.utils; + +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.entity.SysJobEntity; +import org.quartz.*; + +*/ +/** + * 定时任务工具类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +public class ScheduleUtils { + private final static String JOB_NAME = "TASK_"; + + */ +/** + * 获取触发器key + *//* + + public static TriggerKey getTriggerKey(String jobId) { + return TriggerKey.triggerKey(JOB_NAME + jobId); + } + + */ +/** + * 获取jobKey + *//* + + public static JobKey getJobKey(String jobId) { + return JobKey.jobKey(JOB_NAME + jobId); + } + + */ +/** + * 获取表达式触发器 + *//* + + public static CronTrigger getCronTrigger(Scheduler scheduler, String jobId) { + try { + return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId)); + } catch (SchedulerException e) { + throw new BusinessException("获取定时任务CronTrigger出现异常"); + } + } + + */ +/** + * 创建定时任务 + *//* + + public static void createScheduleJob(Scheduler scheduler, SysJobEntity scheduleJob) { + try { + //构建job信息 + JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getId())).build(); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + //按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getId())).withSchedule(scheduleBuilder).build(); + + //放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(SysJobEntity.JOB_PARAM_KEY, scheduleJob); + + scheduler.scheduleJob(jobDetail, trigger); + + //暂停任务 + if (Constant.SCHEDULER_STATUS_PAUSE.equals(scheduleJob.getStatus())) { + pauseJob(scheduler, scheduleJob.getId()); + } + } catch (SchedulerException e) { + throw new BusinessException("创建定时任务失败"); + } + } + + */ +/** + * 更新定时任务 + *//* + + public static void updateScheduleJob(Scheduler scheduler, SysJobEntity scheduleJob) { + try { + TriggerKey triggerKey = getTriggerKey(scheduleJob.getId()); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getId()); + + //按新的cronExpression表达式重新构建trigger + trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); + + //参数 + trigger.getJobDataMap().put(SysJobEntity.JOB_PARAM_KEY, scheduleJob); + + scheduler.rescheduleJob(triggerKey, trigger); + + //暂停任务 + if (Constant.SCHEDULER_STATUS_PAUSE.equals(scheduleJob.getStatus())) { + pauseJob(scheduler, scheduleJob.getId()); + } + + } catch (SchedulerException e) { + throw new BusinessException("更新定时任务失败"); + } + } + + */ +/** + * 立即执行任务 + *//* + + public static void run(Scheduler scheduler, SysJobEntity scheduleJob) { + try { + //参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(SysJobEntity.JOB_PARAM_KEY, scheduleJob); + + scheduler.triggerJob(getJobKey(scheduleJob.getId()), dataMap); + } catch (SchedulerException e) { + throw new BusinessException("立即执行定时任务失败"); + } + } + + */ +/** + * 暂停任务 + *//* + + public static void pauseJob(Scheduler scheduler, String jobId) { + try { + scheduler.pauseJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new BusinessException("暂停定时任务失败"); + } + } + + */ +/** + * 恢复任务 + *//* + + public static void resumeJob(Scheduler scheduler, String jobId) { + try { + scheduler.resumeJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new BusinessException("暂停定时任务失败"); + } + } + + */ +/** + * 删除定时任务 + *//* + + public static void deleteScheduleJob(Scheduler scheduler, String jobId) { + try { + scheduler.deleteJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new BusinessException("删除定时任务失败"); + } + } +} +*/ diff --git a/src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java b/src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java new file mode 100644 index 0000000..25abdb5 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java @@ -0,0 +1,139 @@ +package com.huoran.iasf.common.shiro; + +import com.alibaba.fastjson.JSON; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.UnauthorizedException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.common.utils.HttpContextUtils; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.filter.AccessControlFilter; +import org.apache.shiro.web.util.WebUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMethod; + +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +import static com.huoran.iasf.service.HttpApiSessionService.*; +import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; + + +/** + * shiro过滤器 登录用户权限认证授权 + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Slf4j +public class CustomAccessControlFilter extends AccessControlFilter { + +// @Override +// protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { +// HttpServletRequest httpRequest = WebUtils.toHttp(request); +// HttpServletResponse httpResponse = WebUtils.toHttp(response); +// if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) { +// httpResponse.setHeader("Access-control-Allow-Origin", httpRequest.getHeader("Origin")); +// httpResponse.setHeader("Access-Control-Allow-Methods", httpRequest.getMethod()); +// // httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); +// httpResponse.setHeader("Access-Control-Allow-Headers", httpRequest.getHeader("Access-Control-Request-Headers")); +// httpResponse.setStatus(HttpStatus.OK.value()); +// return false; +// } +// return super.preHandle(request, response); +// } + + + @Override + protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) { + return false; + } + + @Override + protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; +// try { + HttpServletResponse response = (HttpServletResponse) servletResponse; + Subject subject = getSubject(servletRequest, servletResponse); + System.out.println(subject.isAuthenticated() + ""); + System.out.println(HttpContextUtils.isAjaxRequest(request)); + log.info(request.getMethod()); + log.info(request.getRequestURL().toString()); + //从header中获取token + String token = request.getHeader(Constant.ACCESS_TOKEN); + System.out.println("token===============" + token); + //如果header中不存在token,则从参数中获取token + if (StringUtils.isEmpty(token)) { + token = request.getParameter(Constant.ACCESS_TOKEN); + } + if (StringUtils.isEmpty(token)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + request.setAttribute("filterError", new UnauthorizedException(BaseResponseCode.TOKEN_ERROR)); + // 指定处理该请求的处理器 + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, response); + } + // 校验并解析token,如果token过期或者篡改,则会返回null + Claims claims = checkJWT(token); + if (null == claims) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + request.setAttribute("filterError", new UnauthorizedException(BaseResponseCode.TOKEN_ERROR)); + // 指定处理该请求的处理器 + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, response); + }else { + Subject subject1 = getSubject(servletRequest, servletResponse); + UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(token, token); + subject1.login(usernamePasswordToken); + } + return true; + } + + /** + * 校验token + */ + public Claims checkJWT(String token) { + + try { + final Claims claims = Jwts.parser().setSigningKey(APP_SECRET). + parseClaimsJws(token).getBody(); + return claims; + } catch (Exception e) { + return null; + } + } + + private void customResponse(int code, String msg, ServletResponse response) { + try { + R result = R.getResult(code, msg); + + response.setContentType("application/json; charset=utf-8"); + response.setCharacterEncoding("UTF-8"); + + String userJson = JSON.toJSONString(result); + OutputStream out = response.getOutputStream(); + out.write(userJson.getBytes(StandardCharsets.UTF_8)); + out.flush(); + } catch (IOException e) { + log.error("error={}", e, e); + } + } + +} diff --git a/src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java b/src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java new file mode 100644 index 0000000..002dca8 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java @@ -0,0 +1,39 @@ +package com.huoran.iasf.common.shiro; + +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.service.RedisService; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.credential.SimpleCredentialsMatcher; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; + +/** + * 认证 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class CustomHashedCredentialsMatcher extends SimpleCredentialsMatcher { + + @Lazy + @Autowired + private RedisService redisDb; + @Value("${spring.redis.key.prefix.userToken}") + private String userTokenPrefix; + + @Override + public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { + String accessToken = (String) token.getPrincipal(); + if (!redisDb.exists(userTokenPrefix + accessToken)) { + SecurityUtils.getSubject().logout(); +// throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + return false; + } + return true; + } +} diff --git a/src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java b/src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java new file mode 100644 index 0000000..2bf97fc --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java @@ -0,0 +1,90 @@ +package com.huoran.iasf.common.shiro; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.service.PermissionService; +import com.huoran.iasf.service.RedisService; +import com.huoran.iasf.service.RoleService; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authz.AuthorizationException; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.util.StringUtils; + +import java.util.Collection; + +/** + * 授权 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Slf4j +public class CustomRealm extends AuthorizingRealm { + @Lazy + @Autowired + private PermissionService permissionService; + @Lazy + @Autowired + private RoleService roleService; + @Lazy + @Autowired + private RedisService redisService; + @Value("${spring.redis.key.prefix.permissionRefresh}") + private String redisPermissionRefreshKey; + @Value("${spring.redis.key.prefix.userToken}") + private String userTokenPrefix; + @Lazy + @Autowired + private RedisService redisDb; + + + /** + * 执行授权逻辑 + */ + @Override + @SuppressWarnings("unchecked") + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { + SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); + + String sessionInfoStr = redisDb.get(userTokenPrefix + principalCollection.getPrimaryPrincipal()); + if (StringUtils.isEmpty(sessionInfoStr)) { +// throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + throw new AuthorizationException(); + } + JSONObject redisSession = JSON.parseObject(sessionInfoStr); + if (redisSession == null) { + throw new AuthorizationException(); + } + + if (redisSession.get(Constant.ROLES_KEY) != null) { + authorizationInfo.addRoles((Collection) redisSession.get(Constant.ROLES_KEY)); + } + if (redisSession.get(Constant.PERMISSIONS_KEY) != null) { + authorizationInfo.addStringPermissions((Collection) redisSession.get(Constant.PERMISSIONS_KEY)); + } + return authorizationInfo; + } + + + /** + * 执行认证逻辑 + */ + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { + return new SimpleAuthenticationInfo(authenticationToken.getPrincipal(), authenticationToken.getPrincipal(), getName()); + } +} diff --git a/src/main/java/com/huoran/iasf/common/shiro/ShiroConfig.java b/src/main/java/com/huoran/iasf/common/shiro/ShiroConfig.java new file mode 100644 index 0000000..0b0ba91 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/shiro/ShiroConfig.java @@ -0,0 +1,203 @@ +/* +package com.huoran.iasf.common.shiro; + +import com.huoran.iasf.common.config.FileUploadProperties; +import com.huoran.iasf.common.filter.AuthFilter; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +import javax.annotation.Resource; +import javax.servlet.Filter; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +*/ +/** + * ShiroConfig + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日*//* + + + +@Configuration +@EnableConfigurationProperties(FileUploadProperties.class) +public class ShiroConfig { + + @Resource + private FileUploadProperties fileUploadProperties; + + @Bean + public CustomHashedCredentialsMatcher customHashedCredentialsMatcher() { + return new CustomHashedCredentialsMatcher(); + } + +*/ +/** + * 创建realm*//* + + + @Bean + public CustomRealm customRealm() { + CustomRealm customRealm = new CustomRealm(); + customRealm.setCredentialsMatcher(customHashedCredentialsMatcher()); + return customRealm; + } + + @Bean + public SecurityManager securityManager() { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + //关联realm + securityManager.setRealm(customRealm()); + return securityManager; + } + + + */ +/*@Bean + public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { + + //整个shiro执行过程: 过滤器、认证、授权 + + ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); + //设置安全管理器 + shiroFilterFactoryBean.setSecurityManager(securityManager); + LinkedHashMap filtersMap = new LinkedHashMap<>(); + //用来校验token + filtersMap.put("token", new CustomAccessControlFilter()); + shiroFilterFactoryBean.setFilters(filtersMap); + Map filterChainDefinitionMap = new LinkedHashMap<>(); + // 配置不会被拦截的链接 顺序判断 + *//* +*/ +/* filterChainDefinitionMap.put("/sys/user/login", "anon"); + filterChainDefinitionMap.put("/sys/user/token", "anon"); + filterChainDefinitionMap.put("/sys/getVerify", "anon"); + filterChainDefinitionMap.put("/sys/checkVerify", "anon"); + filterChainDefinitionMap.put("/index/**", "anon"); + filterChainDefinitionMap.put("*.html", "anon"); + filterChainDefinitionMap.put("/static/**", "anon"); + filterChainDefinitionMap.put("/doc.html", "anon"); + filterChainDefinitionMap.put("/swagger-resources/**", "anon"); + filterChainDefinitionMap.put("/v2/api-docs", "anon"); + filterChainDefinitionMap.put("/v2/api-docs-ext", "anon"); + filterChainDefinitionMap.put("/webjars/**", "anon"); + filterChainDefinitionMap.put("/druid/**", "anon"); + filterChainDefinitionMap.put("/favicon.ico", "anon"); + filterChainDefinitionMap.put("/captcha.jpg", "anon"); + filterChainDefinitionMap.put("/csrf", "anon"); + //文件上传可直接访问 + filterChainDefinitionMap.put(fileUploadProperties.getAccessUrl(), "anon"); + filterChainDefinitionMap.put("/images/**", "anon"); + filterChainDefinitionMap.put("/js/**", "anon"); + filterChainDefinitionMap.put("/layui/**", "anon"); + filterChainDefinitionMap.put("/css/**", "anon"); + filterChainDefinitionMap.put("/layui-ext/**", "anon"); + filterChainDefinitionMap.put("/app/api/**", "anon"); + + filterChainDefinitionMap.put("/sys/getVerify", "anon"); + filterChainDefinitionMap.put("/sys/user/login", "anon");*//* +*/ +/* + filterChainDefinitionMap.put("/**", "token,authc"); + shiroFilterFactoryBean.setLoginUrl("/login"); + shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); + return shiroFilterFactoryBean; + }*//* + + + @Bean + public ShiroFilterFactoryBean shirFilter() { + ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); + shiroFilterFactoryBean.setLoginUrl("/login"); + shiroFilterFactoryBean.setSecurityManager(securityManager()); + Map filterMap = new HashMap<>(); + + // 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 :这是一个坑呢,一不小心代码就不好使了; + // ① authc:所有url都必须认证通过才可以访问; ② anon:所有url都都可以匿名访问 + + //过滤器1 + filterMap.put("token", new AuthFilter()); + //过滤器2 + //用来校验token + filterMap.put("authc", new CustomAccessControlFilter()); + shiroFilterFactoryBean.setFilters(filterMap); + Map filterChainDefinitionMap = new LinkedHashMap<>(); + // 配置不会被拦截的链接 顺序判断 + filterChainDefinitionMap.put("/sys/user/login", "anon"); + filterChainDefinitionMap.put("/sys/user/token", "anon"); + filterChainDefinitionMap.put("/sys/getVerify", "anon"); + filterChainDefinitionMap.put("/sys/checkVerify", "anon"); + filterChainDefinitionMap.put("/sysFiles/preview/**", "anon"); + filterChainDefinitionMap.put("/sysContent/findById", "anon"); + filterChainDefinitionMap.put("/sysColumn/findById", "anon"); + filterChainDefinitionMap.put("/sysContent/articlePreview", "anon"); + filterChainDefinitionMap.put("/sysContent/newlyPublishedArticles", "anon"); + filterChainDefinitionMap.put("/sysColumn/listWithTreeMenuVisible", "anon"); + filterChainDefinitionMap.put("/sysContent/hotContent", "anon"); + filterChainDefinitionMap.put("/sysColumn/listWithTree", "anon"); + filterChainDefinitionMap.put("/sysColumnLongPage/getLongPageInformation", "anon"); + filterChainDefinitionMap.put("/favicon.ico", "anon"); + filterChainDefinitionMap.put("/sysColumn/queryArticlesByColumnType", "anon"); + filterChainDefinitionMap.put("/content/label/queryAllArticleSubjectTags", "anon"); + filterChainDefinitionMap.put("/sysColumn/oneLevelChecksThemAll", "anon"); + filterChainDefinitionMap.put("/sysColumn/getTheFullArticleByColumn", "anon"); + filterChainDefinitionMap.put("/sys/exportFailure", "anon"); + filterChainDefinitionMap.put("/sysColumnLongPage/getRedisCache", "anon"); + filterChainDefinitionMap.put("/content/classification/allTheQuery", "anon"); + filterChainDefinitionMap.put("/sysColumn/getsSublevelColumnsUnderALevel", "anon"); + filterChainDefinitionMap.put("/sysFiles/upload", "anon"); + */ +/*filterChainDefinitionMap.put("/index/**", "anon"); + filterChainDefinitionMap.put("/doc.html", "anon"); + filterChainDefinitionMap.put("/swagger-resources/**", "anon"); + filterChainDefinitionMap.put("/v2/api-docs", "anon"); + filterChainDefinitionMap.put("/v2/api-docs-ext", "anon"); + filterChainDefinitionMap.put("*.html", "anon"); + filterChainDefinitionMap.put("/static/**", "anon"); + filterChainDefinitionMap.put("/webjars/**", "anon"); + filterChainDefinitionMap.put("/druid/**", "anon"); + filterChainDefinitionMap.put("/favicon.ico", "anon"); + filterChainDefinitionMap.put("/captcha.jpg", "anon"); + filterChainDefinitionMap.put("/csrf", "anon"); + //文件上传可直接访问 + filterChainDefinitionMap.put(fileUploadProperties.getAccessUrl(), "anon"); + filterChainDefinitionMap.put("/images/**", "anon"); + filterChainDefinitionMap.put("/js/**", "anon"); + filterChainDefinitionMap.put("/layui/**", "anon"); + filterChainDefinitionMap.put("/css/**", "anon"); + filterChainDefinitionMap.put("/layui-ext/**", "anon"); + filterChainDefinitionMap.put("/app/api/**", "anon");*//* + + // 所有请求经过过滤器 + filterChainDefinitionMap.put("/**", "authc,token"); + shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); + return shiroFilterFactoryBean; + } + +*/ +/** + * 开启shiro aop注解支持. + * 使用代理方式;所以需要开启代码支持; + * + * @return org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor*//* + + + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); + authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); + return authorizationAttributeSourceAdvisor; + } + +} + +*/ diff --git a/src/main/java/com/huoran/iasf/common/utils/Constant.java b/src/main/java/com/huoran/iasf/common/utils/Constant.java new file mode 100644 index 0000000..c7027f0 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/Constant.java @@ -0,0 +1,85 @@ +package com.huoran.iasf.common.utils; + +/** + * Constant + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class Constant { + + /** + * redis的token相关 + */ + public static final String ACCESS_TOKEN = "token"; + public static final String PERMISSIONS_KEY = "permissions-key"; + public static final String USERID_KEY = "userid-key"; + public static final String USERNAME_KEY = "username-key"; + public static final String ROLES_KEY = "roles-key"; + + /** + * 未删除值 + */ + public static final Integer DATA_NOT_DELETED = 1; + + /** + * 数据库类型 + */ + public static final String DB_TYPE_MYSQL = "mysql"; + public static final String DB_TYPE_ORACLE = "oracle"; + public static final String DB_TYPE_SQL_SERVER = "sqlServer"; + + /** + * 定时任务状态 + */ + public static final Integer SCHEDULER_STATUS_NORMAL = 0; + public static final Integer SCHEDULER_STATUS_PAUSE = 1; + + /** + * 数据范围类型 1:所有/2:自定义/3:本部门及一下/4:仅本部门/5:自己 + */ + public static final Integer DATA_SCOPE_ALL = 1; + public static final Integer DATA_SCOPE_CUSTOM = 2; + public static final Integer DATA_SCOPE_DEPT_AND_CHILD = 3; + public static final Integer DATA_SCOPE_DEPT = 4; + public static final Integer DATA_SCOPE_DEPT_SELF = 5; + + /** + * 文章发布状态:是否发布 0:草稿 1:已发布 + */ + public static final Integer ARTICLE_PUBLISHED = 1; + + public static final Integer ARTICLE_NOT_PUBLISHED = 0; + + + /** + * 文章模板状态:0禁用;1启用 + */ + public static final Integer TEMPLATE_STATUS_DISABLED = 0; + + public static final Integer TEMPLATE_STATUS_ENABLED = 1; + + + /** + * 模板类型 类型(0:列表样式 1:详情样式)', + */ + + public static final Integer LIST_TEMPLATE_TYPES = 0; + + public static final Integer DETAILS_TEMPLATE_TYPE = 1; + + + /** + * 栏目导航菜单是否可见 菜单是否可见(默认0可见 1不可见) + */ + + public static final Integer NAVIGATION_MENU_VISIBLE = 0; + + public static final Integer THE_NAVIGATION_MENU_IS_NOT_VISIBLE = 1; + + /** + * 异常处理 controller request url + */ + public static final String ERROR_CONTROLLER_PATH = "/error/throw"; +} diff --git a/src/main/java/com/huoran/iasf/common/utils/DateUtils.java b/src/main/java/com/huoran/iasf/common/utils/DateUtils.java new file mode 100644 index 0000000..c15ca92 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/DateUtils.java @@ -0,0 +1,30 @@ +package com.huoran.iasf.common.utils; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 日期处理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class DateUtils { + /** + * 时间格式(yyyy-MM-dd HH:mm:ss) + */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + /** + * 时间格式(yyyyMMdd) + */ + public final static String DATEPATTERN = "yyyyMMdd"; + + public static String format(Date date, String pattern) { + if (date != null) { + SimpleDateFormat df = new SimpleDateFormat(pattern); + return df.format(date); + } + return null; + } +} diff --git a/src/main/java/com/huoran/iasf/common/utils/EmailUtils.java b/src/main/java/com/huoran/iasf/common/utils/EmailUtils.java new file mode 100644 index 0000000..ac2cf3d --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/EmailUtils.java @@ -0,0 +1,70 @@ +package com.huoran.iasf.common.utils; + +import org.apache.commons.mail.DefaultAuthenticator; +import org.apache.commons.mail.HtmlEmail; + + +public class EmailUtils { + + //服务器地址 + private static final String SERVER_ADDRESS = "smtp.mxhichina.com"; + //邮箱地址 + private static final String EMAILADDRESS = "postmaster@huorantech.cn"; + //发生邮箱密码 + private static final String EMAILPASSWORD = "HR111aaa"; + //发送人姓名 + private static final String EMAILUSERNAME = "DataForward"; + //授权码 + //private static final String AUTHORIZATION_CODE = "smtp.mxhichina.com"; + //邮件标题 + private static final String EMAILHEAD = "粒子研究院"; + //邮件信息(后接验证码)头部信息 + private static final String EMAILMASSAGEHEAD = "尊敬的用户,欢迎使用粒子研究院,您本次的验证码是: "; + //邮件信息(后接验证码)尾部信息 + private static final String EMAILMASSAGETAIL = ",有效时间为5分钟"; + + + //邮箱验证码 + public static boolean sendEmail(String emailaddress,String code){ + try { + HtmlEmail email = new HtmlEmail(); + email.setHostName(SERVER_ADDRESS); + email.setSSLOnConnect(true); //使用ssl加密true + email.setSslSmtpPort("465"); //使用465端口 + email.setCharset("UTF-8"); + email.addTo(emailaddress); + + email.setFrom(EMAILADDRESS, EMAILUSERNAME); +// -- 使用阿里企业邮箱无授权码 +// email.setAuthentication(EMAILADDRESS, AUTHORIZATION_CODE); + + email.setAuthenticator(new DefaultAuthenticator(EMAILADDRESS,EMAILPASSWORD)); + email.setSubject(EMAILHEAD); + email.setMsg( EMAILMASSAGEHEAD + code + EMAILMASSAGETAIL); + + email.send(); + return true; + } + catch(Exception e){ + e.printStackTrace(); + return false; + } + } + + /** + * 描述:是否是邮箱. + * + * @param str 指定的字符串 + * @return 是否是邮箱:是为true,否则false + */ + public static Boolean isEmail(String str) { + Boolean isEmail = false; + String expr = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$"; + + if (str.matches(expr)) { + isEmail = true; + } + return isEmail; + } + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/utils/ExcelAttribute.java b/src/main/java/com/huoran/iasf/common/utils/ExcelAttribute.java new file mode 100644 index 0000000..cf0bd20 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/ExcelAttribute.java @@ -0,0 +1,25 @@ +package com.huoran.iasf.common.utils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ExcelAttribute { + /** + * 对应的列名称 + */ + String name() default ""; + + /** + * excel列的索引 + */ + int sort(); + + /** + * 字段类型对应的格式 + */ + String format() default ""; +} diff --git a/src/main/java/com/huoran/iasf/common/utils/ExcelImportHelper.java b/src/main/java/com/huoran/iasf/common/utils/ExcelImportHelper.java new file mode 100644 index 0000000..fd001f8 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/ExcelImportHelper.java @@ -0,0 +1,183 @@ +package com.huoran.iasf.common.utils; + +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.vo.req.ExcelImpUserReq; +import org.apache.commons.lang.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ExcelImportHelper { + + //判断row是否为空 + public static boolean isRowEmpty(Row row) { + if (null == row) { + return true; + } + int firstCellNum = row.getFirstCellNum(); //第一个列位置 + int lastCellNum = row.getLastCellNum(); //最后一列位置 + int nullCellNum = 0; //空列数量 + for (int c = firstCellNum; c < lastCellNum; c++) { + Cell cell = row.getCell(c); + if (null == cell || CellType.BLANK == cell.getCellType()) { + nullCellNum++; + continue; + } + cell.setCellType(CellType.STRING); + String cellValue = cell.getStringCellValue().trim(); + if (StringUtils.isEmpty(cellValue)) { + nullCellNum++; + } + } + //所有列都为空 + if (nullCellNum == (lastCellNum - firstCellNum)) { + return true; + } + return false; + } + + + private static Workbook getWorkbook(MultipartFile file) { + String fileName = file.getOriginalFilename(); + Workbook workbook = null; + + if (fileName.endsWith("xlsx")) { + try { + workbook = new XSSFWorkbook(file.getInputStream()); + } catch (IOException e) { + e.printStackTrace(); + } + } else if (fileName.endsWith("xls")) { + try { + workbook = new HSSFWorkbook(file.getInputStream()); + } catch (IOException e) { + e.printStackTrace(); + } + } + return workbook; + } + + + /** + * @Description : 读取文件数据 + * @Param file + * @Author Rong---2021/10/15 + */ + public static List readUser(MultipartFile file) { + List list = new ArrayList<>(); + + Workbook workbook = getWorkbook(file); + ExcelImpUserReq excelImpUserReq = null; + // 循环工作表Sheet + for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) { + Sheet hssfSheet = workbook.getSheetAt(numSheet); + if (hssfSheet == null) { + continue; + } + + int count = 1; + // 循环行Row//开始行2 + for (int rowNum = 2; rowNum <= hssfSheet.getLastRowNum(); rowNum++) { + Row row = hssfSheet.getRow(rowNum); + + if (isRowEmpty(row)) { + count++; + if (count == hssfSheet.getLastRowNum()) { + throw new BusinessException(BaseResponseCode.EXCEL_FILE_NULL); + } + continue; + } + + Cell realName;//姓名 + Cell userName;//账号 + Cell jobNumber;//工号 + Cell dept;//所在部门 + Cell roleName;//角色 + Cell phone;//手机号 + Cell email;//邮箱 + Cell groupName;//用户组 + if (row != null) { + + excelImpUserReq = new ExcelImpUserReq(); + + if (row.getCell(7) != null) { + row.getCell(7).setCellType(CellType.STRING); + groupName = row.getCell(7); + } else { + groupName = row.createCell(7); + } + + if (row.getCell(6) != null) { + row.getCell(6).setCellType(CellType.STRING); + email = row.getCell(6); + } else { + email = row.createCell(6); + } + + if (row.getCell(5) != null) { + row.getCell(5).setCellType(CellType.STRING); + phone = row.getCell(5); + } else { + phone = row.createCell(5); + } + + if (row.getCell(4) != null) { + row.getCell(4).setCellType(CellType.STRING); + dept = row.getCell(4); + } else { + dept = row.createCell(4); + } + + if (row.getCell(3) != null) { + row.getCell(3).setCellType(CellType.STRING); + jobNumber = row.getCell(3); + } else { + jobNumber = row.createCell(3); + } + + if (row.getCell(2) != null) { + row.getCell(2).setCellType(CellType.STRING); + roleName = row.getCell(2); + } else { + roleName = row.createCell(3); + } + + if (row.getCell(1) != null) { + row.getCell(1).setCellType(CellType.STRING); + userName = row.getCell(1); + } else { + userName = row.createCell(1); + } + + if (row.getCell(0) != null) { + row.getCell(0).setCellType(CellType.STRING); + realName = row.getCell(0); + } else { + realName = row.createCell(0); + } + + excelImpUserReq.setRealName(realName.getStringCellValue()); + excelImpUserReq.setUserName(userName.getStringCellValue()); + excelImpUserReq.setJobNumber(jobNumber.getStringCellValue()); + excelImpUserReq.setDept(dept.getStringCellValue()); + excelImpUserReq.setRoleName(roleName.getStringCellValue()); + excelImpUserReq.setPhone(phone.getStringCellValue()); + excelImpUserReq.setEmail(email.getStringCellValue()); + excelImpUserReq.setGroupName(groupName.getStringCellValue()); + + list.add(excelImpUserReq); + } + } + + } + + return list; + } + +} diff --git a/src/main/java/com/huoran/iasf/common/utils/ExcelStyleUtil.java b/src/main/java/com/huoran/iasf/common/utils/ExcelStyleUtil.java new file mode 100644 index 0000000..f55b1a0 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/ExcelStyleUtil.java @@ -0,0 +1,187 @@ +package com.huoran.iasf.common.utils; + +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams; +import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; +import org.apache.poi.ss.usermodel.*; + +/** + * @ProjectName: huorantech + * @Package: com.huoran.common.utils + * @ClassName: ExcelStyleUtil + * @Description: easy poi导出设置样式 + * @Author: Maureen.Rong + * @CreateDate: 2021/9/1 14:29 + * @UpdateDate: 2021/9/1 14:29 + * @Version: 1.0 + */ +public class ExcelStyleUtil implements IExcelExportStyler { + private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT"); + private static final short FONT_SIZE_TEN = 9; + private static final short FONT_SIZE_ELEVEN = 10; + private static final short FONT_SIZE_TWELVE = 50; + + /** + * 大标题样式 + */ + private CellStyle headerStyle; + /** + * 每列标题样式 + */ + private CellStyle titleStyle; + /** + * 数据行样式 + */ + private CellStyle styles; + + public ExcelStyleUtil(Workbook workbook) { + this.init(workbook); + } + + /** + * 初始化样式 + * + * @param workbook + */ + private void init(Workbook workbook) { + this.headerStyle = initHeaderStyle(workbook); + this.titleStyle = initTitleStyle(workbook); + this.styles = initStyles(workbook); + } + + /** + * 大标题样式 + * + * @param color + * @return + */ + @Override + public CellStyle getHeaderStyle(short color) { + return headerStyle; + } + + /** + * 每列标题样式 + * + * @param color + * @return + */ + @Override + public CellStyle getTitleStyle(short color) { + return titleStyle; + } + + /** + * 数据行样式 + * + * @param parity 可以用来表示奇偶行 + * @param entity 数据内容 + * @return 样式 + */ + @Override + public CellStyle getStyles(boolean parity, ExcelExportEntity entity) { + return styles; + } + + /** + * 获取样式方法 + * + * @param dataRow 数据行 + * @param obj 对象 + * @param data 数据 + */ + @Override + public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) { + return getStyles(true, entity); + } + + /** + * 模板使用的样式设置 + */ + @Override + public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) { + return null; + } + + /** + * 初始化--大标题样式 + * + * @param workbook + * @return + */ + private CellStyle initHeaderStyle(Workbook workbook) { + CellStyle style = getBaseCellStyle(workbook); + style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true)); + return style; + } + + /** + * 初始化--每列标题样式 + * + * @param workbook + * @return + */ + private CellStyle initTitleStyle(Workbook workbook) { + CellStyle style = getBaseCellStyle(workbook); + style.setFont(getFont(workbook, FONT_SIZE_ELEVEN, false)); + //背景色 + style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + return style; + } + + /** + * 初始化--数据行样式 + * + * @param workbook + * @return + */ + private CellStyle initStyles(Workbook workbook) { + CellStyle style = getBaseCellStyle(workbook); + style.setFont(getFont(workbook, FONT_SIZE_TEN, false)); + style.setDataFormat(STRING_FORMAT); + return style; + } + + /** + * 基础样式 + * + * @return + */ + private CellStyle getBaseCellStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + //下边框 + style.setBorderBottom(BorderStyle.THIN); + //左边框 + style.setBorderLeft(BorderStyle.THIN); + //上边框 + style.setBorderTop(BorderStyle.THIN); + //右边框 + style.setBorderRight(BorderStyle.THIN); + //水平居中 + style.setAlignment(HorizontalAlignment.CENTER); + //上下居中 + style.setVerticalAlignment(VerticalAlignment.CENTER); + //设置自动换行 + style.setWrapText(true); + return style; + } + + /** + * 字体样式 + * + * @param size 字体大小 + * @param isBold 是否加粗 + * @return + */ + private Font getFont(Workbook workbook, short size, boolean isBold) { + Font font = workbook.createFont(); + //字体样式 + font.setFontName("宋体"); + //是否加粗 + font.setBold(isBold); + //字体大小 + font.setFontHeightInPoints(size); + return font; + } +} diff --git a/src/main/java/com/huoran/iasf/common/utils/GenUtils.java b/src/main/java/com/huoran/iasf/common/utils/GenUtils.java new file mode 100644 index 0000000..c457ad0 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/GenUtils.java @@ -0,0 +1,224 @@ +package com.huoran.iasf.common.utils; + +import org.apache.commons.lang.StringUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * 代码生成器 工具类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class GenUtils { + + public static List getTemplates() { + List templates = new ArrayList<>(); + templates.add("template/Entity.java.vm"); + templates.add("template/Dao.java.vm"); + templates.add("template/Dao.xml.vm"); + templates.add("template/Service.java.vm"); + templates.add("template/ServiceImpl.java.vm"); + templates.add("template/Controller.java.vm"); + templates.add("template/menu.sql.vm"); + templates.add("template/list.html.vm"); + + return templates; + } + + /** + * 生成代码 + */ + /*public static void generatorCode(Map table, + List> columns, ZipOutputStream zip) { + //配置信息 + Configuration config = getConfig(); + boolean hasBigDecimal = false; + //表信息 + TableEntity tableEntity = new TableEntity(); + tableEntity.setTableName(table.get("tableName")); + tableEntity.setComments(table.get("tableComment")); + //表名转换成Java类名 + String className = tableToJava(tableEntity.getTableName(), config.getStringArray("tablePrefix")); + tableEntity.setClassName(className); + tableEntity.setClassname(StringUtils.uncapitalize(className)); + tableEntity.setClassNameLower(className.toLowerCase()); + + //列信息 + List columsList = new ArrayList<>(); + for (Map column : columns) { + ColumnEntity columnEntity = new ColumnEntity(); + columnEntity.setColumnName(column.get("columnName")); + columnEntity.setDataType(column.get("dataType")); + columnEntity.setComments(column.get("columnComment")); + columnEntity.setExtra(column.get("extra")); + + //列名转换成Java属性名 + String attrName = columnToJava(columnEntity.getColumnName()); + columnEntity.setAttrName(attrName); + columnEntity.setAttrname(StringUtils.uncapitalize(attrName)); + + //列的数据类型,转换成Java类型 + String attrType = config.getString(columnEntity.getDataType(), "unknowType"); + columnEntity.setAttrType(attrType); + if (!hasBigDecimal && "BigDecimal".equals(attrType)) { + hasBigDecimal = true; + } + //是否主键 + if ("PRI".equalsIgnoreCase(column.get("columnKey")) && tableEntity.getPk() == null) { + tableEntity.setPk(columnEntity); + } + + columsList.add(columnEntity); + } + tableEntity.setColumns(columsList); + + //没主键,则第一个字段为主键 + if (tableEntity.getPk() == null) { + tableEntity.setPk(tableEntity.getColumns().get(0)); + } + + //设置velocity资源加载器 + Properties prop = new Properties(); + prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + Velocity.init(prop); + String mainPath = config.getString("mainPath"); + mainPath = StringUtils.isBlank(mainPath) ? "com.company" : mainPath; + //封装模板数据 + Map map = new HashMap<>(15); + map.put("tableName", tableEntity.getTableName()); + map.put("comments", tableEntity.getComments()); + map.put("pk", tableEntity.getPk()); + map.put("className", tableEntity.getClassName()); + map.put("classname", tableEntity.getClassname()); + map.put("pathName", tableEntity.getClassname().toLowerCase()); + map.put("columns", tableEntity.getColumns()); + map.put("classNameLower", tableEntity.getClassNameLower()); + map.put("hasBigDecimal", hasBigDecimal); + map.put("mainPath", mainPath); + map.put("package", config.getString("package")); + map.put("author", config.getString("author")); + map.put("email", config.getString("email")); + map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)); + map.put("identity", IdWorker.getId()); + map.put("addId", IdWorker.getId()); + map.put("updateId", IdWorker.getId()); + map.put("deleteId", IdWorker.getId()); + map.put("selectId", IdWorker.getId()); + map.put("identityJoinId", IdWorker.getId()); + map.put("addIdJoinId", IdWorker.getId()); + map.put("updateIdJoinId", IdWorker.getId()); + map.put("deleteIdJoinId", IdWorker.getId()); + map.put("selectIdJoinId", IdWorker.getId()); + VelocityContext context = new VelocityContext(map); + + //获取模板列表 + List templates = getTemplates(); + for (String template : templates) { + //渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, "UTF-8"); + tpl.merge(context, sw); + + try { + //添加到zip + zip.putNextEntry(new ZipEntry(Objects.requireNonNull(getFileName(template, tableEntity.getClassName(), config.getString("package"))))); + IOUtils.write(sw.toString(), zip, "UTF-8"); + IOUtils.closeQuietly(sw); + zip.closeEntry(); + } catch (IOException e) { + // throw new BusinessException("渲染模板失败,表名:" + tableEntity.getTableName()); + } + } + }*/ + + + /** + * 列名转换成Java属性名 + */ + public static String columnToJava(String field) { + String[] fields = field.split("_"); + StringBuilder sbuilder = new StringBuilder(fields[0]); + for (int i = 1; i < fields.length; i++) { + char[] cs = fields[i].toCharArray(); + if(cs[0]>='a') { + cs[0] -= 32; + } + sbuilder.append(String.valueOf(cs)); + } + return sbuilder.toString().substring(0, 1).toUpperCase() + sbuilder.toString().substring(1); + } + + + /** + * 表名转换成Java类名 + */ + public static String tableToJava(String tableName, String[] tablePrefixArray) { + tableName = tableName.toLowerCase(); + if (null != tablePrefixArray && tablePrefixArray.length > 0) { + for (String tablePrefix : tablePrefixArray) { + tablePrefix = tablePrefix.toLowerCase(); + tableName = tableName.replace(tablePrefix, ""); + } + } + return columnToJava(tableName); + } + + /** + * 获取配置信息 + */ +/* public static Configuration getConfig() { + try { + return new PropertiesConfiguration("generator.properties"); + } catch (ConfigurationException e) { + throw new BusinessException("获取配置文件失败"); + } + }*/ + + /** + * 获取文件名 + */ + public static String getFileName(String template, String className, String packageName) { + String packagePath = "main" + File.separator + "java" + File.separator; + if (StringUtils.isNotBlank(packageName)) { + packagePath += packageName.replace(".", File.separator) + File.separator; + } + + if (template.contains("Entity.java.vm")) { + return packagePath + "entity" + File.separator + className + "Entity.java"; + } + + if (template.contains("Dao.java.vm")) { + return packagePath + "mapper" + File.separator + className + "Mapper.java"; + } + + if (template.contains("Service.java.vm")) { + return packagePath + "service" + File.separator + className + "Service.java"; + } + + if (template.contains("ServiceImpl.java.vm")) { + return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; + } + + if (template.contains("Controller.java.vm")) { + return packagePath + "controller" + File.separator + className + "Controller.java"; + } + + if (template.contains("Dao.xml.vm")) { + return "main" + File.separator + "resources" + File.separator + "mapper" + File.separator + className + "Mapper.xml"; + } + + if (template.contains("menu.sql.vm")) { + return className.toLowerCase() + "_menu.sql"; + } + + if (template.contains("list.html.vm")) { + return "main" + File.separator + "resources" + File.separator + "templates" + File.separator + className.toLowerCase() + File.separator + "list" + ".html"; + } + + return null; + } +} diff --git a/src/main/java/com/huoran/iasf/common/utils/HttpContextUtils.java b/src/main/java/com/huoran/iasf/common/utils/HttpContextUtils.java new file mode 100644 index 0000000..dae9e64 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/HttpContextUtils.java @@ -0,0 +1,32 @@ +package com.huoran.iasf.common.utils; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Objects; + +/** + * HttpContextUtils + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class HttpContextUtils { + + public static HttpServletRequest getHttpServletRequest() { + return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); + } + + public static boolean isAjaxRequest(HttpServletRequest request) { + + String accept = request.getHeader("accept"); + String xRequestedWith = request.getHeader("X-Requested-With"); + + // 如果是异步请求或是手机端,则直接返回信息 + return ((accept != null && accept.contains("application/json") + || (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + )); + } +} diff --git a/src/main/java/com/huoran/iasf/common/utils/IPUtils.java b/src/main/java/com/huoran/iasf/common/utils/IPUtils.java new file mode 100644 index 0000000..f0d0f48 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/IPUtils.java @@ -0,0 +1,73 @@ +package com.huoran.iasf.common.utils; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * IPUtils + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class IPUtils { + + private static Logger logger = LoggerFactory.getLogger(IPUtils.class); + + /** + * 获取IP地址 + *

+ * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 + * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + String ip = null; + try { + ip = request.getHeader("x-forwarded-for"); + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } catch (Exception e) { + logger.error("IPUtils ERROR ", e); + } + + // 使用代理,则获取第一个IP地址 + if (!StringUtils.isEmpty(ip) && ip.length() > 15) { + if (ip.indexOf(",") > 0) { + ip = ip.substring(0, ip.indexOf(",")); + } + } + + return ip; + } + + /** + * 获取客户端主机名称 + */ + public static String getHostName() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + logger.error(e.getMessage(), e); + } + return "未知"; + } + +} diff --git a/src/main/java/com/huoran/iasf/common/utils/OkHttpUtils.java b/src/main/java/com/huoran/iasf/common/utils/OkHttpUtils.java new file mode 100644 index 0000000..ded155d --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/OkHttpUtils.java @@ -0,0 +1,299 @@ +package com.huoran.iasf.common.utils; + +import com.alibaba.fastjson.JSON; +import okhttp3.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URLEncoder; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +/** + * Ok http utils + * @author cheney.li + */ +public class OkHttpUtils { + private static OkHttpClient okHttpClient; + private static Semaphore semaphore; + private Map headerMap; + private Map paramMap; + private String url; + private Request.Builder request; + private static final String ERROR_MESSAGE = "OkHttpUtils error:{}"; + private static final Logger logger = LoggerFactory.getLogger(OkHttpUtils.class); + /** + * 初始化okHttpClient,并且允许https访问 + */ + private OkHttpUtils() { + if (okHttpClient == null) { + synchronized (OkHttpUtils.class) { + okHttpClient = new OkHttpClient.Builder() + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(20, TimeUnit.SECONDS) + .readTimeout(20, TimeUnit.SECONDS) + .retryOnConnectionFailure(true) + .build(); + addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"); + } + } + } + + /** + * 用于异步请求时,控制访问线程数,返回结果 + * + * @return + */ + private static Semaphore getSemaphoreInstance() { + //只能1个线程同时访问 + synchronized (OkHttpUtils.class) { + if (semaphore == null) { + semaphore = new Semaphore(0); + } + } + return semaphore; + } + + /** + * 创建OkHttpUtils + * + * @return ok http utils + */ + public static OkHttpUtils builder() { + return new OkHttpUtils(); + } + + /** + * 添加url + * + * @param url url + * @return ok http utils + */ + public OkHttpUtils url(String url) { + this.url = url; + return this; + } + + /** + * 添加参数 + * + * @param key 参数名 + * @param value 参数值 + * @return ok http utils + */ + public OkHttpUtils addParam(String key, String value) { + if (paramMap == null) { + paramMap = new LinkedHashMap<>(16); + } + paramMap.put(key, value); + return this; + } + /** + * 添加参数 + * + * @param map map + * @return ok http utils + */ + public OkHttpUtils addMap(Map map) { + if (paramMap == null) { + paramMap = new LinkedHashMap<>(16); + } + paramMap.putAll(map); + return this; + } + /** + * 添加请求头 + * + * @param key 参数名 + * @param value 参数值 + * @return ok addHeader utils + */ + public OkHttpUtils addHeader(String key, String value) { + if (headerMap == null) { + headerMap = new LinkedHashMap<>(16); + } + headerMap.put(key, value); + return this; + } + + /** + * 初始化get方法 + * + * @return ok http utils + */ + public OkHttpUtils get() { + request = new Request.Builder().get(); + StringBuilder urlBuilder = new StringBuilder(url); + if (paramMap != null) { + urlBuilder.append("?"); + try { + for (Map.Entry entry : paramMap.entrySet()) { + urlBuilder.append(URLEncoder.encode(entry.getKey(), "utf-8")). + append("="). + append(URLEncoder.encode(entry.getValue(), "utf-8")). + append("&"); + } + } catch (Exception e) { + logger.error(ERROR_MESSAGE, e.getMessage()); + } + urlBuilder.deleteCharAt(urlBuilder.length() - 1); + } + request.url(urlBuilder.toString()); + return this; + } + + /** + * 初始化post方法 + * + * @param isJsonPost true等于json的方式提交数据,类似postman里post方法的raw false等于普通的表单提交 + * @return ok http utils + */ + public OkHttpUtils post(boolean isJsonPost) { + RequestBody requestBody; + if (isJsonPost) { + String json = ""; + if (paramMap != null) { + json = JSON.toJSONString(paramMap); + } + requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json); + } else { + FormBody.Builder formBody = new FormBody.Builder(); + if (paramMap != null) { + paramMap.forEach(formBody::add); + } + requestBody = formBody.build(); + } + request = new Request.Builder().post(requestBody).url(url); + return this; + } + + /** + * 同步请求 + * + * @return string + */ + public String sync() { + setHeader(request); + try { + Response response = okHttpClient.newCall(request.build()).execute(); + assert response.body() != null; + return response.body().string(); + } catch (IOException e) { + return "请求失败:" + e.getMessage(); + } + } + + /** + * 异步请求,有返回值 + * + * @return the string + */ + public String async() { + StringBuilder buffer = new StringBuilder(""); + setHeader(request); + okHttpClient.newCall(request.build()).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + buffer.append("请求出错:").append(e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + if (response.body() != null) { + buffer.append(response.body().string()); + getSemaphoreInstance().release(); + } + } + }); + try { + getSemaphoreInstance().acquire(); + } catch (Exception e) { + logger.error(ERROR_MESSAGE, e.getMessage()); + } + return buffer.toString(); + } + + /** + * 异步请求,带有接口回调 + * + * @param callBack call back + */ + public void async(ICallBack callBack) { + setHeader(request); + okHttpClient.newCall(request.build()).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + callBack.onFailure(call, e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + if (response.body() != null) { + callBack.onSuccessful(call, response.body().string()); + } + } + }); + } + + /** + * 为request添加请求头 + * + * @param request + */ + private void setHeader(Request.Builder request) { + if (headerMap != null) { + try { + for (Map.Entry entry : headerMap.entrySet()) { + request.addHeader(entry.getKey(), entry.getValue()); + } + } catch (Exception e) { + logger.error(ERROR_MESSAGE, e.getMessage()); + } + } + } + + + /** + * 自定义一个接口回调 + */ + public interface ICallBack { + + /** + * On successful * + * + * @param call call + * @param data data + */ + void onSuccessful(Call call, String data); + + /** + * On failure * + * + * @param call call + * @param errorMsg error msg + */ + void onFailure(Call call, String errorMsg); + + } + + /** + * Main + * + * @param args args + */ + public static void main(String[] args) { + String tokenJson = OkHttpUtils.builder() + .url("https://10.1.50.198") + .addParam("client_id", "pbase_account") + .addParam("client_secret", "bed0bfd22d87b7bbab9b1d43191ddd57") + .addParam("grant_type", "client_credentials") + .post(false) + .sync(); + logger.info(tokenJson); + } +} + + diff --git a/src/main/java/com/huoran/iasf/common/utils/PasswordEncoder.java b/src/main/java/com/huoran/iasf/common/utils/PasswordEncoder.java new file mode 100644 index 0000000..0d5a677 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/PasswordEncoder.java @@ -0,0 +1,117 @@ +package com.huoran.iasf.common.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +/** + * 密码加密 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class PasswordEncoder { + + private static Logger logger = LoggerFactory.getLogger(PasswordEncoder.class); + + + private final static String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", + "e", "f"}; + + private final static String MD5 = "MD5"; + + private Object salt; + private String algorithm; + + public PasswordEncoder(Object salt) { + this(salt, MD5); + } + + public PasswordEncoder(Object salt, String algorithm) { + this.salt = salt; + this.algorithm = algorithm; + } + + /** + * 密码加密 + * + * @param rawPass 密码 + * @return 加密后 + */ + public String encode(String rawPass) { + String result = null; + try { + MessageDigest md = MessageDigest.getInstance(algorithm); + // 加密后的字符串 + result = byteArrayToHexString(md.digest(mergePasswordAndSalt(rawPass).getBytes(StandardCharsets.UTF_8))); + } catch (Exception e) { + logger.error(e.toString(), e); + } + return result; + } + + /** + * 密码匹配验证 + * + * @param encPass 密文 + * @param rawPass 明文 + * @return 是否匹配 + */ + public boolean matches(String encPass, String rawPass) { + String pass1 = "" + encPass; + String pass2 = encode(rawPass); + + return pass1.equals(pass2); + } + + private String mergePasswordAndSalt(String password) { + if (password == null) { + password = ""; + } + + if ((salt == null) || "".equals(salt)) { + return password; + } else { + return password + "{" + salt.toString() + "}"; + } + } + + /** + * 转换字节数组为16进制字串 + * + * @param b 字节数组 + * @return 16进制字串 + */ + private String byteArrayToHexString(byte[] b) { + StringBuilder resultSb = new StringBuilder(); + for (byte value : b) { + resultSb.append(byteToHexString(value)); + } + return resultSb.toString(); + } + + /** + * 将字节转换为16进制 + * + * @param b 字节 + * @return 16进制 + */ + private static String byteToHexString(byte b) { + int n = b; + if (n < 0) { + n = 256 + n; + } + int d1 = n / 16; + int d2 = n % 16; + return HEX_DIGITS[d1] + HEX_DIGITS[d2]; + } + + public static void main(String[] args) { + + } + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/utils/PasswordUtils.java b/src/main/java/com/huoran/iasf/common/utils/PasswordUtils.java new file mode 100644 index 0000000..6c358e6 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/PasswordUtils.java @@ -0,0 +1,47 @@ +package com.huoran.iasf.common.utils; + +import java.util.UUID; + + +/** + * 密码工具类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class PasswordUtils { + + /** + * 匹配密码 + * + * @param salt 盐 + * @param rawPass 明文 + * @param encPass 密文 + * @return 是否匹配 + */ + public static boolean matches(String salt, String rawPass, String encPass) { + return new PasswordEncoder(salt).matches(encPass, rawPass); + } + + /** + * 明文密码加密 + * + * @param rawPass 明文 + * @param salt 盐 + * @reture 加密后 + */ + public static String encode(String rawPass, String salt) { + return new PasswordEncoder(salt).encode(rawPass); + } + + /** + * 获取加密盐 + * + * @return 盐值 + */ + public static String getSalt() { + return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20); + } + +} diff --git a/src/main/java/com/huoran/iasf/common/utils/R.java b/src/main/java/com/huoran/iasf/common/utils/R.java new file mode 100644 index 0000000..8336db6 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/R.java @@ -0,0 +1,116 @@ +package com.huoran.iasf.common.utils; + +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.exception.code.ResponseCodeInterface; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 返回值R + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class R { + + /** + * 请求响应code,0为成功 其他为失败 + */ + @ApiModelProperty(value = "请求响应code,200为成功 其他为失败", name = "code") + private int code; + + /** + * 响应异常码详细信息 + */ + @ApiModelProperty(value = "响应异常码详细信息", name = "msg") + private String msg; + + @ApiModelProperty(value = "需要返回的数据", name = "data") + private Object data; + + public R(int code, Object data) { + this.code = code; + this.data = data; + this.msg = null; + } + + public R(int code, String msg, Object data) { + this.code = code; + this.msg = msg; + this.data = data; + } + + public R(int code, String msg) { + this.code = code; + this.msg = msg; + this.data = null; + } + + public R() { + this.code = BaseResponseCode.SUCCESS.getCode(); + this.msg = BaseResponseCode.SUCCESS.getMsg(); + this.data = null; + } + + public R(Object data) { + this.data = data; + this.code = BaseResponseCode.SUCCESS.getCode(); + this.msg = BaseResponseCode.SUCCESS.getMsg(); + } + + public R(ResponseCodeInterface responseCodeInterface) { + this.data = null; + this.code = responseCodeInterface.getCode(); + this.msg = responseCodeInterface.getMsg(); + } + + public R(ResponseCodeInterface responseCodeInterface, Object data) { + this.data = data; + this.code = responseCodeInterface.getCode(); + this.msg = responseCodeInterface.getMsg(); + } + + /** + * 操作成功 data为null + */ + public static R success() { + return new R(); + } + + /** + * 操作成功 data 不为null + */ + public static R success(Object data) { + return new R(data); + } + + /** + * 操作失败 data 不为null + */ + public static R fail(String msg) { + return new R(BaseResponseCode.OPERATION_ERROR.getCode(), msg); + } + + public static R fail(Object data) { + return new R(data); + } + + + /** + * 自定义返回 data为null + */ + public static R getResult(int code, String msg) { + return new R(code, msg); + } + + /** + * 自定义返回 入参一般是异常code枚举 data为空 + */ + public static R getResult(BaseResponseCode responseCode) { + return new R(responseCode); + } + + +} diff --git a/src/main/java/com/huoran/iasf/common/utils/RandomUtil.java b/src/main/java/com/huoran/iasf/common/utils/RandomUtil.java new file mode 100644 index 0000000..d352428 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/RandomUtil.java @@ -0,0 +1,64 @@ +package com.huoran.iasf.common.utils; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Random; + +/** + * 获取随机数 + * + * @author cheney + * + */ +public class RandomUtil { + + private static final Random random = new Random(); + + private static final DecimalFormat fourdf = new DecimalFormat("0000"); + + private static final DecimalFormat sixdf = new DecimalFormat("000000"); + + public static String getFourBitRandom() { + return fourdf.format(random.nextInt(10000)); + } + + public static String getSixBitRandom() { + return sixdf.format(random.nextInt(1000000)); + } + + /** + * 给定数组,抽取n个数据 + * @param list + * @param n + * @return + */ + public static ArrayList getRandom(List list, int n) { + + Random random = new Random(); + + HashMap hashMap = new HashMap(); + + // 生成随机数字并存入HashMap + for (int i = 0; i < list.size(); i++) { + + int number = random.nextInt(100) + 1; + + hashMap.put(number, i); + } + + // 从HashMap导入数组 + Object[] robjs = hashMap.values().toArray(); + + ArrayList r = new ArrayList(); + + // 遍历数组并打印数据 + for (int i = 0; i < n; i++) { + r.add(list.get((int) robjs[i])); + System.out.print(list.get((int) robjs[i]) + "\t"); + } + System.out.print("\n"); + return r; + } +} diff --git a/src/main/java/com/huoran/iasf/common/utils/SMSTemplate.java b/src/main/java/com/huoran/iasf/common/utils/SMSTemplate.java new file mode 100644 index 0000000..841e8c0 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/SMSTemplate.java @@ -0,0 +1,34 @@ +package com.huoran.iasf.common.utils; + +/** + * @Author chen + * @DATE 2021/7/7 14:14 + * @Version 1.0 + */ +public interface SMSTemplate { + + // 短信签名 + String SMS_SIGNATURE = "或然科技"; + + // 找回密码验证码 + String RETRIEVE_PASSWORD_CODE = "SMS_219310031"; + + // 身份验证验证码 + String AUTHENTICATION_CODE = "SMS_221515019"; + + // 登录确认验证码 + String LOGIN_VERIFICATION_CODE = "SMS_204155296"; + + // 登录异常验证码 + String LOGIN_EXCEPTION_CODE = "SMS_204155295"; + + // 用户注册验证码 + String USER_REGISTRATION_CODE = "SMS_204155294"; + + // 修改密码验证码 + String MODIFY_PASSWORD_CODE = "SMS_204155293"; + + // 信息变更验证码 + String INFORMATION_CHANGE_CODE = "SMS_204155292"; + +} diff --git a/src/main/java/com/huoran/iasf/common/utils/SendSMSUtils.java b/src/main/java/com/huoran/iasf/common/utils/SendSMSUtils.java new file mode 100644 index 0000000..a02ccdc --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/SendSMSUtils.java @@ -0,0 +1,51 @@ +package com.huoran.iasf.common.utils; + +import com.alibaba.fastjson.JSONObject; +import com.aliyuncs.CommonRequest; +import com.aliyuncs.CommonResponse; +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.http.MethodType; +import com.aliyuncs.profile.DefaultProfile; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; + + +@Slf4j +public class SendSMSUtils { + + public static boolean send(String PhoneNumbers, String templateCode, Map param) { + + if(StringUtils.isEmpty(PhoneNumbers)) { + return false; + } + + DefaultProfile profile = + DefaultProfile.getProfile("default", "LTAI4FzqQHnk4rozqLZ8jCNj", "mveW7B1OyFoKUkHm8WsxmrjHmkJWHq"); + IAcsClient client = new DefaultAcsClient(profile); + + CommonRequest request = new CommonRequest(); + request.setMethod(MethodType.GET); + request.setDomain("dysmsapi.aliyuncs.com"); + request.setVersion("2017-05-25"); + request.setAction("SendSms"); + + request.putQueryParameter("PhoneNumbers", PhoneNumbers); + request.putQueryParameter("SignName", SMSTemplate.SMS_SIGNATURE); + request.putQueryParameter("TemplateCode", templateCode); + request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param)); + + try { + CommonResponse response = client.getCommonResponse(request); + System.out.println(response.getData()); + return response.getHttpResponse().isSuccess(); + } catch (ClientException e) { + e.printStackTrace(); + } + return false; + } + +} diff --git a/src/main/java/com/huoran/iasf/common/utils/SpringContextUtils.java b/src/main/java/com/huoran/iasf/common/utils/SpringContextUtils.java new file mode 100644 index 0000000..fe5c931 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/SpringContextUtils.java @@ -0,0 +1,33 @@ +package com.huoran.iasf.common.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * SpringContextUtils + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Component +public class SpringContextUtils implements ApplicationContextAware { + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + SpringContextUtils.applicationContext = applicationContext; + } + + public static Object getBean(String name) { + try { + return applicationContext.getBean(name); + } catch (Exception e) { + return null; + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/common/utils/TreeStructureUtils.java b/src/main/java/com/huoran/iasf/common/utils/TreeStructureUtils.java new file mode 100644 index 0000000..5ebc0e7 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/TreeStructureUtils.java @@ -0,0 +1,110 @@ +package com.huoran.iasf.common.utils; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.huoran.iasf.entity.SysColumn; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class TreeStructureUtils { + + // 获取树结构数据 + public static List getList(List columns) { + try { + List result = new ArrayList<>(); + for (SysColumn test : columns) { + if (test.getFatherId() == 0) { + result.add(test); + } + } + for (SysColumn test : result) { + List childList = getChildren(test.getId(), columns); + test.setChildren(childList); + } + // 将一层一层的树结构数据返回吧! + return result; + } catch (Exception e) { + // 这里可以抛个异常 + } + return null; + } + + + //把一个List转成树 + public static List buildTree(List list, Integer pid) { + List tree = new ArrayList<>(); + for (SysColumn node : list) { + if (Objects.equals(node.getFatherId(), pid)) { + tree.add(findChild(node, list)); + } + } + return tree; + } + + static SysColumn findChild(SysColumn node, List list) { + for (SysColumn n : list) { + if (Objects.equals(n.getFatherId(), node.getId())) { + if (node.getChildren() == null) { + node.setChildren(new ArrayList()); + } + node.getChildren().add(findChild(n, list)); + } + } + return node; + } + + public static List getChildren(Integer id, List allDept) { + //存放子节点 + List childList = new ArrayList<>(); + //遍历所有栏目,如果父id与传来的id相同,则为传来的id这个栏目的子栏目 + for (SysColumn dept : allDept) { + Integer parentId = dept.getFatherId(); + if (parentId.equals(id)) { + childList.add(dept); + } + } + + //自调用来判断是否还有子节点 + for (SysColumn dept : childList) { + dept.setChildren(getChildren(dept.getId(), allDept)); + } + + //如果没有子节点则返回空集合 + if (childList.size() == 0) { + return new ArrayList<>(); + } + return childList; + } + + + + + + /** + * 双重for循环方法转换成树形结构 + * @param treeList + * @return + */ + public static List forMethod(List treeList) { + List rootTree = new ArrayList<>(); + for (SysColumn tree : treeList) { + // 第一步 筛选出最顶级的父节点 + if (0 == tree.getFatherId()) { + rootTree.add(tree); + } + // 第二步 筛选出该父节点下的所有子节点列表 + for (SysColumn node : treeList) { + if (node.getFatherId().equals(tree.getId())) { + if (CollectionUtils.isEmpty(tree.getChildren())) { + tree.setChildren(new ArrayList<>()); + } + tree.getChildren().add(node); + } + } + } + return rootTree; + } + +} diff --git a/src/main/java/com/huoran/iasf/common/utils/ValidatorUtils.java b/src/main/java/com/huoran/iasf/common/utils/ValidatorUtils.java new file mode 100644 index 0000000..9e89d41 --- /dev/null +++ b/src/main/java/com/huoran/iasf/common/utils/ValidatorUtils.java @@ -0,0 +1,47 @@ +package com.huoran.iasf.common.utils; + + +import com.huoran.iasf.common.exception.BusinessException; + +/** + * hibernate-validator校验工具类 + * + */ +/*public class ValidatorUtils { + private static Validator validator; + + static { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + *//** + * 校验对象 + * @param object 待校验对象 + * @param groups 待校验的组 + * @throws BusinessException 校验不通过,则报RRException异常 + *//* +*//* public static void validateEntity(Object object, Class... groups) + throws BusinessException { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) { + ConstraintViolation constraint = (ConstraintViolation)constraintViolations.iterator().next(); + throw new BusinessException(constraint.getMessage()); + } + }*//* + + *//** + * 空判断处理 + * @param str + * @param message + *//* + public static void isBlank(Object str, String message) { + if (str == null) { + throw new BusinessException(message); + } + if (str instanceof String) { + if (StringUtils.isBlank(String.valueOf(str))) { + throw new BusinessException(message); + } + } + } +}*/ diff --git a/src/main/java/com/huoran/iasf/controller/CaptchaController.java b/src/main/java/com/huoran/iasf/controller/CaptchaController.java new file mode 100644 index 0000000..02d97a7 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/CaptchaController.java @@ -0,0 +1,68 @@ +package com.huoran.iasf.controller; + +import com.huoran.iasf.service.RedisService; +import com.wf.captcha.ArithmeticCaptcha; +import com.wf.captcha.base.Captcha; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 验证码相关 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Api(tags = "登录验证码") +@RestController +@Slf4j +@RequestMapping("/sys") +public class CaptchaController { + + @Resource + private RedisService redisService; + /** + * 获取验证码图片 + * Gets captcha code. + */ +/* @RequestMapping("/getVerify") + public void getCaptchaCode(HttpServletRequest request, HttpServletResponse response) throws IOException { + ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48); + captcha.setLen(2); + CaptchaUtil.out(captcha, request, response); + }*/ + + @ApiOperation(value = "登录验证码") + @GetMapping(value = "/getVerify",produces = "image/png") + public void captcha( + @ApiParam(name = "random", value = "随机数", required = true) + @RequestParam String random, HttpServletResponse response){ + Captcha captcha = new ArithmeticCaptcha(); + //生成验证码 + String text = captcha.text(); + //缓存验证码 + redisService.setAndExpire(random,text,120); + response.setContentType(MediaType.IMAGE_PNG_VALUE); + response.setHeader(HttpHeaders.PRAGMA, "No-cache"); + response.setHeader(HttpHeaders.CACHE_CONTROL, "No-cache"); + response.setDateHeader(HttpHeaders.EXPIRES, 0L); + try { + captcha.out(response.getOutputStream()); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/huoran/iasf/controller/DeptController.java b/src/main/java/com/huoran/iasf/controller/DeptController.java new file mode 100644 index 0000000..88a7e62 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/DeptController.java @@ -0,0 +1,105 @@ +package com.huoran.iasf.controller; + +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysDept; +import com.huoran.iasf.service.DeptService; +import com.huoran.iasf.vo.resp.DeptRespNodeVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 部门管理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@RequestMapping("/sys") +@RestController +@Api(tags = "部门管理") +public class DeptController { + @Resource + private DeptService deptService; + @NoRepeatSubmit + @PostMapping("/dept") + @ApiOperation(value = "新增组织接口") + @LogAnnotation(title = "机构管理", action = "新增组织") + @RequiresPermissions("sys:dept:add") + public R addDept(@RequestBody @Valid SysDept vo) { + boolean ok = deptService.checkDeptRepeat(vo); + if (ok) { + return R.fail("同级下已存在相同的名称:" + vo.getName()); + } + deptService.addDept(vo); + return R.success(); + } + + @DeleteMapping("/dept/{id}") + @ApiOperation(value = "删除组织接口") + @LogAnnotation(title = "机构管理", action = "删除组织") + @RequiresPermissions("sys:dept:deleted") + public R deleted(@PathVariable("id") String id) { + deptService.deleted(id); + return R.success(); + } + + @PutMapping("/dept") + @ApiOperation(value = "更新组织信息接口") + @LogAnnotation(title = "机构管理", action = "更新组织信息") + @RequiresPermissions("sys:dept:update") + public R updateDept(@RequestBody SysDept vo) { + if (StringUtils.isEmpty(vo.getId())) { + return R.fail("id不能为空"); + } + boolean ok = deptService.checkDeptRepeat(vo); + if (ok) { + return R.fail("同级下已存在相同的名称:" + vo.getName()); + } + deptService.updateDept(vo); + return R.success(); + } + + @GetMapping("/dept/{id}") + @ApiOperation(value = "查询组织详情接口") + @LogAnnotation(title = "机构管理", action = "查询组织详情") +// @RequiresPermissions("sys:dept:detail") + public R detailInfo(@PathVariable("id") String id) { + return R.success(deptService.getById(id)); + } + + @GetMapping("/dept/tree") + @ApiOperation(value = "树型组织列表接口",response = DeptRespNodeVO.class) + @LogAnnotation(title = "部门管理", action = "树型组织列表") +// @RequiresPermissions(value = {"sys:user:list", "sys:user:update", "sys:user:add", "sys:dept:add", "sys:dept:update"}, logical = Logical.OR) + public R getTree( + @ApiParam(name = "deptId", value = "部门id",required = false) + @RequestParam(required = false) String deptId) { + return R.success(deptService.deptTreeList(deptId)); + } + +/* @GetMapping("/depts") + @ApiOperation(value = "获取机构列表接口") + @LogAnnotation(title = "机构管理", action = "获取所有组织机构") + @RequiresPermissions("sys:dept:list") + public R getDeptAll() { + List deptList = deptService.list(); + deptList.parallelStream().forEach(entity -> { + SysDept parentDept = deptService.getById(entity.getPid()); + if (parentDept != null) { + entity.setPidName(parentDept.getName()); + } + }); + return R.success(deptList); + }*/ + +} diff --git a/src/main/java/com/huoran/iasf/controller/ExceptionController.java b/src/main/java/com/huoran/iasf/controller/ExceptionController.java new file mode 100644 index 0000000..73efebf --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/ExceptionController.java @@ -0,0 +1,25 @@ +package com.huoran.iasf.controller; + +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.UnauthorizedException; +import com.huoran.iasf.common.utils.Constant; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +/** + * 过滤器异常控制器 + */ +@RestController +public class ExceptionController { + + @RequestMapping(Constant.ERROR_CONTROLLER_PATH) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public void handleException(HttpServletRequest request){ + throw (UnauthorizedException) request.getAttribute("filterError"); + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/HomeController.java b/src/main/java/com/huoran/iasf/controller/HomeController.java new file mode 100644 index 0000000..86a69ae --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/HomeController.java @@ -0,0 +1,44 @@ +/* +package com.huoran.iasf.controller; + +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.service.HomeService; +import com.huoran.iasf.service.HttpSessionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + + +*/ +/** + * 首页 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +@RestController +@RequestMapping("/sys") +@Api(tags = "首页数据") +public class HomeController { + @Resource + private HomeService homeService; + @Resource + private HttpSessionService httpSessionService; + + @GetMapping("/home") + @ApiOperation(value = "获取首页数据接口") + public R getHomeInfo() { + //通过access_token拿userId + String userId = httpSessionService.getCurrentUserId(); + R result = R.success(); + result.setData(homeService.getHomeInfo(userId)); + return result; + } +} +*/ diff --git a/src/main/java/com/huoran/iasf/controller/PermissionController.java b/src/main/java/com/huoran/iasf/controller/PermissionController.java new file mode 100644 index 0000000..7a371db --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/PermissionController.java @@ -0,0 +1,102 @@ +package com.huoran.iasf.controller; + +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysPermission; +import com.huoran.iasf.service.PermissionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * 菜单权限管理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@RequestMapping("/sys") +@RestController +@Api(tags = "菜单权限管理") +public class PermissionController { + + @Resource + private PermissionService permissionService; + +/* @PostMapping("/permission") + @ApiOperation(value = "新增菜单权限接口") + @LogAnnotation(title = "菜单权限管理", action = "新增菜单权限") + @RequiresPermissions("sys:permission:add") + public R addPermission(@RequestBody @Valid SysPermission vo) { + verifyFormPid(vo); + vo.setStatus(1); + permissionService.save(vo); + return R.success(); + }*/ + +/* @DeleteMapping("/permission/{id}") + @ApiOperation(value = "删除菜单权限接口") + @LogAnnotation(title = "菜单权限管理", action = "删除菜单权限") + @RequiresPermissions("sys:permission:deleted") + public R deleted(@PathVariable("id") String id) { + permissionService.deleted(id); + return R.success(); + }*/ + + @GetMapping("/permission/tree/all") + @ApiOperation(value = "获取所有目录菜单树接口") + @LogAnnotation(title = "菜单权限管理", action = "获取所有目录菜单树") +// @RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR) + public R getAllPermissionTree() { + return R.success(permissionService.selectAllByTree()); + } + + /** + * 操作后的菜单类型是目录的时候 父级必须为目录 + * 操作后的菜单类型是菜单的时候,父类必须为目录类型 + * 操作后的菜单类型是按钮的时候 父类必须为菜单类型 + */ + private void verifyFormPid(SysPermission sysPermission) { + SysPermission parent; + parent = permissionService.getById(sysPermission.getPid()); + switch (sysPermission.getType()) { + case 1: + if (parent != null) { + if (parent.getType() != 1) { + throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_CATALOG_ERROR); + } + } else if (!"0".equals(sysPermission.getPid())) { + throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_CATALOG_ERROR); + } + break; + case 2: + if (parent == null || parent.getType() != 1) { + throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_MENU_ERROR); + } + if (StringUtils.isEmpty(sysPermission.getUrl())) { + throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_URL_NOT_NULL); + } + + break; + case 3: + if (parent == null || parent.getType() != 2) { + throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_BTN_ERROR); + } + if (StringUtils.isEmpty(sysPermission.getPerms())) { + throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_URL_PERMS_NULL); + } + if (StringUtils.isEmpty(sysPermission.getUrl())) { + throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_URL_NOT_NULL); + } + break; + default: + } + } +} diff --git a/src/main/java/com/huoran/iasf/controller/RoleController.java b/src/main/java/com/huoran/iasf/controller/RoleController.java new file mode 100644 index 0000000..a5d4107 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/RoleController.java @@ -0,0 +1,129 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysRole; +import com.huoran.iasf.entity.SysRolePermission; +import com.huoran.iasf.service.HttpSessionService; +import com.huoran.iasf.service.RolePermissionService; +import com.huoran.iasf.service.RoleService; +import com.huoran.iasf.vo.req.RolePermissionOperationReqVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * 角色管理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@RequestMapping("/sys") +@RestController +@Api(tags = "角色管理") +public class RoleController { + @Resource + private RoleService roleService; + @Resource + private RolePermissionService rolePermissionService; + @Resource + private HttpSessionService httpSessionService; + @NoRepeatSubmit + @PostMapping("/role") + @ApiOperation(value = "新增角色接口") + @LogAnnotation(title = "角色管理", action = "新增角色") + @RequiresPermissions("sys:role:add") + public R addRole(@RequestBody @Valid SysRole vo) { + boolean ok = roleService.checkDeptRepeat(vo); + if (ok) { + return R.fail("已存在相同的角色名称:" + vo.getName()); + } + roleService.addRole(vo); + //删除角色权限关联 + rolePermissionService.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getRoleId, vo.getId())); + if (!CollectionUtils.isEmpty(vo.getPermissions())) { + RolePermissionOperationReqVO reqVO = new RolePermissionOperationReqVO(); + reqVO.setRoleId(vo.getId()); + reqVO.setPermissionIds(vo.getPermissions()); + rolePermissionService.addRolePermission(reqVO); + // 刷新权限 + httpSessionService.refreshRolePermission(vo.getId()); + } + return R.success(); + } + + @DeleteMapping("/role/deleted") + @ApiOperation(value = "删除角色接口") + @LogAnnotation(title = "角色管理", action = "删除角色") + @RequiresPermissions("sys:role:deleted") + public R deleted(@RequestBody @ApiParam(value = "id集合") List ids) { + roleService.deletedRole(ids); + return R.success(); + } + + @PutMapping("/role") + @ApiOperation(value = "更新角色信息接口") + @LogAnnotation(title = "角色管理", action = "更新角色信息") + @RequiresPermissions("sys:role:update") + public R updateDept(@RequestBody SysRole vo) { + if (StringUtils.isEmpty(vo.getId())) { + return R.fail("id不能为空"); + } + boolean ok = roleService.checkDeptRepeat(vo); + if (ok) { + return R.fail("已存在相同的角色名称:" + vo.getName()); + } + roleService.updateRole(vo); + return R.success(); + } + + @GetMapping("/role/{id}") + @ApiOperation(value = "查询角色详情接口") + @LogAnnotation(title = "角色管理", action = "查询角色详情") +// @RequiresPermissions("sys:role:detail") + public R detailInfo(@PathVariable("id") String id) { + // return R.success(roleService.detailInfo(id)); + SysRole role = roleService.getById(id); + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("role_id", id).select("permission_id"); + List list = rolePermissionService.list(wrapper); + List permissionList = new ArrayList<>(); + list.forEach(rolePermission -> { + permissionList.add(rolePermission.getPermissionId()); + }); + HashMap map = new HashMap<>(); + map.put("role", role); + map.put("permissionList", permissionList); + return R.success(map); + } + + @PostMapping("/roles") + @ApiOperation(value = "分页获取角色信息接口") + @LogAnnotation(title = "角色管理", action = "分页获取角色信息") + @RequiresPermissions("sys:role:list") + @SuppressWarnings("unchecked") + public R pageInfo(@RequestBody SysRole vo) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + if (!StringUtils.isEmpty(vo.getName())) { + queryWrapper.like(SysRole::getName, vo.getName()); + } + queryWrapper.orderByDesc(SysRole::getCreateTime); + return R.success(roleService.page(vo.getQueryPage(), queryWrapper)); + } + +} diff --git a/src/main/java/com/huoran/iasf/controller/RolePermissionController.java b/src/main/java/com/huoran/iasf/controller/RolePermissionController.java new file mode 100644 index 0000000..367cf45 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/RolePermissionController.java @@ -0,0 +1,41 @@ +package com.huoran.iasf.controller; + +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.service.RolePermissionService; +import com.huoran.iasf.vo.req.RolePermissionOperationReqVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 角色和菜单关联 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@RequestMapping("/sys") +@RestController +@Api(tags = "角色菜单关联接口") +public class RolePermissionController { + @Resource + private RolePermissionService rolePermissionService; + + @PostMapping("/role/permission") + @ApiOperation(value = "修改或者新增角色菜单权限接口") + @LogAnnotation(title = "角色和菜单关联接口", action = "修改或者新增角色菜单权限") +// @RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR) + public R operationRolePermission(@RequestBody @Valid RolePermissionOperationReqVO vo) { + rolePermissionService.addRolePermission(vo); + return R.success(); + } +} diff --git a/src/main/java/com/huoran/iasf/controller/SiteController.java b/src/main/java/com/huoran/iasf/controller/SiteController.java new file mode 100644 index 0000000..5e3128a --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SiteController.java @@ -0,0 +1,93 @@ +package com.huoran.iasf.controller; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.Site; +import com.huoran.iasf.service.SiteService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + *

+ * 站点管理 前端控制器 + *

+ * + * @author cheney + * @since 2022-08-24 + */ +@RestController +@RequestMapping("/sys/site") +@Api(tags = "站点管理") +public class SiteController { + + @Autowired + private SiteService siteService; + + @PostMapping("/add") +// @ApiOperation(value = "新增站点") +// @LogAnnotation(title = "站点管理", action = "新增站点") +// @RequiresPermissions("sys:site:add") + public R addUserGroup(@RequestBody Site site) { + Site one = siteService.getOne(new QueryWrapper(). + eq("site_name", site.getSiteName())); + if (ObjectUtil.isNotNull(one)){ + R.fail("站点已存在"); + } + siteService.save(site); + return R.success(); + } + + @DeleteMapping("/delete/{id}") +// @ApiOperation(value = "删除站点") +// @LogAnnotation(title = "站点管理", action = "删除站点") +// @RequiresPermissions("sys:site:deleted") + public R deleted(@PathVariable("id") Integer id) { + siteService.removeById(id); + return R.success(); + } + + @PutMapping("/update") +// @ApiOperation(value = "更新站点") +// @LogAnnotation(title = "站点管理", action = "更新站点") +// @RequiresPermissions("sys:site:update") + public R updateUserGroup(@RequestBody Site site) { + if (StringUtils.isEmpty(site.getId())) { + return R.fail("id不能为空"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("domain_name", site.getDomainName()); + queryWrapper.last(" and id != " + site.getId()); + List groups = siteService.list(queryWrapper); + if (ObjectUtil.isNotNull(groups) && groups.size()>0){ + R.fail("域名已存在"); + } + siteService.updateById(site); + return R.success(); + } + + + @PostMapping("/list") + @ApiOperation(value = "站点列表") + @LogAnnotation(title = "站点管理", action = "获取所有站点") +// @RequiresPermissions("sys:site:list") + public R getUserGroupAll(@RequestBody Site site) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + if (!StringUtils.isEmpty(site.getSiteName())) { + queryWrapper.like(Site::getSiteName, site.getSiteName()); + } + IPage iPage = siteService.page(site.getQueryPage(),queryWrapper); + return R.success(iPage); + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysColumnController.java b/src/main/java/com/huoran/iasf/controller/SysColumnController.java new file mode 100644 index 0000000..1adaa55 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysColumnController.java @@ -0,0 +1,352 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.exception.NotFoundException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.entity.*; +import com.huoran.iasf.service.*; +import com.huoran.iasf.vo.req.ColumnWeightReqVO; +import com.huoran.iasf.vo.req.PaginationColumnReqVO; +import com.huoran.iasf.vo.resp.SortColumnRespVO; +import io.swagger.annotations.*; +import com.huoran.iasf.common.utils.R; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiOperation; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * @描述:栏目基础信息控制类 + * @作者: Rong + * @日期: 2022-08-01 + */ +@RestController +@RequestMapping("/sysColumn") +@Api(value = "栏目基础信息:SysColumnController", tags = "R-栏目管理") +public class SysColumnController { + + @Autowired + public SysColumnService service; + + @Autowired + public SysContentService contentService; + + @Autowired + public SysTemplateService templateService; + + @Autowired + public SysTemplateStyleService styleService; + + @Autowired + public SysColumnLongPageService sysColumnLongPageService; + + @Autowired + public SysTemplateStyleConfigurationService templateStyleConfigurationService; + + @Autowired + public SysFilesService sysFilesService; + + @PostMapping("/listWithTree") + @ApiOperation(value = "栏目树结构", response = SysColumn.class) + public R listWithTree(@RequestBody @Valid PaginationColumnReqVO sysColumn) { + return R.success(service.listWithTree(sysColumn)); + } + + @PostMapping("/listWithTreeMenuVisible") + @ApiOperation(value = "栏目树结构(前台可见,只展示试单可见的栏目)", response = SysColumn.class) + public R listWithTreeMenuVisible(@RequestBody @Valid PaginationColumnReqVO sysColumn) { + return R.success(service.listWithTreeMenuVisible(sysColumn)); + } + + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysColumn.class) + public R findById(@RequestParam("id") @ApiParam(value = "序号") Integer id) { + SysColumn sysColumn = service.getById(id); + if (sysColumn == null) { + throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST); + } + SysTemplateStyle sysTemplateStyle = styleService.getById(sysColumn.getListStyleId()); + + if (sysTemplateStyle.getPath() != null) { + sysColumn.setPath(sysTemplateStyle.getPath()); + } + + return R.success(sysColumn); + } + + @NoRepeatSubmit + @PostMapping("/save") + @ApiOperation(value = "新增", response = SysColumn.class) + public R save(@RequestBody @Valid SysColumn sysColumn) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("father_id", sysColumn.getFatherId()); + Integer count = service.count(queryWrapper); + sysColumn.setSort(count + 1); + boolean addState = service.save(sysColumn); + return addState ? R.success(sysColumn.getId()) : R.fail("新增失败"); + } + + @PostMapping("/update") + @ApiOperation(value = "修改", response = SysColumn.class) + public R update(@RequestBody SysColumn sysColumn) { + boolean updateState = service.updateById(sysColumn); + return updateState ? R.success() : R.fail("编辑失败"); + } + + /*@NoRepeatSubmit + @PostMapping("/delete") + @ApiOperation(value = "删除", response = SysContent.class) + public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + UpdateWrapper filesEntityUpdateWrapper = new UpdateWrapper<>(); + filesEntityUpdateWrapper.eq("quote_id", id); + filesEntityUpdateWrapper.eq("quote_type", 1); + filesEntityUpdateWrapper.set("is_del", 1); + sysFilesService.update(filesEntityUpdateWrapper); + + boolean delState = service.removeById(id); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("column_id", id); + //删除栏目后删除栏目下的文章 + List contentId = contentService.list(queryWrapper); + contentService.removeByIds(contentId); + + return delState ? R.success() : R.fail("删除失败"); + }*/ + + @NoRepeatSubmit + @PostMapping("/batchDeletion") + @ApiOperation(value = "批量删除栏目", response = SysColumn.class) + public R batchDeletion(@ApiParam(name = "ids", value = "主键", required = true) @RequestParam List ids) { + boolean ret = false; + for (Integer id : ids) { + UpdateWrapper filesEntityUpdateWrapper = new UpdateWrapper<>(); + filesEntityUpdateWrapper.eq("quote_id", id); + filesEntityUpdateWrapper.eq("quote_type", 1); + filesEntityUpdateWrapper.set("is_del", 1); + sysFilesService.update(filesEntityUpdateWrapper); + //1 创建list集合,用于封装所有删除菜单id值 + List idList = new ArrayList<>(); + //2 向idList集合设置删除菜单id + //找到当前菜单的子菜单 把结果id封装到idlist里面去 + this.selectCategoryChildById(id + "", idList); + //把当前id封装到list里面 //现在把当前id封装进去 之前都是子菜单的id + idList.add(id); + + //删除当前栏目以及栏目下的文章 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("column_id", idList); + //删除栏目后删除栏目下的文章 + contentService.remove(queryWrapper); + + + //删除长页栏目 + QueryWrapper queryWrapper1 = new QueryWrapper(); + queryWrapper1.in("column_id", idList); + //删除栏目后删除栏目下的文章 + sysColumnLongPageService.remove(queryWrapper1); + ret = service.removeByIds(idList); + } + + + return R.success(); + } + + + @PostMapping("/sameLevelJudgment") + @ApiOperation(value = "同级判重", response = ColumnWeightReqVO.class) + public R sameLevelJudgment(@RequestBody @Valid ColumnWeightReqVO sysColumn) { + return service.sameLevelJudgment(sysColumn) ? R.success() : R.fail("同级下已存在重复栏目!"); + } + + @PostMapping("/sortByColumn") + @ApiOperation(value = "栏目排序(依据id更改)", response = SysColumn.class) + public R sortByColumn(@RequestBody List sortColumnRespVOList) { + for (SortColumnRespVO sort : sortColumnRespVOList) { + + SysColumn column = service.getById(sort.getId()); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("column_name", column.getColumnName()); + queryWrapper.eq("site_id", column.getSiteId()); + queryWrapper.eq("father_id", sort.getFatherId()); + queryWrapper.last(" and id <> " + sort.getId()); + List columnList = service.list(queryWrapper); + if (columnList.size() > 0) { + return R.fail("同级下已存在重复栏目:" + column.getColumnName()); + } + + SysColumn sysColumn = new SysColumn(); + BeanUtils.copyProperties(sort, sysColumn); + service.updateById(sysColumn); + } + + return R.success(); + } + + @ApiOperation("获取一级下的子级栏目") + @PostMapping("/getsTheSubColumn") + public R getsTheSubColumn(@ApiParam(name = "id", value = "id", required = true) @RequestParam Integer id, + @ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId) { + String ids = this.getIds(id); + return service.getsTheSubColumn(id, ids,siteId); + + } + + + @ApiOperation("获取某层级下的子级栏目") + @PostMapping("/getsSublevelColumnsUnderALevel") + public R getsSublevelColumnsUnderALevel(@ApiParam(name = "id", value = "id", required = true) @RequestParam Integer id, + @ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId) { + String ids = this.getIds(id); + return service.getsTheSubColumn(id, ids,siteId); + + } + + + public String getIds(Integer id) { + //1 创建list集合,用于封装所有删除菜单id值 + List idList = new ArrayList<>(); + //2 向idList集合设置删除菜单id + this.selectCategoryChildById(id + "", idList);//找到当前菜单的子菜单 把结果id封装到idlist里面去 + //把当前id封装到list里面 + idList.add(id);//现在把当前id封装进去 之前都是子菜单的id + String str = ""; + for (Integer idstr : idList) { + str += idstr + ","; + } + String ids = str.substring(0, str.length() - 1); + return ids; + } + + public void selectCategoryChildById(String id, List idList) { + //查询菜单里面子菜单id + QueryWrapper wrapper = new QueryWrapper(); + wrapper.eq("father_id", id); + wrapper.eq("deleted", Constant.DATA_NOT_DELETED); + //查询指定列的值 + wrapper.select("id"); + //当前菜单的所有子菜单 + List childIdList = service.list(wrapper); + //把childIdList里面菜单id值获取出来,封装idList里面,做递归查询 + //遍历集合得到每一个对象item + childIdList.stream().forEach(item -> { + //封装idList里面 + idList.add(item.getId()); + //递归查询 + this.selectCategoryChildById(item.getId() + "", idList); + }); + } + + + @ApiOperation("获取一级下的子级栏目以及下的全部文章标签") + @PostMapping("/getTheFullArticleByColumn") + public R getTheFullArticleByColumn(@ApiParam(name = "id", value = "一级栏目id", required = true) @RequestParam Integer id) { + String ids = this.getIds(id); + return contentService.getTheFullArticleByColumn(ids); + } + + + @ApiOperation("获取子级栏目id") + @PostMapping("/getsTheChildColumnId") + public R getsTheSublevelColumnIdOfTheNextLevel(@ApiParam(name = "id", value = "一级栏目id", required = true) @RequestParam Integer id) { + //1 创建list集合,用于封装所有删除菜单id值 + List idList = new ArrayList<>(); + //2 向idList集合设置删除菜单id + this.selectCategoryChildById(id + "", idList);//找到当前菜单的子菜单 把结果id封装到idlist里面去 + //把当前id封装到list里面 + idList.add(id);//现在把当前id封装进去 之前都是子菜单的id + return R.success(idList); + + } + + @ApiOperation("某一级查全部") + @PostMapping("/oneLevelChecksThemAll") + public R oneLevelChecksThemAll(@ApiParam(name = "id", value = "栏目id", required = true) @RequestParam Integer id, + @ApiParam(name = "isSort", value = "判断是否为排序接口调用(1为排序接口调用 0我栏目管理列表调用)", required = true) @RequestParam Integer isSort, + @ApiParam(name = "ids", value = "主键", required = true) @RequestParam Integer siteId + ) { + + Integer pid = service.oneLevelChecksThemAll(id); + String ids = this.getIds(pid); + return service.getSubColumn(pid, ids, isSort,siteId); + } + + + /** + * 查询栏目下的文章(若选中栏目与子级全部栏目类型一致返回全部文章,反之查询选中栏目下的文章) + * 2023.02.22依需求更改为以发布时间排序(非创建时间) + * + * @param columnId + * @return + */ + @ApiOperation("查询栏目下的文章(若选中栏目与子级全部栏目类型一致返回全部文章,反之查询选中栏目下的文章)") + @PostMapping("/queryArticlesByColumnType") + public R queryArticlesByColumnType(@ApiParam(name = "columnId", value = "栏目id", required = true) @RequestParam Integer columnId) { + String ids = this.getIds(columnId); + return service.queryArticlesByColumnType(ids, columnId); + } + + + @NoRepeatSubmit + @PostMapping("/deleteUselessData") + @ApiOperation(value = "删除无用数据", response = SysColumn.class) + public R deleteUselessData() { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("deleted", 0).select("id"); + List list = service.list(queryWrapper); + + for (SysColumn column : list) { + UpdateWrapper filesEntityUpdateWrapper = new UpdateWrapper<>(); + filesEntityUpdateWrapper.eq("quote_id", column.getId()); + filesEntityUpdateWrapper.eq("quote_type", 1); + filesEntityUpdateWrapper.set("is_del", 1); + sysFilesService.update(filesEntityUpdateWrapper); + //1 创建list集合,用于封装所有删除菜单id值 + List idList = new ArrayList<>(); + //2 向idList集合设置删除菜单id + //找到当前菜单的子菜单 把结果id封装到idlist里面去 + this.selectCategoryChildById(column.getId() + "", idList); + //把当前id封装到list里面 //现在把当前id封装进去 之前都是子菜单的id + idList.add(column.getId()); + + //删除当前栏目以及栏目下的文章 + QueryWrapper queryWrapper1 = new QueryWrapper<>(); + queryWrapper1.in("column_id", idList); + //删除栏目后删除栏目下的文章 + contentService.remove(queryWrapper1); + + + //删除长页栏目 + QueryWrapper queryWrapper2 = new QueryWrapper(); + queryWrapper2.in("column_id", idList); + //删除栏目后删除栏目下的文章 + sysColumnLongPageService.remove(queryWrapper2); + service.removeByIds(idList); + } + + + return R.success(); + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysColumnLongPageController.java b/src/main/java/com/huoran/iasf/controller/SysColumnLongPageController.java new file mode 100644 index 0000000..5a58038 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysColumnLongPageController.java @@ -0,0 +1,145 @@ +package com.huoran.iasf.controller; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.common.exception.NotFoundException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.service.SysColumnService; +import com.huoran.iasf.vo.req.SysColumnLongRedisVO; +import io.swagger.annotations.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.common.utils.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.apache.commons.lang.StringUtils; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import com.huoran.iasf.service.SysColumnLongPageService; +import com.huoran.iasf.entity.SysColumnLongPage; + +import javax.validation.Valid; +import java.util.List; +import java.util.concurrent.TimeUnit; + + +/** + * @描述:长页栏目拓展表控制类 + * @作者: Rong + * @日期: 2022-08-09 + */ +@RestController +@RequestMapping("/sysColumnLongPage") +@Api(value = "长页栏目拓展表:SysColumnLongPageController", tags = "R-长页栏目拓展信息") +public class SysColumnLongPageController { + + @Autowired + public SysColumnLongPageService service; + @Autowired + public SysColumnService columnService; + @Autowired + private StringRedisTemplate redisTemplate; + + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysColumnLongPage.class) + public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + SysColumnLongPage sysColumnLongPage = service.getById(id); + if (sysColumnLongPage == null) { + throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST); + } + return R.success(sysColumnLongPage); + } + + + @PostMapping("/getLongPageInformation") + @ApiOperation(value = "根据栏目id查询类型长页栏目信息", response = SysColumnLongPage.class) + public R getLongPageInformation(@ApiParam(name = "columnId", value = "栏目id", required = true) @RequestParam Integer columnId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("column_id", columnId); + List longPageList = service.list(queryWrapper); + return R.success(longPageList); + } + + + @PostMapping("/save") + @ApiOperation(value = "新增", response = SysColumnLongPage.class) + public R save(@RequestBody @Valid @ApiParam(name = "长页栏目拓展表对象", value = "传入json格式", required = true) SysColumnLongPage sysColumnLongPage) { + + SysColumn column = columnService.getById(sysColumnLongPage.getColumnId()); + if (sysColumnLongPage.getState() == Constant.ARTICLE_NOT_PUBLISHED) {//发布状态(0:草稿 1已发布) + //发布状态为草稿箱时候 导航菜单是否启用为禁用状态 + column.setMenuVisible(Constant.THE_NAVIGATION_MENU_IS_NOT_VISIBLE); + } else { + column.setMenuVisible(Constant.NAVIGATION_MENU_VISIBLE); + } + + columnService.updateById(column); + boolean addState = service.save(sysColumnLongPage); + return addState ? R.success() : R.fail("新增失败"); + } + + + @PostMapping("/update") + @ApiOperation(value = "修改", response = SysColumnLongPage.class) + public R update(@RequestBody @ApiParam(name = "长页栏目拓展表对象", value = "传入json格式", required = true) SysColumnLongPage sysColumnLongPage) { + SysColumn column = columnService.getById(sysColumnLongPage.getColumnId()); + if (sysColumnLongPage.getState() == Constant.ARTICLE_NOT_PUBLISHED) {//发布状态(0:草稿 1已发布) + //发布状态为草稿箱时候 导航菜单是否启用为禁用状态 + column.setMenuVisible(Constant.THE_NAVIGATION_MENU_IS_NOT_VISIBLE); + + } else { + column.setMenuVisible(Constant.NAVIGATION_MENU_VISIBLE); + } + + columnService.updateById(column); + boolean updateState = service.updateById(sysColumnLongPage); + return updateState ? R.success() : R.fail("编辑失败"); + } + + + @PostMapping("/delete") + @ApiOperation(value = "删除", response = SysColumnLongPage.class) + public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + boolean delState = service.removeById(id); + return delState ? R.success() : R.fail("删除失败"); + } + + + @PostMapping("/saveTheCache") + @ApiOperation(value = "预览至储存(整个页面存储)") + public R saveTheCache(@RequestBody @ApiParam(name = "预览至储存对象", required = true) SysColumnLongRedisVO vo) { + String key = "saveTheCache:columnId:" + vo.getColumnId(); + //保存到缓存中 + redisTemplate.opsForValue().set(key, vo.getJson()); + return R.success(); + } + + + @PostMapping("/getRedisCache") + @ApiOperation(value = "获取Redis缓存") + public R getRedisCache(@ApiParam(name = "columnId", value = "栏目id主键", required = true) @RequestParam Integer columnId) { + //保存的key名 + String key = "saveTheCache:columnId:" + columnId; + //查看缓存是否有数据 + String returnValue = redisTemplate.opsForValue().get(key); + + //使用缓存返回数据 + if (returnValue != null) { + return R.success(returnValue); + } + + + return R.success(); + } + +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysContentClassificationController.java b/src/main/java/com/huoran/iasf/controller/SysContentClassificationController.java new file mode 100644 index 0000000..951947c --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysContentClassificationController.java @@ -0,0 +1,115 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.common.exception.NotFoundException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysContentClassification; +import com.huoran.iasf.service.SysContentClassificationService; +import io.swagger.annotations.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.beans.factory.annotation.Autowired; +import org.apache.commons.lang.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; + +import javax.validation.Valid; +import java.util.List; + + +/** + * @描述:文章所属分类控制类 + * @作者: Rong + * @日期: 2022-11-08 + */ +@RestController +@RequestMapping("/content/classification") +@Api(value = "文章所属分类:SysContentClassificationController", tags = "R-文章所属分类") +public class SysContentClassificationController { + + @Autowired + public SysContentClassificationService service; + + + @PostMapping("/allTheQuery") + @ApiOperation(value = "查询全部文章所属分类", response = SysContentClassification.class) + public R allTheQuery(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId, + @ApiParam(name = "templateId", value = "模板id", required = true) @RequestParam Integer templateId) { + List list = service.list(new QueryWrapper() + .eq("site_id", siteId).eq("template_id",templateId)); + return R.success(list); + } + + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysContentClassification.class) + public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + SysContentClassification sysContentClassification = service.getById(id); + if (sysContentClassification == null) { + throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST); + } + return R.success(sysContentClassification); + } + + + @PostMapping("/checkForHeavy") + @ApiOperation(value = "分类校验判重", response = SysContentClassification.class) + public R checkForHeavy(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId, + @ApiParam(name = "classificationName", value = "分类名称", required = true) @RequestParam String classificationName, + @ApiParam(name = "classificationId", value = "分类id(新增不传,编辑传)", required = false) @RequestParam Integer classificationId) { + + QueryWrapper queryWrapper = new QueryWrapper().eq("site_id", siteId). + eq("classification_name", classificationName); + + //id不得空表示编辑校验 + if (classificationId != null) { + queryWrapper.last(" and id != " + classificationId); + } + SysContentClassification sysContentClassification = service.getOne(queryWrapper); + if (sysContentClassification != null) { + return R.fail("当前分类名称已存在!"); + } + return R.success(); + + } + + + @PostMapping("/save") + @ApiOperation(value = "新增", response = SysContentClassification.class) + public R save(@RequestBody @Valid @ApiParam(name = "文章所属分类对象", value = "传入json格式", required = true) SysContentClassification sysContentClassification) { + boolean addState = service.save(sysContentClassification); + return addState ? R.success() : R.fail("新增失败"); + } + + + @PostMapping("/update") + @ApiOperation(value = "修改", response = SysContentClassification.class) + public R update(@RequestBody @ApiParam(name = "文章所属分类对象", value = "传入json格式", required = true) SysContentClassification sysContentClassification) { + boolean updateState = service.updateById(sysContentClassification); + return updateState ? R.success() : R.fail("编辑失败"); + } + + + @PostMapping("/delete") + @ApiOperation(value = "删除", response = SysContentClassification.class) + public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + boolean delState = service.removeById(id); + return delState ? R.success() : R.fail("删除失败"); + } + + @PostMapping("/batchDeletion") + @ApiOperation(value = "批量删除", response = SysContentClassification.class) + public R batchDeletion(@ApiParam(name = "id", value = "主键", required = true) @RequestParam List ids) { + boolean delState = service.removeByIds(ids); + return delState ? R.success() : R.fail("删除失败"); + // + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysContentController.java b/src/main/java/com/huoran/iasf/controller/SysContentController.java new file mode 100644 index 0000000..f5fee2d --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysContentController.java @@ -0,0 +1,254 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.huoran.iasf.common.exception.NotFoundException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.entity.SysContentFile; +import com.huoran.iasf.entity.SysFilesEntity; +import com.huoran.iasf.service.SysColumnService; +import com.huoran.iasf.service.SysContentFileService; +import com.huoran.iasf.service.SysFilesService; +import com.huoran.iasf.vo.req.ArticleModifiedSortReq; +import com.huoran.iasf.vo.req.ContentHeavyTitleReqVO; +import com.huoran.iasf.vo.req.ContentReq; +import com.huoran.iasf.vo.req.PageContentReqVO; +import com.huoran.iasf.vo.resp.PageContentRespVO; +import io.swagger.annotations.*; +import com.huoran.iasf.common.utils.R; +import org.apache.ibatis.annotations.Update; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiOperation; +import com.huoran.iasf.service.SysContentService; +import com.huoran.iasf.entity.SysContent; + +import javax.validation.Valid; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +/** + * @描述:文章管理控制类 + * @作者: Rong + * @日期: 2022-08-05 + */ +@RestController +@RequestMapping("/sysContent") +@Api(value = "文章管理:SysContentController", tags = "R-文章管理") +public class SysContentController { + + @Autowired + public SysContentService service; + @Autowired + public SysColumnService columnService; + + @Autowired + public SysContentFileService fileService; + + @Autowired + public SysFilesService sysFilesService; + + + @PostMapping("/pagingQuery") + @ApiOperation(value = "分页查询文章列表", response = PageContentRespVO.class) + public R pagingQuery(@RequestBody @Valid @ApiParam(name = "分页查询参数", value = "传入json格式", required = true) PageContentReqVO sysContent) { + return service.articlePaginationList(sysContent); + } + + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysContent.class) + public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + + + SysContent sysContent = service.getById(id); + if (sysContent == null) { + throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST); + } + + SysColumn sysColumn = columnService.getById(sysContent.getColumnId()); + if (sysColumn == null) { + throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST); + } + /*if (sysColumn == null) { + throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST); + }*/ + if (sysColumn.getColumnName() != null) { + sysContent.setColumnName(sysColumn.getColumnName()); + } + List fileList = fileService.getFileByContentId(id); + sysContent.setFileList(fileList); + + + return R.success(sysContent); + } + + @PostMapping("/save") + @ApiOperation(value = "新增", response = SysContent.class) + public R save(@RequestBody @Valid @ApiParam(name = "文章管理对象", value = "传入json格式", required = true) SysContent sysContent) { + + /* QueryWrapper queryWrap = new QueryWrapper<>(); + queryWrap.eq("column_id", sysContent.getColumnId()); + queryWrap.eq("deleted", 1); + Integer count = service.count(queryWrap); + if (count == 0) { + count = 1; + } + sysContent.setSequence(count + 1);*/ + boolean addState = service.save(sysContent); + + + return addState ? R.success(sysContent.getId()) : R.fail("新增失败"); + } + + + @PostMapping("/update") + @ApiOperation(value = "修改", response = SysContent.class) + public R update(@RequestBody @ApiParam(name = "文章管理对象", value = "传入json格式", required = true) SysContent sysContent) { + boolean updateState = service.updateById(sysContent); + return updateState ? R.success() : R.fail("编辑失败"); + } + + + @PostMapping("/delete") + @ApiOperation(value = "删除", response = SysContent.class) + public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + UpdateWrapper queryWrapper = new UpdateWrapper<>(); + queryWrapper.eq("quote_id", id); + queryWrapper.eq("quote_type", 0); + queryWrapper.set("is_del", 1); + sysFilesService.update(queryWrapper); + boolean delState = service.removeById(id); + return delState ? R.success() : R.fail("删除失败"); + } + + + @PostMapping("/batchDeletion") + @ApiOperation(value = "批量删除文章", response = SysContent.class) + public R batchDeletion(@ApiParam(name = "ids", value = "主键", required = true) @RequestParam List ids) { + for (Integer id : ids) { + UpdateWrapper queryWrapper = new UpdateWrapper<>(); + queryWrapper.eq("quote_id", id); + queryWrapper.eq("quote_type", 0); + queryWrapper.set("is_del", 1); + sysFilesService.update(queryWrapper); + } + boolean delState = service.removeByIds(ids); + return delState ? R.success() : R.fail("删除失败"); + } + + @PostMapping("/checkIfTheTitleIsRepeat") + @ApiOperation(value = "标题判重——只对已发布的判重(新增,编辑,点击发布时候都要调用判断))", response = ContentHeavyTitleReqVO.class) + public R checkIfTheTitleIsRepeat(@RequestBody @Valid ContentHeavyTitleReqVO content) { + return service.checkIfTheTitleIsRepeat(content) ? R.success() : R.fail("该标题已重复!"); + } + + @PostMapping("/newlyPublishedArticles") + @ApiOperation(value = "站点最新发布的文章", response = PageContentReqVO.class) + public R newlyPublishedArticles(@Valid @RequestBody PageContentReqVO content) { + return service.newlyPublishedArticles(content); + } + + + /*查询已发布的、启用了的文章列表接口*/ +/* @PostMapping("/publishedEnabledArticles") + @ApiOperation(value = "查询已发布的、启用了的文章列表", response = PageContentReqVO.class) + public R publishedEnabledArticles() { + return service.publishedEnabledArticles(); + }*/ + + + /** + * 获取栏目下的文章 + * + * @param pageReq + * @return + */ + @PostMapping("/getColumnArticles") + @ApiOperation(value = "获取栏目下的文章", response = SysContent.class) + public R getColumnArticles(@RequestBody @ApiParam(name = "文章管理对象", value = "传入json格式", required = true) ContentReq pageReq) { + IPage page = new Page(pageReq.getPageNum(), pageReq.getPageSize()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("column_id", pageReq.getColumnIds()); + IPage iPage = service.page(page, queryWrapper); + return R.success(iPage); + } + + + @PostMapping("/articleEnableOrDisable") + @ApiOperation(value = "文章启用禁用", response = SysContent.class) + public R articleEnableOrDisable(@ApiParam(name = "id", value = "文章id", required = true) @RequestParam Integer id, @ApiParam(name = "isDisable", value = "是否禁用(0默认,0启用 1禁用)", required = true) @RequestParam Integer isDisable) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set("is_disable", isDisable); + updateWrapper.eq("id", id); + boolean ret = service.update(updateWrapper); + return ret ? R.success() : R.fail("禁用/启用失败"); + } + + @PostMapping("/articlePreview") + @ApiOperation(value = "增加文章浏览量(点击一次算一次)", response = SysContent.class) + public R articlePreview(@ApiParam(name = "contentId", value = "文章id", required = true) @RequestParam Integer contentId) { + return R.success(service.statisticsOfPageViews(contentId)); + + } + + + @PostMapping("/hotContent") + @ApiOperation(value = "热点内容", response = SysContent.class) + public R hotContent(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId) { + return R.success(service.hotContent(siteId)); + + } + + @PostMapping("/siteSearchArticles") + @ApiOperation(value = "站点搜索文章", response = SysContent.class) + public R siteSearchArticles(@RequestBody PageContentReqVO req) { + return service.siteSearchArticles(req); + + } + + + @PostMapping("/articleTopOperation") + @ApiOperation(value = "文章置顶/取消置顶", response = SysContent.class) + public R articleTopOperation(@ApiParam(name = "isTop", value = "是否置顶(默认为0 不置顶 1为置顶)", required = true) @RequestParam Integer isTop, @ApiParam(name = "articleId", value = "文章Id", required = true) @RequestParam Integer articleId) { + //是否置顶(默认为0 不置顶 1为置顶) + UpdateWrapper updateWrap = new UpdateWrapper<>(); + + if (isTop == 1) { + //置顶时间(置顶一次更新一次) + updateWrap.set("top_time", new Date()); + } else { + updateWrap.set("top_time", null); + } + updateWrap.set("is_top", isTop); + updateWrap.eq("id", articleId); + updateWrap.eq("deleted", 1); + boolean ret = service.update(updateWrap); + return ret ? R.success() : R.fail("操作失败"); + + } + + + @PostMapping("/queryArticleColumnParent") + @ApiOperation(value = "查询文章的栏目父级", response = PageContentReqVO.class) + public R queryArticleColumnParent(@ApiParam(name = "articleId", value = "文章id", required = true) @RequestParam Integer articleId) { + return service.queryArticleColumnParent(articleId); + } + + + +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysContentFileController.java b/src/main/java/com/huoran/iasf/controller/SysContentFileController.java new file mode 100644 index 0000000..6c953f9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysContentFileController.java @@ -0,0 +1,82 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysContentFile; +import com.huoran.iasf.service.SysContentFileService; +import io.swagger.annotations.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiOperation; + +import java.util.List; + + +/** + * @描述:文章附件管理表控制类 + * @作者: Rong + * @日期: 2022-11-07 + */ +@RestController +@RequestMapping("/content/file") +@Api(value = "文章附件管理表:SysContentFileController", tags = "文章附件管理表") +public class SysContentFileController { + + @Autowired + public SysContentFileService service; + + + @PostMapping("/theAttachmentUnderTheQueryColumn") + @ApiOperation(value = "查询文章id下的附件", response = SysContentFile.class) + public R theAttachmentUnderTheQueryColumn(@ApiParam(name = "contentId", value = "文章id", required = true) @RequestParam Integer contentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("content_id",contentId); + List sysContentFile = service.list(queryWrapper); + return R.success(sysContentFile); + } + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysContentFile.class) + public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + SysContentFile sysContentFile = service.getById(id); + return R.success(sysContentFile); + } + + @NoRepeatSubmit + @PostMapping("/save") + @ApiOperation(value = "新增", response = SysContentFile.class) + public R save(@RequestBody @ApiParam(name = "文章附件管理表对象", value = "传入json格式", required = true) SysContentFile sysContentFile) { + boolean addState = service.save(sysContentFile); + return addState ? R.success(sysContentFile.getId()) : R.fail("新增失败"); + } + + + @PostMapping("/update") + @ApiOperation(value = "修改", response = SysContentFile.class) + public R update(@RequestBody @ApiParam(name = "文章附件管理表对象", value = "传入json格式", required = true) SysContentFile sysContentFile) { + boolean updateState = service.updateById(sysContentFile); + return updateState ? R.success() : R.fail("编辑失败"); + } + + @NoRepeatSubmit + @PostMapping("/delete") + @ApiOperation(value = "删除", response = SysContentFile.class) + public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + boolean delState = service.removeById(id); + return delState ? R.success() : R.fail("删除失败"); + } + + @PostMapping("/batchDeletion") + @ApiOperation(value = "批量删除", response = SysContentFile.class) + public R batchDeletion(@ApiParam(name = "id", value = "主键", required = true) @RequestParam List ids) { + boolean delState = service.removeByIds(ids); + return delState ? R.success() : R.fail("删除失败"); + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysContentLabelController.java b/src/main/java/com/huoran/iasf/controller/SysContentLabelController.java new file mode 100644 index 0000000..5634d13 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysContentLabelController.java @@ -0,0 +1,107 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.common.exception.NotFoundException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysContentClassification; +import com.huoran.iasf.entity.SysContentLabel; +import com.huoran.iasf.service.SysContentLabelService; +import io.swagger.annotations.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.apache.commons.lang.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiOperation; + +import javax.validation.Valid; +import java.util.List; + + +/** + * @描述:文章主题标签控制类 + * @作者: Rong + * @日期: 2022-11-08 + */ +@RestController +@RequestMapping("/content/label") +@Api(value = "文章主题标签:SysContentLabelController", tags = "R-文章主题标签") +public class SysContentLabelController { + + @Autowired + public SysContentLabelService service; + + + @PostMapping("/queryAllArticleSubjectTags") + @ApiOperation(value = "查询全部文章主题标签", response = SysContentLabel.class) + public R queryAllArticleSubjectTags(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId) { + List list = service.list(new QueryWrapper().eq("site_id", siteId)); + return R.success(list); + } + + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysContentLabel.class) + public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + SysContentLabel sysContentLabel = service.getById(id); + if (sysContentLabel == null) { + throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST); + } + return R.success(sysContentLabel); + } + + + @PostMapping("/save") + @ApiOperation(value = "新增", response = SysContentLabel.class) + public R save(@RequestBody @Valid @ApiParam(name = "文章主题标签对象", value = "传入json格式", required = true) SysContentLabel sysContentLabel) { + boolean addState = service.save(sysContentLabel); + return addState ? R.success() : R.fail("新增失败"); + } + + + @PostMapping("/checkForHeavy") + @ApiOperation(value = "标签校验判重", response = SysContentLabel.class) + public R checkForHeavy(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId, @ApiParam(name = "labelName", value = "标签名称", required = true) @RequestParam String labelName, @ApiParam(name = "labelId", value = "标签id(新增不传,编辑传)", required = false) @RequestParam Integer labelId) { + + QueryWrapper queryWrapper = new QueryWrapper().eq("site_id", siteId).eq("label_name", labelName); + + //id不得空表示编辑校验 + if (labelId != null) { + queryWrapper.last(" and id != " + labelId); + } + SysContentLabel contentLabel = service.getOne(queryWrapper); + if (contentLabel != null) { + return R.fail("当前标签名称已存在!"); + } + return R.success(); + + } + + + @PostMapping("/update") + @ApiOperation(value = "修改", response = SysContentLabel.class) + public R update(@RequestBody @ApiParam(name = "文章主题标签对象", value = "传入json格式", required = true) SysContentLabel sysContentLabel) { + boolean updateState = service.updateById(sysContentLabel); + return updateState ? R.success() : R.fail("编辑失败"); + } + + + @PostMapping("/delete") + @ApiOperation(value = "删除", response = SysContentLabel.class) + public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + boolean delState = service.removeById(id); + return delState ? R.success() : R.fail("删除失败"); + } + + @PostMapping("/batchDeletion") + @ApiOperation(value = "批量删除", response = SysContentLabel.class) + public R batchDeletion(@ApiParam(name = "id", value = "主键", required = true) @RequestParam List ids) { + boolean delState = service.removeByIds(ids); + return delState ? R.success() : R.fail("删除失败"); + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysDictController.java b/src/main/java/com/huoran/iasf/controller/SysDictController.java new file mode 100644 index 0000000..38ff063 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysDictController.java @@ -0,0 +1,100 @@ +/* +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysDictDetailEntity; +import com.huoran.iasf.entity.SysDictEntity; +import com.huoran.iasf.service.SysDictDetailService; +import com.huoran.iasf.service.SysDictService; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + + +*/ +/** + * 字典管理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +// @Api(tags = "字典管理") +// @RestController +// @RequestMapping("/sysDict") +public class SysDictController { + @Resource + private SysDictService sysDictService; + @Resource + private SysDictDetailService sysDictDetailService; + + + @ApiOperation(value = "新增") + @PostMapping("/add") + @RequiresPermissions("sysDict:add") + public R add(@RequestBody SysDictEntity sysDict) { + if (StringUtils.isEmpty(sysDict.getName())) { + return R.fail("字典名称不能为空"); + } + SysDictEntity q = sysDictService.getOne(Wrappers.lambdaQuery().eq(SysDictEntity::getName, sysDict.getName())); + if (q != null) { + return R.fail("字典名称已存在"); + } + sysDictService.save(sysDict); + return R.success(); + } + + @ApiOperation(value = "删除") + @DeleteMapping("/delete") + @RequiresPermissions("sysDict:delete") + public R delete(@RequestBody @ApiParam(value = "id集合") List ids) { + sysDictService.removeByIds(ids); + //删除detail + sysDictDetailService.remove(Wrappers.lambdaQuery().in(SysDictDetailEntity::getDictId, ids)); + return R.success(); + } + + @ApiOperation(value = "更新") + @PutMapping("/update") + @RequiresPermissions("sysDict:update") + public R update(@RequestBody SysDictEntity sysDict) { + if (StringUtils.isEmpty(sysDict.getName())) { + return R.fail("字典名称不能为空"); + } + + SysDictEntity q = sysDictService.getOne(Wrappers.lambdaQuery().eq(SysDictEntity::getName, sysDict.getName())); + if (q != null && !q.getId().equals(sysDict.getId())) { + return R.fail("字典名称已存在"); + } + + sysDictService.updateById(sysDict); + return R.success(); + } + + @ApiOperation(value = "查询分页数据") + @PostMapping("/listByPage") + @RequiresPermissions("sysDict:list") + public R findListByPage(@RequestBody SysDictEntity sysDict) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + //查询条件示例 + if (!StringUtils.isEmpty(sysDict.getName())) { + queryWrapper.like(SysDictEntity::getName, sysDict.getName()); + queryWrapper.or(); + queryWrapper.like(SysDictEntity::getRemark, sysDict.getName()); + } + queryWrapper.orderByAsc(SysDictEntity::getName); + IPage iPage = sysDictService.page(sysDict.getQueryPage(), queryWrapper); + return R.success(iPage); + } + +} +*/ diff --git a/src/main/java/com/huoran/iasf/controller/SysDictDetailController.java b/src/main/java/com/huoran/iasf/controller/SysDictDetailController.java new file mode 100644 index 0000000..7662f1c --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysDictDetailController.java @@ -0,0 +1,94 @@ +/* +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysDictDetailEntity; +import com.huoran.iasf.service.SysDictDetailService; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + + +*/ +/** + * 字典明细管理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +// @Api(tags = "字典明细管理") +// @RestController +// @RequestMapping("/sysDictDetail") +public class SysDictDetailController { + @Resource + private SysDictDetailService sysDictDetailService; + + @ApiOperation(value = "新增") + @PostMapping("/add") + @RequiresPermissions("sysDict:add") + public R add(@RequestBody SysDictDetailEntity sysDictDetail) { + if (StringUtils.isEmpty(sysDictDetail.getValue())) { + return R.fail("字典值不能为空"); + } + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysDictDetailEntity::getValue, sysDictDetail.getValue()); + queryWrapper.eq(SysDictDetailEntity::getDictId, sysDictDetail.getDictId()); + SysDictDetailEntity q = sysDictDetailService.getOne(queryWrapper); + if (q != null) { + return R.fail("字典名称-字典值已存在"); + } + sysDictDetailService.save(sysDictDetail); + return R.success(); + } + + @ApiOperation(value = "删除") + @DeleteMapping("/delete") + @RequiresPermissions("sysDict:delete") + public R delete(@RequestBody @ApiParam(value = "id集合") List ids) { + sysDictDetailService.removeByIds(ids); + return R.success(); + } + + @ApiOperation(value = "更新") + @PutMapping("/update") + @RequiresPermissions("sysDict:update") + public R update(@RequestBody SysDictDetailEntity sysDictDetail) { + if (StringUtils.isEmpty(sysDictDetail.getValue())) { + return R.fail("字典值不能为空"); + } + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysDictDetailEntity::getValue, sysDictDetail.getValue()); + queryWrapper.eq(SysDictDetailEntity::getDictId, sysDictDetail.getDictId()); + SysDictDetailEntity q = sysDictDetailService.getOne(queryWrapper); + if (q != null && !q.getId().equals(sysDictDetail.getId())) { + return R.fail("字典名称-字典值已存在"); + } + + sysDictDetailService.updateById(sysDictDetail); + return R.success(); + } + + + @ApiOperation(value = "查询列表数据") + @PostMapping("/listByPage") + @RequiresPermissions("sysDict:list") + public R findListByPage(@RequestBody SysDictDetailEntity sysDictDetail) { + if (StringUtils.isEmpty(sysDictDetail.getDictId())) { + return R.success(); + } + IPage iPage = sysDictDetailService.listByPage(sysDictDetail.getQueryPage(), sysDictDetail.getDictId()); + return R.success(iPage); + } + +} +*/ diff --git a/src/main/java/com/huoran/iasf/controller/SysFilesController.java b/src/main/java/com/huoran/iasf/controller/SysFilesController.java new file mode 100644 index 0000000..c470442 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysFilesController.java @@ -0,0 +1,163 @@ +package com.huoran.iasf.controller; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.config.NonStaticResourceHttpRequestConfig; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysFilesEntity; +import com.huoran.iasf.entity.SysUser; +import com.huoran.iasf.service.HttpSessionService; +import com.huoran.iasf.service.SysFilesService; +import com.huoran.iasf.service.UserService; +import com.huoran.iasf.vo.UEditorResultVO; +import com.huoran.iasf.vo.req.FileParameters; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; + +import javax.annotation.Resource; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + + +/** + * 文件上传 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@RestController +@RequestMapping("/sysFiles") +@Api(tags = "文件管理") +public class SysFilesController { + @Resource + private SysFilesService sysFilesService; + + @Autowired + private UserService userService; + + @Resource + private HttpSessionService httpSessionService; + + @ApiOperation(value = "上传文件前获取配置文件") + @GetMapping("/upload") + public String upload(@RequestParam(required = false) String action,HttpServletResponse response) throws IOException { + // response.sendRedirect("static/ueditor/config.json"); + // return "redirect:static/ueditor/config.json"; + // 将获取的json数据封装一层,然后在给返回 + JSONObject result = new JSONObject(); + result.put("imageActionName", "upload"); + result.put("imageFieldName", "file"); + return result.toJSONString(); + } + @NoRepeatSubmit + @ApiOperation(value = "新增") + @PostMapping("/upload") + // @RequiresPermissions(value = {"sysFiles:add", "sysContent:update", "sysContent:add"}, logical = Logical.OR) + public UEditorResultVO add( + @RequestParam(required = false) String action, + @RequestParam(value = "file") MultipartFile file, FileParameters fileParameters) { + Integer userId = httpSessionService.getCurrentUserId(); + fileParameters.setUploader(userId.toString()); + //判断文件是否空 + if (file == null || file.getOriginalFilename() == null || "".equalsIgnoreCase(file.getOriginalFilename().trim())) { + UEditorResultVO uEditorResult = new UEditorResultVO(); + uEditorResult.setState("error"); + return uEditorResult; + } + return sysFilesService.saveFile(file,fileParameters); + } + + @ApiOperation(value = "更新文件信息") + @PostMapping("/update") + public R update(@RequestBody FileParameters fileParameters) { + if (StrUtil.isEmpty(fileParameters.getId())){ + return R.fail("id不能为空"); + } + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set("quote",fileParameters.getQuote()). + set("is_release",fileParameters.getIsRelease()). + set("quote_id",fileParameters.getQuoteId()). + eq("id", fileParameters.getId()); + return sysFilesService.update(updateWrapper) ? R.success() : R.fail("更新失败"); + } + @ApiOperation(value = "文件预览") + @GetMapping("/preview/{id}") + public void preview(@PathVariable String id, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + sysFilesService.preview(id, req, res); + } + @NoRepeatSubmit + @ApiOperation(value = "文件下载") + @GetMapping("/download/{id}") + public void download(@PathVariable String id, HttpServletRequest req, HttpServletResponse res) { + sysFilesService.download(id, req, res); + } + + @ApiOperation(value = "删除") + @DeleteMapping("/delete") + @RequiresPermissions("sysFiles:delete") + public R delete(@RequestBody @ApiParam(value = "id集合") List ids) { + sysFilesService.removeByIdsAndFiles(ids); + return R.success(); + } + + @ApiOperation(value = "查询分页数据",response = SysFilesEntity.class) + @PostMapping("/listByPage") + @RequiresPermissions("sysFiles:list") + public R findListByPage(@RequestBody SysFilesEntity sysFiles) { + return sysFilesService.getPage(sysFiles); + + /*LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + if (!StringUtils.isEmpty(sysFiles.getFileName())) { + queryWrapper.like(SysFilesEntity::getFileName, sysFiles.getFileName()); + } + if (!StringUtils.isEmpty(sysFiles.getUploader())) { + queryWrapper.like(SysFilesEntity::getUploader, sysFiles.getUploader()); + } + if (!StringUtils.isEmpty(sysFiles.getQuote())) { + queryWrapper.like(SysFilesEntity::getQuote, sysFiles.getQuote()); + } + if (!StringUtils.isEmpty(sysFiles.getType())) { + queryWrapper.eq(SysFilesEntity::getType, sysFiles.getType()); + } + if (!StringUtils.isEmpty(sysFiles.getSite())) { + queryWrapper.eq(SysFilesEntity::getSite, sysFiles.getSite()); + } + queryWrapper.orderByDesc(SysFilesEntity::getCreateDate); + queryWrapper.isNotNull(SysFilesEntity::getQuote); + //只查看已发布的文件 + queryWrapper.eq(SysFilesEntity::getIsRelease,1); + //查看文章未删除的 + queryWrapper.eq(SysFilesEntity::getIsDel,0); + IPage iPage = sysFilesService.page(sysFiles.getQueryPage(),queryWrapper); + iPage.getRecords().forEach(sysFilesEntity -> { + if (sysFilesEntity.getUploader()!=null){ + SysUser sysUser = userService.getById(sysFilesEntity.getUploader()); + if (sysUser!=null){ + sysFilesEntity.setUploader(sysUser.getRealName()); + } + } + }); + return R.success(iPage);*/ + } + +} diff --git a/src/main/java/com/huoran/iasf/controller/SysGeneratorController.java b/src/main/java/com/huoran/iasf/controller/SysGeneratorController.java new file mode 100644 index 0000000..4c77946 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysGeneratorController.java @@ -0,0 +1,63 @@ +/* +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysGenerator; +import com.huoran.iasf.service.ISysGeneratorService; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.io.IOUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +*/ +/** + * 代码生成 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +// @Api(tags = "系统模块-代码生成") +// @Slf4j +// @RestController +// @RequestMapping("/sysGenerator") +public class SysGeneratorController { + @Resource + private ISysGeneratorService sysGeneratorService; + + */ +/** + * 生成代码 + *//* + + @ApiOperation(value = "生成") + @GetMapping("/gen") + @RequiresPermissions("sysGenerator:add") + public void code(String tables, HttpServletResponse response) throws IOException { + byte[] data = sysGeneratorService.generatorCode(tables.split(",")); + + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"manager.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + + IOUtils.write(data, response.getOutputStream()); + } + + @ApiOperation(value = "查询分页数据") + @PostMapping("/listByPage") + @RequiresPermissions("sysGenerator:list") + public R findListByPage(@RequestBody SysGenerator vo) { + IPage iPage = sysGeneratorService.selectAllTables(vo.getQueryPage(), vo); + return R.success(iPage); + } +} +*/ diff --git a/src/main/java/com/huoran/iasf/controller/SysJobController.java b/src/main/java/com/huoran/iasf/controller/SysJobController.java new file mode 100644 index 0000000..ee8970b --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysJobController.java @@ -0,0 +1,190 @@ +/* +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.job.utils.ScheduleJob; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysJobEntity; +import com.huoran.iasf.service.SysJobService; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.quartz.TriggerUtils; +import org.quartz.impl.triggers.CronTriggerImpl; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + + +*/ +/** + * 定时任务 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +// @Api(tags = "定时任务") +// @RestController +// @RequestMapping("/sysJob") +public class SysJobController { + @Resource + private SysJobService sysJobService; + + @ApiOperation(value = "新增") + @LogAnnotation(title = "新增") + @PostMapping("/add") + @RequiresPermissions("sysJob:add") + public R add(@RequestBody SysJobEntity sysJob) { + if (isValidExpression(sysJob.getCronExpression())) { + return R.fail("cron表达式有误"); + } + R R = ScheduleJob.judgeBean(sysJob.getBeanName()); + if (BaseResponseCode.SUCCESS.getCode() != R.getCode()) { + return R; + } + + sysJobService.saveJob(sysJob); + return R.success(); + } + + @ApiOperation(value = "删除") + @DeleteMapping("/delete") + @RequiresPermissions("sysJob:delete") + @LogAnnotation(title = "删除") + public R delete(@RequestBody @ApiParam(value = "id集合") List ids) { + sysJobService.delete(ids); + return R.success(); + } + + @ApiOperation(value = "更新") + @PutMapping("/update") + @RequiresPermissions("sysJob:update") + @LogAnnotation(title = "更新") + public R update(@RequestBody SysJobEntity sysJob) { + if (isValidExpression(sysJob.getCronExpression())) { + return R.fail("cron表达式有误"); + } + R R = ScheduleJob.judgeBean(sysJob.getBeanName()); + if (BaseResponseCode.SUCCESS.getCode() != R.getCode()) { + return R; + } + + sysJobService.updateJobById(sysJob); + return R.success(); + } + + @ApiOperation(value = "查询分页数据") + @PostMapping("/listByPage") + @RequiresPermissions("sysJob:list") + public R findListByPage(@RequestBody SysJobEntity sysJob) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + //查询条件示例 + if (!StringUtils.isEmpty(sysJob.getBeanName())) { + queryWrapper.like(SysJobEntity::getBeanName, sysJob.getBeanName()); + } + IPage iPage = sysJobService.page(sysJob.getQueryPage(), queryWrapper); + return R.success(iPage); + } + + + */ +/** + * 立即执行任务 + *//* + + @ApiOperation(value = "立即执行任务") + @LogAnnotation(title = "立即执行任务") + @PostMapping("/run") + @RequiresPermissions("sysJob:run") + public R run(@RequestBody List ids) { + sysJobService.run(ids); + + return R.success(); + } + + */ +/** + * 暂停定时任务 + *//* + + @ApiOperation(value = "暂停定时任务") + @LogAnnotation(title = "暂停定时任务") + @PostMapping("/pause") + @RequiresPermissions("sysJob:pause") + public R pause(@RequestBody List ids) { + sysJobService.pause(ids); + + return R.success(); + } + + */ +/** + * 恢复定时任务 + *//* + + @ApiOperation(value = "恢复定时任务") + @LogAnnotation(title = "恢复定时任务") + @PostMapping("/resume") + @RequiresPermissions("sysJob:resume") + public R resume(@RequestBody List ids) { + sysJobService.resume(ids); + return R.success(); + } + + */ +/** + * 判断cron表达式 + * + * @param cronExpression cron表达式 + * @return 是否有误 + *//* + + public static boolean isValidExpression(String cronExpression) { + CronTriggerImpl trigger = new CronTriggerImpl(); + try { + trigger.setCronExpression(cronExpression); + Date date = trigger.computeFirstFireTime(null); + return date == null || !date.after(new Date()); + } catch (Exception e) { + return true; + } + } + + + @ApiOperation(value = "获取运行时间") + @LogAnnotation(title = "获取运行时间") + @PostMapping("/getRecentTriggerTime") + @RequiresPermissions("sysJob:add") + public R getRecentTriggerTime(String cron) { + List list = new ArrayList<>(); + try { + CronTriggerImpl cronTriggerImpl = new CronTriggerImpl(); + cronTriggerImpl.setCronExpression(cron); + // 这个是重点,一行代码搞定 + List dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 5); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + for (Date date : dates) { + list.add(dateFormat.format(date)); + } + + } catch (ParseException e) { + e.printStackTrace(); + } + return R.success(list); + } + + +} +*/ diff --git a/src/main/java/com/huoran/iasf/controller/SysJobLogController.java b/src/main/java/com/huoran/iasf/controller/SysJobLogController.java new file mode 100644 index 0000000..e9fba72 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysJobLogController.java @@ -0,0 +1,59 @@ +/* +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysJobLogEntity; +import com.huoran.iasf.service.SysJobLogService; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + + +*/ +/** + * 定时任务日志 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +// @Api(tags = "定时任务日志") +// @RestController +// @RequestMapping("/sysJobLog") +public class SysJobLogController { + @Resource + private SysJobLogService sysJobLogService; + + @ApiOperation(value = "查询分页数据") + @PostMapping("/listByPage") + @RequiresPermissions("sysJob:list") + public R findListByPage(@RequestBody SysJobLogEntity sysJobLog) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + //查询条件示例 + if (!StringUtils.isEmpty(sysJobLog.getJobId())) { + queryWrapper.like(SysJobLogEntity::getJobId, sysJobLog.getJobId()); + } + queryWrapper.orderByDesc(SysJobLogEntity::getCreateTime); + IPage iPage = sysJobLogService.page(sysJobLog.getQueryPage(), queryWrapper); + return R.success(iPage); + } + + @ApiOperation(value = "清空定时任务日志") + @DeleteMapping("/delete") + @RequiresPermissions("sysJob:delete") + @LogAnnotation(title = "清空") + public R delete() { + sysJobLogService.remove(Wrappers.emptyWrapper()); + return R.success(); + } + +} +*/ diff --git a/src/main/java/com/huoran/iasf/controller/SysLogController.java b/src/main/java/com/huoran/iasf/controller/SysLogController.java new file mode 100644 index 0000000..644d524 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysLogController.java @@ -0,0 +1,63 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysLog; +import com.huoran.iasf.service.LogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 系统操作日志 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ + +@RequestMapping("/sys") +@Api(tags = "系统模块-系统操作日志管理") +@RestController +public class SysLogController { + @Resource + private LogService logService; + + @PostMapping("/logs") + @ApiOperation(value = "分页查询系统操作日志接口") + @LogAnnotation(title = "系统操作日志管理", action = "分页查询系统操作日志") +// @RequiresPermissions("sys:log:list") + public R pageInfo(@RequestBody SysLog vo) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + if (!StringUtils.isEmpty(vo.getUsername())) { + queryWrapper.like(SysLog::getUsername, vo.getUsername()); + } + if (!StringUtils.isEmpty(vo.getOperation())) { + queryWrapper.like(SysLog::getOperation, vo.getOperation()); + } + if (!StringUtils.isEmpty(vo.getStartTime())) { + queryWrapper.gt(SysLog::getCreateTime, vo.getStartTime()); + } + if (!StringUtils.isEmpty(vo.getEndTime())) { + queryWrapper.lt(SysLog::getCreateTime, vo.getEndTime()); + } + queryWrapper.orderByDesc(SysLog::getCreateTime); + return R.success(logService.page(vo.getQueryPage(), queryWrapper)); + } + + @DeleteMapping("/logs") + @ApiOperation(value = "删除日志接口") + @LogAnnotation(title = "系统操作日志管理", action = "删除系统操作日志") +// @RequiresPermissions("sys:log:deleted") + public R deleted(@RequestBody List logIds) { + logService.removeByIds(logIds); + return R.success(); + } +} diff --git a/src/main/java/com/huoran/iasf/controller/SysNavigationStyleController.java b/src/main/java/com/huoran/iasf/controller/SysNavigationStyleController.java new file mode 100644 index 0000000..bbf3327 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysNavigationStyleController.java @@ -0,0 +1,79 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.swagger.annotations.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.common.utils.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.apache.commons.lang.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import com.huoran.iasf.service.SysNavigationStyleService; +import com.huoran.iasf.entity.SysNavigationStyle; + +import java.util.List; + + +/** + * @描述:导航样式配置控制类 + * @作者: Rong + * @日期: 2022-09-01 + */ +@RestController +@RequestMapping("/sysNavigationStyle") +@Api(value = "导航样式配置:SysNavigationStyleController", tags = "R-导航样式配置") +public class SysNavigationStyleController { + + @Autowired + public SysNavigationStyleService service; + + + @PostMapping("/searchAllBySite") + @ApiOperation(value = "按站点搜索所有", response = SysNavigationStyle.class) + public R listByEntity(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("site_id", siteId); + List pageList = service.list(queryWrapper); + return R.success(pageList); + } + + + @PostMapping("/findById") + @ApiOperation(value = "查询详情", response = SysNavigationStyle.class) + public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + SysNavigationStyle sysNavigationStyle = service.getById(id); + return R.success(sysNavigationStyle); + } + + + @PostMapping("/save") + @ApiOperation(value = "新增", response = SysNavigationStyle.class) + public R save(@RequestBody @ApiParam(name = "导航样式配置对象", value = "传入json格式", required = true) SysNavigationStyle sysNavigationStyle) { + boolean addState = service.save(sysNavigationStyle); + return addState ? R.success() : R.fail("新增失败"); + } + + + @PostMapping("/update") + @ApiOperation(value = "修改", response = SysNavigationStyle.class) + public R update(@RequestBody @ApiParam(name = "导航样式配置对象", value = "传入json格式", required = true) SysNavigationStyle sysNavigationStyle) { + boolean updateState = service.updateById(sysNavigationStyle); + return updateState ? R.success() : R.fail("编辑失败"); + } + + + @PostMapping("/delete") + @ApiOperation(value = "删除", response = SysNavigationStyle.class) + public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { + boolean delState = service.removeById(id); + return delState ? R.success() : R.fail("删除失败"); + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysPageManagementController.java b/src/main/java/com/huoran/iasf/controller/SysPageManagementController.java new file mode 100644 index 0000000..71e5bf5 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysPageManagementController.java @@ -0,0 +1,57 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.entity.SysContent; +import com.huoran.iasf.service.SysColumnService; +import com.huoran.iasf.service.SysContentService; +import com.huoran.iasf.vo.req.ColumnWeightReqVO; +import com.huoran.iasf.vo.req.LongPageColumnReqVO; +import com.huoran.iasf.vo.req.PageContentReqVO; +import com.huoran.iasf.vo.req.PaginationColumnReqVO; +import com.huoran.iasf.vo.resp.PageContentRespVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + + +/** + * @描述:页面管理 + * @作者: Rong + * @日期: 2022-08-08 + */ +@RestController +@RequestMapping("/pageManagement") +@Api(value = "页面管理:SysPageManagementController", tags = "R-页面管理") +public class SysPageManagementController { + + @Autowired + public SysColumnService columnService; + + + /** + * 需求:当前接口只查栏目类型为长页栏目的数据 + * + * @param sysContent + * @return + */ + @PostMapping("/longPageColumnList") + @ApiOperation(value = "长页列列表", response = PageContentRespVO.class) + public R longPageColumnList(@RequestBody @Valid @ApiParam(name = "分页查询参数", value = "传入json格式", required = true) LongPageColumnReqVO sysContent) { + return columnService.longPageColumnList(sysContent); + } + + + + + +} + diff --git a/src/main/java/com/huoran/iasf/controller/SysTemplateController.java b/src/main/java/com/huoran/iasf/controller/SysTemplateController.java new file mode 100644 index 0000000..3cec186 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/SysTemplateController.java @@ -0,0 +1,108 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.entity.SysTemplateStyle; +import com.huoran.iasf.entity.SysTemplateStyleConfiguration; +import com.huoran.iasf.service.SysTemplateStyleConfigurationService; +import com.huoran.iasf.service.SysTemplateStyleService; +import io.swagger.annotations.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.common.utils.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.apache.commons.lang.StringUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestParam; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import com.huoran.iasf.service.SysTemplateService; +import com.huoran.iasf.entity.SysTemplate; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * @描述:栏目模板控制类 + * @作者: Rong + * @日期: 2022-11-11 + */ +@RestController +@RequestMapping("/template") +@Api(value = "栏目模板:SysTemplateController", tags = "栏目模板:栏目模板相关") +public class SysTemplateController { + + @Autowired + public SysTemplateService templateService; + + @Autowired + public SysTemplateStyleService styleService; + @Autowired + public SysTemplateStyleConfigurationService templateStyleConfigurationService; + + @PostMapping("/listOfColumnTemplates") + @ApiOperation(value = "获取文章模板列表、详情样式", response = SysTemplate.class) + public R listOfColumnTemplates() { + List list = templateService.list(new QueryWrapper().eq("type", 1).eq("is_hide",0)); + return R.success(list); + } + + + @PostMapping("/longPageListStyle") + @ApiOperation(value = "长页列表样式", response = SysTemplate.class) + public R longPageListStyle() { + List list = styleService.list(new QueryWrapper().eq("is_long_page", 1)); + return R.success(list); + } + + @PostMapping("/theTemplateIdGetsTheStyle") + @ApiOperation(value = "根据模板id获取样式", response = SysTemplateStyle.class) + public R theTemplateIdGetsTheStyle(@ApiParam(name = "templateId", value = "模板id", required = true) @RequestParam Integer templateId) { + + /*QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("type", Constant.LIST_TEMPLATE_TYPES); + queryWrapper.eq("is_long_page", 0); + List listingTemplateTypes = styleService.list(queryWrapper); + + + QueryWrapper queryWrapper1 = new QueryWrapper<>(); + queryWrapper1.eq("template_id",templateId); + queryWrapper1.eq("type", Constant.DETAILS_TEMPLATE_TYPE); + List detailsTypeOfTheTemplate = styleService.list(queryWrapper1);*/ + + List listingTemplateTypes = templateStyleConfigurationService.getsTheStyleUnderTheTemplate(templateId, 0); + List detailsTypeOfTheTemplate = templateStyleConfigurationService.getsTheStyleUnderTheTemplate(templateId, 1); + + + Map map = new HashMap<>(); + map.put("listingTemplateTypes", listingTemplateTypes);//列表样式 + map.put("detailsTypeOfTheTemplate", detailsTypeOfTheTemplate);//详情样式 + return R.success(map); + } + + + @PostMapping("/fullDetailsTemplateStyle") + @ApiOperation(value = "全部详情模板样式", response = SysTemplateStyle.class) + public R fullDetailsTemplateStyle() { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("type", Constant.DETAILS_TEMPLATE_TYPE); + List listingTemplateTypes = styleService.list(queryWrapper); + return R.success(listingTemplateTypes); + } + + + @PostMapping("/individualTemplateDetailsStyle") + @ApiOperation(value = "独立模板详情样式", response = SysTemplate.class) + public R individualTemplateDetailsStyle() { + List list = styleService.list(new QueryWrapper().eq("type", 1).eq("is_long_page", 0).eq("is_hide",0)); + return R.success(list); + } +} + diff --git a/src/main/java/com/huoran/iasf/controller/UserController.java b/src/main/java/com/huoran/iasf/controller/UserController.java new file mode 100644 index 0000000..cfb07e7 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/UserController.java @@ -0,0 +1,227 @@ +package com.huoran.iasf.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysUser; +import com.huoran.iasf.entity.UserDept; +import com.huoran.iasf.mapper.UserDeptMapper; +import com.huoran.iasf.service.HttpSessionService; +import com.huoran.iasf.service.UserService; +import com.huoran.iasf.vo.CheckVo; +import com.huoran.iasf.vo.req.UpdatePhoneOrEmailReq; +import com.huoran.iasf.vo.req.UserListReq; +import com.huoran.iasf.vo.resp.UserListResp; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.apache.shiro.subject.Subject; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.naming.Name; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * 用户管理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@RestController +@Api(tags = "用户管理") +@RequestMapping("/sys") +@Slf4j +public class UserController { + @Resource + private UserService userService; + + @Resource + private UserDeptMapper userDeptMapper; + + @Resource + private HttpSessionService httpSessionService; + + @PostMapping(value = "/user/login") + @ApiOperation(value = "用户登录接口") + public R login(@RequestBody @Valid SysUser vo) { + return R.success(userService.login(vo)); + } + +/* @PostMapping("/user/register") + @ApiOperation(value = "用户注册接口") + public R register(@RequestBody @Valid SysUser vo) { + userService.register(vo); + return R.success(); + }*/ + + @PutMapping("/user") + @ApiOperation(value = "更新用户信息接口") + @LogAnnotation(title = "用户管理", action = "更新用户信息") +// @RequiresPermissions("sys:user:update") + public R updateUserInfo(@RequestBody SysUser vo) { + if (StringUtils.isEmpty(vo.getId())) { + return R.fail("id不能为空"); + } + userService.updateUserInfo(vo); + return R.success(); + } + + @GetMapping("/user/{id}") + @ApiOperation(value = "查询用户详情接口") + @LogAnnotation(title = "用户管理", action = "查询用户详情") +// @RequiresPermissions("sys:user:detail") + public R detailInfo(@PathVariable("id") String id) { + UserListResp userResp = userService.detailInfo(id); + return R.success(userResp); + } + + @PostMapping("/users") + @ApiOperation(value = "分页获取用户列表接口") +// @RequiresPermissions("sys:user:list") + @LogAnnotation(title = "用户管理", action = "分页获取用户列表") + public R pageInfo(@RequestBody UserListReq userListReq) { + return userService.pageInfo(userListReq); + } + + @PostMapping("/user") + @ApiOperation(value = "新增用户接口") +// @RequiresPermissions("sys:user:add") + @LogAnnotation(title = "用户管理", action = "新增用户") + public R addUser(@RequestBody @Valid SysUser vo) { + userService.addUser(vo); + return R.success(); + } + + @GetMapping("/checkJobNumber") + @ApiOperation(value = "工号验证") + public R checkJobNumber(@RequestParam String jobNumber) { + SysUser sysUser = userService.getOne(Wrappers.lambdaQuery().eq(SysUser::getJobNumber, jobNumber)); + if (sysUser != null) { + return R.fail("工号已存在,请勿重复添加!"); + } + return R.success(); + } + + @GetMapping("/checkUsername") + @ApiOperation(value = "账号验证") + public R checkUsername(@RequestParam String userName) { + SysUser sysUser = userService.getOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, userName)); + if (sysUser != null) { + return R.fail("账号已存在,请勿重复添加!"); + } + return R.success(); + } + + @GetMapping("/checkEmail") + @ApiOperation(value = "邮箱验证") + public R checkEmail(@RequestParam String email) { + SysUser sysUser = userService.getOne(Wrappers.lambdaQuery().eq(SysUser::getEmail, email)); + if (sysUser != null) { + return R.fail("邮箱已存在,请勿重复添加!"); + } + return R.success(); + } + + @GetMapping("/checkPhone") + @ApiOperation(value = "手机验证") + public R checkPhone(@RequestParam String phone) { + SysUser sysUser = userService.getOne(Wrappers.lambdaQuery().eq(SysUser::getPhone, phone)); + if (sysUser != null) { + return R.fail("手机号已存在,请勿重复添加!"); + } + return R.success(); + } + @NoRepeatSubmit + @ApiOperation(value = "密码重置", notes = "密码重置") + @GetMapping("/resetPwd") + public R resetPwd(@RequestParam("userId") String userId) { + return userService.resetPwd(userId); + } + + @GetMapping("/user/logout") + @ApiOperation(value = "退出接口") + @LogAnnotation(title = "用户管理", action = "退出") + public R logout() { + httpSessionService.abortUserByToken(); + Subject subject = SecurityUtils.getSubject(); + subject.logout(); + return R.success(); + } + @NoRepeatSubmit + @PutMapping("/user/pwd") + @ApiOperation(value = "修改密码接口") + @LogAnnotation(title = "用户管理", action = "更新密码") + public R updatePwd(@RequestBody SysUser vo) { + if (StringUtils.isEmpty(vo.getOldPwd()) || StringUtils.isEmpty(vo.getNewPwd())) { + return R.fail("旧密码与新密码不能为空"); + } + // Integer userId = httpSessionService.getCurrentUserId(); + // vo.setId(userId); + userService.updatePwd(vo); + return R.success(); + } + @NoRepeatSubmit + @DeleteMapping("/user") + @ApiOperation(value = "删除用户接口") + @LogAnnotation(title = "用户管理", action = "删除用户") +// @RequiresPermissions("sys:user:deleted") + public R deletedUser(@RequestBody @ApiParam(value = "用户id集合") List userIds) { + //删除用户, 删除redis的绑定的角色跟权限 + httpSessionService.abortUserByUserIds(userIds); + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.in(SysUser::getId, userIds); + userService.remove(queryWrapper); + //删除用户部门 + userDeptMapper.delete(Wrappers.lambdaQuery().in(UserDept::getUserId, userIds)); + return R.success(); + } + + @PostMapping("/importStaff") + @ApiOperation("批量导入员工") + public R importStaff(@RequestParam(name = "file") MultipartFile file, HttpServletRequest request) throws IOException { + Map map = userService.importStaff(file); + return R.success(map); + } + + /** + * 批量导入员工失败数据导出 + */ + @ApiOperation(value = "批量导入员工失败数据导出") + @GetMapping("/exportFailure") + public void exportFailureRecord(HttpServletResponse response, @ApiParam(name = "exportCode", value = "importQuestion接口返回的exportCode", required = true) @RequestParam String exportCode) throws Exception { + userService.exportFailureRecord(response, exportCode); + } + @NoRepeatSubmit + @ApiOperation(value = "更换手机号或邮箱--发送验证码") + @PostMapping("/sendPhoneOrEmailCode") + public R sendPhoneOrEmailCode(@RequestBody CheckVo checkVo) { + return userService.sendCheckPhoneCode(checkVo); + } + @NoRepeatSubmit + @ApiOperation(value = "更新手机号或邮箱") + @PostMapping("/updatePhoneOrEmail") + public R updatePhoneOrEmail(@RequestBody UpdatePhoneOrEmailReq updatePhoneOrEmailReq) { + return userService.updatePhoneOrEmail(updatePhoneOrEmailReq); + } + + @ApiOperation(value = "修改用户头像") + @PostMapping("/updateUserAvatars") + public R updateUserAvatars(@RequestParam String userId, MultipartFile file) { + return userService.updateUserAvatars(userId, file); + } + +} diff --git a/src/main/java/com/huoran/iasf/controller/UserDeptController.java b/src/main/java/com/huoran/iasf/controller/UserDeptController.java new file mode 100644 index 0000000..f270c59 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/UserDeptController.java @@ -0,0 +1,21 @@ +package com.huoran.iasf.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 用户员工部门表 前端控制器 + *

+ * + * @author cheney + * @since 2022-08-15 + */ +@RestController +@RequestMapping("/userDept") +public class UserDeptController { + +} + diff --git a/src/main/java/com/huoran/iasf/controller/UserGroupController.java b/src/main/java/com/huoran/iasf/controller/UserGroupController.java new file mode 100644 index 0000000..a17a493 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/UserGroupController.java @@ -0,0 +1,106 @@ +package com.huoran.iasf.controller; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysFilesEntity; +import com.huoran.iasf.entity.UserGroup; +import com.huoran.iasf.service.UserGroupService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + *

+ * 用户组 前端控制器 + *

+ * + * @author cheney + * @since 2022-08-10 + */ +@RestController +@RequestMapping("/sys/userGroup") +@Api(tags = "用户组管理") +public class UserGroupController { + + @Autowired + private UserGroupService userGroupService; + @NoRepeatSubmit + @PostMapping("/add") + @ApiOperation(value = "新增用户组") + @LogAnnotation(title = "用户组管理", action = "新增用户组") + @RequiresPermissions("sys:userGroup:add") + public R addUserGroup(@RequestBody @Valid UserGroup userGroup) { + UserGroup one = userGroupService.getOne(new QueryWrapper(). + eq("group_name", userGroup.getGroupName())); + if (ObjectUtil.isNotNull(one)){ + return R.fail("用户组已存在"); + } + userGroupService.save(userGroup); + return R.success(); + } + @NoRepeatSubmit + @DeleteMapping("/delete/{id}") + @ApiOperation(value = "删除用户组") + @LogAnnotation(title = "用户组管理", action = "删除用户组") + @RequiresPermissions("sys:userGroup:deleted") + public R deleted(@PathVariable("id") Integer id) { + userGroupService.removeById(id); + return R.success(); + } + + @PutMapping("/update") + @ApiOperation(value = "更新用户组信息") + @LogAnnotation(title = "用户组管理", action = "更新用户组信息") + @RequiresPermissions("sys:userGroup:update") + public R updateUserGroup(@RequestBody UserGroup userGroup) { + if (StringUtils.isEmpty(userGroup.getId())) { + return R.fail("id不能为空"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("group_name", userGroup.getGroupName()); + queryWrapper.last(" and id != " + userGroup.getId()); + List groups = userGroupService.list(queryWrapper); + if (ObjectUtil.isNotNull(groups) && groups.size()>0){ + return R.fail("用户组已存在"); + } + userGroupService.updateById(userGroup); + return R.success(); + } + +/* @GetMapping("/detail/{id}") + @ApiOperation(value = "查询用户组详情接口") + @LogAnnotation(title = "用户组管理", action = "查询用户组详情") + @RequiresPermissions("sys:userGroup:detail") + public R detailInfo(@PathVariable("id") Integer id) { + return R.success(userGroupService.getById(id)); + }*/ + + + @PostMapping("/list") + @ApiOperation(value = "用户组列表") + @LogAnnotation(title = "用户组管理", action = "获取所有用户组机构") + @RequiresPermissions("sys:userGroup:list") + public R getUserGroupAll(@RequestBody UserGroup userGroup) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + if (!StringUtils.isEmpty(userGroup.getGroupName())) { + queryWrapper.like(UserGroup::getGroupName, userGroup.getGroupName()); + } + queryWrapper.orderByDesc(UserGroup::getCreateTime); + IPage iPage = userGroupService.page(userGroup.getQueryPage(),queryWrapper); + return R.success(iPage); + } + +} + diff --git a/src/main/java/com/huoran/iasf/controller/UserRoleController.java b/src/main/java/com/huoran/iasf/controller/UserRoleController.java new file mode 100644 index 0000000..d0681b8 --- /dev/null +++ b/src/main/java/com/huoran/iasf/controller/UserRoleController.java @@ -0,0 +1,38 @@ +package com.huoran.iasf.controller; + +import com.huoran.iasf.common.aop.annotation.LogAnnotation; +import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.service.UserRoleService; +import com.huoran.iasf.vo.req.UserRoleOperationReqVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 用户和角色关联 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@RequestMapping("/sys") +@RestController +@Api(tags = "用户角色关联接口") +public class UserRoleController { + @Resource + private UserRoleService userRoleService; + @PostMapping("/user/role") + @ApiOperation(value = "修改或者新增用户角色接口") + @LogAnnotation(title = "用户和角色关联接口", action = "修改或者新增用户角色") + public R operationUserRole(@RequestBody @Valid UserRoleOperationReqVO vo) { + userRoleService.addUserRoleInfo(vo); + return R.success(); + } +} diff --git a/src/main/java/com/huoran/iasf/entity/BaseEntity.java b/src/main/java/com/huoran/iasf/entity/BaseEntity.java new file mode 100644 index 0000000..e1d8cf1 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/BaseEntity.java @@ -0,0 +1,47 @@ +package com.huoran.iasf.entity; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * BaseEntity + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class BaseEntity { + + @JSONField(serialize = false) + @TableField(exist = false) + @ApiModelProperty(value = "页码",example = "1") + private int page = 1; + + @JSONField(serialize = false) + @TableField(exist = false) + @ApiModelProperty(value = "页数",example = "10") + private int limit = 10; + + /** + * 数据权限:用户id + */ + @TableField(exist = false) + @ApiModelProperty(value = "用户id") + private List createIds; + + /** + * page条件 + * @param + * @return + */ + @ApiModelProperty(value = "getQueryPage", hidden = true) + public Page getQueryPage() { + return new Page(page, limit); + } +} diff --git a/src/main/java/com/huoran/iasf/entity/ColumnEntity.java b/src/main/java/com/huoran/iasf/entity/ColumnEntity.java new file mode 100644 index 0000000..829b67f --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/ColumnEntity.java @@ -0,0 +1,104 @@ +package com.huoran.iasf.entity; + +import lombok.Data; + +/** + * 代码生成 列属性 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class ColumnEntity { + /** + * 列名 + */ + private String columnName; + + /** + * 列名类型 + */ + private String dataType; + + /** + * 列名备注 + */ + private String comments; + + /** + * 属性名称(第一个字母大写),如:user_name => UserName + */ + private String attrName; + + /** + * 属性名称(第一个字母小写),如:user_name => userName + */ + private String attrname; + + /** + * 属性类型 + */ + private String attrType; + + /** + * auto_increment + */ + private String extra; + + public String getColumnName() { + return columnName; + } + + public void setColumnName(String columnName) { + this.columnName = columnName; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public String getAttrname() { + return attrname; + } + + public void setAttrname(String attrname) { + this.attrname = attrname; + } + + public String getAttrName() { + return attrName; + } + + public void setAttrName(String attrName) { + this.attrName = attrName; + } + + public String getAttrType() { + return attrType; + } + + public void setAttrType(String attrType) { + this.attrType = attrType; + } + + public String getExtra() { + return extra; + } + + public void setExtra(String extra) { + this.extra = extra; + } +} diff --git a/src/main/java/com/huoran/iasf/entity/Site.java b/src/main/java/com/huoran/iasf/entity/Site.java new file mode 100644 index 0000000..ba8d8a1 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/Site.java @@ -0,0 +1,45 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 站点管理 + *

+ * + * @author cheney + * @since 2022-08-24 + */ +@Data + @EqualsAndHashCode(callSuper = false) + @TableName("sys_site") +@ApiModel(value="Site对象", description="站点管理") +public class Site extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "站点名称") + private String siteName; + + @ApiModelProperty(value = "域名") + private String domainName; + + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysColumn.java b/src/main/java/com/huoran/iasf/entity/SysColumn.java new file mode 100644 index 0000000..ceadc4d --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysColumn.java @@ -0,0 +1,158 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +/** + * @描述:栏目基础信息 + * @作者: Rong + * @日期: 2022-08-03 + */ +@Data +@ApiModel(value = "栏目基础信息") +@TableName("sys_column") +public class SysColumn implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "id") + private Integer id; + + @ApiModelProperty(value = "父id(第一级为0)") + private Integer fatherId; + + @ApiModelProperty(value = "排序") + private Integer sort; + + @ApiModelProperty(value = "层级((1-一级分类 2-二级分类 3-三级分类以此叠加))") + private Integer level; + + @ApiModelProperty(value = "栏目名称") + private String columnName; + + @ApiModelProperty(value = "banner路径") + private String columnBanner; + + @ApiModelProperty(value = "分页条数") + private Integer pageSize; + + @ApiModelProperty(value = "菜单是否可见(默认0可见 1不可见)") + private Integer menuVisible; + + @ApiModelProperty(value = "栏目类型id") + private Integer typeId; + + @ApiModelProperty(value = "栏目模板id") + private Integer templateId; + + @ApiModelProperty(value = "列表样式id") + private Integer listStyleId; + + @ApiModelProperty(value = "详情样式id") + private Integer detailStyleId; + + @ApiModelProperty(value = "链接类型") + private Integer connectionType; + + @ApiModelProperty(value = "链接地址") + private String linkAddress; + + @ApiModelProperty(value = "只有一篇文章时,以详情方式展示(0默认否 1为是)") + private Integer showWithDetails; + + @ApiModelProperty(value = "站点选择(连接类型为其它站点连接时储存)1.EFL中文2.SRL中文") + private Integer siteSelection; + + @ApiModelProperty(value = "创建人id") + @NotNull(message = "创建人id不能为空") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + @NotNull(message = "编辑人id能为空") + private Integer editorId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "状态(0默认草稿箱 1为已发布)") + private Integer status; + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + + @ApiModelProperty(value = "是否在新窗口打开(0:否 1:是)") + private Integer isOpen; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; + + + @ApiModelProperty(value = "栏目副标题") + private String subtitle; + + + //----------------------非数据库字段Start---------------------- + + @ApiModelProperty("子分类") + @TableField(exist = false) + private List children; + + + @TableField(exist = false) + @ApiModelProperty(value = "创建人") + private String creteUser; + + + @TableField(exist = false) + @ApiModelProperty(value = "修改人") + private String editorUser; + + + @TableField(exist = false) + @ApiModelProperty(value = "总浏览") + private Integer totalBrowsing; + + public Integer getTotalBrowsing() { + return 0; + } + + @TableField(exist = false) + @ApiModelProperty(value = "模板名称") + private String templateName; + + @TableField(exist = false) + @ApiModelProperty(value = "列表样式") + private String listStyle; + + + @TableField(exist = false) + @ApiModelProperty(value = "详情样式") + private String detailStyle; + + @TableField(exist = false) + @ApiModelProperty(value = "路径") + private String path; + + //----------------------非数据库字段End---------------------- + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysColumnLongPage.java b/src/main/java/com/huoran/iasf/entity/SysColumnLongPage.java new file mode 100644 index 0000000..427db43 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysColumnLongPage.java @@ -0,0 +1,73 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +/** + * @描述:长页栏目拓展表 + * @作者: Rong + * @日期: 2022-08-09 + */ +@Data +@ApiModel(value = "长页栏目拓展表") +@TableName("sys_column_long_page") +public class SysColumnLongPage implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "id") + private Integer id; + + @ApiModelProperty(value = "栏目id") + @NotNull(message = "栏目id不能为空!") + private Integer columnId; + + @ApiModelProperty(value = "当前页面版面排序") + @NotNull(message = "排序不能为空!") + private Integer sort; + + @ApiModelProperty(value = "创建人id") + @NotNull(message = "创建人id不能为空!") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + @NotNull(message = "编辑人id不能为空!") + private Integer editorId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "内容(编辑前存储的json字符串)") + private String jsonBeforeEditing; + + @ApiModelProperty(value = "内容(编辑后存储的json字符串)") + private String theEditedJson; + + @ApiModelProperty(value = "发布状态(0:草稿 1已发布)") + private Integer state; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysContent.java b/src/main/java/com/huoran/iasf/entity/SysContent.java new file mode 100644 index 0000000..1839c3c --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysContent.java @@ -0,0 +1,224 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +/** + * @描述:文章管理 + * @作者: Rong + * @日期: 2022-08-08 + */ +@Data +@ApiModel(value = "文章管理") +@TableName("sys_content") +public class SysContent implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键") + private Integer id; + + @ApiModelProperty(value = "标题(全库判重)") + private String title; + + @ApiModelProperty(value = "所属栏目") + private Integer columnId; + + @ApiModelProperty(value = "发布时间") + private String releaseTime; + + @ApiModelProperty(value = "来源") + private String source; + + @ApiModelProperty(value = "作者") + private String author; + + @ApiModelProperty(value = "banner图") + private String bannerImg; + + @ApiModelProperty(value = "文章模板(前端自定义)") + private Integer articleTemplate; + + @ApiModelProperty(value = "摘要") + private String summary; + + @ApiModelProperty(value = "标题图(封面图)") + private String titleImg; + + @ApiModelProperty(value = "正文") + private String mainBody; + + @ApiModelProperty(value = "是否发布(0:草稿 1:已发布)") + private Integer isRelease; + + @ApiModelProperty(value = "创建人id") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + private Integer editorId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + @ApiModelProperty(value = "文章总浏览量") + private Integer totalBrowsing; + + @ApiModelProperty(value = "是否在新窗口打开(0:否 1:是)") + private Integer isOpen; + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + @ApiModelProperty(value = "站点id") + private Integer siteId; + + @ApiModelProperty(value = "模板状态(0禁用;1启用)") + private Integer templateStatus; + + /* @ApiModelProperty(value = "其余模板字段") + private String remainingTemplateFields;*/ + + @ApiModelProperty(value = "链接类型") + private Integer connectionType; + + @ApiModelProperty(value = "链接地址") + private String linkAddress; + + @ApiModelProperty(value = "站点选择(连接类型为其它站点连接时储存)") + private Integer siteSelection; + + @ApiModelProperty(value = "编辑人") + private String edit; + + @ApiModelProperty(value = "审核人") + private String audit; + + @ApiModelProperty(value = "活动开始时间") + private String activityStartTime; + + @ApiModelProperty(value = "活动结束时间") + private String activityEndTime; + + @ApiModelProperty(value = "演讲系列") + private String lectureSeries; + + @ApiModelProperty(value = "线上地点") + private String onlineLocation; + + @ApiModelProperty(value = "线下地点") + private String offlineLocation; + + @ApiModelProperty(value = "主讲人") + private String keynoteSpeaker; + + @ApiModelProperty(value = "活动简介") + private String eventProfile; + + @ApiModelProperty(value = "出版年份") + private String publicationYear; + + @ApiModelProperty(value = "出版类型(前端自定义)") + private Integer publicationTypeId; + + @ApiModelProperty(value = "DOI") + private String doi; + + @ApiModelProperty(value = "引用") + private String quote; + + @ApiModelProperty(value = "主题标签(sys_content_label表外键) 可多选逗号隔开") + private String lableId; + + @ApiModelProperty(value = "所属分类(sys_content_classification表外键)") + private Integer classificationId; + + @ApiModelProperty(value = "是否禁用(0默认,0启用 1禁用)") + private Integer isDisable; + + @ApiModelProperty(value = "栏目名称") + @TableField(exist = false) + private String columnName; + + @ApiModelProperty(value = "文章附件") + @TableField(exist = false) + List fileList; + + + @ApiModelProperty(value = "刊物名称") + private String periodicalName; + + @ApiModelProperty(value = "卷") + private String reel; + + @ApiModelProperty(value = "文献号") + private String documentNumber; + + @ApiModelProperty(value = "文章关键字") + private String articleKeyWord; + + /*@ApiModelProperty(value = "顺序(排序号)") + private Integer sequence;*/ + + @ApiModelProperty(value = "是否置顶(默认为0 不置顶 1为置顶)") + private Integer isTop; + + @ApiModelProperty(value = "置顶时间") + private Date topTime; + @ApiModelProperty(value = "专利类别id") + private Integer patentClassId; + + @ApiModelProperty(value = "申请时间") + private String applicationDate; + + @ApiModelProperty(value = "授权日期") + private String dateOfAuthorization; + + @ApiModelProperty(value = "发明人") + private String inventor; + + @ApiModelProperty(value = "专利名称") + private String patentName; + + @ApiModelProperty(value = "申请号") + private String applicationNumber; + + @ApiModelProperty(value = "出版社") + private String publishingHouse; + + @ApiModelProperty(value = "著名著作") + private String famousWorks; + + @ApiModelProperty(value = "编写人员") + private String writersAndEditors; + + @ApiModelProperty(value = "出版日期") + private String publicationTime; + + + @ApiModelProperty(value = "岗位") + private String post; + + @ApiModelProperty(value = "专业") + private String major; + @ApiModelProperty(value = "爱好") + private String hobby; + @ApiModelProperty(value = "荣誉") + private String honor; +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysContentClassification.java b/src/main/java/com/huoran/iasf/entity/SysContentClassification.java new file mode 100644 index 0000000..9913341 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysContentClassification.java @@ -0,0 +1,61 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +/** + * @描述:文章所属分类 + * @作者: Rong + * @日期: 2022-11-08 + */ +@Data +@ApiModel(value = "文章所属分类") +@TableName("sys_content_classification") +public class SysContentClassification implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键") + private Integer id; + + @ApiModelProperty(value = "分类名称") + private String classificationName; + + @ApiModelProperty(value = "创建人id") + @NotNull(message = "创建人id不能为空") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + @NotNull(message = "编辑人id不能为空") + private Integer editorId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; + + @ApiModelProperty(value = "模板id(用于区分哪个模板下的分类)") + @NotNull(message = "模板id不能为空!") + private Integer templateId; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysContentFile.java b/src/main/java/com/huoran/iasf/entity/SysContentFile.java new file mode 100644 index 0000000..3a6c1e2 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysContentFile.java @@ -0,0 +1,63 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * @描述:文章附件管理表 + * @作者: Rong + * @日期: 2022-11-07 + */ +@Data +@ApiModel(value = "文章附件管理表") +@TableName("sys_content_file") +public class SysContentFile implements Serializable { + + private static final long serialVersionUID=1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键") + private Integer id; + + @ApiModelProperty(value = "文章id") + private Integer contentId; + + @ApiModelProperty(value = "文件名") + private String fileName; + + @ApiModelProperty(value = "创建人id") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + private Integer editorId; + + @ApiModelProperty(value = "文件大小") + private String fileSize; + + @ApiModelProperty(value = "文件格式") + private String fileFormat; + + @ApiModelProperty(value = "oss文件名") + private String ossFileName; + + @ApiModelProperty(value = "文件路径") + private String filePath; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysContentLabel.java b/src/main/java/com/huoran/iasf/entity/SysContentLabel.java new file mode 100644 index 0000000..538056b --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysContentLabel.java @@ -0,0 +1,53 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +/** + * @描述:文章主题标签 + * @作者: Rong + * @日期: 2022-11-08 + */ +@Data +@ApiModel(value = "文章主题标签") +@TableName("sys_content_label") +public class SysContentLabel implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键") + private Integer id; + + @ApiModelProperty(value = "标签名称") + private String labelName; + + @ApiModelProperty(value = "创建人id") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + private Integer editorId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysDept.java b/src/main/java/com/huoran/iasf/entity/SysDept.java new file mode 100644 index 0000000..cbf3020 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysDept.java @@ -0,0 +1,63 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Date; + +/** + * 部门 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class SysDept implements Serializable { + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "部门编号(规则:父级关系编码+自己的编码)") + private String deptNo; + + @NotBlank(message = "部门名称不能为空") + @ApiModelProperty(value = "部门名称") + private String name; + + // @NotBlank(message = "父级不能为空") + @ApiModelProperty(value = "父级id") + private Integer pid; + + @TableField(exist = false) + @ApiModelProperty(value = "父级部门名称") + private String pidName; + + @ApiModelProperty(value = "状态(1:正常;0:弃用)") + private Integer status; + + @ApiModelProperty(value = "为了维护更深层级关系") + private String relationCode; + +/* @ApiModelProperty(value = "部门经理user_id") + private String deptManagerId; + + @ApiModelProperty(value = "部门经理名称") + private String managerName; + + @ApiModelProperty(value = "部门经理联系电话") + private String phone;*/ + + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @TableLogic + private Integer deleted; + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysDictDetailEntity.java b/src/main/java/com/huoran/iasf/entity/SysDictDetailEntity.java new file mode 100644 index 0000000..14b1767 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysDictDetailEntity.java @@ -0,0 +1,68 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 字典明细 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_dict_detail") +public class SysDictDetailEntity extends BaseEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("id") + private String id; + + /** + * 字典标签 + */ + @TableField("label") + private String label; + + /** + * 字典值 + */ + @TableField("value") + private String value; + + /** + * 排序 + */ + @TableField("sort") + private Integer sort; + + /** + * 字典id + */ + @TableField("dict_id") + private String dictId; + + /** + * 创建日期 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Date createTime; + + /** + * 字典name + */ + @TableField(exist = false) + private String dictName; + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysDictEntity.java b/src/main/java/com/huoran/iasf/entity/SysDictEntity.java new file mode 100644 index 0000000..b4e05b0 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysDictEntity.java @@ -0,0 +1,51 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 字典管理 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_dict") +public class SysDictEntity extends BaseEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("id") + private String id; + + /** + * 字典名称 + */ + @TableField("name") + private String name; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + /** + * 创建时间 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Date createTime; + + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysFilesEntity.java b/src/main/java/com/huoran/iasf/entity/SysFilesEntity.java new file mode 100644 index 0000000..80f342c --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysFilesEntity.java @@ -0,0 +1,77 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 文件上传 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_files") +public class SysFilesEntity extends BaseEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id") + private String id; + + @ApiModelProperty(value = "url地址") + private String url; + + @TableField("file_name") + @ApiModelProperty(value = "文件名称") + private String fileName; + + @ApiModelProperty(value = "文件路径") + private String filePath; + + @TableField("type") + @ApiModelProperty(value = "文件类型") + private String type; + + @ApiModelProperty(value = "文件格式") + private String format; + + @ApiModelProperty(value = "文件大小") + private Integer fileSize; + + @ApiModelProperty(value = "是否发布(默认0未发布,1已发布)") + private Integer isRelease; + + @ApiModelProperty(value = "上传人") + private String uploader; + + @ApiModelProperty(value = "引用地方") + private String quote; + + @TableField("site") + @ApiModelProperty(value = "站点来源") + private String site; + + @ApiModelProperty(value = "是否已删除,未删除表示该文件正在使用") + @TableLogic + private Integer deleted; + + @ApiModelProperty(value = "文章是否删除") + private Integer isDel; + + @ApiModelProperty(value = "引用id") + private Integer quoteId; + + @ApiModelProperty(value = "0为文章,1为栏目") + private Integer quoteType; + + @TableField(value = "create_date", fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + private Date createDate; +} diff --git a/src/main/java/com/huoran/iasf/entity/SysGenerator.java b/src/main/java/com/huoran/iasf/entity/SysGenerator.java new file mode 100644 index 0000000..f52f515 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysGenerator.java @@ -0,0 +1,30 @@ +package com.huoran.iasf.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * 代码生成 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysGenerator extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + private String tableName; + + private Date createTime; + + private String tableComment; + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysJobEntity.java b/src/main/java/com/huoran/iasf/entity/SysJobEntity.java new file mode 100644 index 0000000..8650736 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysJobEntity.java @@ -0,0 +1,72 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 定时任务 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_job") +public class SysJobEntity extends BaseEntity implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 任务调度参数key + */ + public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY"; + /** + * 任务id + */ + @TableId("id") + private String id; + + /** + * spring bean名称 + */ + @TableField("bean_name") + private String beanName; + + /** + * 参数 + */ + @TableField("params") + private String params; + + /** + * cron表达式 + */ + @TableField("cron_expression") + private String cronExpression; + + /** + * 任务状态 0:正常 1:暂停 + */ + @TableField("status") + private Integer status; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + /** + * 创建时间 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Date createTime; + + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysJobLogEntity.java b/src/main/java/com/huoran/iasf/entity/SysJobLogEntity.java new file mode 100644 index 0000000..0cd494b --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysJobLogEntity.java @@ -0,0 +1,75 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 定时任务日志 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_job_log") +public class SysJobLogEntity extends BaseEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 任务日志id + */ + @TableId("id") + private String id; + + /** + * 任务id + */ + @TableField("job_id") + private String jobId; + + /** + * spring bean名称 + */ + @TableField("bean_name") + private String beanName; + + /** + * 参数 + */ + @TableField("params") + private String params; + + /** + * 任务状态 0:成功 1:失败 + */ + @TableField("status") + private Integer status; + + /** + * 失败信息 + */ + @TableField("error") + private String error; + + /** + * 耗时(单位:毫秒) + */ + @TableField("times") + private Integer times; + + /** + * 创建时间 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Date createTime; + + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysLog.java b/src/main/java/com/huoran/iasf/entity/SysLog.java new file mode 100644 index 0000000..7725668 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysLog.java @@ -0,0 +1,48 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 操作日志 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysLog extends BaseEntity implements Serializable { + @TableId + private String id; + + private String userId; + + private String username; + + private String operation; + + private Integer time; + + private String method; + + private String params; + + private String ip; + + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @TableField(exist = false) + private String startTime; + + @TableField(exist = false) + private String endTime; + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysNavigationStyle.java b/src/main/java/com/huoran/iasf/entity/SysNavigationStyle.java new file mode 100644 index 0000000..16044c3 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysNavigationStyle.java @@ -0,0 +1,52 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * @描述:导航样式配置 + * @作者: Rong + * @日期: 2022-09-01 + */ +@Data +@ApiModel(value = "导航样式配置") +@TableName("sys_navigation_style") +public class SysNavigationStyle implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键") + private Integer id; + + @ApiModelProperty(value = "导航样式") + private Integer navigationStyle; + + @ApiModelProperty(value = "样式模板") + private Integer styleTemplate; + + @ApiModelProperty(value = "站点id") + private Integer siteId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysPermission.java b/src/main/java/com/huoran/iasf/entity/SysPermission.java new file mode 100644 index 0000000..6f5b6ca --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysPermission.java @@ -0,0 +1,77 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 权限菜单 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class SysPermission implements Serializable { + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @NotBlank(message = "菜单权限名称不能为空") + @ApiModelProperty(value = "菜单权限名称") + private String name; + + @ApiModelProperty(value = "授权(多个用逗号分隔,如:sys:user:add,sys:user:edit)") + private String perms; + + @ApiModelProperty(value = "访问地址URL") + private String url; + + @ApiModelProperty(value = "图标") + private String icon; + + @ApiModelProperty(value = "a target属性:_self _blank") + private String target; + + @NotNull(message = "所属菜单不能为空") + @ApiModelProperty(value = "父级菜单权限id") + private Integer pid; + + @ApiModelProperty(value = "排序") + private Integer orderNum; + + @NotNull(message = "菜单权限类型不能为空") + @ApiModelProperty(value = "菜单权限类型(1:目录;2:菜单;3:按钮)") + private Integer type; + + @ApiModelProperty(value = "状态1:正常 0:禁用") + private Integer status; + + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @TableField(fill = FieldFill.INSERT) + private Integer deleted; + + @ApiModelProperty(value = "层级") + @TableField(exist = false) + private Integer level; + + @ApiModelProperty(value = "下级") + @TableField(exist = false) + private List children; + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysRole.java b/src/main/java/com/huoran/iasf/entity/SysRole.java new file mode 100644 index 0000000..2d3271f --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysRole.java @@ -0,0 +1,62 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 角色 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +public class SysRole extends BaseEntity implements Serializable { + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @NotBlank(message = "名称不能为空") + @ApiModelProperty(value = "角色名称") + private String name; + + @ApiModelProperty(value = "角色描述") + private String description; + + @ApiModelProperty(value = "状态(1:正常0:弃用)") + private Integer status; + + @ApiModelProperty(value = "数据范围(1:所有 2:自定义 3: 本部门及以下部门 4:仅本部门") + private Integer dataScope; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + private Integer deleted; + + @TableField(exist = false) + @ApiModelProperty(value = "权限") + private List permissions; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysRolePermission.java b/src/main/java/com/huoran/iasf/entity/SysRolePermission.java new file mode 100644 index 0000000..f479d85 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysRolePermission.java @@ -0,0 +1,33 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 角色权限 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class SysRolePermission implements Serializable { + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private Integer roleId; + + private Integer permissionId; + + @TableField(fill = FieldFill.INSERT) + private Date createTime; + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysTemplate.java b/src/main/java/com/huoran/iasf/entity/SysTemplate.java new file mode 100644 index 0000000..8b1d0ea --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysTemplate.java @@ -0,0 +1,41 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; + +import java.io.Serializable; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 栏目模板 + *

+ * + * @author cheney + * @since 2022-11-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysTemplate对象", description = "栏目模板") +public class SysTemplate implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "模板类型名称") + private String templateType; + + + @ApiModelProperty(value = "类型(0栏目 1文章)") + private Integer type; + + @ApiModelProperty(value = "是否隐藏(0默认不隐藏 1隐藏)") + private Integer isHide; +} diff --git a/src/main/java/com/huoran/iasf/entity/SysTemplateStyle.java b/src/main/java/com/huoran/iasf/entity/SysTemplateStyle.java new file mode 100644 index 0000000..cbaeb9d --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysTemplateStyle.java @@ -0,0 +1,49 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; + +import java.io.Serializable; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cheney + * @since 2022-11-11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysTemplateStyle对象", description = "") +public class SysTemplateStyle implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "类型(0:列表样式 1:详情样式)") + private Integer type; + + @ApiModelProperty(value = "样式名称") + private String style; + + + @ApiModelProperty(value = "跳转路径") + private String path; + + + @ApiModelProperty(value = "是否为长页") + private Integer isLongPage; + + @ApiModelProperty(value = "是否隐藏(0默认不隐藏 1隐藏)") + private Integer isHide; + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysTemplateStyleConfiguration.java b/src/main/java/com/huoran/iasf/entity/SysTemplateStyleConfiguration.java new file mode 100644 index 0000000..3781d96 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysTemplateStyleConfiguration.java @@ -0,0 +1,39 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; + +import java.io.Serializable; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 栏目样式、列表样式、详情样式配置表 + *

+ * + * @author cheney + * @since 2022-11-24 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "SysTemplateStyleConfiguration对象", description = "栏目样式、列表样式、详情样式配置表") +public class SysTemplateStyleConfiguration implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "模板id") + private Integer templateId; + + @ApiModelProperty(value = "样式id") + private Integer styleId; + + +} diff --git a/src/main/java/com/huoran/iasf/entity/SysUser.java b/src/main/java/com/huoran/iasf/entity/SysUser.java new file mode 100644 index 0000000..bae7a9e --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysUser.java @@ -0,0 +1,137 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 用户 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysUser extends BaseEntity implements Serializable { + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @NotBlank(message = "账号不能为空") + @ApiModelProperty(value = "账户名称") + private String username; + + @ApiModelProperty(value = "加密盐值") + private String salt; + + // @NotBlank(message = "密码不能为空") + @ApiModelProperty(value = "用户密码") + private String password; + + @TableField(exist = false) + @ApiModelProperty(value = "旧密码") + private String oldPwd; + + @TableField(exist = false) + @ApiModelProperty(value = "新密码") + private String newPwd; + + @ApiModelProperty(value = "手机号码") + private String phone; + + @ApiModelProperty(value = "用户头像路径") + private String userAvatars; + +/* @TableField(exist = false) + @ApiModelProperty(value = "部门名称") + private String deptName; + + @TableField(exist = false) + @ApiModelProperty(value = "部门编号(规则:父级关系编码+自己的编码)") + private String deptNo;*/ + +/* @TableField(exist = false) + @ApiModelProperty(value = "部门编号(规则:父级关系编码+自己的编码)") + private String deptNo;*/ + + @ApiModelProperty(value = "真实名称") + private String realName; + + @ApiModelProperty(value = "工号") + private String jobNumber; + + @ApiModelProperty(value = "邮箱(唯一)") + private String email; + + @ApiModelProperty(value = "用户组id") + private Integer groupId; + + @TableField(exist = false) + @ApiModelProperty(value = "用户组名称") + private String groupName; + + @ApiModelProperty(value = "账户状态(1.正常 0.锁定 )") + private Integer status; + + @ApiModelProperty(value = "性别(1.男 2.女)") + private Integer sex; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + private Integer deleted; + + @ApiModelProperty(value = "创建人") + private Integer createId; + + @ApiModelProperty(value = "更新人") + private Integer updateId; + + @ApiModelProperty(value = "创建来源(1.web 2.android 3.ios )") + private Integer createWhere; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "最后登陆时间") + private Date lastLoginTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "更新时间") + private Date updateTime; + +/* @TableField(exist = false) + @ApiModelProperty(value = "开始时间") + private String startTime; + + @TableField(exist = false) + @ApiModelProperty(value = "结束时间") + private String endTime;*/ + + @TableField(exist = false) + @ApiModelProperty(value = "角色id") + private List roleIds; + + @TableField(exist = false) + @ApiModelProperty(value = "组织架构id(多个部门id)") + private List deptArchitectureId; + + @TableField(exist = false) + @ApiModelProperty("随机数") + // @NotNull(message = "随机数不能为空") + private String random; + + @TableField(exist = false) + @ApiModelProperty(value = "验证码") + private String captcha; +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/SysUserRole.java b/src/main/java/com/huoran/iasf/entity/SysUserRole.java new file mode 100644 index 0000000..8bc653f --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/SysUserRole.java @@ -0,0 +1,34 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户角色 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class SysUserRole implements Serializable { + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private Integer userId; + + private Integer roleId; + + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/entity/TableEntity.java b/src/main/java/com/huoran/iasf/entity/TableEntity.java new file mode 100644 index 0000000..2449dc0 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/TableEntity.java @@ -0,0 +1,84 @@ +package com.huoran.iasf.entity; + +import java.util.List; + +/** + * 代码生成 表数据 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public class TableEntity { + //表的名称 + private String tableName; + //表的备注 + private String comments; + //表的主键 + private ColumnEntity pk; + //表的列名(不包含主键) + private List columns; + + //类名(第一个字母大写),如:sys_user => SysUser + private String className; + //类名(第一个字母小写),如:sys_user => sysUser + private String classname; + //类名(都小写),如:sys_user => sysuser + private String classNameLower; + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public ColumnEntity getPk() { + return pk; + } + + public void setPk(ColumnEntity pk) { + this.pk = pk; + } + + public List getColumns() { + return columns; + } + + public void setColumns(List columns) { + this.columns = columns; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getClassname() { + return classname; + } + + public void setClassname(String classname) { + this.classname = classname; + } + + public String getClassNameLower() { + return classNameLower; + } + + public void setClassNameLower(String classNameLower) { + this.classNameLower = classNameLower; + } +} diff --git a/src/main/java/com/huoran/iasf/entity/UserDept.java b/src/main/java/com/huoran/iasf/entity/UserDept.java new file mode 100644 index 0000000..2d12239 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/UserDept.java @@ -0,0 +1,42 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 用户员工部门表 + *

+ * + * @author cheney + * @since 2022-08-15 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("sys_user_dept") +@ApiModel(value="UserDept对象", description="用户员工部门表") +public class UserDept implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "用户员工id") + private Integer userId; + + @ApiModelProperty(value = "部门id") + private Integer deptId; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + +} diff --git a/src/main/java/com/huoran/iasf/entity/UserGroup.java b/src/main/java/com/huoran/iasf/entity/UserGroup.java new file mode 100644 index 0000000..c7e22c3 --- /dev/null +++ b/src/main/java/com/huoran/iasf/entity/UserGroup.java @@ -0,0 +1,53 @@ +package com.huoran.iasf.entity; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 用户组 + *

+ * + * @author cheney + * @since 2022-08-10 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sys_user_group") +@ApiModel(value="UserGroup对象", description="用户组") +public class UserGroup extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "名称") + @NotNull(message = "用户组名称不能为空!") + private String groupName; + + @ApiModelProperty(value = "描述") + private String description; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + +} diff --git a/src/main/java/com/huoran/iasf/mapper/GeneratorMapper.java b/src/main/java/com/huoran/iasf/mapper/GeneratorMapper.java new file mode 100644 index 0000000..942fec4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/GeneratorMapper.java @@ -0,0 +1,26 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.entity.SysGenerator; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * 代码生成 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface GeneratorMapper extends BaseMapper { + + IPage selectAllTables(Page page, @Param(value = "vo") SysGenerator vo); + + Map queryTable(String tableName); + + List> queryColumns(String tableName); +} diff --git a/src/main/java/com/huoran/iasf/mapper/SiteMapper.java b/src/main/java/com/huoran/iasf/mapper/SiteMapper.java new file mode 100644 index 0000000..81f935e --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SiteMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.Site; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 站点管理 Mapper 接口 + *

+ * + * @author cheney + * @since 2022-08-24 + */ +public interface SiteMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysColumnLongPageMapper.java b/src/main/java/com/huoran/iasf/mapper/SysColumnLongPageMapper.java new file mode 100644 index 0000000..d7039fb --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysColumnLongPageMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.SysColumnLongPage; +import org.apache.ibatis.annotations.Mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @描述:长页栏目拓展表 Mapper 接口 + * @作者: Rong + * @日期: 2022-08-09 + */ +@Mapper +public interface SysColumnLongPageMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysColumnMapper.java b/src/main/java/com/huoran/iasf/mapper/SysColumnMapper.java new file mode 100644 index 0000000..da8bcdc --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysColumnMapper.java @@ -0,0 +1,43 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.vo.FatherContentRespVO; +import com.huoran.iasf.vo.req.LongPageColumnReqVO; +import com.huoran.iasf.vo.req.PageContentReqVO; +import com.huoran.iasf.vo.req.PaginationColumnReqVO; +import com.huoran.iasf.vo.resp.PageContentRespVO; +import org.apache.ibatis.annotations.Mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @描述: Mapper 接口 + * @作者: Rong + * @日期: 2022-08-01 + */ +@Mapper +public interface SysColumnMapper extends BaseMapper { + List filter(@Param("vo") PaginationColumnReqVO vo); + + List filterMenuVisible(@Param("vo") PaginationColumnReqVO vo); + + + IPage longPageColumnList(Page page, @Param("req") LongPageColumnReqVO req); + + //依据子级查询父级 + List getParentInformationBasedOnChild(@Param("id")Integer id); + + List getsTheSubColumn(@Param("parentId")Integer parentId ,@Param("ids")String ids ,@Param("isSort")Integer isSort,@Param("siteId")Integer siteId); + + + Integer oneLevelChecksThemAll(@Param("theChildId")Integer theChildId); + + List queryByColumnType(@Param("ids")String ids); +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysContentClassificationMapper.java b/src/main/java/com/huoran/iasf/mapper/SysContentClassificationMapper.java new file mode 100644 index 0000000..c691fce --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysContentClassificationMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.SysContentClassification; +import org.apache.ibatis.annotations.Mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @描述:文章所属分类 Mapper 接口 + * @作者: Rong + * @日期: 2022-11-08 + */ +@Mapper +public interface SysContentClassificationMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysContentFileMapper.java b/src/main/java/com/huoran/iasf/mapper/SysContentFileMapper.java new file mode 100644 index 0000000..4d3120a --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysContentFileMapper.java @@ -0,0 +1,18 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.SysContentFile; +import org.apache.ibatis.annotations.Mapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @描述:文章附件管理表 Mapper 接口 + * @作者: Rong + * @日期: 2022-11-07 + */ +@Mapper +public interface SysContentFileMapper extends BaseMapper { + List getFileByContentId(@Param("contentId") Integer contentId); +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysContentLabelMapper.java b/src/main/java/com/huoran/iasf/mapper/SysContentLabelMapper.java new file mode 100644 index 0000000..3c4ab41 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysContentLabelMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysContentLabel; +import org.apache.ibatis.annotations.Mapper; + + +/** + * @描述:文章主题标签 Mapper 接口 + * @作者: Rong + * @日期: 2022-11-08 + */ +@Mapper +public interface SysContentLabelMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysContentMapper.java b/src/main/java/com/huoran/iasf/mapper/SysContentMapper.java new file mode 100644 index 0000000..967f61d --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysContentMapper.java @@ -0,0 +1,48 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.entity.SysContent; +import com.huoran.iasf.entity.SysContentClassification; +import com.huoran.iasf.entity.SysContentLabel; +import com.huoran.iasf.vo.req.PageContentReqVO; +import com.huoran.iasf.vo.resp.PageContentRespVO; +import org.apache.ibatis.annotations.Mapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @描述:文章管理 Mapper 接口 + * @作者: Rong + * @日期: 2022-08-05 + */ +@Mapper +public interface SysContentMapper extends BaseMapper { + IPage articlePaginationList(Page page, @Param("req") PageContentReqVO req); + + IPage getPublishedArticles(Page page, @Param("req") PageContentReqVO req); + + List useTheColumnToGetTagsForTheFullArticle(String ids); + + IPage siteSearchArticles(Page page, @Param("req") PageContentReqVO req); + + + List columnConditionsFilterArticles(@Param("columnId")String columnId); + + /*Integer selectNextId(@Param("content")SysContent sysContent); + + Integer updateSortById(@Param("content")SysContent sysContent); + + Integer selectPreviousId(@Param("content")SysContent sysContent);*/ + + + List queryArticleColumnParent(@Param("columnId")Integer columnId); + + + List hotContent(@Param("siteId")Integer siteId); + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysDeptMapper.java b/src/main/java/com/huoran/iasf/mapper/SysDeptMapper.java new file mode 100644 index 0000000..47c0cc5 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysDeptMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysDept; +import org.apache.ibatis.annotations.Mapper; + +/** + * 部门 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Mapper +public interface SysDeptMapper extends BaseMapper { +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysDictDetailMapper.java b/src/main/java/com/huoran/iasf/mapper/SysDictDetailMapper.java new file mode 100644 index 0000000..c5806d3 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysDictDetailMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysDictDetailEntity; + +/** + * 字典详情 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysDictDetailMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysDictMapper.java b/src/main/java/com/huoran/iasf/mapper/SysDictMapper.java new file mode 100644 index 0000000..b188a7d --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysDictMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysDictEntity; + +/** + * 字典 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysDictMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysFilesMapper.java b/src/main/java/com/huoran/iasf/mapper/SysFilesMapper.java new file mode 100644 index 0000000..38e19bb --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysFilesMapper.java @@ -0,0 +1,21 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.entity.SysFilesEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 文件上传 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Mapper +public interface SysFilesMapper extends BaseMapper { + + IPage fileList(Page page, @Param("req")SysFilesEntity sysFiles); +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysJobLogMapper.java b/src/main/java/com/huoran/iasf/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..4b17b2c --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysJobLogMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysJobLogEntity; + +/** + * 定时任务日志、 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysJobLogMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysJobMapper.java b/src/main/java/com/huoran/iasf/mapper/SysJobMapper.java new file mode 100644 index 0000000..692a83a --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysJobMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysJobEntity; + +/** + * 定时任务 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysJobMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysLogMapper.java b/src/main/java/com/huoran/iasf/mapper/SysLogMapper.java new file mode 100644 index 0000000..fa16d58 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysLogMapper.java @@ -0,0 +1,14 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysLog; + +/** + * 操作日志 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysLogMapper extends BaseMapper { +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysNavigationStyleMapper.java b/src/main/java/com/huoran/iasf/mapper/SysNavigationStyleMapper.java new file mode 100644 index 0000000..d4ec26f --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysNavigationStyleMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysNavigationStyle; +import org.apache.ibatis.annotations.Mapper; + +/** + * @描述:导航样式配置 Mapper 接口 + * @作者: Rong + * @日期: 2022-09-01 + */ +@Mapper +public interface SysNavigationStyleMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysPermissionMapper.java b/src/main/java/com/huoran/iasf/mapper/SysPermissionMapper.java new file mode 100644 index 0000000..0e99662 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysPermissionMapper.java @@ -0,0 +1,19 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysPermission; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 菜单权限 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysPermissionMapper extends BaseMapper { + + List selectRoleMenu(@Param("roleIds") String roleIds); +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysRoleMapper.java b/src/main/java/com/huoran/iasf/mapper/SysRoleMapper.java new file mode 100644 index 0000000..bea4d2d --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysRoleMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysRole; + +/** + * 角色 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysRoleMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysRolePermissionMapper.java b/src/main/java/com/huoran/iasf/mapper/SysRolePermissionMapper.java new file mode 100644 index 0000000..0c4bd50 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysRolePermissionMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysRolePermission; + +/** + * 角色权限 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysRolePermissionMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysTemplateMapper.java b/src/main/java/com/huoran/iasf/mapper/SysTemplateMapper.java new file mode 100644 index 0000000..bca17a5 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysTemplateMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.SysTemplate; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 栏目模板 Mapper 接口 + *

+ * + * @author cheney + * @since 2022-11-11 + */ +public interface SysTemplateMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysTemplateStyleConfigurationMapper.java b/src/main/java/com/huoran/iasf/mapper/SysTemplateStyleConfigurationMapper.java new file mode 100644 index 0000000..aa50c3b --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysTemplateStyleConfigurationMapper.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.SysTemplateStyle; +import com.huoran.iasf.entity.SysTemplateStyleConfiguration; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 栏目样式、列表样式、详情样式配置表 Mapper 接口 + *

+ * + * @author cheney + * @since 2022-11-24 + */ +public interface SysTemplateStyleConfigurationMapper extends BaseMapper { + List getTheStyleUnderTheTemplate(@Param("templateId") Integer templateId,@Param("type") Integer type); +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysTemplateStyleMapper.java b/src/main/java/com/huoran/iasf/mapper/SysTemplateStyleMapper.java new file mode 100644 index 0000000..669822e --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysTemplateStyleMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.SysTemplateStyle; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author cheney + * @since 2022-11-11 + */ +public interface SysTemplateStyleMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/SysUserMapper.java b/src/main/java/com/huoran/iasf/mapper/SysUserMapper.java new file mode 100644 index 0000000..51f2b37 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysUserMapper.java @@ -0,0 +1,23 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.entity.SysUser; +import com.huoran.iasf.vo.req.UserListReq; +import com.huoran.iasf.vo.resp.UserListResp; +import org.apache.ibatis.annotations.Param; + +/** + * 用户 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysUserMapper extends BaseMapper { + + IPage userList(Page page,@Param("req") UserListReq userListReq); + + UserListResp detailInfo(String id); +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/SysUserRoleMapper.java b/src/main/java/com/huoran/iasf/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..f4244d2 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/SysUserRoleMapper.java @@ -0,0 +1,15 @@ +package com.huoran.iasf.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.huoran.iasf.entity.SysUserRole; + +/** + * 用户角色 Mapper + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysUserRoleMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/UserDeptMapper.java b/src/main/java/com/huoran/iasf/mapper/UserDeptMapper.java new file mode 100644 index 0000000..b174a1c --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/UserDeptMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.UserDept; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 用户员工部门表 Mapper 接口 + *

+ * + * @author cheney + * @since 2022-08-15 + */ +public interface UserDeptMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/UserGroupMapper.java b/src/main/java/com/huoran/iasf/mapper/UserGroupMapper.java new file mode 100644 index 0000000..f9e5ad8 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/UserGroupMapper.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.mapper; + +import com.huoran.iasf.entity.UserGroup; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 用户组 Mapper 接口 + *

+ * + * @author cheney + * @since 2022-08-10 + */ +public interface UserGroupMapper extends BaseMapper { + +} diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SiteMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SiteMapper.xml new file mode 100644 index 0000000..450e622 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SiteMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysColumnLongPageMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysColumnLongPageMapper.xml new file mode 100644 index 0000000..a8893be --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysColumnLongPageMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysColumnMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysColumnMapper.xml new file mode 100644 index 0000000..5200724 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysColumnMapper.xml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysContentClassificationMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysContentClassificationMapper.xml new file mode 100644 index 0000000..be99075 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysContentClassificationMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysContentFileMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysContentFileMapper.xml new file mode 100644 index 0000000..32101c1 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysContentFileMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysContentLabelMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysContentLabelMapper.xml new file mode 100644 index 0000000..020ce5c --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysContentLabelMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysContentMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysContentMapper.xml new file mode 100644 index 0000000..fdaa9c1 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysContentMapper.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysFilesMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysFilesMapper.xml new file mode 100644 index 0000000..d38b95e --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysFilesMapper.xml @@ -0,0 +1,49 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysNavigationStyleMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysNavigationStyleMapper.xml new file mode 100644 index 0000000..e466f85 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysNavigationStyleMapper.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysPermissionMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysPermissionMapper.xml new file mode 100644 index 0000000..14ab577 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysPermissionMapper.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateMapper.xml new file mode 100644 index 0000000..187b49a --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleConfigurationMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleConfigurationMapper.xml new file mode 100644 index 0000000..b36c0e9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleConfigurationMapper.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleMapper.xml new file mode 100644 index 0000000..f5149e2 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/SysUserMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/SysUserMapper.xml new file mode 100644 index 0000000..ee24f1d --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/SysUserMapper.xml @@ -0,0 +1,152 @@ + + + + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/UserDeptMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/UserDeptMapper.xml new file mode 100644 index 0000000..35fd249 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/UserDeptMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/com/huoran/iasf/mapper/xml/UserGroupMapper.xml b/src/main/java/com/huoran/iasf/mapper/xml/UserGroupMapper.xml new file mode 100644 index 0000000..6a9d356 --- /dev/null +++ b/src/main/java/com/huoran/iasf/mapper/xml/UserGroupMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/com/huoran/iasf/service/DeptService.java b/src/main/java/com/huoran/iasf/service/DeptService.java new file mode 100644 index 0000000..cdb80dd --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/DeptService.java @@ -0,0 +1,49 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysDept; +import com.huoran.iasf.vo.resp.DeptRespNodeVO; + +import java.util.List; + +/** + * 部门 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface DeptService extends IService { + + /** + * 添加部门 + * + * @param vo vo + */ + void addDept(SysDept vo); + + /** + * 更新部门 + * + * @param vo vo + */ + void updateDept(SysDept vo); + + /** + * 删除部门 + * + * @param id id + */ + void deleted(String id); + + /** + * 部门树形列表 + * + * @param deptId deptId + * @return 树形列表 + */ + List deptTreeList(String deptId); + + + boolean checkDeptRepeat(SysDept sysDept); +} diff --git a/src/main/java/com/huoran/iasf/service/HomeService.java b/src/main/java/com/huoran/iasf/service/HomeService.java new file mode 100644 index 0000000..ae54d0a --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/HomeService.java @@ -0,0 +1,21 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.vo.resp.HomeRespVO; + +/** + * 首页 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface HomeService { + + /** + * 获取首页信息 + * + * @param userId userId + * @return HomeRespVO + */ + HomeRespVO getHomeInfo(String userId); +} diff --git a/src/main/java/com/huoran/iasf/service/HttpApiSessionService.java b/src/main/java/com/huoran/iasf/service/HttpApiSessionService.java new file mode 100644 index 0000000..ffc408b --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/HttpApiSessionService.java @@ -0,0 +1,97 @@ +package com.huoran.iasf.service; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.Date; + +/** + * session管理器 + * @author cheney + * @version V1.0 + * @date 2022年5月11日 + */ +@Service +public class HttpApiSessionService { + + + public static final String USER_ID_KEY = "user_id_key"; + + public static final String USER_USERNAME_KEY = "user_username_key"; + + public static final String SUBJECT = "HuoRan_SUBJECT"; + + public static final long EXPIRE = 1000 * 60 * 60 * 24; //过期时间,毫秒,一天 + + //秘钥 + public static final String APP_SECRET = "HuoRan_SYMMETRIC_ENCRYPTION_HS256"; + + @Resource + private HttpServletRequest request; + + /** + * 生成jwt + * @param userId username + * @return token + */ + public String generateToken(Integer userId, String userName) { + String token = Jwts.builder().setSubject(SUBJECT) + .claim(USER_ID_KEY, userId) + .claim(USER_USERNAME_KEY, userName) + .setIssuedAt(new Date()) + .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) + .signWith(SignatureAlgorithm.HS256, APP_SECRET).compact(); + return token; + } + + + /** + * 校验token + * + * @param token + * @return + */ + public Claims checkJWT(String token) { + + try { + final Claims claims = Jwts.parser().setSigningKey(APP_SECRET). + parseClaimsJws(token).getBody(); + return claims; + } catch (Exception e) { + } + return null; + + } + + /** + * 获取当前session信息 username + * + * @return username + */ + public String getCurrentUsername() { + if (request.getAttribute(USER_USERNAME_KEY) != null) { + return request.getAttribute(USER_USERNAME_KEY).toString(); + } else { + return null; + } + } + + /** + * 获取当前session信息 UserId + * + * @return UserId + */ + public String getCurrentUserId() { + if (request.getAttribute(USER_ID_KEY) != null) { + return request.getAttribute(USER_ID_KEY).toString(); + } else { + return null; + } + } + + +} diff --git a/src/main/java/com/huoran/iasf/service/HttpSessionService.java b/src/main/java/com/huoran/iasf/service/HttpSessionService.java new file mode 100644 index 0000000..58dd00e --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/HttpSessionService.java @@ -0,0 +1,270 @@ +package com.huoran.iasf.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.entity.SysUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * session管理器 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +public class HttpSessionService { + @Resource + private RedisService redisService; + @Resource + private UserRoleService userRoleService; + + @Resource + private HttpServletRequest request; + @Resource + private PermissionService permissionService; + @Resource + private RoleService roleService; + + @Value("${spring.redis.key.prefix.userToken}") + private String userTokenPrefix; + + @Value("${spring.redis.key.expire.userToken}") + private int exire; + + @Value("${spring.redis.key.prefix.permissionRefresh}") + private String redisPermissionRefreshKey; + + @Value("${spring.redis.key.expire.permissionRefresh}") + private Long redisPermissionRefreshExpire; + + @Autowired + private HttpApiSessionService sessionService; + + public String createTokenAndUser(SysUser user, List roles, Set permissions) { + String token = sessionService.generateToken(user.getId(), user.getUsername()); + //方便根据id找到redis的key, 修改密码/退出登陆 方便使用 +// String token = getRandomToken() + "#" + user.getId(); + JSONObject sessionInfo = new JSONObject(); + sessionInfo.put(Constant.USERID_KEY, user.getId()); + sessionInfo.put(Constant.USERNAME_KEY, user.getUsername()); + sessionInfo.put(Constant.ROLES_KEY, roles); + sessionInfo.put(Constant.PERMISSIONS_KEY, permissions); + String key = userTokenPrefix + token; + //设置该用户已登录的token + redisService.setAndExpire(key, sessionInfo.toJSONString(), exire); + + //登陆后删除权限刷新标志 + redisService.del(redisPermissionRefreshKey + user.getId()); + return token; + } + + /** + * 根据token获取userid + * + * @param token token + * @return userid + */ + public static String getUserIdByToken(String token) { + if (StringUtils.isBlank(token) || !token.contains("#")) { + return ""; + } else { + return token.substring(token.indexOf("#") + 1); + } + } + + /** + * 获取参数中的token + * + * @return token + */ + public String getTokenFromHeader() { + String token = request.getHeader(Constant.ACCESS_TOKEN); + //如果header中不存在token,则从参数中获取token + if (StringUtils.isBlank(token)) { + token = request.getParameter(Constant.ACCESS_TOKEN); + } + return token; + } + + /** + * 获取当前session信息 + * + * @return session信息 + */ + public JSONObject getCurrentSession() { + String token = getTokenFromHeader(); + if (null != token) { + if (redisService.exists(userTokenPrefix + token)) { + String sessionInfoStr = redisService.get(userTokenPrefix + token); + return JSON.parseObject(sessionInfoStr); + } else { + return null; + } + } else { + return null; + } + } + + /** + * 获取当前session信息 username + * + * @return username + */ + public String getCurrentUsername() { + if (getCurrentSession() != null) { + return getCurrentSession().getString(Constant.USERNAME_KEY); + } else { + return null; + } + } + + /** + * 获取当前session信息 UserId + * + * @return UserId + */ + public Integer getCurrentUserId() { + if (getCurrentSession() != null) { + return Integer.parseInt(getCurrentSession().getString(Constant.USERID_KEY)); + } else { + return null; + } + } + + + /** + * 使当前用户的token失效 + */ + public void abortUserByToken() { + String token = getTokenFromHeader(); + redisService.del(userTokenPrefix + token); + } + + /** + * 使所有用户的token失效 + */ + public void abortAllUserByToken() { + String token = getTokenFromHeader(); + String userId = getUserIdByToken(token); + redisService.delKeys(userTokenPrefix + "*#" + userId); + } + + /** + * 使用户的token失效 + */ + public void abortUserById(Integer userId) { + redisService.delKeys(userTokenPrefix + "*#" + userId); + } + + /** + * 使多个用户的token失效 + */ + public void abortUserByUserIds(List userIds) { + if (CollectionUtils.isNotEmpty(userIds)) { + for (Integer id : userIds) { + redisService.delKeys(userTokenPrefix + "*#" + id); + } + + } + } + + /** + * 根据用户id, 刷新redis用户权限 + * + * @param userId userId + */ + public void refreshUerId(Integer userId) { + redisService.delKeys(userTokenPrefix + "*#" + userId); + + + Set keys = redisService.keys("#" + userId); + //如果修改了角色/权限, 那么刷新权限 + for (String key : keys) { + JSONObject redisSession = JSON.parseObject(redisService.get(key)); + + List roleNames = getRolesByUserId(userId); + if (!CollectionUtils.isEmpty(roleNames)) { + redisSession.put(Constant.ROLES_KEY, roleNames); + } + Set permissions = getPermissionsByUserId(userId); + redisSession.put(Constant.PERMISSIONS_KEY, permissions); + Long redisTokenKeyExpire = redisService.getExpire(key); + //刷新token绑定的角色权限 + redisService.setAndExpire(key, redisSession.toJSONString(), redisTokenKeyExpire); + + } + } + + /** + * 根据角色id, 刷新redis用户权限 + * + * @param roleId roleId + */ + public void refreshRolePermission(Integer roleId) { + List userIds = userRoleService.getUserIdsByRoleId(roleId); + if (!CollectionUtils.isEmpty(userIds)) { + userIds.parallelStream().forEach(this::refreshUerId); + } + } + + /** + * 根据权限id, 刷新redis用户权限 + * + * @param permissionId permissionId + */ + public void refreshPermission(Integer permissionId) { + List userIds = permissionService.getUserIdsById(permissionId); + if (!CollectionUtils.isEmpty(userIds)) { + userIds.parallelStream().forEach(this::refreshUerId); + } + } + + + /** + * 生成随机的token + * + * @return token + */ + private String getRandomToken() { + Random random = new Random(); + StringBuilder randomStr = new StringBuilder(); + + // 根据length生成相应长度的随机字符串 + for (int i = 0; i < 32; i++) { + String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num"; + + //输出字母还是数字 + if ("char".equalsIgnoreCase(charOrNum)) { + //输出是大写字母还是小写字母 + int temp = random.nextInt(2) % 2 == 0 ? 65 : 97; + randomStr.append((char) (random.nextInt(26) + temp)); + } else { + randomStr.append(random.nextInt(10)); + } + } + + return randomStr.toString(); + } + + + private List getRolesByUserId(Integer userId) { + return roleService.getRoleNames(userId); + } + + private Set getPermissionsByUserId(Integer userId) { + return permissionService.getPermissionsByUserId(userId); + } + +} diff --git a/src/main/java/com/huoran/iasf/service/ISysGeneratorService.java b/src/main/java/com/huoran/iasf/service/ISysGeneratorService.java new file mode 100644 index 0000000..83ae42b --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/ISysGeneratorService.java @@ -0,0 +1,32 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.entity.SysGenerator; + +/** + * 代码生成 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface ISysGeneratorService { + + /** + * 获取所有表 + * + * @param page page + * @param vo vo + * @return IPage + */ + IPage selectAllTables(Page page, SysGenerator vo); + + /** + * 生成代码 + * + * @param tables tables + * @return byte[] + */ + byte[] generatorCode(String[] tables); +} diff --git a/src/main/java/com/huoran/iasf/service/LogService.java b/src/main/java/com/huoran/iasf/service/LogService.java new file mode 100644 index 0000000..f2b426a --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/LogService.java @@ -0,0 +1,14 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysLog; + +/** + * 系统日志 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface LogService extends IService { +} diff --git a/src/main/java/com/huoran/iasf/service/PermissionService.java b/src/main/java/com/huoran/iasf/service/PermissionService.java new file mode 100644 index 0000000..c176309 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/PermissionService.java @@ -0,0 +1,89 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysPermission; +import com.huoran.iasf.vo.resp.PermissionRespNode; + +import java.util.List; +import java.util.Set; + +/** + * 菜单权限 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface PermissionService extends IService { + + /** + * 根据userId获取权限 + * + * @param userId userId + * @return 权限 + */ + List getPermission(Integer userId); + + /** + * 删除权限 + * + * @param permissionId 权限id + */ + void deleted(Integer permissionId); + + /** + * 获取所有 + * + * @return List + */ + List selectAll(); + + /** + * 根据userId获取权限标志 + * + * @param userId userId + * @return Set + */ + Set getPermissionsByUserId(Integer userId); + + /** + * 根据userId获取权限树 + * + * @param userId + * @return List + */ + List permissionTreeList(Integer userId); + + /** + * 根据权限树 + * + * @return List + */ + List selectAllByTree(); + + /** + * 根据目录树 + * + * @param permissionId permissionId + * @return List + */ + List selectAllMenuByTree(Integer permissionId); + + + /** + * 根据权限id获取绑定的userId + * + * @param permissionId permissionId + * @return List + */ + List getUserIdsById(Integer permissionId); + + /** + * 更新 + * + * @param vo vo + */ + void updatePermission(SysPermission vo); + + List permissionList(Integer id); +} diff --git a/src/main/java/com/huoran/iasf/service/RedisService.java b/src/main/java/com/huoran/iasf/service/RedisService.java new file mode 100644 index 0000000..73e4b79 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/RedisService.java @@ -0,0 +1,74 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + + +/** + * redis + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +public class RedisService { + private final StringRedisTemplate redisTemplate; + + public RedisService(StringRedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + public boolean exists(String key) { + return this.redisTemplate.hasKey(key); + } + + public Long getExpire(String key) { + if (null == key) { + throw new BusinessException(BaseResponseCode.KEY_OR_TOMEUNIT); + } + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + + public void set(String key, String value) { + this.redisTemplate.opsForValue().set(key, value); + } + + + public String get(String key) { + return this.redisTemplate.opsForValue().get(key); + } + + public void del(String key) { + if (this.exists(key)) { + this.redisTemplate.delete(key); + } + + } + + public void setAndExpire(String key, String value, long seconds) { + this.redisTemplate.opsForValue().set(key, value); + this.redisTemplate.expire(key, seconds, TimeUnit.SECONDS); + } + + + public Set keys(String pattern) { + return redisTemplate.keys("*" + pattern); + } + + public void delKeys(String pattern) { + Set keys = redisTemplate.keys(pattern); + if (!CollectionUtils.isEmpty(keys)) { + this.redisTemplate.delete(keys); + } + } + + +} diff --git a/src/main/java/com/huoran/iasf/service/RolePermissionService.java b/src/main/java/com/huoran/iasf/service/RolePermissionService.java new file mode 100644 index 0000000..65efdad --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/RolePermissionService.java @@ -0,0 +1,22 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysRolePermission; +import com.huoran.iasf.vo.req.RolePermissionOperationReqVO; + +/** + * 角色权限关联 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface RolePermissionService extends IService { + + /** + * 角色绑定权限 + * + * @param vo vo + */ + void addRolePermission(RolePermissionOperationReqVO vo); +} diff --git a/src/main/java/com/huoran/iasf/service/RoleService.java b/src/main/java/com/huoran/iasf/service/RoleService.java new file mode 100644 index 0000000..7558497 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/RoleService.java @@ -0,0 +1,55 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysRole; + +import java.util.List; + +/** + * 角色 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface RoleService extends IService { + + /** + * 添加角色 + * + * @param vo SysRole + */ + void addRole(SysRole vo); + + /** + * 更新角色 + * + * @param vo SysRole + */ + void updateRole(SysRole vo); + + /** + * 根据id删除 + * + * @param id id + */ + void deletedRole(List ids); + + /** + * 根据userId获取绑定的角色 + * + * @param userId userId + * @return List + */ + List getRoleInfoByUserId(Integer userId); + + /** + * 根据userId获取绑定的角色名 + * + * @param userId userId + * @return List + */ + List getRoleNames(Integer userId); + + boolean checkDeptRepeat(SysRole vo); +} diff --git a/src/main/java/com/huoran/iasf/service/SiteService.java b/src/main/java/com/huoran/iasf/service/SiteService.java new file mode 100644 index 0000000..b9f4a2f --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SiteService.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.Site; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 站点管理 服务类 + *

+ * + * @author cheney + * @since 2022-08-24 + */ +public interface SiteService extends IService { + +} diff --git a/src/main/java/com/huoran/iasf/service/SysColumnLongPageService.java b/src/main/java/com/huoran/iasf/service/SysColumnLongPageService.java new file mode 100644 index 0000000..6052d6b --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysColumnLongPageService.java @@ -0,0 +1,14 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysColumnLongPage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @描述:长页栏目拓展表 service接口 + * @作者: Rong + * @日期: 2022-08-09 + */ +public interface SysColumnLongPageService extends IService { + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/SysColumnService.java b/src/main/java/com/huoran/iasf/service/SysColumnService.java new file mode 100644 index 0000000..61ddc67 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysColumnService.java @@ -0,0 +1,46 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.vo.req.ColumnWeightReqVO; +import com.huoran.iasf.vo.req.LongPageColumnReqVO; +import com.huoran.iasf.vo.req.PageContentReqVO; +import com.huoran.iasf.vo.req.PaginationColumnReqVO; + +import java.util.List; + +/** + * @描述: service接口 + * @作者: Rong + * @日期: 2022-08-01 + */ +public interface SysColumnService extends IService { + + //新增栏目前,同级判重 + boolean sameLevelJudgment(ColumnWeightReqVO column); + + + List listWithTree(PaginationColumnReqVO sysColumn); + + //栏目树结构(前台可见,只展示试单可见的栏目) + List listWithTreeMenuVisible(PaginationColumnReqVO sysColumn); + + //长页栏目列表 + R longPageColumnList(LongPageColumnReqVO reqVO); + + + R getsTheSubColumn(Integer parentId,String ids,Integer siteId); + + + R getsSublevelColumnsUnderALevel(Integer parentId,String ids,Integer siteId); + + Integer oneLevelChecksThemAll(Integer theChildId); + + + R getSubColumn(Integer parentId,String ids,Integer isSort,Integer siteId); + + R queryArticlesByColumnType(String ids,Integer id); + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/SysContentClassificationService.java b/src/main/java/com/huoran/iasf/service/SysContentClassificationService.java new file mode 100644 index 0000000..c5413b9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysContentClassificationService.java @@ -0,0 +1,14 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysContentClassification; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @描述:文章所属分类 service接口 + * @作者: Rong + * @日期: 2022-11-08 + */ +public interface SysContentClassificationService extends IService { + + + } \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/SysContentFileService.java b/src/main/java/com/huoran/iasf/service/SysContentFileService.java new file mode 100644 index 0000000..10effc4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysContentFileService.java @@ -0,0 +1,17 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysContentFile; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * @描述:文章附件管理表 service接口 + * @作者: Rong + * @日期: 2022-11-07 + */ +public interface SysContentFileService extends IService { + + List getFileByContentId(Integer contentId); + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/SysContentLabelService.java b/src/main/java/com/huoran/iasf/service/SysContentLabelService.java new file mode 100644 index 0000000..6e52dc9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysContentLabelService.java @@ -0,0 +1,14 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysContentLabel; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @描述:文章主题标签 service接口 + * @作者: Rong + * @日期: 2022-11-08 + */ +public interface SysContentLabelService extends IService { + + + } \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/SysContentService.java b/src/main/java/com/huoran/iasf/service/SysContentService.java new file mode 100644 index 0000000..a61b155 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysContentService.java @@ -0,0 +1,48 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysContent; +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.vo.req.ArticleModifiedSortReq; +import com.huoran.iasf.vo.req.ContentHeavyTitleReqVO; +import com.huoran.iasf.vo.req.PageContentReqVO; +import io.swagger.annotations.ApiParam; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +/** + * @描述:文章管理 service接口 + * @作者: Rong + * @日期: 2022-08-05 + */ +public interface SysContentService extends IService { + //新增栏目前,标题全库判重 + boolean checkIfTheTitleIsRepeat(ContentHeavyTitleReqVO content); + + //分页栏目列表 + R articlePaginationList(PageContentReqVO reqVO); + + //站点最新发布的文章 + R newlyPublishedArticles(PageContentReqVO reqVO); + + //查询已发布的、启用了的文章列表 + R publishedEnabledArticles(); + + R getTheFullArticleByColumn(String ids); + + //统计浏览 + Integer statisticsOfPageViews(Integer id); + + List hotContent(Integer sideId); + + R siteSearchArticles(PageContentReqVO req); + + R queryArticleColumnParent(Integer articleId); + +// R modifiedSort(List reqList); + +// R modifiedSort(Integer sequenceNumber, Integer articleId); + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/SysDictDetailService.java b/src/main/java/com/huoran/iasf/service/SysDictDetailService.java new file mode 100644 index 0000000..9c9864a --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysDictDetailService.java @@ -0,0 +1,26 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysDictDetailEntity; + +/** + * 数据字典 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysDictDetailService extends IService { + + /** + * 分页 + * + * @param page page + * @param dictId dictId + * @return IPage + */ + IPage listByPage(Page page, String dictId); +} + diff --git a/src/main/java/com/huoran/iasf/service/SysDictService.java b/src/main/java/com/huoran/iasf/service/SysDictService.java new file mode 100644 index 0000000..c21b446 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysDictService.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysDictEntity; + +/** + * 数据字典 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysDictService extends IService { + +} + diff --git a/src/main/java/com/huoran/iasf/service/SysFilesService.java b/src/main/java/com/huoran/iasf/service/SysFilesService.java new file mode 100644 index 0000000..3880148 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysFilesService.java @@ -0,0 +1,36 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysFilesEntity; +import com.huoran.iasf.vo.UEditorResultVO; +import com.huoran.iasf.vo.req.FileParameters; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; + +/** + * 文件上传 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysFilesService extends IService { + + UEditorResultVO saveFile(MultipartFile file, FileParameters fileParameters); + + void removeByIdsAndFiles(List ids); + + void preview(String id, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException; + + void download(String id, HttpServletRequest req, HttpServletResponse res); + + R getPage(SysFilesEntity sysFiles); +} + diff --git a/src/main/java/com/huoran/iasf/service/SysJobLogService.java b/src/main/java/com/huoran/iasf/service/SysJobLogService.java new file mode 100644 index 0000000..4928112 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysJobLogService.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysJobLogEntity; + +/** + * 定时任务 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysJobLogService extends IService { + +} + diff --git a/src/main/java/com/huoran/iasf/service/SysJobService.java b/src/main/java/com/huoran/iasf/service/SysJobService.java new file mode 100644 index 0000000..d0bb02b --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysJobService.java @@ -0,0 +1,67 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysJobEntity; + +import java.util.List; + +/** + * 定时任务 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface SysJobService extends IService { + + /** + * 保存job + * + * @param sysJob sysJob + */ + void saveJob(SysJobEntity sysJob); + + /** + * 更新job + * + * @param sysJob sysJob + */ + void updateJobById(SysJobEntity sysJob); + + /** + * 删除job + * + * @param ids ids + */ + void delete(List ids); + + /** + * 运行一次job + * + * @param ids ids + */ + void run(List ids); + + /** + * 暂停job + * + * @param ids ids + */ + void pause(List ids); + + /** + * 恢复job + * + * @param ids ids + */ + void resume(List ids); + + /** + * 批量更新状态 + * + * @param ids ids + * @param status status + */ + void updateBatch(List ids, int status); +} + diff --git a/src/main/java/com/huoran/iasf/service/SysNavigationStyleService.java b/src/main/java/com/huoran/iasf/service/SysNavigationStyleService.java new file mode 100644 index 0000000..9df908e --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysNavigationStyleService.java @@ -0,0 +1,14 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysNavigationStyle; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @描述:导航样式配置 service接口 + * @作者: Rong + * @日期: 2022-09-01 + */ +public interface SysNavigationStyleService extends IService { + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/SysTemplateService.java b/src/main/java/com/huoran/iasf/service/SysTemplateService.java new file mode 100644 index 0000000..40e065e --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysTemplateService.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysTemplate; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 栏目模板 服务类 + *

+ * + * @author cheney + * @since 2022-11-11 + */ +public interface SysTemplateService extends IService { + +} diff --git a/src/main/java/com/huoran/iasf/service/SysTemplateStyleConfigurationService.java b/src/main/java/com/huoran/iasf/service/SysTemplateStyleConfigurationService.java new file mode 100644 index 0000000..eb3d991 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysTemplateStyleConfigurationService.java @@ -0,0 +1,19 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysTemplateStyle; +import com.huoran.iasf.entity.SysTemplateStyleConfiguration; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + *

+ * 栏目样式、列表样式、详情样式配置表 服务类 + *

+ * + * @author cheney + * @since 2022-11-24 + */ +public interface SysTemplateStyleConfigurationService extends IService { + List getsTheStyleUnderTheTemplate(Integer templateId,Integer type); +} diff --git a/src/main/java/com/huoran/iasf/service/SysTemplateStyleService.java b/src/main/java/com/huoran/iasf/service/SysTemplateStyleService.java new file mode 100644 index 0000000..f32b1ff --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/SysTemplateStyleService.java @@ -0,0 +1,18 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.SysTemplateStyle; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author cheney + * @since 2022-11-11 + */ +public interface SysTemplateStyleService extends IService { + +} diff --git a/src/main/java/com/huoran/iasf/service/UserDeptService.java b/src/main/java/com/huoran/iasf/service/UserDeptService.java new file mode 100644 index 0000000..b25966b --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/UserDeptService.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.UserDept; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 用户员工部门表 服务类 + *

+ * + * @author cheney + * @since 2022-08-15 + */ +public interface UserDeptService extends IService { + +} diff --git a/src/main/java/com/huoran/iasf/service/UserGroupService.java b/src/main/java/com/huoran/iasf/service/UserGroupService.java new file mode 100644 index 0000000..e8cbd21 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/UserGroupService.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.service; + +import com.huoran.iasf.entity.UserGroup; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 用户组 服务类 + *

+ * + * @author cheney + * @since 2022-08-10 + */ +public interface UserGroupService extends IService { + +} diff --git a/src/main/java/com/huoran/iasf/service/UserRoleService.java b/src/main/java/com/huoran/iasf/service/UserRoleService.java new file mode 100644 index 0000000..d0de4d7 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/UserRoleService.java @@ -0,0 +1,40 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.entity.SysUserRole; +import com.huoran.iasf.vo.req.UserRoleOperationReqVO; + +import java.util.List; + +/** + * 用户角色 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface UserRoleService extends IService { + + /** + * 根据userId获取绑定的角色id + * + * @param userId userId + * @return List + */ + List getRoleIdsByUserId(Integer userId); + + /** + * 用户绑定角色 + * + * @param vo vo + */ + void addUserRoleInfo(UserRoleOperationReqVO vo); + + /** + * 根据角色id获取绑定的人 + * + * @param roleId roleId + * @return List + */ + List getUserIdsByRoleId(Integer roleId); +} diff --git a/src/main/java/com/huoran/iasf/service/UserService.java b/src/main/java/com/huoran/iasf/service/UserService.java new file mode 100644 index 0000000..b187c69 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/UserService.java @@ -0,0 +1,69 @@ +package com.huoran.iasf.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysUser; +import com.huoran.iasf.vo.CheckVo; +import com.huoran.iasf.vo.req.UpdatePhoneOrEmailReq; +import com.huoran.iasf.vo.req.UserListReq; +import com.huoran.iasf.vo.resp.LoginRespVO; +import com.huoran.iasf.vo.resp.UserListResp; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Map; + +/** + * 用户 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +public interface UserService extends IService { + + /** + * 注册 + */ + void register(SysUser vo); + + /** + * 登陆 + */ + LoginRespVO login(SysUser vo); + + /** + * 更新用户信息 + */ + void updateUserInfo(SysUser vo); + + /** + * 分页 + */ + R pageInfo(UserListReq userListReq); + + /** + * 添加用户 + */ + void addUser(SysUser vo); + + /** + * 修改密码 + */ + void updatePwd(SysUser vo); + + UserListResp detailInfo(String id); + + R resetPwd(String userId); + + Map importStaff(MultipartFile file); + + void exportFailureRecord(HttpServletResponse response, String exportCode) throws IOException; + + R sendCheckPhoneCode(CheckVo checkVo); + + R updatePhoneOrEmail(UpdatePhoneOrEmailReq updatePhoneOrEmailReq); + + R updateUserAvatars(String userId, MultipartFile file); +} diff --git a/src/main/java/com/huoran/iasf/service/impl/DeptServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/DeptServiceImpl.java new file mode 100644 index 0000000..f0c49a4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/DeptServiceImpl.java @@ -0,0 +1,242 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.entity.SysDept; +import com.huoran.iasf.entity.UserDept; +import com.huoran.iasf.mapper.SysDeptMapper; +import com.huoran.iasf.mapper.SysUserMapper; +import com.huoran.iasf.mapper.UserDeptMapper; +import com.huoran.iasf.service.DeptService; +import com.huoran.iasf.vo.resp.DeptRespNodeVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +/** + * 部门 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +@Slf4j +public class DeptServiceImpl extends ServiceImpl implements DeptService { + + @Resource + private SysDeptMapper sysDeptMapper; + @Resource + private UserDeptMapper userDeptMapper; + @Resource + private SysUserMapper sysUserMapper; + + @Override + public void addDept(SysDept vo) { + String relationCode; + String deptCode = this.getNewDeptCode(); + SysDept parent = sysDeptMapper.selectById(vo.getPid()); + if (vo.getPid()==null){ + vo.setPid(0); + } + if (vo.getPid()==0) { + relationCode = deptCode; + } else if (null == parent) { + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } else { + relationCode = parent.getRelationCode() + deptCode; + } + vo.setDeptNo(deptCode); + vo.setRelationCode(relationCode); + vo.setStatus(1); + sysDeptMapper.insert(vo); + } + + @Override + public boolean checkDeptRepeat(SysDept sysDept){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("name", sysDept.getName()); + queryWrapper.eq("pid", sysDept.getPid()); + if (sysDept.getId()!=null) { + queryWrapper.last(" and id != " + sysDept.getId()); + } + List sysDepts = baseMapper.selectList(queryWrapper); + return sysDepts.size() > 0; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateDept(SysDept vo) { + + SysDept sysDept = sysDeptMapper.selectById(vo.getId()); + if (null == sysDept) { + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } + sysDeptMapper.updateById(vo); + //说明层级发生了变化 + /*if (!StringUtils.isEmpty(vo.getPid()) && !vo.getPid().equals(sysDept.getPid())) { + SysDept parent = sysDeptMapper.selectById(vo.getPid()); + if (!"0".equals(vo.getPid()) && null == parent) { + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } + *//*SysDept oldParent = sysDeptMapper.selectById(sysDept.getPid()); + String oldRelationCode; + String newRelationCode; + //根目录降到其他目录 + if ("0".equals(sysDept.getPid())) { + oldRelationCode = sysDept.getDeptNo(); + newRelationCode = parent.getRelationCode() + sysDept.getDeptNo(); + } else if ("0".equals(vo.getPid())) { // 其他目录升级到跟目录 + oldRelationCode = sysDept.getRelationCode(); + newRelationCode = sysDept.getDeptNo(); + } else { + oldRelationCode = oldParent.getRelationCode(); + newRelationCode = parent.getRelationCode(); + }*//* + *//*LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.likeLeft(SysDept::getDeptNo, sysDept.getDeptNo()); + List list = sysDeptMapper.selectList(wrapper); + list.parallelStream().forEach(entity -> { + String relationCode = entity.getRelationCode().replace(oldRelationCode, newRelationCode); + entity.setRelationCode(relationCode); + sysDeptMapper.updateById(entity); + });*//* + }*/ + } + + @Override + public void deleted(String id) { + SysDept sysDept = sysDeptMapper.selectById(id); + if (null == sysDept) { + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } + List deptIds = sysDeptMapper.selectObjs(Wrappers.lambdaQuery().select(SysDept::getId).likeRight(SysDept::getRelationCode, sysDept.getRelationCode())); + + if (deptIds!=null&&deptIds.size()>0){ + List list = userDeptMapper.selectList(Wrappers.lambdaQuery().in(UserDept::getDeptId, deptIds)); + if (!CollectionUtils.isEmpty(list)) { + throw new BusinessException(BaseResponseCode.NOT_PERMISSION_DELETED_DEPT); + } + }else { + //查询是否有子级部门 + QueryWrapper deptQueryWrapper = new QueryWrapper<>(); + deptQueryWrapper.eq("pid",sysDept.getId()); + List sysDepts = sysDeptMapper.selectList(deptQueryWrapper); + if (sysDepts!=null&& sysDepts.size()>0){ + throw new BusinessException(BaseResponseCode.DELETE_SUB_DEPARTMENTS_FIRST); + } + } + sysDeptMapper.deleteById(id); + } + + @Override + public List deptTreeList(String deptId) { + List list; + if (StringUtils.isEmpty(deptId)) { + list = sysDeptMapper.selectList(Wrappers.emptyWrapper()); + } else { + SysDept sysDept = sysDeptMapper.selectById(deptId); + if (sysDept == null) { + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().likeRight(SysDept::getRelationCode, sysDept.getRelationCode()); + List childIds = sysDeptMapper.selectObjs(queryWrapper); + list = sysDeptMapper.selectList(Wrappers.lambdaQuery().notIn(SysDept::getId, childIds)); + } + // 默认加一个顶级方便新增顶级部门 + DeptRespNodeVO respNodeVO = new DeptRespNodeVO(); + respNodeVO.setName("默认顶级部门"); + respNodeVO.setId(0); +/* respNodeVO.setSpread(true); + respNodeVO.setDisabled(false);*/ + respNodeVO.setChildren(getTree(list)); + List result = new ArrayList<>(); + result.add(respNodeVO); + return result; + } + + private List getTree(List all) { + List list = new ArrayList<>(); + for (SysDept sysDept : all) { + if (sysDept.getPid()==0) { + DeptRespNodeVO deptTree = new DeptRespNodeVO(); + BeanUtils.copyProperties(sysDept, deptTree); + deptTree.setName(sysDept.getName()); + // deptTree.setSpread(true); + deptTree.setChildren(getChild(sysDept.getId(), all)); + list.add(deptTree); + } + } + return list; + } + + private List getChild(Integer id, List all) { + List list = new ArrayList<>(); + for (SysDept sysDept : all) { + if (sysDept.getPid().equals(id)) { + DeptRespNodeVO deptTree = new DeptRespNodeVO(); + BeanUtils.copyProperties(sysDept, deptTree); + deptTree.setName(sysDept.getName()); + deptTree.setChildren(getChild(sysDept.getId(), all)); + list.add(deptTree); + } + } + return list; + } + + //获取新的部门编码 + public String getNewDeptCode() { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.select(SysDept::getDeptNo); + //获取所有的deptCode + List deptCodes = sysDeptMapper.selectObjs(lambdaQueryWrapper); + AtomicReference maxDeptCode = new AtomicReference<>(0); + + //遍历获取最大的DeptCode + deptCodes.forEach(o -> { + String str = String.valueOf(o); + if (str.length() >= 7) { + Integer one = Integer.parseInt(str.substring(str.length() - 5)); + if (one > maxDeptCode.get()) { + maxDeptCode.set(one); + } + } + }); + + return padRight(maxDeptCode.get() + 1, 6, "0"); + } + + + /** + * 右补位,左对齐 + * + * @param len 目标字符串长度 + * @param alexi 补位字符 + * @param oriStr 原字符串 + * @return 目标字符串 + * 以alexin 做为补位 + */ + public static String padRight(int oriStr, int len, String alexi) { + StringBuilder str = new StringBuilder(); + int strlen = String.valueOf(oriStr).length(); + if (strlen < len) { + for (int i = 0; i < len - strlen; i++) { + str.append(alexi); + } + } + str.append(oriStr); + return "D" + str.toString(); + } +} diff --git a/src/main/java/com/huoran/iasf/service/impl/LogServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/LogServiceImpl.java new file mode 100644 index 0000000..bb61562 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/LogServiceImpl.java @@ -0,0 +1,18 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysLog; +import com.huoran.iasf.mapper.SysLogMapper; +import com.huoran.iasf.service.LogService; +import org.springframework.stereotype.Service; + +/** + * 系统日志 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +public class LogServiceImpl extends ServiceImpl implements LogService { +} diff --git a/src/main/java/com/huoran/iasf/service/impl/PermissionServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/PermissionServiceImpl.java new file mode 100644 index 0000000..abd481c --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/PermissionServiceImpl.java @@ -0,0 +1,328 @@ +package com.huoran.iasf.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.UnauthorizedException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.entity.SysPermission; +import com.huoran.iasf.entity.SysRolePermission; +import com.huoran.iasf.entity.SysUserRole; +import com.huoran.iasf.mapper.SysPermissionMapper; +import com.huoran.iasf.service.HttpSessionService; +import com.huoran.iasf.service.PermissionService; +import com.huoran.iasf.service.RolePermissionService; +import com.huoran.iasf.service.UserRoleService; +import com.huoran.iasf.vo.resp.PermissionRespNode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 菜单权限 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +@Slf4j +public class PermissionServiceImpl extends ServiceImpl implements PermissionService { + @Resource + private UserRoleService userRoleService; + @Resource + private RolePermissionService rolePermissionService; + @Resource + private SysPermissionMapper sysPermissionMapper; + @Resource + private HttpSessionService httpSessionService; + + /** + * 根据用户查询拥有的权限 + * 先查出用户拥有的角色 + * 再去差用户拥有的权限 + * 也可以多表关联查询 + */ + @Override + public List getPermission(Integer userId) { + List roleIds = userRoleService.getRoleIdsByUserId(userId); + if (CollectionUtils.isEmpty(roleIds)) { + return null; + } + List permissionIds = rolePermissionService.listObjs(Wrappers.lambdaQuery().select(SysRolePermission::getPermissionId).in(SysRolePermission::getRoleId, roleIds)); + if (CollectionUtils.isEmpty(permissionIds)) { + return null; + } + + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().in(SysPermission::getId, permissionIds).eq(SysPermission::getStatus, 1).orderByAsc(SysPermission::getOrderNum); + return sysPermissionMapper.selectList(queryWrapper); + } + + /** + * 删除菜单权限 + * 判断是否 有角色关联 + * 判断是否有子集 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void deleted(Integer permissionId) { + //获取关联userId + List userIds = getUserIdsById(permissionId); + SysPermission sysPermission = sysPermissionMapper.selectById(permissionId); + if (null == sysPermission) { + log.error("传入 的 id:{}不合法", permissionId); + throw new UnauthorizedException(BaseResponseCode.DATA_ERROR); + } + //获取下一级 + List childs = sysPermissionMapper.selectList(Wrappers.lambdaQuery().eq(SysPermission::getPid, permissionId)); + if (!CollectionUtils.isEmpty(childs)) { + throw new UnauthorizedException(BaseResponseCode.ROLE_PERMISSION_RELATION); + } + sysPermissionMapper.deleteById(permissionId); + //删除和角色关联 + rolePermissionService.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getPermissionId, permissionId)); + + if (!CollectionUtils.isEmpty(userIds)) { + //刷新权限 + userIds.parallelStream().forEach(httpSessionService::refreshUerId); + } + + } + + @Override + public List permissionList(Integer userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_id",userId); + List userRoles = userRoleService.list(queryWrapper); + String roleIds = ""; + if (ObjectUtil.isNotNull(userRoles)&& userRoles.size()>0){ + for (SysUserRole userRole: userRoles) { + roleIds += userRole.getRoleId() +","; + } + roleIds = roleIds.substring(0,roleIds.length()-1); + }else { + throw new BusinessException(BaseResponseCode.ROLE_ERROR); + } + List list = sysPermissionMapper.selectRoleMenu(roleIds); + return build(list); + } + + @Override + public void updatePermission(SysPermission vo) { + sysPermissionMapper.updateById(vo); + httpSessionService.refreshPermission(vo.getId()); + } + + /** + * 获取所有菜单权限 + */ + @Override + public List selectAll() { + List result = sysPermissionMapper.selectList(Wrappers.lambdaQuery().orderByAsc(SysPermission::getOrderNum)); + if (!CollectionUtils.isEmpty(result)) { + for (SysPermission sysPermission : result) { + SysPermission parent = sysPermissionMapper.selectById(sysPermission.getPid()); + if (parent != null) { + // sysPermission.setPidName(parent.getName()); + } + } + } + return result; + } + + /** + * 获取权限标识 + */ + @Override + public Set getPermissionsByUserId(Integer userId) { + + List list = getPermission(userId); + Set permissions = new HashSet<>(); + if (CollectionUtils.isEmpty(list)) { + return null; + } + for (SysPermission sysPermission : list) { + if (!StringUtils.isEmpty(sysPermission.getPerms())) { + permissions.add(sysPermission.getPerms()); + } + + } + return permissions; + } + + /** + * 以树型的形式把用户拥有的菜单权限返回给客户端 + */ + @Override + public List permissionTreeList(Integer userId) { + List list = getPermission(userId); + return getTree(list, true); + } + + /** + * 递归获取菜单树 + */ + private List getTree(List all, boolean type) { + + List list = new ArrayList<>(); + if (CollectionUtils.isEmpty(all)) { + return list; + } + for (SysPermission sysPermission : all) { + if ("0".equals(sysPermission.getPid())) { + PermissionRespNode permissionRespNode = new PermissionRespNode(); + BeanUtils.copyProperties(sysPermission, permissionRespNode); + permissionRespNode.setName(sysPermission.getName()); + + if (type) { + permissionRespNode.setChildren(getChildExcBtn(sysPermission.getId(), all)); + } else { + permissionRespNode.setChildren(getChildAll(sysPermission.getId(), all)); + } + list.add(permissionRespNode); + } + } + return list; + } + + /** + * 递归遍历所有 + */ + private List getChildAll(Integer id, List all) { + + List list = new ArrayList<>(); + for (SysPermission sysPermission : all) { + if (sysPermission.getPid().equals(id)) { + PermissionRespNode permissionRespNode = new PermissionRespNode(); + BeanUtils.copyProperties(sysPermission, permissionRespNode); + permissionRespNode.setName(sysPermission.getName()); + permissionRespNode.setChildren(getChildAll(sysPermission.getId(), all)); + list.add(permissionRespNode); + } + } + return list; + } + + /** + * 只递归获取目录和菜单 + */ + private List getChildExcBtn(Integer id, List all) { + + List list = new ArrayList<>(); + for (SysPermission sysPermission : all) { + if (sysPermission.getPid().equals(id) && sysPermission.getType() != 3) { + PermissionRespNode permissionRespNode = new PermissionRespNode(); + BeanUtils.copyProperties(sysPermission, permissionRespNode); + permissionRespNode.setName(sysPermission.getName()); + permissionRespNode.setChildren(getChildExcBtn(sysPermission.getId(), all)); + list.add(permissionRespNode); + } + } + return list; + } + + /** + * 获取所有菜单权限按钮 + */ + @Override + @Cacheable(value = {"permission"},key = "#root.methodName") + public List selectAllByTree() { + List permissionList = baseMapper.selectList(null); + return build(permissionList); + } + + /** + * 使用递归方法建菜单 + * @param treeNodes 权限菜单 + * @return 权限菜单 + */ + private static List build(List treeNodes) { + List trees = new ArrayList<>(); + for (SysPermission treeNode : treeNodes) { + if (treeNode.getPid()==0) { + treeNode.setLevel(1); + trees.add(findChildren(treeNode,treeNodes)); + } + } + return trees; + } + + /** + * 递归查找子节点 + * @param treeNodes 权限子菜单 + * @return 权限子菜单 + */ + private static SysPermission findChildren(SysPermission treeNode,List treeNodes) { + treeNode.setChildren(new ArrayList()); + + for (SysPermission it : treeNodes) { + if(treeNode.getId().equals(it.getPid())) { + int level = treeNode.getLevel() + 1; + it.setLevel(level); + if (treeNode.getChildren() == null) { + treeNode.setChildren(new ArrayList<>()); + } + treeNode.getChildren().add(findChildren(it,treeNodes)); + } + } + return treeNode; + } + + /** + * 获取所有的目录菜单树排除按钮 + * 因为不管是新增或者修改 + * 选择所属菜单目录的时候 + * 都不可能选择到按钮 + * 而且编辑的时候 所属目录不能 + * 选择自己和它的子类 + */ + @Override + public List selectAllMenuByTree(Integer permissionId) { + + List list = selectAll(); + if (!CollectionUtils.isEmpty(list) && !StringUtils.isEmpty(permissionId)) { + for (SysPermission sysPermission : list) { + if (sysPermission.getId().equals(permissionId)) { + list.remove(sysPermission); + break; + } + } + } + List result = new ArrayList<>(); + //新增顶级目录是为了方便添加一级目录 + PermissionRespNode respNode = new PermissionRespNode(); + respNode.setId(0); + respNode.setName("默认顶级菜单"); + // respNode.setSpread(true); + respNode.setChildren(getTree(list, true)); + result.add(respNode); + return result; + } + + @Override + public List getUserIdsById(Integer id) { + //根据权限id,获取所有角色id + //根据权限id,获取所有角色id + List roleIds = rolePermissionService.listObjs(Wrappers.lambdaQuery().select(SysRolePermission::getRoleId).eq(SysRolePermission::getPermissionId, id)); + if (!CollectionUtils.isEmpty(roleIds)) { + //根据角色id, 获取关联用户 + return userRoleService.listObjs(Wrappers.lambdaQuery().select(SysUserRole::getUserId).in(SysUserRole::getRoleId, roleIds)); + } + return null; + } + + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/RolePermissionServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/RolePermissionServiceImpl.java new file mode 100644 index 0000000..f768982 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/RolePermissionServiceImpl.java @@ -0,0 +1,36 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysRolePermission; +import com.huoran.iasf.mapper.SysRolePermissionMapper; +import com.huoran.iasf.service.RolePermissionService; +import com.huoran.iasf.vo.req.RolePermissionOperationReqVO; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * 角色权限关联 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +public class RolePermissionServiceImpl extends ServiceImpl implements RolePermissionService { + @Override + public void addRolePermission(RolePermissionOperationReqVO vo) { + List list = new ArrayList<>(); + for (Integer permissionId : vo.getPermissionIds()) { + SysRolePermission sysRolePermission = new SysRolePermission(); + sysRolePermission.setPermissionId(permissionId); + sysRolePermission.setRoleId(vo.getRoleId()); + list.add(sysRolePermission); + } + this.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getRoleId, vo.getRoleId())); + this.saveBatch(list); + } + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/RoleServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..ded14d3 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/RoleServiceImpl.java @@ -0,0 +1,154 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.entity.SysRole; +import com.huoran.iasf.entity.SysRolePermission; +import com.huoran.iasf.entity.SysUserRole; +import com.huoran.iasf.mapper.SysRoleMapper; +import com.huoran.iasf.service.HttpSessionService; +import com.huoran.iasf.service.RolePermissionService; +import com.huoran.iasf.service.RoleService; +import com.huoran.iasf.service.UserRoleService; +import com.huoran.iasf.vo.req.RolePermissionOperationReqVO; +import com.huoran.iasf.vo.resp.DeptRespNodeVO; +import com.huoran.iasf.vo.resp.PermissionRespNode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 角色 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +@Slf4j +public class RoleServiceImpl extends ServiceImpl implements RoleService { + @Resource + private SysRoleMapper sysRoleMapper; + @Resource + private UserRoleService userRoleService; + @Resource + private RolePermissionService rolePermissionService; + @Resource + private HttpSessionService httpSessionService; + + + @Transactional(rollbackFor = Exception.class) + @Override + public void addRole(SysRole vo) { + + vo.setStatus(1); + sysRoleMapper.insert(vo); + if (!CollectionUtils.isEmpty(vo.getPermissions())) { + RolePermissionOperationReqVO reqVO = new RolePermissionOperationReqVO(); + reqVO.setRoleId(vo.getId()); + reqVO.setPermissionIds(vo.getPermissions()); + rolePermissionService.addRolePermission(reqVO); + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void updateRole(SysRole vo) { + SysRole sysRole = sysRoleMapper.selectById(vo.getId()); + if (null == sysRole) { + log.error("传入 的 id:{}不合法", vo.getId()); + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } + sysRoleMapper.updateById(vo); + //删除角色权限关联 + rolePermissionService.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getRoleId, sysRole.getId())); + if (!CollectionUtils.isEmpty(vo.getPermissions())) { + RolePermissionOperationReqVO reqVO = new RolePermissionOperationReqVO(); + reqVO.setRoleId(sysRole.getId()); + reqVO.setPermissionIds(vo.getPermissions()); + rolePermissionService.addRolePermission(reqVO); + // 刷新权限 + httpSessionService.refreshRolePermission(sysRole.getId()); + } + } + + + private void setCheckedDept(List deptRespNodes, Set checkDeptList) { + for (DeptRespNodeVO node : deptRespNodes) { + if (checkDeptList.contains(node.getId())) { + // node.setChecked(true); + } + setCheckedDept((List) node.getChildren(), checkDeptList); + } + } + + + private void setChecked(List list, Set checkList) { + for (PermissionRespNode node : list) { + if (checkList.contains(node.getId()) + && CollectionUtils.isEmpty(node.getChildren())) { + // node.setChecked(true); + } + setChecked((List) node.getChildren(), checkList); + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void deletedRole(List ids) { + + for (Integer id : ids) { + //获取关联userId + List userIds = userRoleService.getUserIdsByRoleId(id); + //删除角色 + sysRoleMapper.deleteById(id); + //删除角色权限关联 + rolePermissionService.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getRoleId, id)); + //删除角色用户关联 + userRoleService.remove(Wrappers.lambdaQuery().eq(SysUserRole::getRoleId, id)); + if (!CollectionUtils.isEmpty(userIds)) { + // 刷新权限 + userIds.parallelStream().forEach(httpSessionService::refreshUerId); + } + } + } + + @Override + public List getRoleInfoByUserId(Integer userId) { + + List roleIds = userRoleService.getRoleIdsByUserId(userId); + if (CollectionUtils.isEmpty(roleIds)) { + return null; + } + return sysRoleMapper.selectBatchIds(roleIds); + } + + @Override + public List getRoleNames(Integer userId) { + List sysRoles = getRoleInfoByUserId(userId); + if (CollectionUtils.isEmpty(sysRoles)) { + return null; + } + return sysRoles.stream().map(SysRole::getName).collect(Collectors.toList()); + } + + @Override + public boolean checkDeptRepeat(SysRole vo) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("name", vo.getName()); + if (vo.getId()!=null) { + queryWrapper.last(" and id != " + vo.getId()); + } + List sysRoles = baseMapper.selectList(queryWrapper); + return sysRoles.size() > 0; + } +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SiteServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SiteServiceImpl.java new file mode 100644 index 0000000..6853ed4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SiteServiceImpl.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.service.impl; + +import com.huoran.iasf.entity.Site; +import com.huoran.iasf.mapper.SiteMapper; +import com.huoran.iasf.service.SiteService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 站点管理 服务实现类 + *

+ * + * @author cheney + * @since 2022-08-24 + */ +@Service +public class SiteServiceImpl extends ServiceImpl implements SiteService { + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SysColumnLongPageServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysColumnLongPageServiceImpl.java new file mode 100644 index 0000000..0ad9524 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysColumnLongPageServiceImpl.java @@ -0,0 +1,26 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysColumnLongPage; +import com.huoran.iasf.mapper.SysColumnLongPageMapper; +import com.huoran.iasf.service.SysColumnLongPageService; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Resource; + +/** + * @描述:长页栏目拓展表 服务类 + * @作者: Rong + * @日期: 2022-08-09 + */ +@Service +public class SysColumnLongPageServiceImpl extends ServiceImpl implements SysColumnLongPageService { + + @Autowired + private SysColumnLongPageMapper mapper; + +} + + + diff --git a/src/main/java/com/huoran/iasf/service/impl/SysColumnServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysColumnServiceImpl.java new file mode 100644 index 0000000..582682b --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysColumnServiceImpl.java @@ -0,0 +1,216 @@ +package com.huoran.iasf.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.common.utils.TreeStructureUtils; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.mapper.SysColumnMapper; +import com.huoran.iasf.mapper.SysContentMapper; +import com.huoran.iasf.service.SysColumnService; +import com.huoran.iasf.vo.FatherContentRespVO; +import com.huoran.iasf.vo.req.ColumnWeightReqVO; +import com.huoran.iasf.vo.req.LongPageColumnReqVO; +import com.huoran.iasf.vo.req.PaginationColumnReqVO; +import com.huoran.iasf.vo.resp.PageContentRespVO; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @描述: 服务类 + * @作者: Rong + * @日期: 2022-08-01 + */ +@Service +public class SysColumnServiceImpl extends ServiceImpl implements SysColumnService { + + @Autowired + private SysColumnMapper mapper; + + @Autowired + private SysContentMapper contentMapper; + + @Override + public boolean sameLevelJudgment(ColumnWeightReqVO column) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + + + queryWrapper.eq("column_name", column.getColumnName()); + + if (column.getId() != null) { + queryWrapper.eq("father_id", column.getId()); + } else { + queryWrapper.eq("father_id", 0); + } + + + queryWrapper.eq("site_id", column.getSiteId()); + queryWrapper.eq("deleted", 1); + SysColumn sysColumn = mapper.selectOne(queryWrapper); + if (sysColumn != null) { + if (column.getId() != null) { + //判断为编辑情况下,如果编辑的id与查询出来的一致不提示 + if (column.getId() == sysColumn.getId()) { + return true; + } + } + + return false; + } + return true; + } + + + @Override + public List listWithTree(PaginationColumnReqVO column) { + //查询所有栏目 + List columnList = baseMapper.filter(column); + /*// 创建树形结构(数据集合作为参数) + TreeBuild treeBuild = new TreeBuild(columnList); + // 原查询结果转换树形结构 + columnList = treeBuild.buildTree(); + // AjaxResult:个人封装返回的结果体 + return columnList;*/ + return forMethod(columnList); + + } + + /** + * 双重for循环方法转换成树形结构 + * + * @param treeList + * @return + */ + public static List forMethod(List treeList) { + List rootTree = new ArrayList<>(); + for (SysColumn tree : treeList) { + // 第一步 筛选出最顶级的父节点 + if (0 == tree.getFatherId()) { + rootTree.add(tree); + } + // SysColumn 筛选出该父节点下的所有子节点列表 + for (SysColumn node : treeList) { + if (node.getFatherId().equals(tree.getId())) { + if (CollectionUtils.isEmpty(tree.getChildren())) { + tree.setChildren(new ArrayList<>()); + } + tree.getChildren().add(node); + } + } + } + return rootTree; + } + + @Override + public List listWithTreeMenuVisible(PaginationColumnReqVO column) { + + if (column.getRole() == null) { + + } else if (column.getRole() != null || column.getRole().equals("admin") || ObjectUtil.isNotNull(column.isIsadmin()) || column.isIsadmin()) { + throw new IllegalArgumentException("参数名不能包含admin"); + } + //查询所有栏目 + List columnList = baseMapper.filterMenuVisible(column); + + if (column.getColumnName().equals("")) { + //用来保存父节点 + List rootColumn = new ArrayList<>(); + //用来保存子节点 + List childList = new ArrayList<>(); + //遍历所有栏目,将所有栏目的父栏目id为0的栏目放入父节点集合中 + for (SysColumn column1 : columnList) { + Integer parentId = column1.getFatherId(); + if (parentId == 0) { + rootColumn.add(column1); + } + } + for (SysColumn sysColumn : rootColumn) { + Integer theColumnId = sysColumn.getId(); + //调用工具类获取子节点 + childList = TreeStructureUtils.getChildren(theColumnId, columnList); + sysColumn.setChildren(childList); + } + + return rootColumn; + } + + return columnList; + + } + + @Override + public R longPageColumnList(LongPageColumnReqVO reqVO) { + Page page = new Page(reqVO.getPageNum(), reqVO.getPageSize()); + IPage pageList = baseMapper.longPageColumnList(page, reqVO); + pageList.getRecords().forEach(pageContentRespVO -> { + if (pageContentRespVO.getLevel() > 1) { + //判断该栏目层级为第一级时候不返回上级栏目 + List upperLevel = baseMapper.getParentInformationBasedOnChild(pageContentRespVO.getId()); + pageContentRespVO.setSuperiorColumn(upperLevel); + } + + }); + + + return R.success(pageList); + } + + @Override + public R getsTheSubColumn(Integer pid, String ids, Integer siteId) { + + List getsTheSubColumn = baseMapper.getsTheSubColumn(pid, ids, null, siteId); + return R.success(TreeStructureUtils.buildTree(getsTheSubColumn, pid)); + } + + @Override + public R getsSublevelColumnsUnderALevel(Integer parentId, String ids, Integer siteId) { + + List getsTheSubColumn = baseMapper.getsTheSubColumn(parentId, ids, null, siteId); + List buildTree = TreeStructureUtils.buildTree(getsTheSubColumn, parentId); + return R.success(buildTree); + } + + @Override + public Integer oneLevelChecksThemAll(Integer theChildId) { + Integer getPid = baseMapper.oneLevelChecksThemAll(theChildId); + return getPid; + } + + @Override + public R getSubColumn(Integer parentId, String ids, Integer isSort, Integer siteId) { + List getsTheSubColumn = baseMapper.getsTheSubColumn(parentId, ids, isSort, siteId); + return R.success(TreeStructureUtils.forMethod(getsTheSubColumn)); + } + + @Override + public R queryArticlesByColumnType(String ids, Integer id) { + + Integer count = 0; + for (String columnId : ids.split(",")) { + ++count; + } + + + List queryByColumnType = baseMapper.queryByColumnType(ids); + //为1表示该层级下以及它本身列表样式模板一直则查询全部的 + if (count > 1) { + if (queryByColumnType.size() == 1) { + return R.success(contentMapper.columnConditionsFilterArticles(ids)); + } + } + //表示该层级下的全部层级不一致只查本身 + return R.success(contentMapper.columnConditionsFilterArticles(id + "")); + } + + +} + + + diff --git a/src/main/java/com/huoran/iasf/service/impl/SysContentClassificationServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysContentClassificationServiceImpl.java new file mode 100644 index 0000000..ce7c599 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysContentClassificationServiceImpl.java @@ -0,0 +1,26 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysContentClassification; +import com.huoran.iasf.mapper.SysContentClassificationMapper; +import com.huoran.iasf.service.SysContentClassificationService; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Resource; + +/** + * @描述:文章所属分类 服务类 + * @作者: Rong + * @日期: 2022-11-08 + */ +@Service +public class SysContentClassificationServiceImpl extends ServiceImpl implements SysContentClassificationService { + +@Autowired +private SysContentClassificationMapper mapper; + +} + + + diff --git a/src/main/java/com/huoran/iasf/service/impl/SysContentFileServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysContentFileServiceImpl.java new file mode 100644 index 0000000..11bcbf4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysContentFileServiceImpl.java @@ -0,0 +1,31 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysContentFile; +import com.huoran.iasf.mapper.SysContentFileMapper; +import com.huoran.iasf.service.SysContentFileService; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @描述:文章附件管理表 服务类 + * @作者: Rong + * @日期: 2022-11-07 + */ +@Service +public class SysContentFileServiceImpl extends ServiceImpl implements SysContentFileService { + + @Autowired + private SysContentFileMapper mapper; + + @Override + public List getFileByContentId(Integer contentId) { + return baseMapper.getFileByContentId(contentId); + } +} + + + diff --git a/src/main/java/com/huoran/iasf/service/impl/SysContentLabelServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysContentLabelServiceImpl.java new file mode 100644 index 0000000..bbd4776 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysContentLabelServiceImpl.java @@ -0,0 +1,26 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysContentLabel; +import com.huoran.iasf.mapper.SysContentLabelMapper; +import com.huoran.iasf.service.SysContentLabelService; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Resource; + +/** + * @描述:文章主题标签 服务类 + * @作者: Rong + * @日期: 2022-11-08 + */ +@Service +public class SysContentLabelServiceImpl extends ServiceImpl implements SysContentLabelService { + +@Autowired +private SysContentLabelMapper mapper; + +} + + + diff --git a/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java new file mode 100644 index 0000000..a28e016 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java @@ -0,0 +1,298 @@ +package com.huoran.iasf.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysContent; +import com.huoran.iasf.entity.SysContentFile; +import com.huoran.iasf.mapper.SysContentFileMapper; +import com.huoran.iasf.mapper.SysContentMapper; +import com.huoran.iasf.service.SysContentService; +import com.huoran.iasf.vo.req.ArticleModifiedSortReq; +import com.huoran.iasf.vo.req.ContentHeavyTitleReqVO; +import com.huoran.iasf.vo.req.PageContentReqVO; +import com.huoran.iasf.vo.resp.PageContentRespVO; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @描述:文章管理 服务类 + * @作者: Rong + * @日期: 2022-08-05 + */ +@Service +public class SysContentServiceImpl extends ServiceImpl implements SysContentService { + + private final static Logger logger = LoggerFactory.getLogger(SysContentServiceImpl.class); + @Autowired + private SysContentMapper mapper; + + @Autowired + private StringRedisTemplate redisTemplate; + @Autowired + private SysContentFileMapper fileMapper; + + @Override + public boolean checkIfTheTitleIsRepeat(ContentHeavyTitleReqVO content) { + //只对已发布的标题判重 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("title", content.getTitle()); + queryWrapper.eq("is_release", Constant.ARTICLE_PUBLISHED); + queryWrapper.eq("site_id", content.getSiteId()); + SysContent sysContent = mapper.selectOne(queryWrapper); + if (sysContent != null) { + if (content.getId() != null) { + //判断为编辑情况下,如果编辑的id与查询出来的一致不提示 + if (content.getId().equals(content.getId())) { + return true; + } + } + + return false; + } + return true; + } + + @Override + public R articlePaginationList(PageContentReqVO reqVO) { + Page page = new Page(reqVO.getPageNum(), reqVO.getPageSize()); + IPage pageList = baseMapper.articlePaginationList(page, reqVO); + return R.success(pageList); + } + + @Override + public R newlyPublishedArticles(PageContentReqVO reqVO) { + if (reqVO.getRole() == null) { + + } else if (reqVO.getRole() != null || reqVO.getRole().equals("admin") || ObjectUtil.isNotNull(reqVO.isIsadmin()) || reqVO.isIsadmin()) { + throw new IllegalArgumentException("参数名不能包含admin"); + } + Page page = new Page(reqVO.getPageNum(), reqVO.getPageSize()); + IPage pageList = baseMapper.getPublishedArticles(page, reqVO); + + + for (PageContentRespVO vo : pageList.getRecords()) { + List fileList = fileMapper.getFileByContentId(vo.getId()); + vo.setFileList(fileList); + } + return R.success(pageList); + } + + @Override + public R publishedEnabledArticles() { + //查询已发布的、启用了的文章列表接 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("is_release", Constant.ARTICLE_PUBLISHED); + queryWrapper.eq("template_status", Constant.TEMPLATE_STATUS_ENABLED); + List sysContentList = mapper.selectList(queryWrapper); + return R.success(sysContentList); + + } + + @Override + public R getTheFullArticleByColumn(String ids) { + return R.success(mapper.useTheColumnToGetTagsForTheFullArticle(ids)); + } + + @Override + public Integer statisticsOfPageViews(Integer id) { + + String key = "preview:contentId:" + id; + //查看缓存是否有数据 + String returnValue = redisTemplate.opsForValue().get(key); + if (returnValue == null) { + returnValue = "0"; + } + returnValue = Integer.valueOf(returnValue) + 1 + ""; + //保存到缓存中 + redisTemplate.opsForValue().set(key, returnValue + ""); + + SysContent sysContent = new SysContent(); + sysContent.setId(id); + sysContent.setTotalBrowsing(Integer.valueOf(returnValue)); + mapper.updateById(sysContent); + + return Integer.valueOf(returnValue); + } + + @Override + public List hotContent(Integer siteId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + /* queryWrapper.eq("deleted", Constant.DATA_NOT_DELETED); + queryWrapper.eq("site_id", siteId); + queryWrapper.eq("is_release", Constant.ARTICLE_PUBLISHED); + queryWrapper.eq("is_disable", 0); + queryWrapper.last(" ORDER BY total_browsing desc LIMIT 0,5");*/ + + List contentList = baseMapper.hotContent(siteId); + return contentList; + } + + @Override + public R siteSearchArticles(PageContentReqVO reqVO) { + Page page = new Page(reqVO.getPageNum(), reqVO.getPageSize()); + IPage pageList = baseMapper.siteSearchArticles(page, reqVO); + return R.success(pageList); + } + + @Override + public R queryArticleColumnParent(Integer articleId) { + SysContent sysContent = baseMapper.selectById(articleId); + + return R.success(baseMapper.queryArticleColumnParent(sysContent.getColumnId())); + } + + /*@Override + public R modifiedSort(List reqList) { + for (ArticleModifiedSortReq req : reqList) { + SysContent content = new SysContent(); + content.setId(req.getArticleId()); + content.setSequence(req.getSequence()); + baseMapper.updateById(content); + } + return R.success(); + } + + @Override + public R modifiedSort(Integer sequenceNumber, Integer articleId) { + + // 占分布式锁,去redis占坑 + // 1. 分布式锁占坑 + Boolean lock = redisTemplate.opsForValue().setIfAbsent("articleSortLock", "value", 30, TimeUnit.SECONDS); + if (lock) { + //加锁成功... + if (sequenceNumber <= 0) { + redisTemplate.delete("articleSortLock"); //删除key,释放锁 + return R.fail("请输入正确的序号!"); + } + SysContent content = baseMapper.selectById(articleId); + //获取当前排序的序号 + Integer currentSerialNumber = content.getSequence(); + //获取当前文章所属栏目id + Integer columnId = content.getColumnId(); + + if (currentSerialNumber.equals(sequenceNumber)) { + redisTemplate.delete("articleSortLock"); //删除key,释放锁 + return R.success(); + } + //修改当前序号 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set("sequence", sequenceNumber); + updateWrapper.eq("id", articleId); + //做乐观锁处理 + updateWrapper.eq("sequence", currentSerialNumber); + int updateCount = baseMapper.update(new SysContent(), updateWrapper); + + UpdateWrapper updateWrapper1 = new UpdateWrapper<>(); + updateWrapper1.ne("id", articleId); + //currentSerialNumber 当前文章的序号 + //sequenceNumber 要更改的序号 + + *//** + * 就要判断排序是值改小还是改大 + * 大改小比如53改5那就加一个语句“大于等于5并且小于53” + * 如果是小改大比如3改50那就是“大于3并且小于等于50" + *//* + if (currentSerialNumber > sequenceNumber) { + //改大 gt > + updateWrapper1.setSql(" sequence = sequence + 1"); + updateWrapper1.last(" and sequence >= " + sequenceNumber + " and sequence < " + currentSerialNumber); + } else if (currentSerialNumber < sequenceNumber) { + //改小 + //le为<= +// updateWrapper1.le("sequence", sequenceNumber); + updateWrapper1.setSql(" sequence = sequence - 1"); + updateWrapper1.last(" and sequence > " + currentSerialNumber + " and sequence <= " + sequenceNumber); + //用于判断序号为本身就为1时候就不减了 +// updateWrapper1.ne("sequence", 1); + } + + updateWrapper1.eq("column_id", columnId); + updateWrapper1.eq("deleted", 1); + baseMapper.update(new SysContent(), updateWrapper1); + redisTemplate.delete("articleSortLock"); //删除key,释放锁 + return R.success(); + } else { + return R.fail("当前有用户操作排序,请稍后刷新重试!"); + } + + + }*/ + + /*@Override + public R modifiedSort(Integer newIndex, Integer articleId,Integer sort) { + if (newIndex <= 0) { + return R.fail("请输入正确的序号!"); + } + //获取当前排序的序号 + SysContent content = baseMapper.selectById(articleId); + //获取当前文章所属栏目id + Integer columnId = content.getColumnId(); + //查看当前升序情况下全部文章信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("column_id", columnId); + queryWrapper.eq("deleted", 1); + + if (sort==0){ + queryWrapper.orderByAsc("sequence"); + }else if (sort==1){ + queryWrapper.orderByDesc("sequence"); + } + + List contentList = baseMapper.selectList(queryWrapper); + //获取当前序号在list中的顺序 + int currentIndex = contentList.indexOf(content); + //获取当前排序的序号 + Integer currentSerialNumber = content.getSequence(); + if (currentIndex == -1) { + // 文章不存在,不做任何操作 + return R.success(); + } + //对于传过来的序号 处理用于匹配集合的下标 + if (currentSerialNumber > newIndex) { + newIndex--; + }else { + newIndex++; + } + + if (currentIndex == newIndex) { + // 新旧位置相同,不做任何操作 + return R.success(); + } + // 移除当前位置的文章 + contentList.remove(content); + if (newIndex >= contentList.size()) { + // 插入到末尾 + contentList.add(content); + } else { + // 插入到新位置 + contentList.add(newIndex, content); + } + for (int i = 0; i < contentList.size(); i++) { + SysContent article = contentList.get(i); + article.setSequence(i + 1); + baseMapper.updateById(article); + } + + + return R.success(); + }*/ + + +} + + + + diff --git a/src/main/java/com/huoran/iasf/service/impl/SysDictDetailServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysDictDetailServiceImpl.java new file mode 100644 index 0000000..463721c --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysDictDetailServiceImpl.java @@ -0,0 +1,52 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.entity.SysDictDetailEntity; +import com.huoran.iasf.entity.SysDictEntity; +import com.huoran.iasf.mapper.SysDictDetailMapper; +import com.huoran.iasf.mapper.SysDictMapper; +import com.huoran.iasf.service.SysDictDetailService; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; + +/** + * 数据字典 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service("sysDictDetailService") +public class SysDictDetailServiceImpl extends ServiceImpl implements SysDictDetailService { + @Resource + private SysDictDetailMapper sysDictDetailMapper; + @Resource + private SysDictMapper sysDictMapper; + + + @Override + public IPage listByPage(Page page, String dictId) { + + SysDictEntity sysDictEntity = sysDictMapper.selectById(dictId); + if (sysDictEntity == null) { + throw new BusinessException(BaseResponseCode.DICTIONARY_DATA_FAILED); + } + + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(SysDictDetailEntity::getDictId, dictId); + wrapper.orderByAsc(SysDictDetailEntity::getSort); + IPage result = sysDictDetailMapper.selectPage(page, wrapper); + if (!CollectionUtils.isEmpty(result.getRecords())) { + result.getRecords().parallelStream().forEach(entity -> entity.setDictName(sysDictEntity.getName())); + } + return result; + } +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/impl/SysDictServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysDictServiceImpl.java new file mode 100644 index 0000000..e3e20ed --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysDictServiceImpl.java @@ -0,0 +1,51 @@ +package com.huoran.iasf.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysDictDetailEntity; +import com.huoran.iasf.entity.SysDictEntity; +import com.huoran.iasf.mapper.SysDictDetailMapper; +import com.huoran.iasf.mapper.SysDictMapper; +import com.huoran.iasf.service.SysDictService; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 数据字典 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service("sysDictService") +public class SysDictServiceImpl extends ServiceImpl implements SysDictService { + + @Resource + private SysDictDetailMapper sysDictDetailMapper; + + /** + * 根据字典类型查询字典数据信息 + * + * @param name 字典名称 + * @return 参数键值 + **/ + public JSONArray getType(String name) { + if (StringUtils.isEmpty(name)) { + return new JSONArray(); + } + //根据名称获取字典 + SysDictEntity dict = this.getOne(Wrappers.lambdaQuery().eq(SysDictEntity::getName, name)); + if (dict == null || dict.getId() == null) { + return new JSONArray(); + } + //获取明细 + List list = sysDictDetailMapper.selectList(Wrappers.lambdaQuery().eq(SysDictDetailEntity::getDictId, dict.getId())); + return JSONArray.parseArray(JSON.toJSONString(list)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/impl/SysFilesServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysFilesServiceImpl.java new file mode 100644 index 0000000..4dc5b93 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysFilesServiceImpl.java @@ -0,0 +1,321 @@ +package com.huoran.iasf.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.config.FileUploadProperties; +import com.huoran.iasf.common.config.NonStaticResourceHttpRequestConfig; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.DateUtils; +import com.huoran.iasf.common.utils.R; +import com.huoran.iasf.entity.SysFilesEntity; +import com.huoran.iasf.mapper.SysFilesMapper; +import com.huoran.iasf.service.SysFilesService; +import com.huoran.iasf.vo.UEditorResultVO; +import com.huoran.iasf.vo.req.FileParameters; +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.regex.Pattern; + +/** + * 文件上传 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@EnableConfigurationProperties(FileUploadProperties.class) +@Service("sysFilesService") +public class SysFilesServiceImpl extends ServiceImpl implements SysFilesService { + + @Resource + private FileUploadProperties fileUploadProperties; + + @Autowired + private NonStaticResourceHttpRequestConfig nonStaticResourceHttpRequestConfig; + + @Override + public UEditorResultVO saveFile(MultipartFile file, FileParameters fileParameters) { + if (ObjectUtil.isEmpty(file) || file.getSize() <= 0) { + throw new BusinessException(BaseResponseCode.UPLOAD_EMPTY); + } + //存储文件夹 + String createTime = DateUtils.format(new Date(), DateUtils.DATEPATTERN); + String newPath = fileUploadProperties.getPath() + createTime + File.separator; + File uploadDirectory = new File(newPath); + if (uploadDirectory.exists()) { + if (!uploadDirectory.isDirectory()) { + uploadDirectory.delete(); + } + } else { + uploadDirectory.mkdir(); + } + try { + String fileName = file.getOriginalFilename(); + //获取文件大小 + int fileSize = (int) file.getSize(); + //获取文件的后缀名 + String suffixName = fileName.substring(fileName.lastIndexOf(".")+1); + //id与filename保持一直,删除文件 + String fileNameNew = UUID.randomUUID().toString().replace("-", "") + getFileType(fileName); + String newFilePathName = newPath + fileNameNew; + // String url = fileUploadProperties.getUrl() + "/" + createTime + "/" + fileNameNew; + //创建输出文件对象 + File outFile = new File(newFilePathName); + //拷贝文件到输出文件对象 + FileUtils.copyInputStreamToFile(file.getInputStream(), outFile); + //保存文件记录 + SysFilesEntity sysFilesEntity = new SysFilesEntity(); + sysFilesEntity.setFileName(fileName); + sysFilesEntity.setFilePath(newFilePathName); + sysFilesEntity.setFileSize(fileSize); + sysFilesEntity.setFormat(suffixName); + sysFilesEntity.setUploader(fileParameters.getUploader()); + sysFilesEntity.setQuote(fileParameters.getQuote()); + sysFilesEntity.setSite(fileParameters.getSite()); + sysFilesEntity.setQuoteType(fileParameters.getQuoteType()); + sysFilesEntity.setQuoteId(fileParameters.getQuoteId()); + sysFilesEntity.setType(fileCheck(suffixName)); + this.save(sysFilesEntity); + // String hostAddress = InetAddress.getLocalHost().getHostAddress(); +// String hostAddress = getLocalHostExactAddress().getHostAddress(); + // String url = fileUploadProperties.getUrl() + "/preview" + "/" + sysFilesEntity.getId(); + String url = fileUploadProperties.getIp() + fileUploadProperties.getUrl() + sysFilesEntity.getId(); + sysFilesEntity.setUrl(url); + this.updateById(sysFilesEntity); + + UEditorResultVO uEditorResult = new UEditorResultVO(); + uEditorResult.setState("SUCCESS"); + uEditorResult.setUrl(url); + uEditorResult.setId(sysFilesEntity.getId()); + uEditorResult.setTitle(fileNameNew); + uEditorResult.setOriginal(fileName); + return uEditorResult; + } catch (Exception e) { + throw new BusinessException(BaseResponseCode.UPLOAD_FAILED); + } + } + + public static InetAddress getLocalHostExactAddress() { + try { + InetAddress candidateAddress = null; + + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface iface = networkInterfaces.nextElement(); + // 该网卡接口下的ip会有多个,也需要一个个的遍历,找到自己所需要的 + for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) { + InetAddress inetAddr = inetAddrs.nextElement(); + // 排除loopback回环类型地址(不管是IPv4还是IPv6 只要是回环地址都会返回true) + if (!inetAddr.isLoopbackAddress()) { + if (inetAddr.isSiteLocalAddress()) { + // 如果是site-local地址,就是它了 就是我们要找的 + // ~~~~~~~~~~~~~绝大部分情况下都会在此处返回你的ip地址值~~~~~~~~~~~~~ + return inetAddr; + } + + // 若不是site-local地址 那就记录下该地址当作候选 + if (candidateAddress == null) { + candidateAddress = inetAddr; + } + + } + } + } + + // 如果出去loopback回环地之外无其它地址了,那就回退到原始方案吧 + return candidateAddress == null ? InetAddress.getLocalHost() : candidateAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 获取请求ip地址 + * @throws Exception Exception + */ + private String getRemoteIP() throws Exception { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String ip = ""; + if (request.getHeader("x-forwarded-for") == null) { + ip = request.getRemoteAddr(); + }else{ + ip = request.getHeader("x-forwarded-for"); + } + return ip; + } + + /** + * 校验文件类型的正则 + **/ + public static String fileCheck(String suffixName) { + String reg1 = "(mp4|flv|avi|mov|rm|rmvb|wmv|hevc)"; + Pattern pattern1 = Pattern.compile(reg1); + boolean flag1 = pattern1.matcher(suffixName.toLowerCase()).find(); + if (flag1){ + return "视频"; + } + String reg = "(jpg|png|tiff|webp|heif|gif|bmp)"; + Pattern pattern = Pattern.compile(reg); + boolean flag = pattern.matcher(suffixName.toLowerCase()).find(); + if (flag){ + return "图片"; + } + return "文件"; + } + + + @Override + public void preview(String id, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { + if (id != null) { + SysFilesEntity entity = this.getById(id); + String path = entity.getFilePath(); + res.setContentLength(entity.getFileSize()); + +// if (entity.getFormat().equals("mp4")){ + //保存视频磁盘路径 + Path filePath = Paths.get(path); + + //获取视频的类型,比如是MP4这样 + File file = new File(path); + String mimeType = Files.probeContentType(filePath); + if (StrUtil.isNotEmpty(mimeType)) { + //判断类型,根据不同的类型文件来处理对应的数据 + res.setContentType(mimeType); + res.addHeader("Content-Length", "" + file.length()); + } + //转换视频流部分 + req.setAttribute(NonStaticResourceHttpRequestConfig.ATTR_FILE, filePath); + nonStaticResourceHttpRequestConfig.handleRequest(req, res); +// }else { +// File file = new File(path); +// byte[] buffer = FileUtil.readBytes(path); +// if (file.exists()) { +// try { +// //设置contentType +// res.setContentType(MediaType.ALL_VALUE); +// res.setCharacterEncoding("UTF-8"); +// //获取outputStream +// ServletOutputStream outputStream = res.getOutputStream(); +// //输出 +// IoUtil.write(outputStream, true, buffer); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// } +// } + + } + } + + @Override + public void download(String id, HttpServletRequest req, HttpServletResponse res) { + if (id != null) { + SysFilesEntity entity = this.getById(id); + String path = entity.getFilePath(); + setDownloadContent(entity.getFileName(), req, res); + // 重要,需要设置此值,否则下载后打开文件会提示文件需要修复 + res.setContentLength(entity.getFileSize()); + File file = new File(path); + if (file.exists()) { + byte[] buffer = new byte[1024]; + //输出流 + OutputStream os; + try (FileInputStream fis = new FileInputStream(file); + BufferedInputStream bis = new BufferedInputStream(fis);) { + os = res.getOutputStream(); + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + i = bis.read(buffer); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + } + } + + /** + * 客户端下载文件上response header的设置。 + * + * @param fileName 文件名 + * @param request 请求 + * @param response 响应 + */ + private void setDownloadContent(String fileName, HttpServletRequest request, HttpServletResponse response) { + String agent = request.getHeader("User-Agent"); + try { + if (null != agent && agent.toUpperCase().indexOf("MSIE") > 0) { + fileName = URLEncoder.encode(fileName, "UTF-8"); + } else { + fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1"); + } + } catch (UnsupportedEncodingException e1) { + } + response.setContentType("application/x-msdownload;"); + response.setHeader("Content-Disposition", "attachment; filename=" + fileName); + } + + @Override + public void removeByIdsAndFiles(List ids) { + List list = this.listByIds(ids); + list.forEach(entity -> { + //如果之前的文件存在,删除 + File file = new File(entity.getFilePath()); + if (file.exists()) { + file.delete(); + } + }); + this.removeByIds(ids); + + } + + /** + * 获取文件后缀名 + * + * @param fileName 文件名 + * @return 后缀名 + */ + private String getFileType(String fileName) { + if (fileName != null && fileName.contains(".")) { + return fileName.substring(fileName.lastIndexOf(".")); + } + return ""; + } + + @Override + public R getPage(SysFilesEntity sysFiles) { + Page page = new Page<>(1, 10); + + IPage fileList = baseMapper.fileList(page, sysFiles); + return R.success(fileList); + } +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/impl/SysGeneratorServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysGeneratorServiceImpl.java new file mode 100644 index 0000000..83cc2f9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysGeneratorServiceImpl.java @@ -0,0 +1,69 @@ +/* +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huoran.iasf.common.utils.GenUtils; +import com.huoran.iasf.entity.SysGenerator; +import com.huoran.iasf.mapper.GeneratorMapper; +import com.huoran.iasf.service.ISysGeneratorService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipOutputStream; + +*/ +/** + * 代码生成 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +@Service +@Slf4j +public class SysGeneratorServiceImpl implements ISysGeneratorService { + private final GeneratorMapper generatorMapper; + + public SysGeneratorServiceImpl(GeneratorMapper generatorMapper) { + this.generatorMapper = generatorMapper; + } + + @Override + public IPage selectAllTables(Page page, SysGenerator vo) { + return generatorMapper.selectAllTables(page, vo); + } + + @Override + public byte[] generatorCode(String[] tableNames) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + + for (String tableName : tableNames) { + //查询表信息 + Map table = queryTable(tableName); + //查询列信息 + List> columns = queryColumns(tableName); + //生成代码 + GenUtils.generatorCode(table, columns, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + public Map queryTable(String tableName) { + return generatorMapper.queryTable(tableName); + } + + public List> queryColumns(String tableName) { + return generatorMapper.queryColumns(tableName); + } + + +} +*/ diff --git a/src/main/java/com/huoran/iasf/service/impl/SysJobLogServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysJobLogServiceImpl.java new file mode 100644 index 0000000..308fdb5 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysJobLogServiceImpl.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysJobLogEntity; +import com.huoran.iasf.mapper.SysJobLogMapper; +import com.huoran.iasf.service.SysJobLogService; +import org.springframework.stereotype.Service; + +/** + * 定时任务 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service("sysJobLogService") +public class SysJobLogServiceImpl extends ServiceImpl implements SysJobLogService { + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/service/impl/SysJobServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysJobServiceImpl.java new file mode 100644 index 0000000..594573a --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysJobServiceImpl.java @@ -0,0 +1,120 @@ +/* +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.job.utils.ScheduleUtils; +import com.huoran.iasf.common.utils.Constant; +import com.huoran.iasf.entity.SysJobEntity; +import com.huoran.iasf.mapper.SysJobMapper; +import com.huoran.iasf.service.SysJobService; +import org.quartz.CronTrigger; +import org.quartz.Scheduler; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.List; + +*/ +/** + * 定时任务 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + *//* + +@Service("sysJobService") +public class SysJobServiceImpl extends ServiceImpl implements SysJobService { + @Resource + private Scheduler scheduler; + @Resource + private SysJobMapper sysJobMapper; + + */ +/** + * 项目启动时,初始化定时器 + *//* + + @PostConstruct + public void init() { + List scheduleJobList = this.list(); + for (SysJobEntity scheduleJob : scheduleJobList) { + CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getId()); + //如果不存在,则创建 + if (cronTrigger == null) { + ScheduleUtils.createScheduleJob(scheduler, scheduleJob); + } else { + ScheduleUtils.updateScheduleJob(scheduler, scheduleJob); + } + } + } + + @Override + public void saveJob(SysJobEntity sysJob) { + sysJob.setStatus(Constant.SCHEDULER_STATUS_NORMAL); + this.save(sysJob); + + ScheduleUtils.createScheduleJob(scheduler, sysJob); + } + + @Override + public void updateJobById(SysJobEntity sysJob) { + SysJobEntity sysJobEntity = this.getById(sysJob.getId()); + if (sysJobEntity == null) { + throw new BusinessException("获取定时任务异常"); + } + sysJob.setStatus(sysJobEntity.getStatus()); + ScheduleUtils.updateScheduleJob(scheduler, sysJob); + + this.updateById(sysJob); + } + + @Override + public void delete(List ids) { + for (String jobId : ids) { + ScheduleUtils.deleteScheduleJob(scheduler, jobId); + } + sysJobMapper.deleteBatchIds(ids); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void run(List ids) { + for (String jobId : ids) { + ScheduleUtils.run(scheduler, this.getById(jobId)); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void pause(List ids) { + for (String jobId : ids) { + ScheduleUtils.pauseJob(scheduler, jobId); + } + + updateBatch(ids, Constant.SCHEDULER_STATUS_PAUSE); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void resume(List ids) { + for (String jobId : ids) { + ScheduleUtils.resumeJob(scheduler, jobId); + } + + updateBatch(ids, Constant.SCHEDULER_STATUS_NORMAL); + } + + @Override + public void updateBatch(List ids, int status) { + ids.parallelStream().forEach(id -> { + SysJobEntity sysJobEntity = new SysJobEntity(); + sysJobEntity.setId(id); + sysJobEntity.setStatus(status); + baseMapper.updateById(sysJobEntity); + }); + } +}*/ diff --git a/src/main/java/com/huoran/iasf/service/impl/SysNavigationStyleServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysNavigationStyleServiceImpl.java new file mode 100644 index 0000000..3b1e289 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysNavigationStyleServiceImpl.java @@ -0,0 +1,26 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysNavigationStyle; +import com.huoran.iasf.mapper.SysNavigationStyleMapper; +import com.huoran.iasf.service.SysNavigationStyleService; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Resource; + +/** + * @描述:导航样式配置 服务类 + * @作者: Rong + * @日期: 2022-09-01 + */ +@Service +public class SysNavigationStyleServiceImpl extends ServiceImpl implements SysNavigationStyleService { + + @Autowired + private SysNavigationStyleMapper mapper; + +} + + + diff --git a/src/main/java/com/huoran/iasf/service/impl/SysTemplateServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysTemplateServiceImpl.java new file mode 100644 index 0000000..9b7a50a --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysTemplateServiceImpl.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.service.impl; + +import com.huoran.iasf.entity.SysTemplate; +import com.huoran.iasf.mapper.SysTemplateMapper; +import com.huoran.iasf.service.SysTemplateService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 栏目模板 服务实现类 + *

+ * + * @author cheney + * @since 2022-11-11 + */ +@Service +public class SysTemplateServiceImpl extends ServiceImpl implements SysTemplateService { + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SysTemplateStyleConfigurationServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysTemplateStyleConfigurationServiceImpl.java new file mode 100644 index 0000000..d5e2de2 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysTemplateStyleConfigurationServiceImpl.java @@ -0,0 +1,29 @@ +package com.huoran.iasf.service.impl; + +import com.huoran.iasf.entity.SysTemplateStyle; +import com.huoran.iasf.entity.SysTemplateStyleConfiguration; +import com.huoran.iasf.mapper.SysTemplateStyleConfigurationMapper; +import com.huoran.iasf.service.SysTemplateStyleConfigurationService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 栏目样式、列表样式、详情样式配置表 服务实现类 + *

+ * + * @author cheney + * @since 2022-11-24 + */ +@Service +public class SysTemplateStyleConfigurationServiceImpl extends ServiceImpl implements SysTemplateStyleConfigurationService { + + + + @Override + public List getsTheStyleUnderTheTemplate(Integer templateId, Integer type) { + return baseMapper.getTheStyleUnderTheTemplate(templateId, type); + } +} diff --git a/src/main/java/com/huoran/iasf/service/impl/SysTemplateStyleServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysTemplateStyleServiceImpl.java new file mode 100644 index 0000000..8f2cc41 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/SysTemplateStyleServiceImpl.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.service.impl; + +import com.huoran.iasf.entity.SysTemplateStyle; +import com.huoran.iasf.mapper.SysTemplateStyleMapper; +import com.huoran.iasf.service.SysTemplateStyleService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author cheney + * @since 2022-11-11 + */ +@Service +public class SysTemplateStyleServiceImpl extends ServiceImpl implements SysTemplateStyleService { + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/UserDeptServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/UserDeptServiceImpl.java new file mode 100644 index 0000000..e303ea7 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/UserDeptServiceImpl.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.service.impl; + +import com.huoran.iasf.entity.UserDept; +import com.huoran.iasf.mapper.UserDeptMapper; +import com.huoran.iasf.service.UserDeptService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 用户员工部门表 服务实现类 + *

+ * + * @author cheney + * @since 2022-08-15 + */ +@Service +public class UserDeptServiceImpl extends ServiceImpl implements UserDeptService { + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/UserGroupServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/UserGroupServiceImpl.java new file mode 100644 index 0000000..493289d --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/UserGroupServiceImpl.java @@ -0,0 +1,20 @@ +package com.huoran.iasf.service.impl; + +import com.huoran.iasf.entity.UserGroup; +import com.huoran.iasf.mapper.UserGroupMapper; +import com.huoran.iasf.service.UserGroupService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 用户组 服务实现类 + *

+ * + * @author cheney + * @since 2022-08-10 + */ +@Service +public class UserGroupServiceImpl extends ServiceImpl implements UserGroupService { + +} diff --git a/src/main/java/com/huoran/iasf/service/impl/UserRoleServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/UserRoleServiceImpl.java new file mode 100644 index 0000000..dbbbd14 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/UserRoleServiceImpl.java @@ -0,0 +1,58 @@ +package com.huoran.iasf.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.huoran.iasf.entity.SysUserRole; +import com.huoran.iasf.mapper.SysUserRoleMapper; +import com.huoran.iasf.service.UserRoleService; +import com.huoran.iasf.vo.req.UserRoleOperationReqVO; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +/** + * 用户角色 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +public class UserRoleServiceImpl extends ServiceImpl implements UserRoleService { + @Resource + private SysUserRoleMapper sysUserRoleMapper; + + @Override + public List getRoleIdsByUserId(Integer userId) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().select(SysUserRole::getRoleId).eq(SysUserRole::getUserId, userId); + return sysUserRoleMapper.selectObjs(queryWrapper); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void addUserRoleInfo(UserRoleOperationReqVO vo) { + if (CollectionUtils.isEmpty(vo.getRoleIds())) { + return; + } + List list = new ArrayList<>(); + for (Integer roleId : vo.getRoleIds()) { + SysUserRole sysUserRole = new SysUserRole(); + sysUserRole.setUserId(vo.getUserId()); + sysUserRole.setRoleId(roleId); + list.add(sysUserRole); + } + sysUserRoleMapper.delete(Wrappers.lambdaQuery().eq(SysUserRole::getUserId, vo.getUserId())); + //批量插入 + this.saveBatch(list); + } + + @Override + public List getUserIdsByRoleId(Integer roleId) { + return sysUserRoleMapper.selectObjs(Wrappers.lambdaQuery().select(SysUserRole::getUserId).eq(SysUserRole::getRoleId, roleId)); + } +} diff --git a/src/main/java/com/huoran/iasf/service/impl/UserServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..c4d9bb4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/service/impl/UserServiceImpl.java @@ -0,0 +1,953 @@ +package com.huoran.iasf.service.impl; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Maps; +import com.huoran.iasf.common.exception.BusinessException; +import com.huoran.iasf.common.exception.code.BaseResponseCode; +import com.huoran.iasf.common.utils.*; +import com.huoran.iasf.entity.*; +import com.huoran.iasf.mapper.SysDeptMapper; +import com.huoran.iasf.mapper.SysUserMapper; +import com.huoran.iasf.mapper.UserDeptMapper; +import com.huoran.iasf.mapper.UserGroupMapper; +import com.huoran.iasf.service.*; +import com.huoran.iasf.vo.CheckVo; +import com.huoran.iasf.vo.ImportUserFailureVo; +import com.huoran.iasf.vo.UEditorResultVO; +import com.huoran.iasf.vo.req.*; +import com.huoran.iasf.vo.resp.LoginRespVO; +import com.huoran.iasf.vo.resp.UserListResp; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * 用户 服务类 + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Service +@Slf4j +public class UserServiceImpl extends ServiceImpl implements UserService { + + @Resource + private SysUserMapper sysUserMapper; + @Resource + private RoleService roleService; + @Resource + private PermissionService permissionService; + @Resource + private UserRoleService userRoleService; + @Resource + private UserDeptMapper userDeptMapper; + + @Resource + private SysDeptMapper sysDeptMapper; + + @Resource + private SysFilesService sysFilesService; + + @Resource + private HttpSessionService httpSessionService; + + @Resource + private RedisService redisService; + + @Resource + private UserGroupMapper userGroupMapper; + + @Resource + StringRedisTemplate stringRedisTemplate; + + @Value("${spring.redis.allowMultipleLogin}") + private Boolean allowMultipleLogin; + + @Override + public void register(SysUser sysUser) { + SysUser sysUserOne = sysUserMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, sysUser.getUsername())); + if (sysUserOne != null) { + throw new BusinessException(BaseResponseCode.USERNAME_EXISTS); + } + sysUser.setSalt(PasswordUtils.getSalt()); + String encode = PasswordUtils.encode(sysUser.getPassword(), sysUser.getSalt()); + sysUser.setPassword(encode); + sysUserMapper.insert(sysUser); + } + + @Override + public LoginRespVO login(SysUser vo) { + //验证码校验 + check(vo.getRandom(), vo.getCaptcha()); + SysUser sysUser = sysUserMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, vo.getUsername())); + if (null == sysUser) { + throw new BusinessException(BaseResponseCode.NOT_ACCOUNT); + } + if (sysUser.getStatus() == 2) { + throw new BusinessException(BaseResponseCode.USER_LOCK); + } + if (!PasswordUtils.matches(sysUser.getSalt(), vo.getPassword(), sysUser.getPassword())) { + throw new BusinessException(BaseResponseCode.PASSWORD_ERROR); + } + LoginRespVO respVO = new LoginRespVO(); + sysUser.setLastLoginTime(new Date()); + sysUserMapper.updateById(sysUser); + BeanUtils.copyProperties(sysUser, respVO); + + //是否删除之前token, 此处控制是否支持多登陆端; + // true:允许多处登陆; false:只能单处登陆,顶掉之前登陆 + if (!allowMultipleLogin) { + httpSessionService.abortUserById(sysUser.getId()); + } + List menus = permissionService.permissionList(sysUser.getId()); + + String token = httpSessionService.createTokenAndUser(sysUser, roleService.getRoleNames(sysUser.getId()), permissionService.getPermissionsByUserId(sysUser.getId())); + respVO.setAccessToken(token); + respVO.setPermissionList(menus); + respVO.setUsername(sysUser.getRealName()); + return respVO; + } + + /** + * 校验验证码 + * + * @param random 随机数 + * @param code 验证码 + * @return boolean + */ + public void check(String random, String code) { + String value = redisService.get(random); + //验证码已过期 + if (StringUtils.isEmpty(value)) { + throw new BusinessException(BaseResponseCode.VERIFICATION_CODE_EXPIRED); + } + //验证码错误 + if (!code.equals(value)) { + throw new BusinessException(BaseResponseCode.VERIFICATION_CODE_ERROR); + } + redisService.del(random); + } + + @Override + public void updateUserInfo(SysUser vo) { + + SysUser sysUser = sysUserMapper.selectById(vo.getId()); + if (null == sysUser) { + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } + + //如果用户名变更 + if (!sysUser.getUsername().equals(vo.getUsername())) { + SysUser sysUserOne = sysUserMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, vo.getUsername())); + if (sysUserOne != null) { + throw new BusinessException(BaseResponseCode.USERNAME_EXISTS); + } + } + + //如果用户名、密码、状态 变更,删除redis中用户绑定的角色跟权限 + if (!sysUser.getUsername().equals(vo.getUsername()) + || (!StringUtils.isEmpty(vo.getPassword()) + && !sysUser.getPassword().equals(PasswordUtils.encode(vo.getPassword(), sysUser.getSalt()))) + || !sysUser.getStatus().equals(vo.getStatus())) { + httpSessionService.abortUserById(vo.getId()); + } + + if (StringUtils.isNotEmpty(vo.getPassword())) { + String newPassword = PasswordUtils.encode(vo.getPassword(), sysUser.getSalt()); + vo.setPassword(newPassword); + } else { + vo.setPassword(null); + } + + if (StringUtils.isNotEmpty(vo.getEmail())) { + vo.setEmail(vo.getEmail()); + } + + if (StringUtils.isNotEmpty(vo.getPhone())) { + vo.setPhone(vo.getPhone()); + } + + //更新部门 + if (!CollectionUtils.isEmpty(vo.getDeptArchitectureId())) { + //删除所有部门 + userDeptMapper.delete(Wrappers.lambdaQuery().eq(UserDept::getUserId, vo.getId())); + + List deptArchitectureId = vo.getDeptArchitectureId(); + for (Integer deptId : deptArchitectureId) { + UserDept userDept = new UserDept(); + userDept.setUserId(vo.getId()); + userDept.setDeptId(deptId); + userDeptMapper.insert(userDept); + } + } + + + if (!CollectionUtils.isEmpty(vo.getRoleIds())) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysUserRole::getUserId, vo.getId()); + userRoleService.remove(queryWrapper); + + UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO(); + reqVO.setUserId(vo.getId()); + reqVO.setRoleIds(vo.getRoleIds()); + userRoleService.addUserRoleInfo(reqVO); + } + //刷新权限 + httpSessionService.refreshUerId(vo.getId()); + + vo.setUpdateId(httpSessionService.getCurrentUserId()); + sysUserMapper.updateById(vo); + + } + + @Override + public UserListResp detailInfo(String id) { + return baseMapper.detailInfo(id); + } + + @Override + public R resetPwd(String userId) { + SysUser sysUser = baseMapper.selectById(userId); + sysUser.setSalt(PasswordUtils.getSalt()); + String encode = PasswordUtils.encode("111aaa", sysUser.getSalt()); + sysUser.setPassword(encode); + int update = baseMapper.updateById(sysUser); + return update>0 ? R.success("重置成功") : R.fail("重置失败"); + } + + @Override + public R pageInfo(UserListReq userListReq) { + //查询未加入部门的员工,部门id一定清空 + if (userListReq.getType()==2){ + userListReq.setDeptArchitectureId(null); + } + + Page page = new Page(userListReq.getPageNum(), userListReq.getPageSize()); + IPage userList = baseMapper.userList(page, userListReq); + return R.success(userList); + } + + @Override + public void addUser(SysUser vo) { + + vo.setSalt(PasswordUtils.getSalt()); + String encode = PasswordUtils.encode("111aaa", vo.getSalt()); + vo.setPassword(encode); + vo.setStatus(1); + vo.setCreateWhere(1); + sysUserMapper.insert(vo); + + if (!CollectionUtils.isEmpty(vo.getDeptArchitectureId())) { + List deptArchitectureId = vo.getDeptArchitectureId(); + for (Integer deptId : deptArchitectureId) { + UserDept userDept = new UserDept(); + userDept.setUserId(vo.getId()); + userDept.setDeptId(deptId); + userDeptMapper.insert(userDept); + } + } + + //用户账号赋予角色 + if (!CollectionUtils.isEmpty(vo.getRoleIds())) { + UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO(); + reqVO.setUserId(vo.getId()); + reqVO.setRoleIds(vo.getRoleIds()); + userRoleService.addUserRoleInfo(reqVO); + } + } + + @Override + public void updatePwd(SysUser vo) { + + SysUser sysUser = sysUserMapper.selectById(vo.getId()); + if (sysUser == null) { + throw new BusinessException(BaseResponseCode.DATA_ERROR); + } + if (!PasswordUtils.matches(sysUser.getSalt(), vo.getOldPwd(), sysUser.getPassword())) { + throw new BusinessException(BaseResponseCode.OLD_PASSWORD_ERROR); + } + if (sysUser.getPassword().equals(PasswordUtils.encode(vo.getNewPwd(), sysUser.getSalt()))) { + throw new BusinessException(BaseResponseCode.CANNOT_SAME); + } + sysUser.setPassword(PasswordUtils.encode(vo.getNewPwd(), sysUser.getSalt())); + sysUserMapper.updateById(sysUser); + //退出用户 + httpSessionService.abortAllUserByToken(); + + } + + @Override + @Transactional + public Map importStaff(MultipartFile file) { + List impStaffReqList = ExcelImportHelper.readUser(file); + if (impStaffReqList.size() <= 0) { + //小于等于0为上传空模板的情况下 抛出异常 + throw new BusinessException(BaseResponseCode.EXCEL_FILE_FORMAT_ERROR); + } + int count = 0; + List failVo1 = new ArrayList(); + // 参数合法性校验,只能上传.xlsx后缀的文件 + if (org.apache.commons.lang3.StringUtils.isBlank(file.getOriginalFilename()) + || !file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")).equals(".xlsx")) { + throw new BusinessException(BaseResponseCode.EXCEL_FILE_INVALID); + } + int size = impStaffReqList.size(); + Map map = new HashMap<>(); + Long ii = 1L;//用于记录序列号 + Integer countNum = 0;//用于失败原因排序 eg:1、XXXXX 2、XXXXXXX + try { + Integer countSuccess = 0;//统计成功次数 + Integer countError = 0;//统计失败次数 + + List workNumberList = new ArrayList<>();//用来储存新增前用户在excel中输入的所有学号用于excel中的数据判重 + List accountList = new ArrayList<>();//用来储存新增前用户在excel中输入的所有账号用于excel中的数据判重 + for (int i = 0; i < impStaffReqList.size(); i++) { + boolean ret = true; + ++ii; + ExcelImpUserReq req = impStaffReqList.get(i); + + ImportUserFailureVo vo1 = new ImportUserFailureVo(); + + String errMsg = ""; + //去除Excel中的全角半角空格 + String realName = req.getRealName().replaceAll("\\u00A0", "").trim(); + String username = req.getUserName().replaceAll("\\u00A0", "").trim(); + String getRoleName = req.getRoleName().replaceAll("\\u00A0", "").trim(); + String jobNumber = req.getJobNumber().replaceAll("\\u00A0", "").trim(); + String dept = req.getDept().replaceAll("\\u00A0", "").trim(); + String getPhone = req.getPhone().replaceAll("\\u00A0", "").trim(); + String getEmail = req.getEmail().replaceAll("\\u00A0", "").trim(); + String groupName = req.getGroupName().replaceAll("\\u00A0", "").trim(); + + if (!workNumberList.contains(req.getJobNumber())) { + workNumberList.add(req.getJobNumber()); + } else { + //包含excel数据中存在相同学号 + ++countNum; + vo1.setJobNumber(jobNumber + " *必填项:(当前Excel数据中该工号已存在重复的!)"); + errMsg += countNum + " *必填项:(当前Excel数据中该工号号已存在重复的)"; + ret = false; + } + + if (!accountList.contains(req.getUserName())) { + accountList.add(req.getUserName()); + } else { + //包含excel数据中存在相同账号 + ++countNum; + vo1.setUserName(username + " *必填项:(当前Excel数据中该账号已存在重复的)"); + errMsg += countNum + " *必填项:(当前Excel数据中该账号已存在重复的)"; + ret = false; + } + + //账号id + int usernameId = 0; + + vo1.setIndex(ii); + //检验姓名 + if ("".equals(realName)) { + ++countNum; + vo1.setRealName(realName + " *必填项:(姓名不能为空) "); + errMsg += countNum + "必填项:(姓名不能为空)"; + ret = false; + } else { + vo1.setRealName(realName); + } + //检验账号 + if ("".equals(username)) { + ++countNum; + vo1.setUserName(username + " *必填项:(账号不能为空)"); + errMsg += countNum + " *必填项:(账号不能为空)"; + ret = false; + } else { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysUser::getUsername, username); + SysUser selectOne = baseMapper.selectOne(queryWrapper); + //账号存在,验证该账号相关信息 + if (ObjectUtil.isNotNull(selectOne)) { + if (username.equals(selectOne.getUsername())&&jobNumber.equals(selectOne.getJobNumber())){ + usernameId=selectOne.getId(); + }else { + ++countNum; + vo1.setUserName(username + " *必填项:(账号已有重复的)"); + errMsg += countNum + " *必填项:(账号已有重复的)"; + ret = false; + } + } else { + vo1.setUserName(username); + } + } + + List roleIds = new ArrayList<>(); + + //检验角色 + if ("".equals(getRoleName)) { + ++countNum; + vo1.setRoleName(getRoleName + " *必填项:(角色不能为空)"); + errMsg += countNum + " *必填项:(角色不能为空)"; + ret = false; + } else { + //分隔多个角色 + String[] roleNames = getRoleName.split("/"); + for (int r = 0; r < roleNames.length; r++) { + // 查询多个角色是否存在 + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysRole::getName, roleNames[r]); + SysRole role = roleService.getOne(queryWrapper); + if (role != null && !"超级管理员".equals(role.getName())) { + roleIds.add(role.getId()); + //存在 + vo1.setRoleName(getRoleName); + } else { + //不存在 + vo1.setRoleName(getRoleName + " *必填项:(请输入系统中存在的角色)"); + errMsg += countNum + " *必填项:(请输入系统中存在的角色)"; + ret = false; + } + } + + } + + //检验工号 + if ("".equals(jobNumber)) { + ++countNum; + vo1.setJobNumber(jobNumber + " *必填项:(工号不能为空)"); + errMsg += countNum + " *必填项:(工号不能为空)"; + ret = false; + } else { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysUser::getJobNumber, jobNumber); + SysUser selectOne = baseMapper.selectOne(queryWrapper); + if (ObjectUtil.isNotNull(selectOne)) { + ++countNum; + vo1.setJobNumber(jobNumber + " *必填项:(工号已经存在重复的)"); + errMsg += countNum + " *必填项:(工号已经存在重复的)"; + ret = false; + } else { + vo1.setJobNumber(jobNumber + ""); + } + } + + Integer groupId = 0; + //检验用户组 + if (!"".equals(groupName)) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(UserGroup::getGroupName, groupName); + UserGroup userGroup1 = userGroupMapper.selectOne(queryWrapper); + if (ObjectUtil.isNotNull(userGroup1)) { + groupId=userGroup1.getId(); + }else { + UserGroup userGroup = new UserGroup(); + userGroup.setGroupName(groupName); + int insert = userGroupMapper.insert(userGroup); + groupId=userGroup.getId(); + } + }else { + ++countNum; + vo1.setGroupName(groupName + " *必填项:(用户组不能为空)"); + errMsg += countNum + " *必填项:(用户组不能为空)"; + ret = false; + } + + if (!"".equals(getPhone)) { + //校验手机号格式 + if (!validPhoneNum("0", getPhone)) { + ++countNum; + vo1.setPhone(getPhone + " *请输入正确的手机号!"); + errMsg += countNum + " *请输入正确的手机号!"; + ret = false; + } else { + //用户账号存在,手机号邮箱则跳过效验 + if ("0".equals(usernameId)){ + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysUser::getPhone, getPhone); + SysUser selectOne = baseMapper.selectOne(queryWrapper); + if (ObjectUtil.isNotNull(selectOne)) { + ++countNum; + vo1.setPhone(getPhone + " *该手机号已被绑定!"); + errMsg += countNum + " *该手机号已被绑定!"; + ret = false; + } + vo1.setPhone(getPhone); + } + } + + } else { + vo1.setPhone(getPhone); + } + + if (!"".equals(getEmail)) { + //校验邮箱格式 + if (!isValidEmail(getEmail)) { + ++countNum; + vo1.setEmail(getEmail + "*请输入正确的邮箱格式!"); + errMsg += countNum + " *请输入正确的邮箱格式!"; + ret = false; + } else { + if (0==usernameId){ + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(SysUser::getEmail, getEmail); + SysUser selectOne = baseMapper.selectOne(queryWrapper); + if (ObjectUtil.isNotNull(selectOne)) { + ++countNum; + vo1.setEmail(getEmail + " *该邮箱已被绑定!"); + errMsg += countNum + " *该邮箱已被绑定!"; + ret = false; + } + vo1.setEmail(getEmail); + } + } + + } else { + vo1.setEmail(getEmail); + } + + ArrayList architectureIds = new ArrayList<>(); + //检验所在部门 + if ("".equals(dept)) { + ++countNum; + vo1.setDept(dept + " *必填项:(请输入正确的员工架构!)"); + errMsg += countNum + " *必填项:(请输入正确的员工架构!)"; + ret = false; + } else { + if (ret){ + //检验是否有多部门 + String[] multi = dept.split(","); + //多部门进行循环添加每个部门 + if (multi.length>1){ + for (int d = 0; d < multi.length; d++) { + HashMap hashMap = automaticAddArchitecture(multi[d], countNum, dept, vo1); + + Object countNum1 = hashMap.get("countNum"); + //存在错误数据 + if (countNum1!=null){ + countNum = (Integer) countNum1; + Object vo11 = hashMap.get("vo1"); + vo1 = (ImportUserFailureVo) vo11; + Object errMsg1 = hashMap.get("errMsg"); + errMsg = (String) errMsg1; + Object ret1 = hashMap.get("ret"); + ret = (boolean) ret1; + }else { + //保存架构id + Object architectureId = hashMap.get("architectureId"); + Integer id = 0; + if (architectureId!=null){ + id = (Integer)architectureId; + architectureIds.add(id); + } + } + } + + }else{ + HashMap hashMap = automaticAddArchitecture(dept, countNum, dept, vo1); + + Object countNum1 = hashMap.get("countNum"); + //存在错误数据 + if (countNum1!=null){ + countNum = (Integer) countNum1; + Object vo11 = hashMap.get("vo1"); + vo1 = (ImportUserFailureVo) vo11; + Object errMsg1 = hashMap.get("errMsg"); + errMsg = (String) errMsg1; + Object ret1 = hashMap.get("ret"); + ret = (boolean) ret1; + }else { + //保存架构id + Object architectureId = hashMap.get("architectureId"); + Integer id = 0; + if (architectureId!=null){ + id = (Integer) architectureId; + architectureIds.add(id); + } + } + } + } + } + + vo1.setFailureMsg(errMsg); + countNum = 0; + + failVo1.add(vo1); + + //ret判断 新增成功的插入到数据库 否则则不新增至数据库 + if (ret) { + //用户账号不存在 + if (0==usernameId){ + SysUser vo = new SysUser(); + vo.setSalt(PasswordUtils.getSalt()); + String encode = PasswordUtils.encode("111aaa", vo.getSalt()); + vo.setRealName(realName); + vo.setPhone(getPhone); + vo.setJobNumber(jobNumber); + vo.setEmail(getEmail); + vo.setUsername(username); + vo.setPassword(encode); + vo.setStatus(1); + vo.setCreateWhere(1); + if (groupId!=0){ + vo.setGroupId(groupId); + } + sysUserMapper.insert(vo); + + if (!CollectionUtils.isEmpty(architectureIds)) { + for (Integer deptId : architectureIds) { + UserDept userDept = new UserDept(); + userDept.setUserId(vo.getId()); + userDept.setDeptId(deptId); + userDeptMapper.insert(userDept); + } + } + + //用户账号赋予角色 + UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO(); + reqVO.setUserId(vo.getId()); + reqVO.setRoleIds(roleIds); + userRoleService.addUserRoleInfo(reqVO); + + }else { + //导入新部门、赋予新角色 + List userDepts = userDeptMapper. + selectList(new QueryWrapper().eq("user_id", usernameId)); + + ArrayList staffDepartmentIds = new ArrayList<>(); + for ( UserDept userDept : userDepts) { + staffDepartmentIds.add(userDept.getDeptId()); + } + for (Integer architectureId : architectureIds) { + if (!staffDepartmentIds.contains(architectureId)){ + UserDept userDept = new UserDept(); + userDept.setUserId(usernameId); + userDept.setDeptId(architectureId); + userDeptMapper.insert(userDept); + } + } + + //用户账号赋予角色 + UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO(); + reqVO.setUserId(usernameId); + reqVO.setRoleIds(roleIds); + userRoleService.addUserRoleInfo(reqVO); + + } + //countSuccess:统计累计成功次数 + countSuccess++; + } else { + //countError:累计失败次数 + countError++; + } + } + String exportCode = ""; + + // 有导入失败的数据,才会存入redis + if (countError > 0) { + //生成token + exportCode = "FAILURE_IMPORT" + UUID.randomUUID().toString().replace("-", ""); + ValueOperations ops = stringRedisTemplate.opsForValue(); + + List collect = failVo1.stream().filter(importStaffFailureVo -> { + return !importStaffFailureVo.getFailureMsg().equals(""); + }).collect(Collectors.toList()); + + String failureVOJson = JSON.toJSONString(collect); + ops.set(exportCode, failureVOJson, 30 * 60, TimeUnit.SECONDS); + } + map.put("exportCode", exportCode);//返回导出code + map.put("successNum", countSuccess + "");//本次新增成功数量 + map.put("failureNum", countError + "");//本次新增失败数量 + return map; + } catch (RuntimeException e) { + System.err.println(e.getMessage()); + throw new RuntimeException(); + } + } + + /** + * 组织架构判重,返回下一层级的父id + * + */ + public Integer checkArchitectureRepeat(String name ,Integer pid){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("name",name).eq("pid",pid); + SysDept sysDept = sysDeptMapper.selectOne(queryWrapper); + if (sysDept!=null){ + return sysDept.getId(); + } + return null; + } + + /** + * 根据导入部门自动添加组织架构 + */ + public HashMap automaticAddArchitecture(String architectureName,Integer countNum, + String dept,ImportUserFailureVo vo1){ + HashMap map = Maps.newHashMap(); + //获取部门层级 + String[] split = architectureName.split("/"); + if (split.length>6){ + map.put("countNum",++countNum); + map.put("vo1",vo1.setDept(dept + " 员工架构暂不支持第7层级")); + map.put("errMsg",countNum + " 员工架构暂不支持第7层级"); + map.put("ret",false); + return map; + } + // 检验输入的一级部门是否存在 + //查询一级部门信息 + QueryWrapper queryWrapper1 = new QueryWrapper<>(); + queryWrapper1.eq("name", split[0]); + SysDept sysDept = sysDeptMapper.selectOne(queryWrapper1); + if (sysDept == null) { + //为空表示不存在该部门,一级部门不存在,表示子级部门都能直接新增,达底端返回部门id + Integer pid = 0; + for (int j = 0; j < split.length; j++) { + SysDept sysDept1 = new SysDept(); + sysDept1.setName(split[j]); + sysDept1.setPid(pid); + int insert = sysDeptMapper.insert(sysDept1); + //添加成功后id赋值给下一层级父id + if (insert>0){ + pid = sysDept1.getId(); + } + //最后返回部门id + if (split.length-1==j){ + map.put("architectureId",pid); + } + } + } else { + Integer nextLevelPid = sysDept.getId(); + //存在一级部门,循环查询下一层级,存在则继续向下判断,否则进行新增,到达底端返回部门id + int pid = 1; + for (int j = 1; j < split.length; j++) { + Integer nextPid = checkArchitectureRepeat(split[j],nextLevelPid); + //都存在,最后一次循环返回部门id + if (split.length-1==j){ + map.put("architectureId",nextPid); + } + //层级已存在,进入下次循环 + if (nextPid!=null){ + nextLevelPid = nextPid; + continue; + } + //该层级不存在,进行新增 + SysDept sysDept1 = new SysDept(); + sysDept1.setName(split[j]); + sysDept1.setPid(nextLevelPid); + int insert = sysDeptMapper.insert(sysDept1); + //添加成功后id赋值给下一层级父id + if (insert>0){ + nextLevelPid = sysDept1.getId(); + } + //最后返回部门id + if (split.length-1==j){ + map.put("architectureId",nextLevelPid); + } + } + } + return map; + } + + /** + * @Description : 校验手机号 + * @Param checkType 校验类型:0校验手机号码,1校验座机号码,2两者都校验满足其一就可 + * @Param phoneNum + * @Author Rong---2021/10/18 + */ + public static boolean validPhoneNum(String checkType, String phoneNum) { + boolean flag = false; + Pattern p1 = null; + Pattern p2 = null; + Matcher m = null; + p1 = Pattern.compile("^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\\d{8})?$"); + p2 = Pattern.compile("^(0[0-9]{2,3}\\-)?([1-9][0-9]{6,7})$"); + if ("0".equals(checkType)) { + System.out.println(phoneNum.length()); + if (phoneNum.length() != 11) { + return false; + } else { + m = p1.matcher(phoneNum); + flag = m.matches(); + } + } else if ("1".equals(checkType)) { + if (phoneNum.length() < 11 || phoneNum.length() >= 16) { + return false; + } else { + m = p2.matcher(phoneNum); + flag = m.matches(); + } + } else if ("2".equals(checkType)) { + if (!((phoneNum.length() == 11 && p1.matcher(phoneNum).matches()) || (phoneNum.length() < 16 && p2.matcher(phoneNum).matches()))) { + return false; + } else { + flag = true; + } + } + return flag; + } + + /** + * @Description : 校验邮箱 + * @Param email + * @Author Rong---2021/10/18 + */ + public static boolean isValidEmail(String email) { + if ((email != null) && (!email.isEmpty())) { + return Pattern.matches("^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+([-.][A-Za-z0-9]+)*\\.\\w+([-.][A-Za-z0-9]+)*$", email); + } + return false; + } + + @Override + public void exportFailureRecord(HttpServletResponse response, String token) throws IOException { + if (StringUtils.isEmpty(token)) { + return; + } + ValueOperations ops = stringRedisTemplate.opsForValue(); + //获取数据 + String record = ops.get(token); + if (StringUtils.isEmpty(record)) { + return; + } + List parse = JSON.parseObject(record, new TypeReference>() { + }); + + parse.sort(Comparator.comparing(ImportUserFailureVo::getIndex)); + + // 告诉浏览器用什么软件可以打开此文件 + response.setHeader("content-Type", "application/vnd.ms-excel"); + // 下载文件的默认名称 + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("员工导入失败数据表", "UTF-8") + ".xls"); + //编码 + response.setCharacterEncoding("UTF-8"); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ImportUserFailureVo.class, parse); + ExportParams exportParams = new ExportParams(null, "delivery", ExcelType.XSSF); + exportParams.setStyle(ExcelStyleUtil.class); + workbook.write(response.getOutputStream()); + } + + @Override + public R sendCheckPhoneCode(CheckVo checkVo) { + boolean re = false; + boolean isSend; + String phoneOrEmail = ""; + + String msg = ""; + if (checkVo.getTypes().equals(1)) {//邮箱验证码 + phoneOrEmail = checkVo.getEmail(); + Integer count = baseMapper.selectCount(Wrappers.lambdaQuery().eq(SysUser::getEmail, checkVo.getEmail())); + if (count>0){ + msg = "邮箱已存在!"; + re = true; + } + } else {//手机验证码 + phoneOrEmail = checkVo.getPhone(); + Integer count = baseMapper.selectCount(Wrappers.lambdaQuery().eq(SysUser::getPhone, checkVo.getPhone())); + if (count>0){ + msg = "手机号已存在!"; + re = true; + } + } + + if (re) { + return R.fail(msg); + } + + //先从redis中查询该手机号的验证码是否过期,未过期直接返回发送成功,防重放 + //为了保证该手机号5分钟内在其他场景下内正常使用,存入的key需要与短信模板进行拼接 + String key = org.apache.commons.lang3.StringUtils.join(phoneOrEmail, SMSTemplate.AUTHENTICATION_CODE); + System.out.println(key); + String code = stringRedisTemplate.opsForValue().get(key); + if (!StringUtils.isEmpty(code)) { + return R.success("验证码已发,请勿重复操作!"); + } + code = RandomUtil.getSixBitRandom(); + Map param = new HashMap<>(); + param.put("code", code); + if (checkVo.getTypes().equals(1)) {//邮箱验证码 + isSend = EmailUtils.sendEmail(phoneOrEmail, code); + } else {//手机验证码 + isSend = SendSMSUtils.send(phoneOrEmail, SMSTemplate.AUTHENTICATION_CODE, param); + } + + if (isSend) { + stringRedisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES); + CheckVo checkVo1 = new CheckVo(); + checkVo1.setOpener(key); + return R.success(checkVo1); + } else { + return R.fail("短信发送失败,请稍后重试!"); + } + } + + @Override + public R updatePhoneOrEmail(UpdatePhoneOrEmailReq updatePhoneOrEmailReq) { + String phoneOrEmail = ""; + SysUser user = new SysUser(); + user.setId(updatePhoneOrEmailReq.getUserId()); + if (updatePhoneOrEmailReq.getTypes().equals(1)) {//邮箱验证码 + phoneOrEmail = updatePhoneOrEmailReq.getEmail(); + user.setEmail(updatePhoneOrEmailReq.getEmail()); + } else {//手机验证码 + phoneOrEmail = updatePhoneOrEmailReq.getPhone(); + user.setPhone(updatePhoneOrEmailReq.getPhone()); + } + //从redis中查询该手机号的验证码是否过期 + //为了保证该手机号5分钟内在其他场景下内正常使用,存入的key需要与短信模板进行拼接 + String key = org.apache.commons.lang3.StringUtils.join(phoneOrEmail, SMSTemplate.AUTHENTICATION_CODE); + System.out.println(key); + String code = stringRedisTemplate.opsForValue().get(key); + if (StringUtils.isEmpty(code)) { + return R.fail("验证码已过期!"); + } + if (code.equals(updatePhoneOrEmailReq.getCode())){ + //更新用户手机号 + baseMapper.updateById(user); + return R.success(); + } + return R.fail("验证码错误!"); + } + + @Override + public R updateUserAvatars(String userId, MultipartFile file) { + SysUser sysUser = baseMapper.selectById(userId); + + FileParameters fileParameters = new FileParameters(); + // fileParameters.setQuote("个人资料"); + // fileParameters.setSite("管理后台"); + fileParameters.setUploader(sysUser.getRealName()); + UEditorResultVO uEditorResultVO = sysFilesService.saveFile(file, fileParameters); + + sysUser.setUserAvatars(uEditorResultVO.getUrl()); + int update = baseMapper.updateById(sysUser); + + return update > 0 ? R.success(uEditorResultVO.getUrl()) : R.fail("更新失败"); + } +} diff --git a/src/main/java/com/huoran/iasf/util/TreeBuild.java b/src/main/java/com/huoran/iasf/util/TreeBuild.java new file mode 100644 index 0000000..df8c46e --- /dev/null +++ b/src/main/java/com/huoran/iasf/util/TreeBuild.java @@ -0,0 +1,84 @@ +package com.huoran.iasf.util; + +import com.huoran.iasf.entity.SysColumn; + +import java.util.ArrayList; +import java.util.List; + +/** + * BuildTree 构建树形结构 + */ +public class TreeBuild { + + // 保存参与构建树形的所有数据(通常数据库查询结果) + public List nodeList = new ArrayList<>(); + + /** + * 构造方法 + * + * @param nodeList 将数据集合赋值给nodeList,即所有数据作为所有节点。 + */ + public TreeBuild(List nodeList) { + this.nodeList = nodeList; + } + + /** + * 获取需构建的所有根节点(顶级节点) "0" + * + * @return 所有根节点List集合 + */ + public List getRootNode() { + // 保存所有根节点(所有根节点的数据) + List rootNodeList = new ArrayList<>(); + // treeNode:查询出的每一条数据(节点) + for (SysColumn treeNode : nodeList) { + // 判断当前节点是否为根节点,此处注意:若parentId类型是String,则要采用equals()方法判断。 + if (0 == treeNode.getFatherId()) { + // 是,添加 + rootNodeList.add(treeNode); + } + } + return rootNodeList; + } + + /** + * 根据每一个顶级节点(根节点)进行构建树形结构 + * + * @return 构建整棵树 + */ + public List buildTree() { + // treeNodes:保存一个顶级节点所构建出来的完整树形 + List treeNodes = new ArrayList(); + // getRootNode():获取所有的根节点 + for (SysColumn treeRootNode : getRootNode()) { + // 将顶级节点进行构建子树 + treeRootNode = buildChildTree(treeRootNode); + // 完成一个顶级节点所构建的树形,增加进来 + treeNodes.add(treeRootNode); + } + return treeNodes; + } + + /** + * 递归-----构建子树形结构 + * + * @param pNode 根节点(顶级节点) + * @return 整棵树 + */ + public SysColumn buildChildTree(SysColumn pNode) { + List childTree = new ArrayList(); + // nodeList:所有节点集合(所有数据) + for (SysColumn treeNode : nodeList) { + // 判断当前节点的父节点ID是否等于根节点的ID,即当前节点为其下的子节点 + if (treeNode.getFatherId().equals(pNode.getId())) { + // 再递归进行判断当前节点的情况,调用自身方法 + childTree.add(buildChildTree(treeNode)); + } + } + // for循环结束,即节点下没有任何节点,树形构建结束,设置树结果 + pNode.setChildren(childTree); + return pNode; + } + +} + diff --git a/src/main/java/com/huoran/iasf/vo/CheckVo.java b/src/main/java/com/huoran/iasf/vo/CheckVo.java new file mode 100644 index 0000000..fe2f9ac --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/CheckVo.java @@ -0,0 +1,37 @@ +package com.huoran.iasf.vo; + +/** + * @description + * @author: Mr.JK + * @create: 2021-07-05 18:25 + **/ + + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + + +@Data +@Accessors(chain = true) +@ApiModel(value = "CheckVo",description = "验证码校验参数") +public class CheckVo implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("用户的邮箱地址") + private String email; + + @ApiModelProperty("用户电话号码") + private String phone; + + @ApiModelProperty("验证码类型(1邮箱验证码,2手机验证码)") + private Integer types; + + @ApiModelProperty(value = "验证key") + private String opener; + +} diff --git a/src/main/java/com/huoran/iasf/vo/FatherContentRespVO.java b/src/main/java/com/huoran/iasf/vo/FatherContentRespVO.java new file mode 100644 index 0000000..fba2a00 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/FatherContentRespVO.java @@ -0,0 +1,39 @@ +package com.huoran.iasf.vo; + +import com.baomidou.mybatisplus.annotation.*; +import com.huoran.iasf.entity.SysColumn; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.Date; +import java.util.List; + +/** + * @描述:文章管理 + * @作者: Rong + * @日期: 2022-08-05 + */ +@Data +public class FatherContentRespVO { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "id") + private Integer id; + + @ApiModelProperty(value = "父id(第一级为0)") + private Integer fatherId; + + @ApiModelProperty(value = "排序") + private Integer sort; + + @ApiModelProperty(value = "层级((1-一级分类 2-二级分类 3-三级分类以此叠加))") + private Integer level; + + @ApiModelProperty(value = "栏目名称") + private String columnName; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/ImportUserFailureVo.java b/src/main/java/com/huoran/iasf/vo/ImportUserFailureVo.java new file mode 100644 index 0000000..380c2ef --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/ImportUserFailureVo.java @@ -0,0 +1,55 @@ +package com.huoran.iasf.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import com.huoran.iasf.common.utils.ExcelAttribute; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.ToString; +import lombok.experimental.Accessors; + +@Data +@ToString +@Accessors(chain = true) +@ExcelTarget("ImportStaffFailureVo") +public class ImportUserFailureVo { + + //第几行 + private Long index; + + @Excel(name = "姓名", orderNum = "1", isImportField = "realName", width = 30) + @ApiModelProperty(value = "姓名") + private String realName; + + @ApiModelProperty(value = "账号") + @Excel(name = "账号", orderNum = "2", isImportField = "userName", width = 30) + private String userName; + + @ApiModelProperty(value = "角色") + @Excel(name = "角色", orderNum = "3", isImportField = "roleName", width = 30) + private String roleName; + + @ApiModelProperty(value = "工号") + @Excel(name = "工号", orderNum = "4", isImportField = "jobNumber", width = 30) + private String jobNumber; + + @ApiModelProperty(value = "所在部门") + @Excel(name = "所在部门", orderNum = "5", isImportField = "dept", width = 30) + private String dept; + + @ApiModelProperty(value = "手机号码") + @Excel(name = "手机号码", orderNum = "6", isImportField = "phone", width = 20) + private String phone; + + @ApiModelProperty(value = "邮箱") + @Excel(name = "邮箱", orderNum = "7", isImportField = "email", width = 20) + private String email; + + @ApiModelProperty(value = "用户组") + @Excel(name = "用户组", orderNum = "8", isImportField = "groupName", width = 20) + private String groupName; + + @ExcelAttribute(sort = 9) + @Excel(name = "失败原因", orderNum = "9", isImportField = "failureMsg", width = 50) + private String failureMsg; +} diff --git a/src/main/java/com/huoran/iasf/vo/UEditorResultVO.java b/src/main/java/com/huoran/iasf/vo/UEditorResultVO.java new file mode 100644 index 0000000..c09efa6 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/UEditorResultVO.java @@ -0,0 +1,37 @@ +package com.huoran.iasf.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Author chen + * @DATE 2022/8/25 11:37 + * @Version 1.0 + */ +@Data +public class UEditorResultVO { + /** + * 上传结果 + */ + @ApiModelProperty(value = "上传结果") + private String state; + /** + * 原图名称 + */ + @ApiModelProperty(value = "原图名称") + private String original; + /** + * 保存名称 + */ + @ApiModelProperty(value = "保存名称") + private String title; + /** + * 文件路径 + */ + @ApiModelProperty(value = "文件路径") + private String url; + + @ApiModelProperty(value = "id") + private String id; +} + diff --git a/src/main/java/com/huoran/iasf/vo/req/ArticleModifiedSortReq.java b/src/main/java/com/huoran/iasf/vo/req/ArticleModifiedSortReq.java new file mode 100644 index 0000000..eb3d7c5 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/ArticleModifiedSortReq.java @@ -0,0 +1,16 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +public class ArticleModifiedSortReq { + @ApiModelProperty(value = "顺序(排序号)") + private Integer sequence; + + @ApiModelProperty(value = "文章id") + private Integer articleId; + + +} diff --git a/src/main/java/com/huoran/iasf/vo/req/ColumnWeightReqVO.java b/src/main/java/com/huoran/iasf/vo/req/ColumnWeightReqVO.java new file mode 100644 index 0000000..100b5dd --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/ColumnWeightReqVO.java @@ -0,0 +1,43 @@ +package com.huoran.iasf.vo.req; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @描述:栏目基础信息 + * @作者: Rong + * @日期: 2022-08-03 + */ +@Data +@ApiModel(value = "栏目判重") +public class ColumnWeightReqVO { + + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "id") + private Integer id; + + /*@ApiModelProperty(value = "层级((1-一级分类 2-二级分类 3-三级分类以此叠加))") + @NotNull(message = "层级不能为空") + private Integer level;*/ + + + @ApiModelProperty(value = "父id") + private Integer fatherId; + + + @ApiModelProperty(value = "栏目名称") + @NotNull(message = "栏目名称不能为空") + private String columnName; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; + + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/req/ContentHeavyTitleReqVO.java b/src/main/java/com/huoran/iasf/vo/req/ContentHeavyTitleReqVO.java new file mode 100644 index 0000000..b3f4c62 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/ContentHeavyTitleReqVO.java @@ -0,0 +1,32 @@ +package com.huoran.iasf.vo.req; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @描述:文章管理 + * @作者: Rong + * @日期: 2022-08-05 + */ +@Data +@ApiModel(value = "文章标题判重") +public class ContentHeavyTitleReqVO { + + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键(编辑时需要传)",required = false) + private Integer id; + + @ApiModelProperty(value = "标题(全库判重)",required = true) + @NotNull(message = "标题不能为空") + private String title; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/req/ContentReq.java b/src/main/java/com/huoran/iasf/vo/req/ContentReq.java new file mode 100644 index 0000000..9a04703 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/ContentReq.java @@ -0,0 +1,24 @@ +package com.huoran.iasf.vo.req; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + + +@Data +public class ContentReq{ + @ApiModelProperty(value = "栏目ids") + private List columnIds; + + @ApiModelProperty(value = "当前页数", name = "pageNum", example = "1", required = true) + private Integer pageNum; + @ApiModelProperty(value = "当前页需要显示的数量", name = "pageSize", example = "10", required = true) + private Integer pageSize; + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/req/ExcelImpUserReq.java b/src/main/java/com/huoran/iasf/vo/req/ExcelImpUserReq.java new file mode 100644 index 0000000..9511862 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/ExcelImpUserReq.java @@ -0,0 +1,45 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Author chen + * @DATE 2022/8/15 17:20 + * @Version 1.0 + */ +@Data +@ApiModel(value = "批量导入用户数据") +public class ExcelImpUserReq { + + @ApiModelProperty(value = "姓名") + @NotNull(message = "姓名不能为空!") + private String realName; + + @NotNull(message = "账号不能为空!") + @ApiModelProperty(value = "账号") + private String userName; + + @ApiModelProperty(value = "角色") + @NotNull(message = "角色不能为空!") + private String roleName; + + @ApiModelProperty(value = "工号") + @NotNull(message = "工号不能为空!") + private String jobNumber; + + @ApiModelProperty(value = "所在部门") + private String dept; + + @ApiModelProperty(value = "手机号码") + private String phone; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "用户组") + private String groupName; +} diff --git a/src/main/java/com/huoran/iasf/vo/req/FileParameters.java b/src/main/java/com/huoran/iasf/vo/req/FileParameters.java new file mode 100644 index 0000000..29d3044 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/FileParameters.java @@ -0,0 +1,35 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Author chen + * @DATE 2022/8/8 11:15 + * @Version 1.0 + */ +@Data +public class FileParameters { + + @ApiModelProperty(value = "站点来源",example = "粒子研究院中文站点") + private String site; + + @ApiModelProperty(value = "上传人",example = "管理员") + private String uploader; + + @ApiModelProperty(value = "引用地方",example = "某某文章") + private String quote; + + @ApiModelProperty(value = "文件id") + private String id; + + @ApiModelProperty(value = "引用文章id") + private Integer quoteId; + + @ApiModelProperty(value = "是否发布(默认0未发布,1已发布)") + private Integer isRelease; + + @ApiModelProperty(value = "0为文章,1为栏目") + private Integer quoteType; + +} diff --git a/src/main/java/com/huoran/iasf/vo/req/LongPageColumnReqVO.java b/src/main/java/com/huoran/iasf/vo/req/LongPageColumnReqVO.java new file mode 100644 index 0000000..c6ec635 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/LongPageColumnReqVO.java @@ -0,0 +1,38 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @描述:文章管理 + * @作者: Rong + * @日期: 2022-08-05 + */ +@Data +public class LongPageColumnReqVO extends PageReqVO { + + + @ApiModelProperty(value = "模板名称") + private String templateName; + + + @ApiModelProperty(value = "栏目名称") + private String programName; + + + @ApiModelProperty(value = "栏目类型id",hidden = true) + private Integer columnTypeId; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; + + public Integer getColumnTypeId() { + return 3; + } + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/req/PageContentReqVO.java b/src/main/java/com/huoran/iasf/vo/req/PageContentReqVO.java new file mode 100644 index 0000000..2ccf1b9 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/PageContentReqVO.java @@ -0,0 +1,118 @@ +package com.huoran.iasf.vo.req; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @描述:文章管理 + * @作者: Rong + * @日期: 2022-08-05 + */ +@Data +public class PageContentReqVO extends PageReqVO { + + + @ApiModelProperty(value = "栏目id") + private List columnIds; + + @ApiModelProperty(value = "标题") + private String title; + + @ApiModelProperty(value = "创建人") + private String founder; + + @ApiModelProperty(value = "编辑人") + private String editor; + + @ApiModelProperty(value = "栏目") + private String column; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; + + @ApiModelProperty(value = "标签id(逗号隔开)") + private String lableId; + + + @ApiModelProperty(value = "分类id") + private Integer classificationId; + + + @ApiModelProperty(value = "标签名称") + private List labelName; + + + @ApiModelProperty(value = "召开类型(1.即将召开 2.已经召开)") + private Integer convokeType; + + private String role; + + private boolean isadmin; + + //多余参数处理,参数值不能出现admin,否则返回400 + private Map extraParams = new HashMap<>(); + @JsonAnySetter + public void setExtraParam(String name, String value) { + // 在这里可以对额外参数进行验证或处理 + if (name.contains("admin")||value.contains("admin")) { + throw new IllegalArgumentException("参数名不能包含admin"); + } + this.extraParams.put(name, value); + } + + @JsonAnyGetter + public Map getExtraParams() { + return extraParams; + } + + @ApiModelProperty(value = "修改时间排序(0默认倒序 1升序)") + private Integer modifiedTimeSort; + + @ApiModelProperty(value = "发布时间排序(0默认倒序 1升序)") + private Integer publicationTimeSort; + + + @ApiModelProperty(value = "置顶排序(0默认升序 1倒序)") + private Integer topSort; + + @ApiModelProperty(value = "是否禁用(0默认,0启用 1禁用)") + private Integer isDisable; + + @ApiModelProperty(value = "专利类别id") + private Integer patentClassId; + + @ApiModelProperty(value = "申请时间") + private String applicationDate; + + @ApiModelProperty(value = "专利查询关键词") + private String patentQueryKeyWord; + + @ApiModelProperty(value = "专著查询关键词") + private String monographQueryKeyWord; + + @ApiModelProperty(value = "论文查询关键词") + private String paperQueryKeyWord; + + @ApiModelProperty(value = "出版日期") + private String publicationTime; + + + @ApiModelProperty(value = "发表年度/出版年度") + private String publicationYear; + + + @ApiModelProperty(value = "出版开始时间") + private String publicationStartTime; + + @ApiModelProperty(value = "出版结束时间") + private String endOfPublicationTime; + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/req/PageReqVO.java b/src/main/java/com/huoran/iasf/vo/req/PageReqVO.java new file mode 100644 index 0000000..360e8ab --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/PageReqVO.java @@ -0,0 +1,29 @@ +package com.huoran.iasf.vo.req; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ProjectName: huorantech + * @Package: com.huoran.occupationlab.entity.req + * @ClassName: PageReq + * @Description: 分页 + * @Author: Maureen.Rong + * @CreateDate: 2021/8/12 15:10 + * @UpdateDate: 2021/8/12 15:10 + * @Version: 1.0 + */ +@Data +public class PageReqVO { + + @ApiModelProperty(value = "当前页数", name = "pageNum", example = "1", required = true) + private Integer pageNum; + @ApiModelProperty(value = "当前页需要显示的数量", name = "pageSize", example = "10", required = true) + private Integer pageSize; + + +} diff --git a/src/main/java/com/huoran/iasf/vo/req/PaginationColumnReqVO.java b/src/main/java/com/huoran/iasf/vo/req/PaginationColumnReqVO.java new file mode 100644 index 0000000..6844d0b --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/PaginationColumnReqVO.java @@ -0,0 +1,44 @@ +package com.huoran.iasf.vo.req; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.HashMap; +import java.util.Map; + +/** + * @ProjectName: huorantech + * @Package: com.huoran.occupationlab.entity.req + * @ClassName: PageReq + * @Description: 分页 + * @Author: Maureen.Rong + * @CreateDate: 2021/8/12 15:10 + * @UpdateDate: 2021/8/12 15:10 + * @Version: 1.0 + */ +@Data +public class PaginationColumnReqVO extends PageReqVO { + + @ApiModelProperty(value = "栏目名称") + private String columnName; + + @ApiModelProperty(value = "栏目类型") + private Integer typeId; + + @ApiModelProperty(value = "栏目模板") + private Integer templateId; + + @ApiModelProperty(value = "站点id") + @NotNull(message = "站点id不能为空!") + private Integer siteId; + + @ApiModelProperty(value = "判断是否为排序接口调用(1为排序接口调用 0我栏目管理列表调用)") + private Integer isSort; + + private String role; + + private boolean isadmin; + +} diff --git a/src/main/java/com/huoran/iasf/vo/req/RolePermissionOperationReqVO.java b/src/main/java/com/huoran/iasf/vo/req/RolePermissionOperationReqVO.java new file mode 100644 index 0000000..7453e9b --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/RolePermissionOperationReqVO.java @@ -0,0 +1,25 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * RolePermissionOperationReqVO + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class RolePermissionOperationReqVO { + @ApiModelProperty(value = "角色id") + @NotBlank(message = "角色id不能为空") + private Integer roleId; + @ApiModelProperty(value = "菜单权限集合") + @NotEmpty(message = "菜单权限集合不能为空") + private List permissionIds; +} diff --git a/src/main/java/com/huoran/iasf/vo/req/SortByColumnReqVO.java b/src/main/java/com/huoran/iasf/vo/req/SortByColumnReqVO.java new file mode 100644 index 0000000..4835014 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/SortByColumnReqVO.java @@ -0,0 +1,35 @@ +package com.huoran.iasf.vo.req; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @描述:栏目基础信息 + * @作者: Rong + * @日期: 2022-08-03 + */ +@Data +@ApiModel(value = "栏目基础信息") +@TableName("sys_column") +public class SortByColumnReqVO { + + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "id") + private Integer id; + + @ApiModelProperty(value = "父id") + private Integer fatherId; + + @ApiModelProperty(value = "排序") + private Integer sort; + + @ApiModelProperty(value = "层级((1-一级分类 2-二级分类 3-三级分类以此叠加))") + private Integer level; + + + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/req/SysColumnLongRedisVO.java b/src/main/java/com/huoran/iasf/vo/req/SysColumnLongRedisVO.java new file mode 100644 index 0000000..5449877 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/SysColumnLongRedisVO.java @@ -0,0 +1,31 @@ +package com.huoran.iasf.vo.req; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; + +/** + * @描述:长页栏目拓展表 + * @作者: Rong + * @日期: 2022-08-09 + */ +@Data +public class SysColumnLongRedisVO { + + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "栏目id") + private Integer columnId; + + + @ApiModelProperty(value = "预览储存的整个页面的json") + private String json; + + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/req/UpdatePhoneOrEmailReq.java b/src/main/java/com/huoran/iasf/vo/req/UpdatePhoneOrEmailReq.java new file mode 100644 index 0000000..240f762 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/UpdatePhoneOrEmailReq.java @@ -0,0 +1,30 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Author chen + * @DATE 2022/8/29 15:31 + * @Version 1.0 + */ +@Data +public class UpdatePhoneOrEmailReq { + @ApiModelProperty("用户id") + private Integer userId; + + @ApiModelProperty("用户的邮箱地址") + private String email; + + @ApiModelProperty("用户电话号码") + private String phone; + + @ApiModelProperty("验证码类型(1邮箱验证码,2手机验证码)") + private Integer types; + + @ApiModelProperty("用户输入的验证码") + private String code; + + @ApiModelProperty(value = "验证key") + private String opener; +} diff --git a/src/main/java/com/huoran/iasf/vo/req/UserListReq.java b/src/main/java/com/huoran/iasf/vo/req/UserListReq.java new file mode 100644 index 0000000..c7e78f3 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/UserListReq.java @@ -0,0 +1,28 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Author chen + * @DATE 2022/8/15 15:27 + * @Version 1.0 + */ +@Data +public class UserListReq { + + @ApiModelProperty(value = "类型:必填一个(1.所有员工 2.未加入部门的员工)", required = true, example = "1") + private Integer type; + + @ApiModelProperty(value = "搜索关键词", example = "1") + private String keyWord; + + @ApiModelProperty(value = "员工部门主键ID", example = "2") + private String deptArchitectureId; + + @ApiModelProperty(value = "当前页数", name = "pageNum", example = "1", required = true) + private Integer pageNum; + + @ApiModelProperty(value = "当前页需要显示的数量", name = "pageSize", example = "10", required = true) + private Integer pageSize; +} diff --git a/src/main/java/com/huoran/iasf/vo/req/UserRoleOperationReqVO.java b/src/main/java/com/huoran/iasf/vo/req/UserRoleOperationReqVO.java new file mode 100644 index 0000000..06c2446 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/req/UserRoleOperationReqVO.java @@ -0,0 +1,27 @@ +package com.huoran.iasf.vo.req; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * UserRoleOperationReqVO + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class UserRoleOperationReqVO { + + @ApiModelProperty(value = "用户id") + @NotBlank(message = "用户id不能为空") + private Integer userId; + + @ApiModelProperty(value = "角色id集合") + @NotEmpty(message = "角色id集合不能为空") + private List roleIds; +} diff --git a/src/main/java/com/huoran/iasf/vo/resp/DeptRespNodeVO.java b/src/main/java/com/huoran/iasf/vo/resp/DeptRespNodeVO.java new file mode 100644 index 0000000..b9bc516 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/DeptRespNodeVO.java @@ -0,0 +1,53 @@ +package com.huoran.iasf.vo.resp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * DeptRespNodeVO + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class DeptRespNodeVO { + @ApiModelProperty(value = "组织id") + private Integer id; + + @ApiModelProperty(value = "组织编码") + private String deptNo; + + @ApiModelProperty(value = "部门名称") + private String name; + + // @ApiModelProperty(value = "组织名称") + // private String label; + + @ApiModelProperty(value = "组织父级id") + private String pid; + + @ApiModelProperty(value = "组织状态") + private Integer status; + + @ApiModelProperty(value = "组织关系id") + private String relationCode; + +/* @ApiModelProperty(value = "是否展开 默认不展开(false)") + private boolean spread = true; + + @ApiModelProperty(value = "是否选中") + private boolean checked = false; + + private boolean disabled = false;*/ + + @ApiModelProperty(value = "子集") + private List children; + + // public String getLabel() { + // return title; + // } + +} diff --git a/src/main/java/com/huoran/iasf/vo/resp/HomeRespVO.java b/src/main/java/com/huoran/iasf/vo/resp/HomeRespVO.java new file mode 100644 index 0000000..4ea5342 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/HomeRespVO.java @@ -0,0 +1,22 @@ +package com.huoran.iasf.vo.resp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * HomeRespVO + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class HomeRespVO { + @ApiModelProperty(value = "用户信息") + private UserInfoRespVO userInfo; + @ApiModelProperty(value = "目录菜单") + private List menus; + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/resp/LoginRespVO.java b/src/main/java/com/huoran/iasf/vo/resp/LoginRespVO.java new file mode 100644 index 0000000..6f3fc69 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/LoginRespVO.java @@ -0,0 +1,30 @@ +package com.huoran.iasf.vo.resp; + +import com.huoran.iasf.entity.SysPermission; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * LoginRespVO + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class LoginRespVO { + @ApiModelProperty(value = "token") + private String accessToken; + @ApiModelProperty(value = "用户名") + private String username; + @ApiModelProperty(value = "用户id") + private Integer id; + @ApiModelProperty(value = "电话") + private String phone; + @ApiModelProperty(value = "用户头像路径") + private String userAvatars; + @ApiModelProperty(value = "用户所拥有的菜单权限") + private List permissionList; +} diff --git a/src/main/java/com/huoran/iasf/vo/resp/PageContentRespVO.java b/src/main/java/com/huoran/iasf/vo/resp/PageContentRespVO.java new file mode 100644 index 0000000..e6067d4 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/PageContentRespVO.java @@ -0,0 +1,253 @@ +package com.huoran.iasf.vo.resp; + +import com.baomidou.mybatisplus.annotation.*; +import com.huoran.iasf.entity.SysColumn; +import com.huoran.iasf.entity.SysContentFile; +import com.huoran.iasf.vo.FatherContentRespVO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @描述:文章管理 + * @作者: Rong + * @日期: 2022-08-05 + */ +@Data +public class PageContentRespVO { + + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键") + private Integer id; + + @ApiModelProperty(value = "标题") + private String title; + + @ApiModelProperty(value = "所属栏目") + private String columnName; + + @ApiModelProperty(value = "所属栏目") + private Integer columnId; + + @ApiModelProperty(value = "标题图") + private String titleImg; + + @ApiModelProperty(value = "来源") + private String source; + + @ApiModelProperty(value = "发布时间") + private String releaseTime; + + @ApiModelProperty(value = "摘要") + private String summary; + + @ApiModelProperty(value = "banner图") + private String bannerImg; + + @ApiModelProperty(value = "文章模板(前端自定义)") + private Integer articleTemplate; + + @ApiModelProperty(value = "正文") + private String mainBody; + + @ApiModelProperty(value = "作者") + private String author; + + @ApiModelProperty(value = "是否发布(0:草稿 1:已发布)") + private Integer isRelease; + + @ApiModelProperty(value = "栏目类型(由前端自己设定)") + private Integer typeId; + + + @ApiModelProperty(value = "创建人") + private String founderName; + + @ApiModelProperty(value = "编辑人") + private String editorName; + + @ApiModelProperty(value = "文件") + private String file; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "文章总浏览量") + private Integer totalBrowsing; + + @ApiModelProperty(value = "父id(第一级为0)") + private Integer fatherId; + + @ApiModelProperty(value = "层级((1-一级分类 2-二级分类 3-三级分类以此叠加))") + private Integer level; + + + @ApiModelProperty(value = "上级栏目") + private List superiorColumn; + + @ApiModelProperty(value = "是否禁用(0默认,0启用 1禁用)") + private Integer isDisable; + + + @ApiModelProperty(value = "标签名称") + private String labelName; + + @ApiModelProperty(value = "分类名称(没有显示暂无)") + private String classificationName; + + + @ApiModelProperty(value = "创建人id") + private Integer founderId; + + @ApiModelProperty(value = "编辑人id") + private Integer editorId; + + + @ApiModelProperty(value = "是否在新窗口打开(0:否 1:是)") + private Integer isOpen; + + @ApiModelProperty(value = "是否删除(1未删除;0已删除)") + @TableLogic + private Integer deleted; + + @ApiModelProperty(value = "站点id") + private Integer siteId; + + @ApiModelProperty(value = "模板状态(0禁用;1启用)") + private Integer templateStatus; + + + @ApiModelProperty(value = "链接类型") + private Integer connectionType; + + @ApiModelProperty(value = "链接地址") + private String linkAddress; + + @ApiModelProperty(value = "站点选择(连接类型为其它站点连接时储存)") + private Integer siteSelection; + + @ApiModelProperty(value = "编辑人") + private String edit; + + @ApiModelProperty(value = "审核人") + private String audit; + + @ApiModelProperty(value = "活动开始时间") + private String activityStartTime; + + @ApiModelProperty(value = "活动结束时间") + private String activityEndTime; + + @ApiModelProperty(value = "演讲系列") + private String lectureSeries; + + @ApiModelProperty(value = "线上地点") + private String onlineLocation; + + @ApiModelProperty(value = "线下地点") + private String offlineLocation; + + @ApiModelProperty(value = "主讲人") + private String keynoteSpeaker; + + @ApiModelProperty(value = "活动简介") + private String eventProfile; + + @ApiModelProperty(value = "出版年份") + private String publicationYear; + + @ApiModelProperty(value = "出版类型(前端自定义)") + private Integer publicationTypeId; + + @ApiModelProperty(value = "DOI") + private String doi; + + @ApiModelProperty(value = "引用") + private String quote; + + @ApiModelProperty(value = "主题标签(sys_content_label表外键) 可多选逗号隔开") + private String lableId; + + @ApiModelProperty(value = "所属分类(sys_content_classification表外键)") + private Integer classificationId; + + + @ApiModelProperty(value = "样式id(用于前端区分是会议还是文章跳转界面)") + private Integer listStyleId; + + /*@ApiModelProperty(value = "顺序(排序号)") + private Integer sequence;*/ + + @ApiModelProperty(value = "是否置顶(默认为0 不置顶 1为置顶)") + private Integer isTop; + + + @ApiModelProperty(value = "专利类别id") + private Integer patentClassId; + + @ApiModelProperty(value = "申请时间") + private String applicationDate; + + @ApiModelProperty(value = "授权日期") + private String dateOfAuthorization; + + @ApiModelProperty(value = "发明人") + private String inventor; + + @ApiModelProperty(value = "专利名称") + private String patentName; + + @ApiModelProperty(value = "申请号") + private String applicationNumber; + + @ApiModelProperty(value = "出版社") + private String publishingHouse; + + @ApiModelProperty(value = "著名著作") + private String famousWorks; + + @ApiModelProperty(value = "编写人员") + private String writersAndEditors; + + @ApiModelProperty(value = "刊物名称") + private String periodicalName; + + @ApiModelProperty(value = "卷") + private String reel; + + @ApiModelProperty(value = "文献号") + private String documentNumber; + + @ApiModelProperty(value = "文章关键字") + private String articleKeyWord; + + + @ApiModelProperty(value = "出版日期") + private String publicationTime; + + + @ApiModelProperty(value = "岗位") + private String post; + + @ApiModelProperty(value = "专业") + private String major; + + @ApiModelProperty(value = "爱好") + private String hobby; + + + @ApiModelProperty(value = "荣誉") + private String honor; + + @ApiModelProperty(value = "文章附件") + @TableField(exist = false) + List fileList; +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/resp/PermissionRespNode.java b/src/main/java/com/huoran/iasf/vo/resp/PermissionRespNode.java new file mode 100644 index 0000000..acb72a1 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/PermissionRespNode.java @@ -0,0 +1,49 @@ +package com.huoran.iasf.vo.resp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * PermissionRespNode + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class PermissionRespNode { + @ApiModelProperty(value = "id") + private Integer id; + + @ApiModelProperty(value = "菜单权限名称") + private String name; + + @ApiModelProperty(value = "菜单权限标识,shiro 适配restful") + private String perms; + + @ApiModelProperty(value = "接口地址") + private String url; + +/* @ApiModelProperty(value = "icon") + private String icon;*/ + + // private String target; + + @ApiModelProperty(value = "父级id") + private String pid; + + // @ApiModelProperty(value = "父级名称") + // private String pidName; + +/* @ApiModelProperty(value = "菜单权限类型(1:目录;2:菜单;3:按钮)") + private Integer type;*/ + +/* @ApiModelProperty(value = "排序码") + private Integer orderNum;*/ + + private List children; + + +} diff --git a/src/main/java/com/huoran/iasf/vo/resp/SortColumnRespVO.java b/src/main/java/com/huoran/iasf/vo/resp/SortColumnRespVO.java new file mode 100644 index 0000000..01e88c2 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/SortColumnRespVO.java @@ -0,0 +1,37 @@ +package com.huoran.iasf.vo.resp; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * @描述:栏目基础信息 + * @作者: Rong + * @日期: 2022-08-03 + */ +@Data +public class SortColumnRespVO { + + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "id") + private Integer id; + + @ApiModelProperty(value = "父id(第一级为0)") + private Integer fatherId; + + @ApiModelProperty(value = "排序") + private Integer sort; + + @ApiModelProperty(value = "层级((1-一级分类 2-二级分类 3-三级分类以此叠加))") + private Integer level; + + + +} \ No newline at end of file diff --git a/src/main/java/com/huoran/iasf/vo/resp/UserInfoRespVO.java b/src/main/java/com/huoran/iasf/vo/resp/UserInfoRespVO.java new file mode 100644 index 0000000..fa4cef8 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/UserInfoRespVO.java @@ -0,0 +1,30 @@ +package com.huoran.iasf.vo.resp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * UserInfoRespVO + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class UserInfoRespVO { + @ApiModelProperty(value = "用户id") + private String id; + @ApiModelProperty(value = "账号") + private String username; + @ApiModelProperty(value = "手机号") + private String phone; + @ApiModelProperty(value = "昵称") + private String nickName; + @ApiModelProperty(value = "真实姓名") + private String realName; + @ApiModelProperty(value = "所属机构id") + private String deptId; + @ApiModelProperty(value = "所属机构名称") + private String deptName; + +} diff --git a/src/main/java/com/huoran/iasf/vo/resp/UserListResp.java b/src/main/java/com/huoran/iasf/vo/resp/UserListResp.java new file mode 100644 index 0000000..7ed6784 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/UserListResp.java @@ -0,0 +1,71 @@ +package com.huoran.iasf.vo.resp; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Author chen + * @DATE 2022/8/15 15:34 + * @Version 1.0 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "UserListResp", description = "用户列表") +public class UserListResp { + + @ApiModelProperty(value = "组织架构ID") + private String deptArchitectureId; + + @ApiModelProperty(value = "组织架构名称(部门名称)") + private String deptArchitectureName; + + @ApiModelProperty(value = "用户组id") + private String groupId; + + @ApiModelProperty(value = "性别(1.男 2.女)") + private Integer sex; + + @ApiModelProperty(value = "用户组名称") + private String groupName; + + @ApiModelProperty(value = "职工姓名") + private String realName; + + @ApiModelProperty(value = "账户状态(1.正常 0.锁定 )") + private Integer status; + + @ApiModelProperty(value = "工号") + private String jobNumber; + + @ApiModelProperty(value = "电话") + private String phone; + + @ApiModelProperty(value = "邮箱") + private String email; + + //用于列表逗号隔开展示 + @ApiModelProperty(value = "角色") + private String roleName; + + @ApiModelProperty(value = "角色id") + private String roleId; + + @ApiModelProperty(value = "账号") + private String username; + + @ApiModelProperty(value = "用户id") + private String id; + + @ApiModelProperty(value = "创建时间") + private String createTime; + + @ApiModelProperty(value = "最后登陆时间") + private String lastLoginTime; + + @ApiModelProperty(value = "用户头像路径") + private String userAvatars; +} diff --git a/src/main/java/com/huoran/iasf/vo/resp/UserOwnRoleRespVO.java b/src/main/java/com/huoran/iasf/vo/resp/UserOwnRoleRespVO.java new file mode 100644 index 0000000..d8a7880 --- /dev/null +++ b/src/main/java/com/huoran/iasf/vo/resp/UserOwnRoleRespVO.java @@ -0,0 +1,22 @@ +package com.huoran.iasf.vo.resp; + +import com.huoran.iasf.entity.SysRole; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * UserOwnRoleRespVO + * + * @author cheney + * @version V1.0 + * @date 2022年7月28日 + */ +@Data +public class UserOwnRoleRespVO { + @ApiModelProperty("所有角色集合") + private List allRole; + @ApiModelProperty(value = "用户所拥有角色集合") + private List ownRoles; +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..b8729b2 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,49 @@ +# 开发环境配置 +spring: + datasource: + dynamic: + primary: master #设置默认的数据源或者数据源组,默认值即为master + datasource: + master: + username: root + password: 123456 +# password: iasf#2022 +# password: HuoRan@2021 + driver-class-name: com.mysql.cj.jdbc.Driver +# url: jdbc:mysql://127.0.0.1:3306/iasf?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2b8 + url: jdbc:mysql://192.168.31.136:3306/iasf?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2b8 +# url: jdbc:mysql://139.9.47.170:3306/iasf?serverTimezone=GMT%2B8 + cache: + type: redis + redis: + host: 127.0.0.1 # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: # Redis服务器连接密码(默认为空) + jedis: + pool: + max-active: 8 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 8 # 连接池中的最大空闲连接 + min-idle: 0 # 连接池中的最小空闲连接 + timeout: 3000ms # 连接超时时间(毫秒) + +singleServerConfig: + address: "redis://127.0.0.1:6379" + password: + +file: + #文件上传目录 绝对路径 末尾请加 / windows + path: C:/files/ + #文件预览url +# url: /iasf/sysFiles/preview/ +# ip: http://10.10.11.7 + + #本地开启 + url: :10000/iasf/sysFiles/preview/ + ip: http://192.168.31.136 + + #本次需更新 + #模板数据 + #数据库文章表活动开始以及结束时间类型改为字符串 + diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..349b649 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,39 @@ +# 生产环境配置 +spring: + datasource: + dynamic: + primary: master #设置默认的数据源或者数据源组,默认值即为master + datasource: + master: + username: root + password: HuoRan@2021 + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://139.9.47.170:3306/iasf?serverTimezone=GMT%2B8 + cache: + type: redis + redis: + host: 127.0.0.1 # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: HuoRan@2021 # Redis服务器连接密码(默认为空) + jedis: + pool: + max-active: 8 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 8 # 连接池中的最大空闲连接 + min-idle: 0 # 连接池中的最小空闲连接 + timeout: 3000ms # 连接超时时间(毫秒) + +singleServerConfig: + address: "redis://127.0.0.1:6379" + password: HuoRan@2021 + +file: + #文件上传目录 绝对路径 末尾请加 / linux + path: /usr/local/huoran/huorantech_website/files/ + #文件预览url + url: /iasf/sysFiles/preview/ + ip: https://huorantech.com + +knife4j: + production: true #生成环境禁用查看文档 \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000..c2d41ef --- /dev/null +++ b/src/main/resources/application-test.yml @@ -0,0 +1,30 @@ +# 开发环境配置 +spring: + datasource: + dynamic: + primary: master #设置默认的数据源或者数据源组,默认值即为master + datasource: + master: + username: root + password: HuoRan@2021 + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://139.9.47.170:3306/iasf?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2b8 + redis: + host: localhost # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: # Redis服务器连接密码(默认为空) + jedis: + pool: + max-active: 8 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 8 # 连接池中的最大空闲连接 + min-idle: 0 # 连接池中的最小空闲连接 + timeout: 3000ms # 连接超时时间(毫秒 + +file: + #文件上传目录 绝对路径 末尾请加 / + path: D:/files/ #windows + #path: /data/files/ #linux + #文件预览、下载的url, 末尾请勿加 / + url: :10000/iasf/sysFiles/preview/ diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..e3f24ae --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,45 @@ +# 端口 +server: + port: 10000 + servlet: + context-path: /iasf + +spring: + profiles: + active: dev + mvc: + throw-exception-if-no-handler-found: true + resources: + add-mappings: false + application: + name: iasf + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + # 文件大小限制 + servlet: + multipart: + max-file-size: 1024MB + max-request-size: 1024MB + # redis token信息 + redis: + key: + prefix: + userToken: "user:token:" + passwordError: "user:password:error:" + permissionRefresh: "user:token:permissionRefresh:" + expire: + userToken: 86400 # 1天 7*24*3600 + passwordError: 360000 # 一个小时 + permissionRefresh: 86400 # 1天 7*24*3600 + allowMultipleLogin: true # 允许多处登陆 + +mybatis-plus: + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + mapper-locations: classpath*:com/huoran/iasf/mapper/xml/*.xml + global-config: + db-config: + logic-delete-value: 0 + logic-not-delete-value: 1 + logic-delete-field: deleted diff --git a/src/main/resources/generator.properties b/src/main/resources/generator.properties new file mode 100644 index 0000000..949614a --- /dev/null +++ b/src/main/resources/generator.properties @@ -0,0 +1,61 @@ +#\u4EE3\u7801\u751F\u6210\u5668\uFF0C\u914D\u7F6E\u4FE1\u606F + +mainPath=com.huoran +#\u5305\u540D +package=com.huoran.iasf +#\u4F5C\u8005 +author=cheney +#Email +email=*****@mail.com +#\u8868\u524D\u7F00 +tablePrefix= + +#\u7C7B\u578B\u8F6C\u6362\uFF0C\u914D\u7F6E\u4FE1\u606F +tinyint=Integer +smallint=Integer +mediumint=Integer +int=Integer +integer=Integer +bigint=Long +float=Float +double=Double +decimal=BigDecimal +bit=Boolean + +char=String +varchar=String +tinytext=String +text=String +mediumtext=String +longtext=String + +date=Date +datetime=Date +timestamp=Date + +NUMBER=Integer +INT=Integer +INTEGER=Integer +BINARY_INTEGER=Integer +LONG=String +FLOAT=Float +BINARY_FLOAT=Float +DOUBLE=Double +BINARY_DOUBLE=Double +DECIMAL=BigDecimal +CHAR=String +VARCHAR=String +VARCHAR2=String +NVARCHAR=String +NVARCHAR2=String +CLOB=String +BLOB=String +DATE=Date +DATETIME=Date +TIMESTAMP=Date +TIMESTAMP(6)=Date + +int8=Long +int4=Integer +int2=Integer +numeric=BigDecimal \ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..55ec7dc --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + + ${LOG_PATH}/${LOG_FILE} + + ${FILE_LOG_PATTERN} + + + ${LOG_PATH}/${LOG_HISTORY} + 30 + + + + + + + + 0 + 500 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/company/project/CodeGenerator.java b/src/test/java/com/company/project/CodeGenerator.java new file mode 100644 index 0000000..b738510 --- /dev/null +++ b/src/test/java/com/company/project/CodeGenerator.java @@ -0,0 +1,80 @@ +package com.company.project; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.config.DataSourceConfig; +import com.baomidou.mybatisplus.generator.config.GlobalConfig; +import com.baomidou.mybatisplus.generator.config.PackageConfig; +import com.baomidou.mybatisplus.generator.config.StrategyConfig; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import org.junit.Test; + +/** + * @Author chen + * @DATE 2021/8/10 15:42 + * @Version 1.0 + */ +public class CodeGenerator { + + @Test + public void run() { + + // 1、创建代码生成器 + AutoGenerator mpg = new AutoGenerator(); + + // 2、全局配置 + GlobalConfig gc = new GlobalConfig(); + String projectPath = System.getProperty("user.dir"); + gc.setOutputDir(projectPath + "/src/main/java"); + + gc.setAuthor("cheney");//设置作者 + gc.setOpen(false); //生成后是否打开资源管理器 + gc.setFileOverride(false); //重新生成时文件是否覆盖 + gc.setServiceName("%sService"); //去掉Service接口的首字母I + gc.setIdType(IdType.AUTO); //主键策略 + gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型 + gc.setSwagger2(true);//开启Swagger2模式 + + mpg.setGlobalConfig(gc); + + // 3、数据源配置 + DataSourceConfig dsc = new DataSourceConfig(); + dsc.setUrl("jdbc:mysql://192.168.31.136:3306/iasf?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2b8"); + dsc.setDriverName("com.mysql.cj.jdbc.Driver"); + dsc.setUsername("root"); + dsc.setPassword("123456"); + dsc.setDbType(DbType.MYSQL); + mpg.setDataSource(dsc); + + // 4、包配置 + PackageConfig pc = new PackageConfig(); + pc.setParent("com.huoran.iasf"); + //pc.setModuleName("occupationlab"); //模块名 + pc.setController("controller"); + pc.setEntity("entity"); + pc.setService("service"); + pc.setServiceImpl("service.impl"); + pc.setMapper("mapper"); + mpg.setPackageInfo(pc); + + // 5、策略配置 + StrategyConfig strategy = new StrategyConfig(); + strategy.setInclude("sys_template_style_configuration"); + strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略 +// strategy.setTablePrefix("sys_"); //生成实体时去掉表前缀 + + strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略 + strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作 + + strategy.setRestControllerStyle(true); //restful api风格控制器 + strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符 + + mpg.setStrategy(strategy); + + + // 6、执行 + mpg.execute(); + } +} diff --git a/src/test/java/com/company/project/CompanyFrameApplicationTests.java b/src/test/java/com/company/project/CompanyFrameApplicationTests.java new file mode 100644 index 0000000..c6d9afd --- /dev/null +++ b/src/test/java/com/company/project/CompanyFrameApplicationTests.java @@ -0,0 +1,16 @@ +package com.huoran.iasf; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CompanyFrameApplicationTests { + + @Test + public void contextLoads() { + } + +}