Compare commits

...

110 Commits

Author SHA1 Message Date
cheney 5220f92b0a 去除缓存 3 months ago
cheney 0ffff16f2d 图片缓存去除 4 months ago
cheney 5d18cd233f xss修改、栏目文章缓存添加 4 months ago
cheney b4637b9fe1 依赖提交 6 months ago
cheney 11dc060ead 中文解码问题处理 6 months ago
cheney 42f8eb491b 中文解码问题处理 7 months ago
cheney 7ffa1b4e1f 问题处理 8 months ago
cheney a0353a8567 个人资料接口分开 9 months ago
cheney 1d7e279bf7 搜索加密 9 months ago
cheney 1ad54fa4ca 忽略文件提交 9 months ago
cheney ee5bcc0143 中文转义,为空处理 9 months ago
cheney 302a1d999a 中文转义 9 months ago
cheney f80f84a13b target目录删除 9 months ago
cheney b4a0a1c252 等保测试修改 9 months ago
cheney 2ef382c180 网关添加 9 months ago
rong.liu 5e78724405 增加接口文章可查询全部父级栏目 11 months ago
rong.liu 9be8912160 增加接口文章可查询全部父级栏目 11 months ago
rong.liu cf290c52c5 热点内容增加去除禁用的数据,只展示启用 1 year ago
rong.liu c75bae7dfa 站点最新发布的文章增加返回上传的文件 1 year ago
cheney aaae4c9b6c 或然官网域名提交 1 year ago
cheney 4992c36aed 生产环境配置,访问文件ip配置 1 year ago
rong.liu a34138190d 接口放行 1 year ago
rong.liu 78bee48c55 6.20提交 1 year ago
rong.liu 9159c0f50c commit 2 years ago
rong.liu b8695d2281 增加详情判断 2 years ago
rong.liu 93091ff316 更改正式配置文件 2 years ago
rong.liu 5af13ce83d 栏目标题判重完善 2 years ago
rong.liu 22cc03c9cd 置顶排序完善 2 years ago
rong.liu 56e5644480 排序完善 2 years ago
rong.liu 1db80e42e9 提交代码 2 years ago
cheney adec7258a7 登录处理 2 years ago
cheney 71bf729d36 登录处理 2 years ago
cheney 26d555a99f 用户删除部门删除 2 years ago
rong.liu d6b620f945 完善删除栏目的对子级栏目以及栏目下的文章处理 2 years ago
cheney 202b9d7846 Merge remote-tracking branch 'origin/master' 2 years ago
cheney af76be07c9 判重返回处理 2 years ago
rong.liu cd11e047e2 Merge remote-tracking branch 'origin/master' 2 years ago
rong.liu 4dfe29f07d 栏目更改排序判重 2 years ago
cheney 7e6b38c828 添加权限异常拦截器 2 years ago
rong.liu 1f9bbe96bc 提交代码 2 years ago
rong.liu 9a4264d707 Merge remote-tracking branch 'origin/master' 2 years ago
rong.liu 0f85c6f0e2 提交代码 2 years ago
cheney 013178aeb1 扫描更新 2 years ago
cheney 89019922ff Merge remote-tracking branch 'origin/master' 2 years ago
cheney 6826d59ad7 接口鉴权通过 2 years ago
rong.liu 3ebc8cdf60 Merge remote-tracking branch 'origin/master' 2 years ago
rong.liu c16f137dc6 增加分布式锁解决多用户同时操作排序情况下序号混乱的问题。 2 years ago
cheney 9a1c599124 额外参数处理 2 years ago
cheney c7d5171a3d 额外参数处理 2 years ago
cheney e6b8893c28 错误编码返回更新 2 years ago
cheney 81d1a277b8 拦截处理 2 years ago
cheney f4502cd67b admin拦截 2 years ago
cheney b6b94646f3 Merge remote-tracking branch 'origin/master' 2 years ago
cheney 5f1da038eb 定义返回http code,admin拦截 2 years ago
rong.liu ff46f472ca 代码完善 2 years ago
rong.liu dabe5e677e 完善排序功能 2 years ago
rong.liu 5e48be6055 增加排序功能,以及其余接口增加参数 2 years ago
rong.liu 0be522886a 更改提交字段的时间类型 2 years ago
rong.liu 17964852a3 提交代码 2 years ago
rong.liu 73e9b218c2 文章更改禁启用字段 2 years ago
rong.liu 181e7fd5f1 代码优化 2 years ago
rong.liu 3d168c196e 用户名取真实姓名字段 2 years ago
rong.liu 5121af4fb5 提交代码 2 years ago
rong.liu 892d516332 Merge remote-tracking branch 'origin/master' 2 years ago
rong.liu 9ce3ca891a 提交代码 2 years ago
rong.liu c80c212572 提交代码 2 years ago
cheney 2ebe0ee14c 站点无需鉴权 2 years ago
cheney 21849bec54 隐藏10000端口 2 years ago
cheney c8ded0f143 文章上传名称实时修改 2 years ago
cheney c4292172ed 修改提交 2 years ago
cheney c403a5b7f2 Merge remote-tracking branch 'origin/master' 2 years ago
cheney 885d3996e7 接口通过 2 years ago
rong.liu 11886bb7a3 Merge remote-tracking branch 'origin/master' 2 years ago
rong.liu cf420a70f7 提交代码 2 years ago
cheney 5453a34d8f 无角色异常提示修改 2 years ago
cheney 14ac468f8e 配置提交 2 years ago
rong.liu f2d4bb224a 提交代码 2 years ago
cheney 1baaf672a2 字段更新 2 years ago
cheney ed579b4bbd Merge remote-tracking branch 'origin/master' 2 years ago
cheney eee34eec81 失败导出模板优化,登录权限拦截 2 years ago
rong.liu 4a1e0b54b0 提交代码 2 years ago
rong.liu 2dcb6c6591 提交代码 2 years ago
cheney a7b3289f21 Merge remote-tracking branch 'origin/master' 2 years ago
cheney c7eb9e5749 导入修复 2 years ago
rong.liu 5e36ba9c37 提交代码 2 years ago
cheney 657cfcae0e 附件管理 2 years ago
rong.liu a197613156 树结构更改 2 years ago
rong.liu efe48afa15 列表排序、全局搜索功能 2 years ago
rong.liu 1444047b94 文章浏览统计功能以及各个列表回显统计数量的值。 2 years ago
rong.liu 114b46cd5f Merge remote-tracking branch 'origin/master' 2 years ago
rong.liu c8636533a1 增加获取某层级下的子级栏目(包含自己) 2 years ago
cheney c1bc210339 Merge remote-tracking branch 'origin/master' 2 years ago
cheney b508e2c95b 附件上传预览,配置限制更新 2 years ago
rong.liu 062509c54e 前台页面功能接口增加完善 2 years ago
rong.liu dbc5e46f7e 依据需求更改+1 2 years ago
rong.liu 50c8cc7351 Merge remote-tracking branch 'origin/master' 2 years ago
rong.liu 452488703f 依据需求更改 2 years ago
cheney c72ce75137 修改默认登录密码为1122aa 2 years ago
rong.liu 1b58f64ce0 依据需求更改 2 years ago
rong.liu 0e6b5dd920 提交代码+1 2 years ago
rong.liu c78c2cc9a2 提交代码 2 years ago
rong.liu af0cde5d5b 长页栏目之页面设置功能 2 years ago
rong.liu b9b813c33e 长页栏目更改 2 years ago
rong.liu 90d7f8fa7a add .gitignore 2 years ago
rong.liu d00fe4cb1b 完善展示当前站点最新发布的文章+1 2 years ago
rong.liu 9cc0bd32ee 完善展示当前站点最新发布的文章 2 years ago
rong.liu bee2634885 展示当前站点最新发布的文章 2 years ago
chen b184ed7498 登录返回用户头像路径 2 years ago
chen 27780b1573 更新用户信息删除角色问题 2 years ago
chen 1e2ed7cbc2 文件更新 2 years ago
  1. 46
      .gitignore
  2. 45
      pom.xml
  3. 2
      src/main/java/com/huoran/iasf/IASFApplication.java
  4. 98
      src/main/java/com/huoran/iasf/common/advice/DecryptHttpInputMessage.java
  5. 77
      src/main/java/com/huoran/iasf/common/advice/EncryptRequestBodyAdvice.java
  6. 81
      src/main/java/com/huoran/iasf/common/advice/EncryptResponseBodyAdvice.java
  7. 28
      src/main/java/com/huoran/iasf/common/annotation/Decrypt.java
  8. 24
      src/main/java/com/huoran/iasf/common/annotation/EnableSecurity.java
  9. 14
      src/main/java/com/huoran/iasf/common/annotation/Encrypt.java
  10. 17
      src/main/java/com/huoran/iasf/common/aop/annotation/NoRepeatSubmit.java
  11. 95
      src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java
  12. 228
      src/main/java/com/huoran/iasf/common/aop/aspect/RedisServiceAop.java
  13. 9
      src/main/java/com/huoran/iasf/common/config/FileUploadProperties.java
  14. 22
      src/main/java/com/huoran/iasf/common/config/NonStaticResourceHttpRequestConfig.java
  15. 77
      src/main/java/com/huoran/iasf/common/config/SecretKeyConfig.java
  16. 24
      src/main/java/com/huoran/iasf/common/config/WebMvcConfigurer.java
  17. 14
      src/main/java/com/huoran/iasf/common/exception/EncryptRequestException.java
  18. 20
      src/main/java/com/huoran/iasf/common/exception/NotFoundException.java
  19. 13
      src/main/java/com/huoran/iasf/common/exception/UnauthorizedException.java
  20. 26
      src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java
  21. 74
      src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java
  22. 91
      src/main/java/com/huoran/iasf/common/filter/AuthFilter.java
  23. 56
      src/main/java/com/huoran/iasf/common/filter/XSSFilter.java
  24. 265
      src/main/java/com/huoran/iasf/common/filter/XssHttpServletRequestWrapper.java
  25. 99
      src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java
  26. 3
      src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java
  27. 6
      src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java
  28. 96
      src/main/java/com/huoran/iasf/common/shiro/ShiroConfig.java
  29. 31
      src/main/java/com/huoran/iasf/common/utils/Base64Util.java
  30. 31
      src/main/java/com/huoran/iasf/common/utils/Constant.java
  31. 30
      src/main/java/com/huoran/iasf/common/utils/JsonUtils.java
  32. 6
      src/main/java/com/huoran/iasf/common/utils/R.java
  33. 103
      src/main/java/com/huoran/iasf/common/utils/RSAUtil.java
  34. 110
      src/main/java/com/huoran/iasf/common/utils/TreeStructureUtils.java
  35. 119
      src/main/java/com/huoran/iasf/common/utils/fileUploadUtils.java
  36. 34
      src/main/java/com/huoran/iasf/controller/DeptController.java
  37. 25
      src/main/java/com/huoran/iasf/controller/ExceptionController.java
  38. 2
      src/main/java/com/huoran/iasf/controller/PermissionController.java
  39. 29
      src/main/java/com/huoran/iasf/controller/RoleController.java
  40. 2
      src/main/java/com/huoran/iasf/controller/RolePermissionController.java
  41. 76
      src/main/java/com/huoran/iasf/controller/SeoController.java
  42. 20
      src/main/java/com/huoran/iasf/controller/SiteController.java
  43. 313
      src/main/java/com/huoran/iasf/controller/SysColumnController.java
  44. 84
      src/main/java/com/huoran/iasf/controller/SysColumnLongPageController.java
  45. 132
      src/main/java/com/huoran/iasf/controller/SysContentClassificationController.java
  46. 274
      src/main/java/com/huoran/iasf/controller/SysContentController.java
  47. 82
      src/main/java/com/huoran/iasf/controller/SysContentFileController.java
  48. 126
      src/main/java/com/huoran/iasf/controller/SysContentLabelController.java
  49. 93
      src/main/java/com/huoran/iasf/controller/SysFilesController.java
  50. 9
      src/main/java/com/huoran/iasf/controller/SysLogController.java
  51. 4
      src/main/java/com/huoran/iasf/controller/SysNavigationStyleController.java
  52. 108
      src/main/java/com/huoran/iasf/controller/SysTemplateController.java
  53. 115
      src/main/java/com/huoran/iasf/controller/UserController.java
  54. 2
      src/main/java/com/huoran/iasf/controller/UserDeptController.java
  55. 45
      src/main/java/com/huoran/iasf/controller/UserGroupController.java
  56. 2
      src/main/java/com/huoran/iasf/controller/UserRoleController.java
  57. 44
      src/main/java/com/huoran/iasf/entity/Seo.java
  58. 27
      src/main/java/com/huoran/iasf/entity/SysColumn.java
  59. 16
      src/main/java/com/huoran/iasf/entity/SysColumnLongPage.java
  60. 177
      src/main/java/com/huoran/iasf/entity/SysContent.java
  61. 61
      src/main/java/com/huoran/iasf/entity/SysContentClassification.java
  62. 63
      src/main/java/com/huoran/iasf/entity/SysContentFile.java
  63. 53
      src/main/java/com/huoran/iasf/entity/SysContentLabel.java
  64. 7
      src/main/java/com/huoran/iasf/entity/SysDept.java
  65. 11
      src/main/java/com/huoran/iasf/entity/SysFilesEntity.java
  66. 41
      src/main/java/com/huoran/iasf/entity/SysTemplate.java
  67. 49
      src/main/java/com/huoran/iasf/entity/SysTemplateStyle.java
  68. 39
      src/main/java/com/huoran/iasf/entity/SysTemplateStyleConfiguration.java
  69. 1
      src/main/java/com/huoran/iasf/entity/UserGroup.java
  70. 16
      src/main/java/com/huoran/iasf/mapper/SeoMapper.java
  71. 10
      src/main/java/com/huoran/iasf/mapper/SysColumnMapper.java
  72. 16
      src/main/java/com/huoran/iasf/mapper/SysContentClassificationMapper.java
  73. 18
      src/main/java/com/huoran/iasf/mapper/SysContentFileMapper.java
  74. 16
      src/main/java/com/huoran/iasf/mapper/SysContentLabelMapper.java
  75. 26
      src/main/java/com/huoran/iasf/mapper/SysContentMapper.java
  76. 2
      src/main/java/com/huoran/iasf/mapper/SysDeptMapper.java
  77. 6
      src/main/java/com/huoran/iasf/mapper/SysFilesMapper.java
  78. 16
      src/main/java/com/huoran/iasf/mapper/SysTemplateMapper.java
  79. 20
      src/main/java/com/huoran/iasf/mapper/SysTemplateStyleConfigurationMapper.java
  80. 16
      src/main/java/com/huoran/iasf/mapper/SysTemplateStyleMapper.java
  81. 2
      src/main/java/com/huoran/iasf/mapper/SysUserMapper.java
  82. 5
      src/main/java/com/huoran/iasf/mapper/xml/SeoMapper.xml
  83. 4
      src/main/java/com/huoran/iasf/mapper/xml/SysColumnLongPageMapper.xml
  84. 136
      src/main/java/com/huoran/iasf/mapper/xml/SysColumnMapper.xml
  85. 16
      src/main/java/com/huoran/iasf/mapper/xml/SysContentClassificationMapper.xml
  86. 29
      src/main/java/com/huoran/iasf/mapper/xml/SysContentFileMapper.xml
  87. 16
      src/main/java/com/huoran/iasf/mapper/xml/SysContentLabelMapper.xml
  88. 272
      src/main/java/com/huoran/iasf/mapper/xml/SysContentMapper.xml
  89. 48
      src/main/java/com/huoran/iasf/mapper/xml/SysFilesMapper.xml
  90. 2
      src/main/java/com/huoran/iasf/mapper/xml/SysPermissionMapper.xml
  91. 5
      src/main/java/com/huoran/iasf/mapper/xml/SysTemplateMapper.xml
  92. 13
      src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleConfigurationMapper.xml
  93. 5
      src/main/java/com/huoran/iasf/mapper/xml/SysTemplateStyleMapper.xml
  94. 6
      src/main/java/com/huoran/iasf/service/HttpApiSessionService.java
  95. 15
      src/main/java/com/huoran/iasf/service/HttpSessionService.java
  96. 2
      src/main/java/com/huoran/iasf/service/RoleService.java
  97. 16
      src/main/java/com/huoran/iasf/service/SeoService.java
  98. 18
      src/main/java/com/huoran/iasf/service/SysColumnService.java
  99. 14
      src/main/java/com/huoran/iasf/service/SysContentClassificationService.java
  100. 17
      src/main/java/com/huoran/iasf/service/SysContentFileService.java
  101. Some files were not shown because too many files have changed in this diff Show More

46
.gitignore vendored

@ -1,45 +1,3 @@
# ---> Java /.idea/
# Compiled class file **/target/
*.class *.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
# ---> Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
# Eclipse m2e generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath

@ -52,6 +52,21 @@
<dependencies> <dependencies>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 发送邮箱 --> <!-- 发送邮箱 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
@ -276,6 +291,36 @@
<skipTests>true</skipTests> <skipTests>true</skipTests>
</configuration> </configuration>
</plugin> </plugin>
<!-- 加密插件,防止反编译 -->
<plugin>
<!-- https://gitee.com/roseboy/classfinal -->
<groupId>net.roseboy</groupId>
<artifactId>classfinal-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<!--加密密码,如果是#号,则使用无密码模式加密,【加密后没有pom文件,不用担心泄漏】-->
<password>#</password>
<!--加密的包名(可为空,多个用","分割)-->
<packages>com.huoran.iasf</packages>
<!--需要加密的配置文件,一般是classes目录下的yml或properties文件(可为空,多个用","分割)-->
<cfgfiles>*.properties,*.yml</cfgfiles>
<excludes>org.spring</excludes>
<!--外部依赖的jar目录,例如/tomcat/lib(可为空,多个用","分割)-->
<!--<classpath></classpath>-->
<!--运行命令: java -javaagent:iasf-encrypted.jar -jar iasf-encrypted.jar-->
<!--机器码获取命令:java -jar classfinal-fatjar-1.2.1.jar -C -->
<code>FDDEF78DF2FC3D09D733CBEAB15C3AEFD41D8CD98F00B204E9800998ECF8427ED41D8CD98F00B204E9800998ECF8427E</code>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>classFinal</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins> </plugins>
<resources> <resources>

@ -1,5 +1,6 @@
package com.huoran.iasf; package com.huoran.iasf;
import com.huoran.iasf.common.annotation.EnableSecurity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -13,6 +14,7 @@ import java.net.InetAddress;
@SpringBootApplication @SpringBootApplication
@MapperScan("com.huoran.iasf.mapper") @MapperScan("com.huoran.iasf.mapper")
@Slf4j @Slf4j
@EnableSecurity
@ServletComponentScan(basePackages = {"com.huoran.iasf.common.filter"}) //这一句完成了配置,Springboot的”懒理念“真的厉害。 @ServletComponentScan(basePackages = {"com.huoran.iasf.common.filter"}) //这一句完成了配置,Springboot的”懒理念“真的厉害。
public class IASFApplication { public class IASFApplication {

@ -0,0 +1,98 @@
package com.huoran.iasf.common.advice;
import com.huoran.iasf.common.annotation.Decrypt;
import com.huoran.iasf.common.config.SecretKeyConfig;
import com.huoran.iasf.common.exception.EncryptRequestException;
import com.huoran.iasf.common.utils.Base64Util;
import com.huoran.iasf.common.utils.JsonUtils;
import com.huoran.iasf.common.utils.RSAUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
/**
* Author:Bobby
* DateTime:2019/4/9
**/
public class DecryptHttpInputMessage implements HttpInputMessage {
private Logger log = LoggerFactory.getLogger(this.getClass());
private HttpHeaders headers;
private InputStream body;
public DecryptHttpInputMessage(HttpInputMessage inputMessage, SecretKeyConfig secretKeyConfig, Decrypt decrypt) throws Exception {
String privateKey = secretKeyConfig.getPrivateKey();
String charset = secretKeyConfig.getCharset();
boolean showLog = secretKeyConfig.isShowLog();
boolean timestampCheck = secretKeyConfig.isTimestampCheck();
if (StringUtils.isEmpty(privateKey)) {
throw new IllegalArgumentException("privateKey is null");
}
this.headers = inputMessage.getHeaders();
String content = new BufferedReader(new InputStreamReader(inputMessage.getBody()))
.lines().collect(Collectors.joining(System.lineSeparator()));
String decryptBody;
// 未加密内容
if (content.startsWith("{")||StringUtils.isNumeric(content)||content.length()<10) {
// 必须加密
if (decrypt.required()) {
log.error("not support unencrypted content:{}", content);
throw new EncryptRequestException("not support unencrypted content");
}
log.info("Unencrypted without decryption:{}", content);
decryptBody = content;
} else {
StringBuilder json = new StringBuilder();
content = content.replaceAll(" ", "+");
if (!StringUtils.isEmpty(content)) {
String[] contents = content.split("\\|");
for (String value : contents) {
value = new String(RSAUtil.decrypt(Base64Util.decode(value), privateKey), charset);
json.append(value);
}
}
decryptBody = json.toString();
if(showLog) {
log.info("Encrypted data received:{},After decryption:{}", content, decryptBody);
}
}
// 开启时间戳检查
if (timestampCheck) {
// 容忍最小请求时间
long toleranceTime = System.currentTimeMillis() - decrypt.timeout();
long requestTime = JsonUtils.getNode(decryptBody, "timestamp").asLong();
// 如果请求时间小于最小容忍请求时间, 判定为超时
if (requestTime < toleranceTime) {
log.error("Encryption request has timed out, toleranceTime:{}, requestTime:{}, After decryption:{}", toleranceTime, requestTime, decryptBody);
throw new EncryptRequestException("request timeout");
}
}
this.body = new ByteArrayInputStream(decryptBody.getBytes());
}
@Override
public InputStream getBody(){
return body;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}

@ -0,0 +1,77 @@
package com.huoran.iasf.common.advice;
import com.huoran.iasf.common.annotation.Decrypt;
import com.huoran.iasf.common.config.SecretKeyConfig;
import com.huoran.iasf.common.exception.EncryptRequestException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Objects;
/**
* Author:Bobby
* DateTime:2019/4/9
**/
@ControllerAdvice
public class EncryptRequestBodyAdvice implements RequestBodyAdvice {
private Logger log = LoggerFactory.getLogger(this.getClass());
private boolean encrypt;
private Decrypt decryptAnnotation;
@Autowired
private SecretKeyConfig secretKeyConfig;
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
Method method = methodParameter.getMethod();
if (Objects.isNull(method)) {
encrypt = false;
return false;
}
if (method.isAnnotationPresent(Decrypt.class) && secretKeyConfig.isOpen()) {
encrypt = true;
decryptAnnotation = methodParameter.getMethodAnnotation(Decrypt.class);
return true;
}
// 此处如果按照原逻辑直接返回encrypt, 会造成一次修改为true之后, 后续请求都会变成true, 在不支持时, 需要做修正
encrypt = false;
return false;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType){
if (encrypt) {
try {
return new DecryptHttpInputMessage(inputMessage, secretKeyConfig, decryptAnnotation);
} catch (EncryptRequestException e) {
throw e;
} catch (Exception e) {
log.error("Decryption failed", e);
}
}
return inputMessage;
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
}

@ -0,0 +1,81 @@
package com.huoran.iasf.common.advice;
import com.huoran.iasf.common.annotation.Encrypt;
import com.huoran.iasf.common.config.SecretKeyConfig;
import com.huoran.iasf.common.utils.Base64Util;
import com.huoran.iasf.common.utils.JsonUtils;
import com.huoran.iasf.common.utils.RSAUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* Author:Bobby
* DateTime:2019/4/9
**/
@ControllerAdvice
public class EncryptResponseBodyAdvice implements ResponseBodyAdvice<Object> {
private Logger log = LoggerFactory.getLogger(this.getClass());
private boolean encrypt;
@Autowired
private SecretKeyConfig secretKeyConfig;
private static ThreadLocal<Boolean> encryptLocal = new ThreadLocal<>();
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
Method method = returnType.getMethod();
if (Objects.isNull(method)) {
return encrypt;
}
encrypt = method.isAnnotationPresent(Encrypt.class) && secretKeyConfig.isOpen();
return encrypt;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
// EncryptResponseBodyAdvice.setEncryptStatus(false);
// Dynamic Settings Not Encrypted
Boolean status = encryptLocal.get();
if (null != status && !status) {
encryptLocal.remove();
return body;
}
if (encrypt) {
String publicKey = secretKeyConfig.getPublicKey();
try {
String content = JsonUtils.writeValueAsString(body);
if (!StringUtils.hasText(publicKey)) {
throw new NullPointerException("Please configure rsa.encrypt.privatekeyc parameter!");
}
byte[] data = content.getBytes();
byte[] encodedData = RSAUtil.encrypt(data, publicKey);
String result = Base64Util.encode(encodedData);
if(secretKeyConfig.isShowLog()) {
log.info("Pre-encrypted data:{},After encryption:{}", content, result);
}
return result;
} catch (Exception e) {
log.error("Encrypted data exception", e);
}
}
return body;
}
}

@ -0,0 +1,28 @@
package com.huoran.iasf.common.annotation;
import com.huoran.iasf.common.exception.EncryptRequestException;
import java.lang.annotation.*;
/**
* Author:Bobby
* DateTime:2019/4/9 16:45
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Decrypt{
/**
* 请求参数一定要是加密内容
*/
boolean required() default true;
/**
* 请求数据时间戳校验时间差
* 超过(当前时间-指定时间)的数据认定为伪造
* 注意应用程序需要捕获 {@link EncryptRequestException} 异常
*/
long timeout() default 3000;
}

@ -0,0 +1,24 @@
package com.huoran.iasf.common.annotation;
import com.huoran.iasf.common.advice.EncryptRequestBodyAdvice;
import com.huoran.iasf.common.advice.EncryptResponseBodyAdvice;
import com.huoran.iasf.common.config.SecretKeyConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* Author:Bobby
* DateTime:2019/4/9 16:44
**/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import({SecretKeyConfig.class,
EncryptResponseBodyAdvice.class,
EncryptRequestBodyAdvice.class})
public @interface EnableSecurity{
}

@ -0,0 +1,14 @@
package com.huoran.iasf.common.annotation;
import java.lang.annotation.*;
/**
* Author:Bobby
* DateTime:2019/4/9 16:45
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Encrypt{
}

@ -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:";
}

@ -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;
}
}
}

@ -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;
/**
* 缓存基本的对象IntegerString实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @return 缓存的对象
*/
public <T> ValueOperations<String, T> setCacheObject(String key, T value) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
operation.set(key, value);
return operation;
}
/**
* 缓存基本的对象IntegerString实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
* @return 缓存的对象
*/
public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
operation.set(key, value, timeout, timeUnit);
return operation;
}
/**
* 获得缓存的基本对象
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(String key) {
ValueOperations<String, T> 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 <T> ListOperations<String, T> setCacheList(String key, List<T> 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 <T> List<T> getCacheList(String key) {
List<T> dataList = new ArrayList<T>();
ListOperations<String, T> 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 <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) {
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext()) {
setOperation.add(it.next());
}
return setOperation;
}
/**
* 获得缓存的set
*
* @param key
* @return
*/
public <T> Set<T> getCacheSet(String key) {
Set<T> dataSet = new HashSet<T>();
BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key);
dataSet = operation.members();
return dataSet;
}
/**
* 缓存Map
*
* @param key
* @param dataMap
* @return
*/
public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) {
HashOperations hashOperations = redisTemplate.opsForHash();
if (null != dataMap) {
for (Map.Entry<String, T> entry : dataMap.entrySet()) {
hashOperations.put(key, entry.getKey(), entry.getValue());
}
}
return hashOperations;
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(String key) {
Map<String, T> map = redisTemplate.opsForHash().entries(key);
return map;
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public Collection<String> 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 <T> ValueOperations<String, T> setBillObject(String key, List<Map<String, Object>> value) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
operation.set(key, (T) value);
return operation;
}
/**
* 缓存list<Map<String, Object>>
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
* @return 缓存的对象
*/
public <T> ValueOperations<String, T> setBillObject(String key, List<Map<String, Object>> value, Integer timeout, TimeUnit timeUnit) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
operation.set(key,(T)value, timeout, timeUnit);
return operation;
}
/**
* 缓存Map
*
* @param key
* @param dataMap
* @return
*/
public <T> HashOperations<String, String, T> setCKdBillMap(String key, Map<String, T> dataMap) {
HashOperations hashOperations = redisTemplate.opsForHash();
if (null != dataMap) {
for (Map.Entry<String, T> entry : dataMap.entrySet()) {
hashOperations.put(key, entry.getKey(), entry.getValue());
}
}
return hashOperations;
}
}

@ -16,6 +16,7 @@ import org.springframework.util.StringUtils;
public class FileUploadProperties { public class FileUploadProperties {
private String path; private String path;
private String ip;
private String url; private String url;
private String accessUrl; private String accessUrl;
@ -28,6 +29,14 @@ public class FileUploadProperties {
this.path = path; this.path = path;
} }
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUrl() { public String getUrl() {
return url; return url;
} }

@ -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);
}
}

@ -0,0 +1,77 @@
package com.huoran.iasf.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Author:Bobby
* DateTime:2019/4/9
**/
@ConfigurationProperties(prefix = "rsa.encrypt")
@Configuration
public class SecretKeyConfig {
private String privateKey;
private String publicKey;
private String charset = "UTF-8";
private boolean open = true;
private boolean showLog = false;
/**
* 请求数据时间戳校验时间差
* 超过指定时间的数据认定为伪造
*/
private boolean timestampCheck = false;
public String getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public String getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public boolean isOpen() {
return open;
}
public void setOpen(boolean open) {
this.open = open;
}
public boolean isShowLog() {
return showLog;
}
public void setShowLog(boolean showLog) {
this.showLog = showLog;
}
public boolean isTimestampCheck() {
return timestampCheck;
}
public void setTimestampCheck(boolean timestampCheck) {
this.timestampCheck = timestampCheck;
}
}

@ -15,6 +15,9 @@ import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter; import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; 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.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
@ -41,6 +44,27 @@ public class WebMvcConfigurer extends WebMvcConfigurationSupport {
private FileUploadProperties fileUploadProperties; private FileUploadProperties fileUploadProperties;
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedHeader("*"); // 允许任何头
// corsConfiguration.addAllowedOrigin("*"); // 允许任何头
corsConfiguration.addAllowedOrigin("https://new.iasf.ac.cn"); //允许信任域名
corsConfiguration.addAllowedOrigin("https://www.iasf.ac.cn"); //允许信任域名
corsConfiguration.addAllowedOrigin("http://192.168.31.125:8095"); //允许信任域名
corsConfiguration.addAllowedOrigin("http://192.168.31.125:8088"); //允许信任域名
corsConfiguration.addAllowedOrigin("http://10.10.11.7"); //允许信任域名
corsConfiguration.addAllowedMethod("*"); // 允许任何方法(post、get等)
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 对接口配置跨域设置
return new CorsFilter(source);
}
/** /**
* 使用阿里 FastJson 作为JSON MessageConverter * 使用阿里 FastJson 作为JSON MessageConverter
*/ */

@ -0,0 +1,14 @@
package com.huoran.iasf.common.exception;
/**
* @author imyzt
* @date 2020/06/02
* @description 加密请求超时异常
*/
public class EncryptRequestException extends RuntimeException {
public EncryptRequestException(String msg) {
super(msg);
}
}

@ -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;
}

@ -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;
}

@ -24,33 +24,41 @@ public enum BaseResponseCode implements ResponseCodeInterface {
KEY_OR_TOMEUNIT(10009, "key or TomeUnit 不能为空!"), KEY_OR_TOMEUNIT(10009, "key or TomeUnit 不能为空!"),
DICTIONARY_DATA_FAILED(10010, "获取字典数据失败"), DICTIONARY_DATA_FAILED(10010, "获取字典数据失败"),
UPLOAD_EMPTY(10011, "上传内容为空"), UPLOAD_EMPTY(10011, "上传内容为空"),
UPLOAD_FAILED(10012, "上传失败"), UPLOAD_FAILED(10012, "上传失败,上传格式不支持!"),
VERIFICATION_CODE_ERROR(10007, "验证码错误!"), VERIFICATION_CODE_ERROR(10007, "验证码错误!"),
VERIFICATION_CODE_EXPIRED(10006, "验证码已过期!"), VERIFICATION_CODE_EXPIRED(10006, "验证码已过期!"),
CANNOT_SAME(10005, "新密码不能与旧密码相同!"), CANNOT_SAME(10005, "新密码不能与旧密码相同!"),
EXCEL_FILE_INVALID(10004, "上传excel文件错误!"), EXCEL_FILE_INVALID(10004, "上传excel文件错误!"),
VALID_EXCEPTION(10003, "参数格式校验异常!"), VALID_EXCEPTION(10003, "参数格式校验异常!"),
OPERATION_ERROR(10002, "操作失败"), OPERATION_ERROR(10002, "操作失败"),
SYSTEM_BUSY(10001, "系统繁忙,请稍候再试"), SYSTEM_BUSY(500, "系统繁忙,请稍候再试"),
SUCCESS(200, "success"), SUCCESS(200, "success"),
EXCEL_FILE_FORMAT_ERROR(40007, "请根据模板使用说明录入正确的用户信息!"), EXCEL_FILE_FORMAT_ERROR(40007, "请根据模板使用说明录入正确的用户信息!"),
TOKEN_ERROR(401001, "登录凭证已过期,请重新登录"), TOKEN_ERROR(401, "登录凭证已过期,请重新登录"),
DATA_ERROR(401003, "传入数据异常"), DATA_ERROR(401003, "传入数据异常"),
NOT_ACCOUNT(401004, "该用户不存在,请先注册"), NOT_ACCOUNT(401004, "用户名不存在或密码错误"),
USER_LOCK(401005, "该用户已被锁定,请联系运营人员"), USER_LOCK(401005, "该用户已被锁定,请联系管理员!"),
PASSWORD_ERROR(401006, "用户名或密码错误"), PASSWORD_ERROR(401006, "用户名不存在或密码错误"),
METHOD_ARGUMENT_NOT_VALID_EXCEPTION(401007, "方法参数校验异常"), METHOD_ARGUMENT_NOT_VALID_EXCEPTION(400, "参数错误!"),
UNAUTHORIZED_ERROR(401008, "权鉴校验不通过"), ILLEGAL_CHARACTERS(400, "入参中有非法字符,请修改!"),
// UNAUTHORIZED_ERROR(401008, "权鉴校验不通过"),
UNAUTHORIZED_ERROR(401008, "无操作权限!"),
ROLE_PERMISSION_RELATION(401009, "该菜单权限存在子集关联,不允许删除"), ROLE_PERMISSION_RELATION(401009, "该菜单权限存在子集关联,不允许删除"),
OLD_PASSWORD_ERROR(401010, "旧密码不正确"), OLD_PASSWORD_ERROR(401010, "旧密码不正确"),
NOT_PERMISSION_DELETED_DEPT(401011, "该组织机构下还关联着用户,不允许删除"), NOT_PERMISSION_DELETED_DEPT(401011, "该组织机构下还关联着用户,不允许删除"),
DELETE_SUB_DEPARTMENTS_FIRST(401018, "请先删除子级部门!"),
OPERATION_MENU_PERMISSION_CATALOG_ERROR(401012, "操作后的菜单类型是目录,所属菜单必须为默认顶级菜单或者目录"), OPERATION_MENU_PERMISSION_CATALOG_ERROR(401012, "操作后的菜单类型是目录,所属菜单必须为默认顶级菜单或者目录"),
OPERATION_MENU_PERMISSION_MENU_ERROR(401013, "操作后的菜单类型是菜单,所属菜单必须为目录类型"), OPERATION_MENU_PERMISSION_MENU_ERROR(401013, "操作后的菜单类型是菜单,所属菜单必须为目录类型"),
OPERATION_MENU_PERMISSION_BTN_ERROR(401013, "操作后的菜单类型是按钮,所属菜单必须为菜单类型"), OPERATION_MENU_PERMISSION_BTN_ERROR(401013, "操作后的菜单类型是按钮,所属菜单必须为菜单类型"),
OPERATION_MENU_PERMISSION_URL_NOT_NULL(401015, "菜单权限的url不能为空"), OPERATION_MENU_PERMISSION_URL_NOT_NULL(401015, "菜单权限的url不能为空"),
OPERATION_MENU_PERMISSION_URL_PERMS_NULL(401016, "菜单权限的标识符不能为空"), OPERATION_MENU_PERMISSION_URL_PERMS_NULL(401016, "菜单权限的标识符不能为空"),
EXCEL_FILE_NULL(40006, "导入失败,导入数据为空!") ROLE_ERROR(401017, "账号角色被删,请联系管理员添加角色后再试"),
EXCEL_FILE_NULL(40006, "导入失败,导入数据为空!"),
DATA_DOES_NOT_EXIST(500, "当前数据不存在"),
XSS_FILTER(400, "xss攻击检查:参数含有非法攻击字符,请修改后继续操作!"),
SQL_FILTER(400, "sql攻击检查:参数含有非法攻击字符,请修改后继续操作!"),
; ;
/** /**

@ -1,18 +1,28 @@
package com.huoran.iasf.common.exception.handler; package com.huoran.iasf.common.exception.handler;
import com.alibaba.fastjson.JSONException;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.huoran.iasf.common.exception.BusinessException; import com.huoran.iasf.common.exception.BusinessException;
import com.huoran.iasf.common.exception.EncryptRequestException;
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.exception.code.BaseResponseCode;
import com.huoran.iasf.common.utils.R; import com.huoran.iasf.common.utils.R;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.AuthorizationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException; 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.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException; import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -24,24 +34,74 @@ import java.util.concurrent.atomic.AtomicReference;
* @version V1.0 * @version V1.0
* @date 2022年7月28日 * @date 2022年7月28日
*/ */
@RestControllerAdvice
@Slf4j @Slf4j
@RestControllerAdvice
public class RestExceptionHandler { public class RestExceptionHandler {
/** /**
* 系统繁忙请稍候再试" * 系统繁忙请稍候再试"
*/ */
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public R handleException(Exception e) { public R handleException(Exception e) {
log.error("Exception,exception:{}", e, e); log.error("Exception,exception:{}", e, e);
return R.getResult(BaseResponseCode.SYSTEM_BUSY); 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(EncryptRequestException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R encryptRequestException(EncryptRequestException e) {
log.error("Exception,exception:{}", e, e);
return R.getResult(BaseResponseCode.METHOD_ARGUMENT_NOT_VALID_EXCEPTION);
}
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R illegalArgumentException(JSONException e) {
log.error("Exception,exception:{}", e, e);
return R.getResult(BaseResponseCode.ILLEGAL_CHARACTERS);
}
@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) @ExceptionHandler(value = BusinessException.class)
R businessExceptionHandler(BusinessException e) { @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); log.error("Exception,exception:{}", e, e);
BaseResponseCode em = e.getBaseResponseCode(); BaseResponseCode em = e.getBaseResponseCode();
return new R(em.getCode(), em.getMsg()); return new R(em.getCode(), em.getMsg());
@ -51,6 +111,7 @@ public class RestExceptionHandler {
* 没有权限 返回403视图 * 没有权限 返回403视图
*/ */
@ExceptionHandler(value = AuthorizationException.class) @ExceptionHandler(value = AuthorizationException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public R errorPermission(AuthorizationException e) { public R errorPermission(AuthorizationException e) {
log.error("Exception,exception:{}", e, e); log.error("Exception,exception:{}", e, e);
return new R(BaseResponseCode.UNAUTHORIZED_ERROR); return new R(BaseResponseCode.UNAUTHORIZED_ERROR);
@ -61,6 +122,7 @@ public class RestExceptionHandler {
* 处理参数格式校验异常 * 处理参数格式校验异常
*/ */
@ExceptionHandler(value = MethodArgumentNotValidException.class) @ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public R handleValidException(MethodArgumentNotValidException e){ public R handleValidException(MethodArgumentNotValidException e){
log.error("参数格式校验异常"); log.error("参数格式校验异常");
BindingResult bindingResult = e.getBindingResult(); BindingResult bindingResult = e.getBindingResult();
@ -78,6 +140,7 @@ public class RestExceptionHandler {
* 处理Validated List<entity> 异常 * 处理Validated List<entity> 异常
*/ */
@ExceptionHandler @ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R handle(ConstraintViolationException exception) { public R handle(ConstraintViolationException exception) {
log.error("methodArgumentNotValidExceptionHandler bindingResult.allErrors():{},exception:{}", exception, exception); log.error("methodArgumentNotValidExceptionHandler bindingResult.allErrors():{},exception:{}", exception, exception);
Set<ConstraintViolation<?>> violations = exception.getConstraintViolations(); Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
@ -89,4 +152,11 @@ public class RestExceptionHandler {
return R.getResult(BaseResponseCode.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getCode(), builder.toString()); 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());
}
} }

@ -1,48 +1,60 @@
package com.huoran.iasf.common.filter; package com.huoran.iasf.common.filter;
import com.alibaba.fastjson.JSON;
import com.huoran.iasf.common.utils.R; import com.huoran.iasf.common.exception.BusinessException;
import com.huoran.iasf.service.HttpApiSessionService; 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.Claims;
import io.jsonwebtoken.Jwts;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import javax.annotation.Resource;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import static com.huoran.iasf.service.HttpApiSessionService.USER_ID_KEY; import static com.huoran.iasf.service.HttpApiSessionService.*;
import static com.huoran.iasf.service.HttpApiSessionService.USER_USERNAME_KEY;
/**
* shiro过滤器 登录用户权限认证授权
* @author cheney
* @version V1.0
* @date 2022年7月28日
*/
@Slf4j @Slf4j
@WebFilter(filterName = "authFilter", urlPatterns = "/iasf/*") @WebFilter(filterName = "tokenFilter", urlPatterns = "/**")
@Order(1) @Order(1)
//@Component
public class AuthFilter implements Filter { public class AuthFilter implements Filter {
/** /**
* 白名单 * 白名单
*/ */
private static final String[] whiteList = private static final String[] whiteList =
{"/iasf/sys/user/login", {"/iasf/sys/user/login",
"/iasf/sys/exportFailure"}; "/iasf/sys/exportFailure","/iasf/sys/getVerify","/iasf/doc.html"};
@Resource //需要拦截的地址,验证token是否存在及有效
HttpApiSessionService httpApiSessionService;
//需要拦截的地址
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @SneakyThrows
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
//每一次的请求先校验cookie
HttpServletRequest req = (HttpServletRequest) request; HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response; HttpServletResponse resp = (HttpServletResponse) response;
resp.setHeader("Access-Control-Allow-Origin","*"); resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
resp.setHeader("Access-Control-Allow-Credentials", "true"); resp.setHeader("Access-Control-Allow-Methods", req.getMethod());
resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); resp.setHeader("Access-Control-Max-Age", "3600");
resp.setHeader("Access-Control-Allow-Headers", "*"); resp.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers"));
String url = req.getRequestURI(); String url = req.getRequestURI();
log.info("url:{}", url); log.info("url:{}", url);
if (Arrays.asList(whiteList).contains(url)) { if (Arrays.asList(whiteList).contains(url)) {
chain.doFilter(request, response); chain.doFilter(request, response);
} else { } else {
@ -55,37 +67,44 @@ public class AuthFilter implements Filter {
} }
//token为空返回 //token为空返回
if (StringUtils.isBlank(token)) { if (StringUtils.isBlank(token)) {
resp.setStatus(401); resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
responseResult(resp, R.fail("token不能为空")); 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 // 校验并解析token,如果token过期或者篡改,则会返回null
Claims claims = httpApiSessionService.checkJWT(token); Claims claims = checkJWT(token);
if (null == claims) { if (null == claims) {
resp.setStatus(401); resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
responseResult(resp, R.fail("登陆失效,请重新登陆")); resp.setCharacterEncoding("utf-8");
} resp.setContentType(MediaType.APPLICATION_JSON_VALUE);
//TODO 校验用户状态等 request.setAttribute("filterError", new UnauthorizedException(BaseResponseCode.TOKEN_ERROR));
// 指定处理该请求的处理器
request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, resp);
}else {
// 校验通过后,设置用户信息到request里,在Controller中从Request域中获取用户信息 // 校验通过后,设置用户信息到request里,在Controller中从Request域中获取用户信息
assert claims != null;
request.setAttribute(USER_ID_KEY, claims.get(USER_ID_KEY)); request.setAttribute(USER_ID_KEY, claims.get(USER_ID_KEY));
request.setAttribute(USER_USERNAME_KEY, claims.get(USER_USERNAME_KEY)); request.setAttribute(USER_USERNAME_KEY, claims.get(USER_USERNAME_KEY));
} }
chain.doFilter(request, response);
}
} }
/** /**
* responseResult * 校验token
* @param response */
* @param result*/ public Claims checkJWT(String token) {
private void responseResult(HttpServletResponse response, R result) {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "application/json;charset=UTF-8");
// response.setStatus(200);
try { try {
response.getWriter().write(JSON.toJSONString(result)); final Claims claims = Jwts.parser().setSigningKey(APP_SECRET).
} catch (IOException ex) { parseClaimsJws(token).getBody();
log.error(ex.getMessage()); return claims;
} catch (Exception e) {
return null;
} }
} }
} }

@ -0,0 +1,56 @@
package com.huoran.iasf.common.filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.core.annotation.Order;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@WebFilter(filterName = "xssFilter", urlPatterns = "/*", asyncSupported = true)
@Order(2)
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig1) throws ServletException {
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
//注入xss过滤器实例
if(arg2 != null){
HttpServletRequest req = (HttpServletRequest) arg0;
String method = req.getMethod();
boolean methodB = false;
if("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)){
methodB = true;
}
if (methodB && req.getContentType() != null && req.getContentType().startsWith("multipart/")) {
// 过滤
arg2.doFilter(req, arg1);
}else {
HttpServletResponse response = (HttpServletResponse) arg1;
XssHttpServletRequestWrapper reqW = new XssHttpServletRequestWrapper(req);
//过滤
arg2.doFilter(reqW, response);
}
}
}
@Override
public void destroy() {
}
}

@ -0,0 +1,265 @@
package com.huoran.iasf.common.filter;
import com.alibaba.fastjson.JSONObject;
import com.huoran.iasf.common.exception.BusinessException;
import com.huoran.iasf.common.exception.code.BaseResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Safelist;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.regex.Pattern;
@Slf4j
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
/**
* post请求体
*/
private byte[] body;
/**
* 是否是文件上传
*/
private boolean fileUpload = true;
//富文本验证链接
private static final String[] whiteList =
{"/iasf/sysContent/save",
"/iasf/sysContent/update"};
/**
* sql注入正则
*/
private static String badStrReg =
"\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
/**
* xss脚本正则
*/
private final static Pattern[] scriptPatterns = {
Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
Pattern.compile("script", Pattern.CASE_INSENSITIVE),
Pattern.compile("ScriPT", Pattern.CASE_INSENSITIVE),
Pattern.compile("meta", Pattern.CASE_INSENSITIVE),
Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)
};
public XssHttpServletRequestWrapper() {
super(null);
}
/**
* 构造函数 - 获取post请求体
* @param httpservletrequest
* @throws IOException
*/
public XssHttpServletRequestWrapper(HttpServletRequest httpservletrequest) throws IOException {
super(httpservletrequest);
String sessionStream = getBodyString(httpservletrequest);
body = sessionStream.getBytes(StandardCharsets.UTF_8);
System.out.println(httpservletrequest.getRequestURI());
if(Arrays.asList(whiteList).contains(httpservletrequest.getRequestURI())){
fileUpload = false;
}
}
/**
* 读取post请求体
* @param httpservletrequest
* @return
* @throws IOException
*/
private String getBodyString(HttpServletRequest httpservletrequest) throws IOException {
StringBuilder sb = new StringBuilder();
InputStream ins = httpservletrequest.getInputStream();
try (BufferedReader isr = new BufferedReader(new InputStreamReader(ins, StandardCharsets.UTF_8));) {
String line = "";
while ((line = isr.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
throw e;
}
return sb.toString();
}
/**
* 过滤springmvc中的 @RequestParam 注解中的参数
* @param s
* @return
*/
@Override
public String[] getParameterValues(String s) {
String[] str = super.getParameterValues(s);
if (str == null) {
return null;
}
int i = str.length;
String[] as1 = new String[i];
for (int j = 0; j < i; j++) {
as1[j] = cleanXSS(cleanSQLInject(str[j]));
}
// log.info("XssHttpServletRequestWrapper净化后的请求为:========== {}", Arrays.toString(as1));
return as1;
}
/**
* 过滤request.getParameter的参数
* @param s
* @return
*/
@Override
public String getParameter(String s) {
String s1 = super.getParameter(s);
if (s1 == null) {
return null;
} else {
String s2 = cleanXSS(cleanSQLInject(s1));
// log.info("XssHttpServletRequestWrapper净化后的请求为:========== {}", s2);
return s2;
}
}
/**
* 过滤请求体 json 格式的
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
// 非文件上传进行过滤
if (!fileUpload) {
try {
// 解析请求体为字符串
String bodyStr = new String(body, StandardCharsets.UTF_8);
// 清理HTML,只允许安全的元素和属性
Safelist safelist = Safelist.basicWithImages(); // 自定义safelist
String safeHtml = Jsoup.clean(bodyStr, "", safelist, new Document.OutputSettings().prettyPrint(false));
cleanSQLInject(safeHtml);
} catch (Exception e) {
// 处理解析或处理过程中的任何异常
log.error("Error processing request body {}", e.getMessage());
}
}
// 将请求体参数流转 -- 流读取一次就会消失,所以我们事先读取之后就存在byte数组里边方便流转
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
public String cleanXSS(String src) {
if (StringUtils.isBlank(src)) {
return src;
}
// 创建一个允许的HTML标签和属性的Safelist
Safelist safelist = Safelist.relaxed() // 允许大多数基本的HTML标签和属性
.addTags("img") // 添加额外的标签,如img(记得添加允许的属性,如src和alt)
.addAttributes("*", "class") // 允许所有标签使用"class"属性
.addAttributes("img", "src", "alt") // 允许img标签的src和alt属性
.addProtocols("img", "src", "http", "https") // 只允许http和https协议的src
; // 移除协议相对URL,避免安全问题
// 使用JSoup进行清理
Document document = Jsoup.parseBodyFragment(src, ""); // 解析HTML片段
document.outputSettings(new Document.OutputSettings().prettyPrint(false)); // 禁止美化输出,保持原始结构
String html = document.html();
String clean = Jsoup.clean(html, "", safelist);// 使用Safelist进行清理
return clean; // 返回清理后的HTML字符串
}
/**
* 清除xss
* @param src 单个参数
* @return
*/
/*public String cleanXSS(String src) {
if(StringUtils.isBlank(src)){
return src;
}
String temp = src;
// 校验xss脚本
for (Pattern pattern : scriptPatterns) {
temp = pattern.matcher(temp).replaceAll("");
}
// 校验xss特殊字符 匹配一个空白字符(包括空格、制表符、换页符和换行符等)//这个可以不用,因为有写数据用富文本编辑的时候有换行
// temp = temp.replaceAll("\0|\n|\r", "");
temp = temp.replaceAll("<", "<").replaceAll(">", ">");
if (!temp.equals(src)) {
log.error("xss攻击检查:参数含有非法攻击字符,已禁止继续访问!");
log.error("原始输入信息-->" + temp);
throw new BusinessException(BaseResponseCode.XSS_FILTER);
}
return src;
}*/
/**
* 过滤sql注入 -- 需要增加通配过滤大小写组合
* @param src 单个参数值
* @return
*/
public String cleanSQLInject(String src) {
if(StringUtils.isBlank(src)){
return src;
}
String cleanedText = Jsoup.clean(src, Safelist.basic());
String SQL_KEYWORD_PATTERN =
"(?i)(?:(?!<[^>]*?>))((select|update|insert|delete|drop|create|alter|exec|union|table|database)[^a-zA-Z0-9])";
// 过滤SQL关键字
cleanedText = cleanedText.replaceAll(SQL_KEYWORD_PATTERN, "");
// 非法sql注入正则
// Pattern sqlPattern = Pattern.compile(badStrReg, Pattern.CASE_INSENSITIVE);
// if (sqlPattern.matcher(src.toLowerCase()).find()) {
// log.error("sql注入检查:输入信息存在SQL攻击!");
// throw new BusinessException(BaseResponseCode.SQL_FILTER);
// }
return cleanedText;
}
}

@ -2,29 +2,40 @@ package com.huoran.iasf.common.shiro;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.huoran.iasf.common.exception.BusinessException; 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.exception.code.BaseResponseCode;
import com.huoran.iasf.common.utils.Constant; import com.huoran.iasf.common.utils.Constant;
import com.huoran.iasf.common.utils.R; import com.huoran.iasf.common.utils.R;
import com.huoran.iasf.common.utils.HttpContextUtils; import com.huoran.iasf.common.utils.HttpContextUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter; 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.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static com.huoran.iasf.service.HttpApiSessionService.*;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
/** /**
* 自定义过滤器 * shiro过滤器 登录用户权限认证授权
*
* @author cheney * @author cheney
* @version V1.0 * @version V1.0
* @date 2022年7月28日 * @date 2022年7月28日
@ -32,6 +43,21 @@ import java.nio.charset.StandardCharsets;
@Slf4j @Slf4j
public class CustomAccessControlFilter extends AccessControlFilter { 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 @Override
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) { protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) {
@ -41,7 +67,8 @@ public class CustomAccessControlFilter extends AccessControlFilter {
@Override @Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException { protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletRequest request = (HttpServletRequest) servletRequest;
try { // try {
HttpServletResponse response = (HttpServletResponse) servletResponse;
Subject subject = getSubject(servletRequest, servletResponse); Subject subject = getSubject(servletRequest, servletResponse);
System.out.println(subject.isAuthenticated() + ""); System.out.println(subject.isAuthenticated() + "");
System.out.println(HttpContextUtils.isAjaxRequest(request)); System.out.println(HttpContextUtils.isAjaxRequest(request));
@ -49,52 +76,48 @@ public class CustomAccessControlFilter extends AccessControlFilter {
log.info(request.getRequestURL().toString()); log.info(request.getRequestURL().toString());
//从header中获取token //从header中获取token
String token = request.getHeader(Constant.ACCESS_TOKEN); String token = request.getHeader(Constant.ACCESS_TOKEN);
System.out.println("token===============" + token);
//如果header中不存在token,则从参数中获取token //如果header中不存在token,则从参数中获取token
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
token = request.getParameter(Constant.ACCESS_TOKEN); token = request.getParameter(Constant.ACCESS_TOKEN);
} }
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
throw new BusinessException(BaseResponseCode.TOKEN_ERROR); 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);
} }
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(token, token); // 校验并解析token,如果token过期或者篡改,则会返回null
getSubject(servletRequest, servletResponse).login(usernamePasswordToken); Claims claims = checkJWT(token);
} catch (BusinessException exception) { if (null == claims) {
if (HttpContextUtils.isAjaxRequest(request)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
customResponse(exception.getBaseResponseCode().getCode(), exception.getMessage(), servletResponse); response.setCharacterEncoding("utf-8");
} else if (exception.getBaseResponseCode().getCode() == BaseResponseCode.TOKEN_ERROR.getCode()) { response.setContentType(MediaType.APPLICATION_JSON_VALUE);
servletRequest.getRequestDispatcher("/index/login").forward(servletRequest, servletResponse); request.setAttribute("filterError", new UnauthorizedException(BaseResponseCode.TOKEN_ERROR));
} else if (exception.getBaseResponseCode().getCode() == BaseResponseCode.UNAUTHORIZED_ERROR.getCode()) { // 指定处理该请求的处理器
servletRequest.getRequestDispatcher("/index/403").forward(servletRequest, servletResponse); request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, response);
}else { }else {
servletRequest.getRequestDispatcher("/index/500").forward(servletRequest, servletResponse); Subject subject1 = getSubject(servletRequest, servletResponse);
} UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(token, token);
return false; subject1.login(usernamePasswordToken);
} catch (AuthenticationException e) {
if (HttpContextUtils.isAjaxRequest(request)) {
if (e.getCause() instanceof BusinessException) {
BusinessException exception = (BusinessException) e.getCause();
customResponse(exception.getBaseResponseCode().getCode(), exception.getMessage(), servletResponse);
} else {
customResponse(BaseResponseCode.SYSTEM_BUSY.getCode(), BaseResponseCode.SYSTEM_BUSY.getMsg(), servletResponse);
} }
} else { return true;
servletRequest.getRequestDispatcher("/index/403").forward(servletRequest, servletResponse);
} }
return false;
/**
* 校验token
*/
public Claims checkJWT(String token) {
try {
final Claims claims = Jwts.parser().setSigningKey(APP_SECRET).
parseClaimsJws(token).getBody();
return claims;
} catch (Exception e) { } catch (Exception e) {
if (HttpContextUtils.isAjaxRequest(request)) { return null;
if (e.getCause() instanceof BusinessException) {
BusinessException exception = (BusinessException) e.getCause();
customResponse(exception.getBaseResponseCode().getCode(), exception.getMessage(), servletResponse);
} else {
customResponse(BaseResponseCode.SYSTEM_BUSY.getCode(), BaseResponseCode.SYSTEM_BUSY.getMsg(), servletResponse);
} }
} else {
servletRequest.getRequestDispatcher("/index/500").forward(servletRequest, servletResponse);
}
return false;
}
return true;
} }
private void customResponse(int code, String msg, ServletResponse response) { private void customResponse(int code, String msg, ServletResponse response) {

@ -31,7 +31,8 @@ public class CustomHashedCredentialsMatcher extends SimpleCredentialsMatcher {
String accessToken = (String) token.getPrincipal(); String accessToken = (String) token.getPrincipal();
if (!redisDb.exists(userTokenPrefix + accessToken)) { if (!redisDb.exists(userTokenPrefix + accessToken)) {
SecurityUtils.getSubject().logout(); SecurityUtils.getSubject().logout();
throw new BusinessException(BaseResponseCode.TOKEN_ERROR); // throw new BusinessException(BaseResponseCode.TOKEN_ERROR);
return false;
} }
return true; return true;
} }

@ -13,6 +13,7 @@ import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.realm.AuthorizingRealm;
@ -61,11 +62,12 @@ public class CustomRealm extends AuthorizingRealm {
String sessionInfoStr = redisDb.get(userTokenPrefix + principalCollection.getPrimaryPrincipal()); String sessionInfoStr = redisDb.get(userTokenPrefix + principalCollection.getPrimaryPrincipal());
if (StringUtils.isEmpty(sessionInfoStr)) { if (StringUtils.isEmpty(sessionInfoStr)) {
throw new BusinessException(BaseResponseCode.TOKEN_ERROR); // throw new BusinessException(BaseResponseCode.TOKEN_ERROR);
throw new AuthorizationException();
} }
JSONObject redisSession = JSON.parseObject(sessionInfoStr); JSONObject redisSession = JSON.parseObject(sessionInfoStr);
if (redisSession == null) { if (redisSession == null) {
throw new BusinessException(BaseResponseCode.TOKEN_ERROR); throw new AuthorizationException();
} }
if (redisSession.get(Constant.ROLES_KEY) != null) { if (redisSession.get(Constant.ROLES_KEY) != null) {

@ -1,7 +1,7 @@
/*
package com.huoran.iasf.common.shiro; package com.huoran.iasf.common.shiro;
import com.huoran.iasf.common.config.FileUploadProperties; import com.huoran.iasf.common.config.FileUploadProperties;
import com.huoran.iasf.common.filter.AuthFilter;
import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
@ -9,20 +9,21 @@ import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.Filter; import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
*/
/** /**
* ShiroConfig * ShiroConfig
* *
* @author cheney * @author cheney
* @version V1.0 * @version V1.0
* @date 2022年7月28日 * @date 2022年7月28日*/
*//*
@Configuration @Configuration
@EnableConfigurationProperties(FileUploadProperties.class) @EnableConfigurationProperties(FileUploadProperties.class)
@ -36,9 +37,8 @@ public class ShiroConfig {
return new CustomHashedCredentialsMatcher(); return new CustomHashedCredentialsMatcher();
} }
*/
/** /**
* 创建realm*//* * 创建realm*/
@Bean @Bean
public CustomRealm customRealm() { public CustomRealm customRealm() {
@ -56,7 +56,7 @@ public class ShiroConfig {
} }
@Bean /*@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
//整个shiro执行过程: 过滤器、认证、授权 //整个shiro执行过程: 过滤器、认证、授权
@ -70,8 +70,7 @@ public class ShiroConfig {
shiroFilterFactoryBean.setFilters(filtersMap); shiroFilterFactoryBean.setFilters(filtersMap);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 配置不会被拦截的链接 顺序判断 // 配置不会被拦截的链接 顺序判断
*/ *//* filterChainDefinitionMap.put("/sys/user/login", "anon");
/*filterChainDefinitionMap.put("/sys/user/login", "anon");
filterChainDefinitionMap.put("/sys/user/token", "anon"); filterChainDefinitionMap.put("/sys/user/token", "anon");
filterChainDefinitionMap.put("/sys/getVerify", "anon"); filterChainDefinitionMap.put("/sys/getVerify", "anon");
filterChainDefinitionMap.put("/sys/checkVerify", "anon"); filterChainDefinitionMap.put("/sys/checkVerify", "anon");
@ -94,22 +93,91 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/layui/**", "anon"); filterChainDefinitionMap.put("/layui/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/layui-ext/**", "anon"); filterChainDefinitionMap.put("/layui-ext/**", "anon");
filterChainDefinitionMap.put("/app/api/**", "anon");*//* filterChainDefinitionMap.put("/app/api/**", "anon");
filterChainDefinitionMap.put("/sys/getVerify", "anon"); filterChainDefinitionMap.put("/sys/getVerify", "anon");
filterChainDefinitionMap.put("/sys/user/login", "anon"); filterChainDefinitionMap.put("/sys/user/login", "anon");*//*
filterChainDefinitionMap.put("/**", "token,authc"); filterChainDefinitionMap.put("/**", "token,authc");
shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean; return shiroFilterFactoryBean;
}*/
@Bean
public ShiroFilterFactoryBean shirFilter() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSecurityManager(securityManager());
Map<String, Filter> filterMap = new HashMap<>();
// 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 :这是一个坑呢,一不小心代码就不好使了;
// ① authc:所有url都必须认证通过才可以访问; ② anon:所有url都都可以匿名访问
//过滤器1
filterMap.put("token", new AuthFilter());
//过滤器2
//用来校验token
filterMap.put("authc", new CustomAccessControlFilter());
shiroFilterFactoryBean.setFilters(filterMap);
Map<String, String> 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("/seo/list", "anon");
filterChainDefinitionMap.put("/sysContent/queryArticleColumnParent", "anon");
/*filterChainDefinitionMap.put("/index/**", "anon");
filterChainDefinitionMap.put("/iasf/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("/iasf/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注解支持. * 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持; * 使用代理方式;所以需要开启代码支持;
* *
* @return org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor*//* * @return org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor*/
@Bean @Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
@ -118,7 +186,5 @@ public class ShiroConfig {
return authorizationAttributeSourceAdvisor; return authorizationAttributeSourceAdvisor;
} }
} }
*/

@ -0,0 +1,31 @@
package com.huoran.iasf.common.utils;
import org.apache.commons.codec.binary.Base64;
/**
* Base64
* Author:Bobby
* DateTime:2019/4/9
**/
public class Base64Util{
/**
* Decoding to binary
* @param base64 base64
* @return byte
* @throws Exception Exception
*/
public static byte[] decode(String base64) throws Exception {
return Base64.decodeBase64(base64);
}
/**
* Binary encoding as a string
* @param bytes byte
* @return String
* @throws Exception Exception
*/
public static String encode(byte[] bytes) throws Exception {
return new String(Base64.encodeBase64(bytes));
}
}

@ -51,4 +51,35 @@ public class Constant {
public static final Integer ARTICLE_PUBLISHED = 1; public static final Integer ARTICLE_PUBLISHED = 1;
public static final Integer ARTICLE_NOT_PUBLISHED = 0; 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";
} }

@ -0,0 +1,30 @@
package com.huoran.iasf.common.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* @author imyzt
* @date 2020/06/08
* @description JSON 工具类
*/
public class JsonUtils {
private JsonUtils() {
}
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public static JsonNode getNode(String content, String key) throws IOException {
JsonNode jsonNode = OBJECT_MAPPER.readTree(content);
return jsonNode.get(key);
}
public static String writeValueAsString(Object body) throws JsonProcessingException {
return OBJECT_MAPPER.writeValueAsString(body);
}
}

@ -5,6 +5,8 @@ import com.huoran.iasf.common.exception.code.ResponseCodeInterface;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* 返回值R * 返回值R
* *
@ -13,7 +15,9 @@ import lombok.Data;
* @date 2022年7月28日 * @date 2022年7月28日
*/ */
@Data @Data
public class R { public class R implements Serializable {
// 类的内容
private static final long serialVersionUID = 1L;
/** /**
* 请求响应code0为成功 其他为失败 * 请求响应code0为成功 其他为失败

@ -0,0 +1,103 @@
package com.huoran.iasf.common.utils;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA Util
* Author:Bobby
* DateTime:2019/4/9
**/
public class RSAUtil{
/**
* encryption algorithm RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* RSA Maximum Encrypted Plaintext Size
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA Maximum decrypted ciphertext size
*/
private static final int MAX_DECRYPT_BLOCK = 256;
/**
* encryption
* @param data data
* @param publicKey publicKey
* @return byte
* @throws Exception Exception
*/
public static byte[] encrypt(byte[] data, String publicKey)
throws Exception {
byte[] keyBytes = Base64Util.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// Sectional Encryption of Data
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* Decrypt
* @param text text
* @param privateKey privateKey
* @return byte
* @throws Exception Exception
*/
public static byte[] decrypt(byte[] text, String privateKey)
throws Exception {
byte[] keyBytes = Base64Util.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = text.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// Sectional Encryption of Data
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(text, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(text, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
}

@ -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<SysColumn> getList(List<SysColumn> columns) {
try {
List<SysColumn> result = new ArrayList<>();
for (SysColumn test : columns) {
if (test.getFatherId() == 0) {
result.add(test);
}
}
for (SysColumn test : result) {
List<SysColumn> childList = getChildren(test.getId(), columns);
test.setChildren(childList);
}
// 将一层一层的树结构数据返回吧!
return result;
} catch (Exception e) {
// 这里可以抛个异常
}
return null;
}
//把一个List转成树
public static List<SysColumn> buildTree(List<SysColumn> list, Integer pid) {
List<SysColumn> 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<SysColumn> list) {
for (SysColumn n : list) {
if (Objects.equals(n.getFatherId(), node.getId())) {
if (node.getChildren() == null) {
node.setChildren(new ArrayList<SysColumn>());
}
node.getChildren().add(findChild(n, list));
}
}
return node;
}
public static List<SysColumn> getChildren(Integer id, List<SysColumn> allDept) {
//存放子节点
List<SysColumn> 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<SysColumn> forMethod(List<SysColumn> treeList) {
List<SysColumn> 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;
}
}

@ -0,0 +1,119 @@
package com.huoran.iasf.common.utils;
import com.huoran.iasf.common.exception.BusinessException;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import static com.huoran.iasf.common.exception.code.BaseResponseCode.UPLOAD_FAILED;
/**
* 文件上传校验工具类
**/
public class fileUploadUtils {
// 缓存文件魔数值
public static final HashMap<String, String> mFileTypes = new HashMap<String, String>();
static {
mFileTypes.put("FFD8FFE0", "jpg");
mFileTypes.put("89504E47", "png");
mFileTypes.put("47494638", "gif");
// mFileTypes.put("49492A00", "tif");
// mFileTypes.put("424D", "bmp");
// mFileTypes.put("38425053", "psd");
// mFileTypes.put("3C3F786D6C", "xml");
// mFileTypes.put("68746D6C3E", "html");
mFileTypes.put("D0CF11E0", "doc");
mFileTypes.put("D0CF11E0", "xls");//excel2003版本文件
mFileTypes.put("6D6F6F76", "mov");
mFileTypes.put("504B0304", "xlsx");//excel2007以上版本文件
// mFileTypes.put("5374616E64617264204A", "mdb");
mFileTypes.put("255044462D312E", "pdf");
mFileTypes.put("504B0304", "docx");
mFileTypes.put("00000020667479706D70","MP4");
mFileTypes.put("49443303000000002176","MP3");
// mFileTypes.put("52617221", "rar");
// mFileTypes.put("41564920", "avi");
}
/**
* 文件上传校验
*
* @param file 上传的文件
* @param allowedExtension 允许上传的文件后缀集合
* @throws Exception
*/
public static final void assertAllowed(MultipartFile file, String[] allowedExtension) throws Exception {
//通过文件魔数获取文件的原始类型
String fileExtension = mFileTypes.get(getFileHeader(file));
//原始类型与允许类型集合进行比较,判断文件是否合法
if (!isAllowedExtension(fileExtension, allowedExtension)) {
throw new BusinessException(UPLOAD_FAILED);
}
}
/**
* 获取文件魔数值
*
* @param file
* @return
*/
public static String getFileHeader(MultipartFile file) {
InputStream is = null;
String value = null;
try {
is = file.getInputStream();
byte[] b = new byte[4];
is.read(b, 0, b.length);
value = bytesToHexString(b);
} catch (Exception e) {
} finally {
if (null != is) {
try {
is.close();
} catch (IOException e) {
}
}
}
return value;
}
private static String bytesToHexString(byte[] src) {
StringBuilder builder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
String hv;
for (int i = 0; i < src.length; i++) {
hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
if (hv.length() < 2) {
builder.append(0);
}
builder.append(hv);
}
System.out.println("文件魔数值为:" + builder.toString());
return builder.toString();
}
/**
* 判断MIME类型是否是允许的MIME类型
*
* @param extension
* @param allowedExtension
* @return
*/
public static final boolean isAllowedExtension(String extension, String[] allowedExtension) {
for (String str : allowedExtension) {
if (str.equalsIgnoreCase(extension)) {
return true;
}
}
return false;
}
}

@ -1,6 +1,8 @@
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import com.huoran.iasf.common.annotation.Decrypt;
import com.huoran.iasf.common.aop.annotation.LogAnnotation; 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.common.utils.R;
import com.huoran.iasf.entity.SysDept; import com.huoran.iasf.entity.SysDept;
import com.huoran.iasf.service.DeptService; import com.huoran.iasf.service.DeptService;
@ -15,6 +17,9 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
/** /**
* 部门管理 * 部门管理
@ -29,12 +34,19 @@ import javax.validation.Valid;
public class DeptController { public class DeptController {
@Resource @Resource
private DeptService deptService; private DeptService deptService;
@NoRepeatSubmit
@Decrypt
@PostMapping("/dept") @PostMapping("/dept")
@ApiOperation(value = "新增组织接口") @ApiOperation(value = "新增组织接口")
@LogAnnotation(title = "机构管理", action = "新增组织") @LogAnnotation(title = "机构管理", action = "新增组织")
@RequiresPermissions("sys:dept:add") @RequiresPermissions("sys:dept:add")
public R addDept(@RequestBody @Valid SysDept vo) { public R addDept(@RequestBody @Valid SysDept vo) throws UnsupportedEncodingException {
//中文转码
String name = URLDecoder.decode(vo.getName(), StandardCharsets.UTF_8.toString());
vo.setName(name);
String pidName = URLDecoder.decode(vo.getPidName(), StandardCharsets.UTF_8.toString());
vo.setPidName(pidName);
boolean ok = deptService.checkDeptRepeat(vo); boolean ok = deptService.checkDeptRepeat(vo);
if (ok) { if (ok) {
return R.fail("同级下已存在相同的名称:" + vo.getName()); return R.fail("同级下已存在相同的名称:" + vo.getName());
@ -43,23 +55,31 @@ public class DeptController {
return R.success(); return R.success();
} }
@DeleteMapping("/dept/{id}") @PostMapping("/deleteDept")
@ApiOperation(value = "删除组织接口") @ApiOperation(value = "删除组织接口")
@Decrypt
@LogAnnotation(title = "机构管理", action = "删除组织") @LogAnnotation(title = "机构管理", action = "删除组织")
@RequiresPermissions("sys:dept:deleted") @RequiresPermissions("sys:dept:deleted")
public R deleted(@PathVariable("id") String id) { public R deleted(@RequestBody String id) {
deptService.deleted(id); deptService.deleted(id);
return R.success(); return R.success();
} }
@PutMapping("/dept") @PostMapping("/updateDept")
@Decrypt
@ApiOperation(value = "更新组织信息接口") @ApiOperation(value = "更新组织信息接口")
@LogAnnotation(title = "机构管理", action = "更新组织信息") @LogAnnotation(title = "机构管理", action = "更新组织信息")
@RequiresPermissions("sys:dept:update") @RequiresPermissions("sys:dept:update")
public R updateDept(@RequestBody SysDept vo) { public R updateDept(@RequestBody SysDept vo) throws UnsupportedEncodingException {
if (StringUtils.isEmpty(vo.getId())) { if (StringUtils.isEmpty(vo.getId())) {
return R.fail("id不能为空"); return R.fail("id不能为空");
} }
//中文转码
String name = URLDecoder.decode(vo.getName(), StandardCharsets.UTF_8.toString());
vo.setName(name);
String pidName = URLDecoder.decode(vo.getPidName(), StandardCharsets.UTF_8.toString());
vo.setPidName(pidName);
boolean ok = deptService.checkDeptRepeat(vo); boolean ok = deptService.checkDeptRepeat(vo);
if (ok) { if (ok) {
return R.fail("同级下已存在相同的名称:" + vo.getName()); return R.fail("同级下已存在相同的名称:" + vo.getName());
@ -71,7 +91,7 @@ public class DeptController {
@GetMapping("/dept/{id}") @GetMapping("/dept/{id}")
@ApiOperation(value = "查询组织详情接口") @ApiOperation(value = "查询组织详情接口")
@LogAnnotation(title = "机构管理", action = "查询组织详情") @LogAnnotation(title = "机构管理", action = "查询组织详情")
@RequiresPermissions("sys:dept:detail") // @RequiresPermissions("sys:dept:detail")
public R detailInfo(@PathVariable("id") String id) { public R detailInfo(@PathVariable("id") String id) {
return R.success(deptService.getById(id)); return R.success(deptService.getById(id));
} }

@ -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");
}
}

@ -53,7 +53,7 @@ public class PermissionController {
@GetMapping("/permission/tree/all") @GetMapping("/permission/tree/all")
@ApiOperation(value = "获取所有目录菜单树接口") @ApiOperation(value = "获取所有目录菜单树接口")
@LogAnnotation(title = "菜单权限管理", action = "获取所有目录菜单树") @LogAnnotation(title = "菜单权限管理", action = "获取所有目录菜单树")
@RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR) // @RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR)
public R getAllPermissionTree() { public R getAllPermissionTree() {
return R.success(permissionService.selectAllByTree()); return R.success(permissionService.selectAllByTree());
} }

@ -3,7 +3,9 @@ package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huoran.iasf.common.annotation.Decrypt;
import com.huoran.iasf.common.aop.annotation.LogAnnotation; 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.common.utils.R;
import com.huoran.iasf.entity.SysRole; import com.huoran.iasf.entity.SysRole;
import com.huoran.iasf.entity.SysRolePermission; import com.huoran.iasf.entity.SysRolePermission;
@ -21,6 +23,9 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -42,8 +47,8 @@ public class RoleController {
private RolePermissionService rolePermissionService; private RolePermissionService rolePermissionService;
@Resource @Resource
private HttpSessionService httpSessionService; private HttpSessionService httpSessionService;
@NoRepeatSubmit
@PostMapping("/role") @PostMapping("/addRole")
@ApiOperation(value = "新增角色接口") @ApiOperation(value = "新增角色接口")
@LogAnnotation(title = "角色管理", action = "新增角色") @LogAnnotation(title = "角色管理", action = "新增角色")
@RequiresPermissions("sys:role:add") @RequiresPermissions("sys:role:add")
@ -66,16 +71,17 @@ public class RoleController {
return R.success(); return R.success();
} }
@DeleteMapping("/role/deleted") @PostMapping("/role/deleted")
@ApiOperation(value = "删除角色接口") @ApiOperation(value = "删除角色接口")
@Decrypt
@LogAnnotation(title = "角色管理", action = "删除角色") @LogAnnotation(title = "角色管理", action = "删除角色")
@RequiresPermissions("sys:role:deleted") @RequiresPermissions("sys:role:deleted")
public R deleted(@RequestBody @ApiParam(value = "id集合") List<Integer> ids) { public R deleted(@RequestBody @ApiParam(value = "id集合") List<String> ids) {
roleService.deletedRole(ids); roleService.deletedRole(ids);
return R.success(); return R.success();
} }
@PutMapping("/role") @PostMapping("/updateRole")
@ApiOperation(value = "更新角色信息接口") @ApiOperation(value = "更新角色信息接口")
@LogAnnotation(title = "角色管理", action = "更新角色信息") @LogAnnotation(title = "角色管理", action = "更新角色信息")
@RequiresPermissions("sys:role:update") @RequiresPermissions("sys:role:update")
@ -91,11 +97,12 @@ public class RoleController {
return R.success(); return R.success();
} }
@GetMapping("/role/{id}") @PostMapping("/role")
@Decrypt
@ApiOperation(value = "查询角色详情接口") @ApiOperation(value = "查询角色详情接口")
@LogAnnotation(title = "角色管理", action = "查询角色详情") @LogAnnotation(title = "角色管理", action = "查询角色详情")
@RequiresPermissions("sys:role:detail") @RequiresPermissions("sys:role:detail")
public R detailInfo(@PathVariable("id") String id) { public R detailInfo(@RequestBody Integer id) {
// return R.success(roleService.detailInfo(id)); // return R.success(roleService.detailInfo(id));
SysRole role = roleService.getById(id); SysRole role = roleService.getById(id);
QueryWrapper<SysRolePermission> wrapper = new QueryWrapper<>(); QueryWrapper<SysRolePermission> wrapper = new QueryWrapper<>();
@ -112,11 +119,17 @@ public class RoleController {
} }
@PostMapping("/roles") @PostMapping("/roles")
@Decrypt
@ApiOperation(value = "分页获取角色信息接口") @ApiOperation(value = "分页获取角色信息接口")
@LogAnnotation(title = "角色管理", action = "分页获取角色信息") @LogAnnotation(title = "角色管理", action = "分页获取角色信息")
@RequiresPermissions("sys:role:list") @RequiresPermissions("sys:role:list")
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public R pageInfo(@RequestBody SysRole vo) { public R pageInfo(@RequestBody SysRole vo) throws UnsupportedEncodingException {
if (!StringUtils.isEmpty(vo.getName())) {
//中文转码
String name = URLDecoder.decode(vo.getName(), StandardCharsets.UTF_8.toString());
vo.setName(name);
}
LambdaQueryWrapper<SysRole> queryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<SysRole> queryWrapper = Wrappers.lambdaQuery();
if (!StringUtils.isEmpty(vo.getName())) { if (!StringUtils.isEmpty(vo.getName())) {
queryWrapper.like(SysRole::getName, vo.getName()); queryWrapper.like(SysRole::getName, vo.getName());

@ -33,7 +33,7 @@ public class RolePermissionController {
@PostMapping("/role/permission") @PostMapping("/role/permission")
@ApiOperation(value = "修改或者新增角色菜单权限接口") @ApiOperation(value = "修改或者新增角色菜单权限接口")
@LogAnnotation(title = "角色和菜单关联接口", action = "修改或者新增角色菜单权限") @LogAnnotation(title = "角色和菜单关联接口", action = "修改或者新增角色菜单权限")
@RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR) // @RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR)
public R operationRolePermission(@RequestBody @Valid RolePermissionOperationReqVO vo) { public R operationRolePermission(@RequestBody @Valid RolePermissionOperationReqVO vo) {
rolePermissionService.addRolePermission(vo); rolePermissionService.addRolePermission(vo);
return R.success(); return R.success();

@ -0,0 +1,76 @@
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.Seo;
import com.huoran.iasf.entity.Site;
import com.huoran.iasf.service.SeoService;
import com.huoran.iasf.service.SiteService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author cheney
* @since 2023-08-24
*/
@Api(tags = "seo管理")
@RestController
@RequestMapping("/seo")
public class SeoController {
@Autowired
private SeoService seoService;
@PostMapping("/add")
@ApiOperation(value = "新增seo")
public R addUserGroup(@RequestBody Seo seo) {
Seo one = seoService.getOne(new QueryWrapper<Seo>().
eq("title", seo.getTitle()));
if (ObjectUtil.isNotNull(one)){
R.fail("seo已存在");
}
boolean save = seoService.save(seo);
return save ? R.success() : R.fail("添加失败");
}
@PostMapping("/delete")
@ApiOperation(value = "删除seo")
public R deleted(@RequestParam Integer id) {
boolean remove = seoService.removeById(id);
return remove ? R.success() : R.fail("删除失败");
}
@PostMapping("/update")
@ApiOperation(value = "更新seo")
public R update(@RequestBody Seo seo) {
boolean update = seoService.updateById(seo);
return update ? R.success() : R.fail("更新失败");
}
@GetMapping("/list")
@ApiOperation(value = "站点seo列表")
public R list(@RequestParam Integer siteId) {
QueryWrapper<Seo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("site_id",siteId);
List<Seo> list = seoService.list(queryWrapper);
return R.success(list);
}
}

@ -35,9 +35,9 @@ public class SiteController {
private SiteService siteService; private SiteService siteService;
@PostMapping("/add") @PostMapping("/add")
@ApiOperation(value = "新增站点") // @ApiOperation(value = "新增站点")
@LogAnnotation(title = "站点管理", action = "新增站点") // @LogAnnotation(title = "站点管理", action = "新增站点")
@RequiresPermissions("sys:site:add") // @RequiresPermissions("sys:site:add")
public R addUserGroup(@RequestBody Site site) { public R addUserGroup(@RequestBody Site site) {
Site one = siteService.getOne(new QueryWrapper<Site>(). Site one = siteService.getOne(new QueryWrapper<Site>().
eq("site_name", site.getSiteName())); eq("site_name", site.getSiteName()));
@ -49,18 +49,18 @@ public class SiteController {
} }
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
@ApiOperation(value = "删除站点") // @ApiOperation(value = "删除站点")
@LogAnnotation(title = "站点管理", action = "删除站点") // @LogAnnotation(title = "站点管理", action = "删除站点")
@RequiresPermissions("sys:site:deleted") // @RequiresPermissions("sys:site:deleted")
public R deleted(@PathVariable("id") Integer id) { public R deleted(@PathVariable("id") Integer id) {
siteService.removeById(id); siteService.removeById(id);
return R.success(); return R.success();
} }
@PutMapping("/update") @PutMapping("/update")
@ApiOperation(value = "更新站点") // @ApiOperation(value = "更新站点")
@LogAnnotation(title = "站点管理", action = "更新站点") // @LogAnnotation(title = "站点管理", action = "更新站点")
@RequiresPermissions("sys:site:update") // @RequiresPermissions("sys:site:update")
public R updateUserGroup(@RequestBody Site site) { public R updateUserGroup(@RequestBody Site site) {
if (StringUtils.isEmpty(site.getId())) { if (StringUtils.isEmpty(site.getId())) {
return R.fail("id不能为空"); return R.fail("id不能为空");
@ -80,7 +80,7 @@ public class SiteController {
@PostMapping("/list") @PostMapping("/list")
@ApiOperation(value = "站点列表") @ApiOperation(value = "站点列表")
@LogAnnotation(title = "站点管理", action = "获取所有站点") @LogAnnotation(title = "站点管理", action = "获取所有站点")
@RequiresPermissions("sys:site:list") // @RequiresPermissions("sys:site:list")
public R getUserGroupAll(@RequestBody Site site) { public R getUserGroupAll(@RequestBody Site site) {
LambdaQueryWrapper<Site> queryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<Site> queryWrapper = Wrappers.lambdaQuery();
if (!StringUtils.isEmpty(site.getSiteName())) { if (!StringUtils.isEmpty(site.getSiteName())) {

@ -2,17 +2,27 @@ package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.huoran.iasf.entity.ColumnEntity; import com.huoran.iasf.common.annotation.Decrypt;
import com.huoran.iasf.entity.SysColumn; import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit;
import com.huoran.iasf.entity.SysContent; import com.huoran.iasf.common.exception.NotFoundException;
import com.huoran.iasf.service.SysContentService; 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.ColumnWeightReqVO;
import com.huoran.iasf.vo.req.OneLevelChecksThemAll;
import com.huoran.iasf.vo.req.PaginationColumnReqVO; import com.huoran.iasf.vo.req.PaginationColumnReqVO;
import com.huoran.iasf.vo.req.SubLevelColumnsUnderALevel;
import com.huoran.iasf.vo.resp.SortColumnRespVO; import com.huoran.iasf.vo.resp.SortColumnRespVO;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import com.huoran.iasf.common.utils.R; import com.huoran.iasf.common.utils.R;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -20,11 +30,17 @@ import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import com.huoran.iasf.service.SysColumnService;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
@ -43,70 +59,329 @@ public class SysColumnController {
@Autowired @Autowired
public SysContentService contentService; 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") @PostMapping("/listWithTree")
@Decrypt
@ApiOperation(value = "栏目树结构", response = SysColumn.class) @ApiOperation(value = "栏目树结构", response = SysColumn.class)
public R listWithTree(@RequestBody @Valid PaginationColumnReqVO sysColumn) { public R listWithTree(@RequestBody @Valid PaginationColumnReqVO sysColumn) throws UnsupportedEncodingException {
if (!StringUtils.isEmpty(sysColumn.getColumnName())) {
String columnName = URLDecoder.decode(sysColumn.getColumnName(), StandardCharsets.UTF_8.toString());
sysColumn.setColumnName(columnName);
}
return R.success(service.listWithTree(sysColumn)); return R.success(service.listWithTree(sysColumn));
} }
@PostMapping("/listWithTreeMenuVisible")
@Decrypt
@ApiOperation(value = "栏目树结构(前台可见,只展示试单可见的栏目)", response = SysColumn.class)
public R listWithTreeMenuVisible(@RequestBody @Valid PaginationColumnReqVO sysColumn) {
return R.success(service.listWithTreeMenuVisible(sysColumn));
}
@PostMapping("/findById") @PostMapping("/findById")
@Decrypt
@ApiOperation(value = "查询详情", response = SysColumn.class) @ApiOperation(value = "查询详情", response = SysColumn.class)
public R findById(@RequestParam("id") @ApiParam(value = "序号") Integer id) { public R findById(@RequestBody @ApiParam(value = "序号") Integer id) {
SysColumn sysColumn = service.getById(id); SysColumn sysColumn = service.getById(id);
return R.success(sysColumn); 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") @PostMapping("/save")
@ApiOperation(value = "新增", response = SysColumn.class) @ApiOperation(value = "新增", response = SysColumn.class)
@RequiresPermissions("sys:column:save")
public R save(@RequestBody @Valid SysColumn sysColumn) { public R save(@RequestBody @Valid SysColumn sysColumn) {
QueryWrapper<SysColumn> queryWrapper = new QueryWrapper<SysColumn>();
queryWrapper.eq("father_id", sysColumn.getFatherId());
Integer count = service.count(queryWrapper);
sysColumn.setSort(count + 1);
boolean addState = service.save(sysColumn); boolean addState = service.save(sysColumn);
return addState ? R.success() : R.fail("新增失败"); return addState ? R.success(sysColumn.getId()) : R.fail("新增失败");
} }
@PostMapping("/update") @PostMapping("/update")
@ApiOperation(value = "修改", response = SysColumn.class) @ApiOperation(value = "修改", response = SysColumn.class)
@RequiresPermissions("sys:column:update")
public R update(@RequestBody SysColumn sysColumn) { public R update(@RequestBody SysColumn sysColumn) {
boolean updateState = service.updateById(sysColumn); boolean updateState = service.updateById(sysColumn);
service.removeArticles(sysColumn.getId());
return updateState ? R.success() : R.fail("编辑失败"); return updateState ? R.success() : R.fail("编辑失败");
} }
/*@NoRepeatSubmit
@PostMapping("/delete") @PostMapping("/delete")
@ApiOperation(value = "删除", response = SysContent.class) @ApiOperation(value = "删除", response = SysContent.class)
public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) {
UpdateWrapper<SysFilesEntity> 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); boolean delState = service.removeById(id);
QueryWrapper<SysContent> queryWrapper = new QueryWrapper<>();
queryWrapper.in("column_id", id);
//删除栏目后删除栏目下的文章
List<SysContent> contentId = contentService.list(queryWrapper);
contentService.removeByIds(contentId);
return delState ? R.success() : R.fail("删除失败"); return delState ? R.success() : R.fail("删除失败");
}*/
@NoRepeatSubmit
@Decrypt
@PostMapping("/batchDeletion")
@ApiOperation(value = "批量删除栏目", response = SysColumn.class)
@RequiresPermissions("sys:column:batchDeletion")
public R batchDeletion(@ApiParam(name = "ids", value = "主键", required = true) @RequestBody List<Integer> ids) {
boolean ret = false;
for (Integer id : ids) {
UpdateWrapper<SysFilesEntity> 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<Integer> idList = new ArrayList<>();
//2 向idList集合设置删除菜单id
//找到当前菜单的子菜单 把结果id封装到idlist里面去
this.selectCategoryChildById(id + "", idList);
//把当前id封装到list里面 //现在把当前id封装进去 之前都是子菜单的id
idList.add(id);
//删除当前栏目以及栏目下的文章
QueryWrapper<SysContent> queryWrapper = new QueryWrapper<>();
queryWrapper.in("column_id", idList);
//删除栏目后删除栏目下的文章
contentService.remove(queryWrapper);
//删除长页栏目
QueryWrapper<SysColumnLongPage> queryWrapper1 = new QueryWrapper<SysColumnLongPage>();
queryWrapper1.in("column_id", idList);
//删除栏目后删除栏目下的文章
sysColumnLongPageService.remove(queryWrapper1);
ret = service.removeByIds(idList);
for (Integer columnId : idList) {
service.removeArticles(columnId);
}
}
return R.success();
} }
@PostMapping("/sameLevelJudgment") @PostMapping("/sameLevelJudgment")
@Decrypt
@ApiOperation(value = "同级判重", response = ColumnWeightReqVO.class) @ApiOperation(value = "同级判重", response = ColumnWeightReqVO.class)
public R sameLevelJudgment(@RequestBody @Valid ColumnWeightReqVO sysColumn) { public R sameLevelJudgment(@RequestBody @Valid ColumnWeightReqVO sysColumn) throws UnsupportedEncodingException {
if (!StringUtils.isEmpty(sysColumn.getColumnName())) {
//中文转码
String name = URLDecoder.decode(sysColumn.getColumnName(), StandardCharsets.UTF_8.toString());
sysColumn.setColumnName(name);
}
return service.sameLevelJudgment(sysColumn) ? R.success() : R.fail("同级下已存在重复栏目!"); return service.sameLevelJudgment(sysColumn) ? R.success() : R.fail("同级下已存在重复栏目!");
} }
@PostMapping("/sortByColumn") @PostMapping("/sortByColumn")
@ApiOperation(value = "栏目排序(依据id更改)", response = SysColumn.class) @ApiOperation(value = "栏目排序(依据id更改)", response = SysColumn.class)
@RequiresPermissions("sys:column:sort")
public R sortByColumn(@RequestBody List<SortColumnRespVO> sortColumnRespVOList) { public R sortByColumn(@RequestBody List<SortColumnRespVO> sortColumnRespVOList) {
for (SortColumnRespVO sort : sortColumnRespVOList) { for (SortColumnRespVO sort : sortColumnRespVOList) {
SysColumn column = service.getById(sort.getId());
QueryWrapper<SysColumn> 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<SysColumn> columnList = service.list(queryWrapper);
if (columnList.size() > 0) {
return R.fail("同级下已存在重复栏目:" + column.getColumnName());
}
SysColumn sysColumn = new SysColumn(); SysColumn sysColumn = new SysColumn();
BeanUtils.copyProperties(sort, sysColumn); BeanUtils.copyProperties(sort, sysColumn);
service.updateById(sysColumn); service.updateById(sysColumn);
//依据当前循环获取的栏目id,查询到引用当前栏目的文章对其进行修改栏目id
QueryWrapper<SysContent> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("column_id", sysColumn.getId());
List<SysContent> contentList = contentService.list(queryWrapper);
if (contentList.size() > 0) {
for (SysContent content : contentList) {
UpdateWrapper<SysContent> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("column_id", sysColumn.getId());
contentService.update(content, updateWrapper);
} }
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("获取某层级下的子级栏目")
@Decrypt
@PostMapping("/getsSublevelColumnsUnderALevel")
public R getsSublevelColumnsUnderALevel(
@RequestBody SubLevelColumnsUnderALevel subLevelColumnsUnderALevel) {
String ids = this.getIds(subLevelColumnsUnderALevel.getId());
return service.getsTheSubColumn(subLevelColumnsUnderALevel.getId(), ids,subLevelColumnsUnderALevel.getSiteId());
}
// @Cacheable(value = "articles", key = "#id")
public String getIds(Integer id) {
//1 创建list集合,用于封装所有删除菜单id值
List<Integer> 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<Integer> idList) {
//查询菜单里面子菜单id
QueryWrapper<SysColumn> wrapper = new QueryWrapper<SysColumn>();
wrapper.eq("father_id", id);
wrapper.eq("deleted", Constant.DATA_NOT_DELETED);
//查询指定列的值
wrapper.select("id");
//当前菜单的所有子菜单
List<SysColumn> childIdList = service.list(wrapper);
//把childIdList里面菜单id值获取出来,封装idList里面,做递归查询
//遍历集合得到每一个对象item
childIdList.stream().forEach(item -> {
//封装idList里面
idList.add(item.getId());
//递归查询
this.selectCategoryChildById(item.getId() + "", idList);
});
}
@ApiOperation("获取一级下的子级栏目以及下的全部文章标签")
@Decrypt
@PostMapping("/getTheFullArticleByColumn")
public R getTheFullArticleByColumn(
@ApiParam(name = "id", value = "一级栏目id", required = true)
@RequestBody 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<Integer> idList = new ArrayList<>();
//2 向idList集合设置删除菜单id
this.selectCategoryChildById(id + "", idList);//找到当前菜单的子菜单 把结果id封装到idlist里面去
//把当前id封装到list里面
idList.add(id);//现在把当前id封装进去 之前都是子菜单的id
return R.success(idList);
}
@ApiOperation("某一级查全部")
@Decrypt
@PostMapping("/oneLevelChecksThemAll")
public R oneLevelChecksThemAll(
@RequestBody OneLevelChecksThemAll oneLevelChecksThemAll) {
Integer pid = service.oneLevelChecksThemAll(oneLevelChecksThemAll.getId());
String ids = this.getIds(pid);
return service.getSubColumn(pid, ids, oneLevelChecksThemAll.getIsSort(),oneLevelChecksThemAll.getSiteId());
}
/**
* 查询栏目下的文章(若选中栏目与子级全部栏目类型一致返回全部文章反之查询选中栏目下的文章)
* 2023.02.22依需求更改为以发布时间排序(非创建时间)
*
* @param columnId
* @return
*/
@ApiOperation("查询栏目下的文章(若选中栏目与子级全部栏目类型一致返回全部文章,反之查询选中栏目下的文章)")
@Decrypt
@PostMapping("/queryArticlesByColumnType")
public R queryArticlesByColumnType(
@ApiParam(name = "columnId", value = "栏目id", required = true)
@RequestBody Integer columnId) {
String ids = this.getIds(columnId);
return service.queryArticlesByColumnType(ids, columnId);
} }
@NoRepeatSubmit
@PostMapping("/deleteUselessData")
@ApiOperation(value = "删除无用数据", response = SysColumn.class)
public R deleteUselessData() {
QueryWrapper<SysColumn> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("deleted", 0).select("id");
List<SysColumn> list = service.list(queryWrapper);
for (SysColumn column : list) {
UpdateWrapper<SysFilesEntity> 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<Integer> idList = new ArrayList<>();
//2 向idList集合设置删除菜单id
//找到当前菜单的子菜单 把结果id封装到idlist里面去
this.selectCategoryChildById(column.getId() + "", idList);
//把当前id封装到list里面 //现在把当前id封装进去 之前都是子菜单的id
idList.add(column.getId());
//删除当前栏目以及栏目下的文章
QueryWrapper<SysContent> queryWrapper1 = new QueryWrapper<>();
queryWrapper1.in("column_id", idList);
//删除栏目后删除栏目下的文章
contentService.remove(queryWrapper1);
//删除长页栏目
QueryWrapper<SysColumnLongPage> queryWrapper2 = new QueryWrapper<SysColumnLongPage>();
queryWrapper2.in("column_id", idList);
//删除栏目后删除栏目下的文章
sysColumnLongPageService.remove(queryWrapper2);
service.removeByIds(idList);
} }
return R.success(); return R.success();
} }
} }

@ -1,10 +1,20 @@
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huoran.iasf.common.annotation.Decrypt;
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 io.swagger.annotations.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huoran.iasf.common.utils.R; import com.huoran.iasf.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.lang.StringUtils; 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.*;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -18,6 +28,8 @@ import com.huoran.iasf.service.SysColumnLongPageService;
import com.huoran.iasf.entity.SysColumnLongPage; import com.huoran.iasf.entity.SysColumnLongPage;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
@ -32,19 +44,49 @@ public class SysColumnLongPageController {
@Autowired @Autowired
public SysColumnLongPageService service; public SysColumnLongPageService service;
@Autowired
public SysColumnService columnService;
@Autowired
private StringRedisTemplate redisTemplate;
@PostMapping("/findById") @PostMapping("/findById")
@ApiOperation(value = "查询详情", response = SysColumnLongPage.class) @ApiOperation(value = "查询详情", response = SysColumnLongPage.class)
public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) {
SysColumnLongPage sysColumnLongPage = service.getById(id); SysColumnLongPage sysColumnLongPage = service.getById(id);
if (sysColumnLongPage == null) {
throw new NotFoundException(BaseResponseCode.DATA_DOES_NOT_EXIST);
}
return R.success(sysColumnLongPage); return R.success(sysColumnLongPage);
} }
@PostMapping("/getLongPageInformation")
@Decrypt
@ApiOperation(value = "根据栏目id查询类型长页栏目信息", response = SysColumnLongPage.class)
public R getLongPageInformation(
@ApiParam(name = "columnId", value = "栏目id", required = true)
@RequestBody Integer columnId) {
QueryWrapper<SysColumnLongPage> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("column_id", columnId);
List<SysColumnLongPage> longPageList = service.list(queryWrapper);
return R.success(longPageList);
}
@PostMapping("/save") @PostMapping("/save")
@ApiOperation(value = "新增", response = SysColumnLongPage.class) @ApiOperation(value = "新增", response = SysColumnLongPage.class)
public R save(@RequestBody @Valid @ApiParam(name = "长页栏目拓展表对象", value = "传入json格式", required = true) SysColumnLongPage sysColumnLongPage) { 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); boolean addState = service.save(sysColumnLongPage);
return addState ? R.success() : R.fail("新增失败"); return addState ? R.success() : R.fail("新增失败");
} }
@ -53,6 +95,16 @@ public class SysColumnLongPageController {
@PostMapping("/update") @PostMapping("/update")
@ApiOperation(value = "修改", response = SysColumnLongPage.class) @ApiOperation(value = "修改", response = SysColumnLongPage.class)
public R update(@RequestBody @ApiParam(name = "长页栏目拓展表对象", value = "传入json格式", required = true) SysColumnLongPage sysColumnLongPage) { 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); boolean updateState = service.updateById(sysColumnLongPage);
return updateState ? R.success() : R.fail("编辑失败"); return updateState ? R.success() : R.fail("编辑失败");
} }
@ -64,5 +116,37 @@ public class SysColumnLongPageController {
boolean delState = service.removeById(id); boolean delState = service.removeById(id);
return delState ? R.success() : R.fail("删除失败"); 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")
@Decrypt
@ApiOperation(value = "获取Redis缓存")
public R getRedisCache(
@ApiParam(name = "columnId", value = "栏目id主键", required = true)
@RequestBody Integer columnId) {
//保存的key名
String key = "saveTheCache:columnId:" + columnId;
//查看缓存是否有数据
String returnValue = redisTemplate.opsForValue().get(key);
//使用缓存返回数据
if (returnValue != null) {
return R.success(returnValue);
}
return R.success();
}
} }

@ -0,0 +1,132 @@
package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huoran.iasf.common.annotation.Decrypt;
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 com.huoran.iasf.vo.req.AllTheQuery;
import com.huoran.iasf.vo.req.CheckForHeavy;
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.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
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")
@Decrypt
@ApiOperation(value = "查询全部文章所属分类", response = SysContentClassification.class)
public R allTheQuery(
@RequestBody AllTheQuery allTheQuery) {
List<SysContentClassification> list = service.list(new QueryWrapper<SysContentClassification>()
.eq("site_id", allTheQuery.getSiteId()).eq("template_id",allTheQuery.getTemplateId()));
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")
@Decrypt
@ApiOperation(value = "分类校验判重", response = SysContentClassification.class)
public R checkForHeavy(
@RequestBody CheckForHeavy checkForHeavy) throws UnsupportedEncodingException {
String name = URLDecoder.decode(checkForHeavy.getClassificationName(), StandardCharsets.UTF_8.toString());
checkForHeavy.setClassificationName(name);
QueryWrapper<SysContentClassification> queryWrapper = new QueryWrapper<SysContentClassification>().eq("site_id", checkForHeavy.getSiteId()).
eq("classification_name", checkForHeavy.getClassificationName());
//id不得空表示编辑校验
if (checkForHeavy.getClassificationId() != null) {
queryWrapper.last(" and id != " + checkForHeavy.getClassificationId());
}
SysContentClassification sysContentClassification = service.getOne(queryWrapper);
if (sysContentClassification != null) {
return R.fail("当前分类名称已存在!");
}
return R.success();
}
@PostMapping("/save")
@Decrypt
@ApiOperation(value = "新增", response = SysContentClassification.class)
public R save(@RequestBody @Valid @ApiParam(name = "文章所属分类对象", value = "传入json格式", required = true) SysContentClassification sysContentClassification) throws UnsupportedEncodingException {
String name = URLDecoder.decode(sysContentClassification.getClassificationName(), StandardCharsets.UTF_8.toString());
sysContentClassification.setClassificationName(name);
boolean addState = service.save(sysContentClassification);
return addState ? R.success() : R.fail("新增失败");
}
@PostMapping("/update")
@Decrypt
@ApiOperation(value = "修改", response = SysContentClassification.class)
public R update(@RequestBody @ApiParam(name = "文章所属分类对象", value = "传入json格式", required = true) SysContentClassification sysContentClassification) throws UnsupportedEncodingException {
String name = URLDecoder.decode(sysContentClassification.getClassificationName(), StandardCharsets.UTF_8.toString());
sysContentClassification.setClassificationName(name);
boolean updateState = service.updateById(sysContentClassification);
return updateState ? R.success() : R.fail("编辑失败");
}
@PostMapping("/delete")
@Decrypt
@ApiOperation(value = "删除", response = SysContentClassification.class)
public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestBody Integer id) {
boolean delState = service.removeById(id);
return delState ? R.success() : R.fail("删除失败");
}
@PostMapping("/batchDeletion")
@Decrypt
@ApiOperation(value = "批量删除", response = SysContentClassification.class)
public R batchDeletion(@ApiParam(name = "id", value = "主键", required = true) @RequestBody List<Integer> ids) {
boolean delState = service.removeByIds(ids);
return delState ? R.success() : R.fail("删除失败");
//
}
}

@ -1,11 +1,29 @@
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import com.huoran.iasf.vo.req.ContentHeavyTitleReqVO; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huoran.iasf.vo.req.PageContentReqVO; 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.annotation.Decrypt;
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.*;
import com.huoran.iasf.vo.resp.PageContentRespVO; import com.huoran.iasf.vo.resp.PageContentRespVO;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import com.huoran.iasf.common.utils.R; import com.huoran.iasf.common.utils.R;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Update;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; 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.*;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -17,6 +35,12 @@ import com.huoran.iasf.service.SysContentService;
import com.huoran.iasf.entity.SysContent; import com.huoran.iasf.entity.SysContent;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
@ -31,50 +55,282 @@ public class SysContentController {
@Autowired @Autowired
public SysContentService service; public SysContentService service;
@Autowired
public SysColumnService columnService;
@Autowired
public SysContentFileService fileService;
@Autowired
public SysFilesService sysFilesService;
@PostMapping("/pagingQuery") @PostMapping("/pagingQuery")
@ApiOperation(value = "分页查询", response = PageContentRespVO.class) @Decrypt
public R pagingQuery(@RequestBody @Valid @ApiParam(name = "分页查询参数", value = "传入json格式", required = true) PageContentReqVO sysContent) { @ApiOperation(value = "分页查询文章列表", response = PageContentRespVO.class)
public R pagingQuery(@RequestBody @Valid @ApiParam(name = "分页查询参数", value = "传入json格式", required = true) PageContentReqVO sysContent) throws UnsupportedEncodingException {
if (!StringUtils.isEmpty(sysContent.getTitle())) {
//中文转码
String title = URLDecoder.decode(sysContent.getTitle(), StandardCharsets.UTF_8.toString());
sysContent.setTitle(title);
}
if (!StringUtils.isEmpty(sysContent.getFounder())) {
//中文转码
String founder = URLDecoder.decode(sysContent.getFounder(), StandardCharsets.UTF_8.toString());
sysContent.setFounder(founder);
}
if (!StringUtils.isEmpty(sysContent.getColumn())) {
//中文转码
String column = URLDecoder.decode(sysContent.getColumn(), StandardCharsets.UTF_8.toString());
sysContent.setColumn(column);
}
if (!StringUtils.isEmpty(sysContent.getEditor())) {
//中文转码
String editor = URLDecoder.decode(sysContent.getEditor(), StandardCharsets.UTF_8.toString());
sysContent.setEditor(editor);
}
return service.articlePaginationList(sysContent); return service.articlePaginationList(sysContent);
} }
@PostMapping("/findById") @PostMapping("/findById")
@Decrypt
@ApiOperation(value = "查询详情", response = SysContent.class) @ApiOperation(value = "查询详情", response = SysContent.class)
public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { public R findById(@ApiParam(name = "id", value = "主键", required = true) @RequestBody Integer id) {
SysContent sysContent = service.getById(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<SysContentFile> fileList = fileService.getFileByContentId(id);
sysContent.setFileList(fileList);
return R.success(sysContent); return R.success(sysContent);
} }
@PostMapping("/save") @PostMapping("/save")
@RequiresPermissions("sys:article:save")
@ApiOperation(value = "新增", response = SysContent.class) @ApiOperation(value = "新增", response = SysContent.class)
public R save(@RequestBody @Valid @ApiParam(name = "文章管理对象", value = "传入json格式", required = true) SysContent sysContent) { public R save(
@ApiParam(name = "文章管理对象", value = "传入json格式", required = true)
@RequestBody @Valid SysContent sysContent) {
/* QueryWrapper<SysContent> 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); boolean addState = service.save(sysContent);
return addState ? R.success() : R.fail("新增失败"); columnService.removeArticles(sysContent.getColumnId());
return addState ? R.success(sysContent.getId()) : R.fail("新增失败");
} }
@PostMapping("/update") @PostMapping("/update")
@RequiresPermissions("sys:article:update")
@ApiOperation(value = "修改", response = SysContent.class) @ApiOperation(value = "修改", response = SysContent.class)
public R update(@RequestBody @ApiParam(name = "文章管理对象", value = "传入json格式", required = true) SysContent sysContent) { public R update(@RequestBody @ApiParam(name = "文章管理对象", value = "传入json格式", required = true) SysContent sysContent) {
boolean updateState = service.updateById(sysContent); boolean updateState = service.updateById(sysContent);
columnService.removeArticles(sysContent.getColumnId());
return updateState ? R.success() : R.fail("编辑失败"); return updateState ? R.success() : R.fail("编辑失败");
} }
@PostMapping("/delete") @PostMapping("/delete")
@Decrypt
@RequiresPermissions("sys:article:delete")
@ApiOperation(value = "删除", response = SysContent.class) @ApiOperation(value = "删除", response = SysContent.class)
public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestParam Integer id) { public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestBody Integer id) {
UpdateWrapper<SysFilesEntity> queryWrapper = new UpdateWrapper<>();
queryWrapper.eq("quote_id", id);
queryWrapper.eq("quote_type", 0);
queryWrapper.set("is_del", 1);
sysFilesService.update(queryWrapper);
SysContent sysContent = service.getById(id);
columnService.removeArticles(sysContent.getColumnId());
boolean delState = service.removeById(id); boolean delState = service.removeById(id);
return delState ? R.success() : R.fail("删除失败"); return delState ? R.success() : R.fail("删除失败");
} }
@PostMapping("/batchDeletion")
@Decrypt
@ApiOperation(value = "批量删除文章", response = SysContent.class)
public R batchDeletion(@ApiParam(name = "ids", value = "主键", required = true) @RequestBody List<Integer> ids) {
for (Integer id : ids) {
SysContent sysContent = service.getById(id);
columnService.removeArticles(sysContent.getColumnId());
UpdateWrapper<SysFilesEntity> 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") @PostMapping("/checkIfTheTitleIsRepeat")
// @Decrypt
@ApiOperation(value = "标题判重——只对已发布的判重(新增,编辑,点击发布时候都要调用判断))", response = ContentHeavyTitleReqVO.class) @ApiOperation(value = "标题判重——只对已发布的判重(新增,编辑,点击发布时候都要调用判断))", response = ContentHeavyTitleReqVO.class)
public R checkIfTheTitleIsRepeat(@RequestBody @Valid ContentHeavyTitleReqVO content) { public R checkIfTheTitleIsRepeat(@RequestBody @Valid ContentHeavyTitleReqVO content) throws UnsupportedEncodingException {
// if (!org.springframework.util.StringUtils.isEmpty(content.getTitle())) {
// //中文转码
// String name = URLDecoder.decode(content.getTitle(), StandardCharsets.UTF_8.toString());
// content.setTitle(name);
// }
return service.checkIfTheTitleIsRepeat(content) ? R.success() : R.fail("该标题已重复!"); return service.checkIfTheTitleIsRepeat(content) ? R.success() : R.fail("该标题已重复!");
} }
@PostMapping("/newlyPublishedArticles")
@Decrypt
@ApiOperation(value = "站点最新发布的文章", response = PageContentReqVO.class)
public R newlyPublishedArticles(@Valid @RequestBody PageContentReqVO content) throws UnsupportedEncodingException {
//中文转码
if (!StringUtils.isEmpty(content.getTitle())) {
String title = URLDecoder.decode(content.getTitle(), StandardCharsets.UTF_8.toString());
content.setTitle(title);
}
if (!StringUtils.isEmpty(content.getPatentQueryKeyWord())) {
String title = URLDecoder.decode(content.getPatentQueryKeyWord(), StandardCharsets.UTF_8.toString());
content.setPatentQueryKeyWord(title);
}
if (!StringUtils.isEmpty(content.getMonographQueryKeyWord())) {
String title = URLDecoder.decode(content.getMonographQueryKeyWord(), StandardCharsets.UTF_8.toString());
content.setMonographQueryKeyWord(title);
}
if (!StringUtils.isEmpty(content.getPaperQueryKeyWord())) {
String title = URLDecoder.decode(content.getPaperQueryKeyWord(), StandardCharsets.UTF_8.toString());
content.setPaperQueryKeyWord(title);
}
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<SysContent> queryWrapper = new QueryWrapper<>();
queryWrapper.in("column_id", pageReq.getColumnIds());
IPage<SysContent> iPage = service.page(page, queryWrapper);
return R.success(iPage);
}
@PostMapping("/articleEnableOrDisable")
@Decrypt
@RequiresPermissions("sys:article:enable")
@ApiOperation(value = "文章启用禁用", response = SysContent.class)
public R articleEnableOrDisable(
@RequestBody ArticleEnableOrDisable articleEnableOrDisable) {
UpdateWrapper<SysContent> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("is_disable", articleEnableOrDisable.getIsDisable());
updateWrapper.eq("id", articleEnableOrDisable.getId());
boolean ret = service.update(updateWrapper);
return ret ? R.success() : R.fail("禁用/启用失败");
}
@PostMapping("/articlePreview")
@Decrypt
@ApiOperation(value = "增加文章浏览量(点击一次算一次)", response = SysContent.class)
public R articlePreview(
@ApiParam(name = "contentId", value = "文章id", required = true)
@RequestBody Integer contentId) {
return R.success(service.statisticsOfPageViews(contentId));
}
@PostMapping("/hotContent")
@Decrypt
@ApiOperation(value = "热点内容", response = SysContent.class)
public R hotContent(
@ApiParam(name = "siteId", value = "站点id", required = true)
@RequestBody 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")
@Decrypt
@RequiresPermissions("sys:article:top")
@ApiOperation(value = "文章置顶/取消置顶", response = SysContent.class)
public R articleTopOperation(
@RequestBody ArticleTopOperation articleTopOperation) {
//是否置顶(默认为0 不置顶 1为置顶)
UpdateWrapper<SysContent> updateWrap = new UpdateWrapper<>();
// columnService.removeArticles(columnId);
if (articleTopOperation.getIsTop() == 1) {
//置顶时间(置顶一次更新一次)
updateWrap.set("top_time", new Date());
} else {
updateWrap.set("top_time", null);
}
updateWrap.set("is_top", articleTopOperation.getIsTop());
updateWrap.eq("id", articleTopOperation.getArticleId());
updateWrap.eq("deleted", 1);
boolean ret = service.update(updateWrap);
return ret ? R.success() : R.fail("操作失败");
}
@PostMapping("/queryArticleColumnParent")
@Decrypt
@ApiOperation(value = "查询文章的栏目父级", response = PageContentReqVO.class)
public R queryArticleColumnParent(
@ApiParam(name = "articleId", value = "文章id", required = true)
@RequestBody Integer articleId) {
return service.queryArticleColumnParent(articleId);
}
} }

@ -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<SysContentFile> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("content_id",contentId);
List<SysContentFile> 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<Integer> ids) {
boolean delState = service.removeByIds(ids);
return delState ? R.success() : R.fail("删除失败");
}
}

@ -0,0 +1,126 @@
package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huoran.iasf.common.annotation.Decrypt;
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 com.huoran.iasf.vo.req.LabelCheckForHeavy;
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.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
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")
@Decrypt
@ApiOperation(value = "查询全部文章主题标签", response = SysContentLabel.class)
public R queryAllArticleSubjectTags(
@ApiParam(name = "siteId", value = "站点id", required = true)
@RequestBody Integer siteId) {
List<SysContentLabel> list = service.list(new QueryWrapper<SysContentLabel>().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")
@Decrypt
@ApiOperation(value = "新增", response = SysContentLabel.class)
public R save(@RequestBody @Valid @ApiParam(name = "文章主题标签对象", value = "传入json格式", required = true) SysContentLabel sysContentLabel) throws UnsupportedEncodingException {
String name = URLDecoder.decode(sysContentLabel.getLabelName(), StandardCharsets.UTF_8.toString());
sysContentLabel.setLabelName(name);
boolean addState = service.save(sysContentLabel);
return addState ? R.success() : R.fail("新增失败");
}
@PostMapping("/checkForHeavy")
@Decrypt
@ApiOperation(value = "标签校验判重", response = SysContentLabel.class)
public R checkForHeavy(
@RequestBody LabelCheckForHeavy labelCheckForHeavy) throws UnsupportedEncodingException {
String name = URLDecoder.decode(labelCheckForHeavy.getLabelName(), StandardCharsets.UTF_8.toString());
labelCheckForHeavy.setLabelName(name);
QueryWrapper<SysContentLabel> queryWrapper = new QueryWrapper<SysContentLabel>().
eq("site_id", labelCheckForHeavy.getSiteId()).eq("label_name", labelCheckForHeavy.getLabelName());
//id不得空表示编辑校验
if (labelCheckForHeavy.getLabelId() != null) {
queryWrapper.last(" and id != " + labelCheckForHeavy.getLabelId());
}
SysContentLabel contentLabel = service.getOne(queryWrapper);
if (contentLabel != null) {
return R.fail("当前标签名称已存在!");
}
return R.success();
}
@PostMapping("/update")
@Decrypt
@ApiOperation(value = "修改", response = SysContentLabel.class)
public R update(@RequestBody @ApiParam(name = "文章主题标签对象", value = "传入json格式", required = true) SysContentLabel sysContentLabel) throws UnsupportedEncodingException {
String name = URLDecoder.decode(sysContentLabel.getLabelName(), StandardCharsets.UTF_8.toString());
sysContentLabel.setLabelName(name);
boolean updateState = service.updateById(sysContentLabel);
return updateState ? R.success() : R.fail("编辑失败");
}
@PostMapping("/delete")
@Decrypt
@ApiOperation(value = "删除", response = SysContentLabel.class)
public R delete(@ApiParam(name = "id", value = "主键", required = true) @RequestBody 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<Integer> ids) {
boolean delState = service.removeByIds(ids);
return delState ? R.success() : R.fail("删除失败");
}
}

@ -1,28 +1,47 @@
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huoran.iasf.common.annotation.Decrypt;
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.common.utils.R;
import com.huoran.iasf.common.utils.fileUploadUtils;
import com.huoran.iasf.entity.SysFilesEntity; 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.SysFilesService;
import com.huoran.iasf.service.UserService;
import com.huoran.iasf.vo.UEditorResultVO; import com.huoran.iasf.vo.UEditorResultVO;
import com.huoran.iasf.vo.req.FileParameters; import com.huoran.iasf.vo.req.FileParameters;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.util.StringUtils; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
/** /**
@ -39,6 +58,12 @@ public class SysFilesController {
@Resource @Resource
private SysFilesService sysFilesService; private SysFilesService sysFilesService;
@Autowired
private UserService userService;
@Resource
private HttpSessionService httpSessionService;
@ApiOperation(value = "上传文件前获取配置文件") @ApiOperation(value = "上传文件前获取配置文件")
@GetMapping("/upload") @GetMapping("/upload")
public String upload(@RequestParam(required = false) String action,HttpServletResponse response) throws IOException { public String upload(@RequestParam(required = false) String action,HttpServletResponse response) throws IOException {
@ -50,42 +75,51 @@ public class SysFilesController {
result.put("imageFieldName", "file"); result.put("imageFieldName", "file");
return result.toJSONString(); return result.toJSONString();
} }
// @NoRepeatSubmit
@ApiOperation(value = "新增") @ApiOperation(value = "新增")
@PostMapping("/upload") @PostMapping("/upload")
// @RequiresPermissions(value = {"sysFiles:add", "sysContent:update", "sysContent:add"}, logical = Logical.OR) // @RequiresPermissions(value = {"sysFiles:add", "sysContent:update", "sysContent:add"}, logical = Logical.OR)
public UEditorResultVO add( public UEditorResultVO add(
@RequestParam(required = false) String action, @RequestParam(required = false) String action,
@RequestParam(value = "file") MultipartFile file, FileParameters fileParameters) { @RequestParam(value = "file") MultipartFile file, FileParameters fileParameters) throws Exception {
Integer userId = httpSessionService.getCurrentUserId();
fileParameters.setUploader(userId.toString());
//判断文件是否空 //判断文件是否空
if (file == null || file.getOriginalFilename() == null || "".equalsIgnoreCase(file.getOriginalFilename().trim())) { if (file == null || file.getOriginalFilename() == null || "".equalsIgnoreCase(file.getOriginalFilename().trim())) {
UEditorResultVO uEditorResult = new UEditorResultVO(); UEditorResultVO uEditorResult = new UEditorResultVO();
uEditorResult.setState("error"); uEditorResult.setState("error");
return uEditorResult; return uEditorResult;
} }
String pattern = ".*\\.(mp4|MP3|MP4|jpg|png|gif|doc|xls|xlsx|docx|pdf|mp3)$";
boolean hasExtension = Pattern.matches(pattern, file.getOriginalFilename());
if (!hasExtension){
String[] allowedExtension = new String[]{"jpg", "png", "gif", "doc", "xls", "xlsx", "docx", "pdf", "mov","mp4","MP3"};
fileUploadUtils.assertAllowed(file,allowedExtension);
}
return sysFilesService.saveFile(file,fileParameters); return sysFilesService.saveFile(file,fileParameters);
} }
@ApiOperation(value = "更新文件信息") @ApiOperation(value = "更新文件信息")
@PostMapping("/update") @PostMapping("/update")
public R update(FileParameters fileParameters) { public R update(@RequestBody FileParameters fileParameters) {
if (fileParameters.getId()==null){ if (StrUtil.isEmpty(fileParameters.getId())){
return R.fail("id不能为空"); return R.fail("id不能为空");
} }
UpdateWrapper<SysFilesEntity> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<SysFilesEntity> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("quote",fileParameters.getQuote()). updateWrapper.set("quote",fileParameters.getQuote()).
set("is_release",fileParameters.getIsRelease()). set("is_release",fileParameters.getIsRelease()).
eq("site",fileParameters.getSite()). set("quote_id",fileParameters.getQuoteId()).
eq("id", fileParameters.getId()); eq("id", fileParameters.getId());
return sysFilesService.update(updateWrapper) ? R.success() : R.fail("更新失败"); return sysFilesService.update(updateWrapper) ? R.success() : R.fail("更新失败");
} }
@ApiOperation(value = "文件预览") @ApiOperation(value = "文件预览")
@GetMapping("/preview/{id}") @GetMapping("/preview/{id}")
public void preview(@PathVariable String id, HttpServletRequest req, HttpServletResponse res) { public void preview(@PathVariable String id, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
sysFilesService.preview(id, req, res); sysFilesService.preview(id, req, res);
} }
// @NoRepeatSubmit
@ApiOperation(value = "文件下载") @ApiOperation(value = "文件下载")
@GetMapping("/download/{id}") @GetMapping("/download/{id}")
public void download(@PathVariable String id, HttpServletRequest req, HttpServletResponse res) { public void download(@PathVariable String id, HttpServletRequest req, HttpServletResponse res) {
@ -93,7 +127,8 @@ public class SysFilesController {
} }
@ApiOperation(value = "删除") @ApiOperation(value = "删除")
@DeleteMapping("/delete") @PostMapping("/delete")
@Decrypt
@RequiresPermissions("sysFiles:delete") @RequiresPermissions("sysFiles:delete")
public R delete(@RequestBody @ApiParam(value = "id集合") List<String> ids) { public R delete(@RequestBody @ApiParam(value = "id集合") List<String> ids) {
sysFilesService.removeByIdsAndFiles(ids); sysFilesService.removeByIdsAndFiles(ids);
@ -103,8 +138,30 @@ public class SysFilesController {
@ApiOperation(value = "查询分页数据",response = SysFilesEntity.class) @ApiOperation(value = "查询分页数据",response = SysFilesEntity.class)
@PostMapping("/listByPage") @PostMapping("/listByPage")
@RequiresPermissions("sysFiles:list") @RequiresPermissions("sysFiles:list")
public R findListByPage(@RequestBody SysFilesEntity sysFiles) { public R findListByPage(@RequestBody SysFilesEntity sysFiles) throws UnsupportedEncodingException {
LambdaQueryWrapper<SysFilesEntity> queryWrapper = Wrappers.lambdaQuery(); if (!StringUtils.isEmpty(sysFiles.getQuote())) {
//中文转码
String title = URLDecoder.decode(sysFiles.getQuote(), StandardCharsets.UTF_8.toString());
sysFiles.setQuote(title);
}
if (!StringUtils.isEmpty(sysFiles.getFileName())) {
//中文转码
String title = URLDecoder.decode(sysFiles.getFileName(), StandardCharsets.UTF_8.toString());
sysFiles.setFileName(title);
}
if (!StringUtils.isEmpty(sysFiles.getUploader())) {
//中文转码
String title = URLDecoder.decode(sysFiles.getUploader(), StandardCharsets.UTF_8.toString());
sysFiles.setUploader(title);
}
if (!StringUtils.isEmpty(sysFiles.getType())) {
//中文转码
String title = URLDecoder.decode(sysFiles.getType(), StandardCharsets.UTF_8.toString());
sysFiles.setType(title);
}
return sysFilesService.getPage(sysFiles);
/*LambdaQueryWrapper<SysFilesEntity> queryWrapper = Wrappers.lambdaQuery();
if (!StringUtils.isEmpty(sysFiles.getFileName())) { if (!StringUtils.isEmpty(sysFiles.getFileName())) {
queryWrapper.like(SysFilesEntity::getFileName, sysFiles.getFileName()); queryWrapper.like(SysFilesEntity::getFileName, sysFiles.getFileName());
} }
@ -124,8 +181,18 @@ public class SysFilesController {
queryWrapper.isNotNull(SysFilesEntity::getQuote); queryWrapper.isNotNull(SysFilesEntity::getQuote);
//只查看已发布的文件 //只查看已发布的文件
queryWrapper.eq(SysFilesEntity::getIsRelease,1); queryWrapper.eq(SysFilesEntity::getIsRelease,1);
//查看文章未删除的
queryWrapper.eq(SysFilesEntity::getIsDel,0);
IPage<SysFilesEntity> iPage = sysFilesService.page(sysFiles.getQueryPage(),queryWrapper); IPage<SysFilesEntity> iPage = sysFilesService.page(sysFiles.getQueryPage(),queryWrapper);
return R.success(iPage); 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);*/
} }
} }

@ -1,4 +1,3 @@
/*
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -16,14 +15,13 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
*/
/** /**
* 系统操作日志 * 系统操作日志
* *
* @author cheney * @author cheney
* @version V1.0 * @version V1.0
* @date 2022年7月28日 * @date 2022年7月28日
*//* */
@RequestMapping("/sys") @RequestMapping("/sys")
@Api(tags = "系统模块-系统操作日志管理") @Api(tags = "系统模块-系统操作日志管理")
@ -35,7 +33,7 @@ public class SysLogController {
@PostMapping("/logs") @PostMapping("/logs")
@ApiOperation(value = "分页查询系统操作日志接口") @ApiOperation(value = "分页查询系统操作日志接口")
@LogAnnotation(title = "系统操作日志管理", action = "分页查询系统操作日志") @LogAnnotation(title = "系统操作日志管理", action = "分页查询系统操作日志")
@RequiresPermissions("sys:log:list") // @RequiresPermissions("sys:log:list")
public R pageInfo(@RequestBody SysLog vo) { public R pageInfo(@RequestBody SysLog vo) {
LambdaQueryWrapper<SysLog> queryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<SysLog> queryWrapper = Wrappers.lambdaQuery();
if (!StringUtils.isEmpty(vo.getUsername())) { if (!StringUtils.isEmpty(vo.getUsername())) {
@ -57,10 +55,9 @@ public class SysLogController {
@DeleteMapping("/logs") @DeleteMapping("/logs")
@ApiOperation(value = "删除日志接口") @ApiOperation(value = "删除日志接口")
@LogAnnotation(title = "系统操作日志管理", action = "删除系统操作日志") @LogAnnotation(title = "系统操作日志管理", action = "删除系统操作日志")
@RequiresPermissions("sys:log:deleted") // @RequiresPermissions("sys:log:deleted")
public R deleted(@RequestBody List<String> logIds) { public R deleted(@RequestBody List<String> logIds) {
logService.removeByIds(logIds); logService.removeByIds(logIds);
return R.success(); return R.success();
} }
} }
*/

@ -1,6 +1,7 @@
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huoran.iasf.common.annotation.Decrypt;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huoran.iasf.common.utils.R; import com.huoran.iasf.common.utils.R;
@ -36,8 +37,9 @@ public class SysNavigationStyleController {
@PostMapping("/searchAllBySite") @PostMapping("/searchAllBySite")
@Decrypt
@ApiOperation(value = "按站点搜索所有", response = SysNavigationStyle.class) @ApiOperation(value = "按站点搜索所有", response = SysNavigationStyle.class)
public R listByEntity(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestParam Integer siteId) { public R listByEntity(@ApiParam(name = "siteId", value = "站点id", required = true) @RequestBody Integer siteId) {
QueryWrapper<SysNavigationStyle> queryWrapper = new QueryWrapper<>(); QueryWrapper<SysNavigationStyle> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("site_id", siteId); queryWrapper.eq("site_id", siteId);
List<SysNavigationStyle> pageList = service.list(queryWrapper); List<SysNavigationStyle> pageList = service.list(queryWrapper);

@ -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<SysTemplate> list = templateService.list(new QueryWrapper<SysTemplate>().eq("type", 1).eq("is_hide",0));
return R.success(list);
}
@PostMapping("/longPageListStyle")
@ApiOperation(value = "长页列表样式", response = SysTemplate.class)
public R longPageListStyle() {
List<SysTemplateStyle> list = styleService.list(new QueryWrapper<SysTemplateStyle>().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<SysTemplateStyle> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", Constant.LIST_TEMPLATE_TYPES);
queryWrapper.eq("is_long_page", 0);
List<SysTemplateStyle> listingTemplateTypes = styleService.list(queryWrapper);
QueryWrapper<SysTemplateStyle> queryWrapper1 = new QueryWrapper<>();
queryWrapper1.eq("template_id",templateId);
queryWrapper1.eq("type", Constant.DETAILS_TEMPLATE_TYPE);
List<SysTemplateStyle> detailsTypeOfTheTemplate = styleService.list(queryWrapper1);*/
List<SysTemplateStyle> listingTemplateTypes = templateStyleConfigurationService.getsTheStyleUnderTheTemplate(templateId, 0);
List<SysTemplateStyle> detailsTypeOfTheTemplate = templateStyleConfigurationService.getsTheStyleUnderTheTemplate(templateId, 1);
Map<String, Object> 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<SysTemplateStyle> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", Constant.DETAILS_TEMPLATE_TYPE);
List<SysTemplateStyle> listingTemplateTypes = styleService.list(queryWrapper);
return R.success(listingTemplateTypes);
}
@PostMapping("/individualTemplateDetailsStyle")
@ApiOperation(value = "独立模板详情样式", response = SysTemplate.class)
public R individualTemplateDetailsStyle() {
List<SysTemplateStyle> list = styleService.list(new QueryWrapper<SysTemplateStyle>().eq("type", 1).eq("is_long_page", 0).eq("is_hide",0));
return R.success(list);
}
}

@ -1,10 +1,16 @@
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huoran.iasf.common.annotation.Decrypt;
import com.huoran.iasf.common.aop.annotation.LogAnnotation; 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.common.utils.R;
import com.huoran.iasf.common.utils.fileUploadUtils;
import com.huoran.iasf.entity.SysUser; 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.HttpSessionService;
import com.huoran.iasf.service.UserService; import com.huoran.iasf.service.UserService;
import com.huoran.iasf.vo.CheckVo; import com.huoran.iasf.vo.CheckVo;
@ -23,12 +29,17 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.naming.Name;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern;
/** /**
* 用户管理 * 用户管理
@ -45,10 +56,14 @@ public class UserController {
@Resource @Resource
private UserService userService; private UserService userService;
@Resource
private UserDeptMapper userDeptMapper;
@Resource @Resource
private HttpSessionService httpSessionService; private HttpSessionService httpSessionService;
@PostMapping(value = "/user/login") @PostMapping(value = "/user/login")
@Decrypt
@ApiOperation(value = "用户登录接口") @ApiOperation(value = "用户登录接口")
public R login(@RequestBody @Valid SysUser vo) { public R login(@RequestBody @Valid SysUser vo) {
return R.success(userService.login(vo)); return R.success(userService.login(vo));
@ -61,11 +76,22 @@ public class UserController {
return R.success(); return R.success();
}*/ }*/
@PutMapping("/user") @PostMapping("/updateUser")
@ApiOperation(value = "更新用户信息接口") @ApiOperation(value = "更新用户信息接口")
@LogAnnotation(title = "用户管理", action = "更新用户信息") @LogAnnotation(title = "用户管理", action = "更新用户信息")
@Decrypt
@RequiresPermissions("sys:user:update") @RequiresPermissions("sys:user:update")
public R updateUserInfo(@RequestBody SysUser vo) { public R updateUserInfo(@RequestBody SysUser vo) throws UnsupportedEncodingException {
//中文转码
if (!StringUtils.isEmpty(vo.getRealName())) {
String realName = URLDecoder.decode(vo.getRealName(), StandardCharsets.UTF_8.toString());
vo.setRealName(realName);
}
if (!StringUtils.isEmpty(vo.getUsername())) {
String realName = URLDecoder.decode(vo.getUsername(), StandardCharsets.UTF_8.toString());
vo.setUsername(realName);
}
if (StringUtils.isEmpty(vo.getId())) { if (StringUtils.isEmpty(vo.getId())) {
return R.fail("id不能为空"); return R.fail("id不能为空");
} }
@ -73,28 +99,52 @@ public class UserController {
return R.success(); return R.success();
} }
@GetMapping("/user/{id}") @PostMapping("/queryUser")
@ApiOperation(value = "查询用户详情接口") @ApiOperation(value = "查询用户详情接口")
@Decrypt
@LogAnnotation(title = "用户管理", action = "查询用户详情") @LogAnnotation(title = "用户管理", action = "查询用户详情")
@RequiresPermissions("sys:user:detail") @RequiresPermissions("sys:user:detail")
public R detailInfo(@PathVariable("id") String id) { public R detailInfo(@RequestBody Integer id) {
UserListResp userResp = userService.detailInfo(id); UserListResp userResp = userService.detailInfo(id);
return R.success(userResp); return R.success(userResp);
} }
@PostMapping("/personalData")
@ApiOperation(value = "查询个人资料接口")
@LogAnnotation(title = "用户管理", action = "查询个人资料接口")
public R personalData() {
Integer currentUserId = httpSessionService.getCurrentUserId();
UserListResp userResp = userService.detailInfo(currentUserId);
return R.success(userResp);
}
@PostMapping("/users") @PostMapping("/users")
@ApiOperation(value = "分页获取用户列表接口") @ApiOperation(value = "分页获取用户列表接口")
@RequiresPermissions("sys:user:list") @RequiresPermissions("sys:user:list")
@Decrypt
@LogAnnotation(title = "用户管理", action = "分页获取用户列表") @LogAnnotation(title = "用户管理", action = "分页获取用户列表")
public R pageInfo(@RequestBody UserListReq userListReq) { public R pageInfo(@RequestBody UserListReq userListReq) throws UnsupportedEncodingException {
//中文转码
String key = URLDecoder.decode(userListReq.getKeyWord(), StandardCharsets.UTF_8.toString());
userListReq.setKeyWord(key);
return userService.pageInfo(userListReq); return userService.pageInfo(userListReq);
} }
@PostMapping("/user") @PostMapping("/user")
@ApiOperation(value = "新增用户接口") @ApiOperation(value = "新增用户接口")
@RequiresPermissions("sys:user:add") @RequiresPermissions("sys:user:add")
@Decrypt
@LogAnnotation(title = "用户管理", action = "新增用户") @LogAnnotation(title = "用户管理", action = "新增用户")
public R addUser(@RequestBody @Valid SysUser vo) { public R addUser(@RequestBody @Valid SysUser vo) throws UnsupportedEncodingException {
//中文转码
if (!StringUtils.isEmpty(vo.getRealName())) {
String realName = URLDecoder.decode(vo.getRealName(), StandardCharsets.UTF_8.toString());
vo.setRealName(realName);
}
if (!StringUtils.isEmpty(vo.getUsername())) {
String realName = URLDecoder.decode(vo.getUsername(), StandardCharsets.UTF_8.toString());
vo.setUsername(realName);
}
userService.addUser(vo); userService.addUser(vo);
return R.success(); return R.success();
} }
@ -138,10 +188,16 @@ public class UserController {
} }
return R.success(); return R.success();
} }
@NoRepeatSubmit
@ApiOperation(value = "密码重置", notes = "密码重置") @ApiOperation(value = "密码重置", notes = "密码重置")
@GetMapping("/resetPwd") @Decrypt
public R resetPwd(@RequestParam("userId") String userId) { @PostMapping("/resetPwd")
@RequiresPermissions("sys:user:resetPwd")
public R resetPwd(@RequestBody String userId) {
// Integer currentUserId = httpSessionService.getCurrentUserId();
// if (!userId.equals(currentUserId.toString())){
// return R.fail("只能修改自己的密码");
// }
return userService.resetPwd(userId); return userService.resetPwd(userId);
} }
@ -154,35 +210,46 @@ public class UserController {
subject.logout(); subject.logout();
return R.success(); return R.success();
} }
@NoRepeatSubmit
@PutMapping("/user/pwd") @Decrypt
@PostMapping("/user/pwd")
@ApiOperation(value = "修改密码接口") @ApiOperation(value = "修改密码接口")
@LogAnnotation(title = "用户管理", action = "更新密码") @LogAnnotation(title = "用户管理", action = "更新密码")
public R updatePwd(@RequestBody SysUser vo) { public R updatePwd(@RequestBody SysUser vo) {
if (StringUtils.isEmpty(vo.getOldPwd()) || StringUtils.isEmpty(vo.getNewPwd())) { if (StringUtils.isEmpty(vo.getOldPwd()) || StringUtils.isEmpty(vo.getNewPwd())) {
return R.fail("旧密码与新密码不能为空"); return R.fail("旧密码与新密码不能为空");
} }
// Integer userId = httpSessionService.getCurrentUserId(); Integer userId = httpSessionService.getCurrentUserId();
// vo.setId(userId); if (!userId.equals(vo.getId())){
return R.fail("只能修改自己的密码");
}
boolean password = userService.checkPassword(vo.getNewPwd());
if (!password){
return R.fail("密码长度不小于8位,至少包含数字、大小写字母和特殊字符");
}
userService.updatePwd(vo); userService.updatePwd(vo);
return R.success(); return R.success();
} }
@NoRepeatSubmit
@DeleteMapping("/user") @PostMapping("/deletedUser")
@ApiOperation(value = "删除用户接口") @ApiOperation(value = "删除用户接口")
@Decrypt
@LogAnnotation(title = "用户管理", action = "删除用户") @LogAnnotation(title = "用户管理", action = "删除用户")
@RequiresPermissions("sys:user:deleted") @RequiresPermissions("sys:user:deleted")
public R deletedUser(@RequestBody @ApiParam(value = "用户id集合") List<Integer> userIds) { public R deletedUser(@RequestBody @ApiParam(value = "用户id集合") List<String> userIds) {
//删除用户, 删除redis的绑定的角色跟权限 //删除用户, 删除redis的绑定的角色跟权限
httpSessionService.abortUserByUserIds(userIds); httpSessionService.abortUserByUserIds(userIds);
LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.in(SysUser::getId, userIds); queryWrapper.in(SysUser::getId, userIds);
userService.remove(queryWrapper); userService.remove(queryWrapper);
//删除用户部门
userDeptMapper.delete(Wrappers.<UserDept>lambdaQuery().in(UserDept::getUserId, userIds));
return R.success(); return R.success();
} }
@PostMapping("/importStaff") @PostMapping("/importStaff")
@ApiOperation("批量导入员工") @ApiOperation("批量导入员工")
@RequiresPermissions("sys:user:import")
public R importStaff(@RequestParam(name = "file") MultipartFile file, HttpServletRequest request) throws IOException { public R importStaff(@RequestParam(name = "file") MultipartFile file, HttpServletRequest request) throws IOException {
Map<String, String> map = userService.importStaff(file); Map<String, String> map = userService.importStaff(file);
return R.success(map); return R.success(map);
@ -196,13 +263,13 @@ public class UserController {
public void exportFailureRecord(HttpServletResponse response, @ApiParam(name = "exportCode", value = "importQuestion接口返回的exportCode", required = true) @RequestParam String exportCode) throws Exception { public void exportFailureRecord(HttpServletResponse response, @ApiParam(name = "exportCode", value = "importQuestion接口返回的exportCode", required = true) @RequestParam String exportCode) throws Exception {
userService.exportFailureRecord(response, exportCode); userService.exportFailureRecord(response, exportCode);
} }
@NoRepeatSubmit
@ApiOperation(value = "更换手机号或邮箱--发送验证码") @ApiOperation(value = "更换手机号或邮箱--发送验证码")
@PostMapping("/sendPhoneOrEmailCode") @PostMapping("/sendPhoneOrEmailCode")
public R sendPhoneOrEmailCode(@RequestBody CheckVo checkVo) { public R sendPhoneOrEmailCode(@RequestBody CheckVo checkVo) {
return userService.sendCheckPhoneCode(checkVo); return userService.sendCheckPhoneCode(checkVo);
} }
@NoRepeatSubmit
@ApiOperation(value = "更新手机号或邮箱") @ApiOperation(value = "更新手机号或邮箱")
@PostMapping("/updatePhoneOrEmail") @PostMapping("/updatePhoneOrEmail")
public R updatePhoneOrEmail(@RequestBody UpdatePhoneOrEmailReq updatePhoneOrEmailReq) { public R updatePhoneOrEmail(@RequestBody UpdatePhoneOrEmailReq updatePhoneOrEmailReq) {
@ -211,8 +278,16 @@ public class UserController {
@ApiOperation(value = "修改用户头像") @ApiOperation(value = "修改用户头像")
@PostMapping("/updateUserAvatars") @PostMapping("/updateUserAvatars")
public R updateUserAvatars(@RequestParam String userId, MultipartFile file) { public R updateUserAvatars(MultipartFile file) throws Exception {
return userService.updateUserAvatars(userId, file);
String pattern = ".*\\.(jpg|png|gif)$";
boolean hasExtension = Pattern.matches(pattern, file.getOriginalFilename());
if (!hasExtension){
String[] allowedExtension = new String[]{"jpg", "png", "gif"};
fileUploadUtils.assertAllowed(file,allowedExtension);
}
Integer currentUserId = httpSessionService.getCurrentUserId();
return userService.updateUserAvatars(currentUserId.toString(), file);
} }
} }

@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
* @since 2022-08-15 * @since 2022-08-15
*/ */
@RestController @RestController
@RequestMapping("//user-dept") @RequestMapping("/userDept")
public class UserDeptController { public class UserDeptController {
} }

@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huoran.iasf.common.annotation.Decrypt;
import com.huoran.iasf.common.aop.annotation.LogAnnotation; 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.common.utils.R;
import com.huoran.iasf.entity.SysFilesEntity; import com.huoran.iasf.entity.SysFilesEntity;
import com.huoran.iasf.entity.UserGroup; import com.huoran.iasf.entity.UserGroup;
@ -18,6 +20,10 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
/** /**
@ -35,44 +41,57 @@ public class UserGroupController {
@Autowired @Autowired
private UserGroupService userGroupService; private UserGroupService userGroupService;
@NoRepeatSubmit
@Decrypt
@PostMapping("/add") @PostMapping("/add")
@ApiOperation(value = "新增用户组") @ApiOperation(value = "新增用户组")
@LogAnnotation(title = "用户组管理", action = "新增用户组") @LogAnnotation(title = "用户组管理", action = "新增用户组")
@RequiresPermissions("sys:userGroup:add") @RequiresPermissions("sys:userGroup:add")
public R addUserGroup(@RequestBody @Valid UserGroup userGroup) { public R addUserGroup(@RequestBody @Valid UserGroup userGroup) throws UnsupportedEncodingException {
//中文转码
String groupName = URLDecoder.decode(userGroup.getGroupName(), StandardCharsets.UTF_8.toString());
userGroup.setGroupName(groupName);
String description = URLDecoder.decode(userGroup.getDescription(), StandardCharsets.UTF_8.toString());
userGroup.setDescription(description);
UserGroup one = userGroupService.getOne(new QueryWrapper<UserGroup>(). UserGroup one = userGroupService.getOne(new QueryWrapper<UserGroup>().
eq("group_name", userGroup.getGroupName())); eq("group_name", userGroup.getGroupName()));
if (ObjectUtil.isNotNull(one)){ if (ObjectUtil.isNotNull(one)){
R.fail("用户组已存在"); return R.fail("用户组已存在");
} }
userGroupService.save(userGroup); userGroupService.save(userGroup);
return R.success(); return R.success();
} }
@NoRepeatSubmit
@DeleteMapping("/delete/{id}") @Decrypt
@PostMapping("/deleteUserGroup")
@ApiOperation(value = "删除用户组") @ApiOperation(value = "删除用户组")
@LogAnnotation(title = "用户组管理", action = "删除用户组") @LogAnnotation(title = "用户组管理", action = "删除用户组")
@RequiresPermissions("sys:userGroup:deleted") @RequiresPermissions("sys:userGroup:deleted")
public R deleted(@PathVariable("id") Integer id) { public R deleted(@RequestBody Integer id) {
userGroupService.removeById(id); userGroupService.removeById(id);
return R.success(); return R.success();
} }
@PutMapping("/update") @PostMapping("/updateUserGroup")
@Decrypt
@ApiOperation(value = "更新用户组信息") @ApiOperation(value = "更新用户组信息")
@LogAnnotation(title = "用户组管理", action = "更新用户组信息") @LogAnnotation(title = "用户组管理", action = "更新用户组信息")
@RequiresPermissions("sys:userGroup:update") @RequiresPermissions("sys:userGroup:update")
public R updateUserGroup(@RequestBody UserGroup userGroup) { public R updateUserGroup(@RequestBody UserGroup userGroup) throws UnsupportedEncodingException {
if (StringUtils.isEmpty(userGroup.getId())) { if (StringUtils.isEmpty(userGroup.getId())) {
return R.fail("id不能为空"); return R.fail("id不能为空");
} }
//中文转码
String groupName = URLDecoder.decode(userGroup.getGroupName(), StandardCharsets.UTF_8.toString());
userGroup.setGroupName(groupName);
String description = URLDecoder.decode(userGroup.getDescription(), StandardCharsets.UTF_8.toString());
userGroup.setDescription(description);
QueryWrapper<UserGroup> queryWrapper = new QueryWrapper<>(); QueryWrapper<UserGroup> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("group_name", userGroup.getGroupName()); queryWrapper.eq("group_name", userGroup.getGroupName());
queryWrapper.last(" and id != " + userGroup.getId()); queryWrapper.last(" and id != " + userGroup.getId());
List<UserGroup> groups = userGroupService.list(queryWrapper); List<UserGroup> groups = userGroupService.list(queryWrapper);
if (ObjectUtil.isNotNull(groups) && groups.size()>0){ if (ObjectUtil.isNotNull(groups) && groups.size()>0){
R.fail("用户组已存在"); return R.fail("用户组已存在");
} }
userGroupService.updateById(userGroup); userGroupService.updateById(userGroup);
return R.success(); return R.success();
@ -88,10 +107,16 @@ public class UserGroupController {
@PostMapping("/list") @PostMapping("/list")
@Decrypt
@ApiOperation(value = "用户组列表") @ApiOperation(value = "用户组列表")
@LogAnnotation(title = "用户组管理", action = "获取所有用户组机构") @LogAnnotation(title = "用户组管理", action = "获取所有用户组机构")
@RequiresPermissions("sys:userGroup:list") @RequiresPermissions("sys:userGroup:list")
public R getUserGroupAll(@RequestBody UserGroup userGroup) { public R getUserGroupAll(@RequestBody UserGroup userGroup) throws UnsupportedEncodingException {
if (!StringUtils.isEmpty(userGroup.getGroupName())) {
//中文转码
String groupName = URLDecoder.decode(userGroup.getGroupName(), StandardCharsets.UTF_8.toString());
userGroup.setGroupName(groupName);
}
LambdaQueryWrapper<UserGroup> queryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<UserGroup> queryWrapper = Wrappers.lambdaQuery();
if (!StringUtils.isEmpty(userGroup.getGroupName())) { if (!StringUtils.isEmpty(userGroup.getGroupName())) {
queryWrapper.like(UserGroup::getGroupName, userGroup.getGroupName()); queryWrapper.like(UserGroup::getGroupName, userGroup.getGroupName());

@ -1,6 +1,7 @@
package com.huoran.iasf.controller; package com.huoran.iasf.controller;
import com.huoran.iasf.common.aop.annotation.LogAnnotation; 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.common.utils.R;
import com.huoran.iasf.service.UserRoleService; import com.huoran.iasf.service.UserRoleService;
import com.huoran.iasf.vo.req.UserRoleOperationReqVO; import com.huoran.iasf.vo.req.UserRoleOperationReqVO;
@ -27,7 +28,6 @@ import javax.validation.Valid;
public class UserRoleController { public class UserRoleController {
@Resource @Resource
private UserRoleService userRoleService; private UserRoleService userRoleService;
@PostMapping("/user/role") @PostMapping("/user/role")
@ApiOperation(value = "修改或者新增用户角色接口") @ApiOperation(value = "修改或者新增用户角色接口")
@LogAnnotation(title = "用户和角色关联接口", action = "修改或者新增用户角色") @LogAnnotation(title = "用户和角色关联接口", action = "修改或者新增用户角色")

@ -0,0 +1,44 @@
package com.huoran.iasf.entity;
import com.baomidou.mybatisplus.annotation.TableName;
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;
/**
* <p>
*
* </p>
*
* @author cheney
* @since 2023-08-24
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_seo")
@ApiModel(value="Seo对象", description="")
public class Seo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "标题")
private String title;
@ApiModelProperty(value = "关键词")
private String keyword;
@ApiModelProperty(value = "描述")
private String description;
@ApiModelProperty(value = "站点")
private Integer siteId;
}

@ -51,17 +51,17 @@ public class SysColumn implements Serializable {
@ApiModelProperty(value = "菜单是否可见(默认0可见 1不可见)") @ApiModelProperty(value = "菜单是否可见(默认0可见 1不可见)")
private Integer menuVisible; private Integer menuVisible;
@ApiModelProperty(value = "栏目类型(由前端自己设定)") @ApiModelProperty(value = "栏目类型id")
private Integer typeId; private Integer typeId;
@ApiModelProperty(value = "栏目模板(由前端自己设定)") @ApiModelProperty(value = "栏目模板id")
private Integer templateId; private Integer templateId;
@ApiModelProperty(value = "列表样式(由前端自己设定)") @ApiModelProperty(value = "列表样式id")
private Integer listStyleId; private Integer listStyleId;
@ApiModelProperty(value = "详情样式(由前端自己设定)") @ApiModelProperty(value = "详情样式id")
private Integer detailStyle; private Integer detailStyleId;
@ApiModelProperty(value = "链接类型") @ApiModelProperty(value = "链接类型")
private Integer connectionType; private Integer connectionType;
@ -136,6 +136,23 @@ public class SysColumn implements Serializable {
return 0; 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---------------------- //----------------------非数据库字段End----------------------
} }

@ -37,14 +37,12 @@ public class SysColumnLongPage implements Serializable {
@NotNull(message = "排序不能为空!") @NotNull(message = "排序不能为空!")
private Integer sort; private Integer sort;
@ApiModelProperty(value = "内容(json字符串)")
@NotNull(message = "内容不能为空!")
private String json;
@ApiModelProperty(value = "创建人id") @ApiModelProperty(value = "创建人id")
@NotNull(message = "创建人id不能为空!")
private Integer founderId; private Integer founderId;
@ApiModelProperty(value = "编辑人id") @ApiModelProperty(value = "编辑人id")
@NotNull(message = "编辑人id不能为空!")
private Integer editorId; private Integer editorId;
@ApiModelProperty(value = "创建时间") @ApiModelProperty(value = "创建时间")
@ -56,10 +54,20 @@ public class SysColumnLongPage implements Serializable {
private Date updateTime; private Date updateTime;
@ApiModelProperty(value = "是否删除(1未删除;0已删除)") @ApiModelProperty(value = "是否删除(1未删除;0已删除)")
@TableLogic
private Integer deleted; private Integer deleted;
@ApiModelProperty(value = "备注") @ApiModelProperty(value = "备注")
private String remark; private String remark;
@ApiModelProperty(value = "内容(编辑前存储的json字符串)")
private String jsonBeforeEditing;
@ApiModelProperty(value = "内容(编辑后存储的json字符串)")
private String theEditedJson;
@ApiModelProperty(value = "发布状态(0:草稿 1已发布)")
private Integer state;
} }

@ -7,6 +7,7 @@ import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import java.util.List;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
@ -30,53 +31,44 @@ public class SysContent implements Serializable {
private Integer id; private Integer id;
@ApiModelProperty(value = "标题(全库判重)") @ApiModelProperty(value = "标题(全库判重)")
@NotNull(message = "标题不能为空!")
private String title; private String title;
@ApiModelProperty(value = "所属栏目") @ApiModelProperty(value = "所属栏目")
@NotNull(message = "所属栏目不能为空!")
private Integer columnId; private Integer columnId;
@ApiModelProperty(value = "标题图") @ApiModelProperty(value = "发布时间")
private String titleImg; private String releaseTime;
@ApiModelProperty(value = "来源") @ApiModelProperty(value = "来源")
private String source; private String source;
@ApiModelProperty(value = "发布时间") @ApiModelProperty(value = "作者")
// @NotNull(message = "发布时间不能为空!") private String author;
private Date releaseTime;
@ApiModelProperty(value = "摘要")
private String summary;
@ApiModelProperty(value = "banner图") @ApiModelProperty(value = "banner图")
private String bannerImg; private String bannerImg;
@ApiModelProperty(value = "文章模板(前端自定义)——>没选择时默认读取当前所引用栏目的栏目类型") @ApiModelProperty(value = "文章模板(前端自定义)")
private Integer articleTemplate; private Integer articleTemplate;
@ApiModelProperty(value = "摘要")
private String summary;
@ApiModelProperty(value = "标题图(封面图)")
private String titleImg;
@ApiModelProperty(value = "正文") @ApiModelProperty(value = "正文")
private String mainBody; private String mainBody;
@ApiModelProperty(value = "作者") @ApiModelProperty(value = "是否发布(0:草稿 1:已发布)")
private String author;
@ApiModelProperty(value = "发布状态——>是否发布(0:草稿 1:已发布)")
@NotNull(message = "发布状态不能为空!")
private Integer isRelease; private Integer isRelease;
@ApiModelProperty(value = "创建人id") @ApiModelProperty(value = "创建人id")
@NotNull(message = "创建人id不能为空!")
private Integer founderId; private Integer founderId;
@ApiModelProperty(value = "编辑人id") @ApiModelProperty(value = "编辑人id")
@NotNull(message = "编辑人id不能为空!")
private Integer editorId; private Integer editorId;
@ApiModelProperty(value = "文件")
private String file;
@ApiModelProperty(value = "创建时间") @ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
private Date createTime; private Date createTime;
@ -84,19 +76,9 @@ public class SysContent implements Serializable {
@ApiModelProperty(value = "更新时间") @ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; private Date updateTime;
@ApiModelProperty(value = "文章总浏览量") @ApiModelProperty(value = "文章总浏览量")
private Integer totalBrowsing; private Integer totalBrowsing;
@ApiModelProperty(value = "链接类型")
private Integer connectionType;
@ApiModelProperty(value = "链接地址")
private String linkAddress;
@ApiModelProperty(value = "站点选择(连接类型为其它站点连接时储存)1.EFL中文2.SRL中文")
private Integer siteSelection;
@ApiModelProperty(value = "是否在新窗口打开(0:否 1:是)") @ApiModelProperty(value = "是否在新窗口打开(0:否 1:是)")
private Integer isOpen; private Integer isOpen;
@ -105,9 +87,138 @@ public class SysContent implements Serializable {
private Integer deleted; private Integer deleted;
@ApiModelProperty(value = "站点id") @ApiModelProperty(value = "站点id")
@NotNull(message = "站点id不能为空!")
private Integer siteId; private Integer siteId;
@ApiModelProperty(value = "独立模板状态(0禁用;1启用)") @ApiModelProperty(value = "模板状态(0禁用;1启用)")
private Integer templateStatus; 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<SysContentFile> 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;
} }

@ -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;
}

@ -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;
}

@ -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;
}

@ -1,9 +1,6 @@
package com.huoran.iasf.entity; package com.huoran.iasf.entity;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -60,7 +57,7 @@ public class SysDept implements Serializable {
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; private Date updateTime;
@TableField(fill = FieldFill.INSERT) @TableLogic
private Integer deleted; private Integer deleted;
} }

@ -59,9 +59,18 @@ public class SysFilesEntity extends BaseEntity implements Serializable {
private String site; private String site;
@ApiModelProperty(value = "是否已删除,未删除表示该文件正在使用") @ApiModelProperty(value = "是否已删除,未删除表示该文件正在使用")
@TableField(fill = FieldFill.INSERT) @TableLogic
private Integer deleted; 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) @TableField(value = "create_date", fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间") @ApiModelProperty(value = "创建时间")
private Date createDate; private Date createDate;

@ -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;
/**
* <p>
* 栏目模板
* </p>
*
* @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;
}

@ -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;
/**
* <p>
*
* </p>
*
* @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;
}

@ -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;
/**
* <p>
* 栏目样式列表样式详情样式配置表
* </p>
*
* @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;
}

@ -47,6 +47,7 @@ public class UserGroup extends BaseEntity implements Serializable {
private Date updateTime; private Date updateTime;
@ApiModelProperty(value = "是否删除(1未删除;0已删除)") @ApiModelProperty(value = "是否删除(1未删除;0已删除)")
@TableLogic
private Integer deleted; private Integer deleted;
} }

@ -0,0 +1,16 @@
package com.huoran.iasf.mapper;
import com.huoran.iasf.entity.Seo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author cheney
* @since 2023-08-24
*/
public interface SeoMapper extends BaseMapper<Seo> {
}

@ -2,6 +2,7 @@ package com.huoran.iasf.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.SysColumn;
import com.huoran.iasf.vo.FatherContentRespVO; import com.huoran.iasf.vo.FatherContentRespVO;
import com.huoran.iasf.vo.req.LongPageColumnReqVO; import com.huoran.iasf.vo.req.LongPageColumnReqVO;
@ -25,9 +26,18 @@ import java.util.List;
public interface SysColumnMapper extends BaseMapper<SysColumn> { public interface SysColumnMapper extends BaseMapper<SysColumn> {
List<SysColumn> filter(@Param("vo") PaginationColumnReqVO vo); List<SysColumn> filter(@Param("vo") PaginationColumnReqVO vo);
List<SysColumn> filterMenuVisible(@Param("vo") PaginationColumnReqVO vo);
IPage<PageContentRespVO> longPageColumnList(Page<PageContentRespVO> page, @Param("req") LongPageColumnReqVO req); IPage<PageContentRespVO> longPageColumnList(Page<PageContentRespVO> page, @Param("req") LongPageColumnReqVO req);
//依据子级查询父级 //依据子级查询父级
List<FatherContentRespVO> getParentInformationBasedOnChild(@Param("id")Integer id); List<FatherContentRespVO> getParentInformationBasedOnChild(@Param("id")Integer id);
List<SysColumn> getsTheSubColumn(@Param("parentId")Integer parentId ,@Param("ids")String ids ,@Param("isSort")Integer isSort,@Param("siteId")Integer siteId);
Integer oneLevelChecksThemAll(@Param("theChildId")Integer theChildId);
List<SysColumn> queryByColumnType(@Param("ids")String ids);
} }

@ -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<SysContentClassification> {
}

@ -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<SysContentFile> {
List<SysContentFile> getFileByContentId(@Param("contentId") Integer contentId);
}

@ -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<SysContentLabel> {
}

@ -2,13 +2,19 @@ package com.huoran.iasf.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.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.req.PageContentReqVO;
import com.huoran.iasf.vo.resp.PageContentRespVO; import com.huoran.iasf.vo.resp.PageContentRespVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* @描述文章管理 Mapper 接口 * @描述文章管理 Mapper 接口
* @作者: Rong * @作者: Rong
@ -17,4 +23,24 @@ import org.apache.ibatis.annotations.Param;
@Mapper @Mapper
public interface SysContentMapper extends BaseMapper<SysContent> { public interface SysContentMapper extends BaseMapper<SysContent> {
IPage<PageContentRespVO> articlePaginationList(Page<PageContentRespVO> page, @Param("req") PageContentReqVO req); IPage<PageContentRespVO> articlePaginationList(Page<PageContentRespVO> page, @Param("req") PageContentReqVO req);
IPage<PageContentRespVO> getPublishedArticles(Page<PageContentRespVO> page, @Param("req") PageContentReqVO req);
List<SysContentClassification> useTheColumnToGetTagsForTheFullArticle(String ids);
IPage<SysContent> siteSearchArticles(Page<SysContent> page, @Param("req") PageContentReqVO req);
List<PageContentRespVO> columnConditionsFilterArticles(@Param("columnId")String columnId);
/*Integer selectNextId(@Param("content")SysContent sysContent);
Integer updateSortById(@Param("content")SysContent sysContent);
Integer selectPreviousId(@Param("content")SysContent sysContent);*/
List<SysColumn> queryArticleColumnParent(@Param("columnId")Integer columnId);
} }

@ -2,6 +2,7 @@ package com.huoran.iasf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.huoran.iasf.entity.SysDept; import com.huoran.iasf.entity.SysDept;
import org.apache.ibatis.annotations.Mapper;
/** /**
* 部门 Mapper * 部门 Mapper
@ -10,5 +11,6 @@ import com.huoran.iasf.entity.SysDept;
* @version V1.0 * @version V1.0
* @date 2022年7月28日 * @date 2022年7月28日
*/ */
@Mapper
public interface SysDeptMapper extends BaseMapper<SysDept> { public interface SysDeptMapper extends BaseMapper<SysDept> {
} }

@ -1,7 +1,11 @@
package com.huoran.iasf.mapper; package com.huoran.iasf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; 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 com.huoran.iasf.entity.SysFilesEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/** /**
* 文件上传 Mapper * 文件上传 Mapper
@ -10,6 +14,8 @@ import com.huoran.iasf.entity.SysFilesEntity;
* @version V1.0 * @version V1.0
* @date 2022年7月28日 * @date 2022年7月28日
*/ */
@Mapper
public interface SysFilesMapper extends BaseMapper<SysFilesEntity> { public interface SysFilesMapper extends BaseMapper<SysFilesEntity> {
IPage<SysFilesEntity> fileList(Page<SysFilesEntity> page, @Param("req")SysFilesEntity sysFiles);
} }

@ -0,0 +1,16 @@
package com.huoran.iasf.mapper;
import com.huoran.iasf.entity.SysTemplate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 栏目模板 Mapper 接口
* </p>
*
* @author cheney
* @since 2022-11-11
*/
public interface SysTemplateMapper extends BaseMapper<SysTemplate> {
}

@ -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;
/**
* <p>
* 栏目样式列表样式详情样式配置表 Mapper 接口
* </p>
*
* @author cheney
* @since 2022-11-24
*/
public interface SysTemplateStyleConfigurationMapper extends BaseMapper<SysTemplateStyleConfiguration> {
List<SysTemplateStyle> getTheStyleUnderTheTemplate(@Param("templateId") Integer templateId,@Param("type") Integer type);
}

@ -0,0 +1,16 @@
package com.huoran.iasf.mapper;
import com.huoran.iasf.entity.SysTemplateStyle;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author cheney
* @since 2022-11-11
*/
public interface SysTemplateStyleMapper extends BaseMapper<SysTemplateStyle> {
}

@ -19,5 +19,5 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
IPage<UserListResp> userList(Page<UserListResp> page,@Param("req") UserListReq userListReq); IPage<UserListResp> userList(Page<UserListResp> page,@Param("req") UserListReq userListReq);
UserListResp detailInfo(String id); UserListResp detailInfo(Integer id);
} }

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SeoMapper">
</mapper>

@ -6,8 +6,10 @@
<resultMap id="BaseResultMap" type="com.huoran.iasf.entity.SysColumnLongPage"> <resultMap id="BaseResultMap" type="com.huoran.iasf.entity.SysColumnLongPage">
<id column="id" property="id"/> <id column="id" property="id"/>
<result column="column_id" property="columnId"/> <result column="column_id" property="columnId"/>
<result column="json_before_editing" property="jsonBeforeEditing"/>
<result column="the_edited_json" property="theEditedJson"/>
<result column="sort" property="sort"/> <result column="sort" property="sort"/>
<result column="json" property="json"/> <result column="state" property="state"/>
<result column="founder_id" property="founderId"/> <result column="founder_id" property="founderId"/>
<result column="editor_id" property="editorId"/> <result column="editor_id" property="editorId"/>
<result column="create_time" property="createTime"/> <result column="create_time" property="createTime"/>

@ -15,7 +15,7 @@
<result column="type_id" property="typeId"/> <result column="type_id" property="typeId"/>
<result column="template_id" property="templateId"/> <result column="template_id" property="templateId"/>
<result column="list_style_id" property="listStyleId"/> <result column="list_style_id" property="listStyleId"/>
<result column="detail_style" property="detailStyle"/> <result column="detail_style_id" property="detailStyleId"/>
<result column="connection_type" property="connectionType"/> <result column="connection_type" property="connectionType"/>
<result column="link_address" property="linkAddress"/> <result column="link_address" property="linkAddress"/>
<result column="show_with_details" property="showWithDetails"/> <result column="show_with_details" property="showWithDetails"/>
@ -33,20 +33,23 @@
<select id="filter" resultType="com.huoran.iasf.entity.SysColumn"> <select id="filter" resultType="com.huoran.iasf.entity.SysColumn">
SELECT SELECT
*, *,
(SELECT u.username from sys_user u WHERE u.id = s.founder_id) as creteUser, ( SELECT u.real_name FROM sys_user u WHERE u.id = s.founder_id ) AS creteUser,
(SELECT u.username from sys_user u WHERE u.id = s.editor_id) as editorUser ( SELECT u.real_name FROM sys_user u WHERE u.id = s.editor_id ) AS editorUser,
( SELECT t.template_type FROM sys_template t WHERE t.id = s.template_id ) AS templateName,
( SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.list_style_id ) AS listStyle,
( SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.detail_style_id ) AS detailStyle,
( SELECT sty.path FROM sys_template_style sty WHERE sty.id = s.list_style_id ) AS path
FROM FROM
sys_column s sys_column s
WHERE deleted = 1 and site_id = #{vo.siteId} WHERE
deleted = 1 and site_id = #{vo.siteId}
<if test="vo.columnName != '' and vo.columnName!= null"> <if test="vo.columnName != '' and vo.columnName!= null">
and column_name LIKE CONCAT('%',#{vo.columnName},'%') and column_name LIKE CONCAT('%',#{vo.columnName},'%')
</if> </if>
<if test="vo.isSort== 1"> <if test="vo.isSort== 1">
ORDER BY ORDER BY
s.father_id, s.sort ASC
s.sort ASC,
s.create_time desc
</if> </if>
<if test="vo.isSort== 0"> <if test="vo.isSort== 0">
ORDER BY ORDER BY
@ -58,8 +61,8 @@
<select id="longPageColumnList" resultType="com.huoran.iasf.vo.resp.PageContentRespVO"> <select id="longPageColumnList" resultType="com.huoran.iasf.vo.resp.PageContentRespVO">
SELECT (SELECT u.username FROM sys_user u WHERE u.id = c.founder_id) AS founderName, SELECT (SELECT u.real_name FROM sys_user u WHERE u.id = c.founder_id) AS founderName,
(SELECT u.username FROM sys_user u WHERE u.id = c.editor_id) AS editorName, (SELECT u.real_name FROM sys_user u WHERE u.id = c.editor_id) AS editorName,
c.* c.*
FROM sys_column c FROM sys_column c
WHERE deleted = 1 WHERE deleted = 1
@ -73,16 +76,13 @@
T2.father_id, T2.father_id,
T2.level, T2.level,
T2.sort T2.sort
FROM ( FROM (SELECT @r AS _id,
SELECT @r AS _id,
( SELECT @r := father_id FROM sys_column WHERE id = _id ) AS parent_id, ( SELECT @r := father_id FROM sys_column WHERE id = _id ) AS parent_id,
@l := @l + 1 AS lvl @l := @l + 1 AS lvl
FROM FROM
( SELECT @r := #{id}, @l := 0 ) vars, ( SELECT @r := #{id}, @l := 0 ) vars, sys_column h
sys_column h
WHERE WHERE
@r != 0 @r != 0) T1
) T1
JOIN sys_column T2 ON T1._id = T2.id JOIN sys_column T2 ON T1._id = T2.id
WHERE WHERE
deleted = 1 deleted = 1
@ -90,5 +90,111 @@
ORDER BY ORDER BY
T1.lvl DESC T1.lvl DESC
</select> </select>
<select id="filterMenuVisible" resultType="com.huoran.iasf.entity.SysColumn">
SELECT
*,
( SELECT u.real_name FROM sys_user u WHERE u.id = s.founder_id ) AS creteUser,
( SELECT u.real_name FROM sys_user u WHERE u.id = s.editor_id ) AS editorUser,
( SELECT t.template_type FROM sys_template t WHERE t.id = s.template_id ) AS templateName,
( SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.list_style_id ) AS listStyle,
( SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.detail_style_id ) AS detailStyle,
( SELECT sty.path FROM sys_template_style sty WHERE sty.id = s.list_style_id ) AS path
FROM
sys_column s
WHERE deleted = 1 and site_id = #{vo.siteId}
and menu_visible = 0
<if test="vo.columnName != '' and vo.columnName!= null">
and column_name LIKE CONCAT('%',#{vo.columnName},'%')
</if>
<if test="vo.isSort== 1">
ORDER BY
s.sort ASC
</if>
<if test="vo.isSort== 0">
ORDER BY
s.create_time asc
</if>
</select>
<!--<select id="filterMenuVisible" resultType="com.huoran.iasf.entity.SysColumn">
SELECT
*,
( SELECT u.username FROM sys_user u WHERE u.id = s.founder_id ) AS creteUser,
( SELECT u.username FROM sys_user u WHERE u.id = s.editor_id ) AS editorUser,
( SELECT t.template_type FROM sys_template t WHERE t.id = s.template_id ) AS templateName,
( SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.list_style_id ) AS listStyle,
( SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.detail_style_id ) AS detailStyle,
( SELECT sty.path FROM sys_template_style sty WHERE sty.id = s.list_style_id ) AS path
FROM
sys_column s
WHERE deleted = 1 and site_id = #{vo.siteId}
and menu_visible = 0
<if test="vo.columnName != '' and vo.columnName!= null">
and column_name LIKE CONCAT('%',#{vo.columnName},'%')
</if>
<if test="vo.isSort== 1">
ORDER BY
s.father_id,
s.sort ASC,
s.create_time desc
</if>
<if test="vo.isSort== 0">
ORDER BY
s.create_time asc
</if>
</select>-->
<select id="getsTheSubColumn" resultType="com.huoran.iasf.entity.SysColumn">
SELECT *,
(SELECT u.real_name FROM sys_user u WHERE u.id = s.founder_id) AS creteUser,
(SELECT u.real_name FROM sys_user u WHERE u.id = s.editor_id) AS editorUser,
(SELECT t.template_type FROM sys_template t WHERE t.id = s.template_id) AS templateName,
(SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.list_style_id) AS listStyle,
(SELECT sty.style FROM sys_template_style sty WHERE sty.id = s.detail_style_id) AS detailStyle,
(SELECT sty.path FROM sys_template_style sty WHERE sty.id = s.list_style_id) AS path
FROM sys_column s
WHERE deleted = 1
AND site_id =#{siteId}
<if test="ids != '' and ids!= null">
and FIND_IN_SET(s.id, #{ids})
</if>
<if test="isSort== 1">
ORDER BY
s.sort ASC
</if>
<if test="isSort=='' and isSort == null">
ORDER BY
s.create_time asc
</if>
</select>
<select id="oneLevelChecksThemAll" resultType="java.lang.Integer">
SELECT id
FROM (SELECT @r AS _id,
( SELECT @r := father_id FROM sys_column WHERE id = _id ) AS fatherId,
@l := @l + 1 AS lvl
FROM
( SELECT @r := #{theChildId}, @l := 0 ) vars, sys_column h
WHERE
@r != 0) T1
JOIN sys_column T2 ON T1._id = T2.id
WHERE
deleted = 1
ORDER BY
T1.lvl DESC limit 0, 1
</select>
<select id="queryByColumnType" resultType="com.huoran.iasf.entity.SysColumn">
SELECT id,
father_id,
column_name,
list_style_id
FROM sys_column s
WHERE FIND_IN_SET(s.id, #{ids})
GROUP BY list_style_id
</select>
</mapper> </mapper>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysContentClassificationMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.huoran.iasf.entity.SysContentClassification">
<id column="id" property="id"/>
<result column="classification_name" property="classificationName"/>
<result column="founder_id" property="founderId"/>
<result column="editor_id" property="editorId"/>
<result column="create_time" property="createTime"/>
<result column="deleted" property="deleted"/>
<result column="site_id" property="siteId"/>
</resultMap>
</mapper>

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysContentFileMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.huoran.iasf.entity.SysContentFile">
<id column="id" property="id"/>
<result column="content_id" property="contentId"/>
<result column="file_name" property="fileName"/>
<result column="founder_id" property="founderId"/>
<result column="editor_id" property="editorId"/>
<result column="file_size" property="fileSize"/>
<result column="file_format" property="fileFormat"/>
<result column="oss_file_name" property="ossFileName"/>
<result column="file_path" property="filePath"/>
<result column="create_time" property="createTime"/>
<result column="deleted" property="deleted"/>
</resultMap>
<select id="getFileByContentId" resultType="com.huoran.iasf.entity.SysContentFile">
SELECT
*
FROM
sys_content_file
WHERE
deleted = 1
AND content_id = #{contentId}
</select>
</mapper>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysContentLabelMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.huoran.iasf.entity.SysContentLabel">
<id column="id" property="id"/>
<result column="label_name" property="labelName"/>
<result column="founder_id" property="founderId"/>
<result column="editor_id" property="editorId"/>
<result column="create_time" property="createTime"/>
<result column="deleted" property="deleted"/>
<result column="site_id" property="siteId"/>
</resultMap>
</mapper>

@ -1,40 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysContentMapper"> <mapper namespace="com.huoran.iasf.mapper.SysContentMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.huoran.iasf.entity.SysContent">
<id column="id" property="id"/>
<result column="title" property="title"/>
<result column="column_id" property="columnId"/>
<result column="title_img" property="titleImg"/>
<result column="source" property="source"/>
<result column="release_time" property="releaseTime"/>
<result column="summary" property="summary"/>
<result column="banner_img" property="bannerImg"/>
<result column="article_template" property="articleTemplate"/>
<result column="main_body" property="mainBody"/>
<result column="author" property="author"/>
<result column="is_release" property="isRelease"/>
<result column="founder_id" property="founderId"/>
<result column="editor_id" property="editorId"/>
<result column="file" property="file"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="total_browsing" property="totalBrowsing"/>
<result column="connection_type" property="connectionType"/>
<result column="link_address" property="linkAddress"/>
<result column="site_selection" property="siteSelection"/>
<result column="is_open" property="isOpen"/>
<result column="deleted" property="deleted"/>
<result column="side_id" property="siteId"/>
</resultMap>
<select id="articlePaginationList" resultType="com.huoran.iasf.vo.resp.PageContentRespVO"> <select id="articlePaginationList" resultType="com.huoran.iasf.vo.resp.PageContentRespVO">
SELECT c.*, SELECT c.*,
(SELECT sys_column.column_name FROM sys_column WHERE sys_column.id = c.column_id) AS columnName, (SELECT sys_column.column_name FROM sys_column WHERE sys_column.id = c.column_id) AS columnName,
(SELECT u.username FROM sys_user u WHERE u.id = c.founder_id) AS founderName, (SELECT u.real_name FROM sys_user u WHERE u.id = c.founder_id) AS founderName,
(SELECT u.username FROM sys_user u WHERE u.id = c.editor_id) AS editorName, (SELECT u.real_name FROM sys_user u WHERE u.id = c.editor_id) AS editorName,
(SELECT type_id from sys_column WHERE sys_column.id = c.column_id) as typeId (SELECT type_id from sys_column WHERE sys_column.id = c.column_id) as typeId,
IFNULL( ( SELECT c1.classification_name FROM sys_content_classification c1 WHERE c1.id = c.classification_id ),
'暂无' ) AS classificationName
FROM sys_content c FROM sys_content c
WHERE c.deleted = 1 and site_id = #{req.siteId} WHERE c.deleted = 1 and site_id = #{req.siteId}
<if test="req.columnIds != null and req.columnIds.size() > 0 "> <if test="req.columnIds != null and req.columnIds.size() > 0 ">
@ -50,13 +24,13 @@
and title LIKE CONCAT('%',#{req.title},'%') and title LIKE CONCAT('%',#{req.title},'%')
</if> </if>
<if test="req.founder != null and req.founder != ''"> <if test="req.founder != null and req.founder != ''">
AND ( SELECT u.username FROM sys_user u WHERE u.id = c.founder_id ) LIKE AND ( SELECT u.real_name FROM sys_user u WHERE u.id = c.founder_id ) LIKE
CONCAT('%',#{req.founder},'%') CONCAT('%',#{req.founder},'%')
</if> </if>
<if test="req.editor != null and req.editor != ''"> <if test="req.editor != null and req.editor != ''">
AND ( SELECT u.username FROM sys_user u WHERE u.id = c.editor_id ) LIKE CONCAT('%',#{req.editor},'%') AND ( SELECT u.real_name FROM sys_user u WHERE u.id = c.editor_id ) LIKE CONCAT('%',#{req.editor},'%')
</if> </if>
<if test="req.column != null and req.column != ''"> <if test="req.column != null and req.column != ''">
@ -64,8 +38,238 @@
CONCAT('%',#{req.column},'%') CONCAT('%',#{req.column},'%')
</if> </if>
ORDER BY c.create_time desc
<if test="req.isDisable != null and req.isDisable != '' or req.isDisable==0">
AND c.is_disable = #{req.isDisable}
</if>
<choose>
<when test="req.modifiedTimeSort ==0">
ORDER BY c.update_time desc
</when>
<when test="req.modifiedTimeSort ==1">
ORDER BY c.update_time asc
</when>
<when test="req.publicationTimeSort ==0">
ORDER BY c.release_time desc
</when>
<when test="req.publicationTimeSort ==1">
ORDER BY c.release_time asc
</when>
<when test="req.topSort ==0">
ORDER BY is_top asc,
top_time asc
</when>
<when test="req.topSort ==1">
ORDER BY is_top desc,
top_time DESC
</when>
<otherwise>
ORDER BY
release_time DESC,
create_time DESC
</otherwise>
</choose>
</select> </select>
<select id="getPublishedArticles" resultType="com.huoran.iasf.vo.resp.PageContentRespVO">
SELECT
t.*,(SELECT cl.list_style_id from sys_column cl WHERE cl.id = t.column_id) as listStyleId
FROM
(
SELECT
s.*,
( SELECT GROUP_CONCAT( l.id ) FROM sys_content_label l WHERE deleted = 1 AND FIND_IN_SET( l.id, s.lable_id
) ) AS labelId,
( SELECT c.classification_name FROM sys_content_classification c WHERE deleted = 1 AND s.classification_id =
c.id ) AS classificationName ,
(SELECT c.column_name from sys_column c WHERE c.id = s.column_id) as columnName
FROM
sys_content s
WHERE
is_disable = 0
AND s.deleted = 1
AND is_release = 1
) t
WHERE
t.site_id = #{req.siteId}
<if test="req.labelName != null and req.labelName.size() > 0 ">
and
<foreach collection="req.labelName" item="item" index="index" open="(" separator="or" close=")">
FIND_IN_SET( #{item}, t.labelId)
</foreach>
</if>
<if test="req.classificationId != null">
AND t.classification_id = #{req.classificationId}
</if>
<if test="req.title != null and req.title != ''">
AND title LIKE
CONCAT('%',#{req.title},'%')
</if>
<if test="req.patentClassId != null and req.patentClassId != ''">
AND patent_class_id = #{req.patentClassId}
</if>
<if test="req.applicationDate != null and req.applicationDate != ''">
AND application_date = #{req.applicationDate}
</if>
<if test="req.publicationTime != null and req.publicationTime != ''">
AND publication_time = #{req.publicationTime}
</if>
<if test="req.publicationYear != null and req.publicationYear != ''">
AND publication_year = #{req.publicationYear}
</if>
<if test="req.publicationStartTime != null and req.publicationStartTime != '' ">
AND publication_year &gt; #{req.publicationStartTime}
</if>
<if test="req.endOfPublicationTime != null and req.endOfPublicationTime != ''">
AND publication_year &lt; #{req.endOfPublicationTime}
</if>
<if test="req.patentQueryKeyWord != null and req.patentQueryKeyWord != ''">
AND ( title LIKE CONCAT( '%',#{req.patentQueryKeyWord},'%' ) OR inventor LIKE CONCAT( '%',#{req.patentQueryKeyWord},'%' )OR application_number LIKE CONCAT( '%',#{req.patentQueryKeyWord},'%' ))
</if>
<if test="req.monographQueryKeyWord != null and req.monographQueryKeyWord != ''">
AND ( title LIKE CONCAT( '%',#{req.monographQueryKeyWord},'%' ) OR writers_and_editors LIKE CONCAT( '%',#{req.monographQueryKeyWord},'%' )OR publishing_house LIKE CONCAT( '%',#{req.monographQueryKeyWord},'%' ))
</if>
<if test="req.paperQueryKeyWord != null and req.paperQueryKeyWord != ''">
AND ( author LIKE CONCAT( '%',#{req.paperQueryKeyWord},'%' ) OR periodical_name LIKE CONCAT( '%',#{req.paperQueryKeyWord},'%' )OR title LIKE CONCAT( '%',#{req.paperQueryKeyWord},'%' ))
</if>
<if test="req.columnIds != null and req.columnIds.size() > 0 ">
and t.column_id in
<foreach item="item" index="index" collection="req.columnIds"
open="(" separator="," close=")">
#{item}
</foreach>
</if>
<choose>
<when test="req.convokeType !=null">
<if test="req.convokeType == 1">
and unix_timestamp(activity_start_time) <![CDATA[ >= ]]> unix_timestamp(NOW())
ORDER BY t.activity_start_time asc
</if>
<if test="req.convokeType == 2">
and unix_timestamp(activity_start_time) <![CDATA[ <= ]]> unix_timestamp(NOW())
ORDER BY t.activity_start_time desc
</if>
</when>
<otherwise>
ORDER BY
is_top = 1 DESC,
top_time DESC,
release_time DESC,
create_time DESC
</otherwise>
</choose>
</select>
<select id="useTheColumnToGetTagsForTheFullArticle" resultType="com.huoran.iasf.entity.SysContentClassification">
SELECT *
FROM sys_content_classification c
WHERE c.deleted = 1
AND FIND_IN_SET(
c.id,
(SELECT GROUP_CONCAT(s.classification_id)
FROM sys_content s
INNER JOIN sys_content_classification c ON c.id = s.classification_id
WHERE s.deleted = 1
AND c.deleted = 1
AND FIND_IN_SET(s.column_id, #{ids}))
)
</select>
<select id="siteSearchArticles" resultType="com.huoran.iasf.entity.SysContent">
SELECT
c.*
FROM
sys_content c
WHERE
deleted = 1
AND site_id = #{req.siteId}
<if test="req.title != null and req.title != ''">
AND title LIKE
CONCAT('%',#{req.title},'%')
</if>
ORDER BY
is_top = 1 DESC,
top_time DESC,
release_time DESC,
create_time DESC
</select>
<select id="columnConditionsFilterArticles" resultType="com.huoran.iasf.vo.resp.PageContentRespVO">
SELECT t.*,
(SELECT cl.list_style_id FROM sys_column cl WHERE cl.id = t.column_id) AS listStyleId
FROM (SELECT s.*,
(SELECT GROUP_CONCAT(label_name)
FROM sys_content_label l
WHERE deleted = 1
AND FIND_IN_SET(l.id, s.lable_id)) AS labelName,
(SELECT c.classification_name
FROM sys_content_classification c
WHERE deleted = 1
AND s.classification_id = c.id) AS classificationName
FROM sys_content s
WHERE s.deleted = 1
AND is_disable = 0
AND is_release = 1) t
WHERE FIND_IN_SET(t.column_id, #{columnId})
ORDER BY is_top = 1 DESC,
top_time DESC,
release_time DESC,
create_time DESC
</select>
<select id="queryArticleColumnParent" resultType="com.huoran.iasf.entity.SysColumn">
SELECT t2.*
FROM (
SELECT
@r AS _id,
(SELECT @r := father_id FROM sys_column WHERE id = _id) AS father_id,
@l := @l + 1 AS lvl
FROM
(SELECT @r := #{columnId}, @l := 0) vars,
sys_column h
WHERE @r != 0) T1
JOIN sys_column T2
ON T1._id = T2.id and deleted = 1
ORDER BY T1.lvl DESC
</select>
</mapper> </mapper>

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysFilesMapper">
<select id="fileList" resultType="com.huoran.iasf.entity.SysFilesEntity"
parameterType="com.huoran.iasf.entity.SysFilesEntity">
SELECT
f.id,
f.url,
f.file_name,
f.format,
f.file_size,
f.type,
f.deleted,
f.quote,
f.site,
f.is_release,
f.is_del,
f.quote_id,
f.quote_type,
f.create_date,
u.real_name AS uploader
FROM
sys_files f
LEFT JOIN sys_user u ON f.uploader = u.id
WHERE f.deleted = 1
AND f.is_release = 1
AND f.is_del = 0
and f.quote is not null
<if test="req.site != '' and req.site != null">
AND f.site = #{req.site}
</if>
<if test="req.type != '' and req.type != null">
AND f.type = #{req.type}
</if>
<if test="req.fileName != '' and req.fileName != null">
AND f.file_name LIKE '%' #{req.fileName} '%'
</if>
<if test="req.uploader != '' and req.uploader != null">
AND u.real_name LIKE '%' #{req.uploader} '%'
</if>
<if test="req.quote != '' and req.quote != null">
AND f.quote LIKE '%' #{req.quote} '%'
</if>
ORDER BY
f.create_date DESC
</select>
</mapper>

@ -7,7 +7,7 @@
ap.* ap.*
FROM FROM
sys_role_permission ar sys_role_permission ar
left join sys_permission ap on ar.permission_id = ap.id join sys_permission ap on ar.permission_id = ap.id
where find_in_set(ar.role_id,#{roleIds}) where find_in_set(ar.role_id,#{roleIds})
GROUP BY ap.id GROUP BY ap.id
</select> </select>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysTemplateMapper">
</mapper>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysTemplateStyleConfigurationMapper">
<select id="getTheStyleUnderTheTemplate" resultType="com.huoran.iasf.entity.SysTemplateStyle">
SELECT s.*
FROM sys_template_style_configuration c
inner join sys_template t on c.template_id = t.id
inner join sys_template_style s on s.id = c.style_id
WHERE c.template_id = #{templateId}
and s.type = #{type} and s.is_hide = 0
</select>
</mapper>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huoran.iasf.mapper.SysTemplateStyleMapper">
</mapper>

@ -13,7 +13,7 @@ import java.util.Date;
* session管理器 * session管理器
* @author cheney * @author cheney
* @version V1.0 * @version V1.0
* @date 2020年5月11日 * @date 2022年5月11日
*/ */
@Service @Service
public class HttpApiSessionService { public class HttpApiSessionService {
@ -25,7 +25,7 @@ public class HttpApiSessionService {
public static final String SUBJECT = "HuoRan_SUBJECT"; public static final String SUBJECT = "HuoRan_SUBJECT";
public static final long EXPIRE = 1000 * 60 * 60 * 24 * 2; //过期时间,毫秒,一天 public static final long EXPIRE = 1000 * 60 * 60 * 24; //过期时间,毫秒,一天
//秘钥 //秘钥
public static final String APP_SECRET = "HuoRan_SYMMETRIC_ENCRYPTION_HS256"; public static final String APP_SECRET = "HuoRan_SYMMETRIC_ENCRYPTION_HS256";
@ -38,7 +38,7 @@ public class HttpApiSessionService {
* @param userId username * @param userId username
* @return token * @return token
*/ */
public String geneJsonWebToken(String userId, String userName) { public String generateToken(Integer userId, String userName) {
String token = Jwts.builder().setSubject(SUBJECT) String token = Jwts.builder().setSubject(SUBJECT)
.claim(USER_ID_KEY, userId) .claim(USER_ID_KEY, userId)
.claim(USER_USERNAME_KEY, userName) .claim(USER_USERNAME_KEY, userName)

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.huoran.iasf.common.utils.Constant; import com.huoran.iasf.common.utils.Constant;
import com.huoran.iasf.entity.SysUser; import com.huoran.iasf.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -28,8 +29,7 @@ public class HttpSessionService {
private RedisService redisService; private RedisService redisService;
@Resource @Resource
private UserRoleService userRoleService; private UserRoleService userRoleService;
@Resource
private RolePermissionService rolePermissionService;
@Resource @Resource
private HttpServletRequest request; private HttpServletRequest request;
@Resource @Resource
@ -45,12 +45,17 @@ public class HttpSessionService {
@Value("${spring.redis.key.prefix.permissionRefresh}") @Value("${spring.redis.key.prefix.permissionRefresh}")
private String redisPermissionRefreshKey; private String redisPermissionRefreshKey;
@Value("${spring.redis.key.expire.permissionRefresh}") @Value("${spring.redis.key.expire.permissionRefresh}")
private Long redisPermissionRefreshExpire; private Long redisPermissionRefreshExpire;
@Autowired
private HttpApiSessionService sessionService;
public String createTokenAndUser(SysUser user, List<String> roles, Set<String> permissions) { public String createTokenAndUser(SysUser user, List<String> roles, Set<String> permissions) {
String token = sessionService.generateToken(user.getId(), user.getUsername());
//方便根据id找到redis的key, 修改密码/退出登陆 方便使用 //方便根据id找到redis的key, 修改密码/退出登陆 方便使用
String token = getRandomToken() + "#" + user.getId(); // String token = getRandomToken() + "#" + user.getId();
JSONObject sessionInfo = new JSONObject(); JSONObject sessionInfo = new JSONObject();
sessionInfo.put(Constant.USERID_KEY, user.getId()); sessionInfo.put(Constant.USERID_KEY, user.getId());
sessionInfo.put(Constant.USERNAME_KEY, user.getUsername()); sessionInfo.put(Constant.USERNAME_KEY, user.getUsername());
@ -166,9 +171,9 @@ public class HttpSessionService {
/** /**
* 使多个用户的token失效 * 使多个用户的token失效
*/ */
public void abortUserByUserIds(List<Integer> userIds) { public void abortUserByUserIds(List<String> userIds) {
if (CollectionUtils.isNotEmpty(userIds)) { if (CollectionUtils.isNotEmpty(userIds)) {
for (Integer id : userIds) { for (String id : userIds) {
redisService.delKeys(userTokenPrefix + "*#" + id); redisService.delKeys(userTokenPrefix + "*#" + id);
} }

@ -33,7 +33,7 @@ public interface RoleService extends IService<SysRole> {
* *
* @param id id * @param id id
*/ */
void deletedRole(List<Integer> ids); void deletedRole(List<String> ids);
/** /**
* 根据userId获取绑定的角色 * 根据userId获取绑定的角色

@ -0,0 +1,16 @@
package com.huoran.iasf.service;
import com.huoran.iasf.entity.Seo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author cheney
* @since 2023-08-24
*/
public interface SeoService extends IService<Seo> {
}

@ -7,6 +7,7 @@ import com.huoran.iasf.vo.req.ColumnWeightReqVO;
import com.huoran.iasf.vo.req.LongPageColumnReqVO; import com.huoran.iasf.vo.req.LongPageColumnReqVO;
import com.huoran.iasf.vo.req.PageContentReqVO; import com.huoran.iasf.vo.req.PageContentReqVO;
import com.huoran.iasf.vo.req.PaginationColumnReqVO; import com.huoran.iasf.vo.req.PaginationColumnReqVO;
import org.springframework.cache.annotation.CacheEvict;
import java.util.List; import java.util.List;
@ -23,7 +24,24 @@ public interface SysColumnService extends IService<SysColumn> {
List<SysColumn> listWithTree(PaginationColumnReqVO sysColumn); List<SysColumn> listWithTree(PaginationColumnReqVO sysColumn);
//栏目树结构(前台可见,只展示试单可见的栏目)
List<SysColumn> listWithTreeMenuVisible(PaginationColumnReqVO sysColumn);
//长页栏目列表 //长页栏目列表
R longPageColumnList(LongPageColumnReqVO reqVO); R longPageColumnList(LongPageColumnReqVO reqVO);
R getsTheSubColumn(Integer parentId,String ids,Integer siteId);
void removeArticles(Integer columnId);
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);
} }

@ -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<SysContentClassification> {
}

@ -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<SysContentFile> {
List<SysContentFile> getFileByContentId(Integer contentId);
}

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

Loading…
Cancel
Save